-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathhover.js
More file actions
147 lines (135 loc) · 5.11 KB
/
Copy pathhover.js
File metadata and controls
147 lines (135 loc) · 5.11 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
// A hover bar to let user read out information for particular AA
function Hover(graphLayout, lanes, graph) {
var me = this;
this.graphLayout = graphLayout;
this.lanes = lanes;
this.graph = graph;
this.lastMouseY = 0;
$("#hoverBar").remove();
// How to display the hovered AA
this.hoverBar = graphLayout.entire.append("g")
.attr("id", "hoverBar")
.attr("transform", "translate(0,0) scale(1, 1)")
.attr("height", height)
.attr("width", 1)
.attr("class", "hover-bar")
.attr("display", "none");
for (var i = 0; i < lanes.length; i++) {
var lane = lanes[i];
if (lane.customHighlight) {
// We do not want a highligher for custom sequences (we already do that work)
continue;
}
this.hoverBar.append("rect")
.attr("x", 0)
.attr("y", lane.layout.y)
.attr("width", 1)
.attr("height", lane.layout.height);
}
var lastBrushableLaneIndex = lanes.length - 1;
if (lanes[lastBrushableLaneIndex].name === "aligned") {
lastBrushableLaneIndex--;
}
var lastBrushableLane = lanes[lastBrushableLaneIndex];
// A rectangle capturing highlighting events
this.eventRect = graph.append("rect")
.attr("class", "overlay")
.attr("x", graphLayout.margin.left)
.attr("width", width + graphLayout.margin.right)
.attr("height", lastBrushableLane.layout.y + lastBrushableLane.layout.height + graphLayout.margin.top)
.on("mousedown", function () {
// First check whether we are over something clickable
for (var i = 0; i < lanes.length; i++) {
var lane = lanes[i];
if (lane.click) {
// This will handle the click event properly and return true to terminate
if (lane.click(me.highlightedAA, me.lastMouseY)) {
return;
}
}
}
// This is very tricky. Since the brush is under the "eventRect" layer that gathers mouse
// events, we need to first disable the hover bar, THEN fake a mousedown event
// and pass it over to the brush to process.
// The brush is instructed to call .enable() again on brushend.
// This way these two kinds of interaction alternate between each other
me.disable();
var brush_elm = graph.select(".brush").node();
var new_click_event = new Event('mousedown');
new_click_event.pageX = d3.event.pageX;
new_click_event.clientX = d3.event.clientX;
new_click_event.pageY = d3.event.pageY;
new_click_event.clientY = d3.event.clientY;
brush_elm.dispatchEvent(new_click_event);
})
.on("mouseover", function () {
me.show();
})
.on("mouseout", function () {
me.hide();
})
.on("mousemove", function () {
var x = d3.mouse(this)[0] - margin.left;
var y = d3.mouse(this)[1] - margin.top;
me.highlight(x, y);
});
this.highlighting = false;
this.highlightedAA = -1;
}
// Set the hover to highlight a given amino acid
Hover.prototype = {
highlight: function (mouseX, mouseY) {
this.lastMouseX = mouseX;
this.lastMouseY = mouseY;
var aminoAcid = Math.round(xScale.invert(mouseX));
if (aminoAcid >= xScale.domain()[0] && aminoAcid <= xScale.domain()[1]) {
this.show();
this.highlightedAA = aminoAcid;
var x = xScale(aminoAcid - 0.5) + this.graphLayout.margin.left;
var y = this.graphLayout.margin.top;
var width = xScale(2) - xScale(1);
this.hoverBar.attr("transform", "translate(" + x + "," + y + ") scale(" + width + "," + "1)");
for (var i = 0; i < lanes.length; i++) {
var lane = lanes[i];
if (lane.hover) {
lane.hover(aminoAcid, mouseY);
}
}
} else {
this.hide();
}
this.lastMouseY = mouseY;
},
show: function () {
if (!this.highlighting) {
this.highlighting = true;
this.hoverBar.attr('display', null);
for (var i = 0; i < lanes.length; i++) {
var lane = lanes[i];
if (lane.hover) {
lane.hover(this.highlightedAA, this.lastMouseY);
}
}
}
},
hide: function () {
if (this.highlighting) {
this.highlighting = false;
this.hoverBar.attr('display', 'none');
for (var i = 0; i < lanes.length; i++) {
var lane = lanes[i];
if (lane.unhover) {
lane.unhover();
}
}
}
},
disable: function () {
this.eventRect.attr('display', 'none');
this.highlightedAA = -1;
},
enable: function () {
this.eventRect.attr('display', 'null');
this.highlight(this.lastMouseX, this.lastMouseY);
}
};