react-msaview 3.1.4 → 3.1.6

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 (50) hide show
  1. package/bundle/index.js +31 -40
  2. package/dist/DataModel.d.ts +34 -0
  3. package/dist/DataModel.js +46 -0
  4. package/dist/DataModel.js.map +1 -0
  5. package/dist/SelectedStructuresMixin.d.ts +46 -0
  6. package/dist/SelectedStructuresMixin.js +52 -0
  7. package/dist/SelectedStructuresMixin.js.map +1 -0
  8. package/dist/components/MSAPanel/MSABlock.js +32 -16
  9. package/dist/components/MSAPanel/MSABlock.js.map +1 -1
  10. package/dist/components/MSAPanel/renderMSABlock.js +1 -1
  11. package/dist/components/MSAPanel/renderMSABlock.js.map +1 -1
  12. package/dist/components/MSAPanel/renderMSAMouseover.js +14 -4
  13. package/dist/components/MSAPanel/renderMSAMouseover.js.map +1 -1
  14. package/dist/components/MSAView.js +2 -2
  15. package/dist/components/MSAView.js.map +1 -1
  16. package/dist/components/TreePanel/TreeNodeMenu.js +65 -55
  17. package/dist/components/TreePanel/TreeNodeMenu.js.map +1 -1
  18. package/dist/components/TreePanel/renderTreeCanvas.js +13 -12
  19. package/dist/components/TreePanel/renderTreeCanvas.js.map +1 -1
  20. package/dist/components/dialogs/SettingsDialog.js +42 -32
  21. package/dist/components/dialogs/SettingsDialog.js.map +1 -1
  22. package/dist/measureTextCanvas.d.ts +1 -1
  23. package/dist/measureTextCanvas.js +1 -1
  24. package/dist/measureTextCanvas.js.map +1 -1
  25. package/dist/model.d.ts +121 -108
  26. package/dist/model.js +72 -94
  27. package/dist/model.js.map +1 -1
  28. package/dist/parsers/ClustalMSA.d.ts +1 -11
  29. package/dist/parsers/ClustalMSA.js +1 -15
  30. package/dist/parsers/ClustalMSA.js.map +1 -1
  31. package/dist/util.d.ts +0 -1
  32. package/dist/util.js +0 -7
  33. package/dist/util.js.map +1 -1
  34. package/dist/version.d.ts +1 -1
  35. package/dist/version.js +1 -1
  36. package/package.json +1 -2
  37. package/src/DataModel.ts +46 -0
  38. package/src/SelectedStructuresMixin.ts +59 -0
  39. package/src/components/MSAPanel/MSABlock.tsx +33 -18
  40. package/src/components/MSAPanel/renderMSABlock.ts +0 -1
  41. package/src/components/MSAPanel/renderMSAMouseover.ts +16 -3
  42. package/src/components/MSAView.tsx +3 -3
  43. package/src/components/TreePanel/TreeNodeMenu.tsx +93 -84
  44. package/src/components/TreePanel/renderTreeCanvas.ts +19 -9
  45. package/src/components/dialogs/SettingsDialog.tsx +121 -117
  46. package/src/measureTextCanvas.ts +1 -1
  47. package/src/model.ts +88 -110
  48. package/src/parsers/ClustalMSA.ts +1 -15
  49. package/src/util.ts +0 -11
  50. package/src/version.ts +1 -1
@@ -35,142 +35,146 @@ function FormControlLabel2(rest: FormControlLabelProps) {
35
35
  )
36
36
  }
37
37
 
