@jbrowse/plugin-linear-genome-view 2.3.4 → 2.4.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/Block.js +1 -1
- package/dist/BaseLinearDisplay/components/Block.js.map +1 -1
- package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +11 -11
- package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js.map +1 -1
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +74 -4
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +41 -22
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +1 -1
- package/dist/BaseLinearDisplay/models/configSchema.js +8 -0
- package/dist/BaseLinearDisplay/models/configSchema.js.map +1 -1
- package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.d.ts +1 -1
- package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js +5 -0
- package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
- package/dist/LinearBareDisplay/model.d.ts +62 -4
- package/dist/LinearBasicDisplay/model.d.ts +72 -14
- package/dist/LinearGenomeView/components/CenterLine.js +2 -2
- package/dist/LinearGenomeView/components/CenterLine.js.map +1 -1
- package/dist/LinearGenomeView/components/Cytobands.d.ts +118 -0
- package/dist/LinearGenomeView/components/Cytobands.js +92 -0
- package/dist/LinearGenomeView/components/Cytobands.js.map +1 -0
- package/dist/LinearGenomeView/components/ExportSvgDialog.d.ts +1 -1
- package/dist/LinearGenomeView/components/ExportSvgDialog.js +24 -3
- package/dist/LinearGenomeView/components/ExportSvgDialog.js.map +1 -1
- package/dist/LinearGenomeView/components/Gridlines.js +1 -1
- package/dist/LinearGenomeView/components/Gridlines.js.map +1 -1
- package/dist/LinearGenomeView/components/Header.js +3 -4
- package/dist/LinearGenomeView/components/Header.js.map +1 -1
- package/dist/LinearGenomeView/components/LinearGenomeView.js +1 -1
- package/dist/LinearGenomeView/components/MiniControls.js +5 -4
- package/dist/LinearGenomeView/components/MiniControls.js.map +1 -1
- package/dist/LinearGenomeView/components/OverviewScalebar.d.ts +1 -115
- package/dist/LinearGenomeView/components/OverviewScalebar.js +15 -99
- package/dist/LinearGenomeView/components/OverviewScalebar.js.map +1 -1
- package/dist/LinearGenomeView/components/RubberbandSpan.js +2 -2
- package/dist/LinearGenomeView/components/RubberbandSpan.js.map +1 -1
- package/dist/LinearGenomeView/components/TrackLabel.js +4 -5
- package/dist/LinearGenomeView/components/TrackLabel.js.map +1 -1
- package/dist/LinearGenomeView/components/ZoomControls.js +5 -4
- package/dist/LinearGenomeView/components/ZoomControls.js.map +1 -1
- package/dist/LinearGenomeView/components/util.d.ts +6 -0
- package/dist/LinearGenomeView/components/util.js +11 -1
- package/dist/LinearGenomeView/components/util.js.map +1 -1
- package/dist/LinearGenomeView/model.d.ts +10 -2
- package/dist/LinearGenomeView/model.js +4 -4
- package/dist/LinearGenomeView/model.js.map +1 -1
- package/dist/LinearGenomeView/svgcomponents/SVGBackground.d.ts +6 -0
- package/dist/LinearGenomeView/svgcomponents/SVGBackground.js +13 -0
- package/dist/LinearGenomeView/svgcomponents/SVGBackground.js.map +1 -0
- package/dist/LinearGenomeView/svgcomponents/SVGHeader.d.ts +10 -0
- package/dist/LinearGenomeView/svgcomponents/SVGHeader.js +55 -0
- package/dist/LinearGenomeView/svgcomponents/SVGHeader.js.map +1 -0
- package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.d.ts +13 -0
- package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +56 -0
- package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js.map +1 -0
- package/dist/LinearGenomeView/svgcomponents/SVGRegionSeparators.d.ts +8 -0
- package/dist/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +13 -0
- package/dist/LinearGenomeView/svgcomponents/SVGRegionSeparators.js.map +1 -0
- package/dist/LinearGenomeView/svgcomponents/SVGRuler.d.ts +8 -0
- package/dist/LinearGenomeView/svgcomponents/SVGRuler.js +51 -0
- package/dist/LinearGenomeView/svgcomponents/SVGRuler.js.map +1 -0
- package/dist/LinearGenomeView/svgcomponents/SVGScalebar.d.ts +8 -0
- package/dist/LinearGenomeView/svgcomponents/SVGScalebar.js +22 -0
- package/dist/LinearGenomeView/svgcomponents/SVGScalebar.js.map +1 -0
- package/dist/LinearGenomeView/svgcomponents/SVGTrackLabel.d.ts +8 -0
- package/dist/LinearGenomeView/svgcomponents/SVGTrackLabel.js +15 -0
- package/dist/LinearGenomeView/svgcomponents/SVGTrackLabel.js.map +1 -0
- package/dist/LinearGenomeView/svgcomponents/SVGTracks.d.ts +23 -0
- package/dist/LinearGenomeView/svgcomponents/SVGTracks.js +30 -0
- package/dist/LinearGenomeView/svgcomponents/SVGTracks.js.map +1 -0
- package/dist/LinearGenomeView/util.js +1 -1
- package/dist/LinearGenomeView/util.js.map +1 -1
- package/dist/index.d.ts +133 -18
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/esm/BaseLinearDisplay/components/Block.js +1 -1
- package/esm/BaseLinearDisplay/components/Block.js.map +1 -1
- package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +11 -11
- package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js.map +1 -1
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +74 -4
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +42 -23
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +1 -1
- package/esm/BaseLinearDisplay/models/configSchema.js +8 -0
- package/esm/BaseLinearDisplay/models/configSchema.js.map +1 -1
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.d.ts +1 -1
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +5 -0
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
- package/esm/LinearBareDisplay/model.d.ts +62 -4
- package/esm/LinearBasicDisplay/model.d.ts +72 -14
- package/esm/LinearGenomeView/components/CenterLine.js +2 -2
- package/esm/LinearGenomeView/components/CenterLine.js.map +1 -1
- package/esm/LinearGenomeView/components/Cytobands.d.ts +118 -0
- package/esm/LinearGenomeView/components/Cytobands.js +87 -0
- package/esm/LinearGenomeView/components/Cytobands.js.map +1 -0
- package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +1 -1
- package/esm/LinearGenomeView/components/ExportSvgDialog.js +25 -4
- package/esm/LinearGenomeView/components/ExportSvgDialog.js.map +1 -1
- package/esm/LinearGenomeView/components/Gridlines.js +1 -1
- package/esm/LinearGenomeView/components/Gridlines.js.map +1 -1
- package/esm/LinearGenomeView/components/Header.js +5 -6
- package/esm/LinearGenomeView/components/Header.js.map +1 -1
- package/esm/LinearGenomeView/components/LinearGenomeView.js +1 -1
- package/esm/LinearGenomeView/components/MiniControls.js +5 -4
- package/esm/LinearGenomeView/components/MiniControls.js.map +1 -1
- package/esm/LinearGenomeView/components/OverviewScalebar.d.ts +1 -115
- package/esm/LinearGenomeView/components/OverviewScalebar.js +12 -96
- package/esm/LinearGenomeView/components/OverviewScalebar.js.map +1 -1
- package/esm/LinearGenomeView/components/RubberbandSpan.js +2 -2
- package/esm/LinearGenomeView/components/RubberbandSpan.js.map +1 -1
- package/esm/LinearGenomeView/components/TrackLabel.js +4 -5
- package/esm/LinearGenomeView/components/TrackLabel.js.map +1 -1
- package/esm/LinearGenomeView/components/ZoomControls.js +5 -4
- package/esm/LinearGenomeView/components/ZoomControls.js.map +1 -1
- package/esm/LinearGenomeView/components/util.d.ts +6 -0
- package/esm/LinearGenomeView/components/util.js +9 -0
- package/esm/LinearGenomeView/components/util.js.map +1 -1
- package/esm/LinearGenomeView/model.d.ts +10 -2
- package/esm/LinearGenomeView/model.js +2 -2
- package/esm/LinearGenomeView/model.js.map +1 -1
- package/esm/LinearGenomeView/svgcomponents/SVGBackground.d.ts +6 -0
- package/esm/LinearGenomeView/svgcomponents/SVGBackground.js +7 -0
- package/esm/LinearGenomeView/svgcomponents/SVGBackground.js.map +1 -0
- package/esm/LinearGenomeView/svgcomponents/SVGHeader.d.ts +10 -0
- package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +49 -0
- package/esm/LinearGenomeView/svgcomponents/SVGHeader.js.map +1 -0
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.d.ts +13 -0
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +47 -0
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js.map +1 -0
- package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.d.ts +8 -0
- package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +7 -0
- package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js.map +1 -0
- package/esm/LinearGenomeView/svgcomponents/SVGRuler.d.ts +8 -0
- package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +45 -0
- package/esm/LinearGenomeView/svgcomponents/SVGRuler.js.map +1 -0
- package/esm/LinearGenomeView/svgcomponents/SVGScalebar.d.ts +8 -0
- package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js +16 -0
- package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js.map +1 -0
- package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.d.ts +8 -0
- package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +9 -0
- package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js.map +1 -0
- package/esm/LinearGenomeView/svgcomponents/SVGTracks.d.ts +23 -0
- package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +24 -0
- package/esm/LinearGenomeView/svgcomponents/SVGTracks.js.map +1 -0
- package/esm/LinearGenomeView/util.js +1 -1
- package/esm/LinearGenomeView/util.js.map +1 -1
- package/esm/index.d.ts +133 -18
- package/esm/index.js +3 -2
- package/esm/index.js.map +1 -1
- package/package.json +3 -3
- package/src/BaseLinearDisplay/components/Block.tsx +1 -1
- package/src/BaseLinearDisplay/components/ServerSideRenderedBlockContent.tsx +11 -12
- package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +53 -35
- package/src/BaseLinearDisplay/models/configSchema.ts +8 -0
- package/src/BaseLinearDisplay/models/serverSideRenderedBlock.ts +9 -17
- package/src/LinearGenomeView/components/CenterLine.tsx +2 -2
- package/src/LinearGenomeView/components/Cytobands.tsx +154 -0
- package/src/LinearGenomeView/components/ExportSvgDialog.tsx +56 -4
- package/src/LinearGenomeView/components/Gridlines.tsx +1 -1
- package/src/LinearGenomeView/components/Header.tsx +6 -13
- package/src/LinearGenomeView/components/LinearGenomeView.test.tsx +8 -11
- package/src/LinearGenomeView/components/LinearGenomeView.tsx +1 -1
- package/src/LinearGenomeView/components/MiniControls.tsx +6 -7
- package/src/LinearGenomeView/components/OverviewScalebar.tsx +218 -381
- package/src/LinearGenomeView/components/RubberbandSpan.tsx +2 -2
- package/src/LinearGenomeView/components/TrackLabel.tsx +2 -5
- package/src/LinearGenomeView/components/ZoomControls.tsx +3 -4
- package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.tsx.snap +1234 -1200
- package/src/LinearGenomeView/components/util.ts +13 -0
- package/src/LinearGenomeView/index.test.ts +9 -5
- package/src/LinearGenomeView/model.ts +10 -3
- package/src/LinearGenomeView/svgcomponents/SVGBackground.tsx +21 -0
- package/src/LinearGenomeView/svgcomponents/SVGHeader.tsx +93 -0
- package/src/LinearGenomeView/svgcomponents/SVGLinearGenomeView.tsx +114 -0
- package/src/LinearGenomeView/svgcomponents/SVGRegionSeparators.tsx +31 -0
- package/src/LinearGenomeView/svgcomponents/SVGRuler.tsx +125 -0
- package/src/LinearGenomeView/svgcomponents/SVGScalebar.tsx +57 -0
- package/src/LinearGenomeView/svgcomponents/SVGTrackLabel.tsx +45 -0
- package/src/LinearGenomeView/svgcomponents/SVGTracks.tsx +67 -0
- package/src/LinearGenomeView/util.test.ts +7 -4
- package/src/LinearGenomeView/util.ts +2 -2
- package/src/index.ts +10 -1
- package/dist/LinearGenomeView/components/LinearGenomeViewSvg.d.ts +0 -4
- package/dist/LinearGenomeView/components/LinearGenomeViewSvg.js +0 -141
- package/dist/LinearGenomeView/components/LinearGenomeViewSvg.js.map +0 -1
- package/dist/LinearGenomeView/components/Ruler.d.ts +0 -11
- package/dist/LinearGenomeView/components/Ruler.js +0 -39
- package/dist/LinearGenomeView/components/Ruler.js.map +0 -1
- package/esm/LinearGenomeView/components/LinearGenomeViewSvg.d.ts +0 -4
- package/esm/LinearGenomeView/components/LinearGenomeViewSvg.js +0 -134
- package/esm/LinearGenomeView/components/LinearGenomeViewSvg.js.map +0 -1
- package/esm/LinearGenomeView/components/Ruler.d.ts +0 -11
- package/esm/LinearGenomeView/components/Ruler.js +0 -34
- package/esm/LinearGenomeView/components/Ruler.js.map +0 -1
- package/src/LinearGenomeView/components/LinearGenomeViewSvg.tsx +0 -307
- package/src/LinearGenomeView/components/Ruler.tsx +0 -78
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
getRpcSessionId,
|
|
30
30
|
} from '@jbrowse/core/util/tracks'
|
|
31
31
|
|
|
32
|
+
// locals
|
|
32
33
|
import ServerSideRenderedBlockContent from '../components/ServerSideRenderedBlockContent'
|
|
33
34
|
|
|
34
35
|
// the MST state of a single server-side-rendered block in a display
|
|
@@ -65,7 +66,7 @@ const blockState = types
|
|
|
65
66
|
makeAbortableReaction(
|
|
66
67
|
self as any,
|
|
67
68
|
renderBlockData,
|
|
68
|
-
renderBlockEffect
|
|
69
|
+
renderBlockEffect, // reaction doesn't expect async here
|
|
69
70
|
{
|
|
70
71
|
name: `${display.id}/${assembleLocString(self.region)} rendering`,
|
|
71
72
|
delay: display.renderDelay,
|
|
@@ -140,7 +141,7 @@ const blockState = types
|
|
|
140
141
|
self.renderProps = renderProps
|
|
141
142
|
renderInProgress = undefined
|
|
142
143
|
},
|
|
143
|
-
setError(error:
|
|
144
|
+
setError(error: unknown) {
|
|
144
145
|
console.error(error)
|
|
145
146
|
if (renderInProgress && !renderInProgress.signal.aborted) {
|
|
146
147
|
renderInProgress.abort()
|
|
@@ -260,24 +261,14 @@ export function renderBlockData(
|
|
|
260
261
|
}
|
|
261
262
|
}
|
|
262
263
|
|
|
263
|
-
interface RenderProps {
|
|
264
|
-
displayError: Error
|
|
265
|
-
rendererType: any
|
|
266
|
-
renderProps: { [key: string]: any }
|
|
267
|
-
rpcManager: { call: Function }
|
|
268
|
-
cannotBeRenderedReason: string
|
|
269
|
-
renderArgs: { [key: string]: any }
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
interface ErrorProps {
|
|
273
|
-
displayError: string
|
|
274
|
-
}
|
|
275
|
-
|
|
276
264
|
async function renderBlockEffect(
|
|
277
|
-
props:
|
|
265
|
+
props: ReturnType<typeof renderBlockData> | undefined,
|
|
278
266
|
signal: AbortSignal,
|
|
279
267
|
self: BlockModel,
|
|
280
268
|
) {
|
|
269
|
+
if (!props) {
|
|
270
|
+
return
|
|
271
|
+
}
|
|
281
272
|
const {
|
|
282
273
|
rendererType,
|
|
283
274
|
renderProps,
|
|
@@ -285,7 +276,7 @@ async function renderBlockEffect(
|
|
|
285
276
|
renderArgs,
|
|
286
277
|
cannotBeRenderedReason,
|
|
287
278
|
displayError,
|
|
288
|
-
} = props
|
|
279
|
+
} = props
|
|
289
280
|
if (!isAlive(self)) {
|
|
290
281
|
return undefined
|
|
291
282
|
}
|
|
@@ -315,5 +306,6 @@ async function renderBlockEffect(
|
|
|
315
306
|
features,
|
|
316
307
|
layout,
|
|
317
308
|
maxHeightReached,
|
|
309
|
+
renderProps,
|
|
318
310
|
}
|
|
319
311
|
}
|
|
@@ -5,13 +5,13 @@ import { LinearGenomeViewModel } from '..'
|
|
|
5
5
|
|
|
6
6
|
type LGV = LinearGenomeViewModel
|
|
7
7
|
|
|
8
|
-
const useStyles = makeStyles()(
|
|
8
|
+
const useStyles = makeStyles()(theme => ({
|
|
9
9
|
centerLineContainer: {
|
|
10
10
|
background: 'transparent',
|
|
11
11
|
height: '100%',
|
|
12
12
|
zIndex: 5, // above the track but under menu
|
|
13
13
|
position: 'absolute',
|
|
14
|
-
border:
|
|
14
|
+
border: `1px ${theme.palette.action.active} dashed`,
|
|
15
15
|
borderTop: 'none',
|
|
16
16
|
borderBottom: 'none',
|
|
17
17
|
pointerEvents: 'none',
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { observer } from 'mobx-react'
|
|
3
|
+
|
|
4
|
+
// core
|
|
5
|
+
import { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel'
|
|
6
|
+
import { ContentBlock } from '@jbrowse/core/util/blockTypes'
|
|
7
|
+
import { Assembly } from '@jbrowse/core/assemblyManager/assembly'
|
|
8
|
+
|
|
9
|
+
// locals
|
|
10
|
+
import { HEADER_OVERVIEW_HEIGHT } from '..'
|
|
11
|
+
import { getCytobands } from './util'
|
|
12
|
+
|
|
13
|
+
// rounded rect from https://stackoverflow.com/a/45889603/2129219
|
|
14
|
+
// prettier-ignore
|
|
15
|
+
function rightRoundedRect(x: number, y: number, width: number, height: number, radius: number) {
|
|
16
|
+
return "M" + x + "," + y
|
|
17
|
+
+ "h" + (width - radius)
|
|
18
|
+
+ "a" + radius + "," + radius + " 0 0 1 " + radius + "," + radius
|
|
19
|
+
+ "v" + (height - 2 * radius)
|
|
20
|
+
+ "a" + radius + "," + radius + " 0 0 1 " + -radius + "," + radius
|
|
21
|
+
+ "h" + (radius - width)
|
|
22
|
+
+ "z";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// prettier-ignore
|
|
26
|
+
function leftRoundedRect(x: number, y: number, width: number, height: number, radius: number ) {
|
|
27
|
+
return "M" + (x + radius) + "," + y
|
|
28
|
+
+ "h" + (width - radius)
|
|
29
|
+
+ "v" + height
|
|
30
|
+
+ "h" + (radius - width)
|
|
31
|
+
+ "a" + radius + "," + radius + " 0 0 1 " + (-radius) + "," + (-radius)
|
|
32
|
+
+ "v" + (2 * radius - height)
|
|
33
|
+
+ "a" + radius + "," + radius + " 0 0 1 " + radius + "," + (-radius)
|
|
34
|
+
+ "z";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const colorMap: { [key: string]: string | undefined } = {
|
|
38
|
+
gneg: 'rgb(227,227,227)',
|
|
39
|
+
gpos25: 'rgb(142,142,142)',
|
|
40
|
+
gpos50: 'rgb(85,85,85)',
|
|
41
|
+
gpos100: 'rgb(0,0,0)',
|
|
42
|
+
gpos75: 'rgb(57,57,57)',
|
|
43
|
+
gvar: 'rgb(0,0,0)',
|
|
44
|
+
stalk: 'rgb(127,127,127)',
|
|
45
|
+
acen: '#800',
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default observer(function Cytobands({
|
|
49
|
+
overview,
|
|
50
|
+
block,
|
|
51
|
+
assembly,
|
|
52
|
+
}: {
|
|
53
|
+
overview: Base1DViewModel
|
|
54
|
+
assembly?: Assembly
|
|
55
|
+
block: ContentBlock
|
|
56
|
+
}) {
|
|
57
|
+
const { offsetPx, reversed } = block
|
|
58
|
+
const cytobands = getCytobands(assembly, block.refName)
|
|
59
|
+
const coords = cytobands.map(f => {
|
|
60
|
+
const { refName, start, end, type } = f
|
|
61
|
+
return [
|
|
62
|
+
overview.bpToPx({
|
|
63
|
+
refName,
|
|
64
|
+
coord: start,
|
|
65
|
+
}),
|
|
66
|
+
overview.bpToPx({
|
|
67
|
+
refName,
|
|
68
|
+
coord: end,
|
|
69
|
+
}),
|
|
70
|
+
type,
|
|
71
|
+
]
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
const arr = cytobands || []
|
|
75
|
+
const lcap = reversed ? arr.length - 1 : 0
|
|
76
|
+
const rcap = reversed ? 0 : arr.length - 1
|
|
77
|
+
|
|
78
|
+
let firstCent = true
|
|
79
|
+
return (
|
|
80
|
+
<g transform={`translate(-${offsetPx})`}>
|
|
81
|
+
{coords.map(([start, end, type], index) => {
|
|
82
|
+
const key = `${start}-${end}-${type}`
|
|
83
|
+
if (type === 'acen' && firstCent) {
|
|
84
|
+
firstCent = false
|
|
85
|
+
return (
|
|
86
|
+
<polygon
|
|
87
|
+
key={key}
|
|
88
|
+
points={[
|
|
89
|
+
[start, 0],
|
|
90
|
+
[end, HEADER_OVERVIEW_HEIGHT / 2],
|
|
91
|
+
[start, HEADER_OVERVIEW_HEIGHT],
|
|
92
|
+
].toString()}
|
|
93
|
+
fill={colorMap[type]}
|
|
94
|
+
/>
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
if (type === 'acen' && !firstCent) {
|
|
98
|
+
return (
|
|
99
|
+
<polygon
|
|
100
|
+
key={key}
|
|
101
|
+
points={[
|
|
102
|
+
[start, HEADER_OVERVIEW_HEIGHT / 2],
|
|
103
|
+
[end, 0],
|
|
104
|
+
[end, HEADER_OVERVIEW_HEIGHT],
|
|
105
|
+
].toString()}
|
|
106
|
+
fill={colorMap[type]}
|
|
107
|
+
/>
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (lcap === index) {
|
|
112
|
+
return (
|
|
113
|
+
<path
|
|
114
|
+
key={key}
|
|
115
|
+
d={leftRoundedRect(
|
|
116
|
+
Math.min(start, end),
|
|
117
|
+
0,
|
|
118
|
+
Math.abs(end - start),
|
|
119
|
+
HEADER_OVERVIEW_HEIGHT,
|
|
120
|
+
8,
|
|
121
|
+
)}
|
|
122
|
+
fill={colorMap[type]}
|
|
123
|
+
/>
|
|
124
|
+
)
|
|
125
|
+
} else if (rcap === index) {
|
|
126
|
+
return (
|
|
127
|
+
<path
|
|
128
|
+
key={key}
|
|
129
|
+
d={rightRoundedRect(
|
|
130
|
+
Math.min(start, end),
|
|
131
|
+
0,
|
|
132
|
+
Math.abs(end - start) - 2,
|
|
133
|
+
HEADER_OVERVIEW_HEIGHT,
|
|
134
|
+
8,
|
|
135
|
+
)}
|
|
136
|
+
fill={colorMap[type]}
|
|
137
|
+
/>
|
|
138
|
+
)
|
|
139
|
+
} else {
|
|
140
|
+
return (
|
|
141
|
+
<rect
|
|
142
|
+
key={key}
|
|
143
|
+
x={Math.min(start, end)}
|
|
144
|
+
y={0}
|
|
145
|
+
width={Math.abs(end - start)}
|
|
146
|
+
height={HEADER_OVERVIEW_HEIGHT}
|
|
147
|
+
fill={colorMap[type]}
|
|
148
|
+
/>
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
})}
|
|
152
|
+
</g>
|
|
153
|
+
)
|
|
154
|
+
})
|
|
@@ -6,10 +6,14 @@ import {
|
|
|
6
6
|
DialogActions,
|
|
7
7
|
DialogContent,
|
|
8
8
|
FormControlLabel,
|
|
9
|
+
MenuItem,
|
|
9
10
|
TextField,
|
|
10
11
|
Typography,
|
|
11
12
|
} from '@mui/material'
|
|
12
13
|
import { Dialog, ErrorMessage } from '@jbrowse/core/ui'
|
|
14
|
+
import { getSession, useLocalStorage } from '@jbrowse/core/util'
|
|
15
|
+
|
|
16
|
+
// locals
|
|
13
17
|
import { ExportSvgOptions } from '..'
|
|
14
18
|
|
|
15
19
|
function LoadingMessage() {
|
|
@@ -21,19 +25,28 @@ function LoadingMessage() {
|
|
|
21
25
|
)
|
|
22
26
|
}
|
|
23
27
|
|
|
28
|
+
function useSvgLocal<T>(key: string, val: T) {
|
|
29
|
+
return useLocalStorage('svg-' + key, val)
|
|
30
|
+
}
|
|
31
|
+
|
|
24
32
|
export default function ExportSvgDlg({
|
|
25
33
|
model,
|
|
26
34
|
handleClose,
|
|
27
35
|
}: {
|
|
28
|
-
model: { exportSvg(opts: ExportSvgOptions): void }
|
|
36
|
+
model: { exportSvg(opts: ExportSvgOptions): Promise<void> }
|
|
29
37
|
handleClose: () => void
|
|
30
38
|
}) {
|
|
31
|
-
|
|
39
|
+
const session = getSession(model)
|
|
32
40
|
const offscreenCanvas = typeof OffscreenCanvas !== 'undefined'
|
|
33
41
|
const [rasterizeLayers, setRasterizeLayers] = useState(offscreenCanvas)
|
|
34
42
|
const [loading, setLoading] = useState(false)
|
|
35
|
-
const [filename, setFilename] = useState('jbrowse.svg')
|
|
36
43
|
const [error, setError] = useState<unknown>()
|
|
44
|
+
const [filename, setFilename] = useSvgLocal('file', 'jbrowse.svg')
|
|
45
|
+
const [trackLabels, setTrackLabels] = useSvgLocal('tracklabels', 'offset')
|
|
46
|
+
const [themeName, setThemeName] = useSvgLocal(
|
|
47
|
+
'theme',
|
|
48
|
+
session.themeName || 'default',
|
|
49
|
+
)
|
|
37
50
|
return (
|
|
38
51
|
<Dialog open onClose={handleClose} title="Export SVG">
|
|
39
52
|
<DialogContent>
|
|
@@ -47,6 +60,40 @@ export default function ExportSvgDlg({
|
|
|
47
60
|
value={filename}
|
|
48
61
|
onChange={event => setFilename(event.target.value)}
|
|
49
62
|
/>
|
|
63
|
+
<br />
|
|
64
|
+
<TextField
|
|
65
|
+
select
|
|
66
|
+
label="Track label positioning"
|
|
67
|
+
variant="outlined"
|
|
68
|
+
style={{ width: 150 }}
|
|
69
|
+
value={trackLabels}
|
|
70
|
+
onChange={event => setTrackLabels(event.target.value)}
|
|
71
|
+
>
|
|
72
|
+
<MenuItem value="offset">Offset</MenuItem>
|
|
73
|
+
<MenuItem value="overlay">Overlay</MenuItem>
|
|
74
|
+
<MenuItem value="left">Left</MenuItem>
|
|
75
|
+
<MenuItem value="none">None</MenuItem>
|
|
76
|
+
</TextField>
|
|
77
|
+
<br />
|
|
78
|
+
{session.allThemes ? (
|
|
79
|
+
<TextField
|
|
80
|
+
select
|
|
81
|
+
label="Theme"
|
|
82
|
+
variant="outlined"
|
|
83
|
+
value={themeName}
|
|
84
|
+
onChange={event => setThemeName(event.target.value)}
|
|
85
|
+
>
|
|
86
|
+
{Object.entries(session.allThemes()).map(([key, val]) => (
|
|
87
|
+
<MenuItem key={key} value={key}>
|
|
88
|
+
{
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
val.name || '(Unknown name)'
|
|
91
|
+
}
|
|
92
|
+
</MenuItem>
|
|
93
|
+
))}
|
|
94
|
+
</TextField>
|
|
95
|
+
) : null}
|
|
96
|
+
|
|
50
97
|
{offscreenCanvas ? (
|
|
51
98
|
<FormControlLabel
|
|
52
99
|
control={
|
|
@@ -80,7 +127,12 @@ export default function ExportSvgDlg({
|
|
|
80
127
|
setLoading(true)
|
|
81
128
|
setError(undefined)
|
|
82
129
|
try {
|
|
83
|
-
await model.exportSvg({
|
|
130
|
+
await model.exportSvg({
|
|
131
|
+
rasterizeLayers,
|
|
132
|
+
filename,
|
|
133
|
+
trackLabels,
|
|
134
|
+
themeName,
|
|
135
|
+
})
|
|
84
136
|
handleClose()
|
|
85
137
|
} catch (e) {
|
|
86
138
|
console.error(e)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { observer } from 'mobx-react'
|
|
3
|
-
import { Button, FormGroup, Typography, alpha } from '@mui/material'
|
|
3
|
+
import { Button, IconButton, FormGroup, Typography, alpha } from '@mui/material'
|
|
4
4
|
import { makeStyles } from 'tss-react/mui'
|
|
5
5
|
import { getBpDisplayStr } from '@jbrowse/core/util'
|
|
6
6
|
|
|
@@ -10,12 +10,7 @@ import ArrowForwardIcon from '@mui/icons-material/ArrowForward'
|
|
|
10
10
|
import ArrowBackIcon from '@mui/icons-material/ArrowBack'
|
|
11
11
|
|
|
12
12
|
// locals
|
|
13
|
-
import {
|
|
14
|
-
LinearGenomeViewModel,
|
|
15
|
-
WIDGET_HEIGHT,
|
|
16
|
-
SPACING,
|
|
17
|
-
HEADER_BAR_HEIGHT,
|
|
18
|
-
} from '..'
|
|
13
|
+
import { LinearGenomeViewModel, SPACING } from '..'
|
|
19
14
|
import OverviewScalebar from './OverviewScalebar'
|
|
20
15
|
import ZoomControls from './ZoomControls'
|
|
21
16
|
import SearchBox from './SearchBox'
|
|
@@ -23,7 +18,6 @@ import SearchBox from './SearchBox'
|
|
|
23
18
|
type LGV = LinearGenomeViewModel
|
|
24
19
|
const useStyles = makeStyles()(theme => ({
|
|
25
20
|
headerBar: {
|
|
26
|
-
height: HEADER_BAR_HEIGHT,
|
|
27
21
|
display: 'flex',
|
|
28
22
|
},
|
|
29
23
|
headerForm: {
|
|
@@ -36,7 +30,7 @@ const useStyles = makeStyles()(theme => ({
|
|
|
36
30
|
|
|
37
31
|
panButton: {
|
|
38
32
|
background: alpha(theme.palette.background.paper, 0.8),
|
|
39
|
-
|
|
33
|
+
color: theme.palette.text.primary,
|
|
40
34
|
margin: SPACING,
|
|
41
35
|
},
|
|
42
36
|
bp: {
|
|
@@ -47,7 +41,7 @@ const useStyles = makeStyles()(theme => ({
|
|
|
47
41
|
toggleButton: {
|
|
48
42
|
height: 44,
|
|
49
43
|
border: 'none',
|
|
50
|
-
|
|
44
|
+
marginLeft: theme.spacing(4),
|
|
51
45
|
},
|
|
52
46
|
buttonSpacer: {
|
|
53
47
|
marginRight: theme.spacing(2),
|
|
@@ -57,15 +51,14 @@ const useStyles = makeStyles()(theme => ({
|
|
|
57
51
|
const HeaderButtons = observer(({ model }: { model: LGV }) => {
|
|
58
52
|
const { classes } = useStyles()
|
|
59
53
|
return (
|
|
60
|
-
<
|
|
54
|
+
<IconButton
|
|
61
55
|
onClick={model.activateTrackSelector}
|
|
62
56
|
className={classes.toggleButton}
|
|
63
57
|
title="Open track selector"
|
|
64
58
|
value="track_select"
|
|
65
|
-
color="secondary"
|
|
66
59
|
>
|
|
67
60
|
<TrackSelectorIcon className={classes.buttonSpacer} />
|
|
68
|
-
</
|
|
61
|
+
</IconButton>
|
|
69
62
|
)
|
|
70
63
|
})
|
|
71
64
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { fireEvent, render, waitFor } from '@testing-library/react'
|
|
3
3
|
import { createTestSession } from '@jbrowse/web/src/rootModel'
|
|
4
|
-
import '@testing-library/jest-dom/extend-expect'
|
|
5
4
|
import 'requestidlecallback-polyfill'
|
|
6
5
|
|
|
7
6
|
// locals
|
|
@@ -81,9 +80,8 @@ test('renders one track, one region', async () => {
|
|
|
81
80
|
})
|
|
82
81
|
const model = session.views[0]
|
|
83
82
|
model.setWidth(800)
|
|
84
|
-
const { container,
|
|
85
|
-
<LinearGenomeView model={model}
|
|
86
|
-
)
|
|
83
|
+
const { container, queryAllByTestId, getByPlaceholderText, findByText } =
|
|
84
|
+
render(<LinearGenomeView model={model} />)
|
|
87
85
|
await findByText('Foo Track')
|
|
88
86
|
// test needs to wait until it's updated to display 100 bp in the header to
|
|
89
87
|
// make snapshot pass
|
|
@@ -94,8 +92,9 @@ test('renders one track, one region', async () => {
|
|
|
94
92
|
(getByPlaceholderText('Search for location') as HTMLInputElement).value,
|
|
95
93
|
).toEqual('ctgA:1..100')
|
|
96
94
|
})
|
|
97
|
-
await waitFor(() => expect(
|
|
98
|
-
|
|
95
|
+
await waitFor(() => expect(queryAllByTestId('svgfeatures').length).toBe(1))
|
|
96
|
+
// snapshot has no features rendered
|
|
97
|
+
expect(container).toMatchSnapshot()
|
|
99
98
|
})
|
|
100
99
|
|
|
101
100
|
test('renders two tracks, two regions', async () => {
|
|
@@ -158,13 +157,11 @@ test('renders two tracks, two regions', async () => {
|
|
|
158
157
|
})
|
|
159
158
|
const model = session.views[0]
|
|
160
159
|
model.setWidth(800)
|
|
161
|
-
const { container, findByText,
|
|
160
|
+
const { container, findByText, queryAllByTestId } = render(
|
|
162
161
|
<LinearGenomeView model={model} />,
|
|
163
162
|
)
|
|
164
163
|
await findByText('Foo Track')
|
|
165
164
|
await findByText('798bp')
|
|
166
|
-
await
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
expect(container.firstChild).toMatchSnapshot()
|
|
165
|
+
await waitFor(() => expect(queryAllByTestId('svgfeatures').length).toBe(4))
|
|
166
|
+
expect(container).toMatchSnapshot()
|
|
170
167
|
}, 15000)
|
|
@@ -28,7 +28,7 @@ const LinearGenomeView = observer(({ model }: { model: LGV }) => {
|
|
|
28
28
|
const { classes } = useStyles()
|
|
29
29
|
|
|
30
30
|
if (!initialized && !error) {
|
|
31
|
-
return <LoadingEllipses variant="
|
|
31
|
+
return <LoadingEllipses variant="h6" />
|
|
32
32
|
}
|
|
33
33
|
if (!hasDisplayedRegions || error) {
|
|
34
34
|
return <ImportForm model={model} />
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
2
|
import { observer } from 'mobx-react'
|
|
3
3
|
import { IconButton, Paper } from '@mui/material'
|
|
4
|
+
import Menu from '@jbrowse/core/ui/Menu'
|
|
5
|
+
|
|
6
|
+
// icons
|
|
4
7
|
import ZoomIn from '@mui/icons-material/ZoomIn'
|
|
5
8
|
import ZoomOut from '@mui/icons-material/ZoomOut'
|
|
6
9
|
import ArrowDown from '@mui/icons-material/KeyboardArrowDown'
|
|
7
|
-
|
|
10
|
+
|
|
11
|
+
// locals
|
|
8
12
|
import { LinearGenomeViewModel } from '..'
|
|
9
13
|
|
|
10
14
|
const MiniControls = observer((props: { model: LinearGenomeViewModel }) => {
|
|
@@ -15,10 +19,7 @@ const MiniControls = observer((props: { model: LinearGenomeViewModel }) => {
|
|
|
15
19
|
return hideHeader ? (
|
|
16
20
|
<div style={{ position: 'absolute', right: '0px', zIndex: '1001' }}>
|
|
17
21
|
<Paper style={{ background: '#aaa7' }}>
|
|
18
|
-
<IconButton
|
|
19
|
-
color="secondary"
|
|
20
|
-
onClick={event => setAnchorEl(event.currentTarget)}
|
|
21
|
-
>
|
|
22
|
+
<IconButton onClick={event => setAnchorEl(event.currentTarget)}>
|
|
22
23
|
<ArrowDown fontSize="small" />
|
|
23
24
|
</IconButton>
|
|
24
25
|
|
|
@@ -26,7 +27,6 @@ const MiniControls = observer((props: { model: LinearGenomeViewModel }) => {
|
|
|
26
27
|
data-testid="zoom_out"
|
|
27
28
|
onClick={() => model.zoom(bpPerPx * 2)}
|
|
28
29
|
disabled={bpPerPx >= maxBpPerPx - 0.0001 || scaleFactor !== 1}
|
|
29
|
-
color="secondary"
|
|
30
30
|
>
|
|
31
31
|
<ZoomOut fontSize="small" />
|
|
32
32
|
</IconButton>
|
|
@@ -34,7 +34,6 @@ const MiniControls = observer((props: { model: LinearGenomeViewModel }) => {
|
|
|
34
34
|
data-testid="zoom_in"
|
|
35
35
|
onClick={() => model.zoom(model.bpPerPx / 2)}
|
|
36
36
|
disabled={bpPerPx <= minBpPerPx + 0.0001 || scaleFactor !== 1}
|
|
37
|
-
color="secondary"
|
|
38
37
|
>
|
|
39
38
|
<ZoomIn fontSize="small" />
|
|
40
39
|
</IconButton>
|