@jbrowse/plugin-linear-genome-view 2.8.0 → 2.10.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/Tooltip.js +18 -50
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +4 -16
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +8 -1
- package/dist/BasicTrack/configSchema.d.ts +5 -0
- package/dist/FeatureTrack/configSchema.d.ts +5 -0
- package/dist/LaunchLinearGenomeView/index.js +16 -14
- package/dist/LinearBareDisplay/model.d.ts +8 -11
- package/dist/LinearBareDisplay/model.js +2 -1
- package/dist/LinearBasicDisplay/model.d.ts +30 -33
- package/dist/LinearBasicDisplay/model.js +3 -0
- package/dist/LinearGenomeView/components/CenterLine.js +1 -1
- package/dist/LinearGenomeView/components/Cytobands.d.ts +18 -6
- package/dist/LinearGenomeView/components/Cytobands.js +8 -2
- package/dist/LinearGenomeView/components/ImportForm.js +26 -74
- package/dist/LinearGenomeView/components/ImportFormRefNameAutocomplete.d.ts +12 -0
- package/dist/LinearGenomeView/components/ImportFormRefNameAutocomplete.js +29 -0
- package/dist/LinearGenomeView/components/OverviewScalebar.js +1 -1
- package/dist/LinearGenomeView/components/SearchBox.js +19 -56
- package/dist/LinearGenomeView/components/TracksContainer.js +1 -1
- package/dist/LinearGenomeView/model.d.ts +18 -2
- package/dist/LinearGenomeView/model.js +19 -0
- package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.d.ts +0 -7
- package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +11 -13
- package/dist/LinearGenomeView/svgcomponents/util.d.ts +8 -0
- package/dist/LinearGenomeView/svgcomponents/util.js +9 -0
- package/dist/index.d.ts +776 -7
- package/dist/index.js +5 -4
- package/dist/searchUtils.d.ts +26 -0
- package/dist/searchUtils.js +90 -0
- package/esm/BaseLinearDisplay/components/Tooltip.js +16 -28
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +4 -16
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +8 -1
- package/esm/BasicTrack/configSchema.d.ts +5 -0
- package/esm/FeatureTrack/configSchema.d.ts +5 -0
- package/esm/LaunchLinearGenomeView/index.js +16 -14
- package/esm/LinearBareDisplay/model.d.ts +8 -11
- package/esm/LinearBareDisplay/model.js +2 -1
- package/esm/LinearBasicDisplay/model.d.ts +30 -33
- package/esm/LinearBasicDisplay/model.js +3 -0
- package/esm/LinearGenomeView/components/CenterLine.js +1 -1
- package/esm/LinearGenomeView/components/Cytobands.d.ts +18 -6
- package/esm/LinearGenomeView/components/Cytobands.js +8 -2
- package/esm/LinearGenomeView/components/ImportForm.js +26 -74
- package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.d.ts +12 -0
- package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.js +24 -0
- package/esm/LinearGenomeView/components/OverviewScalebar.js +1 -1
- package/esm/LinearGenomeView/components/SearchBox.js +20 -57
- package/esm/LinearGenomeView/components/TracksContainer.js +1 -1
- package/esm/LinearGenomeView/model.d.ts +18 -2
- package/esm/LinearGenomeView/model.js +19 -0
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.d.ts +0 -7
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +9 -10
- package/esm/LinearGenomeView/svgcomponents/util.d.ts +8 -0
- package/esm/LinearGenomeView/svgcomponents/util.js +5 -0
- package/esm/index.d.ts +776 -7
- package/esm/index.js +4 -3
- package/esm/searchUtils.d.ts +26 -0
- package/esm/searchUtils.js +79 -0
- package/package.json +4 -6
|
@@ -66,10 +66,16 @@ const Cytobands = observer(function ({ overview, block, assembly, }) {
|
|
|
66
66
|
const c = colorMap[type];
|
|
67
67
|
if (type === 'acen' && !centromereSeen) {
|
|
68
68
|
centromereSeen = true; // the next acen entry is drawn with different right triangle
|
|
69
|
-
|
|
69
|
+
const tri = reversed
|
|
70
|
+
? rightTriangle(s - w, 0, w, h)
|
|
71
|
+
: leftTriangle(s, 0, w, h);
|
|
72
|
+
return React.createElement("polygon", { key: k, points: tri, fill: c });
|
|
70
73
|
}
|
|
71
74
|
else if (type === 'acen' && centromereSeen) {
|
|
72
|
-
|
|
75
|
+
const tri = reversed
|
|
76
|
+
? leftTriangle(s - w, 0, w, h)
|
|
77
|
+
: rightTriangle(s, 0, w, h);
|
|
78
|
+
return React.createElement("polygon", { key: k, points: tri, fill: c });
|
|
73
79
|
}
|
|
74
80
|
else if (lcap === index) {
|
|
75
81
|
return React.createElement("path", { key: k, d: leftRoundedRect(l, 0, w, h, 8), fill: c });
|
|
@@ -6,9 +6,8 @@ import { Button, FormControl, Container, Grid, CircularProgress, } from '@mui/ma
|
|
|
6
6
|
import { ErrorMessage, AssemblySelector } from '@jbrowse/core/ui';
|
|
7
7
|
// icons
|
|
8
8
|
import CloseIcon from '@mui/icons-material/Close';
|
|
9
|
-
|
|
10
|
-
import
|
|
11
|
-
import { fetchResults, splitLast } from './util';
|
|
9
|
+
import { handleSelectedRegion, navToOption } from '../../searchUtils';
|
|
10
|
+
import ImportFormRefNameAutocomplete from './ImportFormRefNameAutocomplete';
|
|
12
11
|
const useStyles = makeStyles()(theme => ({
|
|
13
12
|
importFormContainer: {
|
|
14
13
|
padding: theme.spacing(2),
|
|
@@ -24,11 +23,10 @@ const LinearGenomeViewImportForm = observer(function ({ model, }) {
|
|
|
24
23
|
var _a;
|
|
25
24
|
const { classes } = useStyles();
|
|
26
25
|
const session = getSession(model);
|
|
27
|
-
const { assemblyNames, assemblyManager
|
|
28
|
-
const {
|
|
26
|
+
const { assemblyNames, assemblyManager } = session;
|
|
27
|
+
const { error } = model;
|
|
29
28
|
const [selectedAsm, setSelectedAsm] = useState(assemblyNames[0]);
|
|
30
29
|
const [option, setOption] = useState();
|
|
31
|
-
const searchScope = model.searchScope(selectedAsm);
|
|
32
30
|
const assembly = assemblyManager.get(selectedAsm);
|
|
33
31
|
const assemblyError = assemblyNames.length
|
|
34
32
|
? assembly === null || assembly === void 0 ? void 0 : assembly.error
|
|
@@ -46,74 +44,37 @@ const LinearGenomeViewImportForm = observer(function ({ model, }) {
|
|
|
46
44
|
useEffect(() => {
|
|
47
45
|
setValue(r0);
|
|
48
46
|
}, [r0, selectedAsm]);
|
|
49
|
-
async function navToOption(option) {
|
|
50
|
-
const location = option.getLocation();
|
|
51
|
-
const trackId = option.getTrackId();
|
|
52
|
-
if (location) {
|
|
53
|
-
await model.navToLocString(location, selectedAsm);
|
|
54
|
-
if (trackId) {
|
|
55
|
-
model.showTrack(trackId);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
// gets a string as input, or use stored option results from previous query,
|
|
60
|
-
// then re-query and
|
|
61
|
-
// 1) if it has multiple results: pop a dialog
|
|
62
|
-
// 2) if it's a single result navigate to it
|
|
63
|
-
// 3) else assume it's a locstring and navigate to it
|
|
64
|
-
async function handleSelectedRegion(input) {
|
|
65
|
-
var _a;
|
|
66
|
-
try {
|
|
67
|
-
if ((option === null || option === void 0 ? void 0 : option.getDisplayString()) === input && option.hasLocation()) {
|
|
68
|
-
await navToOption(option);
|
|
69
|
-
}
|
|
70
|
-
else if ((_a = option === null || option === void 0 ? void 0 : option.results) === null || _a === void 0 ? void 0 : _a.length) {
|
|
71
|
-
model.setSearchResults(option.results, option.getLabel(), selectedAsm);
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
const [ref, rest] = splitLast(input, ':');
|
|
75
|
-
const allRefs = (assembly === null || assembly === void 0 ? void 0 : assembly.allRefNamesWithLowerCase) || [];
|
|
76
|
-
if (allRefs.includes(input) ||
|
|
77
|
-
(allRefs.includes(ref) && !Number.isNaN(Number.parseInt(rest, 10)))) {
|
|
78
|
-
await model.navToLocString(input, selectedAsm);
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
const results = await fetchResults({
|
|
82
|
-
queryString: input,
|
|
83
|
-
searchType: 'exact',
|
|
84
|
-
searchScope,
|
|
85
|
-
rankSearchResults,
|
|
86
|
-
textSearchManager,
|
|
87
|
-
assembly,
|
|
88
|
-
});
|
|
89
|
-
if (results.length > 1) {
|
|
90
|
-
model.setSearchResults(results, input.toLowerCase(), selectedAsm);
|
|
91
|
-
}
|
|
92
|
-
else if (results.length === 1) {
|
|
93
|
-
await navToOption(results[0]);
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
await model.navToLocString(input, selectedAsm);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
catch (e) {
|
|
102
|
-
console.error(e);
|
|
103
|
-
session.notify(`${e}`, 'warning');
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
47
|
// implementation notes:
|
|
107
48
|
// having this wrapped in a form allows intuitive use of enter key to submit
|
|
108
49
|
return (React.createElement("div", { className: classes.container },
|
|
109
50
|
displayError ? React.createElement(ErrorMessage, { error: displayError }) : null,
|
|
110
51
|
React.createElement(Container, { className: classes.importFormContainer },
|
|
111
52
|
React.createElement("form", { onSubmit: async (event) => {
|
|
53
|
+
var _a;
|
|
112
54
|
event.preventDefault();
|
|
113
55
|
model.setError(undefined);
|
|
114
56
|
if (value) {
|
|
115
57
|
// has it's own error handling
|
|
116
|
-
|
|
58
|
+
try {
|
|
59
|
+
if ((option === null || option === void 0 ? void 0 : option.getDisplayString()) === value &&
|
|
60
|
+
option.hasLocation()) {
|
|
61
|
+
await navToOption({
|
|
62
|
+
option,
|
|
63
|
+
model,
|
|
64
|
+
assemblyName: selectedAsm,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
else if ((_a = option === null || option === void 0 ? void 0 : option.results) === null || _a === void 0 ? void 0 : _a.length) {
|
|
68
|
+
model.setSearchResults(option.results, option.getLabel(), selectedAsm);
|
|
69
|
+
}
|
|
70
|
+
else if (assembly) {
|
|
71
|
+
await handleSelectedRegion({ input: value, assembly, model });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
console.error(e);
|
|
76
|
+
session.notify(`${e}`, 'warning');
|
|
77
|
+
}
|
|
117
78
|
}
|
|
118
79
|
} },
|
|
119
80
|
React.createElement(Grid, { container: true, spacing: 1, justifyContent: "center", alignItems: "center" },
|
|
@@ -121,16 +82,7 @@ const LinearGenomeViewImportForm = observer(function ({ model, }) {
|
|
|
121
82
|
React.createElement(FormControl, null,
|
|
122
83
|
React.createElement(AssemblySelector, { onChange: val => setSelectedAsm(val), localStorageKey: "lgv", session: session, selected: selectedAsm }))),
|
|
123
84
|
React.createElement(Grid, { item: true }, selectedAsm ? (assemblyError ? (React.createElement(CloseIcon, { style: { color: 'red' } })) : assemblyLoaded ? (React.createElement(FormControl, null,
|
|
124
|
-
React.createElement(
|
|
125
|
-
queryString,
|
|
126
|
-
assembly,
|
|
127
|
-
textSearchManager,
|
|
128
|
-
rankSearchResults,
|
|
129
|
-
searchScope,
|
|
130
|
-
}), model: model, assemblyName: selectedAsm, value: value, minWidth: 270, onChange: str => setValue(str), onSelect: val => setOption(val), TextFieldProps: {
|
|
131
|
-
variant: 'outlined',
|
|
132
|
-
helperText: 'Enter sequence name, feature name, or location',
|
|
133
|
-
} }))) : (React.createElement(CircularProgress, { size: 20, disableShrink: true }))) : null),
|
|
85
|
+
React.createElement(ImportFormRefNameAutocomplete, { value: value, setValue: setValue, selectedAsm: selectedAsm, setOption: setOption, model: model }))) : (React.createElement(CircularProgress, { size: 20, disableShrink: true }))) : null),
|
|
134
86
|
React.createElement(Grid, { item: true },
|
|
135
87
|
React.createElement(FormControl, null,
|
|
136
88
|
React.createElement(Button, { type: "submit", disabled: !value, className: classes.button, variant: "contained", color: "primary" }, "Open")),
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import BaseResult from '@jbrowse/core/TextSearch/BaseResults';
|
|
3
|
+
import { LinearGenomeViewModel } from '..';
|
|
4
|
+
type LGV = LinearGenomeViewModel;
|
|
5
|
+
declare const ImportFormRefNameAutocomplete: ({ model, selectedAsm, value, setValue, setOption, }: {
|
|
6
|
+
value: string;
|
|
7
|
+
setValue: (arg: string) => void;
|
|
8
|
+
model: LGV;
|
|
9
|
+
selectedAsm: string;
|
|
10
|
+
setOption: (arg: BaseResult) => void;
|
|
11
|
+
}) => React.JSX.Element;
|
|
12
|
+
export default ImportFormRefNameAutocomplete;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { observer } from 'mobx-react';
|
|
3
|
+
import { getSession } from '@jbrowse/core/util';
|
|
4
|
+
// locals
|
|
5
|
+
import RefNameAutocomplete from './RefNameAutocomplete';
|
|
6
|
+
import { fetchResults } from './util';
|
|
7
|
+
const ImportFormRefNameAutocomplete = observer(function ({ model, selectedAsm, value, setValue, setOption, }) {
|
|
8
|
+
const session = getSession(model);
|
|
9
|
+
const { assemblyManager, textSearchManager } = session;
|
|
10
|
+
const { rankSearchResults } = model;
|
|
11
|
+
const searchScope = model.searchScope(selectedAsm);
|
|
12
|
+
const assembly = assemblyManager.get(selectedAsm);
|
|
13
|
+
return (React.createElement(RefNameAutocomplete, { fetchResults: queryString => fetchResults({
|
|
14
|
+
queryString,
|
|
15
|
+
assembly,
|
|
16
|
+
textSearchManager,
|
|
17
|
+
rankSearchResults,
|
|
18
|
+
searchScope,
|
|
19
|
+
}), model: model, assemblyName: selectedAsm, value: value, minWidth: 270, onChange: str => setValue(str), onSelect: val => setOption(val), TextFieldProps: {
|
|
20
|
+
variant: 'outlined',
|
|
21
|
+
helperText: 'Enter sequence name, feature name, or location',
|
|
22
|
+
} }));
|
|
23
|
+
});
|
|
24
|
+
export default ImportFormRefNameAutocomplete;
|
|
@@ -195,7 +195,7 @@ const OverviewScalebar = observer(function ({ model, children, }) {
|
|
|
195
195
|
overview.showAllRegions();
|
|
196
196
|
return overview;
|
|
197
197
|
}, [
|
|
198
|
-
JSON.stringify(displayedRegions),
|
|
198
|
+
JSON.stringify(displayedRegions), // eslint-disable-line react-hooks/exhaustive-deps
|
|
199
199
|
model.minimumBlockWidth,
|
|
200
200
|
modWidth,
|
|
201
201
|
displayedRegions,
|
|
@@ -5,18 +5,14 @@ import { makeStyles } from 'tss-react/mui';
|
|
|
5
5
|
import { getSession } from '@jbrowse/core/util';
|
|
6
6
|
// locals
|
|
7
7
|
import RefNameAutocomplete from './RefNameAutocomplete';
|
|
8
|
-
import { fetchResults
|
|
8
|
+
import { fetchResults } from './util';
|
|
9
9
|
import { SPACING, WIDGET_HEIGHT } from '..';
|
|
10
|
+
import { handleSelectedRegion, navToOption } from '../../searchUtils';
|
|
10
11
|
const useStyles = makeStyles()(() => ({
|
|
11
12
|
headerRefName: {
|
|
12
13
|
minWidth: 100,
|
|
13
14
|
},
|
|
14
15
|
}));
|
|
15
|
-
function checkRef(str, allRefs) {
|
|
16
|
-
const [ref, rest] = splitLast(str, ':');
|
|
17
|
-
return (allRefs.includes(str) ||
|
|
18
|
-
(allRefs.includes(ref) && !Number.isNaN(Number.parseInt(rest, 10))));
|
|
19
|
-
}
|
|
20
16
|
const SearchBox = observer(function ({ model, showHelp, }) {
|
|
21
17
|
const { classes } = useStyles();
|
|
22
18
|
const theme = useTheme();
|
|
@@ -26,61 +22,28 @@ const SearchBox = observer(function ({ model, showHelp, }) {
|
|
|
26
22
|
const assemblyName = assemblyNames[0];
|
|
27
23
|
const assembly = assemblyManager.get(assemblyName);
|
|
28
24
|
const searchScope = model.searchScope(assemblyName);
|
|
29
|
-
async
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (trackId) {
|
|
35
|
-
model.showTrack(trackId);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
// gets a string as input, or use stored option results from previous query,
|
|
40
|
-
// then re-query and
|
|
41
|
-
// 1) if it has multiple results: pop a dialog
|
|
42
|
-
// 2) if it's a single result navigate to it
|
|
43
|
-
// 3) else assume it's a locstring and navigate to it
|
|
44
|
-
async function handleSelectedRegion(option) {
|
|
45
|
-
var _a;
|
|
46
|
-
try {
|
|
47
|
-
const input = option.getLabel();
|
|
48
|
-
const allRefs = (assembly === null || assembly === void 0 ? void 0 : assembly.allRefNamesWithLowerCase) || [];
|
|
49
|
-
if (option.hasLocation()) {
|
|
50
|
-
await navToOption(option);
|
|
51
|
-
}
|
|
52
|
-
else if ((_a = option.results) === null || _a === void 0 ? void 0 : _a.length) {
|
|
53
|
-
model.setSearchResults(option.results, option.getLabel());
|
|
54
|
-
}
|
|
55
|
-
else if (input.split(' ').every(entry => checkRef(entry, allRefs))) {
|
|
56
|
-
await model.navToLocString(input, assemblyName);
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
const results = await fetchResults({
|
|
60
|
-
queryString: input,
|
|
61
|
-
searchType: 'exact',
|
|
62
|
-
searchScope,
|
|
63
|
-
rankSearchResults,
|
|
64
|
-
textSearchManager,
|
|
65
|
-
assembly,
|
|
66
|
-
});
|
|
67
|
-
if (results.length > 1) {
|
|
68
|
-
model.setSearchResults(results, input.toLowerCase());
|
|
25
|
+
return (React.createElement(RefNameAutocomplete, { showHelp: showHelp, onSelect: async (option) => {
|
|
26
|
+
var _a;
|
|
27
|
+
try {
|
|
28
|
+
if (option.hasLocation()) {
|
|
29
|
+
await navToOption({ option, model, assemblyName });
|
|
69
30
|
}
|
|
70
|
-
else if (results
|
|
71
|
-
|
|
31
|
+
else if ((_a = option.results) === null || _a === void 0 ? void 0 : _a.length) {
|
|
32
|
+
model.setSearchResults(option.results, option.getLabel());
|
|
72
33
|
}
|
|
73
|
-
else {
|
|
74
|
-
await
|
|
34
|
+
else if (assembly) {
|
|
35
|
+
await handleSelectedRegion({
|
|
36
|
+
input: option.getLabel(),
|
|
37
|
+
assembly,
|
|
38
|
+
model,
|
|
39
|
+
});
|
|
75
40
|
}
|
|
76
41
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return (React.createElement(RefNameAutocomplete, { showHelp: showHelp, onSelect: handleSelectedRegion, assemblyName: assemblyName, fetchResults: queryString => fetchResults({
|
|
42
|
+
catch (e) {
|
|
43
|
+
console.error(e);
|
|
44
|
+
getSession(model).notify(`${e}`, 'warning');
|
|
45
|
+
}
|
|
46
|
+
}, assemblyName: assemblyName, fetchResults: queryString => fetchResults({
|
|
84
47
|
queryString,
|
|
85
48
|
searchScope,
|
|
86
49
|
rankSearchResults,
|
|
@@ -2,6 +2,7 @@ import React, { useRef } from 'react';
|
|
|
2
2
|
import { makeStyles } from 'tss-react/mui';
|
|
3
3
|
import { observer } from 'mobx-react';
|
|
4
4
|
import { Menu } from '@jbrowse/core/ui';
|
|
5
|
+
import { getEnv } from '@jbrowse/core/util';
|
|
5
6
|
// local utils
|
|
6
7
|
import { SCALE_BAR_HEIGHT } from '..';
|
|
7
8
|
import { useSideScroll, useRangeSelect, useWheelScroll } from './hooks';
|
|
@@ -12,7 +13,6 @@ import Gridlines from './Gridlines';
|
|
|
12
13
|
import CenterLine from './CenterLine';
|
|
13
14
|
import VerticalGuide from './VerticalGuide';
|
|
14
15
|
import RubberbandSpan from './RubberbandSpan';
|
|
15
|
-
import { getEnv } from '@jbrowse/core/util';
|
|
16
16
|
const useStyles = makeStyles()({
|
|
17
17
|
tracksContainer: {
|
|
18
18
|
position: 'relative',
|
|
@@ -6,6 +6,7 @@ import BaseResult from '@jbrowse/core/TextSearch/BaseResults';
|
|
|
6
6
|
import { BlockSet, BaseBlock } from '@jbrowse/core/util/blockTypes';
|
|
7
7
|
import { Instance } from 'mobx-state-tree';
|
|
8
8
|
import PluginManager from '@jbrowse/core/PluginManager';
|
|
9
|
+
import { Assembly } from '@jbrowse/core/assemblyManager/assembly';
|
|
9
10
|
export interface BpOffset {
|
|
10
11
|
refName?: string;
|
|
11
12
|
index: number;
|
|
@@ -20,7 +21,9 @@ export interface BpOffset {
|
|
|
20
21
|
export interface ExportSvgOptions {
|
|
21
22
|
rasterizeLayers?: boolean;
|
|
22
23
|
filename?: string;
|
|
23
|
-
Wrapper?: React.FC<
|
|
24
|
+
Wrapper?: React.FC<{
|
|
25
|
+
children: React.ReactNode;
|
|
26
|
+
}>;
|
|
24
27
|
fontSize?: number;
|
|
25
28
|
rulerHeight?: number;
|
|
26
29
|
textHeight?: number;
|
|
@@ -46,6 +49,9 @@ export declare const WIDGET_HEIGHT = 32;
|
|
|
46
49
|
/**
|
|
47
50
|
* #stateModel LinearGenomeView
|
|
48
51
|
* #category view
|
|
52
|
+
*
|
|
53
|
+
* extends
|
|
54
|
+
* - [BaseViewModel](../baseviewmodel)
|
|
49
55
|
*/
|
|
50
56
|
export declare function stateModelFactory(pluginManager: PluginManager): import("mobx-state-tree").IModelType<{
|
|
51
57
|
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
@@ -292,7 +298,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
292
298
|
/**
|
|
293
299
|
* #action
|
|
294
300
|
*/
|
|
295
|
-
toggleTrack(trackId: string):
|
|
301
|
+
toggleTrack(trackId: string): boolean;
|
|
296
302
|
/**
|
|
297
303
|
* #action
|
|
298
304
|
*/
|
|
@@ -463,6 +469,16 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
463
469
|
* navigating to the locstring
|
|
464
470
|
*/
|
|
465
471
|
navToLocString(input: string, optAssemblyName?: string): Promise<void>;
|
|
472
|
+
/**
|
|
473
|
+
* #action
|
|
474
|
+
* Performs a text index search, and navigates to it immediately if a
|
|
475
|
+
* single result is returned. Will pop up a search dialog if multiple
|
|
476
|
+
* results are returned
|
|
477
|
+
*/
|
|
478
|
+
navToSearchString({ input, assembly, }: {
|
|
479
|
+
input: string;
|
|
480
|
+
assembly: Assembly;
|
|
481
|
+
}): Promise<void>;
|
|
466
482
|
/**
|
|
467
483
|
* #action
|
|
468
484
|
* Similar to `navToLocString`, but accepts parsed location objects
|
|
@@ -24,6 +24,7 @@ import MenuOpenIcon from '@mui/icons-material/MenuOpen';
|
|
|
24
24
|
import MiniControls from './components/MiniControls';
|
|
25
25
|
import Header from './components/Header';
|
|
26
26
|
import { generateLocations, parseLocStrings } from './util';
|
|
27
|
+
import { handleSelectedRegion } from '../searchUtils';
|
|
27
28
|
// lazies
|
|
28
29
|
const ReturnToImportFormDialog = lazy(() => import('@jbrowse/core/ui/ReturnToImportFormDialog'));
|
|
29
30
|
const SequenceSearchDialog = lazy(() => import('./components/SequenceSearchDialog'));
|
|
@@ -53,6 +54,9 @@ export const WIDGET_HEIGHT = 32;
|
|
|
53
54
|
/**
|
|
54
55
|
* #stateModel LinearGenomeView
|
|
55
56
|
* #category view
|
|
57
|
+
*
|
|
58
|
+
* extends
|
|
59
|
+
* - [BaseViewModel](../baseviewmodel)
|
|
56
60
|
*/
|
|
57
61
|
export function stateModelFactory(pluginManager) {
|
|
58
62
|
return types
|
|
@@ -595,7 +599,9 @@ export function stateModelFactory(pluginManager) {
|
|
|
595
599
|
// if none had that configuration, turn one on
|
|
596
600
|
if (!hiddenCount) {
|
|
597
601
|
self.showTrack(trackId);
|
|
602
|
+
return true;
|
|
598
603
|
}
|
|
604
|
+
return false;
|
|
599
605
|
},
|
|
600
606
|
/**
|
|
601
607
|
* #action
|
|
@@ -1077,6 +1083,19 @@ export function stateModelFactory(pluginManager) {
|
|
|
1077
1083
|
}
|
|
1078
1084
|
return this.navToLocations(parseLocStrings(input, assemblyName, isValidRefName), assemblyName);
|
|
1079
1085
|
},
|
|
1086
|
+
/**
|
|
1087
|
+
* #action
|
|
1088
|
+
* Performs a text index search, and navigates to it immediately if a
|
|
1089
|
+
* single result is returned. Will pop up a search dialog if multiple
|
|
1090
|
+
* results are returned
|
|
1091
|
+
*/
|
|
1092
|
+
async navToSearchString({ input, assembly, }) {
|
|
1093
|
+
await handleSelectedRegion({
|
|
1094
|
+
input,
|
|
1095
|
+
assembly,
|
|
1096
|
+
model: self,
|
|
1097
|
+
});
|
|
1098
|
+
},
|
|
1080
1099
|
/**
|
|
1081
1100
|
* #action
|
|
1082
1101
|
* Similar to `navToLocString`, but accepts parsed location objects
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
import { LinearGenomeViewModel, ExportSvgOptions } from '..';
|
|
2
2
|
type LGV = LinearGenomeViewModel;
|
|
3
|
-
interface Display {
|
|
4
|
-
height: number;
|
|
5
|
-
}
|
|
6
|
-
interface Track {
|
|
7
|
-
displays: Display[];
|
|
8
|
-
}
|
|
9
|
-
export declare function totalHeight(tracks: Track[], textHeight: number, trackLabels: string): number;
|
|
10
3
|
export declare function renderToSvg(model: LGV, opts: ExportSvgOptions): Promise<string>;
|
|
11
4
|
export { default as SVGRuler } from './SVGRuler';
|
|
12
5
|
export { default as SVGTracks } from './SVGTracks';
|
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
/* eslint-disable react-refresh/only-export-components */
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { renderToStaticMarkup } from 'react-dom/server';
|
|
4
3
|
import { when } from 'mobx';
|
|
5
|
-
import { getSession, max, measureText,
|
|
4
|
+
import { getSession, max, measureText, renderToStaticMarkup, } from '@jbrowse/core/util';
|
|
6
5
|
import { ThemeProvider } from '@mui/material';
|
|
7
6
|
import { createJBrowseTheme } from '@jbrowse/core/ui';
|
|
7
|
+
import { getTrackName } from '@jbrowse/core/util/tracks';
|
|
8
|
+
import { getRoot } from 'mobx-state-tree';
|
|
8
9
|
import SVGBackground from './SVGBackground';
|
|
9
10
|
import SVGTracks from './SVGTracks';
|
|
10
11
|
import SVGHeader from './SVGHeader';
|
|
11
|
-
import {
|
|
12
|
-
export function totalHeight(tracks, textHeight, trackLabels) {
|
|
13
|
-
return sum(tracks.map(t => t.displays[0].height +
|
|
14
|
-
(['none', 'left'].includes(trackLabels) ? 0 : textHeight)));
|
|
15
|
-
}
|
|
12
|
+
import { totalHeight } from './util';
|
|
16
13
|
// render LGV to SVG
|
|
17
14
|
export async function renderToSvg(model, opts) {
|
|
18
|
-
var _a;
|
|
19
15
|
await when(() => model.initialized);
|
|
20
16
|
const { textHeight = 18, headerHeight = 40, rulerHeight = 50, fontSize = 13, cytobandHeight = 100, trackLabels = 'offset', themeName = 'default', Wrapper = ({ children }) => React.createElement(React.Fragment, null, children), } = opts;
|
|
21
17
|
const session = getSession(model);
|
|
22
|
-
const
|
|
18
|
+
const { allThemes } = session;
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
|
+
const { createRootFn } = getRoot(model);
|
|
21
|
+
const theme = allThemes === null || allThemes === void 0 ? void 0 : allThemes()[themeName];
|
|
23
22
|
const { width, tracks, showCytobands } = model;
|
|
24
23
|
const shift = 50;
|
|
25
24
|
const c = +showCytobands * cytobandHeight;
|
|
@@ -41,7 +40,7 @@ export async function renderToSvg(model, opts) {
|
|
|
41
40
|
React.createElement("g", { transform: `translate(${shift} 0)` },
|
|
42
41
|
React.createElement("g", { transform: `translate(${trackLabelOffset})` },
|
|
43
42
|
React.createElement(SVGHeader, { model: model, fontSize: fontSize, rulerHeight: rulerHeight, cytobandHeight: cytobandHeight })),
|
|
44
|
-
React.createElement(SVGTracks, { textHeight: textHeight, fontSize: fontSize, model: model, displayResults: displayResults, offset: offset, trackLabels: trackLabels, trackLabelOffset: trackLabelOffset }))))));
|
|
43
|
+
React.createElement(SVGTracks, { textHeight: textHeight, fontSize: fontSize, model: model, displayResults: displayResults, offset: offset, trackLabels: trackLabels, trackLabelOffset: trackLabelOffset }))))), createRootFn);
|
|
45
44
|
}
|
|
46
45
|
export { default as SVGRuler } from './SVGRuler';
|
|
47
46
|
export { default as SVGTracks } from './SVGTracks';
|