38
+ function Checkbox2({
39
+ checked,
40
+ label,
41
+ onChange,
42
+ }: {
43
+ checked: boolean
44
+ label: string
45
+ onChange: () => void
46
+ }) {
47
+ return (
48
+ <FormControlLabel2
49
+ control={<Checkbox checked={checked} onChange={onChange} />}
50
+ label={label}
51
+ />
52
+ )
53
+ }
54
+
38
55
  const SettingsContent = observer(function ({ model }: { model: MsaViewModel }) {
56
+ return (
57
+ <>
58
+ <TreeSettings model={model} />
59
+ <MSASettings model={model} />
60
+ </>
61
+ )
62
+ })
63
+
64
+ function TreeSettings({ model }: { model: MsaViewModel }) {
39
65
  const { classes } = useStyles()
40
66
  const {
41
- bgColor,
42
- colWidth,
43
- colorSchemeName,
44
67
  drawTree,
45
68
  drawNodeBubbles,
46
69
  labelsAlignRight,
47
70
  noTree,
48
- rowHeight,
49
71
  showBranchLen,
50
72
  treeWidthMatchesArea,
51
73
  treeWidth,
52
74
  } = model
75
+
53
76
  return (
54
- <>
55
- <div>
56
- <Button onClick={() => model.clearHidden()}>Clear hidden</Button>
57
- <h1>Tree options</h1>
58
- <FormControlLabel2
59
- control={
60
- <Checkbox
61
- checked={showBranchLen}
62
- onChange={() => model.setShowBranchLen(!showBranchLen)}
63
- />
64
- }
65
- label="Show branch length?"
66
- />
77
+ <div>
78
+ <h1>Tree options</h1>
79
+ <Checkbox2
80
+ checked={showBranchLen}
81
+ onChange={() => model.setShowBranchLen(!showBranchLen)}
82
+ label="Show branch length?"
83
+ />
67
84
 
68
- <FormControlLabel2
69
- control={
70
- <Checkbox
71
- checked={drawNodeBubbles}
72
- onChange={() => model.setDrawNodeBubbles(!drawNodeBubbles)}
73
- />
74
- }
75
- label="Draw clickable bubbles on tree branches?"
76
- />
77
- <FormControlLabel2
78
- control={
79
- <Checkbox
80
- checked={drawTree}
81
- onChange={() => model.setDrawTree(!drawTree)}
82
- />
83
- }
84
- label="Show tree?"
85
- />
85
+ <Checkbox2
86
+ checked={drawNodeBubbles}
87
+ onChange={() => model.setDrawNodeBubbles(!drawNodeBubbles)}
88
+ label="Draw clickable bubbles on tree branches?"
89
+ />
90
+ <Checkbox2
91
+ checked={drawTree}
92
+ onChange={() => model.setDrawTree(!drawTree)}
93
+ label="Show tree?"
94
+ />
86
95
 
87
- <FormControlLabel2
88
- control={
89
- <Checkbox
90
- checked={labelsAlignRight}
91
- onChange={() => model.setLabelsAlignRight(!labelsAlignRight)}
92
- />
93
- }
94
- label="Tree labels align right?"
95
- />
96
- {!noTree ? (
97
- <div>
98
- <FormControlLabel2
99
- control={
100
- <Checkbox
101
- checked={treeWidthMatchesArea}
102
- onChange={() =>
103
- model.setTreeWidthMatchesArea(!treeWidthMatchesArea)
104
- }
105
- />
106
- }
107
- label="Make tree width fit to tree area?"
108
- />
109
- {!treeWidthMatchesArea ? (
110
- <div className={classes.flex}>
111
- <Typography>Tree width ({treeWidth}px)</Typography>
112
- <Slider
113
- className={classes.field}
114
- min={50}
115
- max={600}
116
- value={treeWidth}
117
- onChange={(_, val) => model.setTreeWidth(val as number)}
118
- />
119
- </div>
120
- ) : null}
121
- </div>
122
- ) : null}
123
- </div>
124
- <div>
125
- <h1>MSA options</h1>
126
-
127
- <FormControlLabel2
128
- control={
129
- <Checkbox
130
- checked={bgColor}
131
- onChange={() => model.setBgColor(!bgColor)}
132
- />
133
- }
134
- label="Color background tiles of MSA?"
135
- />
136
-
137
- <div className={classes.flex}>
138
- <Typography>Column width ({colWidth}px)</Typography>
139
- <Slider
140
- className={classes.field}
141
- min={1}
142
- max={50}
143
- value={colWidth}
144
- onChange={(_, val) => model.setColWidth(val as number)}
145
- />
146
- </div>
147
- <div className={classes.flex}>
148
- <Typography>Row height ({rowHeight}px)</Typography>
149
- <Slider
150
- className={classes.field}
151
- min={1}
152
- max={50}
153
- value={rowHeight}
154
- onChange={(_, val) => model.setRowHeight(val as number)}
96
+ <Checkbox2
97
+ checked={labelsAlignRight}
98
+ onChange={() => model.setLabelsAlignRight(!labelsAlignRight)}
99
+ label="Tree labels align right?"
100
+ />
101
+ {!noTree ? (
102
+ <div>
103
+ <Checkbox2
104
+ checked={treeWidthMatchesArea}
105
+ onChange={() =>
106
+ model.setTreeWidthMatchesArea(!treeWidthMatchesArea)
107
+ }
108
+ label="Make tree width fit to tree area?"
155
109
  />
110
+ {!treeWidthMatchesArea ? (
111
+ <div className={classes.flex}>
112
+ <Typography>Tree width ({treeWidth}px)</Typography>
113
+ <Slider
114
+ className={classes.field}
115
+ min={50}
116
+ max={600}
117
+ value={treeWidth}
118
+ onChange={(_, val) => model.setTreeWidth(val as number)}
119
+ />
120
+ </div>
121
+ ) : null}
156
122
  </div>
123
+ ) : null}
124
+ </div>
125
+ )
126
+ }
127
+
128
+ function MSASettings({ model }: { model: MsaViewModel }) {
129
+ const { classes } = useStyles()
130
+ const { bgColor, colWidth, colorSchemeName, rowHeight } = model
131
+
132
+ return (
133
+ <div>
134
+ <h1>MSA options</h1>
135
+
136
+ <Checkbox2
137
+ checked={bgColor}
138
+ onChange={() => model.setBgColor(!bgColor)}
139
+ label="Color background tiles of MSA?"
140
+ />
157
141
 
158
- <TextField
159
- select
160
- label="Color scheme"
161
- value={colorSchemeName}
162
- onChange={event => model.setColorSchemeName(event.target.value)}
163
- >
164
- {Object.keys(colorSchemes).map(option => (
165
- <MenuItem key={option} value={option}>
166
- {option}
167
- </MenuItem>
168
- ))}
169
- </TextField>
142
+ <div className={classes.flex}>
143
+ <Typography>Column width ({colWidth}px)</Typography>
144
+ <Slider
145
+ className={classes.field}
146
+ min={1}
147
+ max={50}
148
+ value={colWidth}
149
+ onChange={(_, val) => model.setColWidth(val as number)}
150
+ />
170
151
  </div>
171
- </>
152
+ <div className={classes.flex}>
153
+ <Typography>Row height ({rowHeight}px)</Typography>
154
+ <Slider
155
+ className={classes.field}
156
+ min={1}
157
+ max={50}
158
+ value={rowHeight}
159
+ onChange={(_, val) => model.setRowHeight(val as number)}
160
+ />
161
+ </div>
162
+
163
+ <TextField
164
+ select
165
+ label="Color scheme"
166
+ value={colorSchemeName}
167
+ onChange={event => model.setColorSchemeName(event.target.value)}
168
+ >
169
+ {Object.keys(colorSchemes).map(option => (
170
+ <MenuItem key={option} value={option}>
171
+ {option}
172
+ </MenuItem>
173
+ ))}
174
+ </TextField>
175
+ </div>
172
176
  )
173
- })
177
+ }
174
178
 
