forked from dms-view/dms-view.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprot_struct.js
More file actions
155 lines (142 loc) · 4.4 KB
/
Copy pathprot_struct.js
File metadata and controls
155 lines (142 loc) · 4.4 KB
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Code for example: interactive/simple-viewer
// Create NGL Stage object
const stage = new NGL.Stage("protein");
stage.setParameters({
backgroundColor: "white"
});
// Handle window resizing
window.addEventListener("resize", function(event) {
stage.handleResize();
}, false);
// add button to the screen
function addElement(el) {
Object.assign(el.style, {
position: "absolute",
zIndex: 10
})
stage.viewer.container.appendChild(el)
}
// make button
function createElement(name, properties, style) {
var el = document.createElement(name)
Object.assign(el, properties)
Object.assign(el.style, style)
return el
}
// button that selects certain parts of the protein
function createSelect(options, properties, style) {
var select = createElement("select", properties, style)
options.forEach(function(d) {
select.add(createElement("option", {
value: d[0],
text: d[1]
}))
})
return select
}
// color a site by a certain color
function selectSiteOnProtein(siteString, color) {
// highlighted site representation should match main representation except
// the highlighted site should be spacefill if main protein cartoon
backbone = ["cartoon"]
if (backbone.includes(polymerSelect.value)) {
fill = "spacefill";
} else {
fill = polymerSelect.value
}
// color the site
if(protein){
protein.addRepresentation(fill, {
color: color,
name: siteString
}).setSelection(siteString)
}
}
// remove color from a site
function deselectSiteOnProtein(siteString) {
stage.getRepresentationsByName(siteString).dispose()
}
// select protein display type
var polymerSelect = createSelect([
["cartoon", "cartoon"],
["spacefill", "spacefill"],
["licorice", "sticks"],
["surface", "surface"]
], {
onchange: function(e) {
stage.getRepresentationsByName("polymer").dispose()
stage.eachComponent(function(o) {
o.addRepresentation(e.target.value, {
sele: "polymer",
name: "polymer",
color: greyColor
})
// on change, reselect the points so they are "on top"
d3.selectAll(".selected").data().forEach(function(element) {
element.protein_chain.forEach(function(chain){
deselectSiteOnProtein(":" + chain + " and " + element.protein_site)
selectSiteOnProtein(
":" + chain + " and " + element.protein_site,
color_key[element.site]
)
})
});
})
}
}, {
top: "36px",
left: "12px"
})
// tooltip setup
const tooltip = createElement("div", {}, {
display: "none",
position: "absolute",
zIndex: 10,
pointerEvents: "none",
backgroundColor: "rgba(255,255,255, 0.8)", // white and transparent
color: "black",
padding: "8px",
fontFamily: "sans-serif"
})
stage.viewer.container.appendChild(tooltip);
// remove default hoverPick mouse action
// this appears to remve the default tooltip behavior
stage.mouseControls.remove("hoverPick")
// listen to `hovered` signal to move tooltip around and change its text
stage.signals.hovered.add(function(pickingProxy) {
if (pickingProxy && (pickingProxy.atom || pickingProxy.bond)) {
var atom = pickingProxy.atom || pickingProxy.closestBondAtom;
var cp = pickingProxy.canvasPosition;
// extract the protein chain and site
var site_name = atom.qualifiedName().split(":")[0].split("]")[1]
var chain_name = atom.qualifiedName().split(":")[1].split(".")[0]
// extract the data corresponding to this site
var residue_data = Array.from(chart.condition_data.values()).filter(d =>
(+d.protein_site == site_name) && (d.protein_chain.includes(chain_name)))
// there should not be more than one entry
try {
if (residue_data.length > 1) throw "data parse wrong";
} catch (err) {
console.log(err)
}
// if there are no entries, don't display tooltip
if (residue_data.length == 0) {
tooltip.style.display = "none";
} else {
residue_data = residue_data[0]
// write to the tooltip
tooltip.innerHTML =
`Atom: ${chain_name} ${site_name}
<hr/>
Site: ${residue_data.label_site}<br/>
${residue_data.metric_name.substring(5,)}: ${parseFloat(residue_data.metric).toFixed(2)}
Wildtype: ${residue_data.wildtype}<br/>
`
tooltip.style.bottom = cp.y + 3 + "px";
tooltip.style.left = cp.x + 3 + "px";
tooltip.style.display = "block";
}
} else {
tooltip.style.display = "none";
}
});