@jbrowse/plugin-linear-comparative-view 2.15.4 → 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.
- package/dist/LaunchLinearSyntenyView.js +41 -11
- package/dist/LinearComparativeDisplay/stateModelFactory.d.ts +14 -9
- package/dist/LinearComparativeDisplay/stateModelFactory.js +8 -9
- package/dist/LinearComparativeView/components/Header.d.ts +2 -3
- package/dist/LinearComparativeView/components/Header.js +72 -62
- package/dist/LinearComparativeView/components/HeaderSearchBoxes.d.ts +6 -0
- package/dist/LinearComparativeView/components/HeaderSearchBoxes.js +34 -0
- package/dist/LinearComparativeView/components/LinearComparativeRenderArea.d.ts +6 -0
- package/dist/LinearComparativeView/components/LinearComparativeRenderArea.js +61 -0
- package/dist/LinearComparativeView/components/LinearComparativeView.d.ts +2 -4
- package/dist/LinearComparativeView/components/LinearComparativeView.js +3 -67
- package/dist/LinearComparativeView/components/Rubberband.js +1 -1
- package/dist/LinearComparativeView/index.js +3 -0
- package/dist/LinearComparativeView/model.d.ts +265 -12
- package/dist/LinearComparativeView/model.js +45 -75
- package/dist/LinearSyntenyDisplay/afterAttach.js +5 -3
- package/dist/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +32 -24
- package/dist/LinearSyntenyDisplay/components/SyntenyContextMenu.js +12 -6
- package/dist/LinearSyntenyDisplay/components/util.d.ts +2 -1
- package/dist/LinearSyntenyDisplay/components/util.js +5 -5
- package/dist/LinearSyntenyDisplay/drawSynteny.d.ts +1 -1
- package/dist/LinearSyntenyDisplay/drawSynteny.js +28 -22
- package/dist/LinearSyntenyDisplay/index.js +1 -1
- package/dist/LinearSyntenyDisplay/model.d.ts +12 -11
- package/dist/LinearSyntenyDisplay/model.js +7 -0
- package/dist/LinearSyntenyView/components/ImportForm/{ImportCustomTrack.d.ts → AddCustomTrack.d.ts} +2 -3
- package/dist/LinearSyntenyView/components/ImportForm/{ImportCustomTrack.js → AddCustomTrack.js} +3 -3
- package/dist/LinearSyntenyView/components/ImportForm/LinearSyntenyImportForm.js +195 -0
- package/dist/LinearSyntenyView/components/ImportForm/Spacer.d.ts +2 -0
- package/dist/LinearSyntenyView/components/ImportForm/Spacer.js +10 -0
- package/dist/LinearSyntenyView/components/ImportForm/TrackSelector.d.ts +10 -0
- package/dist/LinearSyntenyView/components/ImportForm/{ImportSyntenyTrackSelector.js → TrackSelector.js} +15 -20
- package/dist/LinearSyntenyView/components/ImportForm/TrackSelectorUtil.d.ts +14 -0
- package/dist/LinearSyntenyView/components/ImportForm/TrackSelectorUtil.js +52 -0
- package/dist/LinearSyntenyView/components/LinearSyntenyView.js +3 -3
- package/dist/LinearSyntenyView/index.js +1 -1
- package/dist/LinearSyntenyView/model.d.ts +267 -9
- package/dist/LinearSyntenyView/model.js +2 -2
- package/dist/LinearSyntenyView/svgcomponents/SVGLinearGenomeView.d.ts +12 -0
- package/dist/LinearSyntenyView/svgcomponents/SVGLinearGenomeView.js +19 -0
- package/dist/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.d.ts +1 -3
- package/dist/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js +36 -27
- package/dist/LinearSyntenyViewHelper/index.d.ts +2 -0
- package/dist/LinearSyntenyViewHelper/index.js +25 -0
- package/dist/LinearSyntenyViewHelper/stateModelFactory.d.ts +30 -0
- package/dist/LinearSyntenyViewHelper/stateModelFactory.js +105 -0
- package/dist/index.js +2 -0
- package/esm/LaunchLinearSyntenyView.js +41 -11
- package/esm/LinearComparativeDisplay/stateModelFactory.d.ts +14 -9
- package/esm/LinearComparativeDisplay/stateModelFactory.js +9 -10
- package/esm/LinearComparativeView/components/Header.d.ts +2 -3
- package/esm/LinearComparativeView/components/Header.js +73 -63
- package/esm/LinearComparativeView/components/HeaderSearchBoxes.d.ts +6 -0
- package/esm/LinearComparativeView/components/HeaderSearchBoxes.js +29 -0
- package/esm/LinearComparativeView/components/LinearComparativeRenderArea.d.ts +6 -0
- package/esm/LinearComparativeView/components/LinearComparativeRenderArea.js +56 -0
- package/esm/LinearComparativeView/components/LinearComparativeView.d.ts +2 -4
- package/esm/LinearComparativeView/components/LinearComparativeView.js +3 -67
- package/esm/LinearComparativeView/components/Rubberband.js +1 -1
- package/esm/LinearComparativeView/index.js +3 -0
- package/esm/LinearComparativeView/model.d.ts +265 -12
- package/esm/LinearComparativeView/model.js +47 -77
- package/esm/LinearSyntenyDisplay/afterAttach.js +6 -4
- package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +33 -25
- package/esm/LinearSyntenyDisplay/components/SyntenyContextMenu.js +12 -6
- package/esm/LinearSyntenyDisplay/components/util.d.ts +2 -1
- package/esm/LinearSyntenyDisplay/components/util.js +5 -5
- package/esm/LinearSyntenyDisplay/drawSynteny.d.ts +1 -1
- package/esm/LinearSyntenyDisplay/drawSynteny.js +28 -22
- package/esm/LinearSyntenyDisplay/index.js +1 -1
- package/esm/LinearSyntenyDisplay/model.d.ts +12 -11
- package/esm/LinearSyntenyDisplay/model.js +8 -1
- package/esm/LinearSyntenyView/components/ImportForm/{ImportCustomTrack.d.ts → AddCustomTrack.d.ts} +2 -3
- package/esm/LinearSyntenyView/components/ImportForm/{ImportCustomTrack.js → AddCustomTrack.js} +3 -3
- package/esm/LinearSyntenyView/components/ImportForm/LinearSyntenyImportForm.js +167 -0
- package/esm/LinearSyntenyView/components/ImportForm/Spacer.d.ts +2 -0
- package/esm/LinearSyntenyView/components/ImportForm/Spacer.js +4 -0
- package/esm/LinearSyntenyView/components/ImportForm/TrackSelector.d.ts +10 -0
- package/esm/LinearSyntenyView/components/ImportForm/{ImportSyntenyTrackSelector.js → TrackSelector.js} +15 -20
- package/esm/LinearSyntenyView/components/ImportForm/TrackSelectorUtil.d.ts +14 -0
- package/esm/LinearSyntenyView/components/ImportForm/TrackSelectorUtil.js +23 -0
- package/esm/LinearSyntenyView/components/LinearSyntenyView.js +3 -3
- package/esm/LinearSyntenyView/index.js +1 -1
- package/esm/LinearSyntenyView/model.d.ts +267 -9
- package/esm/LinearSyntenyView/model.js +2 -2
- package/esm/LinearSyntenyView/svgcomponents/SVGLinearGenomeView.d.ts +12 -0
- package/esm/LinearSyntenyView/svgcomponents/SVGLinearGenomeView.js +13 -0
- package/esm/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.d.ts +1 -3
- package/esm/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js +38 -29
- package/esm/LinearSyntenyViewHelper/index.d.ts +2 -0
- package/esm/LinearSyntenyViewHelper/index.js +19 -0
- package/esm/LinearSyntenyViewHelper/stateModelFactory.d.ts +30 -0
- package/esm/LinearSyntenyViewHelper/stateModelFactory.js +102 -0
- package/esm/index.js +2 -0
- package/package.json +2 -2
- package/dist/LinearSyntenyView/components/ImportForm/ImportSyntenyTrackSelector.d.ts +0 -9
- package/dist/LinearSyntenyView/components/ImportForm/index.js +0 -138
- package/esm/LinearSyntenyView/components/ImportForm/ImportSyntenyTrackSelector.d.ts +0 -9
- package/esm/LinearSyntenyView/components/ImportForm/index.js +0 -110
- /package/dist/LinearSyntenyView/components/ImportForm/{index.d.ts → LinearSyntenyImportForm.d.ts} +0 -0
- /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
|
-
|
|
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
|
|
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 - ((
|
|
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 (
|
|
107
|
-
|
|
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
|
-
|
|
123
|
+
scheduled.current = false;
|
|
114
124
|
});
|
|
115
125
|
});
|
|
116
126
|
}
|
|
117
127
|
}
|
|
118
128
|
}
|
|
119
|
-
|
|
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
|
-
|
|
131
|
+
var _a;
|
|
132
|
+
(_a = k2p.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('wheel', onWheel);
|
|
125
133
|
};
|
|
126
|
-
|
|
127
|
-
|
|
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:
|
|
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 (
|
|
149
|
-
|
|
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
|
-
|
|
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.
|
|
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[
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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[
|
|
16
|
-
const x12 = p12.offsetPx - offsets[
|
|
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):
|
|
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 =
|
|
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 /
|
|
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
|
|
49
|
-
const x11 = p11.offsetPx - offsets[
|
|
50
|
-
const x12 = p12.offsetPx - offsets[
|
|
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
|
|
79
|
-
const x11 = p11.offsetPx - offsets[
|
|
80
|
-
const x12 = p12.offsetPx - offsets[
|
|
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[
|
|
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
|
|
145
|
-
// if the last element of continuing was a large
|
|
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 <
|
|
172
|
-
const feature =
|
|
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 =
|
|
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: '
|
|
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"
|
|
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"
|
|
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
|
*/
|
package/dist/LinearSyntenyView/components/ImportForm/{ImportCustomTrack.d.ts → AddCustomTrack.d.ts}
RENAMED
|
@@ -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,
|
|
6
|
-
sessionTrackData: Conf;
|
|
5
|
+
declare const ImportCustomTrack: ({ assembly1, assembly2, setUserOpenedSyntenyTrack, }: {
|
|
7
6
|
assembly1: string;
|
|
8
7
|
assembly2: string;
|
|
9
|
-
|
|
8
|
+
setUserOpenedSyntenyTrack: (arg: Conf) => void;
|
|
10
9
|
}) => React.JSX.Element;
|
|
11
10
|
export default ImportCustomTrack;
|
package/dist/LinearSyntenyView/components/ImportForm/{ImportCustomTrack.js → AddCustomTrack.js}
RENAMED
|
@@ -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,
|
|
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
|
-
|
|
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
|
-
|
|
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,
|