@jbrowse/plugin-dotplot-view 2.15.0 → 2.15.1

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.
Files changed (25) hide show
  1. package/dist/DotplotDisplay/stateModelFactory.d.ts +6 -1
  2. package/dist/DotplotRenderer/DotplotRenderer.d.ts +1 -9
  3. package/dist/DotplotRenderer/DotplotRenderer.js +25 -214
  4. package/dist/DotplotRenderer/drawDotplot.d.ts +21 -0
  5. package/dist/DotplotRenderer/drawDotplot.js +216 -0
  6. package/dist/DotplotView/components/{DotplotTooltip.d.ts → DotplotTooltipClick.d.ts} +2 -8
  7. package/dist/DotplotView/components/DotplotTooltipClick.js +21 -0
  8. package/dist/DotplotView/components/DotplotTooltipMouseover.d.ts +10 -0
  9. package/dist/DotplotView/components/DotplotTooltipMouseover.js +20 -0
  10. package/dist/DotplotView/components/DotplotView.js +6 -3
  11. package/dist/DotplotView/model.d.ts +1 -0
  12. package/esm/DotplotDisplay/stateModelFactory.d.ts +6 -1
  13. package/esm/DotplotRenderer/DotplotRenderer.d.ts +1 -9
  14. package/esm/DotplotRenderer/DotplotRenderer.js +2 -214
  15. package/esm/DotplotRenderer/drawDotplot.d.ts +21 -0
  16. package/esm/DotplotRenderer/drawDotplot.js +213 -0
  17. package/esm/DotplotView/components/{DotplotTooltip.d.ts → DotplotTooltipClick.d.ts} +2 -8
  18. package/esm/DotplotView/components/DotplotTooltipClick.js +15 -0
  19. package/esm/DotplotView/components/DotplotTooltipMouseover.d.ts +10 -0
  20. package/esm/DotplotView/components/DotplotTooltipMouseover.js +15 -0
  21. package/esm/DotplotView/components/DotplotView.js +7 -4
  22. package/esm/DotplotView/model.d.ts +1 -0
  23. package/package.json +2 -2
  24. package/dist/DotplotView/components/DotplotTooltip.js +0 -84
  25. package/esm/DotplotView/components/DotplotTooltip.js +0 -78
@@ -25,7 +25,12 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
25
25
  error: unknown;
26
26
  message: string | undefined;
