@jbrowse/plugin-linear-comparative-view 2.15.3 → 2.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/LaunchLinearSyntenyView.js +41 -11
  2. package/dist/LinearComparativeDisplay/stateModelFactory.d.ts +14 -9
  3. package/dist/LinearComparativeDisplay/stateModelFactory.js +8 -9
  4. package/dist/LinearComparativeView/components/Header.d.ts +2 -3
  5. package/dist/LinearComparativeView/components/Header.js +72 -62
  6. package/dist/LinearComparativeView/components/HeaderSearchBoxes.d.ts +6 -0
  7. package/dist/LinearComparativeView/components/HeaderSearchBoxes.js +34 -0
  8. package/dist/LinearComparativeView/components/LinearComparativeRenderArea.d.ts +6 -0
  9. package/dist/LinearComparativeView/components/LinearComparativeRenderArea.js +61 -0
  10. package/dist/LinearComparativeView/components/LinearComparativeView.d.ts +2 -4
  11. package/dist/LinearComparativeView/components/LinearComparativeView.js +3 -67
  12. package/dist/LinearComparativeView/components/Rubberband.js +1 -1
  13. package/dist/LinearComparativeView/index.js +3 -0
  14. package/dist/LinearComparativeView/model.d.ts +265 -12
  15. package/dist/LinearComparativeView/model.js +45 -75
  16. package/dist/LinearSyntenyDisplay/afterAttach.js +5 -3
  17. package/dist/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +32 -24
  18. package/dist/LinearSyntenyDisplay/components/SyntenyContextMenu.js +12 -6
  19. package/dist/LinearSyntenyDisplay/components/util.d.ts +2 -1
  20. package/dist/LinearSyntenyDisplay/components/util.js +5 -5
  21. package/dist/LinearSyntenyDisplay/drawSynteny.d.ts +1 -1
  22. package/dist/LinearSyntenyDisplay/drawSynteny.js +28 -22
  23. package/dist/LinearSyntenyDisplay/index.js +1 -1
  24. package/dist/LinearSyntenyDisplay/model.d.ts +12 -11
  25. package/dist/LinearSyntenyDisplay/model.js +7 -0
  26. package/dist/LinearSyntenyView/components/ImportForm/{ImportCustomTrack.d.ts → AddCustomTrack.d.ts} +2 -3
  27. package/dist/LinearSyntenyView/components/ImportForm/{ImportCustomTrack.js → AddCustomTrack.js} +3 -3
  28. package/dist/LinearSyntenyView/components/ImportForm/LinearSyntenyImportForm.js +195 -0
  29. package/dist/LinearSyntenyView/components/ImportForm/Spacer.d.ts +2 -0
  30. package/dist/LinearSyntenyView/components/ImportForm/Spacer.js +10 -0
  31. package/dist/LinearSyntenyView/components/ImportForm/TrackSelector.d.ts +10 -0
  32. package/dist/LinearSyntenyView/components/ImportForm/{ImportSyntenyTrackSelector.js → TrackSelector.js} +15 -20
  33. package/dist/LinearSyntenyView/components/ImportForm/TrackSelectorUtil.d.ts +14 -0
  34. package/dist/LinearSyntenyView/components/ImportForm/TrackSelectorUtil.js +52 -0
  35. package/dist/LinearSyntenyView/components/LinearSyntenyView.js +3 -3
  36. package/dist/LinearSyntenyView/index.js +1 -1
  37. package/dist/LinearSyntenyView/model.d.ts +267 -9
  38. package/dist/LinearSyntenyView/model.js +2 -2
  39. package/dist/LinearSyntenyView/svgcomponents/SVGLinearGenomeView.d.ts +12 -0
  40. package/dist/LinearSyntenyView/svgcomponents/SVGLinearGenomeView.js +19 -0
  41. package/dist/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.d.ts +1 -3
  42. package/dist/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js +36 -27
  43. package/dist/LinearSyntenyViewHelper/index.d.ts +2 -0
  44. package/dist/LinearSyntenyViewHelper/index.js +25 -0
  45. package/dist/LinearSyntenyViewHelper/stateModelFactory.d.ts +30 -0
  46. package/dist/LinearSyntenyViewHelper/stateModelFactory.js +105 -0
  47. package/dist/index.js +2 -0
  48. package/esm/LaunchLinearSyntenyView.js +41 -11
  49. package/esm/LinearComparativeDisplay/stateModelFactory.d.ts +14 -9
  50. package/esm/LinearComparativeDisplay/stateModelFactory.js +9 -10
  51. package/esm/LinearComparativeView/components/Header.d.ts +2 -3
  52. package/esm/LinearComparativeView/components/Header.js +73 -63
  53. package/esm/LinearComparativeView/components/HeaderSearchBoxes.d.ts +6 -0
  54. package/esm/LinearComparativeView/components/HeaderSearchBoxes.js +29 -0
  55. package/esm/LinearComparativeView/components/LinearComparativeRenderArea.d.ts +6 -0
  56. package/esm/LinearComparativeView/components/LinearComparativeRenderArea.js +56 -0
  57. package/esm/LinearComparativeView/components/LinearComparativeView.d.ts +2 -4
  58. package/esm/LinearComparativeView/components/LinearComparativeView.js +3 -67
  59. package/esm/LinearComparativeView/components/Rubberband.js +1 -1
  60. package/esm/LinearComparativeView/index.js +3 -0
  61. package/esm/LinearComparativeView/model.d.ts +265 -12
  62. package/esm/LinearComparativeView/model.js +47 -77
  63. package/esm/LinearSyntenyDisplay/afterAttach.js +6 -4
  64. package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +33 -25
  65. package/esm/LinearSyntenyDisplay/components/SyntenyContextMenu.js +12 -6
  66. package/esm/LinearSyntenyDisplay/components/util.d.ts +2 -1
  67. package/esm/LinearSyntenyDisplay/components/util.js +5 -5
  68. package/esm/LinearSyntenyDisplay/drawSynteny.d.ts +1 -1
  69. package/esm/LinearSyntenyDisplay/drawSynteny.js +28 -22
  70. package/esm/LinearSyntenyDisplay/index.js +1 -1
  71. package/esm/LinearSyntenyDisplay/model.d.ts +12 -11
  72. package/esm/LinearSyntenyDisplay/model.js +8 -1
  73. package/esm/LinearSyntenyView/components/ImportForm/{ImportCustomTrack.d.ts → AddCustomTrack.d.ts} +2 -3
  74. package/esm/LinearSyntenyView/components/ImportForm/{ImportCustomTrack.js → AddCustomTrack.js} +3 -3
  75. package/esm/LinearSyntenyView/components/ImportForm/LinearSyntenyImportForm.js +167 -0
  76. package/esm/LinearSyntenyView/components/ImportForm/Spacer.d.ts +2 -0
  77. package/esm/LinearSyntenyView/components/ImportForm/Spacer.js +4 -0
  78. package/esm/LinearSyntenyView/components/ImportForm/TrackSelector.d.ts +10 -0
  79. package/esm/LinearSyntenyView/components/ImportForm/{ImportSyntenyTrackSelector.js → TrackSelector.js} +15 -20
  80. package/esm/LinearSyntenyView/components/ImportForm/TrackSelectorUtil.d.ts +14 -0
  81. package/esm/LinearSyntenyView/components/ImportForm/TrackSelectorUtil.js +23 -0
  82. package/esm/LinearSyntenyView/components/LinearSyntenyView.js +3 -3
  83. package/esm/LinearSyntenyView/index.js +1 -1
  84. package/esm/LinearSyntenyView/model.d.ts +267 -9
  85. package/esm/LinearSyntenyView/model.js +2 -2
  86. package/esm/LinearSyntenyView/svgcomponents/SVGLinearGenomeView.d.ts +12 -0
  87. package/esm/LinearSyntenyView/svgcomponents/SVGLinearGenomeView.js +13 -0
  88. package/esm/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.d.ts +1 -3
  89. package/esm/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js +38 -29
  90. package/esm/LinearSyntenyViewHelper/index.d.ts +2 -0
  91. package/esm/LinearSyntenyViewHelper/index.js +19 -0
  92. package/esm/LinearSyntenyViewHelper/stateModelFactory.d.ts +30 -0
  93. package/esm/LinearSyntenyViewHelper/stateModelFactory.js +102 -0
  94. package/esm/index.js +2 -0
  95. package/package.json +2 -2
  96. package/dist/LinearSyntenyView/components/ImportForm/ImportSyntenyTrackSelector.d.ts +0 -9
  97. package/dist/LinearSyntenyView/components/ImportForm/index.js +0 -138
  98. package/esm/LinearSyntenyView/components/ImportForm/ImportSyntenyTrackSelector.d.ts +0 -9
  99. package/esm/LinearSyntenyView/components/ImportForm/index.js +0 -110
  100. /package/dist/LinearSyntenyView/components/ImportForm/{index.d.ts → LinearSyntenyImportForm.d.ts} +0 -0
  101. /package/esm/LinearSyntenyView/components/ImportForm/{index.d.ts → LinearSyntenyImportForm.d.ts} +0 -0
