@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
@@ -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,22 +1,7 @@
1
- import { readConfObject, } from '@jbrowse/core/configuration';
2
1
  import { renameRegionsIfNeeded, renderToAbstractCanvas, } from '@jbrowse/core/util';
3
- import { bpToPx } from '@jbrowse/core/util/Base1DUtils';
4
- import { getSnapshot } from 'mobx-state-tree';
5
2
  import ComparativeRenderer from '@jbrowse/core/pluggableElementTypes/renderers/ComparativeServerSideRendererType';
6
- import { MismatchParser } from '@jbrowse/plugin-alignments';
7
3
  // locals
8
4
  import { Dotplot1DView } from '../DotplotView/model';
9
- import { createJBrowseTheme } from '@jbrowse/core/ui';
10
- const { parseCigar } = MismatchParser;
11
- const r = 'fell outside of range due to CIGAR string';
12
- const lt = '(less than min coordinate of feature)';
13
- const gt = '(greater than max coordinate of feature)';
14
- const fudgeFactor = 1; // allow 1px fuzzyness before warn
15
- function drawCir(ctx, x, y, r = 1) {
16
- ctx.beginPath();
17
- ctx.arc(x, y, r / 2, 0, 2 * Math.PI);
18
- ctx.fill();
19
- }
20
5
  export default class DotplotRenderer extends ComparativeRenderer {
21
6
  constructor() {
22
7
  super(...arguments);
@@ -42,204 +27,6 @@ export default class DotplotRenderer extends ComparativeRenderer {
42
27
  view.vview.displayedRegions = await process(view.vview.displayedRegions);
43
28
  return args;
44
29
  }
45
- async drawDotplot(ctx, props) {
46
- var _a, _b;
47
- const { config, views, height, drawCigar, theme } = props;
48
- const color = readConfObject(config, 'color');
49
- const posColor = readConfObject(config, 'posColor');
50
- const negColor = readConfObject(config, 'negColor');
51
- const colorBy = readConfObject(config, 'colorBy');
52
- const lineWidth = readConfObject(config, 'lineWidth');
53
- const thresholds = readConfObject(config, 'thresholds');
54
- const palette = readConfObject(config, 'thresholdsPalette');
55
- const isCallback = config.color.isCallback;
56
- const hview = views[0];
57
- const vview = views[1];
58
- const db1 = (_a = hview.dynamicBlocks.contentBlocks[0]) === null || _a === void 0 ? void 0 : _a.offsetPx;
59
- const db2 = (_b = vview.dynamicBlocks.contentBlocks[0]) === null || _b === void 0 ? void 0 : _b.offsetPx;
60
- const warnings = [];
61
- ctx.lineWidth = lineWidth;
62
- // we operate on snapshots of these attributes of the hview/vview because
63
- // it is significantly faster than accessing the mobx objects
64
- const { bpPerPx: hBpPerPx } = hview;
65
- const { bpPerPx: vBpPerPx } = vview;
66
- function clampWithWarnX(num, min, max, feature) {
67
- const strand = feature.get('strand') || 1;
68
- if (strand === -1) {
69
- ;
70
- [max, min] = [min, max];
71
- }
72
- if (num < min - fudgeFactor) {
73
- let start = feature.get('start');
74
- let end = feature.get('end');
75
- const refName = feature.get('refName');
76
- if (strand === -1) {
77
- ;
78
- [end, start] = [start, end];
79
- }
80
- warnings.push({
81
- message: `feature at (X ${refName}:${start}-${end}) ${r} ${lt}`,
82
- effect: 'clipped the feature',
83
- });
84
- return min;
85
- }
86
- if (num > max + fudgeFactor) {
87
- const strand = feature.get('strand') || 1;
88
- const start = strand === 1 ? feature.get('start') : feature.get('end');
89
- const end = strand === 1 ? feature.get('end') : feature.get('start');
90
- const refName = feature.get('refName');
91
- warnings.push({
92
- message: `feature at (X ${refName}:${start}-${end}) ${r} ${gt}`,
93
- effect: 'clipped the feature',
94
- });
95
- return max;
96
- }
97
- return num;
98
- }
99
- function clampWithWarnY(num, min, max, feature) {
100
- if (num < min - fudgeFactor) {
101
- const mate = feature.get('mate');
102
- const { refName, start, end } = mate;
103
- warnings.push({
104
- message: `feature at (Y ${refName}:${start}-${end}) ${r} ${lt}`,
105
- effect: 'clipped the feature',
106
- });
107
- return min;
108
- }
109
- if (num > max + fudgeFactor) {
110
- const mate = feature.get('mate');
111
- const { refName, start, end } = mate;
112
- warnings.push({
113
- message: `feature at (Y ${refName}:${start}-${end}) ${r} ${gt}`,
114
- effect: 'clipped the feature',
115
- });
116
- return max;
117
- }
118
- return num;
119
- }
120
- const hsnap = {
121
- ...getSnapshot(hview),
122
- staticBlocks: hview.staticBlocks,
123
- width: hview.width,
124
- };
125
- const vsnap = {
126
- ...getSnapshot(vview),
127
- staticBlocks: vview.staticBlocks,
128
- width: vview.width,
129
- };
130
- const t = createJBrowseTheme(theme);
131
- for (const feature of hview.features || []) {
132
- const strand = feature.get('strand') || 1;
133
- const start = strand === 1 ? feature.get('start') : feature.get('end');
134
- const end = strand === 1 ? feature.get('end') : feature.get('start');
135
- const refName = feature.get('refName');
136
- const mate = feature.get('mate');
137
- const mateRef = mate.refName;
138
- let r = 'black';
139
- if (colorBy === 'identity') {
140
- const identity = feature.get('identity');
141
- for (let i = 0; i < thresholds.length; i++) {
142
- if (identity > +thresholds[i]) {
143
- r = palette[i] || 'black';
144
- break;
145
- }
146
- }
147
- }
148
- else if (colorBy === 'meanQueryIdentity') {
149
- r = `hsl(${feature.get('meanScore') * 200},100%,40%)`;
150
- }
151
- else if (colorBy === 'mappingQuality') {
152
- r = `hsl(${feature.get('mappingQual')},100%,40%)`;
153
- }
154
- else if (colorBy === 'strand') {
155
- r = strand === -1 ? negColor : posColor;
156
- }
157
- else if (colorBy === 'default') {
158
- r = isCallback
159
- ? readConfObject(config, 'color', { feature })
160
- : color === '#f0f'
161
- ? t.palette.text.primary
162
- : color;
163
- }
164
- ctx.fillStyle = r;
165
- ctx.strokeStyle = r;
166
- const b10 = bpToPx({ self: hsnap, refName, coord: start });
167
- const b20 = bpToPx({ self: hsnap, refName, coord: end });
168
- const e10 = bpToPx({ self: vsnap, refName: mateRef, coord: mate.start });
169
- const e20 = bpToPx({ self: vsnap, refName: mateRef, coord: mate.end });
170
- if (b10 !== undefined &&
171
- b20 !== undefined &&
172
- e10 !== undefined &&
173
- e20 !== undefined) {
174
- const b1 = b10.offsetPx - db1;
175
- const b2 = b20.offsetPx - db1;
176
- const e1 = e10.offsetPx - db2;
177
- const e2 = e20.offsetPx - db2;
178
- if (Math.abs(b1 - b2) <= 4 && Math.abs(e1 - e2) <= 4) {
179
- drawCir(ctx, b1, height - e1, lineWidth);
180
- }
181
- else {
182
- let currX = b1;
183
- let currY = e1;
184
- const cigar = feature.get('CIGAR');
185
- if (drawCigar && cigar) {
186
- const cigarOps = parseCigar(cigar);
187
- ctx.beginPath();
188
- ctx.moveTo(currX, height - currY);
189
- let lastDrawnX = currX;
190
- let lastDrawnY = currX;
191
- for (let i = 0; i < cigarOps.length; i += 2) {
192
- const val = +cigarOps[i];
193
- const op = cigarOps[i + 1];
194
- if (op === 'M' || op === '=' || op === 'X') {
195
- currX += (val / hBpPerPx) * strand;
196
- currY += val / vBpPerPx;
197
- }
198
- else if (op === 'D' || op === 'N') {
199
- currX += (val / hBpPerPx) * strand;
200
- }
201
- else if (op === 'I') {
202
- currY += val / vBpPerPx;
203
- }
204
- currX = clampWithWarnX(currX, b1, b2, feature);
205
- currY = clampWithWarnY(currY, e1, e2, feature);
206
- // only draw a line segment if it is bigger than 0.5px
207
- if (Math.abs(currX - lastDrawnX) > 0.5 ||
208
- Math.abs(currY - lastDrawnY) > 0.5) {
209
- ctx.lineTo(currX, height - currY);
210
- lastDrawnX = currX;
211
- lastDrawnY = currY;
212
- }
213
- }
214
- ctx.stroke();
215
- }
216
- else {
217
- ctx.beginPath();
218
- ctx.moveTo(b1, height - e1);
219
- ctx.lineTo(b2, height - e2);
220
- ctx.stroke();
221
- }
222
- }
223
- }
224
- else {
225
- if (warnings.length <= 5) {
226
- if (b10 === undefined || b20 === undefined) {
227
- warnings.push({
228
- message: `feature at (X ${refName}:${start}-${end}) not plotted, fell outside of range`,
229
- effect: 'feature not rendered',
230
- });
231
- }
232
- else {
233
- warnings.push({
234
- message: `feature at (Y ${mateRef}:${mate.start}-${mate.end}) not plotted, fell outside of range`,
235
- effect: 'feature not rendered',
236
- });
237
- }
238
- }
239
- }
240
- }
241
- return { warnings };
242
- }
243
30
  async render(renderProps) {
244
31
  var _a, _b;
245
32
  const { width, height, view: { hview, vview }, } = renderProps;
@@ -255,7 +42,8 @@ export default class DotplotRenderer extends ComparativeRenderer {
255
42
  regions: target.dynamicBlocks.contentBlocks,
256
43
  });
257
44
  target.setFeatures(feats);
258
- const ret = await renderToAbstractCanvas(width, height, renderProps, ctx => this.drawDotplot(ctx, { ...renderProps, views }));
45
+ const { drawDotplot } = await import('./drawDotplot');
46
+ const ret = await renderToAbstractCanvas(width, height, renderProps, ctx => drawDotplot(ctx, { ...renderProps, views }));
259
47
  const results = await super.render({
260
48
  ...renderProps,
261
49
  ...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,213 @@
1
+ import { readConfObject, } from '@jbrowse/core/configuration';
2
+ import { bpToPx } from '@jbrowse/core/util/Base1DUtils';
3
+ import { getSnapshot } from 'mobx-state-tree';
4
+ import { MismatchParser } from '@jbrowse/plugin-alignments';
5
+ import { createJBrowseTheme } from '@jbrowse/core/ui';
6
+ const { parseCigar } = MismatchParser;
7
+ const r = 'fell outside of range due to CIGAR string';
8
+ const lt = '(less than min coordinate of feature)';
9
+ const gt = '(greater than max coordinate of feature)';
10
+ const fudgeFactor = 1; // allow 1px fuzzyness before warn
11
+ function drawCir(ctx, x, y, r = 1) {
12
+ ctx.beginPath();
13
+ ctx.arc(x, y, r / 2, 0, 2 * Math.PI);
14
+ ctx.fill();
15
+ }
16
+ export async function drawDotplot(ctx, props) {
17
+ var _a, _b;
18
+ const { config, views, height, drawCigar, theme } = props;
19
+ const color = readConfObject(config, 'color');
20
+ const posColor = readConfObject(config, 'posColor');
21
+ const negColor = readConfObject(config, 'negColor');
22
+ const colorBy = readConfObject(config, 'colorBy');
23
+ const lineWidth = readConfObject(config, 'lineWidth');
24
+ const thresholds = readConfObject(config, 'thresholds');
25
+ const palette = readConfObject(config, 'thresholdsPalette');
26
+ const isCallback = config.color.isCallback;
27
+ const hview = views[0];
28
+ const vview = views[1];
29
+ const db1 = (_a = hview.dynamicBlocks.contentBlocks[0]) === null || _a === void 0 ? void 0 : _a.offsetPx;
30
+ const db2 = (_b = vview.dynamicBlocks.contentBlocks[0]) === null || _b === void 0 ? void 0 : _b.offsetPx;
31
+ const warnings = [];
32
+ ctx.lineWidth = lineWidth;
33
+ // we operate on snapshots of these attributes of the hview/vview because
34
+ // it is significantly faster than accessing the mobx objects
35
+ const { bpPerPx: hBpPerPx } = hview;
36
+ const { bpPerPx: vBpPerPx } = vview;
37
+ function clampWithWarnX(num, min, max, feature) {
38
+ const strand = feature.get('strand') || 1;
39
+ if (strand === -1) {
40
+ ;
41
+ [max, min] = [min, max];
42
+ }
43
+ if (num < min - fudgeFactor) {
44
+ let start = feature.get('start');
45
+ let end = feature.get('end');
46
+ const refName = feature.get('refName');
47
+ if (strand === -1) {
48
+ ;
49
+ [end, start] = [start, end];
50
+ }
51
+ warnings.push({
52
+ message: `feature at (X ${refName}:${start}-${end}) ${r} ${lt}`,
53
+ effect: 'clipped the feature',
54
+ });
55
+ return min;
56
+ }
57
+ if (num > max + fudgeFactor) {
58
+ const strand = feature.get('strand') || 1;
59
+ const start = strand === 1 ? feature.get('start') : feature.get('end');
60
+ const end = strand === 1 ? feature.get('end') : feature.get('start');
61
+ const refName = feature.get('refName');
62
+ warnings.push({
63
+ message: `feature at (X ${refName}:${start}-${end}) ${r} ${gt}`,
64
+ effect: 'clipped the feature',
65
+ });
66
+ return max;
67
+ }
68
+ return num;
69
+ }
70
+ function clampWithWarnY(num, min, max, feature) {
71
+ if (num < min - fudgeFactor) {
72
+ const mate = feature.get('mate');
73
+ const { refName, start, end } = mate;
74
+ warnings.push({
75
+ message: `feature at (Y ${refName}:${start}-${end}) ${r} ${lt}`,
76
+ effect: 'clipped the feature',
77
+ });
78
+ return min;
79
+ }
80
+ if (num > max + fudgeFactor) {
81
+ const mate = feature.get('mate');
82
+ const { refName, start, end } = mate;
83
+ warnings.push({
84
+ message: `feature at (Y ${refName}:${start}-${end}) ${r} ${gt}`,
85
+ effect: 'clipped the feature',
86
+ });
87
+ return max;
88
+ }
89
+ return num;
90
+ }
91
+ const hsnap = {
92
+ ...getSnapshot(hview),
93
+ staticBlocks: hview.staticBlocks,
94
+ width: hview.width,
95
+ };
96
+ const vsnap = {
97
+ ...getSnapshot(vview),
98
+ staticBlocks: vview.staticBlocks,
99
+ width: vview.width,
100
+ };
101
+ const t = createJBrowseTheme(theme);
102
+ for (const feature of hview.features || []) {
103
+ const strand = feature.get('strand') || 1;
104
+ const start = strand === 1 ? feature.get('start') : feature.get('end');
105
+ const end = strand === 1 ? feature.get('end') : feature.get('start');
106
+ const refName = feature.get('refName');
107
+ const mate = feature.get('mate');
108
+ const mateRef = mate.refName;
109
+ let r = 'black';
110
+ if (colorBy === 'identity') {
111
+ const identity = feature.get('identity');
112
+ for (let i = 0; i < thresholds.length; i++) {
113
+ if (identity > +thresholds[i]) {
114
+ r = palette[i] || 'black';
115
+ break;
116
+ }
117
+ }
118
+ }
119
+ else if (colorBy === 'meanQueryIdentity') {
120
+ r = `hsl(${feature.get('meanScore') * 200},100%,40%)`;
121
+ }
122
+ else if (colorBy === 'mappingQuality') {
123
+ r = `hsl(${feature.get('mappingQual')},100%,40%)`;
124
+ }
125
+ else if (colorBy === 'strand') {
126
+ r = strand === -1 ? negColor : posColor;
127
+ }
128
+ else if (colorBy === 'default') {
129
+ r = isCallback
130
+ ? readConfObject(config, 'color', { feature })
131
+ : color === '#f0f'
132
+ ? t.palette.text.primary
133
+ : color;
134
+ }
135
+ ctx.fillStyle = r;
136
+ ctx.strokeStyle = r;
137
+ const b10 = bpToPx({ self: hsnap, refName, coord: start });
138
+ const b20 = bpToPx({ self: hsnap, refName, coord: end });
139
+ const e10 = bpToPx({ self: vsnap, refName: mateRef, coord: mate.start });
140
+ const e20 = bpToPx({ self: vsnap, refName: mateRef, coord: mate.end });
141
+ if (b10 !== undefined &&
142
+ b20 !== undefined &&
143
+ e10 !== undefined &&
144
+ e20 !== undefined) {
145
+ const b1 = b10.offsetPx - db1;
146
+ const b2 = b20.offsetPx - db1;
147
+ const e1 = e10.offsetPx - db2;
148
+ const e2 = e20.offsetPx - db2;
149
+ if (Math.abs(b1 - b2) <= 4 && Math.abs(e1 - e2) <= 4) {
150
+ drawCir(ctx, b1, height - e1, lineWidth);
151
+ }
152
+ else {
153
+ let currX = b1;
154
+ let currY = e1;
155
+ const cigar = feature.get('CIGAR');
156
+ if (drawCigar && cigar) {
157
+ const cigarOps = parseCigar(cigar);
158
+ ctx.beginPath();
159
+ ctx.moveTo(currX, height - currY);
160
+ let lastDrawnX = currX;
161
+ let lastDrawnY = currX;
162
+ for (let i = 0; i < cigarOps.length; i += 2) {
163
+ const val = +cigarOps[i];
164
+ const op = cigarOps[i + 1];
165
+ if (op === 'M' || op === '=' || op === 'X') {
166
+ currX += (val / hBpPerPx) * strand;
167
+ currY += val / vBpPerPx;
168
+ }
169
+ else if (op === 'D' || op === 'N') {
170
+ currX += (val / hBpPerPx) * strand;
171
+ }
172
+ else if (op === 'I') {
173
+ currY += val / vBpPerPx;
174
+ }
175
+ currX = clampWithWarnX(currX, b1, b2, feature);
176
+ currY = clampWithWarnY(currY, e1, e2, feature);
177
+ // only draw a line segment if it is bigger than 0.5px
178
+ if (Math.abs(currX - lastDrawnX) > 0.5 ||
179
+ Math.abs(currY - lastDrawnY) > 0.5) {
180
+ ctx.lineTo(currX, height - currY);
181
+ lastDrawnX = currX;
182
+ lastDrawnY = currY;
183
+ }
184
+ }
185
+ ctx.stroke();
186
+ }
187
+ else {
188
+ ctx.beginPath();
189
+ ctx.moveTo(b1, height - e1);
190
+ ctx.lineTo(b2, height - e2);
191
+ ctx.stroke();
192
+ }
193
+ }
194
+ }
195
+ else {
196
+ if (warnings.length <= 5) {
197
+ if (b10 === undefined || b20 === undefined) {
198
+ warnings.push({
199
+ message: `feature at (X ${refName}:${start}-${end}) not plotted, fell outside of range`,
200
+ effect: 'feature not rendered',
201
+ });
202
+ }
203
+ else {
204
+ warnings.push({
205
+ message: `feature at (Y ${mateRef}:${mate.start}-${mate.end}) not plotted, fell outside of range`,
206
+ effect: 'feature not rendered',
207
+ });
208
+ }
209
+ }
210
+ }
211
+ }
212
+ return { warnings };
213
+ }
@@ -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,15 @@
1
+ import React from 'react';
2
+ import { observer } from 'mobx-react';
3
+ import BaseTooltip from '@jbrowse/core/ui/BaseTooltip';
4
+ import { locstr } from './util';
5
+ export const DotplotTooltipClick = observer(function ({ model, mousedown, mousedownClient, xdistance, ydistance, }) {
6
+ const { hview, vview, viewHeight } = model;
7
+ const x = ((mousedownClient === null || mousedownClient === void 0 ? void 0 : mousedownClient[0]) || 0) - (xdistance < 0 ? 0 : 0);
8
+ const y = ((mousedownClient === null || mousedownClient === void 0 ? void 0 : mousedownClient[1]) || 0) - (ydistance < 0 ? 0 : 0);
9
+ return mousedown && Math.abs(xdistance) > 3 && Math.abs(ydistance) > 3 ? (React.createElement(BaseTooltip, { clientPoint: { x, y } },
10
+ `x - ${locstr(mousedown[0], hview)}`,
11
+ React.createElement("br", null),
12
+ `y - ${locstr(viewHeight - mousedown[1], vview)}`,
13
+ React.createElement("br", null))) : null;
14
+ });
15
+ export default 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,15 @@
1
+ import React from 'react';
2
+ import { observer } from 'mobx-react';
3
+ import BaseTooltip from '@jbrowse/core/ui/BaseTooltip';
4
+ import { locstr } from './util';
5
+ const DotplotTooltipMouseover = observer(function ({ model, mouserect, mouserectClient, xdistance, }) {
6
+ const { hview, vview, viewHeight } = model;
7
+ return mouserect ? (React.createElement(BaseTooltip, { placement: xdistance < 0 ? 'left' : 'right', clientPoint: mouserectClient
8
+ ? { x: mouserectClient[0], y: mouserectClient[1] }
9
+ : undefined },
10
+ `x - ${locstr(mouserect[0], hview)}`,
11
+ React.createElement("br", null),
12
+ `y - ${locstr(viewHeight - mouserect[1], vview)}`,
13
+ React.createElement("br", null))) : null;
14
+ });
15
+ export default DotplotTooltipMouseover;
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useRef } from 'react';
1
+ import React, { useState, useEffect, useRef, lazy, Suspense } from 'react';
2
2
  import { LoadingEllipses, Menu, ResizeHandle } from '@jbrowse/core/ui';
3
3
  import { observer } from 'mobx-react';
4
4
  import { transaction } from 'mobx';
@@ -7,7 +7,8 @@ import ImportForm from './ImportForm';
7
7
  import Header from './Header';
8
8
  import Grid from './Grid';
9
9
  import { VerticalAxis, HorizontalAxis } from './Axes';
10
- import { TooltipWhereClicked, TooltipWhereMouseovered } from './DotplotTooltip';
10
+ const TooltipWhereClicked = lazy(() => import('./DotplotTooltipClick'));
11
+ const TooltipWhereMouseovered = lazy(() => import('./DotplotTooltipMouseover'));
11
12
  const blank = { left: 0, top: 0, width: 0, height: 0 };
12
13
  const useStyles = makeStyles()(theme => ({
13
14
  spacer: {
@@ -194,8 +195,10 @@ const DotplotViewInternal = observer(function ({ model, }) {
194
195
  React.createElement(VerticalAxis, { model: model }),
195
196
  React.createElement(HorizontalAxis, { model: model }),
196
197
  React.createElement("div", { ref: ref, className: classes.content },
197
- mouseOvered && validSelect ? (React.createElement(TooltipWhereMouseovered, { model: model, mouserect: mouserect, mouserectClient: mouserectClient, xdistance: xdistance })) : null,
198
- validSelect ? (React.createElement(TooltipWhereClicked, { model: model, mousedown: mousedown, mousedownClient: mousedownClient, xdistance: xdistance, ydistance: ydistance })) : null,
198
+ mouseOvered && validSelect ? (React.createElement(Suspense, { fallback: null },
199
+ React.createElement(TooltipWhereMouseovered, { model: model, mouserect: mouserect, mouserectClient: mouserectClient, xdistance: xdistance }))) : null,
200
+ validSelect ? (React.createElement(Suspense, { fallback: null },
201
+ React.createElement(TooltipWhereClicked, { model: model, mousedown: mousedown, mousedownClient: mousedownClient, xdistance: xdistance, ydistance: ydistance }))) : null,
199
202
  React.createElement("div", { style: { cursor: ctrlKeyDown ? 'pointer' : cursorMode }, onMouseDown: event => {
200
203
  if (event.button === 0) {
201
204
  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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-dotplot-view",
3
- "version": "2.15.0",
3
+ "version": "2.15.1",
4
4
  "description": "JBrowse 2 dotplot view",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -61,5 +61,5 @@
61
61
  "publishConfig": {
62
62
  "access": "public"
63
63
  },
64
- "gitHead": "87eeb1fbf8311dbf88d5e75b5a265f03beffdda8"
64
+ "gitHead": "86ed70124fc5a0b1161266659d1ca9f8796bf3fe"
65
65
  }