@jbrowse/plugin-circular-view 2.5.0 → 2.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist/BaseChordDisplay/components/BaseChordDisplay.d.ts +1 -1
  2. package/dist/BaseChordDisplay/components/BaseChordDisplay.js +0 -1
  3. package/dist/BaseChordDisplay/components/DisplayError.d.ts +2 -1
  4. package/dist/BaseChordDisplay/components/DisplayError.js +0 -1
  5. package/dist/BaseChordDisplay/components/Loading.d.ts +2 -1
  6. package/dist/BaseChordDisplay/components/Loading.js +0 -1
  7. package/dist/BaseChordDisplay/index.js +0 -1
  8. package/dist/BaseChordDisplay/models/configSchema.js +0 -1
  9. package/dist/BaseChordDisplay/models/model.d.ts +8 -2
  10. package/dist/BaseChordDisplay/models/model.js +0 -1
  11. package/dist/BaseChordDisplay/models/renderReaction.js +0 -1
  12. package/dist/CircularView/components/CircularView.d.ts +2 -1
  13. package/dist/CircularView/components/CircularView.js +0 -1
  14. package/dist/CircularView/components/Controls.d.ts +2 -1
  15. package/dist/CircularView/components/Controls.js +0 -1
  16. package/dist/CircularView/components/ExportSvgDialog.d.ts +2 -1
  17. package/dist/CircularView/components/ExportSvgDialog.js +0 -1
  18. package/dist/CircularView/components/ImportForm.d.ts +2 -1
  19. package/dist/CircularView/components/ImportForm.js +0 -1
  20. package/dist/CircularView/components/Ruler.d.ts +2 -1
  21. package/dist/CircularView/components/Ruler.js +0 -1
  22. package/dist/CircularView/index.js +0 -1
  23. package/dist/CircularView/models/CircularView.d.ts +1 -3
  24. package/dist/CircularView/models/CircularView.js +30 -7
  25. package/dist/CircularView/models/slices.js +0 -1
  26. package/dist/CircularView/models/viewportVisibleRegion.js +0 -1
  27. package/dist/CircularView/svgcomponents/SVGBackground.d.ts +2 -1
  28. package/dist/CircularView/svgcomponents/SVGBackground.js +0 -1
  29. package/dist/CircularView/svgcomponents/SVGCircularView.js +0 -1
  30. package/dist/LaunchCircularView/index.js +0 -1
  31. package/dist/index.js +0 -1
  32. package/esm/BaseChordDisplay/components/BaseChordDisplay.d.ts +1 -1
  33. package/esm/BaseChordDisplay/components/BaseChordDisplay.js +0 -1
  34. package/esm/BaseChordDisplay/components/DisplayError.d.ts +2 -1
  35. package/esm/BaseChordDisplay/components/DisplayError.js +0 -1
  36. package/esm/BaseChordDisplay/components/Loading.d.ts +2 -1
  37. package/esm/BaseChordDisplay/components/Loading.js +0 -1
  38. package/esm/BaseChordDisplay/index.js +0 -1
  39. package/esm/BaseChordDisplay/models/configSchema.js +0 -1
  40. package/esm/BaseChordDisplay/models/model.d.ts +8 -2
  41. package/esm/BaseChordDisplay/models/model.js +0 -1
  42. package/esm/BaseChordDisplay/models/renderReaction.js +0 -1
  43. package/esm/CircularView/components/CircularView.d.ts +2 -1
  44. package/esm/CircularView/components/CircularView.js +0 -1
  45. package/esm/CircularView/components/Controls.d.ts +2 -1
  46. package/esm/CircularView/components/Controls.js +0 -1
  47. package/esm/CircularView/components/ExportSvgDialog.d.ts +2 -1
  48. package/esm/CircularView/components/ExportSvgDialog.js +0 -1
  49. package/esm/CircularView/components/ImportForm.d.ts +2 -1
  50. package/esm/CircularView/components/ImportForm.js +0 -1
  51. package/esm/CircularView/components/Ruler.d.ts +2 -1
  52. package/esm/CircularView/components/Ruler.js +0 -1
  53. package/esm/CircularView/index.js +0 -1
  54. package/esm/CircularView/models/CircularView.d.ts +1 -3
  55. package/esm/CircularView/models/CircularView.js +6 -6
  56. package/esm/CircularView/models/slices.js +0 -1
  57. package/esm/CircularView/models/viewportVisibleRegion.js +0 -1
  58. package/esm/CircularView/svgcomponents/SVGBackground.d.ts +2 -1
  59. package/esm/CircularView/svgcomponents/SVGBackground.js +0 -1
  60. package/esm/CircularView/svgcomponents/SVGCircularView.js +0 -1
  61. package/esm/LaunchCircularView/index.js +0 -1
  62. package/esm/index.js +0 -1
  63. package/package.json +3 -4
  64. package/dist/BaseChordDisplay/components/BaseChordDisplay.js.map +0 -1
  65. package/dist/BaseChordDisplay/components/DisplayError.js.map +0 -1
  66. package/dist/BaseChordDisplay/components/Loading.js.map +0 -1
  67. package/dist/BaseChordDisplay/index.js.map +0 -1
  68. package/dist/BaseChordDisplay/models/configSchema.js.map +0 -1
  69. package/dist/BaseChordDisplay/models/model.js.map +0 -1
  70. package/dist/BaseChordDisplay/models/renderReaction.js.map +0 -1
  71. package/dist/CircularView/components/CircularView.js.map +0 -1
  72. package/dist/CircularView/components/Controls.js.map +0 -1
  73. package/dist/CircularView/components/ExportSvgDialog.js.map +0 -1
  74. package/dist/CircularView/components/ImportForm.js.map +0 -1
  75. package/dist/CircularView/components/Ruler.js.map +0 -1
  76. package/dist/CircularView/index.js.map +0 -1
  77. package/dist/CircularView/models/CircularView.js.map +0 -1
  78. package/dist/CircularView/models/slices.js.map +0 -1
  79. package/dist/CircularView/models/viewportVisibleRegion.js.map +0 -1
  80. package/dist/CircularView/svgcomponents/SVGBackground.js.map +0 -1
  81. package/dist/CircularView/svgcomponents/SVGCircularView.js.map +0 -1
  82. package/dist/LaunchCircularView/index.js.map +0 -1
  83. package/dist/index.js.map +0 -1
  84. package/esm/BaseChordDisplay/components/BaseChordDisplay.js.map +0 -1
  85. package/esm/BaseChordDisplay/components/DisplayError.js.map +0 -1
  86. package/esm/BaseChordDisplay/components/Loading.js.map +0 -1
  87. package/esm/BaseChordDisplay/index.js.map +0 -1
  88. package/esm/BaseChordDisplay/models/configSchema.js.map +0 -1
  89. package/esm/BaseChordDisplay/models/model.js.map +0 -1
  90. package/esm/BaseChordDisplay/models/renderReaction.js.map +0 -1
  91. package/esm/CircularView/components/CircularView.js.map +0 -1
  92. package/esm/CircularView/components/Controls.js.map +0 -1
  93. package/esm/CircularView/components/ExportSvgDialog.js.map +0 -1
  94. package/esm/CircularView/components/ImportForm.js.map +0 -1
  95. package/esm/CircularView/components/Ruler.js.map +0 -1
  96. package/esm/CircularView/index.js.map +0 -1
  97. package/esm/CircularView/models/CircularView.js.map +0 -1
  98. package/esm/CircularView/models/slices.js.map +0 -1
  99. package/esm/CircularView/models/viewportVisibleRegion.js.map +0 -1
  100. package/esm/CircularView/svgcomponents/SVGBackground.js.map +0 -1
  101. package/esm/CircularView/svgcomponents/SVGCircularView.js.map +0 -1
  102. package/esm/LaunchCircularView/index.js.map +0 -1
  103. package/esm/index.js.map +0 -1
  104. package/src/BaseChordDisplay/components/BaseChordDisplay.tsx +0 -26
  105. package/src/BaseChordDisplay/components/DisplayError.tsx +0 -47
  106. package/src/BaseChordDisplay/components/Loading.tsx +0 -111
  107. package/src/BaseChordDisplay/index.ts +0 -3
  108. package/src/BaseChordDisplay/models/configSchema.ts +0 -30
  109. package/src/BaseChordDisplay/models/model.tsx +0 -314
  110. package/src/BaseChordDisplay/models/renderReaction.ts +0 -75
  111. package/src/CircularView/components/CircularView.tsx +0 -128
  112. package/src/CircularView/components/Controls.tsx +0 -119
  113. package/src/CircularView/components/ExportSvgDialog.tsx +0 -132
  114. package/src/CircularView/components/ImportForm.tsx +0 -68
  115. package/src/CircularView/components/Ruler.tsx +0 -265
  116. package/src/CircularView/index.ts +0 -16
  117. package/src/CircularView/models/CircularView.ts +0 -620
  118. package/src/CircularView/models/__snapshots__/slices.test.js.snap +0 -91
  119. package/src/CircularView/models/slices.test.js +0 -70
  120. package/src/CircularView/models/slices.ts +0 -101
  121. package/src/CircularView/models/viewportVisibleRegion.test.js +0 -168
  122. package/src/CircularView/models/viewportVisibleRegion.ts +0 -272
  123. package/src/CircularView/svgcomponents/SVGBackground.tsx +0 -21
  124. package/src/CircularView/svgcomponents/SVGCircularView.tsx +0 -58
  125. package/src/LaunchCircularView/index.ts +0 -48
  126. package/src/index.ts +0 -43