175
179
  const SettingsDialog = observer(function ({
176
180
  model,
@@ -1,6 +1,6 @@
1
1
  let canvasHandle: HTMLCanvasElement | undefined
2
2
 
3
- export default function measureTextCanvas(text: string, fontSize: number) {
3
+ export function measureTextCanvas(text: string, fontSize: number) {
4
4
  if (!canvasHandle) {
5
5
  canvasHandle = document.createElement('canvas')
6
6
  }
package/src/model.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import React from 'react'
2
2
  import { autorun } from 'mobx'
3
- import { Instance, cast, types, addDisposer, SnapshotIn } from 'mobx-state-tree'
3
+ import { Instance, cast, types, addDisposer } from 'mobx-state-tree'
4
4
  import { hierarchy, cluster, HierarchyNode } from 'd3-hierarchy'
5
5
  import { ascending } from 'd3-array'
6
6
  import Stockholm from 'stockholm-js'
7
7
  import { saveAs } from 'file-saver'
8
+ import { Theme } from '@mui/material'
9
+
8
10
  // jbrowse
9
11
  import { FileLocation, ElementId } from '@jbrowse/core/util/types/mst'
10
12
  import { FileLocation as FileLocationType } from '@jbrowse/core/util/types'
@@ -16,7 +18,6 @@ import BaseViewModel from '@jbrowse/core/pluggableElementTypes/models/BaseViewMo
16
18
  import {
17
19
  clamp,
18
20
  collapse,
19
- filterHiddenLeafNodes,
20
21
  generateNodeIds,
21
22
  maxLength,
22
23
  setBrLength,
@@ -24,20 +25,26 @@ import {
24
25
  NodeWithIds,
25
26
  NodeWithIdsAndLength,
26
27
  } from './util'
28
+
29
+ import { blocksX, blocksY } from './calculateBlocks'
30
+ import { measureTextCanvas } from './measureTextCanvas'
31
+
32
+ // components
27
33
  import TextTrack from './components/TextTrack'
28
34
  import BoxTrack from './components/BoxTrack'
35
+
36
+ // parsers
29
37
  import ClustalMSA from './parsers/ClustalMSA'
30
38
  import StockholmMSA from './parsers/StockholmMSA'
31
39
  import FastaMSA from './parsers/FastaMSA'
32
40
  import parseNewick from './parseNewick'
33
41
  import colorSchemes from './colorSchemes'
42
+
43
+ // models
34
44
  import { UniprotTrack } from './UniprotTrack'
35
- import { StructureModel } from './StructureModel'
45
+ import { DataModelF } from './DataModel'
36
46
  import { DialogQueueSessionMixin } from './DialogQueue'
37
- import { renderToSvg } from './renderToSvg'
38
- import { Theme } from '@mui/material'
39
- import { blocksX, blocksY } from './calculateBlocks'
40
- import measureTextCanvas from './measureTextCanvas'
47
+ import { SelectedStructuresMixin } from './SelectedStructuresMixin'
41
48
 
42
49
  export interface RowDetails {
43
50
  [key: string]: unknown
@@ -82,16 +89,30 @@ export interface IBoxTrack {
82
89
 
83
90
  export type BasicTrack = IBoxTrack | ITextTrack
84
91
 
85
- export type StructureSnap = SnapshotIn<typeof StructureModel>
86
-
87
92
  /**
88
93
  * #stateModel MsaView
89
94
  * extends
90
95
  * - BaseViewModel
91
96
  * - DialogQueueSessionMixin
97
+ * - SelectedStructuresMixin
92
98
  */
93
99
  function x() {} // eslint-disable-line @typescript-eslint/no-unused-vars
94
100
 
101
+ function reparseTree(tree: NodeWithIds): NodeWithIds {
102
+ return {
103
+ ...tree,
104
+ branchset: tree.branchset.map(r =>
105
+ r.branchset.length
106
+ ? reparseTree(r)
107
+ : {
108
+ branchset: [r],
109
+ id: `${r.id}-leafnode`,
110
+ name: `${r.name}-hidden`,
111
+ },
112
+ ),
113
+ }
114
+ }
115
+
95
116
  export type DialogComponentType =
96
117
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
97
118
  | React.LazyExoticComponent<React.FC<any>>
@@ -102,6 +123,7 @@ const model = types
102
123
  .compose(
103
124
  BaseViewModel,
104
125
  DialogQueueSessionMixin(),
126
+ SelectedStructuresMixin(),
105
127
  types.model('MsaView', {
106
128
  /**
107
129
  * #property
@@ -157,12 +179,6 @@ const model = types
157
179
  */
158
180
  scrollX: 0,
159
181
 
160
- /**
161
- * #property
162
- * currently "selected" structures, generally PDB 3-D protein structures
163
- */
164
- selectedStructures: types.array(StructureModel),
165
-
166
182
  /**
167
183
  * #property
168
184
  * right-align the labels
@@ -244,12 +260,7 @@ const model = types
244
260
  */
245
261
  collapsed: types.array(types.string),
246
262
 
247
- /**
248
- * #property
249
- * array of leaf nodes that are 'hidden', similar to collapsed but for leaf nodes
250
- */
251
- hidden: types.array(types.string),
252
-
263
+ collapsed2: types.array(types.string),
253
264
  /**
254
265
  * #property
255
266
  * focus on particular subtree
@@ -274,26 +285,7 @@ const model = types
274
285
  * data from the loaded tree/msa/treeMetadata, generally loaded by
275
286
  * autorun
276
287
  */
277
- data: types.optional(
278
- types
279
- .model({
280
- tree: types.maybe(types.string),
281
- msa: types.maybe(types.string),
282
- treeMetadata: types.maybe(types.string),
283
- })
284
- .actions(self => ({
285
- setTree(tree?: string) {
286
- self.tree = tree
287
- },
288
- setMSA(msa?: string) {
289
- self.msa = msa
290
- },
291
- setTreeMetadata(treeMetadata?: string) {
292
- self.treeMetadata = treeMetadata
293
- },
294
- })),
295
- { tree: '', msa: '' },
296
- ),
288
+ data: types.optional(DataModelF(), { tree: '', msa: '' }),
297
289
  }),
298
290
  )
299
291
  .volatile(() => ({
@@ -321,6 +313,18 @@ const model = types
321
313
  */
322
314
  mouseCol: undefined as number | undefined,
323
315
 
316
+ /**
317
+ * #volatile
318
+ * the currently mouse-click row
319
+ */
320
+ mouseClickRow: undefined as number | undefined,
321
+
322
+ /**
323
+ * #volatile
324
+ * the currently mouse-click column
325
+ */
326
+ mouseClickCol: undefined as number | undefined,
327
+
324
328
  /**
325
329
  * #volatile
326
330
  * a dummy variable that is incremented when ref changes so autorun for
@@ -333,6 +337,11 @@ const model = types
333
337
  */
334
338
  minimapHeight: 56,
335
339
 
340
+ /**
341
+ * #volatile
342
+ */
343
+ marginLeft: 20,
344
+
336
345
  /**
337
346
  * #volatile
338
347
  */
@@ -352,49 +361,6 @@ const model = types
352
361
  self.height = height
353
362
  },
354
363
 
355
- /**
356
- * #action
357
- * add to the selected structures
358
- */
359
- addStructureToSelection(elt: StructureSnap) {
360
- self.selectedStructures.push(elt)
361
- },
362
-
363
- /**
364
- * #action
365
- * remove from the selected structures
366
- */
367
- removeStructureFromSelection(elt: StructureSnap) {
368
- const r = self.selectedStructures.find(node => node.id === elt.id)
369
- if (r) {
370
- self.selectedStructures.remove(r)
371
- }
372
- },
373
-
374
- /**
375
- * #action
376
- * toggle a structure from the selected structures list
377
- */
378
- toggleStructureSelection(elt: {
379
- id: string
380
- structure: { startPos: number; endPos: number; pdb: string }
381
- }) {
382
- const r = self.selectedStructures.find(node => node.id === elt.id)
383
- if (r) {
384
- self.selectedStructures.remove(r)
385
- } else {
386
- self.selectedStructures.push(elt)
387
- }
388
- },
389
-
390
- /**
391
- * #action
392
- * clear all selected structures
393
- */
394
- clearSelectedStructures() {
395
- self.selectedStructures = cast([])
396
- },
397
-
398
364
  /**
399
365
  * #action
400
366
  * set error state
@@ -412,6 +378,15 @@ const model = types
412
378
  self.mouseRow = row
413
379
  },
414
380
 
381
+ /**
382
+ * #action
383
+ * set mouse click position (row, column) in the MSA
384
+ */
385
+ setMouseClickPos(col?: number, row?: number) {
386
+ self.mouseClickCol = col
387
+ self.mouseClickRow = row
388
+ },
389
+
415
390
  /**
416
391
  * #action
417
392
  * set row height (px)
@@ -488,20 +463,6 @@ const model = types
488
463
  self.drawTree = arg
489
464
  },
490
465
 
491
- /**
492
- * #action
493
- */
494
- hideNode(arg: string) {
495
- self.hidden.push(arg)
496
- },
497
-
498
- /**
499
- * #action
500
- */
501
- clearHidden() {
502
- self.hidden.clear()
503
- },
504
-
505
466
  /**
506
467
  * #action
507
468
  */
@@ -513,6 +474,16 @@ const model = types
513
474
  }
514
475
  },
515
476
 
477
+ /**
478
+ * #action
479
+ */
480
+ toggleCollapsed2(node: string) {
481
+ if (self.collapsed2.includes(node)) {
482
+ self.collapsed2.remove(node)
483
+ } else {
484
+ self.collapsed2.push(node)
485
+ }
486
+ },
516
487
  /**
517
488
  * #action
518
489
  */
@@ -675,7 +646,7 @@ const model = types
675
646
  * #getter
676
647
  */
677
648
  get _tree(): NodeWithIds {
678
- return self.data.tree
649
+ const ret = self.data.tree
679
650
  ? generateNodeIds(parseNewick(self.data.tree))
680
651
  : this.MSA?.getTree() || {
681
652
  noTree: true,
@@ -683,6 +654,7 @@ const model = types
683
654
  id: 'empty',
684
655
  name: 'empty',
685
656
  }
657
+ return reparseTree(ret)
686
658
  },
687
659
  /**
688
660
  * #getter
@@ -721,18 +693,13 @@ const model = types
721
693
  }
722
694
  }
723
695
 
724
- if (self.collapsed.length) {
725
- self.collapsed
696
+ if (self.collapsed.length || self.collapsed2.length) {
697
+ ;[...self.collapsed, ...self.collapsed2]
726
698
  .map(collapsedId => hier.find(node => node.data.id === collapsedId))
727
699
  .filter(notEmpty)
728
700
  .map(node => collapse(node))
729
701
  }
730
- if (self.hidden.length) {
731
- self.hidden
732
- .map(hiddenId => hier.find(node => node.data.id === hiddenId))
733
- .filter(notEmpty)
734
- .map(node => filterHiddenLeafNodes(node.parent, node.id))
735
- }
702
+
736
703
  return hier
737
704
  },
738
705
  /**
@@ -758,6 +725,13 @@ const model = types
758
725
  get msaAreaWidth() {
759
726
  return self.width - self.treeAreaWidth
760
727
  },
728
+
729
+ /**
730
+ * #getter
731
+ */
732
+ get treeAreaWidthMinusMargin() {
733
+ return self.treeAreaWidth - self.marginLeft
734
+ },
761
735
  /**
762
736
  * #getter
763
737
  */
@@ -1148,7 +1122,7 @@ const model = types
1148
1122
  relativePxToBp(rowName: string, position: number) {
1149
1123
  const { rowNames, rows } = self
1150
1124
  const index = rowNames.indexOf(rowName)
1151
- if (index !== -1) {
1125
+ if (index !== -1 && rows[index]) {
1152
1126
  const row = rows[index][1]
1153
1127
 
1154
1128
  let k = 0
@@ -1170,7 +1144,7 @@ const model = types
1170
1144
  relativePxToBp2(rowName: string, position: number) {
1171
1145
  const { rowNames, rows } = self
1172
1146
  const index = rowNames.indexOf(rowName)
1173
- if (index !== -1) {
1147
+ if (index !== -1 && rows[index]) {
1174
1148
  const row = rows[index][1]
1175
1149
 
1176
1150
  let k = 0
@@ -1219,6 +1193,7 @@ const model = types
1219
1193
  includeMinimap?: boolean
1220
1194
  exportType: string
1221
1195
  }) {
1196
+ const { renderToSvg } = await import('./renderToSvg')
1222
1197
  const html = await renderToSvg(self as MsaViewModel, opts)
1223
1198
  const blob = new Blob([html], { type: 'image/svg+xml' })
1224
1199
  saveAs(blob, 'image.svg')
@@ -1286,7 +1261,10 @@ const model = types
1286
1261
  autorun(async () => {
1287
1262
  if (self.treeWidthMatchesArea) {
1288
1263
  self.setTreeWidth(
1289
- Math.max(50, self.treeAreaWidth - self.labelsWidth - 10),
1264
+ Math.max(
1265
+ 50,
1266
+ self.treeAreaWidth - self.labelsWidth - 10 - self.marginLeft,
1267
+ ),
1290
1268
  )
1291
1269
  }
1292
1270
  }),
@@ -60,20 +60,6 @@ export default class ClustalMSA {
60
60
  }
61
61
 
62
62
  get tracks() {
63
- return this.seqConsensus?.trim()
64
- ? [
65
- {
66
- id: 'seqConsensus',
67
- name: 'Sequence consensus',
68
- data: this.seqConsensus,
69
- customColorScheme: {
70
- '*': 'white',
71
- ':': 'grey',
72
- '.': 'darkgrey',
73
- ' ': 'black',
74
- },
75
- },
76
- ]
77
- : []
63
+ return []
78
64
  }
79
65
  }
package/src/util.ts CHANGED
@@ -145,17 +145,6 @@ export function collapse(d: HierarchyNode<NodeWithIds>) {
145
145
  }
146
146
  }
147
147
 
148
- // Collapse the node and all it's children, from
149
- // https://bl.ocks.org/d3noob/43a860bc0024792f8803bba8ca0d5ecd
150
- export function filterHiddenLeafNodes(
151
- d: HierarchyNode<NodeWithIds> | null,
152
- hiddenId?: string,
153
- ) {
154
- if (d?.children) {
155
- d.children = d.children.filter(f => f.id !== hiddenId)
156
- }
157
- }
158
-
159
148
  export function clamp(min: number, num: number, max: number) {
160
149
  return Math.min(Math.max(num, min), max)
161
150
  }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '3.1.4'
1
+ export const version = '3.1.6'