@@ -45,21 +45,21 @@ const useStyles = (0, mui_1.makeStyles)()({
45
45
  rel: {
46
46
  position: 'relative',
47
47
  },
48
- abs: {
48
+ mouseoverCanvas: {
49
49
  position: 'absolute',
50
- },
51
- none: {
52
50
  pointEvents: 'none',
53
51
  },
52
+ mainCanvas: {
53
+ position: 'absolute',
54
+ },
54
55
  });
55
56
  const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, }) {
56
- const { classes, cx } = useStyles();
57
+ const { classes } = useStyles();
57
58
  const xOffset = (0, react_1.useRef)(0);
58
- const currScrollFrame = (0, react_1.useRef)();
59
59
  const view = (0, util_1.getContainingView)(model);
60
- const height = view.middleComparativeHeight;
61
60
  const width = view.width;
62
61
  const delta = (0, react_1.useRef)(0);
62
+ const scheduled = (0, react_1.useRef)(false);
63
63
  const timeout = (0, react_1.useRef)();
64
64
  const [anchorEl, setAnchorEl] = (0, react_1.useState)();
65
65
  const [tooltip, setTooltip] = (0, react_1.useState)('');
@@ -67,7 +67,8 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
67
67
  const [mouseCurrDownX, setMouseCurrDownX] = (0, react_1.useState)();
68
68
  const [mouseInitialDownX, setMouseInitialDownX] = (0, react_1.useState)();
69
69
  const [currY, setCurrY] = (0, react_1.useState)();
70
- const { mouseoverId } = model;
70
+ const { mouseoverId, height } = model;
71
+ const k2p = (0, react_1.useRef)();
71
72
  // these useCallbacks avoid new refs from being created on any mouseover,
72
73
  // etc.
73
74
  // biome-ignore lint/correctness/useExhaustiveDependencies:
@@ -79,6 +80,13 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
79
80
  // biome-ignore lint/correctness/useExhaustiveDependencies:
80
81
  const k2 = (0, react_1.useCallback)((ref) => {
81
82
  model.setMainCanvasRef(ref);
83
+ k2p.current = ref; // this ref is additionally used in useEffect below
84
+ },
85
+ // eslint-disable-next-line react-hooks/exhaustive-deps
86
+ [model, height, width]);
87
+ // biome-ignore lint/correctness/useExhaustiveDependencies:
88
+ (0, react_1.useEffect)(() => {
89
+ var _a;
82
90
  function onWheel(event) {
83
91
  event.preventDefault();
84
92
  if (event.ctrlKey) {
@@ -90,11 +98,12 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
90
98
  clearTimeout(timeout.current);
91
99
  }
92
100
  timeout.current = setTimeout(() => {
101
+ var _a;
93
102
  for (const v of view.views) {
94
103
  v.setScaleFactor(1);
95
104
  v.zoomTo(delta.current > 0
96
105
  ? v.bpPerPx * (1 + delta.current)
97
- : v.bpPerPx / (1 - delta.current), event.clientX - ((ref === null || ref === void 0 ? void 0 : ref.getBoundingClientRect().left) || 0));
106
+ : v.bpPerPx / (1 - delta.current), event.clientX - (((_a = k2p.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left) || 0));
98
107
  }
99
108
  delta.current = 0;
100
109
  }, 300);
@@ -103,29 +112,27 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
103
112
  if (Math.abs(event.deltaY) < Math.abs(event.deltaX)) {
104
113
  xOffset.current += event.deltaX / 2;
105
114
  }
106
- if (currScrollFrame.current === undefined) {
107
- currScrollFrame.current = requestAnimationFrame(() => {
115
+ if (!scheduled.current) {
116
+ scheduled.current = true;
117
+ window.requestAnimationFrame(() => {
108
118
  (0, mobx_1.transaction)(() => {
109
119
  for (const v of view.views) {
110
120
  v.horizontalScroll(xOffset.current);
111
121
  }
112
122
  xOffset.current = 0;
113
- currScrollFrame.current = undefined;
123
+ scheduled.current = false;
114
124
  });
115
125
  });
116
126
  }
117
127
  }
118
128
  }
119
- ref === null || ref === void 0 ? void 0 : ref.addEventListener('wheel', onWheel);
120
- // this is a react 19-ism to have a cleanup in the ref callback
121
- // https://react.dev/blog/2024/04/25/react-19#cleanup-functions-for-refs
122
- // note: it warns in earlier versions of react
129
+ (_a = k2p.current) === null || _a === void 0 ? void 0 : _a.addEventListener('wheel', onWheel);
123
130
  return () => {
124
- ref === null || ref === void 0 ? void 0 : ref.removeEventListener('wheel', onWheel);
131
+ var _a;
132
+ (_a = k2p.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('wheel', onWheel);
125
133
  };
126
- },
127
- // eslint-disable-next-line react-hooks/exhaustive-deps
128
- [model, height, width]);
134
+ // eslint-disable-next-line react-hooks/exhaustive-deps
135
+ }, [model, height, width]);
129
136
  // biome-ignore lint/correctness/useExhaustiveDependencies:
130
137
  const k3 = (0, react_1.useCallback)((ref) => {
131
138
  model.setClickMapCanvasRef(ref);
@@ -139,20 +146,21 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
139
146
  // eslint-disable-next-line react-hooks/exhaustive-deps
140
147
  [model, height, width]);
141
148
  return (react_1.default.createElement("div", { className: classes.rel },
142
- react_1.default.createElement("canvas", { ref: k1, width: width, height: height, className: cx(classes.abs, classes.none) }),
149
+ react_1.default.createElement("canvas", { ref: k1, width: width, height: height, className: classes.mouseoverCanvas }),
143
150
  react_1.default.createElement("canvas", { ref: k2, onMouseMove: event => {
144
151
  var _a;
145
152
  if (mouseCurrDownX !== undefined) {
146
153
  xOffset.current += mouseCurrDownX - event.clientX;
147
154
  setMouseCurrDownX(event.clientX);
148
- if (currScrollFrame.current === undefined) {
149
- currScrollFrame.current = requestAnimationFrame(() => {
155
+ if (!scheduled.current) {
156
+ scheduled.current = true;
157
+ window.requestAnimationFrame(() => {
150
158
  (0, mobx_1.transaction)(() => {
151
159
  for (const v of view.views) {
152
160
  v.horizontalScroll(xOffset.current);
153
161
  }
154
162
  xOffset.current = 0;
155
- currScrollFrame.current = undefined;
163
+ scheduled.current = false;
156
164
  });
157
165
  });
158
166
  }
@@ -204,7 +212,7 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
204
212
  }
205
213
  }, onContextMenu: evt => {
206
214
  (0, util_2.onSynContextClick)(evt, model, setAnchorEl);
207
- }, "data-testid": "synteny_canvas", className: classes.abs, width: width, height: height }),
215
+ }, "data-testid": "synteny_canvas", className: classes.mainCanvas, width: width, height: height }),
208
216
  react_1.default.createElement("canvas", { ref: k3, className: classes.pix, width: width, height: height }),
209
217
  react_1.default.createElement("canvas", { ref: k4, className: classes.pix, width: width, height: height }),
210
218
  mouseoverId && tooltip && currX && currY ? (react_1.default.createElement(SyntenyTooltip, { title: tooltip })) : null,
@@ -7,6 +7,7 @@ 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");
10
11
  function SyntenyContextMenu({ model, onClose, anchorEl, }) {
11
12
  const view = (0, util_1.getContainingView)(model);
12
13
  const { clientX, clientY, feature } = anchorEl;
@@ -35,17 +36,22 @@ function SyntenyContextMenu({ model, onClose, anchorEl, }) {
35
36
  label: 'Center on feature',
36
37
  onClick: () => {
37
38
  const { f } = feature;
39
+ const track = (0, mobx_state_tree_1.getParent)(model, 4);
38
40
  const start = f.get('start');
39
41
  const end = f.get('end');
40
42
  const refName = f.get('refName');
41
43
  const mate = f.get('mate');
42
- view.views[0].navToLocString(`${refName}:${start}-${end}`).catch((e) => {
43
- console.error(e);
44
- (0, util_1.getSession)(model).notifyError(`${e}`, e);
44
+ const l1 = view.views[track.level];
45
+ const l2 = view.views[track.level + 1];
46
+ l1.navToLocString(`${refName}:${start}-${end}`).catch((e) => {
47
+ const err = `${l1.assemblyNames[0]}:${e}`;
48
+ console.error(err);
49
+ (0, util_1.getSession)(model).notifyError(err, e);
45
50
  });
46
- view.views[1].navToLocString(`${mate.refName}:${mate.start}-${mate.end}`).catch((e) => {
47
- console.error(e);
48
- (0, util_1.getSession)(model).notifyError(`${e}`, e);
51
+ l2.navToLocString(`${mate.refName}:${mate.start}-${mate.end}`).catch((e) => {
52
+ const err = `${l2.assemblyNames[0]}:${e}`;
53
+ console.error(err);
54
+ (0, util_1.getSession)(model).notifyError(err, e);
49
55
  });
50
56
  },
51
57
  },
@@ -19,10 +19,11 @@ interface FeatPos {
19
19
  f: Feature;
20
20
  cigar: string[];
21
21
  }
22
- export declare function drawMatchSimple({ feature, ctx, offsets, cb, height, drawCurves, oobLimit, viewWidth, hideTiny, }: {
22
+ export declare function drawMatchSimple({ feature, ctx, offsets, level, cb, height, drawCurves, oobLimit, viewWidth, hideTiny, }: {
23
23
  feature: FeatPos;
24
24
  ctx: CanvasRenderingContext2D;
25
25
  offsets: number[];
26
+ level: number;
26
27
  oobLimit: number;
27
28
  viewWidth: number;
28
29
  cb: (ctx: CanvasRenderingContext2D) => void;
@@ -10,12 +10,12 @@ exports.getTooltip = getTooltip;
10
10
  const util_1 = require("@jbrowse/core/util");
11
11
  // locals
12
12
  const drawSynteny_1 = require("../drawSynteny");
13
- function drawMatchSimple({ feature, ctx, offsets, cb, height, drawCurves, oobLimit, viewWidth, hideTiny, }) {
13
+ function drawMatchSimple({ feature, ctx, offsets, level, cb, height, drawCurves, oobLimit, viewWidth, hideTiny, }) {
14
14
  const { p11, p12, p21, p22 } = feature;
15
- const x11 = p11.offsetPx - offsets[0];
16
- const x12 = p12.offsetPx - offsets[0];
17
- const x21 = p21.offsetPx - offsets[1];
18
- const x22 = p22.offsetPx - offsets[1];
15
+ const x11 = p11.offsetPx - offsets[level];
16
+ const x12 = p12.offsetPx - offsets[level];
17
+ const x21 = p21.offsetPx - offsets[level + 1];
18
+ const x22 = p22.offsetPx - offsets[level + 1];
19
19
  const l1 = Math.abs(x12 - x11);
20
20
  const l2 = Math.abs(x22 - x21);
21
21
  const y1 = 0;
@@ -1,5 +1,5 @@
1
1
  import { LinearSyntenyDisplayModel } from './model';
2
2
  export declare const MAX_COLOR_RANGE: number;
3
3
  export declare function getId(r: number, g: number, b: number, unitMultiplier: number): number;
4
- export declare function drawRef(model: LinearSyntenyDisplayModel, ctx1: CanvasRenderingContext2D, ctx3?: CanvasRenderingContext2D): undefined;
4
+ export declare function drawRef(model: LinearSyntenyDisplayModel, ctx1: CanvasRenderingContext2D, ctx3?: CanvasRenderingContext2D): void;
5
5
  export declare function drawMouseoverSynteny(model: LinearSyntenyDisplayModel): void;
@@ -6,6 +6,7 @@ exports.drawRef = drawRef;
6
6
  exports.drawMouseoverSynteny = drawMouseoverSynteny;
7
7
  const util_1 = require("@jbrowse/core/util");
8
8
  const util_2 = require("./components/util");
9
+ const mobx_state_tree_1 = require("mobx-state-tree");
9
10
  exports.MAX_COLOR_RANGE = 255 * 255 * 255; // max color range
10
11
  function makeColor(idx) {
11
12
  const r = Math.floor(idx / (255 * 255)) % 255;
@@ -29,27 +30,28 @@ function getId(r, g, b, unitMultiplier) {
29
30
  function drawRef(model, ctx1, ctx3) {
30
31
  var _a;
31
32
  const view = (0, util_1.getContainingView)(model);
33
+ // @ts-expect-error
34
+ const level = (0, mobx_state_tree_1.getParent)(model, 4).level;
32
35
  const drawCurves = view.drawCurves;
33
36
  const drawCIGAR = view.drawCIGAR;
34
- const height = view.middleComparativeHeight;
37
+ const { height, featPositions } = model;
35
38
  const width = view.width;
36
39
  const bpPerPxs = view.views.map(v => v.bpPerPx);
37
40
  if (ctx3) {
38
41
  ctx3.imageSmoothingEnabled = false;
39
42
  }
40
43
  ctx1.beginPath();
41
- const featPos = model.featPositions;
42
44
  const offsets = view.views.map(v => v.offsetPx);
43
- const unitMultiplier = Math.floor(exports.MAX_COLOR_RANGE / featPos.length);
45
+ const unitMultiplier = Math.floor(exports.MAX_COLOR_RANGE / featPositions.length);
44
46
  // this loop is optimized to draw many thin lines with a single ctx.stroke
45
47
  // call, a separate loop below draws larger boxes
46
48
  ctx1.fillStyle = colorMap.M;
47
49
  ctx1.strokeStyle = colorMap.M;
48
- for (const { p11, p12, p21, p22 } of featPos) {
49
- const x11 = p11.offsetPx - offsets[0];
50
- const x12 = p12.offsetPx - offsets[0];
51
- const x21 = p21.offsetPx - offsets[1];
52
- const x22 = p22.offsetPx - offsets[1];
50
+ for (const { p11, p12, p21, p22 } of featPositions) {
51
+ const x11 = p11.offsetPx - offsets[level];
52
+ const x12 = p12.offsetPx - offsets[level];
53
+ const x21 = p21.offsetPx - offsets[level + 1];
54
+ const x22 = p22.offsetPx - offsets[level + 1];
53
55
  const l1 = Math.abs(x12 - x11);
54
56
  const l2 = Math.abs(x22 - x21);
55
57
  const y1 = 0;
@@ -75,11 +77,11 @@ function drawRef(model, ctx1, ctx3) {
75
77
  // ctx.stroke once is much more efficient than calling stroke() many times
76
78
  ctx1.fillStyle = colorMap.M;
77
79
  ctx1.strokeStyle = colorMap.M;
78
- for (const { p11, p12, p21, p22, f, cigar } of featPos) {
79
- const x11 = p11.offsetPx - offsets[0];
80
- const x12 = p12.offsetPx - offsets[0];
81
- const x21 = p21.offsetPx - offsets[1];
82
- const x22 = p22.offsetPx - offsets[1];
80
+ for (const { p11, p12, p21, p22, f, cigar } of featPositions) {
81
+ const x11 = p11.offsetPx - offsets[level];
82
+ const x12 = p12.offsetPx - offsets[level];
83
+ const x21 = p21.offsetPx - offsets[level + 1];
84
+ const x22 = p22.offsetPx - offsets[level + 1];
83
85
  const l1 = Math.abs(x12 - x11);
84
86
  const l2 = Math.abs(x22 - x21);
85
87
  const minX = Math.min(x21, x22);
@@ -114,8 +116,8 @@ function drawRef(model, ctx1, ctx3) {
114
116
  px1 = cx1;
115
117
  px2 = cx2;
116
118
  }
117
- const d1 = len / bpPerPxs[0];
118
- const d2 = len / bpPerPxs[1];
119
+ const d1 = len / bpPerPxs[level];
120
+ const d2 = len / bpPerPxs[level + 1];
119
121
  if (op === 'M' || op === '=' || op === 'X') {
120
122
  cx1 += d1 * rev1;
121
123
  cx2 += d2 * rev2;
@@ -141,9 +143,9 @@ function drawRef(model, ctx1, ctx3) {
141
143
  continuingFlag = true;
142
144
  }
143
145
  else {
144
- // allow rendering the dominant color when using continuing flag
145
- // if the last element of continuing was a large feature, else
146
- // just use match
146
+ // allow rendering the dominant color when using continuing
147
+ // flag if the last element of continuing was a large
148
+ // feature, else just use match
147
149
  ctx1.fillStyle =
148
150
  colorMap[(continuingFlag && d1 > 1) || d2 > 1 ? op : 'M'];
149
151
  continuingFlag = false;
@@ -168,8 +170,8 @@ function drawRef(model, ctx1, ctx3) {
168
170
  }
169
171
  ctx2.imageSmoothingEnabled = false;
170
172
  ctx2.clearRect(0, 0, width, height);
171
- for (let i = 0; i < featPos.length; i++) {
172
- const feature = featPos[i];
173
+ for (let i = 0; i < featPositions.length; i++) {
174
+ const feature = featPositions[i];
173
175
  const idx = i * unitMultiplier + 1;
174
176
  ctx2.fillStyle = makeColor(idx);
175
177
  // too many click map false positives with colored stroked lines
@@ -180,6 +182,7 @@ function drawRef(model, ctx1, ctx3) {
180
182
  feature,
181
183
  ctx: ctx2,
182
184
  drawCurves,
185
+ level,
183
186
  offsets,
184
187
  oobLimit,
185
188
  viewWidth: view.width,
@@ -187,7 +190,6 @@ function drawRef(model, ctx1, ctx3) {
187
190
  height,
188
191
  });
189
192
  }
190
- return undefined;
191
193
  }
192
194
  function drawMouseoverSynteny(model) {
193
195
  var _a;
@@ -195,10 +197,12 @@ function drawMouseoverSynteny(model) {
195
197
  const highResolutionScaling = 1;
196
198
  const view = (0, util_1.getContainingView)(model);
197
199
  const drawCurves = view.drawCurves;
198
- const height = view.middleComparativeHeight;
200
+ const height = model.height;
199
201
  const width = view.width;
200
202
  const ctx = (_a = model.mouseoverCanvas) === null || _a === void 0 ? void 0 : _a.getContext('2d');
201
203
  const offsets = view.views.map(v => v.offsetPx);
204
+ // @ts-expect-error
205
+ const level = (0, mobx_state_tree_1.getParent)(model, 4).level;
202
206
  if (!ctx) {
203
207
  return;
204
208
  }
@@ -213,6 +217,7 @@ function drawMouseoverSynteny(model) {
213
217
  ctx.fill();
214
218
  },
215
219
  feature: feature1,
220
+ level,
216
221
  ctx,
217
222
  oobLimit,
218
223
  viewWidth: view.width,
@@ -230,6 +235,7 @@ function drawMouseoverSynteny(model) {
230
235
  },
231
236
  feature: feature2,
232
237
  ctx,
238
+ level,
233
239
  oobLimit,
234
240
  viewWidth: view.width,
235
241
  drawCurves,
@@ -40,7 +40,7 @@ function LinearSyntenyDisplayF(pluginManager) {
40
40
  configSchema,
41
41
  stateModel: (0, model_1.default)(configSchema),
42
42
  trackType: 'SyntenyTrack',
43
- viewType: 'LinearSyntenyView',
43
+ viewType: 'LinearSyntenyViewHelper',
44
44
  ReactComponent: (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./components/Component')))),
45
45
  });
46
46
  });
@@ -24,7 +24,6 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
24
24
  } & {
25
25
  type: import("mobx-state-tree").ISimpleType<"LinearComparativeDisplay">;
26
26
  configuration: AnyConfigurationSchemaType;
27
- height: import("mobx-state-tree").IType<number | undefined, number, number>;
28
27
  } & {
29
28
  /**
30
29
  * #property
@@ -69,7 +68,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
69
68
  rendererTypeName: string;
70
69
  error: unknown;
71
70
  message: string | undefined;
72
- } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
71
+ } & import("mobx-state-tree" /**
72
+ * #action
73
+ */).IStateTreeNode<import("mobx-state-tree").IModelType<{
73
74
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
74
75
  type: import("mobx-state-tree").ISimpleType<string>;
75
76
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
@@ -77,9 +78,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
77
78
  rendererTypeName: string;
78
79
  error: unknown;
79
80
  message: string | undefined;
80
- }, import("mobx-state-tree" /**
81
- * #action
82
- */)._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
81
+ }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
83
82
  }> | null;
84
83
  readonly adapterConfig: any;
85
84
  readonly parentTrack: any;
@@ -116,7 +115,6 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
116
115
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & any & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>);
117
116
  } & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>);
118
117
  } & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>;
119
- height: number;
120
118
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
121
119
  rendererTypeName: string;
122
120
  error: unknown;
@@ -152,7 +150,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
152
150
  rendererTypeName: string;
153
151
  error: unknown;
154
152
  message: string | undefined;
155
- } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
153
+ } & import("mobx-state-tree" /**
154
+ * #action
155
+ */).IStateTreeNode<import("mobx-state-tree").IModelType<{
156
156
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
157
157
  type: import("mobx-state-tree").ISimpleType<string>;
158
158
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
@@ -160,9 +160,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
160
160
  rendererTypeName: string;
161
161
  error: unknown;
162
162
  message: string | undefined;
163
- }, import("mobx-state-tree" /**
164
- * #action
165
- */)._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
163
+ }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
166
164
  }> | null;
167
165
  readonly adapterConfig: any;
168
166
  readonly parentTrack: any;
@@ -188,7 +186,6 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
188
186
  } & {
189
187
  type: import("mobx-state-tree").ISimpleType<"LinearComparativeDisplay">;
190
188
  configuration: AnyConfigurationSchemaType;
191
- height: import("mobx-state-tree").IType<number | undefined, number, number>;
192
189
  }, {
193
190
  rendererTypeName: string;
194
191
  error: unknown;
@@ -314,6 +311,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
314
311
  * #getter
315
312
  */
316
313
  readonly trackIds: string[];
314
+ /**
315
+ * #getter
316
+ */
317
+ readonly height: number;
317
318
  /**
318
319
  * #getter
319
320
  */
@@ -139,6 +139,13 @@ function stateModelFactory(configSchema) {
139
139
  get trackIds() {
140
140
  return (0, configuration_1.getConf)(self, 'trackIds');
141
141
  },
142
+ /**
143
+ * #getter
144
+ */
145
+ get height() {
146
+ // @ts-expect-error
147
+ return (0, mobx_state_tree_1.getParent)(self, 4).height;
148
+ },
142
149
  /**
143
150
  * #getter
144
151
  */
@@ -2,10 +2,9 @@ import React from 'react';
2
2
  import { SnapshotIn } from 'mobx-state-tree';
3
3
  import { AnyConfigurationModel } from '@jbrowse/core/configuration';
4
4
  type Conf = SnapshotIn<AnyConfigurationModel>;
5
- declare const ImportCustomTrack: ({ assembly1, assembly2, setSessionTrackData, }: {
6
- sessionTrackData: Conf;
5
+ declare const ImportCustomTrack: ({ assembly1, assembly2, setUserOpenedSyntenyTrack, }: {
7
6
  assembly1: string;
8
7
  assembly2: string;
9
- setSessionTrackData: (arg: Conf) => void;
8
+ setUserOpenedSyntenyTrack: (arg: Conf) => void;
10
9
  }) => React.JSX.Element;
11
10
  export default ImportCustomTrack;
@@ -91,7 +91,7 @@ function getAdapter({ radioOption, assembly1, assembly2, fileLocation, indexFile
91
91
  throw new Error(`Unknown to detect type ${radioOption} from filename (select radio button to clarify)`);
92
92
  }
93
93
  }
94
- const ImportCustomTrack = (0, mobx_react_1.observer)(function ({ assembly1, assembly2, setSessionTrackData, }) {
94
+ const ImportCustomTrack = (0, mobx_react_1.observer)(function ({ assembly1, assembly2, setUserOpenedSyntenyTrack, }) {
95
95
  const [bed2Location, setBed2Location] = (0, react_1.useState)();
96
96
  const [bed1Location, setBed1Location] = (0, react_1.useState)();
97
97
  const [fileLocation, setFileLocation] = (0, react_1.useState)();
@@ -106,7 +106,7 @@ const ImportCustomTrack = (0, mobx_react_1.observer)(function ({ assembly1, asse
106
106
  const fn = fileName ? (0, util_1.basename)(fileName) : 'MyTrack';
107
107
  const trackId = `${fn}-${Date.now()}`;
108
108
  setError(undefined);
109
- setSessionTrackData({
109
+ setUserOpenedSyntenyTrack({
110
110
  trackId,
111
111
  name: fn,
112
112
  assemblyNames: [assembly2, assembly1],
@@ -136,7 +136,7 @@ const ImportCustomTrack = (0, mobx_react_1.observer)(function ({ assembly1, asse
136
136
  fileLocation,
137
137
  indexFileLocation,
138
138
  radioOption,
139
- setSessionTrackData,
139
+ setUserOpenedSyntenyTrack,
140
140
  ]);
141
141
  return (react_1.default.createElement(material_1.Paper, { style: { padding: 12 } },
142
142
  error ? react_1.default.createElement(ui_1.ErrorMessage, { error: error }) : null,