@jbrowse/plugin-linear-genome-view 2.13.0 → 2.14.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/BaseLinearDisplay/components/LinearBlocks.js +2 -2
- package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +3 -1
- package/dist/BaseLinearDisplay/components/Tooltip.js +1 -1
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +1 -1
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +8 -5
- package/dist/BaseLinearDisplay/models/FeatureDensityMixin.js +2 -3
- package/dist/BaseLinearDisplay/models/renderSvg.d.ts +1 -1
- package/dist/BaseLinearDisplay/models/renderSvg.js +3 -1
- package/dist/BaseLinearDisplay/models/util.d.ts +1 -1
- package/dist/BaseLinearDisplay/models/util.js +3 -5
- package/dist/LaunchLinearGenomeView/index.js +12 -11
- package/dist/LinearBareDisplay/model.d.ts +1 -1
- package/dist/LinearBasicDisplay/components/AddFiltersDialog.js +9 -3
- package/dist/LinearBasicDisplay/components/SetMaxHeightDialog.js +6 -2
- package/dist/LinearBasicDisplay/model.d.ts +2 -4
- package/dist/LinearBasicDisplay/model.js +9 -3
- package/dist/LinearGenomeView/components/Cytobands.js +6 -23
- package/dist/LinearGenomeView/components/ExportSvgDialog.js +16 -6
- package/dist/LinearGenomeView/components/GetSequenceDialog.js +13 -16
- package/dist/LinearGenomeView/components/Header.js +6 -2
- package/dist/LinearGenomeView/components/Highlight.js +24 -25
- package/dist/LinearGenomeView/components/ImportForm.js +5 -2
- package/dist/LinearGenomeView/components/ImportFormRefNameAutocomplete.js +5 -1
- package/dist/LinearGenomeView/components/LinearGenomeView.d.ts +2 -3
- package/dist/LinearGenomeView/components/LinearGenomeView.js +5 -3
- package/dist/LinearGenomeView/components/MiniControls.js +6 -2
- package/dist/LinearGenomeView/components/OverviewHighlight.js +23 -30
- package/dist/LinearGenomeView/components/OverviewRubberband.js +1 -1
- package/dist/LinearGenomeView/components/OverviewScalebar.js +6 -11
- package/dist/LinearGenomeView/components/OverviewScalebarPolygon.js +1 -2
- package/dist/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js +6 -5
- package/dist/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.js +6 -2
- package/dist/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.js +3 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete/index.js +9 -7
- package/dist/LinearGenomeView/components/RubberbandSpan.js +3 -5
- package/dist/LinearGenomeView/components/Scalebar.js +2 -1
- package/dist/LinearGenomeView/components/SearchResultsDialog.js +3 -1
- package/dist/LinearGenomeView/components/SearchResultsTable.js +2 -3
- package/dist/LinearGenomeView/components/SequenceSearchDialog.js +15 -5
- package/dist/LinearGenomeView/components/TrackContainer.js +2 -2
- package/dist/LinearGenomeView/components/TrackLabel.js +15 -5
- package/dist/LinearGenomeView/components/TrackLabelDragHandle.js +3 -1
- package/dist/LinearGenomeView/components/TracksContainer.js +1 -1
- package/dist/LinearGenomeView/components/ZoomControls.js +10 -4
- package/dist/LinearGenomeView/components/hooks.d.ts +2 -2
- package/dist/LinearGenomeView/components/hooks.js +24 -26
- package/dist/LinearGenomeView/components/util.d.ts +2 -2
- package/dist/LinearGenomeView/model.d.ts +24 -13
- package/dist/LinearGenomeView/model.js +75 -46
- package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +0 -1
- package/dist/LinearGenomeView/svgcomponents/SVGRuler.js +1 -1
- package/dist/LinearGenomeView/util.d.ts +1 -1
- package/dist/LinearGenomeView/util.js +4 -9
- package/dist/index.d.ts +3 -414
- package/dist/searchUtils.js +4 -6
- package/esm/BaseLinearDisplay/components/LinearBlocks.js +2 -2
- package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +3 -1
- package/esm/BaseLinearDisplay/components/Tooltip.js +1 -1
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +1 -1
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +8 -5
- package/esm/BaseLinearDisplay/models/FeatureDensityMixin.js +2 -3
- package/esm/BaseLinearDisplay/models/renderSvg.d.ts +1 -1
- package/esm/BaseLinearDisplay/models/renderSvg.js +3 -1
- package/esm/BaseLinearDisplay/models/util.d.ts +1 -1
- package/esm/BaseLinearDisplay/models/util.js +3 -5
- package/esm/LaunchLinearGenomeView/index.js +13 -12
- package/esm/LinearBareDisplay/model.d.ts +1 -1
- package/esm/LinearBasicDisplay/components/AddFiltersDialog.js +9 -3
- package/esm/LinearBasicDisplay/components/SetMaxHeightDialog.js +6 -2
- package/esm/LinearBasicDisplay/model.d.ts +2 -4
- package/esm/LinearBasicDisplay/model.js +9 -3
- package/esm/LinearGenomeView/components/Cytobands.js +6 -23
- package/esm/LinearGenomeView/components/ExportSvgDialog.js +16 -6
- package/esm/LinearGenomeView/components/GetSequenceDialog.js +13 -16
- package/esm/LinearGenomeView/components/Header.js +6 -2
- package/esm/LinearGenomeView/components/Highlight.js +26 -27
- package/esm/LinearGenomeView/components/ImportForm.js +5 -2
- package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.js +5 -1
- package/esm/LinearGenomeView/components/LinearGenomeView.d.ts +2 -3
- package/esm/LinearGenomeView/components/LinearGenomeView.js +5 -3
- package/esm/LinearGenomeView/components/MiniControls.js +6 -2
- package/esm/LinearGenomeView/components/OverviewHighlight.js +24 -31
- package/esm/LinearGenomeView/components/OverviewRubberband.js +1 -1
- package/esm/LinearGenomeView/components/OverviewScalebar.js +6 -11
- package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +1 -2
- package/esm/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js +6 -5
- package/esm/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.js +6 -2
- package/esm/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.js +3 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete/index.js +10 -8
- package/esm/LinearGenomeView/components/RubberbandSpan.js +3 -5
- package/esm/LinearGenomeView/components/Scalebar.js +2 -1
- package/esm/LinearGenomeView/components/SearchResultsDialog.js +3 -1
- package/esm/LinearGenomeView/components/SearchResultsTable.js +2 -3
- package/esm/LinearGenomeView/components/SequenceSearchDialog.js +15 -5
- package/esm/LinearGenomeView/components/TrackContainer.js +2 -2
- package/esm/LinearGenomeView/components/TrackLabel.js +15 -5
- package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +3 -1
- package/esm/LinearGenomeView/components/TracksContainer.js +1 -1
- package/esm/LinearGenomeView/components/ZoomControls.js +10 -4
- package/esm/LinearGenomeView/components/hooks.d.ts +2 -2
- package/esm/LinearGenomeView/components/hooks.js +24 -26
- package/esm/LinearGenomeView/components/util.d.ts +2 -2
- package/esm/LinearGenomeView/model.d.ts +24 -13
- package/esm/LinearGenomeView/model.js +77 -48
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +0 -1
- package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +1 -1
- package/esm/LinearGenomeView/util.d.ts +1 -1
- package/esm/LinearGenomeView/util.js +4 -9
- package/esm/index.d.ts +3 -414
- package/esm/searchUtils.js +4 -6
- package/package.json +3 -3
|
@@ -45,10 +45,10 @@ const RenderedBlocks = (0, mobx_react_1.observer)(function ({ model, }) {
|
|
|
45
45
|
height: 16,
|
|
46
46
|
} }, "Max height reached")) : null));
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
if (block.type === 'ElidedBlock') {
|
|
49
49
|
return react_1.default.createElement(Block_1.ElidedBlock, { key: key, width: block.widthPx });
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
if (block.type === 'InterRegionPaddingBlock') {
|
|
52
52
|
return (react_1.default.createElement(Block_1.InterRegionPaddingBlock, { key: key, width: block.widthPx, style: { background: 'none' }, boundary: block.variant === 'boundary' }));
|
|
53
53
|
}
|
|
54
54
|
throw new Error(`invalid block type ${JSON.stringify(block)}`);
|
|
@@ -62,7 +62,9 @@ const ServerSideRenderedBlockContent = (0, mobx_react_1.observer)(function ({ mo
|
|
|
62
62
|
if (model.error) {
|
|
63
63
|
return (react_1.default.createElement(BlockMsg_1.default, { message: `${model.error}`, severity: "error", action: react_1.default.createElement(react_1.default.Fragment, null,
|
|
64
64
|
react_1.default.createElement(material_1.Tooltip, { title: "Reload track" },
|
|
65
|
-
react_1.default.createElement(material_1.IconButton, { "data-testid": "reload_button", onClick: () =>
|
|
65
|
+
react_1.default.createElement(material_1.IconButton, { "data-testid": "reload_button", onClick: () => {
|
|
66
|
+
model.reload();
|
|
67
|
+
} },
|
|
66
68
|
react_1.default.createElement(Refresh_1.default, null))),
|
|
67
69
|
react_1.default.createElement(material_1.Tooltip, { title: "Show stack trace" },
|
|
68
70
|
react_1.default.createElement(material_1.IconButton, { onClick: () => {
|
|
@@ -47,7 +47,7 @@ const Tooltip = (0, mobx_react_1.observer)(function ({ model, clientMouseCoord,
|
|
|
47
47
|
const contents = featureUnderMouse
|
|
48
48
|
? (0, configuration_1.getConf)(model, 'mouseover', { feature: featureUnderMouse })
|
|
49
49
|
: undefined;
|
|
50
|
-
const popperTheme = (_a = theme
|
|
50
|
+
const popperTheme = (_a = theme.components) === null || _a === void 0 ? void 0 : _a.MuiPopper;
|
|
51
51
|
return featureUnderMouse && contents ? (react_1.default.createElement(material_1.Portal, { container: (_b = popperTheme === null || popperTheme === void 0 ? void 0 : popperTheme.defaultProps) === null || _b === void 0 ? void 0 : _b.container },
|
|
52
52
|
react_1.default.createElement("div", { className: classes.tooltip, ref: refs.setFloating, style: {
|
|
53
53
|
...floatingStyles,
|
|
@@ -139,7 +139,7 @@ export declare const BaseLinearDisplay: import("mobx-state-tree").IModelType<{
|
|
|
139
139
|
error: unknown;
|
|
140
140
|
message: string | undefined;
|
|
141
141
|
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
142
|
-
onHorizontalScroll?:
|
|
142
|
+
onHorizontalScroll?: () => void;
|
|
143
143
|
blockState?: Record<string, any>;
|
|
144
144
|
}>;
|
|
145
145
|
readonly DisplayBlurb: React.FC<{
|
|
@@ -137,7 +137,7 @@ function stateModelFactory() {
|
|
|
137
137
|
get features() {
|
|
138
138
|
const featureMaps = [];
|
|
139
139
|
for (const block of self.blockState.values()) {
|
|
140
|
-
if (block
|
|
140
|
+
if (block.features) {
|
|
141
141
|
featureMaps.push(block.features);
|
|
142
142
|
}
|
|
143
143
|
}
|
|
@@ -171,7 +171,7 @@ function stateModelFactory() {
|
|
|
171
171
|
let ret;
|
|
172
172
|
self.blockState.forEach(block => {
|
|
173
173
|
var _a;
|
|
174
|
-
const val = (_a = block
|
|
174
|
+
const val = (_a = block.layout) === null || _a === void 0 ? void 0 : _a.getByID(id);
|
|
175
175
|
if (val) {
|
|
176
176
|
ret = val;
|
|
177
177
|
}
|
|
@@ -252,7 +252,9 @@ function stateModelFactory() {
|
|
|
252
252
|
self.setError();
|
|
253
253
|
self.setCurrStatsBpPerPx(0);
|
|
254
254
|
self.clearFeatureDensityStats();
|
|
255
|
-
[...self.blockState.values()].
|
|
255
|
+
[...self.blockState.values()].forEach(val => {
|
|
256
|
+
val.doReload();
|
|
257
|
+
});
|
|
256
258
|
superReload();
|
|
257
259
|
},
|
|
258
260
|
};
|
|
@@ -374,6 +376,7 @@ function stateModelFactory() {
|
|
|
374
376
|
},
|
|
375
377
|
}))
|
|
376
378
|
.preProcessSnapshot(snap => {
|
|
379
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
377
380
|
if (!snap) {
|
|
378
381
|
return snap;
|
|
379
382
|
}
|
|
@@ -383,9 +386,9 @@ function stateModelFactory() {
|
|
|
383
386
|
const { height, ...rest } = snap;
|
|
384
387
|
return { heightPreConfig: height, ...rest };
|
|
385
388
|
})
|
|
386
|
-
.postProcessSnapshot(
|
|
389
|
+
.postProcessSnapshot(snap => {
|
|
387
390
|
// xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit
|
|
388
|
-
const r =
|
|
391
|
+
const r = snap;
|
|
389
392
|
const { blockState, ...rest } = r;
|
|
390
393
|
return rest;
|
|
391
394
|
});
|
|
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.default = FeatureDensityMixin;
|
|
7
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
8
7
|
const react_1 = __importDefault(require("react"));
|
|
9
8
|
const configuration_1 = require("@jbrowse/core/configuration");
|
|
10
9
|
const util_1 = require("@jbrowse/core/util");
|
|
@@ -103,9 +102,9 @@ function FeatureDensityMixin() {
|
|
|
103
102
|
/**
|
|
104
103
|
* #action
|
|
105
104
|
*/
|
|
106
|
-
|
|
105
|
+
getFeatureDensityStats() {
|
|
107
106
|
if (!self.featureDensityStatsP) {
|
|
108
|
-
self.featureDensityStatsP = (0, util_2.getFeatureDensityStatsPre)(self).catch(e => {
|
|
107
|
+
self.featureDensityStatsP = (0, util_2.getFeatureDensityStatsPre)(self).catch((e) => {
|
|
109
108
|
if ((0, mobx_state_tree_1.isAlive)(self)) {
|
|
110
109
|
this.setFeatureDensityStatsP(undefined);
|
|
111
110
|
}
|
|
@@ -4,5 +4,5 @@ import { ExportSvgOptions } from '../../LinearGenomeView';
|
|
|
4
4
|
import { BaseLinearDisplayModel } from './BaseLinearDisplayModel';
|
|
5
5
|
export declare function renderBaseLinearDisplaySvg(self: BaseLinearDisplayModel, opts: ExportSvgOptions & {
|
|
6
6
|
overrideHeight: number;
|
|
7
|
-
theme
|
|
7
|
+
theme?: ThemeOptions;
|
|
8
8
|
}): Promise<React.JSX.Element>;
|
|
@@ -71,7 +71,9 @@ async function renderBaseLinearDisplaySvg(self, opts) {
|
|
|
71
71
|
const { offsetPx, widthPx } = block;
|
|
72
72
|
const offset = offsetPx - viewOffsetPx;
|
|
73
73
|
const clipid = (0, util_2.getId)(id, index);
|
|
74
|
-
return (
|
|
74
|
+
return (
|
|
75
|
+
/* biome-ignore lint/suspicious/noArrayIndexKey: */
|
|
76
|
+
react_1.default.createElement(react_1.default.Fragment, { key: `frag-${index}` },
|
|
75
77
|
react_1.default.createElement("defs", null,
|
|
76
78
|
react_1.default.createElement("clipPath", { id: clipid },
|
|
77
79
|
react_1.default.createElement("rect", { x: 0, y: 0, width: widthPx, height: overrideHeight || height }))),
|
|
@@ -7,17 +7,15 @@ const util_1 = require("@jbrowse/core/util");
|
|
|
7
7
|
const tracks_1 = require("@jbrowse/core/util/tracks");
|
|
8
8
|
const mobx_state_tree_1 = require("mobx-state-tree");
|
|
9
9
|
function getDisplayStr(totalBytes) {
|
|
10
|
-
let displayBp;
|
|
11
10
|
if (Math.floor(totalBytes / 1000000) > 0) {
|
|
12
|
-
|
|
11
|
+
return `${Number.parseFloat((totalBytes / 1000000).toPrecision(3))} Mb`;
|
|
13
12
|
}
|
|
14
13
|
else if (Math.floor(totalBytes / 1000) > 0) {
|
|
15
|
-
|
|
14
|
+
return `${Number.parseFloat((totalBytes / 1000).toPrecision(3))} Kb`;
|
|
16
15
|
}
|
|
17
16
|
else {
|
|
18
|
-
|
|
17
|
+
return `${Math.floor(totalBytes)} bytes`;
|
|
19
18
|
}
|
|
20
|
-
return displayBp;
|
|
21
19
|
}
|
|
22
20
|
// stabilize clipid under test for snapshot
|
|
23
21
|
function getId(id, index) {
|
|
@@ -27,22 +27,23 @@ function LaunchLinearGenomeViewF(pluginManager) {
|
|
|
27
27
|
}
|
|
28
28
|
if (highlight !== undefined) {
|
|
29
29
|
highlight.forEach(async (h) => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
const p = (0, util_1.parseLocString)(h, refName => isValidRefName(refName, assembly));
|
|
31
|
+
const { start, end } = p;
|
|
32
|
+
if (start !== undefined && end !== undefined) {
|
|
33
|
+
view.addToHighlights({
|
|
34
|
+
...p,
|
|
35
|
+
start,
|
|
36
|
+
end,
|
|
34
37
|
assemblyName: assembly,
|
|
35
|
-
};
|
|
36
|
-
if ((location === null || location === void 0 ? void 0 : location.start) !== undefined &&
|
|
37
|
-
(location === null || location === void 0 ? void 0 : location.end) !== undefined) {
|
|
38
|
-
view.addToHighlights(location);
|
|
39
|
-
}
|
|
38
|
+
});
|
|
40
39
|
}
|
|
41
40
|
});
|
|
42
41
|
}
|
|
43
42
|
await (0, searchUtils_1.handleSelectedRegion)({ input: loc, model: view, assembly: asm });
|
|
44
43
|
const idsNotFound = [];
|
|
45
|
-
tracks.forEach(track =>
|
|
44
|
+
tracks.forEach(track => {
|
|
45
|
+
tryTrack(view, track, idsNotFound);
|
|
46
|
+
});
|
|
46
47
|
if (idsNotFound.length) {
|
|
47
48
|
throw new Error(`Could not resolve identifiers: ${idsNotFound.join(',')}`);
|
|
48
49
|
}
|
|
@@ -58,7 +59,7 @@ function tryTrack(model, trackId, idsNotFound) {
|
|
|
58
59
|
model.showTrack(trackId);
|
|
59
60
|
}
|
|
60
61
|
catch (e) {
|
|
61
|
-
if (
|
|
62
|
+
if (/Could not resolve identifier/.exec(`${e}`)) {
|
|
62
63
|
idsNotFound.push(trackId);
|
|
63
64
|
}
|
|
64
65
|
else {
|
|
@@ -128,7 +128,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
128
128
|
error: unknown;
|
|
129
129
|
message: string | undefined;
|
|
130
130
|
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
131
|
-
onHorizontalScroll?:
|
|
131
|
+
onHorizontalScroll?: () => void;
|
|
132
132
|
blockState?: Record<string, any>;
|
|
133
133
|
}>;
|
|
134
134
|
readonly DisplayBlurb: import("react").FC<{
|
|
@@ -55,7 +55,9 @@ const AddFiltersDialog = (0, mobx_react_1.observer)(function ({ model, handleClo
|
|
|
55
55
|
.split('\n')
|
|
56
56
|
.map(line => line.trim())
|
|
57
57
|
.filter(line => !!line)
|
|
58
|
-
.map(line =>
|
|
58
|
+
.map(line => {
|
|
59
|
+
checkJexl(line.trim());
|
|
60
|
+
});
|
|
59
61
|
setError(undefined);
|
|
60
62
|
}
|
|
61
63
|
catch (e) {
|
|
@@ -79,7 +81,9 @@ const AddFiltersDialog = (0, mobx_react_1.observer)(function ({ model, handleClo
|
|
|
79
81
|
react_1.default.createElement("code", null, "jexl:get(feature,'score') > 400"),
|
|
80
82
|
" - show only features that have a score greater than 400"))),
|
|
81
83
|
error ? react_1.default.createElement("p", { className: classes.error }, `${error}`) : null,
|
|
82
|
-
react_1.default.createElement(material_1.TextField, { variant: "outlined", multiline: true, minRows: 5, maxRows: 10, className: classes.dialogContent, fullWidth: true, value: data, onChange: event =>
|
|
84
|
+
react_1.default.createElement(material_1.TextField, { variant: "outlined", multiline: true, minRows: 5, maxRows: 10, className: classes.dialogContent, fullWidth: true, value: data, onChange: event => {
|
|
85
|
+
setData(event.target.value);
|
|
86
|
+
}, InputProps: {
|
|
83
87
|
classes: {
|
|
84
88
|
input: classes.textAreaFont,
|
|
85
89
|
},
|
|
@@ -89,6 +93,8 @@ const AddFiltersDialog = (0, mobx_react_1.observer)(function ({ model, handleClo
|
|
|
89
93
|
model.setJexlFilters(data.split('\n'));
|
|
90
94
|
handleClose();
|
|
91
95
|
} }, "Submit"),
|
|
92
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: () =>
|
|
96
|
+
react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
97
|
+
handleClose();
|
|
98
|
+
} }, "Cancel"))));
|
|
93
99
|
});
|
|
94
100
|
exports.default = AddFiltersDialog;
|
|
@@ -40,12 +40,16 @@ const SetMaxHeightDialog = (0, mobx_react_1.observer)(function ({ model, handleC
|
|
|
40
40
|
return (react_1.default.createElement(ui_1.Dialog, { open: true, onClose: handleClose, title: "Set max height" },
|
|
41
41
|
react_1.default.createElement(material_1.DialogContent, { className: classes.root },
|
|
42
42
|
react_1.default.createElement(material_1.Typography, null, "Set max height for the track. For example, you can increase this if the layout says \"Max height reached\""),
|
|
43
|
-
react_1.default.createElement(material_1.TextField, { value: max, onChange: event =>
|
|
43
|
+
react_1.default.createElement(material_1.TextField, { value: max, onChange: event => {
|
|
44
|
+
setMax(event.target.value);
|
|
45
|
+
}, placeholder: "Enter max score" })),
|
|
44
46
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
45
47
|
react_1.default.createElement(material_1.Button, { variant: "contained", color: "primary", type: "submit", autoFocus: true, onClick: () => {
|
|
46
48
|
model.setMaxHeight(max !== '' && !Number.isNaN(+max) ? +max : undefined);
|
|
47
49
|
handleClose();
|
|
48
50
|
} }, "Submit"),
|
|
49
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: () =>
|
|
51
|
+
react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
52
|
+
handleClose();
|
|
53
|
+
} }, "Cancel"))));
|
|
50
54
|
});
|
|
51
55
|
exports.default = SetMaxHeightDialog;
|
|
@@ -156,7 +156,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
156
156
|
error: unknown;
|
|
157
157
|
message: string | undefined;
|
|
158
158
|
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
159
|
-
onHorizontalScroll?:
|
|
159
|
+
onHorizontalScroll?: () => void;
|
|
160
160
|
blockState? /**
|
|
161
161
|
* #getter
|
|
162
162
|
*/: Record<string, any>;
|
|
@@ -294,9 +294,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
294
294
|
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
295
295
|
setSubschema(slotName: string, data: Record<string, unknown>): Record<string, unknown> | ({
|
|
296
296
|
[x: string]: any;
|
|
297
|
-
} & import("mobx-state-tree/dist/internal"
|
|
298
|
-
* #property
|
|
299
|
-
*/).NonEmptyObject & {
|
|
297
|
+
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
300
298
|
setSubschema(slotName: string, data: Record<string, unknown>): Record<string, unknown> | ({
|
|
301
299
|
[x: string]: any;
|
|
302
300
|
} & import("mobx-state-tree/dist/internal").NonEmptyObject & any & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>);
|
|
@@ -198,14 +198,18 @@ function stateModelFactory(configSchema) {
|
|
|
198
198
|
icon: Visibility_1.default,
|
|
199
199
|
type: 'checkbox',
|
|
200
200
|
checked: self.showLabels,
|
|
201
|
-
onClick: () =>
|
|
201
|
+
onClick: () => {
|
|
202
|
+
self.toggleShowLabels();
|
|
203
|
+
},
|
|
202
204
|
},
|
|
203
205
|
{
|
|
204
206
|
label: 'Show descriptions',
|
|
205
207
|
icon: Visibility_1.default,
|
|
206
208
|
type: 'checkbox',
|
|
207
209
|
checked: self.showDescriptions,
|
|
208
|
-
onClick: () =>
|
|
210
|
+
onClick: () => {
|
|
211
|
+
self.toggleShowDescriptions();
|
|
212
|
+
},
|
|
209
213
|
},
|
|
210
214
|
{
|
|
211
215
|
label: 'Display mode',
|
|
@@ -217,7 +221,9 @@ function stateModelFactory(configSchema) {
|
|
|
217
221
|
'collapse',
|
|
218
222
|
].map(val => ({
|
|
219
223
|
label: val,
|
|
220
|
-
onClick: () =>
|
|
224
|
+
onClick: () => {
|
|
225
|
+
self.setDisplayMode(val);
|
|
226
|
+
},
|
|
221
227
|
})),
|
|
222
228
|
},
|
|
223
229
|
{
|
|
@@ -10,26 +10,11 @@ const __1 = require("..");
|
|
|
10
10
|
const util_1 = require("./util");
|
|
11
11
|
const util_2 = require("@jbrowse/core/util");
|
|
12
12
|
// rounded rect from https://stackoverflow.com/a/45889603/2129219
|
|
13
|
-
// prettier-ignore
|
|
14
13
|
function rightRoundedRect(x, y, width, height, radius) {
|
|
15
|
-
return
|
|
16
|
-
+ "h" + (width - radius)
|
|
17
|
-
+ "a" + radius + "," + radius + " 0 0 1 " + radius + "," + radius
|
|
18
|
-
+ "v" + (height - 2 * radius)
|
|
19
|
-
+ "a" + radius + "," + radius + " 0 0 1 " + -radius + "," + radius
|
|
20
|
-
+ "h" + (radius - width)
|
|
21
|
-
+ "z";
|
|
14
|
+
return `M${x},${y}h${width - radius}a${radius},${radius} 0 0 1 ${radius},${radius}v${height - 2 * radius}a${radius},${radius} 0 0 1 ${-radius},${radius}h${radius - width}z`;
|
|
22
15
|
}
|
|
23
|
-
// prettier-ignore
|
|
24
16
|
function leftRoundedRect(x, y, width, height, radius) {
|
|
25
|
-
return
|
|
26
|
-
+ "h" + (width - radius)
|
|
27
|
-
+ "v" + height
|
|
28
|
-
+ "h" + (radius - width)
|
|
29
|
-
+ "a" + radius + "," + radius + " 0 0 1 " + (-radius) + "," + (-radius)
|
|
30
|
-
+ "v" + (2 * radius - height)
|
|
31
|
-
+ "a" + radius + "," + radius + " 0 0 1 " + radius + "," + (-radius)
|
|
32
|
-
+ "z";
|
|
17
|
+
return `M${x + radius},${y}h${width - radius}v${height}h${radius - width}a${radius},${radius} 0 0 1 ${-radius},${-radius}v${2 * radius - height}a${radius},${radius} 0 0 1 ${radius},${-radius}z`;
|
|
33
18
|
}
|
|
34
19
|
function leftTriangle(x, y, width, height) {
|
|
35
20
|
return [
|
|
@@ -76,20 +61,18 @@ const Cytobands = (0, mobx_react_1.observer)(function ({ overview, block, assemb
|
|
|
76
61
|
? rightTriangle(s - w, 0, w, h)
|
|
77
62
|
: leftTriangle(s, 0, w, h), ...(0, util_2.getFillProps)(c) }));
|
|
78
63
|
}
|
|
79
|
-
|
|
64
|
+
if (type === 'acen' && centromereSeen) {
|
|
80
65
|
return (react_1.default.createElement("polygon", { key: k, points: reversed
|
|
81
66
|
? leftTriangle(s - w, 0, w, h)
|
|
82
67
|
: rightTriangle(s, 0, w, h), ...(0, util_2.getFillProps)(c) }));
|
|
83
68
|
}
|
|
84
|
-
|
|
69
|
+
if (lcap === index) {
|
|
85
70
|
return (react_1.default.createElement("path", { key: k, d: leftRoundedRect(l, 0, w, h, 8), ...(0, util_2.getFillProps)(c) }));
|
|
86
71
|
}
|
|
87
|
-
|
|
72
|
+
if (rcap === index) {
|
|
88
73
|
return (react_1.default.createElement("path", { key: k, d: rightRoundedRect(l, 0, w, h, 8), ...(0, util_2.getFillProps)(c) }));
|
|
89
74
|
}
|
|
90
|
-
|
|
91
|
-
return (react_1.default.createElement("rect", { key: k, x: l, y: 0, width: w, height: h, ...(0, util_2.getFillProps)(c) }));
|
|
92
|
-
}
|
|
75
|
+
return (react_1.default.createElement("rect", { key: k, x: l, y: 0, width: w, height: h, ...(0, util_2.getFillProps)(c) }));
|
|
93
76
|
})));
|
|
94
77
|
});
|
|
95
78
|
exports.default = Cytobands;
|
|
@@ -34,7 +34,7 @@ function LoadingMessage() {
|
|
|
34
34
|
react_1.default.createElement(material_1.Typography, { display: "inline" }, "Creating SVG")));
|
|
35
35
|
}
|
|
36
36
|
function useSvgLocal(key, val) {
|
|
37
|
-
return (0, util_1.useLocalStorage)(
|
|
37
|
+
return (0, util_1.useLocalStorage)(`svg-${key}`, val);
|
|
38
38
|
}
|
|
39
39
|
function TextField2({ children, ...rest }) {
|
|
40
40
|
return (react_1.default.createElement("div", null,
|
|
@@ -52,18 +52,28 @@ function ExportSvgDialog({ model, handleClose, }) {
|
|
|
52
52
|
return (react_1.default.createElement(ui_1.Dialog, { open: true, onClose: handleClose, title: "Export SVG" },
|
|
53
53
|
react_1.default.createElement(material_1.DialogContent, null,
|
|
54
54
|
error ? (react_1.default.createElement(ui_1.ErrorMessage, { error: error })) : loading ? (react_1.default.createElement(LoadingMessage, null)) : null,
|
|
55
|
-
react_1.default.createElement(TextField2, { helperText: "filename", value: filename, onChange: event =>
|
|
56
|
-
|
|
55
|
+
react_1.default.createElement(TextField2, { helperText: "filename", value: filename, onChange: event => {
|
|
56
|
+
setFilename(event.target.value);
|
|
57
|
+
} }),
|
|
58
|
+
react_1.default.createElement(TextField2, { select: true, label: "Track label positioning", variant: "outlined", style: { width: 150 }, value: trackLabels, onChange: event => {
|
|
59
|
+
setTrackLabels(event.target.value);
|
|
60
|
+
} },
|
|
57
61
|
react_1.default.createElement(material_1.MenuItem, { value: "offset" }, "Offset"),
|
|
58
62
|
react_1.default.createElement(material_1.MenuItem, { value: "overlay" }, "Overlay"),
|
|
59
63
|
react_1.default.createElement(material_1.MenuItem, { value: "left" }, "Left"),
|
|
60
64
|
react_1.default.createElement(material_1.MenuItem, { value: "none" }, "None")),
|
|
61
|
-
session.allThemes ? (react_1.default.createElement(TextField2, { select: true, label: "Theme", variant: "outlined", value: themeName, onChange: event =>
|
|
65
|
+
session.allThemes ? (react_1.default.createElement(TextField2, { select: true, label: "Theme", variant: "outlined", value: themeName, onChange: event => {
|
|
66
|
+
setThemeName(event.target.value);
|
|
67
|
+
} }, Object.entries(session.allThemes()).map(([key, val]) => (react_1.default.createElement(material_1.MenuItem, { key: key, value: key },
|
|
62
68
|
// @ts-expect-error
|
|
63
69
|
val.name || '(Unknown name)'))))) : null,
|
|
64
|
-
offscreenCanvas ? (react_1.default.createElement(material_1.FormControlLabel, { control: react_1.default.createElement(material_1.Checkbox, { checked: rasterizeLayers, onChange: () =>
|
|
70
|
+
offscreenCanvas ? (react_1.default.createElement(material_1.FormControlLabel, { control: react_1.default.createElement(material_1.Checkbox, { checked: rasterizeLayers, onChange: () => {
|
|
71
|
+
setRasterizeLayers(val => !val);
|
|
72
|
+
} }), label: "Rasterize canvas based tracks? File may be much larger if this is turned off" })) : (react_1.default.createElement(material_1.Typography, null, "Note: rasterizing layers not yet supported in this browser, so SVG size may be large"))),
|
|
65
73
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
66
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: () =>
|
|
74
|
+
react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
75
|
+
handleClose();
|
|
76
|
+
} }, "Cancel"),
|
|
67
77
|
react_1.default.createElement(material_1.Button, { variant: "contained", color: "primary", type: "submit", onClick: async () => {
|
|
68
78
|
setLoading(true);
|
|
69
79
|
setError(undefined);
|
|
@@ -76,7 +76,6 @@ async function fetchSequence(model, regions, signal) {
|
|
|
76
76
|
}
|
|
77
77
|
const GetSequenceDialog = (0, mobx_react_1.observer)(function ({ model, handleClose, }) {
|
|
78
78
|
const { classes } = useStyles();
|
|
79
|
-
const session = (0, util_1.getSession)(model);
|
|
80
79
|
const [error, setError] = (0, react_1.useState)();
|
|
81
80
|
const [sequenceChunks, setSequenceChunks] = (0, react_1.useState)();
|
|
82
81
|
const [rev, setReverse] = (0, react_1.useState)(false);
|
|
@@ -85,7 +84,6 @@ const GetSequenceDialog = (0, mobx_react_1.observer)(function ({ model, handleCl
|
|
|
85
84
|
const { leftOffset, rightOffset } = model;
|
|
86
85
|
const loading = Boolean(sequenceChunks === undefined);
|
|
87
86
|
(0, react_1.useEffect)(() => {
|
|
88
|
-
let active = true;
|
|
89
87
|
const controller = new AbortController();
|
|
90
88
|
(async () => {
|
|
91
89
|
try {
|
|
@@ -97,26 +95,19 @@ const GetSequenceDialog = (0, mobx_react_1.observer)(function ({ model, handleCl
|
|
|
97
95
|
throw new Error('Selected region is out of bounds');
|
|
98
96
|
}
|
|
99
97
|
const chunks = await fetchSequence(model, selection, controller.signal);
|
|
100
|
-
|
|
101
|
-
setSequenceChunks(chunks);
|
|
102
|
-
}
|
|
98
|
+
setSequenceChunks(chunks);
|
|
103
99
|
}
|
|
104
100
|
catch (e) {
|
|
105
101
|
console.error(e);
|
|
106
|
-
|
|
107
|
-
setError(e);
|
|
108
|
-
}
|
|
102
|
+
setError(e);
|
|
109
103
|
}
|
|
110
104
|
})();
|
|
111
105
|
return () => {
|
|
112
106
|
controller.abort();
|
|
113
|
-
active = false;
|
|
114
107
|
};
|
|
115
|
-
}, [model,
|
|
108
|
+
}, [model, leftOffset, rightOffset]);
|
|
116
109
|
const sequence = sequenceChunks
|
|
117
|
-
? (0, formatFastaStrings_1.formatSeqFasta)(sequenceChunks
|
|
118
|
-
.filter(f => !!f)
|
|
119
|
-
.map(chunk => {
|
|
110
|
+
? (0, formatFastaStrings_1.formatSeqFasta)(sequenceChunks.map(chunk => {
|
|
120
111
|
let chunkSeq = chunk.get('seq');
|
|
121
112
|
const chunkRefName = chunk.get('refName');
|
|
122
113
|
const chunkStart = chunk.get('start') + 1;
|
|
@@ -155,14 +146,20 @@ const GetSequenceDialog = (0, mobx_react_1.observer)(function ({ model, handleCl
|
|
|
155
146
|
},
|
|
156
147
|
} }),
|
|
157
148
|
react_1.default.createElement(material_1.FormGroup, null,
|
|
158
|
-
react_1.default.createElement(material_1.FormControlLabel, { control: react_1.default.createElement(material_1.Checkbox, { value: rev, onChange: event =>
|
|
159
|
-
|
|
149
|
+
react_1.default.createElement(material_1.FormControlLabel, { control: react_1.default.createElement(material_1.Checkbox, { value: rev, onChange: event => {
|
|
150
|
+
setReverse(event.target.checked);
|
|
151
|
+
} }), label: "Reverse sequence" }),
|
|
152
|
+
react_1.default.createElement(material_1.FormControlLabel, { control: react_1.default.createElement(material_1.Checkbox, { value: comp, onChange: event => {
|
|
153
|
+
setComplement(event.target.checked);
|
|
154
|
+
} }), label: "Complement sequence" })),
|
|
160
155
|
react_1.default.createElement(material_1.Typography, { style: { margin: 10 } }, "Note: Check both boxes for the \"reverse complement\"")),
|
|
161
156
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
162
157
|
react_1.default.createElement(material_1.Button, { onClick: () => {
|
|
163
158
|
(0, copy_to_clipboard_1.default)(sequence);
|
|
164
159
|
setCopied(true);
|
|
165
|
-
setTimeout(() =>
|
|
160
|
+
setTimeout(() => {
|
|
161
|
+
setCopied(false);
|
|
162
|
+
}, 500);
|
|
166
163
|
}, disabled: loading || !!error || sequenceTooLarge, color: "primary", startIcon: react_1.default.createElement(Icons_1.ContentCopy, null) }, copied ? 'Copied' : 'Copy to clipboard'),
|
|
167
164
|
react_1.default.createElement(material_1.Button, { onClick: () => {
|
|
168
165
|
(0, file_saver_1.saveAs)(new Blob([sequence || ''], {
|
|
@@ -55,9 +55,13 @@ const HeaderButtons = (0, mobx_react_1.observer)(({ model }) => {
|
|
|
55
55
|
function PanControls({ model }) {
|
|
56
56
|
const { classes } = useStyles();
|
|
57
57
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
58
|
-
react_1.default.createElement(material_1.Button, { variant: "outlined", className: classes.panButton, onClick: () =>
|
|
58
|
+
react_1.default.createElement(material_1.Button, { variant: "outlined", className: classes.panButton, onClick: () => {
|
|
59
|
+
model.slide(-0.9);
|
|
60
|
+
} },
|
|
59
61
|
react_1.default.createElement(ArrowBack_1.default, null)),
|
|
60
|
-
react_1.default.createElement(material_1.Button, { variant: "outlined", className: classes.panButton, onClick: () =>
|
|
62
|
+
react_1.default.createElement(material_1.Button, { variant: "outlined", className: classes.panButton, onClick: () => {
|
|
63
|
+
model.slide(0.9);
|
|
64
|
+
} },
|
|
61
65
|
react_1.default.createElement(ArrowForward_1.default, null))));
|
|
62
66
|
}
|
|
63
67
|
const RegionWidth = (0, mobx_react_1.observer)(({ model }) => {
|
|
@@ -37,25 +37,22 @@ const material_1 = require("@mui/material");
|
|
|
37
37
|
const Link_1 = __importDefault(require("@mui/icons-material/Link"));
|
|
38
38
|
const Close_1 = __importDefault(require("@mui/icons-material/Close"));
|
|
39
39
|
const Bookmark_1 = __importDefault(require("@mui/icons-material/Bookmark"));
|
|
40
|
-
const useStyles = (0, mui_1.makeStyles)()(theme => {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
});
|
|
52
|
-
});
|
|
40
|
+
const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
41
|
+
highlight: {
|
|
42
|
+
height: '100%',
|
|
43
|
+
position: 'absolute',
|
|
44
|
+
overflow: 'hidden',
|
|
45
|
+
background: (0, colord_1.colord)(theme.palette.highlight.main).alpha(0.35).toRgbString(),
|
|
46
|
+
},
|
|
47
|
+
linkIcon: {
|
|
48
|
+
color: (0, colord_1.colord)(theme.palette.highlight.main).darken(0.2).toRgbString(),
|
|
49
|
+
},
|
|
50
|
+
}));
|
|
53
51
|
const Highlight = (0, mobx_react_1.observer)(function Highlight({ model, highlight, }) {
|
|
54
|
-
var _a
|
|
52
|
+
var _a;
|
|
55
53
|
const { classes } = useStyles();
|
|
56
54
|
const [open, setOpen] = (0, react_1.useState)(false);
|
|
57
55
|
const anchorEl = (0, react_1.useRef)(null);
|
|
58
|
-
const color = (_b = (_a = (0, material_1.useTheme)().palette.highlight) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod';
|
|
59
56
|
const session = (0, util_1.getSession)(model);
|
|
60
57
|
const { assemblyManager } = session;
|
|
61
58
|
const dismissHighlight = () => {
|
|
@@ -81,20 +78,20 @@ const Highlight = (0, mobx_react_1.observer)(function Highlight({ model, highlig
|
|
|
81
78
|
}
|
|
82
79
|
: undefined;
|
|
83
80
|
};
|
|
84
|
-
const asm = assemblyManager.get(highlight
|
|
81
|
+
const asm = assemblyManager.get(highlight.assemblyName);
|
|
85
82
|
const h = mapCoords({
|
|
86
83
|
...highlight,
|
|
87
|
-
refName: (
|
|
84
|
+
refName: (_a = asm === null || asm === void 0 ? void 0 : asm.getCanonicalRefName(highlight.refName)) !== null && _a !== void 0 ? _a : highlight.refName,
|
|
88
85
|
});
|
|
89
86
|
return h ? (react_1.default.createElement("div", { className: classes.highlight, style: {
|
|
90
87
|
left: h.left,
|
|
91
88
|
width: h.width,
|
|
92
89
|
} },
|
|
93
|
-
react_1.default.createElement(material_1.Tooltip, { title:
|
|
94
|
-
react_1.default.createElement(material_1.IconButton, { ref: anchorEl, onClick: () =>
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
90
|
+
react_1.default.createElement(material_1.Tooltip, { title: "Highlighted from URL parameter", arrow: true },
|
|
91
|
+
react_1.default.createElement(material_1.IconButton, { ref: anchorEl, onClick: () => {
|
|
92
|
+
setOpen(true);
|
|
93
|
+
}, style: { zIndex: 3 } },
|
|
94
|
+
react_1.default.createElement(Link_1.default, { fontSize: "small", className: classes.linkIcon }))),
|
|
98
95
|
react_1.default.createElement(ui_1.Menu, { anchorEl: anchorEl.current, onMenuItemClick: (_event, callback) => {
|
|
99
96
|
callback(session);
|
|
100
97
|
handleClose();
|
|
@@ -102,7 +99,9 @@ const Highlight = (0, mobx_react_1.observer)(function Highlight({ model, highlig
|
|
|
102
99
|
{
|
|
103
100
|
label: 'Dismiss highlight',
|
|
104
101
|
icon: Close_1.default,
|
|
105
|
-
onClick: () =>
|
|
102
|
+
onClick: () => {
|
|
103
|
+
dismissHighlight();
|
|
104
|
+
},
|
|
106
105
|
},
|
|
107
106
|
{
|
|
108
107
|
label: 'Bookmark highlighted region',
|
|
@@ -112,7 +111,7 @@ const Highlight = (0, mobx_react_1.observer)(function Highlight({ model, highlig
|
|
|
112
111
|
if (!bookmarkWidget) {
|
|
113
112
|
bookmarkWidget = session.addWidget('GridBookmarkWidget', 'GridBookmark');
|
|
114
113
|
}
|
|
115
|
-
// @ts-
|
|
114
|
+
// @ts-expect-error
|
|
116
115
|
bookmarkWidget.addBookmark(highlight);
|
|
117
116
|
dismissHighlight();
|
|
118
117
|
},
|
|
@@ -120,6 +119,6 @@ const Highlight = (0, mobx_react_1.observer)(function Highlight({ model, highlig
|
|
|
120
119
|
] }))) : null;
|
|
121
120
|
});
|
|
122
121
|
const HighlightGroup = (0, mobx_react_1.observer)(function HighlightGroup({ model, }) {
|
|
123
|
-
return model.highlight.map((highlight, idx) => (react_1.default.createElement(Highlight, { key: JSON.stringify(highlight)
|
|
122
|
+
return model.highlight.map((highlight, idx) => (react_1.default.createElement(Highlight, { key: `${JSON.stringify(highlight)}-${idx}`, model: model, highlight: highlight })));
|
|
124
123
|
});
|
|
125
124
|
exports.default = HighlightGroup;
|