Molecular structures in svelte

Different javascript libraries are available for displaying molecular structures, such as NGL and 3Dmol.js.

3Dmoljs

We’ve integrated a structure viewer in our (award-winning) proof-of-concept tool for exploring protein post-translational modifications EProm, but that required quite a bit of tweaking.

But here’s a minimal example for viewing the structure for CYP2D6, using NGL.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<svelte:head>
  <script src="https://unpkg.com/ngl"></script>
</svelte:head>

<script>
  import { Stage } from 'ngl';
  import { onMount } from 'svelte';

  let stage;

  onMount(async () => {
    stage = new Stage("viewport", { backgroundColor: "lightgrey" })
    fetch("https://alphafold.ebi.ac.uk/api/prediction/P10635")
      .then(response => response.json())
      .then(data => { console.log(data[0].pdbUrl); return data[0].pdbUrl })
      .then(pdbUrl => stage.loadFile(pdbUrl, {defaultRepresentation: true}))
  });
</script>

<div id="viewport" style="width:600px; height:400px;"></div>

The alphafold call returns a JSON object that includes the PDB URL, which we first need to extract.

The end result:

cyp2d6 structure

If you don’t want the default representation, you can remove that option from line 16, and add the representation separately on the component:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
...
<script>
...
    stage = new Stage("viewport", { backgroundColor: "lightgrey" })
    fetch("https://alphafold.ebi.ac.uk/api/prediction/P10635")
      .then(response => response.json())
      .then(data => { console.log(data[0].pdbUrl); return data[0].pdbUrl })
      .then(pdbUrl => stage.loadFile(pdbUrl))
      .then(component => { component.addRepresentation("ball+stick", { colorScheme: "atomindex" });
                           component.autoView() })
  });
</script>

<div id="viewport" style="width:600px; height:400px;"></div>

Some useful colour schemes are

  • sstruc: see the secondary structure

  • residueindex: so you know which residues are in proximity in the primary structure

For a full list of possible representations, see here.

We can also add representations after the onMount. This will make it possible to change those and the colours interactively. For example (also using async-await instead of then for my own reference):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<svelte:head>
  <script src="https://unpkg.com/ngl"></script>
</svelte:head>

<script>
  import { Stage } from 'ngl';
  import { onMount } from 'svelte';

  let stage;
  let my_representation = 'cartoon'
  let my_colours = 'atomindex'

  onMount(async () => {
    stage = new Stage("viewport", { backgroundColor: "#eeeeee" })

    const response = await fetch("https://alphafold.ebi.ac.uk/api/prediction/P10635")
    const data = await response.json()
    const pdbUrl = await data[0].pdbUrl
    component = await stage.loadFile(pdbUrl)   
  });

  $: {
    if ( typeof component === 'object' ) {
      component.removeAllRepresentations();
      component.addRepresentation(my_representation, {colorScheme: my_colours})
      component.autoView()
    }
  }
</script>

<div id="viewport" style="width:600px; height:400px;"></div>