@@ -1,119 +0,0 @@
1
- import React, { useState } from 'react'
2
- import { observer } from 'mobx-react'
3
- import { IconButton } from '@mui/material'
4
- import { makeStyles } from 'tss-react/mui'
5
- import JBrowseMenu from '@jbrowse/core/ui/Menu'
6
-
7
- // icons
8
- import ZoomOutIcon from '@mui/icons-material/ZoomOut'
9
- import ZoomInIcon from '@mui/icons-material/ZoomIn'
10
- import RotateLeftIcon from '@mui/icons-material/RotateLeft'
11
- import RotateRightIcon from '@mui/icons-material/RotateRight'
12
- import LockOpenIcon from '@mui/icons-material/LockOpen'
13
- import LockIcon from '@mui/icons-material/Lock'
14
- import PhotoCamera from '@mui/icons-material/PhotoCamera'
15
- import MoreVert from '@mui/icons-material/MoreVert'
16
- import { TrackSelector as TrackSelectorIcon } from '@jbrowse/core/ui/Icons'
17
-
18
- // locals
19
- import { CircularViewModel } from '../models/CircularView'
20
- import { getSession } from '@jbrowse/core/util'
21
- import ExportSvgDlg from './ExportSvgDialog'
22
-
23
- const useStyles = makeStyles()(theme => ({
24
- controls: {
25
- position: 'absolute',
26
- borderRight: `1px solid ${theme.palette.divider}`,
27
- borderBottom: `1px solid ${theme.palette.divider}`,
28
- left: 0,
29
- top: 0,
30
- },
31
- }))
32
-
33
- export default observer(function ({ model }: { model: CircularViewModel }) {
34
- const { classes } = useStyles()
35
- const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null)
36
- return (
37
- <div className={classes.controls}>
38
- <IconButton
39
- onClick={model.zoomOutButton}
40
- title={model.lockedFitToWindow ? 'unlock to zoom out' : 'zoom out'}
41
- disabled={model.atMaxBpPerPx || model.lockedFitToWindow}
42
- >
43
- <ZoomOutIcon />
44
- </IconButton>
45
-
46
- <IconButton
47
- onClick={model.zoomInButton}
48
- disabled={model.atMinBpPerPx}
49
- title="zoom in"
50
- >
51
- <ZoomInIcon />
52
- </IconButton>
53
-
54
- <IconButton
55
- onClick={model.rotateCounterClockwiseButton}
56
- title="rotate counter-clockwise"
57
- >
58
- <RotateLeftIcon />
59
- </IconButton>
60
-
61
- <IconButton
62
- onClick={model.rotateClockwiseButton}
63
- title="rotate clockwise"
64
- >
65
- <RotateRightIcon />
66
- </IconButton>
67
-
68
- <IconButton
69
- onClick={model.toggleFitToWindowLock}
70
- title={
71
- model.lockedFitToWindow
72
- ? 'locked model to window size'
73
- : 'unlocked model to zoom further'
74
- }
75
- disabled={model.tooSmallToLock}
76
- >
77
- {model.lockedFitToWindow ? <LockIcon /> : <LockOpenIcon />}
78
- </IconButton>
79
-
80
- <IconButton onClick={event => setAnchorEl(event.currentTarget)}>
81
- <MoreVert />
82
- </IconButton>
83
-
84
- {model.hideTrackSelectorButton ? null : (
85
- <IconButton
86
- onClick={model.activateTrackSelector}
87
- title="Open track selector"
88
- data-testid="circular_track_select"
89
- >
90
- <TrackSelectorIcon />
91
- </IconButton>
92
- )}
93
-
94
- {anchorEl ? (
95
- <JBrowseMenu
96
- anchorEl={anchorEl}
97
- menuItems={[
98
- {
99
- label: 'Export SVG',
100
- icon: PhotoCamera,
101
- onClick: () => {
102
- getSession(model).queueDialog(handleClose => [
103
- ExportSvgDlg,
104
- { model, handleClose },
105
- ])
106
- },
107
- },
108
- ]}
109
- onMenuItemClick={(_event, callback) => {
110
- callback()
111
- setAnchorEl(null)
112
- }}
113
- open={Boolean(anchorEl)}
114
- onClose={() => setAnchorEl(null)}
115
- />
116
- ) : null}
117
- </div>
118
- )
119
- })
@@ -1,132 +0,0 @@
1
- import React, { useState } from 'react'
2
- import {
3
- Button,
4
- Checkbox,
5
- CircularProgress,
6
- DialogActions,
7
- DialogContent,
8
- FormControlLabel,
9
- MenuItem,
10
- TextField,
11
- Typography,
12
- } from '@mui/material'
13
- import { Dialog, ErrorMessage } from '@jbrowse/core/ui'
14
-
15
- // locals
16
- import { ExportSvgOptions } from '../models/CircularView'
17
- import { getSession, useLocalStorage } from '@jbrowse/core/util'
18
-
19
- function LoadingMessage() {
20
- return (
21
- <div>
22
- <CircularProgress size={20} style={{ marginRight: 20 }} />
23
- <Typography display="inline">Creating SVG</Typography>
24
- </div>
25
- )
26
- }
27
-
28
- function useSvgLocal<T>(key: string, val: T) {
29
- return useLocalStorage('svg-' + key, val)
30
- }
31
-
32
- export default function ExportSvgDlg({
33
- model,
34
- handleClose,
35
- }: {
36
- model: { exportSvg(opts: ExportSvgOptions): Promise<void> }
37
- handleClose: () => void
38
- }) {
39
- const session = getSession(model)
40
- const offscreenCanvas = typeof OffscreenCanvas !== 'undefined'
41
- const [rasterizeLayers, setRasterizeLayers] = useState(offscreenCanvas)
42
- const [loading, setLoading] = useState(false)
43
- const [error, setError] = useState<unknown>()
44
- const [filename, setFilename] = useSvgLocal('file', 'jbrowse.svg')
45
- const [themeName, setThemeName] = useSvgLocal(
46
- 'theme',
47
- session.themeName || 'default',
48
- )
49
- return (
50
- <Dialog open onClose={handleClose} title="Export SVG">
51
- <DialogContent>
52
- {error ? (
53
- <ErrorMessage error={error} />
54
- ) : loading ? (
55
- <LoadingMessage />
56
- ) : null}
57
- <TextField
58
- helperText="filename"
59
- value={filename}
60
- onChange={event => setFilename(event.target.value)}
61
- />
62
- <br />
63
-
64
- {session.allThemes ? (
65
- <TextField
66
- select
67
- label="Theme"
68
- value={themeName}
69
- onChange={event => setThemeName(event.target.value)}
70
- >
71
- {Object.entries(session.allThemes()).map(([key, val]) => (
72
- <MenuItem key={key} value={key}>
73
- {
74
- // @ts-expect-error
75
- val.name || '(Unknown name)'
76
- }
77
- </MenuItem>
78
- ))}
79
- </TextField>
80
- ) : null}
81
- {offscreenCanvas ? (
82
- <FormControlLabel
83
- control={
84
- <Checkbox
85
- checked={rasterizeLayers}
86
- onChange={() => setRasterizeLayers(val => !val)}
87
- />
88
- }
89
- label="Rasterize canvas based tracks? File may be much larger if this is turned off"
90
- />
91
- ) : (
92
- <Typography>
93
- Note: rasterizing layers not yet supported in this browser, so SVG
94
- size may be large
95
- </Typography>
96
- )}
97
- </DialogContent>
98
- <DialogActions>
99
- <Button
100
- variant="contained"
101
- color="secondary"
102
- onClick={() => handleClose()}
103
- >
104
- Cancel
105
- </Button>
106
- <Button
107
- variant="contained"
108
- color="primary"
109
- type="submit"
110
- onClick={async () => {
111
- setLoading(true)
112
- setError(undefined)
113
- try {
114
- await model.exportSvg({
115
- rasterizeLayers,
116
- filename,
117
- themeName,
118
- })
119
- handleClose()
120
- } catch (e) {
121
- console.error(e)
122
- setError(e)
123
- setLoading(false)
124
- }
125
- }}
126
- >
127
- Submit
128
- </Button>
129
- </DialogActions>
130
- </Dialog>
131
- )
132
- }
@@ -1,68 +0,0 @@
1
- import React, { useState } from 'react'
2
- import { Button, Container, Grid } from '@mui/material'
3
- import { makeStyles } from 'tss-react/mui'
4
- import { observer } from 'mobx-react'
5
- import { getSession } from '@jbrowse/core/util'
6
- import { ErrorMessage, AssemblySelector } from '@jbrowse/core/ui'
7
-
8
- const useStyles = makeStyles()(theme => ({
9
- importFormContainer: {
10
- padding: theme.spacing(6),
11
- },
12
- }))
13
-
14
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
- const ImportForm = observer(({ model }: { model: any }) => {
16
- const { classes } = useStyles()
17
- const session = getSession(model)
18
- const { error } = model
19
- const { assemblyNames, assemblyManager } = session
20
- const [selectedAsm, setSelectedAsm] = useState(assemblyNames[0])
21
- const assembly = assemblyManager.get(selectedAsm)
22
- const assemblyError = assemblyNames.length
23
- ? assembly?.error
24
- : 'No configured assemblies'
25
- const regions = assembly?.regions || []
26
- const err = assemblyError || error
27
-
28
- return (
29
- <Container className={classes.importFormContainer}>
30
- {err ? (
31
- <Grid container spacing={1} justifyContent="center" alignItems="center">
32
- <Grid item>
33
- <ErrorMessage error={err} />
34
- </Grid>
35
- </Grid>
36
- ) : null}
37
- <Grid container spacing={1} justifyContent="center" alignItems="center">
38
- <Grid item>
39
- <AssemblySelector
40
- onChange={val => {
41
- model.setError(undefined)
42
- setSelectedAsm(val)
43
- }}
44
- session={session}
45
- selected={selectedAsm}
46
- />
47
- </Grid>
48
-
49
- <Grid item>
50
- <Button
51
- disabled={!regions?.length}
52
- onClick={() => {
53
- model.setError(undefined)
54
- model.setDisplayedRegions(regions)
55
- }}
56
- variant="contained"
57
- color="primary"
58
- >
59
- {/* if there's an error, it's not actively loading so just display open */}
60
- {regions.length || err ? 'Open' : 'Loading...'}
61
- </Button>
62
- </Grid>
63
- </Grid>
64
- </Container>
65
- )
66
- })
67
-
68
- export default ImportForm
@@ -1,265 +0,0 @@
1
- import React from 'react'
2
- import { observer } from 'mobx-react'
3
- import {
4
- getSession,
5
- polarToCartesian,
6
- radToDeg,
7
- assembleLocString,
8
- } from '@jbrowse/core/util'
9
- import { makeContrasting } from '@jbrowse/core/util/color'
10
- import { useTheme } from '@mui/material/styles'
11
- import { makeStyles } from 'tss-react/mui'
12
-
13
- // locals
14
- import {
15
- Slice,
16
- SliceElidedRegion,
17
- SliceNonElidedRegion,
18
- } from '../models/slices'
19
- import { CircularViewModel } from '../models/CircularView'
20
-
21
- const useStyles = makeStyles()({
22
- rulerLabel: {
23
- fontSize: '0.8rem',
24
- fontWeight: 500,
25
- lineHeight: 1.6,
26
- letterSpacing: '0.0075em',
27
- },
28
- })
29
-
30
- function sliceArcPath(
31
- slice: Slice,
32
- radiusPx: number,
33
- startBase: number,
34
- endBase: number,
35
- ) {
36
- // A rx ry x-axis-rotation large-arc-flag sweep-flag x y
37
- if (slice.flipped) {
38
- ;[startBase, endBase] = [endBase, startBase]
39
- }
40
- const startXY = slice.bpToXY(startBase, radiusPx)
41
- const endXY = slice.bpToXY(endBase, radiusPx)
42
- const largeArc =
43
- Math.abs(endBase - startBase) / slice.bpPerRadian > Math.PI ? '1' : '0'
44
- const sweepFlag = '1'
45
- return [
46
- 'M',
47
- ...startXY,
48
- 'A',
49
- radiusPx,
50
- radiusPx,
51
- '0',
52
- largeArc,
53
- sweepFlag,
54
- ...endXY,
55
- ].join(' ')
56
- }
57
-
58
- const ElisionRulerArc = observer(function ({
59
- model,
60
- slice,
61
- region,
62
- }: {
63
- model: CircularViewModel
64
- slice: Slice
65
- region: SliceElidedRegion
66
- }) {
67
- const theme = useTheme()
68
- const { radiusPx: modelRadiusPx } = model
69
- const radiusPx = modelRadiusPx + 1
70
- const { endRadians, startRadians } = slice
71
- const startXY = polarToCartesian(radiusPx, startRadians)
72
- const endXY = polarToCartesian(radiusPx, endRadians)
73
- const widthPx = (endRadians - startRadians) * radiusPx
74
- const largeArc = endRadians - startRadians > Math.PI ? '1' : '0'
75
- // TODO: draw the elision
76
- const centerRadians = (endRadians + startRadians) / 2
77
- const regionCount = `[${Number(region.regions.length).toLocaleString()}]`
78
- return (
79
- <>
80
- <RulerLabel
81
- text={regionCount}
82
- view={model}
83
- maxWidthPx={widthPx}
84
- radians={centerRadians}
85
- radiusPx={radiusPx}
86
- title={`${regionCount} more regions`}
87
- color={theme.palette.text.primary}
88
- />
89
- <path
90
- d={[
91
- 'M',
92
- ...startXY,
93
- 'A',
94
- radiusPx,
95
- radiusPx,
96
- '0',
97
- largeArc,
98
- '1',
99
- ...endXY,
100
- ].join(' ')}
101
- stroke={theme.palette.text.secondary}
102
- strokeWidth={2}
103
- strokeDasharray="2,2"
104
- fill="none"
105
- />
106
- </>
107
- )
108
- })
109
-
110
- const RulerLabel = observer(function ({
111
- view,
112
- text,
113
- maxWidthPx,
114
- radians,
115
- radiusPx,
116
- title,
117
- color,
118
- }: {
119
- view: CircularViewModel
120
- text: string
121
- maxWidthPx: number
122
- radiusPx: number
123
- radians: number
124
- title?: string
125
- color: string
126
- }) {
127
- const { classes } = useStyles()
128
- const textXY = polarToCartesian(radiusPx + 5, radians)
129
- if (!text) {
130
- return null
131
- }
132
-
133
- if (text.length * 6.5 < maxWidthPx) {
134
- // text is rotated parallel to the ruler arc
135
- return (
136
- <text
137
- x={0}
138
- y={0}
139
- className={classes.rulerLabel}
140
- textAnchor="middle"
141
- dominantBaseline="baseline"
142
- transform={`translate(${textXY}) rotate(${radToDeg(radians) + 90})`}
143
- style={{ fill: color }}
144
- >
145
- {text}
146
- <title>{title || text}</title>
147
- </text>
148
- )
149
- }
150
- if (maxWidthPx > 4) {
151
- // text is rotated perpendicular to the ruler arc
152
- const overallRotation = radToDeg(radians + view.offsetRadians - Math.PI / 2)
153
- if (overallRotation >= 180) {
154
- return (
155
- <text
156
- x={0}
157
- y={0}
158
- className={classes.rulerLabel}
159
- textAnchor="start"
160
- dominantBaseline="middle"
161
- transform={`translate(${textXY}) rotate(${radToDeg(radians)})`}
162
- style={{ fill: color }}
163
- >
164
- {text}
165
- <title>{title || text}</title>
166
- </text>
167
- )
168
- }
169
- return (
170
- <text
171
- x={0}
172
- y={0}
173
- className={classes.rulerLabel}
174
- textAnchor="end"
175
- dominantBaseline="middle"
176
- transform={`translate(${textXY}) rotate(${radToDeg(radians) + 180})`}
177
- style={{ fill: color }}
178
- >
179
- {text}
180
- <title>{title || text}</title>
181
- </text>
182
- )
183
- }
184
-
185
- // if you get here there is no room for the text at all
186
- return null
187
- })
188
-
189
- const RegionRulerArc = observer(function ({
190
- model,
191
- slice,
192
- region,
193
- }: {
194
- model: CircularViewModel
195
- slice: Slice
196
- region: SliceNonElidedRegion
197
- }) {
198
- const theme = useTheme()
199
- const { radiusPx } = model
200
- const { endRadians, startRadians } = slice
201
- const centerRadians = (endRadians + startRadians) / 2
202
- const widthPx = (endRadians - startRadians) * radiusPx
203
- const session = getSession(model)
204
- let color
205
- const assembly = session.assemblyManager.get(region.assemblyName)
206
- if (assembly) {
207
- color = assembly.getRefNameColor(region.refName)
208
- }
209
- if (color) {
210
- try {
211
- color = makeContrasting(color, theme.palette.background.paper)
212
- } catch (error) {
213
- color = theme.palette.text.primary
214
- }
215
- } else {
216
- color = theme.palette.text.primary
217
- }
218
-
219
- // TODO: slice flipping
220
- return (
221
- <>
222
- <RulerLabel
223
- text={region.refName}
224
- view={model}
225
- maxWidthPx={widthPx}
226
- radians={centerRadians}
227
- radiusPx={radiusPx}
228
- color={color}
229
- />
230
- <path
231
- d={sliceArcPath(slice, radiusPx + 1, region.start, region.end)}
232
- stroke={color}
233
- strokeWidth={2}
234
- fill="none"
235
- />
236
- </>
237
- )
238
- })
239
-
240
- export default observer(function ({
241
- model,
242
- slice,
243
- }: {
244
- model: CircularViewModel
245
- slice: Slice
246
- }) {
247
- if (slice.region.elided) {
248
- return (
249
- <ElisionRulerArc
250
- key={assembleLocString(slice.region.regions[0])}
251
- model={model}
252
- region={slice.region}
253
- slice={slice}
254
- />
255
- )
256
- }
257
- return (
258
- <RegionRulerArc
259
- key={assembleLocString(slice.region)}
260
- region={slice.region}
261
- model={model}
262
- slice={slice}
263
- />
264
- )
265
- })
@@ -1,16 +0,0 @@
1
- import { lazy } from 'react'
2
- import PluginManager from '@jbrowse/core/PluginManager'
3
- import ViewType from '@jbrowse/core/pluggableElementTypes/ViewType'
4
- import stateModelFactory from './models/CircularView'
5
-
6
- export default (pluginManager: PluginManager) => {
7
- pluginManager.addViewType(
8
- () =>
9
- new ViewType({
10
- ReactComponent: lazy(() => import('./components/CircularView')),
11
- stateModel: stateModelFactory(pluginManager),
12
- name: 'CircularView',
13
- displayName: 'Circular view',
14
- }),
15
- )
16
- }