oncoprintjs 5.0.2 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.es.js +14731 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.js +14745 -0
- package/dist/index.js.map +1 -0
- package/dist/js/CachedProperty.d.ts +10 -10
- package/dist/js/binarysearch.d.ts +1 -1
- package/dist/js/bucketsort.d.ts +16 -16
- package/dist/js/clustering.d.ts +14 -14
- package/dist/js/extractrgba.d.ts +4 -4
- package/dist/js/haselementsininterval.d.ts +1 -1
- package/dist/js/heatmapcolors.d.ts +5 -4
- package/dist/js/makesvgelement.d.ts +1 -1
- package/dist/js/modelutils.d.ts +7 -7
- package/dist/js/oncoprint.d.ts +168 -170
- package/dist/js/oncoprintheaderview.d.ts +23 -22
- package/dist/js/oncoprintlabelview.d.ts +79 -78
- package/dist/js/oncoprintlegendrenderer.d.ts +32 -31
- package/dist/js/oncoprintminimapview.d.ts +69 -66
- package/dist/js/oncoprintmodel.d.ts +400 -398
- package/dist/js/oncoprintruleset.d.ts +176 -177
- package/dist/js/oncoprintshape.d.ts +67 -67
- package/dist/js/oncoprintshapetosvg.d.ts +2 -2
- package/dist/js/oncoprintshapetovertexes.d.ts +5 -5
- package/dist/js/oncoprinttooltip.d.ts +23 -22
- package/dist/js/oncoprinttrackinfoview.d.ts +40 -39
- package/dist/js/oncoprinttrackoptionsview.d.ts +58 -57
- package/dist/js/oncoprintwebglcellview.d.ts +168 -167
- package/dist/js/oncoprintzoomslider.d.ts +28 -27
- package/dist/js/polyfill.d.ts +4 -4
- package/dist/js/precomputedcomparator.d.ts +13 -13
- package/dist/js/shaders.d.ts +2 -2
- package/dist/js/svgfactory.d.ts +24 -23
- package/dist/js/utils.d.ts +16 -16
- package/dist/js/workers/clustering-worker.d.ts +19 -20
- package/dist/test/gradientCategoricalRuleset.spec.d.ts +1 -1
- package/dist/test/monolith.spec.d.ts +1 -1
- package/jest.config.ts +2 -0
- package/package.json +20 -26
- package/rollup.config.ts +14 -0
- package/rules/geneticrules.ts +344 -305
- package/server.js +11 -0
- package/src/img/menudots.svg +9 -9
- package/src/img/zoomtofit.svg +12 -12
- package/src/index.tsx +13 -0
- package/src/js/CachedProperty.ts +6 -7
- package/src/js/binarysearch.ts +8 -3
- package/src/js/bucketsort.ts +89 -47
- package/src/js/clustering.ts +22 -10
- package/src/js/extractrgba.ts +16 -12
- package/src/js/haselementsininterval.ts +8 -4
- package/src/js/heatmapcolors.ts +515 -515
- package/src/js/main.js +1 -1
- package/src/js/makesvgelement.ts +2 -2
- package/src/js/modelutils.ts +11 -8
- package/src/js/oncoprint.ts +706 -385
- package/src/js/oncoprintheaderview.ts +165 -125
- package/src/js/oncoprintlabelview.ts +388 -170
- package/src/js/oncoprintlegendrenderer.ts +203 -72
- package/src/js/oncoprintminimapview.ts +1010 -417
- package/src/js/oncoprintmodel.ts +894 -530
- package/src/js/oncoprintruleset.ts +694 -379
- package/src/js/oncoprintshape.ts +240 -97
- package/src/js/oncoprintshapetosvg.ts +77 -26
- package/src/js/oncoprintshapetovertexes.ts +153 -48
- package/src/js/oncoprinttooltip.ts +58 -27
- package/src/js/oncoprinttrackinfoview.ts +115 -59
- package/src/js/oncoprinttrackoptionsview.ts +353 -187
- package/src/js/oncoprintwebglcellview.ts +951 -415
- package/src/js/oncoprintzoomslider.ts +172 -107
- package/src/js/polyfill.ts +7 -3
- package/src/js/precomputedcomparator.ts +133 -50
- package/src/js/shaders.ts +2 -4
- package/src/js/svgfactory.ts +128 -73
- package/src/js/utils.ts +51 -31
- package/src/js/workers/clustering-worker.ts +50 -42
- package/src/test/gradientCategoricalRuleset.spec.ts +55 -38
- package/src/test/monolith.spec.ts +718 -285
- package/test/generate_data.py +108 -0
- package/test/glyphmap-data.js +1041 -0
- package/test/heatmap-data.js +1027 -0
- package/test/index.html +21 -0
- package/test/oncoprint-glyphmap.js +79 -0
- package/test/oncoprint-heatmap.js +123 -0
- package/tsconfig.json +4 -10
- package/tsconfig.test.json +11 -0
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/oncoprintjs.iml +0 -12
- package/.idea/vcs.xml +0 -6
- package/.idea/workspace.xml +0 -106
- package/dist/.gitkeep +0 -0
- package/dist/js/minimaputils.d.ts +0 -0
- package/dist/oncoprint.bundle.js +0 -33
- package/jest.config.js +0 -12
- package/src/js/minimaputils.ts +0 -0
- package/typings/custom.d.ts +0 -7
- package/typings/missing.d.ts +0 -7
- package/webpack.config.js +0 -43
|
@@ -2,41 +2,46 @@ import gl_matrix from 'gl-matrix';
|
|
|
2
2
|
import OncoprintZoomSlider from './oncoprintzoomslider';
|
|
3
3
|
import $ from 'jquery';
|
|
4
4
|
import zoomToFitIcon from '../img/zoomtofit.svg';
|
|
5
|
-
import OncoprintModel, {ColumnIndex, TrackId} from
|
|
5
|
+
import OncoprintModel, { ColumnIndex, TrackId } from './oncoprintmodel';
|
|
6
6
|
import OncoprintWebGLCellView, {
|
|
7
7
|
OncoprintShaderProgram,
|
|
8
8
|
OncoprintTrackBuffer,
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
OncoprintVertexTrackBuffer,
|
|
10
|
+
OncoprintWebGLContext,
|
|
11
|
+
} from './oncoprintwebglcellview';
|
|
11
12
|
import MouseMoveEvent = JQuery.MouseMoveEvent;
|
|
12
|
-
import {clamp, cloneShallow} from
|
|
13
|
+
import { clamp, cloneShallow } from './utils';
|
|
14
|
+
import _ from 'lodash';
|
|
13
15
|
|
|
14
16
|
export type MinimapViewportSpec = {
|
|
15
|
-
left_col:ColumnIndex; // leftmost col included in viewport
|
|
16
|
-
right_col:ColumnIndex; // col at the boundary of viewport, first col to the right of viewport
|
|
17
|
-
scroll_y_proportion:number; // between 0 and 1
|
|
18
|
-
zoom_y:number; // between 0 and 1
|
|
17
|
+
left_col: ColumnIndex; // leftmost col included in viewport
|
|
18
|
+
right_col: ColumnIndex; // col at the boundary of viewport, first col to the right of viewport
|
|
19
|
+
scroll_y_proportion: number; // between 0 and 1
|
|
20
|
+
zoom_y: number; // between 0 and 1
|
|
19
21
|
};
|
|
20
22
|
|
|
21
23
|
type OverlayRectParams = {
|
|
22
|
-
top:number;
|
|
23
|
-
left_col:ColumnIndex;
|
|
24
|
-
right_col:ColumnIndex;
|
|
25
|
-
height:number;
|
|
24
|
+
top: number;
|
|
25
|
+
left_col: ColumnIndex;
|
|
26
|
+
right_col: ColumnIndex;
|
|
27
|
+
height: number;
|
|
26
28
|
};
|
|
27
29
|
|
|
28
30
|
class OverlayRectSpec {
|
|
29
31
|
constructor(
|
|
30
|
-
private params:OverlayRectParams,
|
|
31
|
-
private getCellWidth:()=>number
|
|
32
|
+
private params: OverlayRectParams,
|
|
33
|
+
private getCellWidth: () => number
|
|
32
34
|
) {}
|
|
33
35
|
|
|
34
|
-
public setParams(p:OverlayRectParams) {
|
|
36
|
+
public setParams(p: OverlayRectParams) {
|
|
35
37
|
this.params = p;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
public clone() {
|
|
39
|
-
return new OverlayRectSpec(
|
|
41
|
+
return new OverlayRectSpec(
|
|
42
|
+
cloneShallow(this.params),
|
|
43
|
+
this.getCellWidth
|
|
44
|
+
);
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
public get left_col() {
|
|
@@ -73,55 +78,68 @@ class OverlayRectSpec {
|
|
|
73
78
|
}
|
|
74
79
|
|
|
75
80
|
export default class OncoprintMinimapView {
|
|
76
|
-
private handleContextLost:()=>void;
|
|
81
|
+
private handleContextLost: () => void;
|
|
77
82
|
private layout_numbers = {
|
|
78
|
-
window_width
|
|
79
|
-
window_height
|
|
80
|
-
vertical_zoom_area_width
|
|
81
|
-
horizontal_zoom_area_height
|
|
82
|
-
padding
|
|
83
|
-
window_bar_height
|
|
84
|
-
canvas_left
|
|
85
|
-
canvas_top
|
|
83
|
+
window_width: -1,
|
|
84
|
+
window_height: -1,
|
|
85
|
+
vertical_zoom_area_width: -1,
|
|
86
|
+
horizontal_zoom_area_height: -1,
|
|
87
|
+
padding: -1,
|
|
88
|
+
window_bar_height: -1,
|
|
89
|
+
canvas_left: -1,
|
|
90
|
+
canvas_top: -1,
|
|
86
91
|
};
|
|
87
|
-
private current_rect:OverlayRectSpec;
|
|
88
|
-
|
|
89
|
-
private $window_bar:JQuery;
|
|
90
|
-
private $close_btn:JQuery;
|
|
91
|
-
private horizontal_zoom:OncoprintZoomSlider;
|
|
92
|
-
private vertical_zoom:OncoprintZoomSlider;
|
|
93
|
-
|
|
94
|
-
private ctx:OncoprintWebGLContext|null;
|
|
95
|
-
private
|
|
96
|
-
private
|
|
97
|
-
private
|
|
98
|
-
private
|
|
99
|
-
|
|
100
|
-
|
|
92
|
+
private current_rect: OverlayRectSpec;
|
|
93
|
+
|
|
94
|
+
private $window_bar: JQuery;
|
|
95
|
+
private $close_btn: JQuery;
|
|
96
|
+
private horizontal_zoom: OncoprintZoomSlider;
|
|
97
|
+
private vertical_zoom: OncoprintZoomSlider;
|
|
98
|
+
|
|
99
|
+
private ctx: OncoprintWebGLContext | null;
|
|
100
|
+
private ext: ANGLE_instanced_arrays | null;
|
|
101
|
+
private overlay_ctx: CanvasRenderingContext2D | null;
|
|
102
|
+
private pMatrix: any;
|
|
103
|
+
private mvMatrix: any;
|
|
104
|
+
private shader_program: OncoprintShaderProgram;
|
|
105
|
+
|
|
106
|
+
private resize_hover:
|
|
107
|
+
| 'r'
|
|
108
|
+
| 'l'
|
|
109
|
+
| 't'
|
|
110
|
+
| 'b'
|
|
111
|
+
| 'tl'
|
|
112
|
+
| 'br'
|
|
113
|
+
| 'bl'
|
|
114
|
+
| 'tr'
|
|
115
|
+
| false = false;
|
|
101
116
|
|
|
102
117
|
private rendering_suppressed = false;
|
|
103
118
|
private visible = false;
|
|
104
119
|
|
|
105
120
|
constructor(
|
|
106
|
-
private $div:JQuery,
|
|
107
|
-
private $canvas:JQuery<HTMLCanvasElement>,
|
|
108
|
-
private $overlay_canvas:JQuery<HTMLCanvasElement>,
|
|
109
|
-
model:OncoprintModel,
|
|
110
|
-
cell_view:OncoprintWebGLCellView,
|
|
111
|
-
width:number,
|
|
112
|
-
height:number,
|
|
113
|
-
drag_callback:(x:number, y:number)=>void,
|
|
114
|
-
viewport_callback:(vp:MinimapViewportSpec)=>void,
|
|
115
|
-
horz_zoom_callback:(z:number)=>void,
|
|
116
|
-
vert_zoom_callback:(z:number)=>void,
|
|
117
|
-
zoom_to_fit_callback:()=>void,
|
|
118
|
-
close_callback:()=>void
|
|
121
|
+
private $div: JQuery,
|
|
122
|
+
private $canvas: JQuery<HTMLCanvasElement>,
|
|
123
|
+
private $overlay_canvas: JQuery<HTMLCanvasElement>,
|
|
124
|
+
model: OncoprintModel,
|
|
125
|
+
cell_view: OncoprintWebGLCellView,
|
|
126
|
+
width: number,
|
|
127
|
+
height: number,
|
|
128
|
+
drag_callback: (x: number, y: number) => void,
|
|
129
|
+
viewport_callback: (vp: MinimapViewportSpec) => void,
|
|
130
|
+
horz_zoom_callback: (z: number) => void,
|
|
131
|
+
vert_zoom_callback: (z: number) => void,
|
|
132
|
+
zoom_to_fit_callback: () => void,
|
|
133
|
+
close_callback: () => void
|
|
119
134
|
) {
|
|
120
135
|
this.$div = $div;
|
|
121
136
|
this.$canvas = $canvas;
|
|
122
137
|
this.$overlay_canvas = $overlay_canvas;
|
|
123
138
|
|
|
124
|
-
this.current_rect = new OverlayRectSpec(
|
|
139
|
+
this.current_rect = new OverlayRectSpec(
|
|
140
|
+
{ top: 0, left_col: 0, right_col: 0, height: 0 },
|
|
141
|
+
() => model.getCellWidth(true) * this.getZoom(model).x
|
|
142
|
+
);
|
|
125
143
|
|
|
126
144
|
const self = this;
|
|
127
145
|
const padding = 4;
|
|
@@ -129,18 +147,26 @@ export default class OncoprintMinimapView {
|
|
|
129
147
|
const horizontal_zoom_area_height = 20;
|
|
130
148
|
const window_bar_height = 20;
|
|
131
149
|
|
|
132
|
-
this.handleContextLost =
|
|
150
|
+
this.handleContextLost = function() {
|
|
133
151
|
// catch when context lost and refresh it
|
|
134
152
|
// eg if cell view uses a ton of contexts, then browser clears oldest context,
|
|
135
153
|
// then the minimap would be empty until we refresh the context and rerender
|
|
136
154
|
self.drawOncoprintAndOverlayRect(model, cell_view);
|
|
137
|
-
}
|
|
155
|
+
}.bind(this);
|
|
138
156
|
|
|
139
|
-
this.$canvas[0].addEventListener(
|
|
157
|
+
this.$canvas[0].addEventListener(
|
|
158
|
+
'webglcontextlost',
|
|
159
|
+
this.handleContextLost
|
|
160
|
+
);
|
|
140
161
|
|
|
141
162
|
this.layout_numbers = {
|
|
142
163
|
window_width: padding + width + padding + vertical_zoom_area_width,
|
|
143
|
-
window_height:
|
|
164
|
+
window_height:
|
|
165
|
+
window_bar_height +
|
|
166
|
+
padding +
|
|
167
|
+
height +
|
|
168
|
+
padding +
|
|
169
|
+
horizontal_zoom_area_height,
|
|
144
170
|
vertical_zoom_area_width: vertical_zoom_area_width,
|
|
145
171
|
horizontal_zoom_area_height: horizontal_zoom_area_height,
|
|
146
172
|
padding: padding,
|
|
@@ -149,181 +175,285 @@ export default class OncoprintMinimapView {
|
|
|
149
175
|
canvas_top: window_bar_height + padding,
|
|
150
176
|
};
|
|
151
177
|
|
|
152
|
-
this.$div.css({
|
|
178
|
+
this.$div.css({
|
|
179
|
+
'min-width': this.layout_numbers.window_width,
|
|
153
180
|
'min-height': this.layout_numbers.window_height,
|
|
154
|
-
|
|
181
|
+
outline: 'solid 1px black',
|
|
182
|
+
'background-color': '#ffffff',
|
|
183
|
+
});
|
|
155
184
|
|
|
156
|
-
this.$window_bar = $('<div>')
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
185
|
+
this.$window_bar = $('<div>')
|
|
186
|
+
.css({
|
|
187
|
+
position: 'absolute',
|
|
188
|
+
'min-width': this.layout_numbers.window_width,
|
|
189
|
+
'min-height': this.layout_numbers.window_bar_height,
|
|
190
|
+
'background-color': '#cccccc',
|
|
191
|
+
})
|
|
160
192
|
.appendTo(this.$div);
|
|
161
193
|
|
|
162
|
-
this.$close_btn = $('<div>')
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
194
|
+
this.$close_btn = $('<div>')
|
|
195
|
+
.css({
|
|
196
|
+
position: 'absolute',
|
|
197
|
+
top: 3,
|
|
198
|
+
left: 3,
|
|
199
|
+
'min-width': this.layout_numbers.window_bar_height - 6,
|
|
200
|
+
'min-height': this.layout_numbers.window_bar_height - 6,
|
|
201
|
+
cursor: 'pointer',
|
|
202
|
+
})
|
|
168
203
|
.appendTo(this.$div);
|
|
169
|
-
$('<span>')
|
|
204
|
+
$('<span>')
|
|
205
|
+
.addClass('icon fa fa-times-circle')
|
|
206
|
+
.css('font-size', this.layout_numbers.window_bar_height - 6 + 'px')
|
|
207
|
+
.appendTo(this.$close_btn);
|
|
170
208
|
|
|
171
|
-
this.$close_btn.click(close_callback || function(){});
|
|
209
|
+
this.$close_btn.click(close_callback || function() {});
|
|
172
210
|
|
|
173
211
|
this.$canvas[0].width = width;
|
|
174
212
|
this.$canvas[0].height = height;
|
|
175
|
-
this.$canvas.css({
|
|
213
|
+
this.$canvas.css({
|
|
214
|
+
top: this.layout_numbers.canvas_top,
|
|
215
|
+
left: this.layout_numbers.canvas_left,
|
|
216
|
+
});
|
|
176
217
|
this.$overlay_canvas[0].width = width;
|
|
177
218
|
this.$overlay_canvas[0].height = width;
|
|
178
|
-
this.$overlay_canvas.css({
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
'
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
219
|
+
this.$overlay_canvas.css({
|
|
220
|
+
top: this.layout_numbers.canvas_top,
|
|
221
|
+
left: this.layout_numbers.canvas_left,
|
|
222
|
+
outline: 'solid 1px #444444',
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
this.horizontal_zoom = new OncoprintZoomSlider(this.$div, {
|
|
226
|
+
btn_size: this.layout_numbers.horizontal_zoom_area_height - padding,
|
|
227
|
+
horizontal: true,
|
|
228
|
+
width: width,
|
|
229
|
+
init_val: model.getHorzZoom(),
|
|
230
|
+
left: padding,
|
|
231
|
+
top: this.layout_numbers.canvas_top + height + padding,
|
|
232
|
+
onChange: function(val) {
|
|
233
|
+
horz_zoom_callback(val);
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
this.vertical_zoom = new OncoprintZoomSlider(this.$div, {
|
|
237
|
+
btn_size: this.layout_numbers.vertical_zoom_area_width - padding,
|
|
238
|
+
vertical: true,
|
|
239
|
+
height: height,
|
|
240
|
+
init_val: model.getVertZoom(),
|
|
241
|
+
left: this.layout_numbers.canvas_left + width + padding,
|
|
242
|
+
top: this.layout_numbers.window_bar_height + padding,
|
|
243
|
+
onChange: function(val) {
|
|
244
|
+
vert_zoom_callback(val);
|
|
245
|
+
},
|
|
246
|
+
});
|
|
194
247
|
|
|
195
248
|
(function setUpZoomToFitButton() {
|
|
196
|
-
const btn_height =
|
|
197
|
-
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
249
|
+
const btn_height =
|
|
250
|
+
self.layout_numbers.horizontal_zoom_area_height - padding;
|
|
251
|
+
const btn_width =
|
|
252
|
+
self.layout_numbers.vertical_zoom_area_width - padding;
|
|
253
|
+
const $btn = $('<div>')
|
|
254
|
+
.css({
|
|
255
|
+
position: 'absolute',
|
|
256
|
+
height: btn_height,
|
|
257
|
+
width: btn_width,
|
|
258
|
+
outline: 'solid 1px black',
|
|
259
|
+
left: self.layout_numbers.canvas_left + width + padding,
|
|
260
|
+
top: self.layout_numbers.canvas_top + height + padding,
|
|
261
|
+
cursor: 'pointer',
|
|
262
|
+
})
|
|
263
|
+
.addClass('oncoprint-zoomtofit-btn')
|
|
209
264
|
.appendTo($div);
|
|
210
|
-
$
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
265
|
+
$(`<img src="${zoomToFitIcon}" />`)
|
|
266
|
+
.css({
|
|
267
|
+
height: btn_height - 4,
|
|
268
|
+
width: btn_width - 4,
|
|
269
|
+
'margin-top': -6,
|
|
270
|
+
'margin-left': 2,
|
|
271
|
+
})
|
|
272
|
+
.appendTo($btn);
|
|
273
|
+
$btn.hover(
|
|
274
|
+
function() {
|
|
275
|
+
$(this).css({ 'background-color': '#cccccc' });
|
|
276
|
+
},
|
|
277
|
+
function() {
|
|
278
|
+
$(this).css({ 'background-color': '#ffffff' });
|
|
279
|
+
}
|
|
280
|
+
);
|
|
215
281
|
|
|
216
282
|
zoom_to_fit_callback = zoom_to_fit_callback || function() {};
|
|
217
283
|
$btn.click(zoom_to_fit_callback);
|
|
218
284
|
})();
|
|
219
285
|
this.getWebGLContextAndSetUpMatrices();
|
|
220
286
|
this.setUpShaders();
|
|
221
|
-
this.overlay_ctx = $overlay_canvas[0].getContext(
|
|
287
|
+
this.overlay_ctx = $overlay_canvas[0].getContext('2d');
|
|
222
288
|
|
|
223
289
|
// Set up dragging
|
|
224
290
|
const resize_hit_zone = 5;
|
|
225
|
-
function mouseInRectDragZone(x:number, y:number) {
|
|
226
|
-
return (
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
291
|
+
function mouseInRectDragZone(x: number, y: number) {
|
|
292
|
+
return (
|
|
293
|
+
x >= self.current_rect.left + resize_hit_zone &&
|
|
294
|
+
x <=
|
|
295
|
+
self.current_rect.left +
|
|
296
|
+
self.current_rect.width -
|
|
297
|
+
resize_hit_zone &&
|
|
298
|
+
y >= self.current_rect.top + resize_hit_zone &&
|
|
299
|
+
y <=
|
|
300
|
+
self.current_rect.top +
|
|
301
|
+
self.current_rect.height -
|
|
302
|
+
resize_hit_zone
|
|
303
|
+
);
|
|
230
304
|
}
|
|
231
305
|
|
|
232
|
-
function mouseInsideRectHitZone(x:number, y:number) {
|
|
233
|
-
return (
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
306
|
+
function mouseInsideRectHitZone(x: number, y: number) {
|
|
307
|
+
return (
|
|
308
|
+
x >= self.current_rect.left - resize_hit_zone &&
|
|
309
|
+
x <=
|
|
310
|
+
self.current_rect.left +
|
|
311
|
+
self.current_rect.width +
|
|
312
|
+
resize_hit_zone &&
|
|
313
|
+
y >= self.current_rect.top - resize_hit_zone &&
|
|
314
|
+
y <=
|
|
315
|
+
self.current_rect.top +
|
|
316
|
+
self.current_rect.height +
|
|
317
|
+
resize_hit_zone
|
|
318
|
+
);
|
|
237
319
|
}
|
|
238
320
|
|
|
239
|
-
function mouseInRightHorzResizeZone(x:number, y:number) {
|
|
240
|
-
return
|
|
241
|
-
!
|
|
242
|
-
|
|
243
|
-
(
|
|
321
|
+
function mouseInRightHorzResizeZone(x: number, y: number) {
|
|
322
|
+
return (
|
|
323
|
+
!mouseInTopLeftResizeZone(x, y) &&
|
|
324
|
+
!mouseInTopRightResizeZone(x, y) &&
|
|
325
|
+
!mouseInBottomLeftResizeZone(x, y) &&
|
|
326
|
+
!mouseInBottomRightResizeZone(x, y) &&
|
|
327
|
+
mouseInsideRectHitZone(x, y) &&
|
|
328
|
+
Math.abs(
|
|
329
|
+
x - (self.current_rect.left + self.current_rect.width)
|
|
330
|
+
) < resize_hit_zone
|
|
331
|
+
);
|
|
244
332
|
}
|
|
245
333
|
|
|
246
|
-
function mouseInLeftHorzResizeZone(x:number, y:number) {
|
|
247
|
-
return
|
|
248
|
-
!
|
|
249
|
-
|
|
250
|
-
(
|
|
334
|
+
function mouseInLeftHorzResizeZone(x: number, y: number) {
|
|
335
|
+
return (
|
|
336
|
+
!mouseInTopLeftResizeZone(x, y) &&
|
|
337
|
+
!mouseInTopRightResizeZone(x, y) &&
|
|
338
|
+
!mouseInBottomLeftResizeZone(x, y) &&
|
|
339
|
+
!mouseInBottomRightResizeZone(x, y) &&
|
|
340
|
+
mouseInsideRectHitZone(x, y) &&
|
|
341
|
+
Math.abs(x - self.current_rect.left) < resize_hit_zone
|
|
342
|
+
);
|
|
251
343
|
}
|
|
252
344
|
|
|
253
|
-
function mouseInTopVertResizeZone(x:number, y:number) {
|
|
254
|
-
return
|
|
255
|
-
!
|
|
256
|
-
|
|
257
|
-
(
|
|
345
|
+
function mouseInTopVertResizeZone(x: number, y: number) {
|
|
346
|
+
return (
|
|
347
|
+
!mouseInTopLeftResizeZone(x, y) &&
|
|
348
|
+
!mouseInTopRightResizeZone(x, y) &&
|
|
349
|
+
!mouseInBottomLeftResizeZone(x, y) &&
|
|
350
|
+
!mouseInBottomRightResizeZone(x, y) &&
|
|
351
|
+
mouseInsideRectHitZone(x, y) &&
|
|
352
|
+
Math.abs(y - self.current_rect.top) < resize_hit_zone
|
|
353
|
+
);
|
|
258
354
|
}
|
|
259
355
|
|
|
260
|
-
function mouseInBottomVertResizeZone(x:number, y:number) {
|
|
261
|
-
return
|
|
262
|
-
!
|
|
263
|
-
|
|
264
|
-
(
|
|
356
|
+
function mouseInBottomVertResizeZone(x: number, y: number) {
|
|
357
|
+
return (
|
|
358
|
+
!mouseInTopLeftResizeZone(x, y) &&
|
|
359
|
+
!mouseInTopRightResizeZone(x, y) &&
|
|
360
|
+
!mouseInBottomLeftResizeZone(x, y) &&
|
|
361
|
+
!mouseInBottomRightResizeZone(x, y) &&
|
|
362
|
+
mouseInsideRectHitZone(x, y) &&
|
|
363
|
+
Math.abs(
|
|
364
|
+
y - (self.current_rect.top + self.current_rect.height)
|
|
365
|
+
) < resize_hit_zone
|
|
366
|
+
);
|
|
265
367
|
}
|
|
266
368
|
|
|
267
|
-
function mouseInTopLeftResizeZone(x:number, y:number) {
|
|
268
|
-
return (
|
|
269
|
-
|
|
369
|
+
function mouseInTopLeftResizeZone(x: number, y: number) {
|
|
370
|
+
return (
|
|
371
|
+
Math.abs(y - self.current_rect.top) < resize_hit_zone &&
|
|
372
|
+
Math.abs(x - self.current_rect.left) < resize_hit_zone
|
|
373
|
+
);
|
|
270
374
|
}
|
|
271
375
|
|
|
272
|
-
function mouseInBottomLeftResizeZone(x:number, y:number) {
|
|
273
|
-
return (
|
|
274
|
-
|
|
376
|
+
function mouseInBottomLeftResizeZone(x: number, y: number) {
|
|
377
|
+
return (
|
|
378
|
+
Math.abs(
|
|
379
|
+
y - (self.current_rect.top + self.current_rect.height)
|
|
380
|
+
) < resize_hit_zone &&
|
|
381
|
+
Math.abs(x - self.current_rect.left) < resize_hit_zone
|
|
382
|
+
);
|
|
275
383
|
}
|
|
276
384
|
|
|
277
|
-
function mouseInTopRightResizeZone(x:number, y:number) {
|
|
278
|
-
return (
|
|
279
|
-
|
|
385
|
+
function mouseInTopRightResizeZone(x: number, y: number) {
|
|
386
|
+
return (
|
|
387
|
+
Math.abs(y - self.current_rect.top) < resize_hit_zone &&
|
|
388
|
+
Math.abs(
|
|
389
|
+
x - (self.current_rect.left + self.current_rect.width)
|
|
390
|
+
) < resize_hit_zone
|
|
391
|
+
);
|
|
280
392
|
}
|
|
281
393
|
|
|
282
|
-
function mouseInBottomRightResizeZone(x:number, y:number) {
|
|
283
|
-
return (
|
|
284
|
-
|
|
394
|
+
function mouseInBottomRightResizeZone(x: number, y: number) {
|
|
395
|
+
return (
|
|
396
|
+
Math.abs(
|
|
397
|
+
y - (self.current_rect.top + self.current_rect.height)
|
|
398
|
+
) < resize_hit_zone &&
|
|
399
|
+
Math.abs(
|
|
400
|
+
x - (self.current_rect.left + self.current_rect.width)
|
|
401
|
+
) < resize_hit_zone
|
|
402
|
+
);
|
|
285
403
|
}
|
|
286
404
|
|
|
287
|
-
function updateRectResizeHoverLocation(x?:number, y?:number) {
|
|
288
|
-
if (typeof x ===
|
|
405
|
+
function updateRectResizeHoverLocation(x?: number, y?: number) {
|
|
406
|
+
if (typeof x === 'undefined') {
|
|
289
407
|
self.resize_hover = false;
|
|
290
408
|
} else {
|
|
291
409
|
if (mouseInRightHorzResizeZone(x, y)) {
|
|
292
|
-
self.resize_hover =
|
|
410
|
+
self.resize_hover = 'r';
|
|
293
411
|
} else if (mouseInLeftHorzResizeZone(x, y)) {
|
|
294
|
-
self.resize_hover =
|
|
412
|
+
self.resize_hover = 'l';
|
|
295
413
|
} else if (mouseInTopVertResizeZone(x, y)) {
|
|
296
|
-
self.resize_hover =
|
|
414
|
+
self.resize_hover = 't';
|
|
297
415
|
} else if (mouseInBottomVertResizeZone(x, y)) {
|
|
298
|
-
self.resize_hover =
|
|
416
|
+
self.resize_hover = 'b';
|
|
299
417
|
} else if (mouseInTopLeftResizeZone(x, y)) {
|
|
300
|
-
self.resize_hover =
|
|
418
|
+
self.resize_hover = 'tl';
|
|
301
419
|
} else if (mouseInBottomRightResizeZone(x, y)) {
|
|
302
|
-
self.resize_hover =
|
|
420
|
+
self.resize_hover = 'br';
|
|
303
421
|
} else if (mouseInBottomLeftResizeZone(x, y)) {
|
|
304
|
-
self.resize_hover =
|
|
422
|
+
self.resize_hover = 'bl';
|
|
305
423
|
} else if (mouseInTopRightResizeZone(x, y)) {
|
|
306
|
-
self.resize_hover =
|
|
424
|
+
self.resize_hover = 'tr';
|
|
307
425
|
} else {
|
|
308
426
|
self.resize_hover = false;
|
|
309
427
|
}
|
|
310
428
|
}
|
|
311
429
|
}
|
|
312
430
|
|
|
313
|
-
function updateCSSCursor(x?:number, y?:number) {
|
|
431
|
+
function updateCSSCursor(x?: number, y?: number) {
|
|
314
432
|
let cursor_val;
|
|
315
|
-
if (typeof x ===
|
|
433
|
+
if (typeof x === 'undefined') {
|
|
316
434
|
cursor_val = 'auto';
|
|
317
435
|
} else {
|
|
318
436
|
if (mouseInRectDragZone(x, y)) {
|
|
319
437
|
cursor_val = 'move';
|
|
320
|
-
} else if (
|
|
438
|
+
} else if (
|
|
439
|
+
mouseInRightHorzResizeZone(x, y) ||
|
|
440
|
+
mouseInLeftHorzResizeZone(x, y)
|
|
441
|
+
) {
|
|
321
442
|
cursor_val = 'ew-resize';
|
|
322
|
-
} else if (
|
|
443
|
+
} else if (
|
|
444
|
+
mouseInTopVertResizeZone(x, y) ||
|
|
445
|
+
mouseInBottomVertResizeZone(x, y)
|
|
446
|
+
) {
|
|
323
447
|
cursor_val = 'ns-resize';
|
|
324
|
-
} else if (
|
|
448
|
+
} else if (
|
|
449
|
+
mouseInTopLeftResizeZone(x, y) ||
|
|
450
|
+
mouseInBottomRightResizeZone(x, y)
|
|
451
|
+
) {
|
|
325
452
|
cursor_val = 'nwse-resize';
|
|
326
|
-
} else if (
|
|
453
|
+
} else if (
|
|
454
|
+
mouseInBottomLeftResizeZone(x, y) ||
|
|
455
|
+
mouseInTopRightResizeZone(x, y)
|
|
456
|
+
) {
|
|
327
457
|
cursor_val = 'nesw-resize';
|
|
328
458
|
} else {
|
|
329
459
|
cursor_val = 'auto';
|
|
@@ -332,7 +462,11 @@ export default class OncoprintMinimapView {
|
|
|
332
462
|
$div.css('cursor', cursor_val);
|
|
333
463
|
}
|
|
334
464
|
|
|
335
|
-
function getCanvasMouse(
|
|
465
|
+
function getCanvasMouse(
|
|
466
|
+
view: OncoprintMinimapView,
|
|
467
|
+
div_mouse_x: number,
|
|
468
|
+
div_mouse_y: number
|
|
469
|
+
) {
|
|
336
470
|
const canv_top = parseInt(view.$canvas[0].style.top, 10);
|
|
337
471
|
const canv_left = parseInt(view.$canvas[0].style.left, 10);
|
|
338
472
|
const canv_width = parseInt(view.$canvas[0].width as any, 10);
|
|
@@ -341,28 +475,44 @@ export default class OncoprintMinimapView {
|
|
|
341
475
|
const mouse_x = div_mouse_x - canv_left;
|
|
342
476
|
const mouse_y = div_mouse_y - canv_top;
|
|
343
477
|
|
|
344
|
-
const outside =
|
|
478
|
+
const outside =
|
|
479
|
+
mouse_x < 0 ||
|
|
480
|
+
mouse_x >= canv_width ||
|
|
481
|
+
mouse_y < 0 ||
|
|
482
|
+
mouse_y >= canv_height;
|
|
345
483
|
|
|
346
|
-
return {
|
|
347
|
-
'mouse_y': mouse_y,
|
|
348
|
-
'outside': outside};
|
|
484
|
+
return { mouse_x: mouse_x, mouse_y: mouse_y, outside: outside };
|
|
349
485
|
}
|
|
350
486
|
|
|
351
487
|
let dragging = false;
|
|
352
|
-
let drag_type:
|
|
488
|
+
let drag_type:
|
|
489
|
+
| 'move'
|
|
490
|
+
| 'resize_r'
|
|
491
|
+
| 'resize_l'
|
|
492
|
+
| 'resize_b'
|
|
493
|
+
| 'resize_t'
|
|
494
|
+
| 'resize_tr'
|
|
495
|
+
| 'resize_br'
|
|
496
|
+
| 'resize_tl'
|
|
497
|
+
| 'resize_bl'
|
|
498
|
+
| false = false;
|
|
353
499
|
let drag_start_col = -1;
|
|
354
500
|
let drag_start_vert_scroll = -1;
|
|
355
501
|
let drag_start_x = -1;
|
|
356
502
|
let drag_start_y = -1;
|
|
357
503
|
let drag_start_vert_zoom = -1;
|
|
358
504
|
let y_ratio = -1;
|
|
359
|
-
let drag_start_rect:OverlayRectSpec;
|
|
505
|
+
let drag_start_rect: OverlayRectSpec;
|
|
360
506
|
|
|
361
|
-
$(document).on(
|
|
507
|
+
$(document).on('mousedown', function(evt) {
|
|
362
508
|
const offset = self.$div.offset();
|
|
363
509
|
const overlay_mouse_x = evt.pageX - offset.left;
|
|
364
510
|
const overlay_mouse_y = evt.pageY - offset.top;
|
|
365
|
-
const mouse = getCanvasMouse(
|
|
511
|
+
const mouse = getCanvasMouse(
|
|
512
|
+
self,
|
|
513
|
+
overlay_mouse_x,
|
|
514
|
+
overlay_mouse_y
|
|
515
|
+
);
|
|
366
516
|
|
|
367
517
|
if (!mouse.outside) {
|
|
368
518
|
const mouse_x = mouse.mouse_x;
|
|
@@ -370,190 +520,267 @@ export default class OncoprintMinimapView {
|
|
|
370
520
|
dragging = false;
|
|
371
521
|
drag_type = false;
|
|
372
522
|
|
|
373
|
-
|
|
374
|
-
|
|
523
|
+
y_ratio =
|
|
524
|
+
model.getOncoprintHeight() /
|
|
525
|
+
parseInt(self.$canvas[0].height as any, 10);
|
|
375
526
|
if (mouseInRectDragZone(mouse_x, mouse_y)) {
|
|
376
|
-
drag_type =
|
|
527
|
+
drag_type = 'move';
|
|
377
528
|
} else if (mouseInRightHorzResizeZone(mouse_x, mouse_y)) {
|
|
378
|
-
drag_type =
|
|
529
|
+
drag_type = 'resize_r';
|
|
379
530
|
} else if (mouseInLeftHorzResizeZone(mouse_x, mouse_y)) {
|
|
380
|
-
drag_type =
|
|
531
|
+
drag_type = 'resize_l';
|
|
381
532
|
} else if (mouseInTopVertResizeZone(mouse_x, mouse_y)) {
|
|
382
|
-
drag_type =
|
|
533
|
+
drag_type = 'resize_t';
|
|
383
534
|
} else if (mouseInBottomVertResizeZone(mouse_x, mouse_y)) {
|
|
384
|
-
drag_type =
|
|
535
|
+
drag_type = 'resize_b';
|
|
385
536
|
} else if (mouseInTopRightResizeZone(mouse_x, mouse_y)) {
|
|
386
|
-
drag_type =
|
|
537
|
+
drag_type = 'resize_tr';
|
|
387
538
|
} else if (mouseInBottomRightResizeZone(mouse_x, mouse_y)) {
|
|
388
|
-
drag_type =
|
|
539
|
+
drag_type = 'resize_br';
|
|
389
540
|
} else if (mouseInTopLeftResizeZone(mouse_x, mouse_y)) {
|
|
390
|
-
drag_type =
|
|
541
|
+
drag_type = 'resize_tl';
|
|
391
542
|
} else if (mouseInBottomLeftResizeZone(mouse_x, mouse_y)) {
|
|
392
|
-
drag_type =
|
|
543
|
+
drag_type = 'resize_bl';
|
|
393
544
|
}
|
|
394
545
|
if (drag_type !== false) {
|
|
395
546
|
dragging = true;
|
|
396
547
|
drag_start_x = mouse_x;
|
|
397
548
|
drag_start_y = mouse_y;
|
|
398
|
-
drag_start_col = model.getClosestColumnIndexToLeft(
|
|
549
|
+
drag_start_col = model.getClosestColumnIndexToLeft(
|
|
550
|
+
model.getHorzScroll(),
|
|
551
|
+
true
|
|
552
|
+
);
|
|
399
553
|
drag_start_vert_scroll = model.getVertScroll();
|
|
400
554
|
drag_start_vert_zoom = model.getVertZoom();
|
|
401
555
|
drag_start_rect = self.current_rect.clone();
|
|
402
556
|
}
|
|
403
557
|
}
|
|
404
558
|
});
|
|
405
|
-
$(document).on(
|
|
559
|
+
$(document).on('mousemove', function(evt) {
|
|
406
560
|
const offset = self.$div.offset();
|
|
407
561
|
const overlay_mouse_x = evt.pageX - offset.left;
|
|
408
562
|
const overlay_mouse_y = evt.pageY - offset.top;
|
|
409
|
-
const mouse = getCanvasMouse(
|
|
563
|
+
const mouse = getCanvasMouse(
|
|
564
|
+
self,
|
|
565
|
+
overlay_mouse_x,
|
|
566
|
+
overlay_mouse_y
|
|
567
|
+
);
|
|
410
568
|
const mouse_x = mouse.mouse_x;
|
|
411
569
|
const mouse_y = mouse.mouse_y;
|
|
412
570
|
let zoom = self.getZoom(model);
|
|
413
|
-
let cell_width = model.getCellWidth(true)*zoom.x;
|
|
571
|
+
let cell_width = model.getCellWidth(true) * zoom.x;
|
|
414
572
|
if (dragging) {
|
|
415
573
|
evt.preventDefault();
|
|
416
|
-
let delta_col =
|
|
574
|
+
let delta_col =
|
|
575
|
+
Math.floor(mouse_x / cell_width) -
|
|
576
|
+
Math.floor(drag_start_x / cell_width);
|
|
417
577
|
let delta_y = mouse_y - drag_start_y;
|
|
418
|
-
if (drag_type ===
|
|
578
|
+
if (drag_type === 'move') {
|
|
419
579
|
const delta_y_scroll = delta_y * y_ratio;
|
|
420
|
-
drag_callback(
|
|
580
|
+
drag_callback(
|
|
581
|
+
self.colToLeft(
|
|
582
|
+
model,
|
|
583
|
+
clamp(
|
|
584
|
+
drag_start_col + delta_col,
|
|
585
|
+
0,
|
|
586
|
+
model.getIdOrder().length - 1
|
|
587
|
+
)
|
|
588
|
+
),
|
|
589
|
+
drag_start_vert_scroll + delta_y_scroll
|
|
590
|
+
);
|
|
421
591
|
} else {
|
|
422
|
-
let render_rect:OverlayRectParams;
|
|
592
|
+
let render_rect: OverlayRectParams;
|
|
423
593
|
zoom = self.getZoom(model);
|
|
424
594
|
const max_num_cols = model.getIdOrder().length;
|
|
425
|
-
const min_num_cols = Math.ceil(
|
|
595
|
+
const min_num_cols = Math.ceil(
|
|
596
|
+
cell_view.getVisibleAreaWidth() /
|
|
597
|
+
(model.getCellWidth(true) +
|
|
598
|
+
model.getCellPadding(true, true))
|
|
599
|
+
);
|
|
426
600
|
const max_height = model.getOncoprintHeight(true) * zoom.y;
|
|
427
|
-
const min_height =
|
|
601
|
+
const min_height =
|
|
602
|
+
cell_view.getVisibleAreaHeight(model) * zoom.y;
|
|
428
603
|
const drag_start_right_col = drag_start_rect.right_col;
|
|
429
|
-
const drag_start_bottom =
|
|
430
|
-
|
|
604
|
+
const drag_start_bottom =
|
|
605
|
+
drag_start_rect.top + drag_start_rect.height;
|
|
606
|
+
if (drag_type === 'resize_r') {
|
|
431
607
|
// Width must be valid
|
|
432
|
-
delta_col = clamp(
|
|
608
|
+
delta_col = clamp(
|
|
609
|
+
delta_col,
|
|
433
610
|
min_num_cols - drag_start_rect.num_cols,
|
|
434
|
-
max_num_cols - drag_start_rect.num_cols
|
|
611
|
+
max_num_cols - drag_start_rect.num_cols
|
|
612
|
+
);
|
|
435
613
|
// Right must be valid
|
|
436
|
-
delta_col = Math.min(
|
|
614
|
+
delta_col = Math.min(
|
|
615
|
+
delta_col,
|
|
616
|
+
max_num_cols - drag_start_right_col
|
|
617
|
+
);
|
|
437
618
|
render_rect = {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
619
|
+
top: drag_start_rect.top,
|
|
620
|
+
left_col: drag_start_rect.left_col,
|
|
621
|
+
right_col: drag_start_rect.right_col + delta_col,
|
|
622
|
+
height: drag_start_rect.height,
|
|
442
623
|
};
|
|
443
|
-
} else if (drag_type ===
|
|
624
|
+
} else if (drag_type === 'resize_l') {
|
|
444
625
|
// Width must be valid
|
|
445
|
-
delta_col = clamp(
|
|
626
|
+
delta_col = clamp(
|
|
627
|
+
delta_col,
|
|
446
628
|
drag_start_rect.num_cols - max_num_cols,
|
|
447
|
-
drag_start_rect.num_cols - min_num_cols
|
|
629
|
+
drag_start_rect.num_cols - min_num_cols
|
|
630
|
+
);
|
|
448
631
|
// Left must be valid
|
|
449
|
-
delta_col = Math.max(
|
|
632
|
+
delta_col = Math.max(
|
|
633
|
+
delta_col,
|
|
634
|
+
-drag_start_rect.left_col
|
|
635
|
+
);
|
|
450
636
|
render_rect = {
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
637
|
+
top: drag_start_rect.top,
|
|
638
|
+
left_col: drag_start_rect.left_col + delta_col,
|
|
639
|
+
right_col: drag_start_rect.right_col,
|
|
640
|
+
height: drag_start_rect.height,
|
|
455
641
|
};
|
|
456
|
-
} else if (drag_type ===
|
|
642
|
+
} else if (drag_type === 'resize_t') {
|
|
457
643
|
// Height must be valid
|
|
458
|
-
delta_y = clamp(
|
|
644
|
+
delta_y = clamp(
|
|
645
|
+
delta_y,
|
|
459
646
|
drag_start_rect.height - max_height,
|
|
460
|
-
drag_start_rect.height - min_height
|
|
647
|
+
drag_start_rect.height - min_height
|
|
648
|
+
);
|
|
461
649
|
// Top must be valid
|
|
462
650
|
delta_y = Math.max(delta_y, -drag_start_rect.top);
|
|
463
651
|
render_rect = {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
652
|
+
top: drag_start_rect.top + delta_y,
|
|
653
|
+
left_col: drag_start_rect.left_col,
|
|
654
|
+
right_col: drag_start_rect.right_col,
|
|
655
|
+
height: drag_start_rect.height - delta_y,
|
|
468
656
|
};
|
|
469
|
-
} else if (drag_type ===
|
|
657
|
+
} else if (drag_type === 'resize_b') {
|
|
470
658
|
// Height must be valid
|
|
471
|
-
delta_y = clamp(
|
|
659
|
+
delta_y = clamp(
|
|
660
|
+
delta_y,
|
|
472
661
|
min_height - drag_start_rect.height,
|
|
473
|
-
max_height - drag_start_rect.height
|
|
662
|
+
max_height - drag_start_rect.height
|
|
663
|
+
);
|
|
474
664
|
// Bottom must be valid
|
|
475
|
-
delta_y = Math.min(
|
|
665
|
+
delta_y = Math.min(
|
|
666
|
+
delta_y,
|
|
667
|
+
max_height - drag_start_bottom
|
|
668
|
+
);
|
|
476
669
|
render_rect = {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
670
|
+
top: drag_start_rect.top,
|
|
671
|
+
left_col: drag_start_rect.left_col,
|
|
672
|
+
right_col: drag_start_rect.right_col,
|
|
673
|
+
height: drag_start_rect.height + delta_y,
|
|
481
674
|
};
|
|
482
|
-
} else if (drag_type ===
|
|
675
|
+
} else if (drag_type === 'resize_tr') {
|
|
483
676
|
// Width must be valid
|
|
484
|
-
delta_col = clamp(
|
|
677
|
+
delta_col = clamp(
|
|
678
|
+
delta_col,
|
|
485
679
|
min_num_cols - drag_start_rect.num_cols,
|
|
486
|
-
max_num_cols - drag_start_rect.num_cols
|
|
680
|
+
max_num_cols - drag_start_rect.num_cols
|
|
681
|
+
);
|
|
487
682
|
// Right must be valid
|
|
488
|
-
delta_col = Math.min(
|
|
683
|
+
delta_col = Math.min(
|
|
684
|
+
delta_col,
|
|
685
|
+
max_num_cols - drag_start_right_col
|
|
686
|
+
);
|
|
489
687
|
// Height must be valid
|
|
490
|
-
delta_y = clamp(
|
|
688
|
+
delta_y = clamp(
|
|
689
|
+
delta_y,
|
|
491
690
|
drag_start_rect.height - max_height,
|
|
492
|
-
drag_start_rect.height - min_height
|
|
691
|
+
drag_start_rect.height - min_height
|
|
692
|
+
);
|
|
493
693
|
// Top must be valid
|
|
494
694
|
delta_y = Math.max(delta_y, -drag_start_rect.top);
|
|
495
695
|
render_rect = {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
696
|
+
top: drag_start_rect.top + delta_y,
|
|
697
|
+
left_col: drag_start_rect.left_col,
|
|
698
|
+
right_col: drag_start_rect.right_col + delta_col,
|
|
699
|
+
height: drag_start_rect.height - delta_y,
|
|
500
700
|
};
|
|
501
|
-
} else if (drag_type ===
|
|
701
|
+
} else if (drag_type === 'resize_tl') {
|
|
502
702
|
// Width must be valid
|
|
503
|
-
delta_col = clamp(
|
|
703
|
+
delta_col = clamp(
|
|
704
|
+
delta_col,
|
|
504
705
|
drag_start_rect.num_cols - max_num_cols,
|
|
505
|
-
drag_start_rect.num_cols - min_num_cols
|
|
706
|
+
drag_start_rect.num_cols - min_num_cols
|
|
707
|
+
);
|
|
506
708
|
// Left must be valid
|
|
507
|
-
delta_col = Math.max(
|
|
709
|
+
delta_col = Math.max(
|
|
710
|
+
delta_col,
|
|
711
|
+
-drag_start_rect.left_col
|
|
712
|
+
);
|
|
508
713
|
// Height must be valid
|
|
509
|
-
delta_y = clamp(
|
|
714
|
+
delta_y = clamp(
|
|
715
|
+
delta_y,
|
|
510
716
|
drag_start_rect.height - max_height,
|
|
511
|
-
drag_start_rect.height - min_height
|
|
717
|
+
drag_start_rect.height - min_height
|
|
718
|
+
);
|
|
512
719
|
// Top must be valid
|
|
513
720
|
delta_y = Math.max(delta_y, -drag_start_rect.top);
|
|
514
721
|
render_rect = {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
722
|
+
top: drag_start_rect.top + delta_y,
|
|
723
|
+
left_col: drag_start_rect.left_col + delta_col,
|
|
724
|
+
right_col: drag_start_rect.right_col,
|
|
725
|
+
height: drag_start_rect.height - delta_y,
|
|
519
726
|
};
|
|
520
|
-
} else if (drag_type ===
|
|
727
|
+
} else if (drag_type === 'resize_br') {
|
|
521
728
|
// Height must be valid
|
|
522
|
-
delta_y = clamp(
|
|
729
|
+
delta_y = clamp(
|
|
730
|
+
delta_y,
|
|
523
731
|
min_height - drag_start_rect.height,
|
|
524
|
-
max_height - drag_start_rect.height
|
|
732
|
+
max_height - drag_start_rect.height
|
|
733
|
+
);
|
|
525
734
|
// Bottom must be valid
|
|
526
|
-
delta_y = Math.min(
|
|
735
|
+
delta_y = Math.min(
|
|
736
|
+
delta_y,
|
|
737
|
+
max_height - drag_start_bottom
|
|
738
|
+
);
|
|
527
739
|
// Width must be valid
|
|
528
|
-
delta_col = clamp(
|
|
740
|
+
delta_col = clamp(
|
|
741
|
+
delta_col,
|
|
529
742
|
min_num_cols - drag_start_rect.num_cols,
|
|
530
|
-
max_num_cols - drag_start_rect.num_cols
|
|
743
|
+
max_num_cols - drag_start_rect.num_cols
|
|
744
|
+
);
|
|
531
745
|
// Right must be valid
|
|
532
|
-
delta_col = Math.min(
|
|
746
|
+
delta_col = Math.min(
|
|
747
|
+
delta_col,
|
|
748
|
+
max_num_cols - drag_start_right_col
|
|
749
|
+
);
|
|
533
750
|
render_rect = {
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
751
|
+
top: drag_start_rect.top,
|
|
752
|
+
left_col: drag_start_rect.left_col,
|
|
753
|
+
right_col: drag_start_rect.right_col + delta_col,
|
|
754
|
+
height: drag_start_rect.height + delta_y,
|
|
538
755
|
};
|
|
539
|
-
} else if (drag_type ===
|
|
756
|
+
} else if (drag_type === 'resize_bl') {
|
|
540
757
|
// Height must be valid
|
|
541
|
-
delta_y = clamp(
|
|
758
|
+
delta_y = clamp(
|
|
759
|
+
delta_y,
|
|
542
760
|
min_height - drag_start_rect.height,
|
|
543
|
-
max_height - drag_start_rect.height
|
|
761
|
+
max_height - drag_start_rect.height
|
|
762
|
+
);
|
|
544
763
|
// Bottom must be valid
|
|
545
|
-
delta_y = Math.min(
|
|
764
|
+
delta_y = Math.min(
|
|
765
|
+
delta_y,
|
|
766
|
+
max_height - drag_start_bottom
|
|
767
|
+
);
|
|
546
768
|
// Width must be valid
|
|
547
|
-
delta_col = clamp(
|
|
769
|
+
delta_col = clamp(
|
|
770
|
+
delta_col,
|
|
548
771
|
drag_start_rect.num_cols - max_num_cols,
|
|
549
|
-
drag_start_rect.num_cols - min_num_cols
|
|
772
|
+
drag_start_rect.num_cols - min_num_cols
|
|
773
|
+
);
|
|
550
774
|
// Left must be valid
|
|
551
|
-
delta_col = Math.max(
|
|
775
|
+
delta_col = Math.max(
|
|
776
|
+
delta_col,
|
|
777
|
+
-drag_start_rect.left_col
|
|
778
|
+
);
|
|
552
779
|
render_rect = {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
780
|
+
top: drag_start_rect.top,
|
|
781
|
+
left_col: drag_start_rect.left_col + delta_col,
|
|
782
|
+
right_col: drag_start_rect.right_col,
|
|
783
|
+
height: drag_start_rect.height + delta_y,
|
|
557
784
|
};
|
|
558
785
|
}
|
|
559
786
|
self.current_rect.setParams(render_rect);
|
|
@@ -573,13 +800,28 @@ export default class OncoprintMinimapView {
|
|
|
573
800
|
|
|
574
801
|
function endDrag() {
|
|
575
802
|
if (dragging) {
|
|
576
|
-
if (
|
|
577
|
-
|
|
803
|
+
if (
|
|
804
|
+
[
|
|
805
|
+
'resize_t',
|
|
806
|
+
'resize_b',
|
|
807
|
+
'resize_l',
|
|
808
|
+
'resize_r',
|
|
809
|
+
'resize_tl',
|
|
810
|
+
'resize_tr',
|
|
811
|
+
'resize_bl',
|
|
812
|
+
'resize_br',
|
|
813
|
+
].indexOf(drag_type as any) > -1
|
|
814
|
+
) {
|
|
578
815
|
viewport_callback({
|
|
579
816
|
left_col: self.current_rect.left_col,
|
|
580
|
-
scroll_y_proportion:
|
|
817
|
+
scroll_y_proportion:
|
|
818
|
+
self.current_rect.top /
|
|
819
|
+
parseInt(self.$canvas[0].height as any, 10),
|
|
581
820
|
right_col: self.current_rect.right_col,
|
|
582
|
-
zoom_y:
|
|
821
|
+
zoom_y:
|
|
822
|
+
(drag_start_rect.height /
|
|
823
|
+
self.current_rect.height) *
|
|
824
|
+
drag_start_vert_zoom,
|
|
583
825
|
});
|
|
584
826
|
}
|
|
585
827
|
dragging = false;
|
|
@@ -587,12 +829,16 @@ export default class OncoprintMinimapView {
|
|
|
587
829
|
}
|
|
588
830
|
}
|
|
589
831
|
|
|
590
|
-
$(document).on(
|
|
832
|
+
$(document).on('mouseup', function(evt) {
|
|
591
833
|
const offset = self.$div.offset();
|
|
592
834
|
const overlay_mouse_x = evt.pageX - offset.left;
|
|
593
835
|
const overlay_mouse_y = evt.pageY - offset.top;
|
|
594
836
|
endDrag();
|
|
595
|
-
const mouse = getCanvasMouse(
|
|
837
|
+
const mouse = getCanvasMouse(
|
|
838
|
+
self,
|
|
839
|
+
overlay_mouse_x,
|
|
840
|
+
overlay_mouse_y
|
|
841
|
+
);
|
|
596
842
|
if (!mouse.outside) {
|
|
597
843
|
let mouse_x = mouse.mouse_x;
|
|
598
844
|
let mouse_y = mouse.mouse_y;
|
|
@@ -610,32 +856,38 @@ export default class OncoprintMinimapView {
|
|
|
610
856
|
let start_mouse_y = 0;
|
|
611
857
|
let start_left = 0;
|
|
612
858
|
let start_top = 0;
|
|
613
|
-
function handleDrag(evt:MouseMoveEvent) {
|
|
859
|
+
function handleDrag(evt: MouseMoveEvent) {
|
|
614
860
|
evt.preventDefault();
|
|
615
861
|
const delta_mouse_x = evt.pageX - start_mouse_x;
|
|
616
862
|
const delta_mouse_y = evt.pageY - start_mouse_y;
|
|
617
|
-
self.setWindowPosition(
|
|
863
|
+
self.setWindowPosition(
|
|
864
|
+
start_left + delta_mouse_x,
|
|
865
|
+
start_top + delta_mouse_y
|
|
866
|
+
);
|
|
618
867
|
}
|
|
619
|
-
self.$window_bar.hover(
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
868
|
+
self.$window_bar.hover(
|
|
869
|
+
function() {
|
|
870
|
+
$(this).css({ cursor: 'move' });
|
|
871
|
+
},
|
|
872
|
+
function() {
|
|
873
|
+
$(this).css({ cursor: 'auto' });
|
|
874
|
+
}
|
|
875
|
+
);
|
|
624
876
|
|
|
625
|
-
self.$window_bar.on(
|
|
877
|
+
self.$window_bar.on('mousedown', function(evt) {
|
|
626
878
|
start_mouse_x = evt.pageX;
|
|
627
879
|
start_mouse_y = evt.pageY;
|
|
628
880
|
start_left = parseInt(self.$div.css('left'), 10);
|
|
629
881
|
start_top = parseInt(self.$div.css('top'), 10);
|
|
630
|
-
$(document).on(
|
|
882
|
+
$(document).on('mousemove', handleDrag);
|
|
631
883
|
});
|
|
632
|
-
$(document).on(
|
|
633
|
-
$(document).off(
|
|
884
|
+
$(document).on('mouseup click', function() {
|
|
885
|
+
$(document).off('mousemove', handleDrag);
|
|
634
886
|
});
|
|
635
887
|
})();
|
|
636
888
|
}
|
|
637
889
|
|
|
638
|
-
private colToLeft(model:OncoprintModel, colIndex:number) {
|
|
890
|
+
private colToLeft(model: OncoprintModel, colIndex: number) {
|
|
639
891
|
return model.getZoomedColumnLeft(model.getIdOrder()[colIndex]);
|
|
640
892
|
}
|
|
641
893
|
|
|
@@ -645,20 +897,29 @@ export default class OncoprintMinimapView {
|
|
|
645
897
|
|
|
646
898
|
private getNewCanvas() {
|
|
647
899
|
const old_canvas = this.$canvas[0];
|
|
648
|
-
old_canvas.removeEventListener(
|
|
900
|
+
old_canvas.removeEventListener(
|
|
901
|
+
'webglcontextlost',
|
|
902
|
+
this.handleContextLost
|
|
903
|
+
);
|
|
649
904
|
const new_canvas = old_canvas.cloneNode();
|
|
650
|
-
new_canvas.addEventListener(
|
|
905
|
+
new_canvas.addEventListener('webglcontextlost', this.handleContextLost);
|
|
651
906
|
const parent_node = old_canvas.parentNode;
|
|
652
907
|
parent_node.removeChild(old_canvas);
|
|
653
908
|
parent_node.insertBefore(new_canvas, this.$overlay_canvas[0]);
|
|
654
909
|
this.$canvas = $(new_canvas) as JQuery<HTMLCanvasElement>;
|
|
655
910
|
this.ctx = null;
|
|
911
|
+
this.ext = null;
|
|
656
912
|
}
|
|
657
913
|
|
|
658
914
|
private getWebGLCanvasContext() {
|
|
659
915
|
try {
|
|
660
916
|
const canvas = this.$canvas[0];
|
|
661
|
-
const ctx =
|
|
917
|
+
const ctx =
|
|
918
|
+
this.ctx ||
|
|
919
|
+
(canvas.getContext('experimental-webgl', {
|
|
920
|
+
alpha: false,
|
|
921
|
+
antialias: true,
|
|
922
|
+
}) as OncoprintWebGLContext);
|
|
662
923
|
ctx.clearColor(1.0, 1.0, 1.0, 1.0);
|
|
663
924
|
ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT);
|
|
664
925
|
ctx.viewportWidth = canvas.width;
|
|
@@ -677,7 +938,7 @@ export default class OncoprintMinimapView {
|
|
|
677
938
|
}
|
|
678
939
|
|
|
679
940
|
private ensureWebGLContext() {
|
|
680
|
-
for (let i=0; i<5; i++) {
|
|
941
|
+
for (let i = 0; i < 5; i++) {
|
|
681
942
|
if (!this.ctx || this.ctx.isContextLost()) {
|
|
682
943
|
// have to get a new canvas when context is lost by browser
|
|
683
944
|
this.getNewCanvas();
|
|
@@ -688,37 +949,51 @@ export default class OncoprintMinimapView {
|
|
|
688
949
|
}
|
|
689
950
|
}
|
|
690
951
|
if (!this.ctx || this.ctx.isContextLost()) {
|
|
691
|
-
throw new Error(
|
|
952
|
+
throw new Error(
|
|
953
|
+
'Unable to get WebGL context for Oncoprint Minimap'
|
|
954
|
+
);
|
|
692
955
|
}
|
|
693
956
|
}
|
|
694
957
|
|
|
695
|
-
private createShaderProgram(
|
|
958
|
+
private createShaderProgram(
|
|
959
|
+
vertex_shader: WebGLShader,
|
|
960
|
+
fragment_shader: WebGLShader
|
|
961
|
+
) {
|
|
696
962
|
const program = this.ctx.createProgram();
|
|
697
963
|
this.ctx.attachShader(program, vertex_shader);
|
|
698
964
|
this.ctx.attachShader(program, fragment_shader);
|
|
699
965
|
|
|
700
966
|
this.ctx.linkProgram(program);
|
|
701
967
|
|
|
702
|
-
const success = this.ctx.getProgramParameter(
|
|
968
|
+
const success = this.ctx.getProgramParameter(
|
|
969
|
+
program,
|
|
970
|
+
this.ctx.LINK_STATUS
|
|
971
|
+
);
|
|
703
972
|
if (!success) {
|
|
704
973
|
const msg = this.ctx.getProgramInfoLog(program);
|
|
705
974
|
this.ctx.deleteProgram(program);
|
|
706
|
-
throw
|
|
975
|
+
throw 'Unable to link shader program: ' + msg;
|
|
707
976
|
}
|
|
708
977
|
|
|
709
978
|
return program;
|
|
710
979
|
}
|
|
711
980
|
|
|
712
|
-
private createShader(
|
|
981
|
+
private createShader(
|
|
982
|
+
source: string,
|
|
983
|
+
type: 'VERTEX_SHADER' | 'FRAGMENT_SHADER'
|
|
984
|
+
) {
|
|
713
985
|
const shader = this.ctx.createShader(this.ctx[type]);
|
|
714
986
|
this.ctx.shaderSource(shader, source);
|
|
715
987
|
this.ctx.compileShader(shader);
|
|
716
988
|
|
|
717
|
-
const success = this.ctx.getShaderParameter(
|
|
989
|
+
const success = this.ctx.getShaderParameter(
|
|
990
|
+
shader,
|
|
991
|
+
this.ctx.COMPILE_STATUS
|
|
992
|
+
);
|
|
718
993
|
if (!success) {
|
|
719
994
|
const msg = this.ctx.getShaderInfoLog(shader);
|
|
720
995
|
this.ctx.deleteShader(shader);
|
|
721
|
-
throw
|
|
996
|
+
throw 'Unable to compile shader: ' + msg;
|
|
722
997
|
}
|
|
723
998
|
|
|
724
999
|
return shader;
|
|
@@ -726,19 +1001,31 @@ export default class OncoprintMinimapView {
|
|
|
726
1001
|
|
|
727
1002
|
private getWebGLContextAndSetUpMatrices() {
|
|
728
1003
|
this.ctx = this.getWebGLCanvasContext();
|
|
1004
|
+
if (this.ctx) {
|
|
1005
|
+
this.ext = this.ctx.getExtension('ANGLE_instanced_arrays');
|
|
1006
|
+
}
|
|
729
1007
|
(function initializeMatrices(self) {
|
|
730
1008
|
const mvMatrix = gl_matrix.mat4.create();
|
|
731
1009
|
gl_matrix.mat4.lookAt(mvMatrix, [0, 0, 1], [0, 0, 0], [0, 1, 0]);
|
|
732
1010
|
self.mvMatrix = mvMatrix;
|
|
733
1011
|
|
|
734
1012
|
const pMatrix = gl_matrix.mat4.create();
|
|
735
|
-
gl_matrix.mat4.ortho(
|
|
1013
|
+
gl_matrix.mat4.ortho(
|
|
1014
|
+
pMatrix,
|
|
1015
|
+
0,
|
|
1016
|
+
self.ctx.viewportWidth,
|
|
1017
|
+
self.ctx.viewportHeight,
|
|
1018
|
+
0,
|
|
1019
|
+
-5,
|
|
1020
|
+
1000
|
|
1021
|
+
); // y axis inverted so that y increases down like SVG
|
|
736
1022
|
self.pMatrix = pMatrix;
|
|
737
1023
|
})(this);
|
|
738
1024
|
}
|
|
739
1025
|
|
|
740
1026
|
private setUpShaders() {
|
|
741
|
-
const vertex_shader_source = [
|
|
1027
|
+
const vertex_shader_source = [
|
|
1028
|
+
'precision highp float;',
|
|
742
1029
|
'attribute float aPosVertex;',
|
|
743
1030
|
'attribute float aColVertex;',
|
|
744
1031
|
'attribute float aVertexOncoprintColumn;',
|
|
@@ -766,83 +1053,201 @@ export default class OncoprintMinimapView {
|
|
|
766
1053
|
' gl_Position *= vec4(zoomX, zoomY, 1.0, 1.0);',
|
|
767
1054
|
' gl_Position = uPMatrix * uMVMatrix * gl_Position;',
|
|
768
1055
|
' texCoord = (aColVertex + 0.5) / texSize;',
|
|
769
|
-
'}'
|
|
770
|
-
|
|
1056
|
+
'}',
|
|
1057
|
+
].join('\n');
|
|
1058
|
+
const fragment_shader_source = [
|
|
1059
|
+
'precision mediump float;',
|
|
771
1060
|
'varying float texCoord;',
|
|
772
1061
|
'uniform sampler2D uSampler;',
|
|
773
1062
|
'void main(void) {',
|
|
774
1063
|
' gl_FragColor = texture2D(uSampler, vec2(texCoord, 0.5));',
|
|
775
|
-
'}'
|
|
776
|
-
|
|
777
|
-
const
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
this.
|
|
782
|
-
|
|
1064
|
+
'}',
|
|
1065
|
+
].join('\n');
|
|
1066
|
+
const vertex_shader = this.createShader(
|
|
1067
|
+
vertex_shader_source,
|
|
1068
|
+
'VERTEX_SHADER'
|
|
1069
|
+
);
|
|
1070
|
+
const fragment_shader = this.createShader(
|
|
1071
|
+
fragment_shader_source,
|
|
1072
|
+
'FRAGMENT_SHADER'
|
|
1073
|
+
);
|
|
1074
|
+
|
|
1075
|
+
const shader_program = this.createShaderProgram(
|
|
1076
|
+
vertex_shader,
|
|
1077
|
+
fragment_shader
|
|
1078
|
+
) as OncoprintShaderProgram;
|
|
1079
|
+
shader_program.vertexPositionAttribute = this.ctx.getAttribLocation(
|
|
1080
|
+
shader_program,
|
|
1081
|
+
'aPosVertex'
|
|
1082
|
+
);
|
|
1083
|
+
this.ctx.enableVertexAttribArray(
|
|
1084
|
+
shader_program.vertexPositionAttribute
|
|
1085
|
+
);
|
|
1086
|
+
shader_program.vertexColorAttribute = this.ctx.getAttribLocation(
|
|
1087
|
+
shader_program,
|
|
1088
|
+
'aColVertex'
|
|
1089
|
+
);
|
|
783
1090
|
this.ctx.enableVertexAttribArray(shader_program.vertexColorAttribute);
|
|
784
|
-
shader_program.vertexOncoprintColumnAttribute = this.ctx.getAttribLocation(
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
shader_program.
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
1091
|
+
shader_program.vertexOncoprintColumnAttribute = this.ctx.getAttribLocation(
|
|
1092
|
+
shader_program,
|
|
1093
|
+
'aVertexOncoprintColumn'
|
|
1094
|
+
);
|
|
1095
|
+
this.ctx.enableVertexAttribArray(
|
|
1096
|
+
shader_program.vertexOncoprintColumnAttribute
|
|
1097
|
+
);
|
|
1098
|
+
|
|
1099
|
+
shader_program.samplerUniform = this.ctx.getUniformLocation(
|
|
1100
|
+
shader_program,
|
|
1101
|
+
'uSampler'
|
|
1102
|
+
);
|
|
1103
|
+
shader_program.pMatrixUniform = this.ctx.getUniformLocation(
|
|
1104
|
+
shader_program,
|
|
1105
|
+
'uPMatrix'
|
|
1106
|
+
);
|
|
1107
|
+
shader_program.mvMatrixUniform = this.ctx.getUniformLocation(
|
|
1108
|
+
shader_program,
|
|
1109
|
+
'uMVMatrix'
|
|
1110
|
+
);
|
|
1111
|
+
shader_program.columnWidthUniform = this.ctx.getUniformLocation(
|
|
1112
|
+
shader_program,
|
|
1113
|
+
'columnWidth'
|
|
1114
|
+
);
|
|
1115
|
+
shader_program.zoomXUniform = this.ctx.getUniformLocation(
|
|
1116
|
+
shader_program,
|
|
1117
|
+
'zoomX'
|
|
1118
|
+
);
|
|
1119
|
+
shader_program.zoomYUniform = this.ctx.getUniformLocation(
|
|
1120
|
+
shader_program,
|
|
1121
|
+
'zoomY'
|
|
1122
|
+
);
|
|
1123
|
+
shader_program.offsetYUniform = this.ctx.getUniformLocation(
|
|
1124
|
+
shader_program,
|
|
1125
|
+
'offsetY'
|
|
1126
|
+
);
|
|
1127
|
+
shader_program.positionBitPackBaseUniform = this.ctx.getUniformLocation(
|
|
1128
|
+
shader_program,
|
|
1129
|
+
'positionBitPackBase'
|
|
1130
|
+
);
|
|
1131
|
+
shader_program.texSizeUniform = this.ctx.getUniformLocation(
|
|
1132
|
+
shader_program,
|
|
1133
|
+
'texSize'
|
|
1134
|
+
);
|
|
796
1135
|
|
|
797
1136
|
this.shader_program = shader_program;
|
|
798
1137
|
}
|
|
799
1138
|
|
|
800
|
-
private getTrackBuffers(
|
|
801
|
-
|
|
1139
|
+
private getTrackBuffers(
|
|
1140
|
+
cell_view: OncoprintWebGLCellView,
|
|
1141
|
+
track_id: TrackId
|
|
1142
|
+
) {
|
|
1143
|
+
const pos_buffer = this.ctx.createBuffer() as OncoprintVertexTrackBuffer;
|
|
802
1144
|
const pos_array = cell_view.vertex_data[track_id].pos_array;
|
|
1145
|
+
const universal_shapes_start_index =
|
|
1146
|
+
cell_view.vertex_data[track_id].universal_shapes_start_index;
|
|
803
1147
|
|
|
804
1148
|
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, pos_buffer);
|
|
805
|
-
this.ctx.bufferData(
|
|
1149
|
+
this.ctx.bufferData(
|
|
1150
|
+
this.ctx.ARRAY_BUFFER,
|
|
1151
|
+
pos_array,
|
|
1152
|
+
this.ctx.STATIC_DRAW
|
|
1153
|
+
);
|
|
806
1154
|
pos_buffer.itemSize = 1;
|
|
807
|
-
pos_buffer.
|
|
1155
|
+
pos_buffer.specificShapesNumItems =
|
|
1156
|
+
universal_shapes_start_index / pos_buffer.itemSize;
|
|
1157
|
+
pos_buffer.universalShapesNumItems =
|
|
1158
|
+
(pos_array.length - universal_shapes_start_index) /
|
|
1159
|
+
pos_buffer.itemSize;
|
|
808
1160
|
|
|
809
|
-
const col_buffer = this.ctx.createBuffer() as
|
|
1161
|
+
const col_buffer = this.ctx.createBuffer() as OncoprintVertexTrackBuffer;
|
|
810
1162
|
const col_array = cell_view.vertex_data[track_id].col_array;
|
|
811
1163
|
|
|
812
1164
|
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, col_buffer);
|
|
813
|
-
this.ctx.bufferData(
|
|
1165
|
+
this.ctx.bufferData(
|
|
1166
|
+
this.ctx.ARRAY_BUFFER,
|
|
1167
|
+
col_array,
|
|
1168
|
+
this.ctx.STATIC_DRAW
|
|
1169
|
+
);
|
|
814
1170
|
col_buffer.itemSize = 1;
|
|
815
|
-
col_buffer.
|
|
1171
|
+
col_buffer.specificShapesNumItems =
|
|
1172
|
+
universal_shapes_start_index / col_buffer.itemSize;
|
|
1173
|
+
col_buffer.universalShapesNumItems =
|
|
1174
|
+
(col_array.length - universal_shapes_start_index) /
|
|
1175
|
+
col_buffer.itemSize;
|
|
816
1176
|
|
|
817
1177
|
const tex = this.ctx.createTexture();
|
|
818
1178
|
this.ctx.bindTexture(this.ctx.TEXTURE_2D, tex);
|
|
819
1179
|
|
|
820
1180
|
const color_bank = cell_view.vertex_data[track_id].col_bank;
|
|
821
|
-
const width = Math.pow(
|
|
1181
|
+
const width = Math.pow(
|
|
1182
|
+
2,
|
|
1183
|
+
Math.ceil((Math as any).log2(color_bank.length / 4))
|
|
1184
|
+
);
|
|
822
1185
|
while (color_bank.length < 4 * width) {
|
|
823
1186
|
color_bank.push(0);
|
|
824
1187
|
}
|
|
825
1188
|
const height = 1;
|
|
826
|
-
this.ctx.texImage2D(
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
1189
|
+
this.ctx.texImage2D(
|
|
1190
|
+
this.ctx.TEXTURE_2D,
|
|
1191
|
+
0,
|
|
1192
|
+
this.ctx.RGBA,
|
|
1193
|
+
width,
|
|
1194
|
+
height,
|
|
1195
|
+
0,
|
|
1196
|
+
this.ctx.RGBA,
|
|
1197
|
+
this.ctx.UNSIGNED_BYTE,
|
|
1198
|
+
new Uint8Array(color_bank)
|
|
1199
|
+
);
|
|
1200
|
+
this.ctx.texParameteri(
|
|
1201
|
+
this.ctx.TEXTURE_2D,
|
|
1202
|
+
this.ctx.TEXTURE_MIN_FILTER,
|
|
1203
|
+
this.ctx.NEAREST
|
|
1204
|
+
);
|
|
1205
|
+
this.ctx.texParameteri(
|
|
1206
|
+
this.ctx.TEXTURE_2D,
|
|
1207
|
+
this.ctx.TEXTURE_MAG_FILTER,
|
|
1208
|
+
this.ctx.NEAREST
|
|
1209
|
+
);
|
|
1210
|
+
|
|
1211
|
+
const color_texture = { texture: tex, size: width };
|
|
831
1212
|
|
|
832
1213
|
const vertex_column_buffer = this.ctx.createBuffer() as OncoprintTrackBuffer;
|
|
833
1214
|
const vertex_column_array = cell_view.vertex_column_array[track_id];
|
|
834
1215
|
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, vertex_column_buffer);
|
|
835
|
-
this.ctx.bufferData(
|
|
1216
|
+
this.ctx.bufferData(
|
|
1217
|
+
this.ctx.ARRAY_BUFFER,
|
|
1218
|
+
new Float32Array(vertex_column_array),
|
|
1219
|
+
this.ctx.STATIC_DRAW
|
|
1220
|
+
);
|
|
836
1221
|
vertex_column_buffer.itemSize = 1;
|
|
837
|
-
vertex_column_buffer.numItems =
|
|
1222
|
+
vertex_column_buffer.numItems =
|
|
1223
|
+
vertex_column_array.length / vertex_column_buffer.itemSize;
|
|
838
1224
|
|
|
839
|
-
return {
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
1225
|
+
return {
|
|
1226
|
+
position: pos_buffer,
|
|
1227
|
+
color: col_buffer,
|
|
1228
|
+
color_tex: color_texture,
|
|
1229
|
+
column: vertex_column_buffer,
|
|
1230
|
+
};
|
|
1231
|
+
}
|
|
844
1232
|
|
|
845
|
-
private
|
|
1233
|
+
private getSimpleCountBuffer(model: OncoprintModel) {
|
|
1234
|
+
const numColumns = model.getIdOrder().length;
|
|
1235
|
+
const buffer = this.ctx.createBuffer() as OncoprintTrackBuffer;
|
|
1236
|
+
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, buffer);
|
|
1237
|
+
this.ctx.bufferData(
|
|
1238
|
+
this.ctx.ARRAY_BUFFER,
|
|
1239
|
+
new Float32Array(_.range(0, numColumns)),
|
|
1240
|
+
this.ctx.STATIC_DRAW
|
|
1241
|
+
);
|
|
1242
|
+
buffer.itemSize = 1;
|
|
1243
|
+
buffer.numItems = numColumns;
|
|
1244
|
+
return buffer;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
private drawOncoprint(
|
|
1248
|
+
model: OncoprintModel,
|
|
1249
|
+
cell_view: OncoprintWebGLCellView
|
|
1250
|
+
) {
|
|
846
1251
|
if (!this.shouldRender) {
|
|
847
1252
|
return;
|
|
848
1253
|
}
|
|
@@ -855,6 +1260,7 @@ export default class OncoprintMinimapView {
|
|
|
855
1260
|
this.ctx.clear(this.ctx.COLOR_BUFFER_BIT | this.ctx.DEPTH_BUFFER_BIT);
|
|
856
1261
|
|
|
857
1262
|
const tracks = model.getTracks();
|
|
1263
|
+
const simple_count_buffer = this.getSimpleCountBuffer(model);
|
|
858
1264
|
for (let i = 0; i < tracks.length; i++) {
|
|
859
1265
|
const track_id = tracks[i];
|
|
860
1266
|
const cell_top = model.getCellTops(track_id, true);
|
|
@@ -863,44 +1269,169 @@ export default class OncoprintMinimapView {
|
|
|
863
1269
|
continue;
|
|
864
1270
|
}
|
|
865
1271
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
1272
|
+
for (const forSpecificShapes of [false, true]) {
|
|
1273
|
+
const shader_program = this.shader_program;
|
|
1274
|
+
this.ctx.useProgram(shader_program);
|
|
1275
|
+
|
|
1276
|
+
if (forSpecificShapes) {
|
|
1277
|
+
this.ctx.bindBuffer(
|
|
1278
|
+
this.ctx.ARRAY_BUFFER,
|
|
1279
|
+
buffers.position
|
|
1280
|
+
);
|
|
1281
|
+
this.ctx.vertexAttribPointer(
|
|
1282
|
+
shader_program.vertexPositionAttribute,
|
|
1283
|
+
buffers.position.itemSize,
|
|
1284
|
+
this.ctx.FLOAT,
|
|
1285
|
+
false,
|
|
1286
|
+
0,
|
|
1287
|
+
0
|
|
1288
|
+
);
|
|
1289
|
+
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, buffers.color);
|
|
1290
|
+
this.ctx.vertexAttribPointer(
|
|
1291
|
+
shader_program.vertexColorAttribute,
|
|
1292
|
+
buffers.color.itemSize,
|
|
1293
|
+
this.ctx.FLOAT,
|
|
1294
|
+
false,
|
|
1295
|
+
0,
|
|
1296
|
+
0
|
|
1297
|
+
);
|
|
1298
|
+
|
|
1299
|
+
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, buffers.column);
|
|
1300
|
+
this.ctx.vertexAttribPointer(
|
|
1301
|
+
shader_program.vertexOncoprintColumnAttribute,
|
|
1302
|
+
buffers.column.itemSize,
|
|
1303
|
+
this.ctx.FLOAT,
|
|
1304
|
+
false,
|
|
1305
|
+
0,
|
|
1306
|
+
0
|
|
1307
|
+
);
|
|
1308
|
+
// make sure to set divisor 0, otherwise the track will only use the first item in the column buffer
|
|
1309
|
+
this.ext.vertexAttribDivisorANGLE(
|
|
1310
|
+
shader_program.vertexOncoprintColumnAttribute,
|
|
1311
|
+
0
|
|
1312
|
+
);
|
|
1313
|
+
} else {
|
|
1314
|
+
// set up for drawArraysInstanced
|
|
1315
|
+
const universalShapesStart =
|
|
1316
|
+
buffers.position.specificShapesNumItems *
|
|
1317
|
+
buffers.position.itemSize;
|
|
1318
|
+
this.ctx.bindBuffer(
|
|
1319
|
+
this.ctx.ARRAY_BUFFER,
|
|
1320
|
+
buffers.position
|
|
1321
|
+
);
|
|
1322
|
+
this.ctx.vertexAttribPointer(
|
|
1323
|
+
shader_program.vertexPositionAttribute,
|
|
1324
|
+
buffers.position.itemSize,
|
|
1325
|
+
this.ctx.FLOAT,
|
|
1326
|
+
false,
|
|
1327
|
+
0,
|
|
1328
|
+
4 * universalShapesStart
|
|
1329
|
+
);
|
|
1330
|
+
|
|
1331
|
+
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, buffers.color);
|
|
1332
|
+
this.ctx.vertexAttribPointer(
|
|
1333
|
+
shader_program.vertexColorAttribute,
|
|
1334
|
+
buffers.color.itemSize,
|
|
1335
|
+
this.ctx.FLOAT,
|
|
1336
|
+
false,
|
|
1337
|
+
0,
|
|
1338
|
+
4 * universalShapesStart
|
|
1339
|
+
);
|
|
1340
|
+
|
|
1341
|
+
this.ctx.bindBuffer(
|
|
1342
|
+
this.ctx.ARRAY_BUFFER,
|
|
1343
|
+
simple_count_buffer
|
|
1344
|
+
);
|
|
1345
|
+
this.ctx.vertexAttribPointer(
|
|
1346
|
+
shader_program.vertexOncoprintColumnAttribute,
|
|
1347
|
+
1,
|
|
1348
|
+
this.ctx.FLOAT,
|
|
1349
|
+
false,
|
|
1350
|
+
0,
|
|
1351
|
+
0
|
|
1352
|
+
);
|
|
1353
|
+
this.ext.vertexAttribDivisorANGLE(
|
|
1354
|
+
shader_program.vertexOncoprintColumnAttribute,
|
|
1355
|
+
1
|
|
1356
|
+
);
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
this.ctx.activeTexture(this.ctx.TEXTURE0);
|
|
1360
|
+
this.ctx.bindTexture(
|
|
1361
|
+
this.ctx.TEXTURE_2D,
|
|
1362
|
+
buffers.color_tex.texture
|
|
1363
|
+
);
|
|
1364
|
+
this.ctx.uniform1i(this.shader_program.samplerUniform, 0);
|
|
1365
|
+
this.ctx.uniform1f(
|
|
1366
|
+
this.shader_program.texSizeUniform,
|
|
1367
|
+
buffers.color_tex.size
|
|
1368
|
+
);
|
|
1369
|
+
|
|
1370
|
+
this.ctx.uniformMatrix4fv(
|
|
1371
|
+
this.shader_program.pMatrixUniform,
|
|
1372
|
+
false,
|
|
1373
|
+
this.pMatrix
|
|
1374
|
+
);
|
|
1375
|
+
this.ctx.uniformMatrix4fv(
|
|
1376
|
+
this.shader_program.mvMatrixUniform,
|
|
1377
|
+
false,
|
|
1378
|
+
this.mvMatrix
|
|
1379
|
+
);
|
|
1380
|
+
this.ctx.uniform1f(
|
|
1381
|
+
this.shader_program.columnWidthUniform,
|
|
1382
|
+
model.getCellWidth(true)
|
|
1383
|
+
);
|
|
1384
|
+
this.ctx.uniform1f(this.shader_program.zoomXUniform, zoom.x);
|
|
1385
|
+
this.ctx.uniform1f(this.shader_program.zoomYUniform, zoom.y);
|
|
1386
|
+
this.ctx.uniform1f(
|
|
1387
|
+
this.shader_program.offsetYUniform,
|
|
1388
|
+
cell_top
|
|
1389
|
+
);
|
|
1390
|
+
this.ctx.uniform1f(
|
|
1391
|
+
this.shader_program.positionBitPackBaseUniform,
|
|
1392
|
+
cell_view.position_bit_pack_base
|
|
1393
|
+
);
|
|
1394
|
+
|
|
1395
|
+
if (forSpecificShapes) {
|
|
1396
|
+
this.ctx.drawArrays(
|
|
1397
|
+
this.ctx.TRIANGLES,
|
|
1398
|
+
0,
|
|
1399
|
+
buffers.position.specificShapesNumItems
|
|
1400
|
+
);
|
|
1401
|
+
} else {
|
|
1402
|
+
this.ext.drawArraysInstancedANGLE(
|
|
1403
|
+
this.ctx.TRIANGLES,
|
|
1404
|
+
0,
|
|
1405
|
+
buffers.position.itemSize *
|
|
1406
|
+
buffers.position.universalShapesNumItems,
|
|
1407
|
+
simple_count_buffer.numItems
|
|
1408
|
+
);
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
this.ctx.flush();
|
|
889
1412
|
}
|
|
890
1413
|
}
|
|
891
1414
|
|
|
892
|
-
private getZoom(model:OncoprintModel) {
|
|
893
|
-
let zoom_x =
|
|
894
|
-
|
|
1415
|
+
private getZoom(model: OncoprintModel) {
|
|
1416
|
+
let zoom_x =
|
|
1417
|
+
parseInt(this.$canvas[0].width as any, 10) /
|
|
1418
|
+
model.getOncoprintWidthNoColumnPaddingNoGaps();
|
|
1419
|
+
let zoom_y =
|
|
1420
|
+
parseInt(this.$canvas[0].height as any, 10) /
|
|
1421
|
+
model.getOncoprintHeight(true);
|
|
895
1422
|
zoom_x = Math.max(0, Math.min(1, zoom_x));
|
|
896
1423
|
zoom_y = Math.max(0, Math.min(1, zoom_y));
|
|
897
1424
|
return {
|
|
898
1425
|
x: zoom_x,
|
|
899
|
-
y: zoom_y
|
|
1426
|
+
y: zoom_y,
|
|
900
1427
|
};
|
|
901
1428
|
}
|
|
902
1429
|
|
|
903
|
-
private drawOverlayRect(
|
|
1430
|
+
private drawOverlayRect(
|
|
1431
|
+
model: OncoprintModel,
|
|
1432
|
+
cell_view: OncoprintWebGLCellView,
|
|
1433
|
+
opt_rect?: OverlayRectSpec
|
|
1434
|
+
) {
|
|
904
1435
|
if (!this.shouldRender) {
|
|
905
1436
|
return;
|
|
906
1437
|
}
|
|
@@ -920,9 +1451,13 @@ export default class OncoprintMinimapView {
|
|
|
920
1451
|
|
|
921
1452
|
const zoom = this.getZoom(model);
|
|
922
1453
|
left_col = model.getClosestColumnIndexToLeft(viewport.left, false);
|
|
923
|
-
right_col = model.getClosestColumnIndexToLeft(
|
|
1454
|
+
right_col = model.getClosestColumnIndexToLeft(
|
|
1455
|
+
viewport.right,
|
|
1456
|
+
false,
|
|
1457
|
+
true
|
|
1458
|
+
);
|
|
924
1459
|
left = left_col * cell_width * zoom.x;
|
|
925
|
-
width = (right_col-left_col) * cell_width * zoom.x;
|
|
1460
|
+
width = (right_col - left_col) * cell_width * zoom.x;
|
|
926
1461
|
top = viewport.top * zoom.y;
|
|
927
1462
|
height = (viewport.bottom - viewport.top) * zoom.y;
|
|
928
1463
|
}
|
|
@@ -933,58 +1468,73 @@ export default class OncoprintMinimapView {
|
|
|
933
1468
|
const canv_height = parseInt(canv.height as any, 10);
|
|
934
1469
|
|
|
935
1470
|
// Clear
|
|
936
|
-
ctx.fillStyle =
|
|
1471
|
+
ctx.fillStyle = 'rgba(0,0,0,0)';
|
|
937
1472
|
ctx.clearRect(0, 0, canv_width, canv_height);
|
|
938
1473
|
// Draw rectangle
|
|
939
|
-
ctx.fillStyle =
|
|
1474
|
+
ctx.fillStyle = 'rgba(255,255,255,0.4)';
|
|
940
1475
|
ctx.fillRect(left, top, width, height);
|
|
941
1476
|
// Draw border line by line
|
|
942
|
-
const unhover_color =
|
|
943
|
-
const hover_color =
|
|
1477
|
+
const unhover_color = 'rgba(0,0,0,0.75)';
|
|
1478
|
+
const hover_color = 'rgba(255,0,0,1)';
|
|
944
1479
|
const unhover_width = 1;
|
|
945
1480
|
const hover_width = 2;
|
|
946
|
-
const top_is_hovered =
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
1481
|
+
const top_is_hovered =
|
|
1482
|
+
this.resize_hover === 't' ||
|
|
1483
|
+
this.resize_hover === 'tr' ||
|
|
1484
|
+
this.resize_hover === 'tl';
|
|
1485
|
+
const right_is_hovered =
|
|
1486
|
+
this.resize_hover === 'r' ||
|
|
1487
|
+
this.resize_hover === 'tr' ||
|
|
1488
|
+
this.resize_hover === 'br';
|
|
1489
|
+
const bottom_is_hovered =
|
|
1490
|
+
this.resize_hover === 'b' ||
|
|
1491
|
+
this.resize_hover === 'br' ||
|
|
1492
|
+
this.resize_hover === 'bl';
|
|
1493
|
+
const left_is_hovered =
|
|
1494
|
+
this.resize_hover === 'l' ||
|
|
1495
|
+
this.resize_hover === 'tl' ||
|
|
1496
|
+
this.resize_hover === 'bl';
|
|
950
1497
|
// Draw top border
|
|
951
1498
|
ctx.beginPath();
|
|
952
1499
|
ctx.moveTo(left, top);
|
|
953
1500
|
ctx.strokeStyle = top_is_hovered ? hover_color : unhover_color;
|
|
954
1501
|
ctx.lineWidth = top_is_hovered ? hover_width : unhover_width;
|
|
955
|
-
ctx.lineTo(left+width, top);
|
|
1502
|
+
ctx.lineTo(left + width, top);
|
|
956
1503
|
ctx.stroke();
|
|
957
1504
|
// Draw right border
|
|
958
1505
|
ctx.beginPath();
|
|
959
|
-
ctx.moveTo(left+width, top);
|
|
1506
|
+
ctx.moveTo(left + width, top);
|
|
960
1507
|
ctx.strokeStyle = right_is_hovered ? hover_color : unhover_color;
|
|
961
1508
|
ctx.lineWidth = right_is_hovered ? hover_width : unhover_width;
|
|
962
|
-
ctx.lineTo(left+width, top+height);
|
|
1509
|
+
ctx.lineTo(left + width, top + height);
|
|
963
1510
|
ctx.stroke();
|
|
964
1511
|
// Draw bottom border
|
|
965
1512
|
ctx.beginPath();
|
|
966
|
-
ctx.moveTo(left+width, top+height);
|
|
1513
|
+
ctx.moveTo(left + width, top + height);
|
|
967
1514
|
ctx.strokeStyle = bottom_is_hovered ? hover_color : unhover_color;
|
|
968
1515
|
ctx.lineWidth = bottom_is_hovered ? hover_width : unhover_width;
|
|
969
|
-
ctx.lineTo(left, top+height);
|
|
1516
|
+
ctx.lineTo(left, top + height);
|
|
970
1517
|
ctx.stroke();
|
|
971
1518
|
// Draw left border
|
|
972
1519
|
ctx.beginPath();
|
|
973
|
-
ctx.moveTo(left, top+height);
|
|
1520
|
+
ctx.moveTo(left, top + height);
|
|
974
1521
|
ctx.strokeStyle = left_is_hovered ? hover_color : unhover_color;
|
|
975
1522
|
ctx.lineWidth = left_is_hovered ? hover_width : unhover_width;
|
|
976
1523
|
ctx.lineTo(left, top);
|
|
977
1524
|
ctx.stroke();
|
|
978
1525
|
|
|
979
1526
|
this.current_rect.setParams({
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1527
|
+
top: top,
|
|
1528
|
+
left_col: left_col,
|
|
1529
|
+
right_col: right_col,
|
|
1530
|
+
height: height,
|
|
984
1531
|
});
|
|
985
1532
|
}
|
|
986
1533
|
|
|
987
|
-
private drawOncoprintAndOverlayRect(
|
|
1534
|
+
private drawOncoprintAndOverlayRect(
|
|
1535
|
+
model: OncoprintModel,
|
|
1536
|
+
cell_view: OncoprintWebGLCellView
|
|
1537
|
+
) {
|
|
988
1538
|
if (!this.shouldRender) {
|
|
989
1539
|
return;
|
|
990
1540
|
}
|
|
@@ -992,75 +1542,114 @@ export default class OncoprintMinimapView {
|
|
|
992
1542
|
this.drawOverlayRect(model, cell_view);
|
|
993
1543
|
}
|
|
994
1544
|
|
|
995
|
-
|
|
996
1545
|
// API BEGINS HERE
|
|
997
1546
|
|
|
998
|
-
public moveTrack(model:OncoprintModel, cell_view:OncoprintWebGLCellView) {
|
|
1547
|
+
public moveTrack(model: OncoprintModel, cell_view: OncoprintWebGLCellView) {
|
|
999
1548
|
this.drawOncoprintAndOverlayRect(model, cell_view);
|
|
1000
1549
|
}
|
|
1001
|
-
public addTracks(model:OncoprintModel, cell_view:OncoprintWebGLCellView) {
|
|
1550
|
+
public addTracks(model: OncoprintModel, cell_view: OncoprintWebGLCellView) {
|
|
1002
1551
|
this.drawOncoprintAndOverlayRect(model, cell_view);
|
|
1003
1552
|
}
|
|
1004
|
-
public removeTrack(
|
|
1553
|
+
public removeTrack(
|
|
1554
|
+
model: OncoprintModel,
|
|
1555
|
+
cell_view: OncoprintWebGLCellView
|
|
1556
|
+
) {
|
|
1005
1557
|
this.drawOncoprintAndOverlayRect(model, cell_view);
|
|
1006
1558
|
}
|
|
1007
|
-
public setHorzZoom(
|
|
1559
|
+
public setHorzZoom(
|
|
1560
|
+
model: OncoprintModel,
|
|
1561
|
+
cell_view: OncoprintWebGLCellView
|
|
1562
|
+
) {
|
|
1008
1563
|
this.drawOverlayRect(model, cell_view);
|
|
1009
1564
|
this.horizontal_zoom.setSliderValue(model.getHorzZoom());
|
|
1010
1565
|
}
|
|
1011
|
-
public setVertZoom(
|
|
1566
|
+
public setVertZoom(
|
|
1567
|
+
model: OncoprintModel,
|
|
1568
|
+
cell_view: OncoprintWebGLCellView
|
|
1569
|
+
) {
|
|
1012
1570
|
this.drawOverlayRect(model, cell_view);
|
|
1013
1571
|
this.vertical_zoom.setSliderValue(model.getVertZoom());
|
|
1014
1572
|
}
|
|
1015
|
-
public setZoom(model:OncoprintModel, cell_view:OncoprintWebGLCellView) {
|
|
1573
|
+
public setZoom(model: OncoprintModel, cell_view: OncoprintWebGLCellView) {
|
|
1016
1574
|
this.drawOverlayRect(model, cell_view);
|
|
1017
1575
|
this.horizontal_zoom.setSliderValue(model.getHorzZoom());
|
|
1018
1576
|
this.vertical_zoom.setSliderValue(model.getVertZoom());
|
|
1019
1577
|
}
|
|
1020
|
-
public setScroll(model:OncoprintModel, cell_view:OncoprintWebGLCellView) {
|
|
1578
|
+
public setScroll(model: OncoprintModel, cell_view: OncoprintWebGLCellView) {
|
|
1021
1579
|
this.drawOverlayRect(model, cell_view);
|
|
1022
1580
|
}
|
|
1023
|
-
public setHorzScroll(
|
|
1581
|
+
public setHorzScroll(
|
|
1582
|
+
model: OncoprintModel,
|
|
1583
|
+
cell_view: OncoprintWebGLCellView
|
|
1584
|
+
) {
|
|
1024
1585
|
this.drawOverlayRect(model, cell_view);
|
|
1025
1586
|
}
|
|
1026
|
-
public setVertScroll(
|
|
1587
|
+
public setVertScroll(
|
|
1588
|
+
model: OncoprintModel,
|
|
1589
|
+
cell_view: OncoprintWebGLCellView
|
|
1590
|
+
) {
|
|
1027
1591
|
this.drawOverlayRect(model, cell_view);
|
|
1028
1592
|
}
|
|
1029
|
-
public setViewport(
|
|
1593
|
+
public setViewport(
|
|
1594
|
+
model: OncoprintModel,
|
|
1595
|
+
cell_view: OncoprintWebGLCellView
|
|
1596
|
+
) {
|
|
1030
1597
|
this.drawOverlayRect(model, cell_view);
|
|
1031
1598
|
this.horizontal_zoom.setSliderValue(model.getHorzZoom());
|
|
1032
1599
|
this.vertical_zoom.setSliderValue(model.getVertZoom());
|
|
1033
1600
|
}
|
|
1034
|
-
public sort(model:OncoprintModel, cell_view:OncoprintWebGLCellView) {
|
|
1601
|
+
public sort(model: OncoprintModel, cell_view: OncoprintWebGLCellView) {
|
|
1035
1602
|
this.drawOncoprintAndOverlayRect(model, cell_view);
|
|
1036
1603
|
}
|
|
1037
|
-
public setTrackData(
|
|
1604
|
+
public setTrackData(
|
|
1605
|
+
model: OncoprintModel,
|
|
1606
|
+
cell_view: OncoprintWebGLCellView
|
|
1607
|
+
) {
|
|
1038
1608
|
this.drawOncoprintAndOverlayRect(model, cell_view);
|
|
1039
1609
|
}
|
|
1040
|
-
public shareRuleSet(
|
|
1610
|
+
public shareRuleSet(
|
|
1611
|
+
model: OncoprintModel,
|
|
1612
|
+
cell_view: OncoprintWebGLCellView
|
|
1613
|
+
) {
|
|
1041
1614
|
this.drawOncoprintAndOverlayRect(model, cell_view);
|
|
1042
1615
|
}
|
|
1043
|
-
public setRuleSet(
|
|
1616
|
+
public setRuleSet(
|
|
1617
|
+
model: OncoprintModel,
|
|
1618
|
+
cell_view: OncoprintWebGLCellView
|
|
1619
|
+
) {
|
|
1044
1620
|
this.drawOncoprintAndOverlayRect(model, cell_view);
|
|
1045
1621
|
}
|
|
1046
|
-
public setIdOrder(
|
|
1622
|
+
public setIdOrder(
|
|
1623
|
+
model: OncoprintModel,
|
|
1624
|
+
cell_view: OncoprintWebGLCellView
|
|
1625
|
+
) {
|
|
1047
1626
|
this.drawOncoprintAndOverlayRect(model, cell_view);
|
|
1048
1627
|
}
|
|
1049
|
-
public setTrackGroupHeader(
|
|
1628
|
+
public setTrackGroupHeader(
|
|
1629
|
+
model: OncoprintModel,
|
|
1630
|
+
cell_view: OncoprintWebGLCellView
|
|
1631
|
+
) {
|
|
1050
1632
|
this.drawOncoprintAndOverlayRect(model, cell_view);
|
|
1051
1633
|
}
|
|
1052
1634
|
public suppressRendering() {
|
|
1053
1635
|
this.rendering_suppressed = true;
|
|
1054
1636
|
}
|
|
1055
|
-
public releaseRendering(
|
|
1637
|
+
public releaseRendering(
|
|
1638
|
+
model: OncoprintModel,
|
|
1639
|
+
cell_view: OncoprintWebGLCellView
|
|
1640
|
+
) {
|
|
1056
1641
|
this.rendering_suppressed = false;
|
|
1057
1642
|
this.drawOncoprintAndOverlayRect(model, cell_view);
|
|
1058
1643
|
}
|
|
1059
|
-
public hideIds(model:OncoprintModel, cell_view:OncoprintWebGLCellView) {
|
|
1644
|
+
public hideIds(model: OncoprintModel, cell_view: OncoprintWebGLCellView) {
|
|
1060
1645
|
this.drawOncoprintAndOverlayRect(model, cell_view);
|
|
1061
1646
|
}
|
|
1062
1647
|
|
|
1063
|
-
public setMinimapVisible(
|
|
1648
|
+
public setMinimapVisible(
|
|
1649
|
+
visible: boolean,
|
|
1650
|
+
model?: OncoprintModel,
|
|
1651
|
+
cell_view?: OncoprintWebGLCellView
|
|
1652
|
+
) {
|
|
1064
1653
|
this.visible = visible;
|
|
1065
1654
|
|
|
1066
1655
|
if (this.visible && model && cell_view) {
|
|
@@ -1068,17 +1657,21 @@ export default class OncoprintMinimapView {
|
|
|
1068
1657
|
}
|
|
1069
1658
|
}
|
|
1070
1659
|
|
|
1071
|
-
public setWindowPosition(x:number, y:number) {
|
|
1072
|
-
this.$div.css({
|
|
1660
|
+
public setWindowPosition(x: number, y: number) {
|
|
1661
|
+
this.$div.css({ top: y, left: x });
|
|
1073
1662
|
}
|
|
1074
1663
|
|
|
1075
|
-
public setWidth(
|
|
1664
|
+
public setWidth(
|
|
1665
|
+
w: number,
|
|
1666
|
+
model: OncoprintModel,
|
|
1667
|
+
cell_view: OncoprintWebGLCellView
|
|
1668
|
+
) {
|
|
1076
1669
|
this.$canvas[0].width = w;
|
|
1077
1670
|
this.$overlay_canvas[0].width = w;
|
|
1078
1671
|
this.getWebGLContextAndSetUpMatrices();
|
|
1079
1672
|
this.setUpShaders();
|
|
1080
|
-
this.overlay_ctx = this.$overlay_canvas[0].getContext(
|
|
1673
|
+
this.overlay_ctx = this.$overlay_canvas[0].getContext('2d');
|
|
1081
1674
|
|
|
1082
1675
|
this.drawOncoprintAndOverlayRect(model, cell_view);
|
|
1083
1676
|
}
|
|
1084
|
-
}
|
|
1677
|
+
}
|