react-msaview 5.0.7 → 5.0.16
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/bundle/index.js +135 -35
- package/bundle/index.js.LICENSE.txt +1 -1
- package/bundle/index.js.map +1 -1
- package/dist/components/Checkbox2.js +3 -6
- package/dist/components/Checkbox2.js.map +1 -1
- package/dist/components/MSAViewer.d.ts +14 -0
- package/dist/components/MSAViewer.js +34 -0
- package/dist/components/MSAViewer.js.map +1 -0
- package/dist/components/SequenceTextArea.js +4 -4
- package/dist/components/SequenceTextArea.js.map +1 -1
- package/dist/components/Track.js +5 -24
- package/dist/components/Track.js.map +1 -1
- package/dist/components/dialogs/DomainDialog.js +2 -5
- package/dist/components/dialogs/DomainDialog.js.map +1 -1
- package/dist/components/dialogs/InterProScanDialog.js +7 -7
- package/dist/components/dialogs/InterProScanDialog.js.map +1 -1
- package/dist/components/dialogs/SettingsDialog.js +3 -19
- package/dist/components/dialogs/SettingsDialog.js.map +1 -1
- package/dist/components/header/ColorSchemeMenu.d.ts +6 -0
- package/dist/components/header/ColorSchemeMenu.js +19 -0
- package/dist/components/header/ColorSchemeMenu.js.map +1 -0
- package/dist/components/header/{ZoomStar.d.ts → FileMenu.d.ts} +2 -2
- package/dist/components/header/FileMenu.js +71 -0
- package/dist/components/header/FileMenu.js.map +1 -0
- package/dist/components/header/Header.js +8 -6
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/header/HeaderMenu.js +3 -145
- package/dist/components/header/HeaderMenu.js.map +1 -1
- package/dist/components/header/MSASettingsMenu.d.ts +6 -0
- package/dist/components/header/MSASettingsMenu.js +36 -0
- package/dist/components/header/MSASettingsMenu.js.map +1 -0
- package/dist/components/header/SettingsMenu.js +1 -21
- package/dist/components/header/SettingsMenu.js.map +1 -1
- package/dist/components/header/TreeSettingsMenu.d.ts +6 -0
- package/dist/components/header/TreeSettingsMenu.js +74 -0
- package/dist/components/header/TreeSettingsMenu.js.map +1 -0
- package/dist/components/header/ZoomMenu.js +0 -8
- package/dist/components/header/ZoomMenu.js.map +1 -1
- package/dist/components/header/getDomainsMenu.d.ts +31 -0
- package/dist/components/header/getDomainsMenu.js +75 -0
- package/dist/components/header/getDomainsMenu.js.map +1 -0
- package/dist/components/import/ImportFormExamples.js +22 -20
- package/dist/components/import/ImportFormExamples.js.map +1 -1
- package/dist/components/msa/MSACanvas.js +13 -84
- package/dist/components/msa/MSACanvas.js.map +1 -1
- package/dist/components/msa/MSACanvasBlock.js +1 -3
- package/dist/components/msa/MSACanvasBlock.js.map +1 -1
- package/dist/components/msa/renderMSABlock.js +2 -4
- package/dist/components/msa/renderMSABlock.js.map +1 -1
- package/dist/components/msa/renderMSAMouseover.js +1 -7
- package/dist/components/msa/renderMSAMouseover.js.map +1 -1
- package/dist/components/tree/TreeCanvas.js +14 -91
- package/dist/components/tree/TreeCanvas.js.map +1 -1
- package/dist/components/tree/TreeNodeMenu.js +5 -16
- package/dist/components/tree/TreeNodeMenu.js.map +1 -1
- package/dist/components/tree/renderTreeCanvas.js +55 -22
- package/dist/components/tree/renderTreeCanvas.js.map +1 -1
- package/dist/constants.d.ts +0 -2
- package/dist/constants.js +0 -2
- package/dist/constants.js.map +1 -1
- package/dist/fetchUtils.d.ts +0 -1
- package/dist/fetchUtils.js +0 -4
- package/dist/fetchUtils.js.map +1 -1
- package/dist/flatToTree.d.ts +0 -5
- package/dist/flatToTree.js +13 -30
- package/dist/flatToTree.js.map +1 -1
- package/dist/hierarchy.d.ts +29 -0
- package/dist/hierarchy.js +164 -0
- package/dist/hierarchy.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/launchInterProScan.d.ts +0 -5
- package/dist/launchInterProScan.js +5 -3
- package/dist/launchInterProScan.js.map +1 -1
- package/dist/model/DataModel.d.ts +9 -0
- package/dist/model/DataModel.js +12 -1
- package/dist/model/DataModel.js.map +1 -1
- package/dist/model/msaModel.d.ts +3 -0
- package/dist/model/msaModel.js +0 -1
- package/dist/model/msaModel.js.map +1 -1
- package/dist/model/treeModel.d.ts +3 -6
- package/dist/model/treeModel.js +3 -15
- package/dist/model/treeModel.js.map +1 -1
- package/dist/model.d.ts +24 -77
- package/dist/model.js +118 -239
- package/dist/model.js.map +1 -1
- package/dist/neighborJoining.js +38 -629
- package/dist/neighborJoining.js.map +1 -1
- package/dist/parseAsn1.d.ts +0 -12
- package/dist/parseAsn1.js +125 -332
- package/dist/parseAsn1.js.map +1 -1
- package/dist/useWheelScroll.d.ts +8 -0
- package/dist/useWheelScroll.js +93 -0
- package/dist/useWheelScroll.js.map +1 -0
- package/dist/util.d.ts +1 -6
- package/dist/util.js +5 -34
- package/dist/util.js.map +1 -1
- package/dist/vendor/copyToClipboard.d.ts +1 -10
- package/dist/vendor/copyToClipboard.js +14 -109
- package/dist/vendor/copyToClipboard.js.map +1 -1
- package/dist/vendor/fileSaver.d.ts +1 -11
- package/dist/vendor/fileSaver.js +7 -76
- package/dist/vendor/fileSaver.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +10 -13
- package/src/collapseLogic.test.ts +115 -0
- package/src/components/Checkbox2.tsx +9 -18
- package/src/components/MSAViewer.tsx +67 -0
- package/src/components/SequenceTextArea.tsx +4 -4
- package/src/components/Track.tsx +10 -26
- package/src/components/dialogs/DomainDialog.tsx +4 -5
- package/src/components/dialogs/InterProScanDialog.tsx +7 -7
- package/src/components/dialogs/SettingsDialog.tsx +0 -37
- package/src/components/header/ColorSchemeMenu.tsx +35 -0
- package/src/components/header/FileMenu.tsx +84 -0
- package/src/components/header/Header.tsx +8 -6
- package/src/components/header/HeaderMenu.tsx +4 -155
- package/src/components/header/MSASettingsMenu.tsx +48 -0
- package/src/components/header/SettingsMenu.tsx +0 -23
- package/src/components/header/TreeSettingsMenu.tsx +96 -0
- package/src/components/header/ZoomMenu.tsx +0 -8
- package/src/components/header/getDomainsMenu.ts +83 -0
- package/src/components/import/ImportFormExamples.tsx +38 -35
- package/src/components/msa/MSACanvas.tsx +21 -91
- package/src/components/msa/MSACanvasBlock.tsx +1 -3
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +1 -1
- package/src/components/msa/renderMSABlock.ts +2 -5
- package/src/components/msa/renderMSAMouseover.ts +0 -6
- package/src/components/tree/TreeCanvas.tsx +35 -100
- package/src/components/tree/TreeNodeMenu.tsx +5 -14
- package/src/components/tree/renderTreeCanvas.test.ts +205 -0
- package/src/components/tree/renderTreeCanvas.ts +64 -27
- package/src/constants.ts +0 -2
- package/src/fetchUtils.ts +0 -5
- package/src/flatToTree.ts +20 -38
- package/src/hierarchy.test.ts +120 -0
- package/src/hierarchy.ts +221 -0
- package/src/index.ts +2 -0
- package/src/launchInterProScan.ts +4 -3
- package/src/model/DataModel.ts +12 -1
- package/src/model/msaModel.ts +0 -2
- package/src/model/treeModel.ts +2 -18
- package/src/model.ts +180 -278
- package/src/neighborJoining.ts +38 -628
- package/src/parseAsn1.test.ts +4 -1
- package/src/parseAsn1.ts +135 -405
- package/src/useWheelScroll.ts +109 -0
- package/src/util.ts +5 -50
- package/src/vendor/copyToClipboard.ts +14 -122
- package/src/vendor/fileSaver.ts +8 -105
- package/src/version.ts +1 -1
- package/dist/components/dialogs/AddTrackDialog.d.ts +0 -8
- package/dist/components/dialogs/AddTrackDialog.js +0 -30
- package/dist/components/dialogs/AddTrackDialog.js.map +0 -1
- package/dist/components/dialogs/TabPanel.d.ts +0 -6
- package/dist/components/dialogs/TabPanel.js +0 -6
- package/dist/components/dialogs/TabPanel.js.map +0 -1
- package/dist/components/header/ZoomStar.js +0 -40
- package/dist/components/header/ZoomStar.js.map +0 -1
- package/dist/layout.d.ts +0 -26
- package/dist/layout.js +0 -74
- package/dist/layout.js.map +0 -1
- package/dist/reparseTree.d.ts +0 -2
- package/dist/reparseTree.js +0 -15
- package/dist/reparseTree.js.map +0 -1
- package/src/components/dialogs/AddTrackDialog.tsx +0 -85
- package/src/components/dialogs/TabPanel.tsx +0 -19
- package/src/components/header/ZoomStar.tsx +0 -74
- package/src/createPaletteMap.test.ts +0 -57
- package/src/layout.ts +0 -118
- package/src/reparseTree.ts +0 -18
package/dist/reparseTree.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// this reparse routine helps to allow the app to hide/collapse a single
|
|
2
|
-
// leafnode
|
|
3
|
-
export function reparseTree(tree) {
|
|
4
|
-
return {
|
|
5
|
-
...tree,
|
|
6
|
-
children: tree.children.map(r => r.children.length
|
|
7
|
-
? reparseTree(r)
|
|
8
|
-
: {
|
|
9
|
-
children: [r],
|
|
10
|
-
id: `${r.id}-leafnode`,
|
|
11
|
-
name: `${r.name}-hidden`,
|
|
12
|
-
}),
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
//# sourceMappingURL=reparseTree.js.map
|
package/dist/reparseTree.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reparseTree.js","sourceRoot":"","sources":["../src/reparseTree.ts"],"names":[],"mappings":"AAEA,wEAAwE;AACxE,WAAW;AACX,MAAM,UAAU,WAAW,CAAC,IAAiB;IAC3C,OAAO;QACL,GAAG,IAAI;QACP,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAC9B,CAAC,CAAC,QAAQ,CAAC,MAAM;YACf,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;YAChB,CAAC,CAAC;gBACE,QAAQ,EAAE,CAAC,CAAC,CAAC;gBACb,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,WAAW;gBACtB,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,SAAS;aACzB,CACN;KACF,CAAA;AACH,CAAC"}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
2
|
-
|
|
3
|
-
import { Dialog, FileSelector } from '@jbrowse/core/ui'
|
|
4
|
-
import {
|
|
5
|
-
Button,
|
|
6
|
-
DialogActions,
|
|
7
|
-
DialogContent,
|
|
8
|
-
MenuItem,
|
|
9
|
-
TextField,
|
|
10
|
-
Typography,
|
|
11
|
-
} from '@mui/material'
|
|
12
|
-
import { observer } from 'mobx-react'
|
|
13
|
-
|
|
14
|
-
import type { MsaViewModel } from '../../model.ts'
|
|
15
|
-
import type { FileLocation } from '@jbrowse/core/util/types'
|
|
16
|
-
|
|
17
|
-
const AddTrackDialog = observer(function ({
|
|
18
|
-
model,
|
|
19
|
-
onClose,
|
|
20
|
-
open,
|
|
21
|
-
}: {
|
|
22
|
-
model: MsaViewModel
|
|
23
|
-
onClose: () => void
|
|
24
|
-
open: boolean
|
|
25
|
-
}) {
|
|
26
|
-
const options = model.rows.map(r => r[0])
|
|
27
|
-
const [trackFile, setTrackFile] = useState<FileLocation>()
|
|
28
|
-
const [currentOption, setCurrentOption] = useState('')
|
|
29
|
-
|
|
30
|
-
return (
|
|
31
|
-
<Dialog
|
|
32
|
-
onClose={() => {
|
|
33
|
-
onClose()
|
|
34
|
-
}}
|
|
35
|
-
open={open}
|
|
36
|
-
title="Add track"
|
|
37
|
-
>
|
|
38
|
-
<DialogContent>
|
|
39
|
-
<Typography>
|
|
40
|
-
Open relevant per-alignment tracks e.g. protein domains
|
|
41
|
-
</Typography>
|
|
42
|
-
<TextField
|
|
43
|
-
select
|
|
44
|
-
helperText="Which row does this track apply to?"
|
|
45
|
-
value={currentOption}
|
|
46
|
-
onChange={event => {
|
|
47
|
-
setCurrentOption(event.target.value)
|
|
48
|
-
}}
|
|
49
|
-
>
|
|
50
|
-
{options.map((option, index) => (
|
|
51
|
-
<MenuItem key={`${option}-${index}`} value={option}>
|
|
52
|
-
{option}
|
|
53
|
-
</MenuItem>
|
|
54
|
-
))}
|
|
55
|
-
</TextField>
|
|
56
|
-
<FileSelector location={trackFile} setLocation={setTrackFile} />
|
|
57
|
-
<DialogActions>
|
|
58
|
-
<Button
|
|
59
|
-
onClick={() => {
|
|
60
|
-
model.setError(undefined)
|
|
61
|
-
if (trackFile) {
|
|
62
|
-
model.setMSAFilehandle(trackFile)
|
|
63
|
-
}
|
|
64
|
-
}}
|
|
65
|
-
variant="contained"
|
|
66
|
-
color="primary"
|
|
67
|
-
>
|
|
68
|
-
Open
|
|
69
|
-
</Button>
|
|
70
|
-
<Button
|
|
71
|
-
color="secondary"
|
|
72
|
-
variant="contained"
|
|
73
|
-
onClick={() => {
|
|
74
|
-
onClose()
|
|
75
|
-
}}
|
|
76
|
-
>
|
|
77
|
-
Cancel
|
|
78
|
-
</Button>
|
|
79
|
-
</DialogActions>
|
|
80
|
-
</DialogContent>
|
|
81
|
-
</Dialog>
|
|
82
|
-
)
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
export default AddTrackDialog
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
3
|
-
// this is from MUI example
|
|
4
|
-
export default function TabPanel({
|
|
5
|
-
children,
|
|
6
|
-
value,
|
|
7
|
-
index,
|
|
8
|
-
...other
|
|
9
|
-
}: {
|
|
10
|
-
children?: React.ReactNode
|
|
11
|
-
index: number
|
|
12
|
-
value: number
|
|
13
|
-
}) {
|
|
14
|
-
return (
|
|
15
|
-
<div role="tabpanel" hidden={value !== index} {...other}>
|
|
16
|
-
{value === index && <div>{children}</div>}
|
|
17
|
-
</div>
|
|
18
|
-
)
|
|
19
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
3
|
-
import RestartAlt from '@mui/icons-material/RestartAlt'
|
|
4
|
-
import { IconButton } from '@mui/material'
|
|
5
|
-
import { observer } from 'mobx-react'
|
|
6
|
-
import { makeStyles } from 'tss-react/mui'
|
|
7
|
-
|
|
8
|
-
import type { MsaViewModel } from '../../model.ts'
|
|
9
|
-
|
|
10
|
-
const useStyles = makeStyles()(theme => ({
|
|
11
|
-
dpad: {
|
|
12
|
-
display: 'grid',
|
|
13
|
-
gridTemplateColumns: 'repeat(3, 1fr)',
|
|
14
|
-
},
|
|
15
|
-
icon: {
|
|
16
|
-
padding: theme.spacing(0.5),
|
|
17
|
-
},
|
|
18
|
-
}))
|
|
19
|
-
|
|
20
|
-
const ZoomStar = observer(function ({ model }: { model: MsaViewModel }) {
|
|
21
|
-
const { classes } = useStyles()
|
|
22
|
-
return (
|
|
23
|
-
<div className={classes.dpad}>
|
|
24
|
-
<div />
|
|
25
|
-
<IconButton
|
|
26
|
-
className={classes.icon}
|
|
27
|
-
onClick={() => {
|
|
28
|
-
model.zoomInVertical()
|
|
29
|
-
}}
|
|
30
|
-
>
|
|
31
|
-
Y+
|
|
32
|
-
</IconButton>
|
|
33
|
-
<div />
|
|
34
|
-
|
|
35
|
-
<IconButton
|
|
36
|
-
className={classes.icon}
|
|
37
|
-
onClick={() => {
|
|
38
|
-
model.zoomOutHorizontal()
|
|
39
|
-
}}
|
|
40
|
-
>
|
|
41
|
-
X-
|
|
42
|
-
</IconButton>
|
|
43
|
-
<IconButton
|
|
44
|
-
className={classes.icon}
|
|
45
|
-
onClick={() => {
|
|
46
|
-
model.resetZoom()
|
|
47
|
-
}}
|
|
48
|
-
>
|
|
49
|
-
<RestartAlt />
|
|
50
|
-
</IconButton>
|
|
51
|
-
<IconButton
|
|
52
|
-
className={classes.icon}
|
|
53
|
-
onClick={() => {
|
|
54
|
-
model.zoomInHorizontal()
|
|
55
|
-
}}
|
|
56
|
-
>
|
|
57
|
-
X+
|
|
58
|
-
</IconButton>
|
|
59
|
-
|
|
60
|
-
<div />
|
|
61
|
-
<IconButton
|
|
62
|
-
className={classes.icon}
|
|
63
|
-
onClick={() => {
|
|
64
|
-
model.zoomOutVertical()
|
|
65
|
-
}}
|
|
66
|
-
>
|
|
67
|
-
Y-
|
|
68
|
-
</IconButton>
|
|
69
|
-
<div />
|
|
70
|
-
</div>
|
|
71
|
-
)
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
export default ZoomStar
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { expect, test } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import { createPaletteMap } from './createPaletteMap.ts'
|
|
4
|
-
import palettes from './ggplotPalettes.ts'
|
|
5
|
-
|
|
6
|
-
// Original implementation for comparison
|
|
7
|
-
function originalFillPalette(keys: string[]) {
|
|
8
|
-
let i = 0
|
|
9
|
-
const map = {} as Record<string, string>
|
|
10
|
-
for (const key of keys) {
|
|
11
|
-
const k = Math.min(keys.length - 1, palettes.length - 1)
|
|
12
|
-
map[key] = palettes[k]![i]!
|
|
13
|
-
i++
|
|
14
|
-
}
|
|
15
|
-
return map
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
test('createPaletteMap matches original implementation with 1 key', () => {
|
|
19
|
-
const keys = ['IPR001234']
|
|
20
|
-
expect(createPaletteMap(keys)).toEqual(originalFillPalette(keys))
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
test('createPaletteMap matches original implementation with 3 keys', () => {
|
|
24
|
-
const keys = ['IPR001234', 'IPR005678', 'IPR009012']
|
|
25
|
-
expect(createPaletteMap(keys)).toEqual(originalFillPalette(keys))
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
test('createPaletteMap matches original implementation with 8 keys (max palette size)', () => {
|
|
29
|
-
const keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
|
|
30
|
-
expect(createPaletteMap(keys)).toEqual(originalFillPalette(keys))
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
test('createPaletteMap matches original implementation with more keys than palette colors', () => {
|
|
34
|
-
const keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
|
|
35
|
-
expect(createPaletteMap(keys)).toEqual(originalFillPalette(keys))
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
test('createPaletteMap returns correct colors for 3 keys', () => {
|
|
39
|
-
const keys = ['X', 'Y', 'Z']
|
|
40
|
-
const result = createPaletteMap(keys)
|
|
41
|
-
// With 3 keys, uses palette index 2 (0-indexed)
|
|
42
|
-
expect(result).toEqual({
|
|
43
|
-
X: '#F8766D',
|
|
44
|
-
Y: '#00BA38',
|
|
45
|
-
Z: '#619CFF',
|
|
46
|
-
})
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
test('createPaletteMap returns empty object for empty keys', () => {
|
|
50
|
-
expect(createPaletteMap([])).toEqual({})
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
test('createPaletteMap preserves key order', () => {
|
|
54
|
-
const keys = ['Z', 'A', 'M']
|
|
55
|
-
const result = createPaletteMap(keys)
|
|
56
|
-
expect(Object.keys(result)).toEqual(['Z', 'A', 'M'])
|
|
57
|
-
})
|
package/src/layout.ts
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import Flatbush from 'flatbush'
|
|
2
|
-
|
|
3
|
-
export default class Layout {
|
|
4
|
-
public rectangles: Map<
|
|
5
|
-
string,
|
|
6
|
-
{
|
|
7
|
-
minY: number
|
|
8
|
-
maxY: number
|
|
9
|
-
minX: number
|
|
10
|
-
maxX: number
|
|
11
|
-
id: string
|
|
12
|
-
data: unknown
|
|
13
|
-
}
|
|
14
|
-
>
|
|
15
|
-
|
|
16
|
-
public maxHeightReached = false
|
|
17
|
-
|
|
18
|
-
private maxHeight: number
|
|
19
|
-
|
|
20
|
-
private flatbush: Flatbush | null = null
|
|
21
|
-
|
|
22
|
-
private indexToId: string[] = []
|
|
23
|
-
|
|
24
|
-
private pTotalHeight: number
|
|
25
|
-
|
|
26
|
-
constructor({
|
|
27
|
-
maxHeight = 10000,
|
|
28
|
-
}: {
|
|
29
|
-
maxHeight?: number
|
|
30
|
-
} = {}) {
|
|
31
|
-
this.rectangles = new Map()
|
|
32
|
-
this.maxHeight = Math.ceil(maxHeight)
|
|
33
|
-
this.pTotalHeight = 0 // total height, in units of bitmap squares (px/pitchY)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
private rebuildIndex() {
|
|
37
|
-
// Rebuild the spatial index with current rectangles
|
|
38
|
-
const rects = Array.from(this.rectangles.values())
|
|
39
|
-
if (rects.length === 0) {
|
|
40
|
-
this.flatbush = null
|
|
41
|
-
this.indexToId = []
|
|
42
|
-
return
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
this.flatbush = new Flatbush(rects.length)
|
|
46
|
-
this.indexToId = []
|
|
47
|
-
|
|
48
|
-
for (const rect of rects) {
|
|
49
|
-
this.flatbush.add(rect.minX, rect.minY, rect.maxX, rect.maxY)
|
|
50
|
-
this.indexToId.push(rect.id)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
this.flatbush.finish()
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
private collides(box: {
|
|
57
|
-
minX: number
|
|
58
|
-
minY: number
|
|
59
|
-
maxX: number
|
|
60
|
-
maxY: number
|
|
61
|
-
}): boolean {
|
|
62
|
-
if (!this.flatbush) {
|
|
63
|
-
return false
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const results = this.flatbush.search(box.minX, box.minY, box.maxX, box.maxY)
|
|
67
|
-
|
|
68
|
-
return results.length > 0
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* @returns top position for the rect, or Null if laying
|
|
73
|
-
* out the rect would exceed maxHeighe
|
|
74
|
-
*/
|
|
75
|
-
addRect(
|
|
76
|
-
id: string,
|
|
77
|
-
left: number,
|
|
78
|
-
right: number,
|
|
79
|
-
height: number,
|
|
80
|
-
data: unknown,
|
|
81
|
-
): number | null {
|
|
82
|
-
// add to flatbush
|
|
83
|
-
const existingRecord = this.rectangles.get(id)
|
|
84
|
-
if (existingRecord) {
|
|
85
|
-
return existingRecord.minY
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
let currHeight = 0
|
|
89
|
-
while (
|
|
90
|
-
this.collides({
|
|
91
|
-
minX: left,
|
|
92
|
-
minY: currHeight,
|
|
93
|
-
maxX: right,
|
|
94
|
-
maxY: currHeight + height,
|
|
95
|
-
}) &&
|
|
96
|
-
currHeight <= this.maxHeight
|
|
97
|
-
) {
|
|
98
|
-
currHeight += 1
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const record = {
|
|
102
|
-
minX: left,
|
|
103
|
-
minY: currHeight,
|
|
104
|
-
maxX: right,
|
|
105
|
-
maxY: currHeight + height,
|
|
106
|
-
id,
|
|
107
|
-
data,
|
|
108
|
-
}
|
|
109
|
-
this.rectangles.set(id, record)
|
|
110
|
-
this.rebuildIndex()
|
|
111
|
-
this.pTotalHeight = Math.max(this.pTotalHeight, currHeight)
|
|
112
|
-
return currHeight
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
get totalHeight() {
|
|
116
|
-
return this.pTotalHeight
|
|
117
|
-
}
|
|
118
|
-
}
|
package/src/reparseTree.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { NodeWithIds } from './types.ts'
|
|
2
|
-
|
|
3
|
-
// this reparse routine helps to allow the app to hide/collapse a single
|
|
4
|
-
// leafnode
|
|
5
|
-
export function reparseTree(tree: NodeWithIds): NodeWithIds {
|
|
6
|
-
return {
|
|
7
|
-
...tree,
|
|
8
|
-
children: tree.children.map(r =>
|
|
9
|
-
r.children.length
|
|
10
|
-
? reparseTree(r)
|
|
11
|
-
: {
|
|
12
|
-
children: [r],
|
|
13
|
-
id: `${r.id}-leafnode`,
|
|
14
|
-
name: `${r.name}-hidden`,
|
|
15
|
-
},
|
|
16
|
-
),
|
|
17
|
-
}
|
|
18
|
-
}
|