27
27
  } & {
28
- readonly RenderingComponent: React.FC<{
28
+ readonly RenderingComponent: React.
29
+ /**
30
+ * #stateModel DotplotDisplay
31
+ * #category display
32
+ */
33
+ FC<{
29
34
  model: {
30
35
  id: string;
31
36
  type: string;
@@ -27,14 +27,6 @@ interface DotplotRenderArgs extends RenderArgs {
27
27
  export default class DotplotRenderer extends ComparativeRenderer {
28
28
  supportsSVG: boolean;
29
29
  renameRegionsIfNeeded(args: DotplotRenderArgs): Promise<DotplotRenderArgs>;
30
- drawDotplot(ctx: CanvasRenderingContext2D, props: DotplotRenderArgsDeserialized & {
31
- views: Dotplot1DViewModel[];
32
- }): Promise<{
33
- warnings: {
34
- message: string;
35
- effect: string;
36
- }[];
37
- }>;
38
30
  render(renderProps: DotplotRenderArgsDeserialized): Promise<{
39
31
  height: number;
40
32
  width: number;
@@ -52,7 +44,7 @@ export default class DotplotRenderer extends ComparativeRenderer {
52
44
  offsetY: number;
53
45
  bpPerPxX: number;
54
46
  bpPerPxY: number;
55
- reactElement: import("react").JSX.Element;
47
+ reactElement: React.JSX.Element;
56
48
  html?: string;
57
49
  } | {
58
50
  height: number;
@@ -1,27 +1,35 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
5
28
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const configuration_1 = require("@jbrowse/core/configuration");
7
29
  const util_1 = require("@jbrowse/core/util");
8
- const Base1DUtils_1 = require("@jbrowse/core/util/Base1DUtils");
9
- const mobx_state_tree_1 = require("mobx-state-tree");
10
30
  const ComparativeServerSideRendererType_1 = __importDefault(require("@jbrowse/core/pluggableElementTypes/renderers/ComparativeServerSideRendererType"));
11
- const plugin_alignments_1 = require("@jbrowse/plugin-alignments");
12
31
  // locals
13
32
  const model_1 = require("../DotplotView/model");
14
- const ui_1 = require("@jbrowse/core/ui");
15
- const { parseCigar } = plugin_alignments_1.MismatchParser;
16
- const r = 'fell outside of range due to CIGAR string';
17
- const lt = '(less than min coordinate of feature)';
18
- const gt = '(greater than max coordinate of feature)';
19
- const fudgeFactor = 1; // allow 1px fuzzyness before warn
20
- function drawCir(ctx, x, y, r = 1) {
21
- ctx.beginPath();
22
- ctx.arc(x, y, r / 2, 0, 2 * Math.PI);
23
- ctx.fill();
24
- }
25
33
  class DotplotRenderer extends ComparativeServerSideRendererType_1.default {
26
34
  constructor() {
27
35
  super(...arguments);
@@ -47,204 +55,6 @@ class DotplotRenderer extends ComparativeServerSideRendererType_1.default {
47
55
  view.vview.displayedRegions = await process(view.vview.displayedRegions);
48
56
  return args;
49
57
  }
50
- async drawDotplot(ctx, props) {
51
- var _a, _b;
52
- const { config, views, height, drawCigar, theme } = props;
53
- const color = (0, configuration_1.readConfObject)(config, 'color');
54
- const posColor = (0, configuration_1.readConfObject)(config, 'posColor');
55
- const negColor = (0, configuration_1.readConfObject)(config, 'negColor');
56
- const colorBy = (0, configuration_1.readConfObject)(config, 'colorBy');
57
- const lineWidth = (0, configuration_1.readConfObject)(config, 'lineWidth');
58
- const thresholds = (0, configuration_1.readConfObject)(config, 'thresholds');
59
- const palette = (0, configuration_1.readConfObject)(config, 'thresholdsPalette');
60
- const isCallback = config.color.isCallback;
61
- const hview = views[0];
62
- const vview = views[1];
63
- const db1 = (_a = hview.dynamicBlocks.contentBlocks[0]) === null || _a === void 0 ? void 0 : _a.offsetPx;
64
- const db2 = (_b = vview.dynamicBlocks.contentBlocks[0]) === null || _b === void 0 ? void 0 : _b.offsetPx;
65
- const warnings = [];
66
- ctx.lineWidth = lineWidth;
67
- // we operate on snapshots of these attributes of the hview/vview because
68
- // it is significantly faster than accessing the mobx objects
69
- const { bpPerPx: hBpPerPx } = hview;
70
- const { bpPerPx: vBpPerPx } = vview;
71
- function clampWithWarnX(num, min, max, feature) {
72
- const strand = feature.get('strand') || 1;
73
- if (strand === -1) {
74
- ;
75
- [max, min] = [min, max];
76
- }
77
- if (num < min - fudgeFactor) {
78
- let start = feature.get('start');
79
- let end = feature.get('end');
80
- const refName = feature.get('refName');
81
- if (strand === -1) {
82
- ;
83
- [end, start] = [start, end];
84
- }
85
- warnings.push({
86
- message: `feature at (X ${refName}:${start}-${end}) ${r} ${lt}`,
87
- effect: 'clipped the feature',
88
- });
89
- return min;
90
- }
91
- if (num > max + fudgeFactor) {
92
- const strand = feature.get('strand') || 1;
93
- const start = strand === 1 ? feature.get('start') : feature.get('end');
94
- const end = strand === 1 ? feature.get('end') : feature.get('start');
95
- const refName = feature.get('refName');
96
- warnings.push({
97
- message: `feature at (X ${refName}:${start}-${end}) ${r} ${gt}`,
98
- effect: 'clipped the feature',
99
- });
100
- return max;
101
- }
102
- return num;
103
- }
104
- function clampWithWarnY(num, min, max, feature) {
105
- if (num < min - fudgeFactor) {
106
- const mate = feature.get('mate');
107
- const { refName, start, end } = mate;
108
- warnings.push({
109
- message: `feature at (Y ${refName}:${start}-${end}) ${r} ${lt}`,
110
- effect: 'clipped the feature',
111
- });
112
- return min;
113
- }
114
- if (num > max + fudgeFactor) {
115
- const mate = feature.get('mate');
116
- const { refName, start, end } = mate;
117
- warnings.push({
118
- message: `feature at (Y ${refName}:${start}-${end}) ${r} ${gt}`,
119
- effect: 'clipped the feature',
120
- });
121
- return max;
122
- }
123
- return num;
124
- }
125
- const hsnap = {
126
- ...(0, mobx_state_tree_1.getSnapshot)(hview),
127
- staticBlocks: hview.staticBlocks,
128
- width: hview.width,
129
- };
130
- const vsnap = {
131
- ...(0, mobx_state_tree_1.getSnapshot)(vview),
132
- staticBlocks: vview.staticBlocks,
133
- width: vview.width,
134
- };
135
- const t = (0, ui_1.createJBrowseTheme)(theme);
136
- for (const feature of hview.features || []) {
137
- const strand = feature.get('strand') || 1;
138
- const start = strand === 1 ? feature.get('start') : feature.get('end');
139
- const end = strand === 1 ? feature.get('end') : feature.get('start');
140
- const refName = feature.get('refName');
141
- const mate = feature.get('mate');
142
- const mateRef = mate.refName;
143
- let r = 'black';
144
- if (colorBy === 'identity') {
145
- const identity = feature.get('identity');
146
- for (let i = 0; i < thresholds.length; i++) {
147
- if (identity > +thresholds[i]) {
148
- r = palette[i] || 'black';
149
- break;
150
- }
151
- }
152
- }
153
- else if (colorBy === 'meanQueryIdentity') {
154
- r = `hsl(${feature.get('meanScore') * 200},100%,40%)`;
155
- }
156
- else if (colorBy === 'mappingQuality') {
157
- r = `hsl(${feature.get('mappingQual')},100%,40%)`;
158
- }
159
- else if (colorBy === 'strand') {
160
- r = strand === -1 ? negColor : posColor;
161
- }
162
- else if (colorBy === 'default') {
163
- r = isCallback
164
- ? (0, configuration_1.readConfObject)(config, 'color', { feature })
165
- : color === '#f0f'
166
- ? t.palette.text.primary
167
- : color;
168
- }
169
- ctx.fillStyle = r;
170
- ctx.strokeStyle = r;
171
- const b10 = (0, Base1DUtils_1.bpToPx)({ self: hsnap, refName, coord: start });
172
- const b20 = (0, Base1DUtils_1.bpToPx)({ self: hsnap, refName, coord: end });
173
- const e10 = (0, Base1DUtils_1.bpToPx)({ self: vsnap, refName: mateRef, coord: mate.start });
174
- const e20 = (0, Base1DUtils_1.bpToPx)({ self: vsnap, refName: mateRef, coord: mate.end });
175
- if (b10 !== undefined &&
176
- b20 !== undefined &&
177
- e10 !== undefined &&
178
- e20 !== undefined) {
179
- const b1 = b10.offsetPx - db1;
180
- const b2 = b20.offsetPx - db1;
181
- const e1 = e10.offsetPx - db2;
182
- const e2 = e20.offsetPx - db2;
183
- if (Math.abs(b1 - b2) <= 4 && Math.abs(e1 - e2) <= 4) {
184
- drawCir(ctx, b1, height - e1, lineWidth);
185
- }
186
- else {
187
- let currX = b1;
188
- let currY = e1;
189
- const cigar = feature.get('CIGAR');
190
- if (drawCigar && cigar) {
191
- const cigarOps = parseCigar(cigar);
192
- ctx.beginPath();
193
- ctx.moveTo(currX, height - currY);
194
- let lastDrawnX = currX;
195
- let lastDrawnY = currX;
196
- for (let i = 0; i < cigarOps.length; i += 2) {
197
- const val = +cigarOps[i];
198
- const op = cigarOps[i + 1];
199
- if (op === 'M' || op === '=' || op === 'X') {
200
- currX += (val / hBpPerPx) * strand;
201
- currY += val / vBpPerPx;
202
- }
203
- else if (op === 'D' || op === 'N') {
204
- currX += (val / hBpPerPx) * strand;
205
- }
206
- else if (op === 'I') {
207
- currY += val / vBpPerPx;
208
- }
209
- currX = clampWithWarnX(currX, b1, b2, feature);
210
- currY = clampWithWarnY(currY, e1, e2, feature);
211
- // only draw a line segment if it is bigger than 0.5px
212
- if (Math.abs(currX - lastDrawnX) > 0.5 ||
213
- Math.abs(currY - lastDrawnY) > 0.5) {
214
- ctx.lineTo(currX, height - currY);
215
- lastDrawnX = currX;
216
- lastDrawnY = currY;
217
- }
218
- }
219
- ctx.stroke();
220
- }
221
- else {
222
- ctx.beginPath();
223
- ctx.moveTo(b1, height - e1);
224
- ctx.lineTo(b2, height - e2);
225
- ctx.stroke();
226
- }
227
- }
228
- }
229
- else {
230
- if (warnings.length <= 5) {
231
- if (b10 === undefined || b20 === undefined) {
232
- warnings.push({
233
- message: `feature at (X ${refName}:${start}-${end}) not plotted, fell outside of range`,
234
- effect: 'feature not rendered',
235
- });
236
- }
237
- else {
238
- warnings.push({
239
- message: `feature at (Y ${mateRef}:${mate.start}-${mate.end}) not plotted, fell outside of range`,
240
- effect: 'feature not rendered',
241
- });
242
- }
243
- }
244
- }
245
- }
246
- return { warnings };
247
- }
248
58
  async render(renderProps) {
249
59
  var _a, _b;
250
60
  const { width, height, view: { hview, vview }, } = renderProps;
@@ -260,7 +70,8 @@ class DotplotRenderer extends ComparativeServerSideRendererType_1.default {
260
70
  regions: target.dynamicBlocks.contentBlocks,
261
71
  });
262
72
  target.setFeatures(feats);
263
- const ret = await (0, util_1.renderToAbstractCanvas)(width, height, renderProps, ctx => this.drawDotplot(ctx, { ...renderProps, views }));
73
+ const { drawDotplot } = await Promise.resolve().then(() => __importStar(require('./drawDotplot')));
74
+ const ret = await (0, util_1.renderToAbstractCanvas)(width, height, renderProps, ctx => drawDotplot(ctx, { ...renderProps, views }));
264
75
  const results = await super.render({
265
76
  ...renderProps,
266
77
  ...ret,
@@ -0,0 +1,21 @@
1
+ import { AnyConfigurationModel } from '@jbrowse/core/configuration';
2
+ import { RenderArgsDeserialized } from '@jbrowse/core/pluggableElementTypes/renderers/ComparativeServerSideRendererType';
3
+ import { Dotplot1DViewModel } from '../DotplotView/model';
4
+ export interface DotplotRenderArgsDeserialized extends RenderArgsDeserialized {
5
+ adapterConfig: AnyConfigurationModel;
6
+ height: number;
7
+ width: number;
8
+ highResolutionScaling: number;
9
+ view: {
10
+ hview: Dotplot1DViewModel;
11
+ vview: Dotplot1DViewModel;
12
+ };
13
+ }
14
+ export declare function drawDotplot(ctx: CanvasRenderingContext2D, props: DotplotRenderArgsDeserialized & {
15
+ views: Dotplot1DViewModel[];
16
+ }): Promise<{
17
+ warnings: {
18
+ message: string;
19
+ effect: string;
20
+ }[];
21
+ }>;
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.drawDotplot = drawDotplot;
4
+ const configuration_1 = require("@jbrowse/core/configuration");
5
+ const Base1DUtils_1 = require("@jbrowse/core/util/Base1DUtils");
6
+ const mobx_state_tree_1 = require("mobx-state-tree");
7
+ const plugin_alignments_1 = require("@jbrowse/plugin-alignments");
8
+ const ui_1 = require("@jbrowse/core/ui");
9
+ const { parseCigar } = plugin_alignments_1.MismatchParser;
10
+ const r = 'fell outside of range due to CIGAR string';
11
+ const lt = '(less than min coordinate of feature)';
12
+ const gt = '(greater than max coordinate of feature)';
13
+ const fudgeFactor = 1; // allow 1px fuzzyness before warn
14
+ function drawCir(ctx, x, y, r = 1) {
15
+ ctx.beginPath();
16
+ ctx.arc(x, y, r / 2, 0, 2 * Math.PI);
17
+ ctx.fill();
18
+ }
19
+ async function drawDotplot(ctx, props) {
20
+ var _a, _b;
21
+ const { config, views, height, drawCigar, theme } = props;
22
+ const color = (0, configuration_1.readConfObject)(config, 'color');
23
+ const posColor = (0, configuration_1.readConfObject)(config, 'posColor');
24
+ const negColor = (0, configuration_1.readConfObject)(config, 'negColor');
25
+ const colorBy = (0, configuration_1.readConfObject)(config, 'colorBy');
26
+ const lineWidth = (0, configuration_1.readConfObject)(config, 'lineWidth');
27
+ const thresholds = (0, configuration_1.readConfObject)(config, 'thresholds');
28
+ const palette = (0, configuration_1.readConfObject)(config, 'thresholdsPalette');
29
+ const isCallback = config.color.isCallback;
30
+ const hview = views[0];
31
+ const vview = views[1];
32
+ const db1 = (_a = hview.dynamicBlocks.contentBlocks[0]) === null || _a === void 0 ? void 0 : _a.offsetPx;
33
+ const db2 = (_b = vview.dynamicBlocks.contentBlocks[0]) === null || _b === void 0 ? void 0 : _b.offsetPx;
34
+ const warnings = [];
35
+ ctx.lineWidth = lineWidth;
36
+ // we operate on snapshots of these attributes of the hview/vview because
37
+ // it is significantly faster than accessing the mobx objects
38
+ const { bpPerPx: hBpPerPx } = hview;
39
+ const { bpPerPx: vBpPerPx } = vview;
40
+ function clampWithWarnX(num, min, max, feature) {
41
+ const strand = feature.get('strand') || 1;
42
+ if (strand === -1) {
43
+ ;
44
+ [max, min] = [min, max];
45
+ }
46
+ if (num < min - fudgeFactor) {
47
+ let start = feature.get('start');
48
+ let end = feature.get('end');
49
+ const refName = feature.get('refName');
50
+ if (strand === -1) {
51
+ ;
52
+ [end, start] = [start, end];
53
+ }
54
+ warnings.push({
55
+ message: `feature at (X ${refName}:${start}-${end}) ${r} ${lt}`,
56
+ effect: 'clipped the feature',
57
+ });
58
+ return min;
59
+ }
60
+ if (num > max + fudgeFactor) {
61
+ const strand = feature.get('strand') || 1;
62
+ const start = strand === 1 ? feature.get('start') : feature.get('end');
63
+ const end = strand === 1 ? feature.get('end') : feature.get('start');
64
+ const refName = feature.get('refName');
65
+ warnings.push({
66
+ message: `feature at (X ${refName}:${start}-${end}) ${r} ${gt}`,
67
+ effect: 'clipped the feature',
68
+ });
69
+ return max;
70
+ }
71
+ return num;
72
+ }
73
+ function clampWithWarnY(num, min, max, feature) {
74
+ if (num < min - fudgeFactor) {
75
+ const mate = feature.get('mate');
76
+ const { refName, start, end } = mate;
77
+ warnings.push({
78
+ message: `feature at (Y ${refName}:${start}-${end}) ${r} ${lt}`,
79
+ effect: 'clipped the feature',
80
+ });
81
+ return min;
82
+ }
83
+ if (num > max + fudgeFactor) {
84
+ const mate = feature.get('mate');
85
+ const { refName, start, end } = mate;
86
+ warnings.push({
87
+ message: `feature at (Y ${refName}:${start}-${end}) ${r} ${gt}`,
88
+ effect: 'clipped the feature',
89
+ });
90
+ return max;
91
+ }
92
+ return num;
93
+ }
94
+ const hsnap = {
95
+ ...(0, mobx_state_tree_1.getSnapshot)(hview),
96
+ staticBlocks: hview.staticBlocks,
97
+ width: hview.width,
98
+ };
99
+ const vsnap = {
100
+ ...(0, mobx_state_tree_1.getSnapshot)(vview),
101
+ staticBlocks: vview.staticBlocks,
102
+ width: vview.width,
103
+ };
104
+ const t = (0, ui_1.createJBrowseTheme)(theme);
105
+ for (const feature of hview.features || []) {
106
+ const strand = feature.get('strand') || 1;
107
+ const start = strand === 1 ? feature.get('start') : feature.get('end');
108
+ const end = strand === 1 ? feature.get('end') : feature.get('start');
109
+ const refName = feature.get('refName');
110
+ const mate = feature.get('mate');
111
+ const mateRef = mate.refName;
112
+ let r = 'black';
113
+ if (colorBy === 'identity') {
114
+ const identity = feature.get('identity');
115
+ for (let i = 0; i < thresholds.length; i++) {
116
+ if (identity > +thresholds[i]) {
117
+ r = palette[i] || 'black';
118
+ break;
119
+ }
120
+ }
121
+ }
122
+ else if (colorBy === 'meanQueryIdentity') {
123
+ r = `hsl(${feature.get('meanScore') * 200},100%,40%)`;
124
+ }
125
+ else if (colorBy === 'mappingQuality') {
126
+ r = `hsl(${feature.get('mappingQual')},100%,40%)`;
127
+ }
128
+ else if (colorBy === 'strand') {
129
+ r = strand === -1 ? negColor : posColor;
130
+ }
131
+ else if (colorBy === 'default') {
132
+ r = isCallback
133
+ ? (0, configuration_1.readConfObject)(config, 'color', { feature })
134
+ : color === '#f0f'
135
+ ? t.palette.text.primary
136
+ : color;
137
+ }
138
+ ctx.fillStyle = r;
139
+ ctx.strokeStyle = r;
140
+ const b10 = (0, Base1DUtils_1.bpToPx)({ self: hsnap, refName, coord: start });
141
+ const b20 = (0, Base1DUtils_1.bpToPx)({ self: hsnap, refName, coord: end });
142
+ const e10 = (0, Base1DUtils_1.bpToPx)({ self: vsnap, refName: mateRef, coord: mate.start });
143
+ const e20 = (0, Base1DUtils_1.bpToPx)({ self: vsnap, refName: mateRef, coord: mate.end });
144
+ if (b10 !== undefined &&
145
+ b20 !== undefined &&
146
+ e10 !== undefined &&
147
+ e20 !== undefined) {
148
+ const b1 = b10.offsetPx - db1;
149
+ const b2 = b20.offsetPx - db1;
150
+ const e1 = e10.offsetPx - db2;
151
+ const e2 = e20.offsetPx - db2;
152
+ if (Math.abs(b1 - b2) <= 4 && Math.abs(e1 - e2) <= 4) {
153
+ drawCir(ctx, b1, height - e1, lineWidth);
154
+ }
155
+ else {
156
+ let currX = b1;
157
+ let currY = e1;
158
+ const cigar = feature.get('CIGAR');
159
+ if (drawCigar && cigar) {
160
+ const cigarOps = parseCigar(cigar);
161
+ ctx.beginPath();
162
+ ctx.moveTo(currX, height - currY);
163
+ let lastDrawnX = currX;
164
+ let lastDrawnY = currX;
165
+ for (let i = 0; i < cigarOps.length; i += 2) {
166
+ const val = +cigarOps[i];
167
+ const op = cigarOps[i + 1];
168
+ if (op === 'M' || op === '=' || op === 'X') {
169
+ currX += (val / hBpPerPx) * strand;
170
+ currY += val / vBpPerPx;
171
+ }
172
+ else if (op === 'D' || op === 'N') {
173
+ currX += (val / hBpPerPx) * strand;
174
+ }
175
+ else if (op === 'I') {
176
+ currY += val / vBpPerPx;
177
+ }
178
+ currX = clampWithWarnX(currX, b1, b2, feature);
179
+ currY = clampWithWarnY(currY, e1, e2, feature);
180
+ // only draw a line segment if it is bigger than 0.5px
181
+ if (Math.abs(currX - lastDrawnX) > 0.5 ||
182
+ Math.abs(currY - lastDrawnY) > 0.5) {
183
+ ctx.lineTo(currX, height - currY);
184
+ lastDrawnX = currX;
185
+ lastDrawnY = currY;
186
+ }
187
+ }
188
+ ctx.stroke();
189
+ }
190
+ else {
191
+ ctx.beginPath();
192
+ ctx.moveTo(b1, height - e1);
193
+ ctx.lineTo(b2, height - e2);
194
+ ctx.stroke();
195
+ }
196
+ }
197
+ }
198
+ else {
199
+ if (warnings.length <= 5) {
200
+ if (b10 === undefined || b20 === undefined) {
201
+ warnings.push({
202
+ message: `feature at (X ${refName}:${start}-${end}) not plotted, fell outside of range`,
203
+ effect: 'feature not rendered',
204
+ });
205
+ }
206
+ else {
207
+ warnings.push({
208
+ message: `feature at (Y ${mateRef}:${mate.start}-${mate.end}) not plotted, fell outside of range`,
209
+ effect: 'feature not rendered',
210
+ });
211
+ }
212
+ }
213
+ }
214
+ }
215
+ return { warnings };
216
+ }
@@ -1,17 +1,11 @@
1
1
  import React from 'react';
2
2
  import { DotplotViewModel } from '../model';
3
3
  type Coord = [number, number] | undefined;
4
- export declare const TooltipWhereMouseovered: ({ model, mouserect, mouserectClient, xdistance, }: {
5
- model: DotplotViewModel;
6
- mouserect: Coord;
7
- mouserectClient: Coord;
8
- xdistance: number;
9
- }) => React.JSX.Element | null;
10
- export declare const TooltipWhereClicked: ({ model, mousedown, mousedownClient, xdistance, ydistance, }: {
4
+ export declare const DotplotTooltipClick: ({ model, mousedown, mousedownClient, xdistance, ydistance, }: {
11
5
  model: DotplotViewModel;
12
6
  mousedown: Coord;
13
7
  mousedownClient: Coord;
14
8
  xdistance: number;
15
9
  ydistance: number;
16
10
  }) => React.JSX.Element | null;
17
- export {};
11
+ export default DotplotTooltipClick;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DotplotTooltipClick = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const mobx_react_1 = require("mobx-react");
9
+ const BaseTooltip_1 = __importDefault(require("@jbrowse/core/ui/BaseTooltip"));
10
+ const util_1 = require("./util");
11
+ exports.DotplotTooltipClick = (0, mobx_react_1.observer)(function ({ model, mousedown, mousedownClient, xdistance, ydistance, }) {
12
+ const { hview, vview, viewHeight } = model;
13
+ const x = ((mousedownClient === null || mousedownClient === void 0 ? void 0 : mousedownClient[0]) || 0) - (xdistance < 0 ? 0 : 0);
14
+ const y = ((mousedownClient === null || mousedownClient === void 0 ? void 0 : mousedownClient[1]) || 0) - (ydistance < 0 ? 0 : 0);
15
+ return mousedown && Math.abs(xdistance) > 3 && Math.abs(ydistance) > 3 ? (react_1.default.createElement(BaseTooltip_1.default, { clientPoint: { x, y } },
16
+ `x - ${(0, util_1.locstr)(mousedown[0], hview)}`,
17
+ react_1.default.createElement("br", null),
18
+ `y - ${(0, util_1.locstr)(viewHeight - mousedown[1], vview)}`,
19
+ react_1.default.createElement("br", null))) : null;
20
+ });
21
+ exports.default = exports.DotplotTooltipClick;
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { DotplotViewModel } from '../model';
3
+ type Coord = [number, number] | undefined;
4
+ declare const DotplotTooltipMouseover: ({ model, mouserect, mouserectClient, xdistance, }: {
5
+ model: DotplotViewModel;
6
+ mouserect: Coord;
7
+ mouserectClient: Coord;
8
+ xdistance: number;
9
+ }) => React.JSX.Element | null;
10
+ export default DotplotTooltipMouseover;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const mobx_react_1 = require("mobx-react");
8
+ const BaseTooltip_1 = __importDefault(require("@jbrowse/core/ui/BaseTooltip"));
9
+ const util_1 = require("./util");
10
+ const DotplotTooltipMouseover = (0, mobx_react_1.observer)(function ({ model, mouserect, mouserectClient, xdistance, }) {
11
+ const { hview, vview, viewHeight } = model;
12
+ return mouserect ? (react_1.default.createElement(BaseTooltip_1.default, { placement: xdistance < 0 ? 'left' : 'right', clientPoint: mouserectClient
13
+ ? { x: mouserectClient[0], y: mouserectClient[1] }
14
+ : undefined },
15
+ `x - ${(0, util_1.locstr)(mouserect[0], hview)}`,
16
+ react_1.default.createElement("br", null),
17
+ `y - ${(0, util_1.locstr)(viewHeight - mouserect[1], vview)}`,
18
+ react_1.default.createElement("br", null))) : null;
19
+ });
20
+ exports.default = DotplotTooltipMouseover;
@@ -35,7 +35,8 @@ const ImportForm_1 = __importDefault(require("./ImportForm"));
35
35
  const Header_1 = __importDefault(require("./Header"));
36
36
  const Grid_1 = __importDefault(require("./Grid"));
37
37
  const Axes_1 = require("./Axes");
38
- const DotplotTooltip_1 = require("./DotplotTooltip");
38
+ const TooltipWhereClicked = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./DotplotTooltipClick'))));
39
+ const TooltipWhereMouseovered = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./DotplotTooltipMouseover'))));
39
40
  const blank = { left: 0, top: 0, width: 0, height: 0 };
40
41
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
41
42
  spacer: {
@@ -222,8 +223,10 @@ const DotplotViewInternal = (0, mobx_react_1.observer)(function ({ model, }) {
222
223
  react_1.default.createElement(Axes_1.VerticalAxis, { model: model }),
223
224
  react_1.default.createElement(Axes_1.HorizontalAxis, { model: model }),
224
225
  react_1.default.createElement("div", { ref: ref, className: classes.content },
225
- mouseOvered && validSelect ? (react_1.default.createElement(DotplotTooltip_1.TooltipWhereMouseovered, { model: model, mouserect: mouserect, mouserectClient: mouserectClient, xdistance: xdistance })) : null,
226
- validSelect ? (react_1.default.createElement(DotplotTooltip_1.TooltipWhereClicked, { model: model, mousedown: mousedown, mousedownClient: mousedownClient, xdistance: xdistance, ydistance: ydistance })) : null,
226
+ mouseOvered && validSelect ? (react_1.default.createElement(react_1.Suspense, { fallback: null },
227
+ react_1.default.createElement(TooltipWhereMouseovered, { model: model, mouserect: mouserect, mouserectClient: mouserectClient, xdistance: xdistance }))) : null,
228
+ validSelect ? (react_1.default.createElement(react_1.Suspense, { fallback: null },
229
+ react_1.default.createElement(TooltipWhereClicked, { model: model, mousedown: mousedown, mousedownClient: mousedownClient, xdistance: xdistance, ydistance: ydistance }))) : null,
227
230
  react_1.default.createElement("div", { style: { cursor: ctrlKeyDown ? 'pointer' : cursorMode }, onMouseDown: event => {
228
231
  if (event.button === 0) {
229
232
  const { clientX, clientY } = event;
@@ -194,6 +194,7 @@ export default function stateModelFactory(pm: PluginManager): import("mobx-state
194
194
  trackMenuItems(): (import("@jbrowse/core/ui").MenuDivider | import("@jbrowse/core/ui").MenuSubHeader | import("@jbrowse/core/ui").NormalMenuItem | import("@jbrowse/core/ui").CheckboxMenuItem | import("@jbrowse/core/ui").RadioMenuItem | import("@jbrowse/core/ui").SubMenuItem | {
195
195
  type: string;
196
196
  label: string;
197
+ priority: number;
197
198
  subMenu: {
198
199
  type: string;
199
200
  label: string;
@@ -25,7 +25,12 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
25
25
  error: unknown;
26
26
  message: string | undefined;
27
27
  } & {
28
- readonly RenderingComponent: React.FC<{
28
+ readonly RenderingComponent: React.
29
+ /**
30
+ * #stateModel DotplotDisplay
31
+ * #category display
32
+ */
33
+ FC<{
29
34
  model: {
30
35
  id: string;
31
36
  type: string;