oncoprintjs 6.0.3 → 6.0.5

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/dist/index.js CHANGED
@@ -1395,6 +1395,12 @@ var OncoprintModel = /** @class */ (function () {
1395
1395
  writable: true,
1396
1396
  value: void 0
1397
1397
  });
1398
+ Object.defineProperty(this, "data_groups", {
1399
+ enumerable: true,
1400
+ configurable: true,
1401
+ writable: true,
1402
+ value: void 0
1403
+ });
1398
1404
  Object.defineProperty(this, "column_indexes_after_a_gap", {
1399
1405
  enumerable: true,
1400
1406
  configurable: true,
@@ -1616,6 +1622,38 @@ var OncoprintModel = /** @class */ (function () {
1616
1622
  }
1617
1623
  return gapIds;
1618
1624
  });
1625
+ this.data_groups = new CachedProperty({}, function (model) {
1626
+ // multiple tracks can have gaps
1627
+ // the groups will be segemented heirarchically
1628
+ var trackIdsWithGaps = model
1629
+ .getTracks()
1630
+ .filter(function (trackId) { return model.getTrackShowGaps(trackId); });
1631
+ var data_groups = ___default["default"].reduce(model.track_label, function (agg, label, trackId) {
1632
+ // key the data by the datum UID
1633
+ var keyedData = ___default["default"].keyBy(model.track_data[trackId], function (m) { return m.uid; });
1634
+ var groups = trackIdsWithGaps.map(function (id) {
1635
+ // we need the datum in sorted order
1636
+ var data = model.id_order.map(function (d) { return keyedData[d]; });
1637
+ var indexesAfterGap = model.column_indexes_after_a_gap.get();
1638
+ // the indexes come AFTER a gap, so we need to include zero up front
1639
+ // in order to get initial slice of data
1640
+ var groupStartIndexes = tslib.__spreadArrays([0], indexesAfterGap);
1641
+ // using the group start indexes, slice the id data into corresponding groups
1642
+ return groupStartIndexes.map(function (n, i) {
1643
+ if (i === groupStartIndexes.length - 1) {
1644
+ // we're at last one, so last group
1645
+ return data.slice(n);
1646
+ }
1647
+ else {
1648
+ return data.slice(n, groupStartIndexes[i + 1]);
1649
+ }
1650
+ });
1651
+ });
1652
+ agg[label.trim()] = groups;
1653
+ return agg;
1654
+ }, {});
1655
+ return data_groups;
1656
+ });
1619
1657
  this.visible_id_order.addBoundProperty(this.ids_after_a_gap);
1620
1658
  this.precomputed_comparator.addBoundProperty(this.ids_after_a_gap);
1621
1659
  this.column_indexes_after_a_gap = new CachedProperty([], function (model) {
@@ -2195,7 +2233,12 @@ var OncoprintModel = /** @class */ (function () {
2195
2233
  configurable: true,
2196
2234
  writable: true,
2197
2235
  value: function () {
2198
- return this.getCellWidth(true);
2236
+ if (this.showGaps()) {
2237
+ return 50; // this creates enough space for 3 digit percentage
2238
+ }
2239
+ else {
2240
+ return this.getCellWidth(true);
2241
+ }
2199
2242
  }
2200
2243
  });
2201
2244
  Object.defineProperty(OncoprintModel.prototype, "getCellWidth", {
@@ -3021,7 +3064,18 @@ var OncoprintModel = /** @class */ (function () {
3021
3064
  var lastIdLeft = base
3022
3065
  ? this.getColumnLeft(lastId)
3023
3066
  : this.getZoomedColumnLeft(lastId);
3024
- return lastIdLeft + this.getCellWidth(base) + 1; // this fixes some edge case issues with scrolling
3067
+ // when gaps are showing, we need to add space at the end of the
3068
+ // oncoprint to accomodate the label
3069
+ var lastGap = this.showGaps() ? this.getGapSize() : 0;
3070
+ return lastIdLeft + this.getCellWidth(base) + lastGap + 1; // this fixes some edge case issues with scrolling
3071
+ }
3072
+ });
3073
+ Object.defineProperty(OncoprintModel.prototype, "showGaps", {
3074
+ enumerable: false,
3075
+ configurable: true,
3076
+ writable: true,
3077
+ value: function () {
3078
+ return ___default["default"].some(this.track_show_gaps);
3025
3079
  }
3026
3080
  });
3027
3081
  Object.defineProperty(OncoprintModel.prototype, "getOncoprintWidthNoColumnPaddingNoGaps", {
@@ -3340,6 +3394,29 @@ var OncoprintModel = /** @class */ (function () {
3340
3394
  this.track_custom_options[track_id] = options;
3341
3395
  }
3342
3396
  });
3397
+ // get the pixel offset (from the grid origin) for the gaps based
3398
+ Object.defineProperty(OncoprintModel.prototype, "getGapOffsets", {
3399
+ enumerable: false,
3400
+ configurable: true,
3401
+ writable: true,
3402
+ value: function () {
3403
+ var _this = this;
3404
+ var offsets = ___default["default"](this.ids_after_a_gap.get())
3405
+ .keys()
3406
+ .map(function (num) { return _this.getZoomedColumnLeft(num); })
3407
+ .sort(function (a, b) { return a - b; })
3408
+ .value();
3409
+ // we only want to include this if gaps are on
3410
+ if (this.showGaps) {
3411
+ var last = this.getZoomedColumnLeft(this.id_order[this.id_order.length - 1]) +
3412
+ this.getGapSize() +
3413
+ this.cell_width +
3414
+ this.cell_padding;
3415
+ offsets.push(last);
3416
+ }
3417
+ return offsets;
3418
+ }
3419
+ });
3343
3420
  Object.defineProperty(OncoprintModel.prototype, "setTrackInfoTooltip", {
3344
3421
  enumerable: false,
3345
3422
  configurable: true,
@@ -4438,7 +4515,7 @@ var COLUMN_LABEL_ANGLE = 65;
4438
4515
  var COLUMN_LABEL_MARGIN = 30;
4439
4516
  var CELL_HIGHLIGHT_STROKE = 'rgba(0,0,0,0.5)';
4440
4517
  var OncoprintWebGLCellView = /** @class */ (function () {
4441
- function OncoprintWebGLCellView($container, $canvas, $overlay_canvas, $column_label_canvas, $dummy_scroll_div_contents, model, tooltip, highlight_area_callback, cell_over_callback, cell_click_callback) {
4518
+ function OncoprintWebGLCellView($container, $canvas, $overlay_canvas, $gap_canvas, $column_label_canvas, $dummy_scroll_div_contents, model, tooltip, highlight_area_callback, cell_over_callback, cell_click_callback) {
4442
4519
  Object.defineProperty(this, "$container", {
4443
4520
  enumerable: true,
4444
4521
  configurable: true,
@@ -4457,6 +4534,12 @@ var OncoprintWebGLCellView = /** @class */ (function () {
4457
4534
  writable: true,
4458
4535
  value: $overlay_canvas
4459
4536
  });
4537
+ Object.defineProperty(this, "$gap_canvas", {
4538
+ enumerable: true,
4539
+ configurable: true,
4540
+ writable: true,
4541
+ value: $gap_canvas
4542
+ });
4460
4543
  Object.defineProperty(this, "$column_label_canvas", {
4461
4544
  enumerable: true,
4462
4545
  configurable: true,
@@ -4529,6 +4612,12 @@ var OncoprintWebGLCellView = /** @class */ (function () {
4529
4612
  writable: true,
4530
4613
  value: void 0
4531
4614
  });
4615
+ Object.defineProperty(this, "gap_ctx", {
4616
+ enumerable: true,
4617
+ configurable: true,
4618
+ writable: true,
4619
+ value: void 0
4620
+ });
4532
4621
  Object.defineProperty(this, "ext", {
4533
4622
  enumerable: true,
4534
4623
  configurable: true,
@@ -4661,6 +4750,18 @@ var OncoprintWebGLCellView = /** @class */ (function () {
4661
4750
  writable: true,
4662
4751
  value: {}
4663
4752
  }); // index of first vertex corresponding to given id for given track, e.g. 0, 3, 6, ...
4753
+ Object.defineProperty(this, "gapTooltipTargets", {
4754
+ enumerable: true,
4755
+ configurable: true,
4756
+ writable: true,
4757
+ value: []
4758
+ });
4759
+ Object.defineProperty(this, "hoveredGap", {
4760
+ enumerable: true,
4761
+ configurable: true,
4762
+ writable: true,
4763
+ value: void 0
4764
+ });
4664
4765
  this.getWebGLContextAndSetUpMatrices();
4665
4766
  this.setUpShaders(model);
4666
4767
  this.getOverlayContextAndClear();
@@ -4767,9 +4868,28 @@ var OncoprintWebGLCellView = /** @class */ (function () {
4767
4868
  self.scroll_y, model.getTrackTooltipFn(overlapping_cells.track)(overlapping_data));
4768
4869
  }
4769
4870
  else {
4770
- tooltip.hideIfNotAlreadyGoingTo(150);
4771
4871
  overlapping_cells = null;
4772
4872
  }
4873
+ // find a gap which is in range of mouse position
4874
+ var overlappingGap = self.gapTooltipTargets.find(function (t) {
4875
+ return (___default["default"].inRange(mouseX - t.origin_x, 0, 20) &&
4876
+ ___default["default"].inRange(t.origin_y - mouseY, -10, 15));
4877
+ });
4878
+ // if there is no gap, turn
4879
+ if (overlappingGap === undefined) {
4880
+ self.hoveredGap = undefined;
4881
+ }
4882
+ else if (self.hoveredGap === overlappingGap) ;
4883
+ else {
4884
+ // we have a new hovered gap, so show a tooltip
4885
+ var clientRect = self.$overlay_canvas[0].getBoundingClientRect();
4886
+ self.hoveredGap = overlappingGap;
4887
+ tooltip.center = false;
4888
+ tooltip.show(250, clientRect.left + overlappingGap.origin_x, clientRect.top + overlappingGap.origin_y - 20, $__default["default"]("<span>" + overlappingGap.data.tooltipFormatter() + "</span>"), false);
4889
+ }
4890
+ if (!overlapping_data && !overlappingGap) {
4891
+ tooltip.hideIfNotAlreadyGoingTo(150);
4892
+ }
4773
4893
  }
4774
4894
  else {
4775
4895
  overlapping_cells = null;
@@ -4813,6 +4933,22 @@ var OncoprintWebGLCellView = /** @class */ (function () {
4813
4933
  self.highlightHighlightedTracks(model);
4814
4934
  });
4815
4935
  }
4936
+ Object.defineProperty(OncoprintWebGLCellView.prototype, "drawGapLabel", {
4937
+ enumerable: false,
4938
+ configurable: true,
4939
+ writable: true,
4940
+ value: function (txt, x, y) {
4941
+ this.gap_ctx.font = '15pt Arial';
4942
+ this.gap_ctx.textAlign = 'right';
4943
+ var origin_x = x * this.supersampling_ratio + 52;
4944
+ var origin_y = y * this.supersampling_ratio + 4;
4945
+ this.gap_ctx.fillText(txt, origin_x, origin_y);
4946
+ return {
4947
+ origin_x: x,
4948
+ origin_y: y,
4949
+ };
4950
+ }
4951
+ });
4816
4952
  Object.defineProperty(OncoprintWebGLCellView.prototype, "getNewCanvas", {
4817
4953
  enumerable: false,
4818
4954
  configurable: true,
@@ -4828,6 +4964,19 @@ var OncoprintWebGLCellView = /** @class */ (function () {
4828
4964
  this.ext = null;
4829
4965
  }
4830
4966
  });
4967
+ Object.defineProperty(OncoprintWebGLCellView.prototype, "getGapContext", {
4968
+ enumerable: false,
4969
+ configurable: true,
4970
+ writable: true,
4971
+ value: function () {
4972
+ try {
4973
+ return this.$gap_canvas[0].getContext('2d');
4974
+ }
4975
+ catch (e) {
4976
+ return null;
4977
+ }
4978
+ }
4979
+ });
4831
4980
  Object.defineProperty(OncoprintWebGLCellView.prototype, "getWebGLCanvasContext", {
4832
4981
  enumerable: false,
4833
4982
  configurable: true,
@@ -4991,6 +5140,7 @@ var OncoprintWebGLCellView = /** @class */ (function () {
4991
5140
  configurable: true,
4992
5141
  writable: true,
4993
5142
  value: function () {
5143
+ this.gap_ctx = this.getGapContext();
4994
5144
  this.ctx = this.getWebGLCanvasContext();
4995
5145
  if (this.ctx) {
4996
5146
  this.ext = this.ctx.getExtension('ANGLE_instanced_arrays');
@@ -5069,6 +5219,11 @@ var OncoprintWebGLCellView = /** @class */ (function () {
5069
5219
  this.dummy_scroll_div_client_size.update();
5070
5220
  this.$canvas[0].height = this.supersampling_ratio * height;
5071
5221
  this.$canvas[0].style.height = height + 'px';
5222
+ this.$gap_canvas[0].height = this.supersampling_ratio * height;
5223
+ this.$gap_canvas[0].style.height = height + 'px';
5224
+ this.$gap_canvas[0].width =
5225
+ this.supersampling_ratio * visible_area_width;
5226
+ this.$gap_canvas[0].style.width = visible_area_width + 'px';
5072
5227
  this.$overlay_canvas[0].height = this.supersampling_ratio * height;
5073
5228
  this.$overlay_canvas[0].style.height = height + 'px';
5074
5229
  this.$column_label_canvas[0].height = this.supersampling_ratio * height;
@@ -5094,6 +5249,7 @@ var OncoprintWebGLCellView = /** @class */ (function () {
5094
5249
  configurable: true,
5095
5250
  writable: true,
5096
5251
  value: function (model, dont_resize) {
5252
+ var _this = this;
5097
5253
  if (this.rendering_suppressed) {
5098
5254
  return;
5099
5255
  }
@@ -5123,75 +5279,98 @@ var OncoprintWebGLCellView = /** @class */ (function () {
5123
5279
  }
5124
5280
  this.ctx.clearColor(1.0, 1.0, 1.0, 1.0);
5125
5281
  this.ctx.clear(this.ctx.COLOR_BUFFER_BIT | this.ctx.DEPTH_BUFFER_BIT);
5282
+ this.gap_ctx.clearRect(0, 0, this.$gap_canvas[0].width, this.$gap_canvas[0].height);
5283
+ var gapOffsets = model.getGapOffsets();
5126
5284
  var tracks = model.getTracks();
5127
- for (var i = 0; i < tracks.length; i++) {
5285
+ this.gapTooltipTargets = [];
5286
+ var _loop_1 = function (i) {
5128
5287
  var track_id = tracks[i];
5129
5288
  var cell_top = model.getCellTops(track_id);
5130
5289
  var cell_height = model.getCellHeight(track_id);
5290
+ if (model.showGaps()) {
5291
+ var gaps = this_1.getGaps(model, track_id);
5292
+ if (gaps) {
5293
+ gaps.forEach(function (gap, i) {
5294
+ var x = gapOffsets[i] - scroll_x - model.getGapSize();
5295
+ var y = model.getZoomedTrackTops()[track_id] +
5296
+ cell_height -
5297
+ scroll_y;
5298
+ _this.drawGapLabel(gap.labelFormatter(), x, y);
5299
+ _this.gapTooltipTargets.push({
5300
+ origin_x: x,
5301
+ origin_y: y,
5302
+ data: gap,
5303
+ });
5304
+ });
5305
+ }
5306
+ }
5131
5307
  if (cell_top / zoom_y >= window_bottom ||
5132
5308
  (cell_top + cell_height) / zoom_y < window_top) {
5133
- // vertical clipping
5134
- continue;
5309
+ return "continue";
5135
5310
  }
5136
- var buffers = this.getTrackBuffers(track_id);
5311
+ var buffers = this_1.getTrackBuffers(track_id);
5137
5312
  if (buffers.position.numItems === 0) {
5138
- continue;
5313
+ return "continue";
5139
5314
  }
5140
5315
  for (var _i = 0, _a = [false, true]; _i < _a.length; _i++) {
5141
5316
  var forSpecificShapes = _a[_i];
5142
- var shader_program = this.shader_program;
5143
- this.ctx.useProgram(shader_program);
5317
+ var shader_program = this_1.shader_program;
5318
+ this_1.ctx.useProgram(shader_program);
5144
5319
  if (forSpecificShapes) {
5145
- this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, buffers.position);
5146
- this.ctx.vertexAttribPointer(shader_program.vertexPositionAttribute, buffers.position.itemSize, this.ctx.FLOAT, false, 0, 0);
5147
- this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, buffers.color);
5148
- this.ctx.vertexAttribPointer(shader_program.vertexColorAttribute, buffers.color.itemSize, this.ctx.FLOAT, false, 0, 0);
5149
- this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, buffers.column);
5150
- this.ctx.vertexAttribPointer(shader_program.vertexOncoprintColumnAttribute, buffers.column.itemSize, this.ctx.FLOAT, false, 0, 0);
5320
+ this_1.ctx.bindBuffer(this_1.ctx.ARRAY_BUFFER, buffers.position);
5321
+ this_1.ctx.vertexAttribPointer(shader_program.vertexPositionAttribute, buffers.position.itemSize, this_1.ctx.FLOAT, false, 0, 0);
5322
+ this_1.ctx.bindBuffer(this_1.ctx.ARRAY_BUFFER, buffers.color);
5323
+ this_1.ctx.vertexAttribPointer(shader_program.vertexColorAttribute, buffers.color.itemSize, this_1.ctx.FLOAT, false, 0, 0);
5324
+ this_1.ctx.bindBuffer(this_1.ctx.ARRAY_BUFFER, buffers.column);
5325
+ this_1.ctx.vertexAttribPointer(shader_program.vertexOncoprintColumnAttribute, buffers.column.itemSize, this_1.ctx.FLOAT, false, 0, 0);
5151
5326
  // make sure to set divisor 0, otherwise the track will only use the first item in the column buffer
5152
- this.ext.vertexAttribDivisorANGLE(shader_program.vertexOncoprintColumnAttribute, 0);
5327
+ this_1.ext.vertexAttribDivisorANGLE(shader_program.vertexOncoprintColumnAttribute, 0);
5153
5328
  }
5154
5329
  else {
5155
5330
  // set up for drawArraysInstanced
5156
5331
  var universalShapesStart = buffers.position.specificShapesNumItems *
5157
5332
  buffers.position.itemSize;
5158
- this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, buffers.position);
5159
- this.ctx.vertexAttribPointer(shader_program.vertexPositionAttribute, buffers.position.itemSize, this.ctx.FLOAT, false, 0, 4 * universalShapesStart);
5160
- this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, buffers.color);
5161
- this.ctx.vertexAttribPointer(shader_program.vertexColorAttribute, buffers.color.itemSize, this.ctx.FLOAT, false, 0, 4 * universalShapesStart);
5162
- this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, this.simple_count_buffer);
5163
- this.ctx.vertexAttribPointer(shader_program.vertexOncoprintColumnAttribute, 1, this.ctx.FLOAT, false, 0, 4 * horz_first_id_in_window_index);
5164
- this.ext.vertexAttribDivisorANGLE(shader_program.vertexOncoprintColumnAttribute, 1);
5333
+ this_1.ctx.bindBuffer(this_1.ctx.ARRAY_BUFFER, buffers.position);
5334
+ this_1.ctx.vertexAttribPointer(shader_program.vertexPositionAttribute, buffers.position.itemSize, this_1.ctx.FLOAT, false, 0, 4 * universalShapesStart);
5335
+ this_1.ctx.bindBuffer(this_1.ctx.ARRAY_BUFFER, buffers.color);
5336
+ this_1.ctx.vertexAttribPointer(shader_program.vertexColorAttribute, buffers.color.itemSize, this_1.ctx.FLOAT, false, 0, 4 * universalShapesStart);
5337
+ this_1.ctx.bindBuffer(this_1.ctx.ARRAY_BUFFER, this_1.simple_count_buffer);
5338
+ this_1.ctx.vertexAttribPointer(shader_program.vertexOncoprintColumnAttribute, 1, this_1.ctx.FLOAT, false, 0, 4 * horz_first_id_in_window_index);
5339
+ this_1.ext.vertexAttribDivisorANGLE(shader_program.vertexOncoprintColumnAttribute, 1);
5165
5340
  }
5166
- this.ctx.activeTexture(this.ctx.TEXTURE0);
5167
- this.ctx.bindTexture(this.ctx.TEXTURE_2D, buffers.color_tex.texture);
5168
- this.ctx.uniform1i(shader_program.samplerUniform, 0);
5169
- this.ctx.uniform1f(shader_program.texSizeUniform, buffers.color_tex.size);
5170
- this.ctx.uniform1fv(shader_program.columnsRightAfterGapsUniform, this.getColumnIndexesAfterAGap(model)); // need min size of 1
5171
- this.ctx.uniform1f(shader_program.gapSizeUniform, model.getGapSize());
5172
- this.ctx.uniformMatrix4fv(shader_program.pMatrixUniform, false, this.pMatrix);
5173
- this.ctx.uniformMatrix4fv(shader_program.mvMatrixUniform, false, this.mvMatrix);
5174
- this.ctx.uniform1f(shader_program.columnWidthUniform, model.getCellWidth(true) + model.getCellPadding(true));
5175
- this.ctx.uniform1f(shader_program.scrollXUniform, scroll_x);
5176
- this.ctx.uniform1f(shader_program.scrollYUniform, scroll_y);
5177
- this.ctx.uniform1f(shader_program.zoomXUniform, zoom_x);
5178
- this.ctx.uniform1f(shader_program.zoomYUniform, zoom_y);
5179
- this.ctx.uniform1f(shader_program.offsetYUniform, cell_top);
5180
- this.ctx.uniform1f(shader_program.supersamplingRatioUniform, this.supersampling_ratio);
5181
- this.ctx.uniform1f(shader_program.positionBitPackBaseUniform, this.position_bit_pack_base);
5341
+ this_1.ctx.activeTexture(this_1.ctx.TEXTURE0);
5342
+ this_1.ctx.bindTexture(this_1.ctx.TEXTURE_2D, buffers.color_tex.texture);
5343
+ this_1.ctx.uniform1i(shader_program.samplerUniform, 0);
5344
+ this_1.ctx.uniform1f(shader_program.texSizeUniform, buffers.color_tex.size);
5345
+ this_1.ctx.uniform1fv(shader_program.columnsRightAfterGapsUniform, this_1.getColumnIndexesAfterAGap(model)); // need min size of 1
5346
+ this_1.ctx.uniform1f(shader_program.gapSizeUniform, model.getGapSize());
5347
+ this_1.ctx.uniformMatrix4fv(shader_program.pMatrixUniform, false, this_1.pMatrix);
5348
+ this_1.ctx.uniformMatrix4fv(shader_program.mvMatrixUniform, false, this_1.mvMatrix);
5349
+ this_1.ctx.uniform1f(shader_program.columnWidthUniform, model.getCellWidth(true) + model.getCellPadding(true));
5350
+ this_1.ctx.uniform1f(shader_program.scrollXUniform, scroll_x);
5351
+ this_1.ctx.uniform1f(shader_program.scrollYUniform, scroll_y);
5352
+ this_1.ctx.uniform1f(shader_program.zoomXUniform, zoom_x);
5353
+ this_1.ctx.uniform1f(shader_program.zoomYUniform, zoom_y);
5354
+ this_1.ctx.uniform1f(shader_program.offsetYUniform, cell_top);
5355
+ this_1.ctx.uniform1f(shader_program.supersamplingRatioUniform, this_1.supersampling_ratio);
5356
+ this_1.ctx.uniform1f(shader_program.positionBitPackBaseUniform, this_1.position_bit_pack_base);
5182
5357
  if (forSpecificShapes) {
5183
- var first_index = this.id_to_first_vertex_index[track_id][horz_first_id_in_window];
5358
+ var first_index = this_1.id_to_first_vertex_index[track_id][horz_first_id_in_window];
5184
5359
  var first_index_out = horz_first_id_after_window === null
5185
5360
  ? buffers.position.specificShapesNumItems
5186
- : this.id_to_first_vertex_index[track_id][horz_first_id_after_window];
5187
- this.ctx.drawArrays(this.ctx.TRIANGLES, first_index, first_index_out - first_index);
5361
+ : this_1.id_to_first_vertex_index[track_id][horz_first_id_after_window];
5362
+ this_1.ctx.drawArrays(this_1.ctx.TRIANGLES, first_index, first_index_out - first_index);
5188
5363
  }
5189
5364
  else {
5190
- this.ext.drawArraysInstancedANGLE(this.ctx.TRIANGLES, 0, buffers.position.itemSize *
5365
+ this_1.ext.drawArraysInstancedANGLE(this_1.ctx.TRIANGLES, 0, buffers.position.itemSize *
5191
5366
  buffers.position.universalShapesNumItems, horz_first_id_after_window_index -
5192
5367
  horz_first_id_in_window_index);
5193
5368
  }
5194
5369
  }
5370
+ };
5371
+ var this_1 = this;
5372
+ for (var i = 0; i < tracks.length; i++) {
5373
+ _loop_1(i);
5195
5374
  }
5196
5375
  this.ctx.flush();
5197
5376
  this.renderColumnLabels(model, id_order.slice(horz_first_id_in_window_index, horz_first_id_after_window_index === -1
@@ -6200,21 +6379,57 @@ var OncoprintWebGLCellView = /** @class */ (function () {
6200
6379
  return this.dummy_scroll_div_client_size.get();
6201
6380
  }
6202
6381
  });
6382
+ Object.defineProperty(OncoprintWebGLCellView.prototype, "getGaps", {
6383
+ enumerable: false,
6384
+ configurable: true,
6385
+ writable: true,
6386
+ value: function (model, track_id) {
6387
+ var _a;
6388
+ var custom = model.getTrackCustomOptions(track_id);
6389
+ return ___default["default"].isEmpty(model.ids_after_a_gap.get())
6390
+ ? undefined
6391
+ : (_a = custom.find(function (t) { return !!t.gapLabelsFn; })) === null || _a === void 0 ? void 0 : _a.gapLabelsFn(model);
6392
+ }
6393
+ });
6203
6394
  Object.defineProperty(OncoprintWebGLCellView.prototype, "toSVGGroup", {
6204
6395
  enumerable: false,
6205
6396
  configurable: true,
6206
6397
  writable: true,
6207
6398
  value: function (model, offset_x, offset_y) {
6399
+ var _a;
6208
6400
  var root = svgfactory.group(offset_x || 0, offset_y || 0);
6209
6401
  var cell_tops = model.getCellTops();
6210
6402
  var tracks = model.getTracks();
6211
6403
  var zoomedColumnLeft = model.getZoomedColumnLeft();
6212
6404
  // add cell shapes
6213
- for (var i = 0; i < tracks.length; i++) {
6405
+ var gapOffsets = model.getGapOffsets();
6406
+ var _loop_2 = function (i) {
6214
6407
  var track_id = tracks[i];
6215
6408
  var offset_y_1 = cell_tops[track_id];
6409
+ var cell_height = model.getCellHeight(track_id);
6216
6410
  var universal_shapes = model.getTrackUniversalShapes(track_id, false);
6217
6411
  var identified_shape_list_list = model.getSpecificShapesForData(track_id, false);
6412
+ var custom = model.getTrackCustomOptions(track_id);
6413
+ if (gapOffsets[0]) {
6414
+ var gaps = ___default["default"].isEmpty(model.ids_after_a_gap.get())
6415
+ ? undefined
6416
+ : (_a = custom.find(function (t) { return !!t.gapLabelsFn; })) === null || _a === void 0 ? void 0 : _a.gapLabelsFn(model);
6417
+ if (gaps) {
6418
+ gaps.forEach(function (gap, i) {
6419
+ var textElt = makesvgelement('text', {
6420
+ x: gapOffsets[i] - model.getGapSize() + 25,
6421
+ y: offset_y_1 + cell_height - 3,
6422
+ 'font-size': '10',
6423
+ 'font-family': 'Arial',
6424
+ 'font-weight': 'normal',
6425
+ 'text-anchor': 'end',
6426
+ 'alignment-baseline': 'top',
6427
+ });
6428
+ textElt.textContent = gap.labelFormatter();
6429
+ root.appendChild(textElt);
6430
+ });
6431
+ }
6432
+ }
6218
6433
  for (var j = 0; j < identified_shape_list_list.length; j++) {
6219
6434
  var id_sl = identified_shape_list_list[j];
6220
6435
  var id = id_sl.id;
@@ -6233,6 +6448,9 @@ var OncoprintWebGLCellView = /** @class */ (function () {
6233
6448
  root.appendChild(svgfactory.fromShape(sl[h], offset_x_1, offset_y_1));
6234
6449
  }
6235
6450
  }
6451
+ };
6452
+ for (var i = 0; i < tracks.length; i++) {
6453
+ _loop_2(i);
6236
6454
  }
6237
6455
  // add column labels
6238
6456
  var labels = model.getColumnLabels();
@@ -9720,20 +9938,24 @@ var OncoprintTrackOptionsView = /** @class */ (function () {
9720
9938
  .addClass(SEPARATOR_CLASS);
9721
9939
  }
9722
9940
  });
9941
+ // 11/2/2023 we are removing sort arrow
9942
+ // leaving commented out if it needs to be restored based on complaint
9723
9943
  Object.defineProperty(OncoprintTrackOptionsView, "renderSortArrow", {
9724
9944
  enumerable: false,
9725
9945
  configurable: true,
9726
9946
  writable: true,
9727
9947
  value: function ($sortarrow, model, track_id) {
9728
- var sortarrow_char = '';
9729
- if (model.isTrackSortDirectionChangeable(track_id)) {
9730
- sortarrow_char = {
9731
- '1': '<i class="fa fa-signal" aria-hidden="true" title="Sorted ascending"></i>',
9732
- '-1': '<i class="fa fa-signal" style="transform: scaleX(-1);" aria-hidden="true" title="Sorted descending"></i>',
9733
- '0': '',
9734
- }[model.getTrackSortDirection(track_id)];
9735
- }
9736
- $sortarrow.html(sortarrow_char);
9948
+ // let sortarrow_char = '';
9949
+ // if (model.isTrackSortDirectionChangeable(track_id)) {
9950
+ // sortarrow_char = {
9951
+ // '1':
9952
+ // '<i class="fa fa-signal" aria-hidden="true" title="Sorted ascending"></i>',
9953
+ // '-1':
9954
+ // '<i class="fa fa-signal" style="transform: scaleX(-1);" aria-hidden="true" title="Sorted descending"></i>',
9955
+ // '0': '',
9956
+ // }[model.getTrackSortDirection(track_id)];
9957
+ // }
9958
+ // $sortarrow.html(sortarrow_char);
9737
9959
  }
9738
9960
  });
9739
9961
  Object.defineProperty(OncoprintTrackOptionsView.prototype, "renderTrackOptions", {
@@ -10827,7 +11049,7 @@ var OncoprintTrackInfoView = /** @class */ (function () {
10827
11049
  })
10828
11050
  .appendTo(this.$div);
10829
11051
  this.$text_ctr = $__default["default"]('<div></div>')
10830
- .css({ position: 'absolute' })
11052
+ .css({ position: 'absolute', overflow: 'visible', width: '100%' })
10831
11053
  .appendTo(this.$ctr);
10832
11054
  }
10833
11055
  Object.defineProperty(OncoprintTrackInfoView.prototype, "destroyLabelElts", {
@@ -10863,6 +11085,7 @@ var OncoprintTrackInfoView = /** @class */ (function () {
10863
11085
  var self = this;
10864
11086
  var _loop_1 = function (j) {
10865
11087
  (function () {
11088
+ var _a, _b;
10866
11089
  var i = j;
10867
11090
  var $new_label = $__default["default"]('<span>')
10868
11091
  .css({
@@ -10870,13 +11093,29 @@ var OncoprintTrackInfoView = /** @class */ (function () {
10870
11093
  'font-family': self.font_family,
10871
11094
  'font-weight': self.font_weight,
10872
11095
  'font-size': font_size,
11096
+ right: '11px',
10873
11097
  })
10874
11098
  .addClass('noselect');
10875
11099
  var text = model.getTrackInfo(tracks[i]);
10876
11100
  if (!text) {
10877
11101
  return;
10878
11102
  }
10879
- $new_label.text(text);
11103
+ var num = (_a = text.match(/^[\d\.]*/)) === null || _a === void 0 ? void 0 : _a[0];
11104
+ var suffix = (_b = text.match(/[^\d]*$/)) === null || _b === void 0 ? void 0 : _b[0];
11105
+ var float = parseFloat(num);
11106
+ var formattedPercent = '';
11107
+ if (isNaN(float)) {
11108
+ formattedPercent = 'N/P';
11109
+ suffix = ''; // we don't want any suffix in this case
11110
+ }
11111
+ else if (_.isNumber(float)) {
11112
+ formattedPercent =
11113
+ float < 1 && float > 0
11114
+ ? '<1'
11115
+ : Math.round(float).toString();
11116
+ }
11117
+ else ;
11118
+ $new_label.text(formattedPercent + suffix);
10880
11119
  $new_label.appendTo(self.$text_ctr);
10881
11120
  self.$label_elts.push($new_label);
10882
11121
  setTimeout(function () {
@@ -13116,6 +13355,10 @@ var Oncoprint = /** @class */ (function () {
13116
13355
  .attr({ width: '0px', height: '0px' })
13117
13356
  .css({ position: 'absolute', top: '0px', left: '0px' })
13118
13357
  .addClass('noselect');
13358
+ var $gap_canvas = $__default["default"]('<canvas></canvas>')
13359
+ .attr({ width: '0px', height: '0px' })
13360
+ .css({ position: 'absolute', top: '0px', left: '0px' })
13361
+ .addClass('noselect gap_canvas');
13119
13362
  var $dummy_scroll_div = $__default["default"]('<div>')
13120
13363
  .css({
13121
13364
  position: 'absolute',
@@ -13178,6 +13421,7 @@ var Oncoprint = /** @class */ (function () {
13178
13421
  $legend_div.appendTo($legend_ctr);
13179
13422
  $minimap_div.appendTo($ctr);
13180
13423
  $cell_canvas.appendTo($cell_div);
13424
+ $gap_canvas.appendTo($cell_div);
13181
13425
  $cell_overlay_canvas.appendTo($cell_div);
13182
13426
  $column_label_canvas.appendTo($cell_div); // column labels should show above the overlay canvas because the text should show over the highlights
13183
13427
  $dummy_scroll_div.appendTo($cell_div);
@@ -13199,7 +13443,7 @@ var Oncoprint = /** @class */ (function () {
13199
13443
  this.$cell_overlay_canvas = $cell_overlay_canvas;
13200
13444
  this.model = new OncoprintModel(params);
13201
13445
  this.header_view = new OncoprintHeaderView(this.$header_div);
13202
- this.cell_view = new OncoprintWebGLCellView($cell_div, $cell_canvas, $cell_overlay_canvas, $column_label_canvas, $dummy_scroll_div_contents, this.model, new OncoprintToolTip($tooltip_ctr), function (left, right) {
13446
+ this.cell_view = new OncoprintWebGLCellView($cell_div, $cell_canvas, $cell_overlay_canvas, $gap_canvas, $column_label_canvas, $dummy_scroll_div_contents, this.model, new OncoprintToolTip($tooltip_ctr), function (left, right) {
13203
13447
  var enclosed_ids = self.model.getIdsInZoomedLeftInterval(left, right);
13204
13448
  self.setHorzZoom(self.model.getHorzZoomToFit(self.cell_view.getVisibleAreaWidth(), enclosed_ids));
13205
13449
  self.$dummy_scroll_div.scrollLeft(self.model.getZoomedColumnLeft(enclosed_ids[0]));
@@ -14755,6 +14999,7 @@ var Oncoprint = /** @class */ (function () {
14755
14999
 
14756
15000
  exports.GeneticAlterationRuleSet = GeneticAlterationRuleSet;
14757
15001
  exports.OncoprintJS = Oncoprint;
15002
+ exports.OncoprintModel = OncoprintModel;
14758
15003
  exports.Rule = Rule;
14759
15004
  exports.RuleSet = RuleSet;
14760
15005
  exports.shapeToSvg = shapeToSVG;