@jbrowse/plugin-linear-comparative-view 2.16.0 → 2.16.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 (43) hide show
  1. package/dist/LGVSyntenyDisplay/components/LaunchSyntenyViewDialog.d.ts +2 -1
  2. package/dist/LGVSyntenyDisplay/components/LaunchSyntenyViewDialog.js +4 -2
  3. package/dist/LGVSyntenyDisplay/components/util.d.ts +4 -1
  4. package/dist/LGVSyntenyDisplay/components/util.js +7 -15
  5. package/dist/LGVSyntenyDisplay/model.d.ts +26 -14
  6. package/dist/LGVSyntenyDisplay/model.js +23 -1
  7. package/dist/LinearComparativeDisplay/stateModelFactory.d.ts +28 -5
  8. package/dist/LinearComparativeDisplay/stateModelFactory.js +14 -3
  9. package/dist/LinearSyntenyDisplay/afterAttach.js +2 -3
  10. package/dist/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +22 -15
  11. package/dist/LinearSyntenyDisplay/components/SyntenyContextMenu.js +2 -4
  12. package/dist/LinearSyntenyDisplay/components/util.d.ts +5 -1
  13. package/dist/LinearSyntenyDisplay/components/util.js +7 -9
  14. package/dist/LinearSyntenyDisplay/drawSynteny.js +7 -9
  15. package/dist/LinearSyntenyDisplay/model.d.ts +48 -11
  16. package/dist/LinearSyntenyDisplay/model.js +38 -22
  17. package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.d.ts +14 -0
  18. package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.js +100 -0
  19. package/dist/SyntenyFeatureDetail/index.d.ts +2 -0
  20. package/dist/SyntenyFeatureDetail/index.js +56 -0
  21. package/dist/index.js +2 -0
  22. package/esm/LGVSyntenyDisplay/components/LaunchSyntenyViewDialog.d.ts +2 -1
  23. package/esm/LGVSyntenyDisplay/components/LaunchSyntenyViewDialog.js +4 -2
  24. package/esm/LGVSyntenyDisplay/components/util.d.ts +4 -1
  25. package/esm/LGVSyntenyDisplay/components/util.js +8 -16
  26. package/esm/LGVSyntenyDisplay/model.d.ts +26 -14
  27. package/esm/LGVSyntenyDisplay/model.js +25 -3
  28. package/esm/LinearComparativeDisplay/stateModelFactory.d.ts +28 -5
  29. package/esm/LinearComparativeDisplay/stateModelFactory.js +14 -3
  30. package/esm/LinearSyntenyDisplay/afterAttach.js +3 -4
  31. package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +22 -15
  32. package/esm/LinearSyntenyDisplay/components/SyntenyContextMenu.js +2 -4
  33. package/esm/LinearSyntenyDisplay/components/util.d.ts +5 -1
  34. package/esm/LinearSyntenyDisplay/components/util.js +7 -9
  35. package/esm/LinearSyntenyDisplay/drawSynteny.js +7 -9
  36. package/esm/LinearSyntenyDisplay/model.d.ts +48 -11
  37. package/esm/LinearSyntenyDisplay/model.js +39 -23
  38. package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.d.ts +14 -0
  39. package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.js +72 -0
  40. package/esm/SyntenyFeatureDetail/index.d.ts +2 -0
  41. package/esm/SyntenyFeatureDetail/index.js +27 -0
  42. package/esm/index.js +2 -0
  43. package/package.json +3 -3
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  import { Feature } from '@jbrowse/core/util';
3
- export default function LaunchSyntenyViewDialog({ model, feature, handleClose, }: {
3
+ export default function LaunchSyntenyViewDialog({ model, feature, trackId, handleClose, }: {
4
4
  model: unknown;
5
5
  feature: Feature;
6
+ trackId: string;
6
7
  handleClose: () => void;
7
8
  }): React.JSX.Element;
@@ -28,15 +28,16 @@ const react_1 = __importStar(require("react"));
28
28
  const ui_1 = require("@jbrowse/core/ui");
29
29
  const util_1 = require("@jbrowse/core/util");
30
30
  const material_1 = require("@mui/material");
31
- const util_2 = require("./util");
32
31
  const mui_1 = require("tss-react/mui");
32
+ // locals
33
+ const util_2 = require("./util");
33
34
  const useStyles = (0, mui_1.makeStyles)()({
34
35
  padding: {
35
36
  margin: 10,
36
37
  border: '1px solid #ccc',
37
38
  },
38
39
  });
39
- function LaunchSyntenyViewDialog({ model, feature, handleClose, }) {
40
+ function LaunchSyntenyViewDialog({ model, feature, trackId, handleClose, }) {
40
41
  const { classes } = useStyles();
41
42
  const inverted = feature.get('strand') === -1;
42
43
  const [horizontallyFlip, setHorizontallyFlip] = (0, react_1.useState)(inverted);
@@ -59,6 +60,7 @@ function LaunchSyntenyViewDialog({ model, feature, handleClose, }) {
59
60
  feature,
60
61
  windowSize: +windowSize,
61
62
  horizontallyFlip,
63
+ trackId,
62
64
  model,
63
65
  });
64
66
  }
@@ -1,8 +1,11 @@
1
1
  import { Feature } from '@jbrowse/core/util';
2
2
  import { IAnyStateTreeNode } from 'mobx-state-tree';
3
- export declare function navToSynteny({ feature, windowSize: ws, model, horizontallyFlip, }: {
3
+ import { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
4
+ export declare function navToSynteny({ feature, windowSize: ws, model, trackId, view, horizontallyFlip, }: {
4
5
  windowSize: number;
6
+ trackId: string;
5
7
  horizontallyFlip: boolean;
6
8
  feature: Feature;
9
+ view?: LinearGenomeViewModel;
7
10
  model: IAnyStateTreeNode;
8
11
  }): Promise<void>;
@@ -30,18 +30,13 @@ function findPosInCigar(cigar, startX) {
30
30
  }
31
31
  return [featX, mateX];
32
32
  }
33
- async function navToSynteny({ feature, windowSize: ws, model, horizontallyFlip, }) {
33
+ async function navToSynteny({ feature, windowSize: ws, model, trackId, view, horizontallyFlip, }) {
34
34
  const session = (0, util_1.getSession)(model);
35
- const track = (0, util_1.getContainingTrack)(model);
36
- const view = (0, util_1.getContainingView)(model);
37
- const reg = view.dynamicBlocks.contentBlocks[0];
38
- if (!reg) {
39
- throw new Error('no visible region');
40
- }
35
+ const reg = view === null || view === void 0 ? void 0 : view.dynamicBlocks.contentBlocks[0];
41
36
  const cigar = feature.get('CIGAR');
42
37
  const strand = feature.get('strand');
43
- const regStart = reg.start;
44
- const regEnd = reg.end;
38
+ const featRef = feature.get('refName');
39
+ const featAsm = feature.get('assemblyName');
45
40
  const featStart = feature.get('start');
46
41
  const featEnd = feature.get('end');
47
42
  const mate = feature.get('mate');
@@ -49,13 +44,13 @@ async function navToSynteny({ feature, windowSize: ws, model, horizontallyFlip,
49
44
  const mateEnd = mate.end;
50
45
  const mateAsm = mate.assemblyName;
51
46
  const mateRef = mate.refName;
52
- const featAsm = reg.assemblyName;
53
- const featRef = reg.refName;
54
47
  let rMateStart;
55
48
  let rMateEnd;
56
49
  let rFeatStart;
57
50
  let rFeatEnd;
58
- if (cigar) {
51
+ if (reg && cigar) {
52
+ const regStart = reg.start;
53
+ const regEnd = reg.end;
59
54
  const p = parseCigar(cigar);
60
55
  const [fStartX, mStartX] = findPosInCigar(p, regStart - featStart);
61
56
  const [fEndX, mEndX] = findPosInCigar(p, regEnd - featStart);
@@ -72,17 +67,14 @@ async function navToSynteny({ feature, windowSize: ws, model, horizontallyFlip,
72
67
  rMateStart = mateStart;
73
68
  rMateEnd = mateEnd;
74
69
  }
75
- const trackId = track.configuration.trackId;
76
70
  const view2 = session.addView('LinearSyntenyView', {
77
71
  type: 'LinearSyntenyView',
78
72
  views: [
79
73
  {
80
- id: `${Math.random()}`,
81
74
  type: 'LinearGenomeView',
82
75
  hideHeader: true,
83
76
  },
84
77
  {
85
- id: `${Math.random()}`,
86
78
  type: 'LinearGenomeView',
87
79
  hideHeader: true,
88
80
  },
@@ -1,4 +1,5 @@
1
1
  import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration';
2
+ import { Feature } from '@jbrowse/core/util';
2
3
  /**
3
4
  * #stateModel LGVSyntenyDisplay
4
5
  * displays location of "synteny" feature in a plain LGV, allowing linking out
@@ -10,7 +11,14 @@ import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration';
10
11
  declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("mobx-state-tree").IModelType<{
11
12
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
12
13
  type: import("mobx-state-tree").ISimpleType<string>;
13
- rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
14
+ rpcDriverName: import("mobx-state-tree" /**
15
+ * #stateModel LGVSyntenyDisplay
16
+ * displays location of "synteny" feature in a plain LGV, allowing linking out
17
+ * to external synteny views
18
+ *
19
+ * extends
20
+ * - [SharedLinearPileupDisplayMixin](../sharedlinearpileupdisplaymixin)
21
+ */).IMaybe<import("mobx-state-tree").ISimpleType<string>>;
14
22
  } & {
15
23
  heightPreConfig: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<number>>;
16
24
  } & {
@@ -38,7 +46,7 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
38
46
  renderInProgress: AbortController | undefined;
39
47
  filled: boolean;
40
48
  reactElement: React.ReactElement | undefined;
41
- features: Map<string, import("@jbrowse/core/util").Feature> | undefined;
49
+ features: Map<string, Feature> | undefined;
42
50
  layout: any;
43
51
  status: string;
44
52
  error: unknown;
@@ -63,7 +71,7 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
63
71
  setMessage(messageText: string): void;
64
72
  setRendered(props: {
65
73
  reactElement: React.ReactElement;
66
- features: Map<string, import("@jbrowse/core/util").Feature>;
74
+ features: Map<string, Feature>;
67
75
  layout: any;
68
76
  maxHeightReached: boolean;
69
77
  renderProps: any;
@@ -223,7 +231,7 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
223
231
  regionCannotBeRendered(_region: import("@jbrowse/core/util").Region): import("react").JSX.Element | null;
224
232
  } & {
225
233
  featureIdUnderMouse: undefined | string;
226
- contextMenuFeature: undefined | import("@jbrowse/core/util").Feature;
234
+ contextMenuFeature: undefined | Feature;
227
235
  } & {
228
236
  readonly DisplayMessageComponent: import("react").FC<any> | undefined;
229
237
  readonly blockType: "dynamicBlocks" | "staticBlocks";
@@ -233,19 +241,19 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
233
241
  readonly TooltipComponent: import("@jbrowse/core/util").AnyReactComponentType;
234
242
  readonly selectedFeatureId: string | undefined;
235
243
  } & {
236
- readonly features: import("@jbrowse/core/util/compositeMap").default<string, import("@jbrowse/core/util").Feature>;
237
- readonly featureUnderMouse: import("@jbrowse/core/util").Feature | undefined;
244
+ readonly features: import("@jbrowse/core/util/compositeMap").default<string, Feature>;
245
+ readonly featureUnderMouse: Feature | undefined;
238
246
  getFeatureOverlapping(blockKey: string, x: number, y: number): string | undefined;
239
247
  getFeatureByID(blockKey: string, id: string): [number, number, number, number] | undefined;
240
248
  searchFeatureByID(id: string): [number, number, number, number] | undefined;
241
249
  } & {
242
250
  addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
243
251
  deleteBlock(key: string): void;
244
- selectFeature(feature: import("@jbrowse/core/util").Feature): void;
245
- navToFeature(feature: import("@jbrowse/core/util").Feature): void;
252
+ selectFeature(feature: Feature): void;
253
+ navToFeature(feature: Feature): void;
246
254
  clearFeatureSelection(): void;
247
255
  setFeatureIdUnderMouse(feature?: string): void;
248
- setContextMenuFeature(feature?: import("@jbrowse/core/util").Feature): void;
256
+ setContextMenuFeature(feature?: Feature): void;
249
257
  } & {
250
258
  reload(): Promise<void>;
251
259
  } & {
@@ -257,7 +265,7 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
257
265
  afterAttach(): void;
258
266
  } & {
259
267
  colorTagMap: import("mobx").ObservableMap<string, string>;
260
- featureUnderMouseVolatile: undefined | import("@jbrowse/core/util").Feature;
268
+ featureUnderMouseVolatile: undefined | Feature;
261
269
  tagsReady: boolean;
262
270
  } & {
263
271
  readonly autorunReady: boolean;
@@ -272,9 +280,9 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
272
280
  extra?: import("@jbrowse/plugin-alignments/src/shared/color").ExtraColorBy;
273
281
  }): void;
274
282
  updateColorTagMap(uniqueTag: string[]): void;
275
- setFeatureUnderMouse(feat?: import("@jbrowse/core/util").Feature): void;
276
- selectFeature(feature: import("@jbrowse/core/util").Feature): void;
277
- copyFeatureToClipboard(feature: import("@jbrowse/core/util").Feature): void;
283
+ setFeatureUnderMouse(feat?: Feature): void;
284
+ selectFeature(feature: Feature): void;
285
+ copyFeatureToClipboard(feature: Feature): void;
278
286
  setConfig(conf: import("@jbrowse/core/configuration").AnyConfigurationModel): void;
279
287
  setFilterBy(filter: import("@jbrowse/plugin-alignments/src/shared").IFilter): void;
280
288
  setJexlFilters(filters: string[]): void;
@@ -293,7 +301,7 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
293
301
  } & {
294
302
  readonly maxHeight: any;
295
303
  readonly featureHeightSetting: any;
296
- readonly featureUnderMouse: import("@jbrowse/core/util").Feature | undefined;
304
+ readonly featureUnderMouse: Feature | undefined;
297
305
  renderReady(): boolean;
298
306
  readonly filters: import("@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain").default;
299
307
  } & {
@@ -352,6 +360,10 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
352
360
  }[];
353
361
  })[];
354
362
  } & {
363
+ /**
364
+ * #action
365
+ */
366
+ selectFeature(feature: Feature): void;
355
367
  afterCreate(): void;
356
368
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>;
357
369
  export default stateModelFactory;
@@ -62,12 +62,13 @@ function stateModelFactory(schema) {
62
62
  ...(feature
63
63
  ? [
64
64
  {
65
- label: 'Open synteny view for this position',
65
+ label: 'Launch synteny view for this position',
66
66
  onClick: () => {
67
67
  (0, util_1.getSession)(self).queueDialog(handleClose => [
68
68
  LaunchSyntenyViewDialog,
69
69
  {
70
70
  model: self,
71
+ trackId: (0, configuration_1.getConf)((0, util_1.getContainingTrack)(self), 'trackId'),
71
72
  handleClose,
72
73
  feature,
73
74
  },
@@ -98,6 +99,27 @@ function stateModelFactory(schema) {
98
99
  };
99
100
  })
100
101
  .actions(self => ({
102
+ /**
103
+ * #action
104
+ */
105
+ selectFeature(feature) {
106
+ const session = (0, util_1.getSession)(self);
107
+ if ((0, util_1.isSessionModelWithWidgets)(session)) {
108
+ const r2 = (0, util_1.getContainingView)(self);
109
+ let r3 = r2;
110
+ try {
111
+ r3 = (0, util_1.getContainingView)(r3);
112
+ }
113
+ catch (e) { }
114
+ const featureWidget = session.addWidget('SyntenyFeatureWidget', 'syntenyFeature', {
115
+ featureData: feature.toJSON(),
116
+ view: r3,
117
+ track: (0, util_1.getContainingTrack)(self),
118
+ });
119
+ session.showWidget(featureWidget);
120
+ }
121
+ session.setSelection(feature);
122
+ },
101
123
  afterCreate() {
102
124
  // use color by stand to help indicate inversions better on first load,
103
125
  // otherwise use selected orientation
@@ -43,7 +43,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
43
43
  message: string | undefined;
44
44
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
45
45
  onHorizontalScroll?: () => void;
46
- blockState?: Record<string, any>;
46
+ blockState? /**
47
+ * #action
48
+ * controlled by a reaction
49
+ */: Record<string, any>;
47
50
  }>;
48
51
  readonly DisplayBlurb: React.FC<{
49
52
  model: {
@@ -55,7 +58,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
55
58
  error: unknown;
56
59
  message: string | undefined;
57
60
  } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
58
- id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
61
+ id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree" /**
62
+ * #action
63
+ * controlled by a reaction
64
+ */).ISimpleType<string>, [undefined]>;
59
65
  type: import("mobx-state-tree").ISimpleType<string>;
60
66
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
61
67
  }, {
@@ -82,6 +88,14 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
82
88
  features: Feature[] | undefined;
83
89
  message: string | undefined;
84
90
  } & {
91
+ /**
92
+ * #getter
93
+ */
94
+ readonly level: number;
95
+ /**
96
+ * #getter
97
+ */
98
+ readonly height: number;
85
99
  /**
86
100
  * #getter
87
101
  */
@@ -126,7 +140,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
126
140
  message: string | undefined;
127
141
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
128
142
  onHorizontalScroll?: () => void;
129
- blockState?: Record<string, any>;
143
+ blockState? /**
144
+ * #action
145
+ * controlled by a reaction
146
+ */: Record<string, any>;
130
147
  }>;
131
148
  readonly DisplayBlurb: React.FC<{
132
149
  model: {
@@ -138,7 +155,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
138
155
  error: unknown;
139
156
  message: string | undefined;
140
157
  } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
141
- id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
158
+ id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree" /**
159
+ * #action
160
+ * controlled by a reaction
161
+ */).ISimpleType<string>, [undefined]>;
142
162
  type: import("mobx-state-tree").ISimpleType<string>;
143
163
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
144
164
  }, {
@@ -201,7 +221,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
201
221
  message: string | undefined;
202
222
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
203
223
  onHorizontalScroll?: () => void;
204
- blockState?: Record<string, any>;
224
+ blockState? /**
225
+ * #action
226
+ * controlled by a reaction
227
+ */: Record<string, any>;
205
228
  }>;
206
229
  readonly DisplayBlurb: React.FC<{
207
230
  model: {
@@ -28,6 +28,18 @@ function stateModelFactory(configSchema) {
28
28
  message: undefined,
29
29
  }))
30
30
  .views(self => ({
31
+ /**
32
+ * #getter
33
+ */
34
+ get level() {
35
+ return (0, mobx_state_tree_1.getParent)(self, 4).level;
36
+ },
37
+ /**
38
+ * #getter
39
+ */
40
+ get height() {
41
+ return (0, mobx_state_tree_1.getParent)(self, 4).height;
42
+ },
31
43
  /**
32
44
  * #getter
33
45
  */
@@ -133,7 +145,7 @@ function renderBlockData(self) {
133
145
  // renderProps is something under our control. Compare to
134
146
  // serverSideRenderedBlock
135
147
  (0, configuration_1.readConfObject)(self.configuration);
136
- const { adapterConfig } = self;
148
+ const { level, adapterConfig } = self;
137
149
  const parent = (0, util_1.getContainingView)(self);
138
150
  const sessionId = (0, tracks_1.getRpcSessionId)(self);
139
151
  (0, mobx_state_tree_1.getSnapshot)(parent);
@@ -142,8 +154,7 @@ function renderBlockData(self) {
142
154
  rpcManager,
143
155
  renderProps: {
144
156
  ...display.renderProps(),
145
- // @ts-expect-error
146
- level: (0, mobx_state_tree_1.getParent)(self, 4).level,
157
+ level,
147
158
  view: parent,
148
159
  adapterConfig,
149
160
  sessionId,
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.doAfterAttach = doAfterAttach;
4
+ const mobx_1 = require("mobx");
4
5
  const mobx_state_tree_1 = require("mobx-state-tree");
5
6
  const util_1 = require("@jbrowse/core/util");
6
7
  const Base1DUtils_1 = require("@jbrowse/core/util/Base1DUtils");
7
8
  const plugin_alignments_1 = require("@jbrowse/plugin-alignments");
8
- const mobx_1 = require("mobx");
9
9
  const drawSynteny_1 = require("./drawSynteny");
10
10
  function doAfterAttach(self) {
11
11
  (0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
@@ -51,10 +51,9 @@ function doAfterAttach(self) {
51
51
  if (!initialized) {
52
52
  return;
53
53
  }
54
+ const { level } = self;
54
55
  const { assemblyManager } = (0, util_1.getSession)(self);
55
56
  const view = (0, util_1.getContainingView)(self);
56
- // @ts-expect-error
57
- const level = (0, mobx_state_tree_1.getParent)(self, 4).level;
58
57
  const viewSnaps = view.views.map(view => ({
59
58
  ...(0, mobx_state_tree_1.getSnapshot)(view),
60
59
  width: view.width,
@@ -46,6 +46,7 @@ const useStyles = (0, mui_1.makeStyles)()({
46
46
  position: 'relative',
47
47
  },
48
48
  mouseoverCanvas: {
49
+ imageRendering: 'pixelated',
49
50
  position: 'absolute',
50
51
  pointEvents: 'none',
51
52
  },
@@ -55,6 +56,7 @@ const useStyles = (0, mui_1.makeStyles)()({
55
56
  });
56
57
  const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, }) {
57
58
  const { classes } = useStyles();
59
+ const { mouseoverId, height } = model;
58
60
  const xOffset = (0, react_1.useRef)(0);
59
61
  const view = (0, util_1.getContainingView)(model);
60
62
  const width = view.width;
@@ -67,20 +69,19 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
67
69
  const [mouseCurrDownX, setMouseCurrDownX] = (0, react_1.useState)();
68
70
  const [mouseInitialDownX, setMouseInitialDownX] = (0, react_1.useState)();
69
71
  const [currY, setCurrY] = (0, react_1.useState)();
70
- const { mouseoverId, height } = model;
71
- const k2p = (0, react_1.useRef)();
72
+ const mainSyntenyCanvasRefp = (0, react_1.useRef)();
72
73
  // these useCallbacks avoid new refs from being created on any mouseover,
73
74
  // etc.
74
75
  // biome-ignore lint/correctness/useExhaustiveDependencies:
75
- const k1 = (0, react_1.useCallback)((ref) => {
76
+ const mouseoverDetectionCanvasRef = (0, react_1.useCallback)((ref) => {
76
77
  model.setMouseoverCanvasRef(ref);
77
78
  },
78
79
  // eslint-disable-next-line react-hooks/exhaustive-deps
79
80
  [model, height, width]);
80
81
  // biome-ignore lint/correctness/useExhaustiveDependencies:
81
- const k2 = (0, react_1.useCallback)((ref) => {
82
+ const mainSyntenyCanvasRef = (0, react_1.useCallback)((ref) => {
82
83
  model.setMainCanvasRef(ref);
83
- k2p.current = ref; // this ref is additionally used in useEffect below
84
+ mainSyntenyCanvasRefp.current = ref; // this ref is additionally used in useEffect below
84
85
  },
85
86
  // eslint-disable-next-line react-hooks/exhaustive-deps
86
87
  [model, height, width]);
@@ -103,7 +104,9 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
103
104
  v.setScaleFactor(1);
104
105
  v.zoomTo(delta.current > 0
105
106
  ? v.bpPerPx * (1 + delta.current)
106
- : v.bpPerPx / (1 - delta.current), event.clientX - (((_a = k2p.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left) || 0));
107
+ : v.bpPerPx / (1 - delta.current), event.clientX -
108
+ (((_a = mainSyntenyCanvasRefp.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left) ||
109
+ 0));
107
110
  }
108
111
  delta.current = 0;
109
112
  }, 300);
@@ -126,28 +129,28 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
126
129
  }
127
130
  }
128
131
  }
129
- (_a = k2p.current) === null || _a === void 0 ? void 0 : _a.addEventListener('wheel', onWheel);
132
+ (_a = mainSyntenyCanvasRefp.current) === null || _a === void 0 ? void 0 : _a.addEventListener('wheel', onWheel);
130
133
  return () => {
131
134
  var _a;
132
- (_a = k2p.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('wheel', onWheel);
135
+ (_a = mainSyntenyCanvasRefp.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('wheel', onWheel);
133
136
  };
134
137
  // eslint-disable-next-line react-hooks/exhaustive-deps
135
138
  }, [model, height, width]);
136
139
  // biome-ignore lint/correctness/useExhaustiveDependencies:
137
- const k3 = (0, react_1.useCallback)((ref) => {
140
+ const clickMapCanvasRef = (0, react_1.useCallback)((ref) => {
138
141
  model.setClickMapCanvasRef(ref);
139
142
  },
140
143
  // eslint-disable-next-line react-hooks/exhaustive-deps
141
144
  [model, height, width]);
142
145
  // biome-ignore lint/correctness/useExhaustiveDependencies:
143
- const k4 = (0, react_1.useCallback)((ref) => {
146
+ const cigarClickMapCanvasRef = (0, react_1.useCallback)((ref) => {
144
147
  model.setCigarClickMapCanvasRef(ref);
145
148
  },
146
149
  // eslint-disable-next-line react-hooks/exhaustive-deps
147
150
  [model, height, width]);
148
151
  return (react_1.default.createElement("div", { className: classes.rel },
149
- react_1.default.createElement("canvas", { ref: k1, width: width, height: height, className: classes.mouseoverCanvas }),
150
- react_1.default.createElement("canvas", { ref: k2, onMouseMove: event => {
152
+ react_1.default.createElement("canvas", { ref: mouseoverDetectionCanvasRef, width: width, height: height, className: classes.mouseoverCanvas }),
153
+ react_1.default.createElement("canvas", { ref: mainSyntenyCanvasRef, onMouseMove: event => {
151
154
  var _a;
152
155
  if (mouseCurrDownX !== undefined) {
153
156
  xOffset.current += mouseCurrDownX - event.clientX;
@@ -194,7 +197,11 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
194
197
  const { f, cigar } = model.featPositions[id];
195
198
  const unitMultiplier2 = Math.floor(drawSynteny_1.MAX_COLOR_RANGE / cigar.length);
196
199
  const cigarIdx = (0, drawSynteny_1.getId)(r2, g2, b2, unitMultiplier2);
197
- setTooltip((0, util_2.getTooltip)(f, cigar[cigarIdx], cigar[cigarIdx + 1]));
200
+ setTooltip((0, util_2.getTooltip)({
201
+ feature: f,
202
+ cigarOp: cigar[cigarIdx],
203
+ cigarOpLen: cigar[cigarIdx + 1],
204
+ }));
198
205
  }
199
206
  }
200
207
  }, onMouseLeave: () => {
@@ -213,8 +220,8 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
213
220
  }, onContextMenu: evt => {
214
221
  (0, util_2.onSynContextClick)(evt, model, setAnchorEl);
215
222
  }, "data-testid": "synteny_canvas", className: classes.mainCanvas, width: width, height: height }),
216
- react_1.default.createElement("canvas", { ref: k3, className: classes.pix, width: width, height: height }),
217
- react_1.default.createElement("canvas", { ref: k4, className: classes.pix, width: width, height: height }),
223
+ react_1.default.createElement("canvas", { ref: clickMapCanvasRef, className: classes.pix, width: width, height: height }),
224
+ react_1.default.createElement("canvas", { ref: cigarClickMapCanvasRef, className: classes.pix, width: width, height: height }),
218
225
  mouseoverId && tooltip && currX && currY ? (react_1.default.createElement(SyntenyTooltip, { title: tooltip })) : null,
219
226
  anchorEl ? (react_1.default.createElement(SyntenyContextMenu_1.default, { model: model, anchorEl: anchorEl, onClose: () => {
220
227
  setAnchorEl(undefined);
@@ -7,7 +7,6 @@ exports.default = SyntenyContextMenu;
7
7
  const react_1 = __importDefault(require("react"));
8
8
  const util_1 = require("@jbrowse/core/util");
9
9
  const ui_1 = require("@jbrowse/core/ui");
10
- const mobx_state_tree_1 = require("mobx-state-tree");
11
10
  function SyntenyContextMenu({ model, onClose, anchorEl, }) {
12
11
  const view = (0, util_1.getContainingView)(model);
13
12
  const { clientX, clientY, feature } = anchorEl;
@@ -36,13 +35,12 @@ function SyntenyContextMenu({ model, onClose, anchorEl, }) {
36
35
  label: 'Center on feature',
37
36
  onClick: () => {
38
37
  const { f } = feature;
39
- const track = (0, mobx_state_tree_1.getParent)(model, 4);
40
38
  const start = f.get('start');
41
39
  const end = f.get('end');
42
40
  const refName = f.get('refName');
43
41
  const mate = f.get('mate');
44
- const l1 = view.views[track.level];
45
- const l2 = view.views[track.level + 1];
42
+ const l1 = view.views[model.level];
43
+ const l2 = view.views[model.level + 1];
46
44
  l1.navToLocString(`${refName}:${start}-${end}`).catch((e) => {
47
45
  const err = `${l1.assemblyNames[0]}:${e}`;
48
46
  console.error(err);
@@ -36,5 +36,9 @@ export declare function drawBox(ctx: CanvasRenderingContext2D, x1: number, x2: n
36
36
  export declare function drawBezierBox(ctx: CanvasRenderingContext2D, x1: number, x2: number, y1: number, x3: number, x4: number, y2: number, mid: number): void;
37
37
  export declare function onSynClick(event: React.MouseEvent, model: LinearSyntenyDisplayModel): import("../model").FeatPos | undefined;
38
38
  export declare function onSynContextClick(event: React.MouseEvent, model: LinearSyntenyDisplayModel, setAnchorEl: (arg: ClickCoord) => void): void;
39
- export declare function getTooltip(f: Feature, cigarOp?: string, cigarOpLen?: string): string;
39
+ export declare function getTooltip({ feature, cigarOp, cigarOpLen, }: {
40
+ feature: Feature;
41
+ cigarOp?: string;
42
+ cigarOpLen?: string;
43
+ }): string;
40
44
  export {};
@@ -63,7 +63,6 @@ function drawBox(ctx, x1, x2, y1, x3, x4, y2) {
63
63
  ctx.lineTo(x3, y2);
64
64
  ctx.lineTo(x4, y2);
65
65
  ctx.closePath();
66
- ctx.fill();
67
66
  }
68
67
  function drawBezierBox(ctx, x1, x2, y1, x3, x4, y2, mid) {
69
68
  const len1 = Math.abs(x1 - x2);
@@ -83,13 +82,11 @@ function drawBezierBox(ctx, x1, x2, y1, x3, x4, y2, mid) {
83
82
  ctx.lineTo(x4, y2);
84
83
  ctx.bezierCurveTo(x4, mid, x1, mid, x1, y1);
85
84
  ctx.closePath();
86
- ctx.fill();
87
85
  }
88
86
  function onSynClick(event, model) {
89
87
  const view = (0, util_1.getContainingView)(model);
90
88
  const track = (0, util_1.getContainingTrack)(model);
91
- const ref1 = model.clickMapCanvas;
92
- const ref2 = model.cigarClickMapCanvas;
89
+ const { featPositions, numFeats, clickMapCanvas: ref1, cigarClickMapCanvas: ref2, level, } = model;
93
90
  if (!ref1 || !ref2) {
94
91
  return;
95
92
  }
@@ -102,18 +99,19 @@ function onSynClick(event, model) {
102
99
  const x = event.clientX - rect.left;
103
100
  const y = event.clientY - rect.top;
104
101
  const [r1, g1, b1] = ctx1.getImageData(x, y, 1, 1).data;
105
- const unitMultiplier = Math.floor(drawSynteny_1.MAX_COLOR_RANGE / model.numFeats);
102
+ const unitMultiplier = Math.floor(drawSynteny_1.MAX_COLOR_RANGE / numFeats);
106
103
  const id = (0, drawSynteny_1.getId)(r1, g1, b1, unitMultiplier);
107
- const feat = model.featPositions[id];
104
+ const feat = featPositions[id];
108
105
  if (feat) {
109
106
  const { f } = feat;
110
107
  model.setClickId(f.id());
111
108
  const session = (0, util_1.getSession)(model);
112
109
  if ((0, util_1.isSessionModelWithWidgets)(session)) {
113
- session.showWidget(session.addWidget('BaseFeatureWidget', 'baseFeature', {
110
+ session.showWidget(session.addWidget('SyntenyFeatureWidget', 'syntenyFeature', {
114
111
  view,
115
112
  track,
116
113
  featureData: f.toJSON(),
114
+ level,
117
115
  }));
118
116
  }
119
117
  }
@@ -144,9 +142,9 @@ function onSynContextClick(event, model, setAnchorEl) {
144
142
  setAnchorEl({ clientX, clientY, feature: f });
145
143
  }
146
144
  }
147
- function getTooltip(f, cigarOp, cigarOpLen) {
145
+ function getTooltip({ feature, cigarOp, cigarOpLen, }) {
148
146
  // @ts-expect-error
149
- const f1 = f.toJSON();
147
+ const f1 = feature.toJSON();
150
148
  const f2 = f1.mate;
151
149
  const l1 = f1.end - f1.start;
152
150
  const l2 = f2.end - f2.start;