react-msaview 8.4.0 → 9.0.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.
Files changed (87) hide show
  1. package/bundle/index.js +503 -89
  2. package/bundle/index.js.map +4 -4
  3. package/dist/components/MSAView.js +2 -2
  4. package/dist/components/MSAView.js.map +1 -1
  5. package/dist/components/MSAViewer.d.ts +1 -3
  6. package/dist/components/MSAViewer.js +1 -2
  7. package/dist/components/MSAViewer.js.map +1 -1
  8. package/dist/components/ResizeHandles.js +1 -1
  9. package/dist/components/ResizeHandles.js.map +1 -1
  10. package/dist/components/Track.js +1 -1
  11. package/dist/components/Track.js.map +1 -1
  12. package/dist/components/dialogs/ExportSVGDialog.js +2 -2
  13. package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
  14. package/dist/components/header/GoToBox.d.ts +332 -0
  15. package/dist/components/header/GoToBox.js +14 -4
  16. package/dist/components/header/GoToBox.js.map +1 -1
  17. package/dist/components/header/settingsMenuItems.js +4 -1
  18. package/dist/components/header/settingsMenuItems.js.map +1 -1
  19. package/dist/components/tree/CladeLabels.js +3 -3
  20. package/dist/components/tree/CladeLabels.js.map +1 -1
  21. package/dist/components/tree/TreeCanvas.js +4 -4
  22. package/dist/components/tree/TreeCanvas.js.map +1 -1
  23. package/dist/components/tree/TreeCanvasBlock.js +4 -4
  24. package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
  25. package/dist/components/tree/TreeOverview.js +10 -5
  26. package/dist/components/tree/TreeOverview.js.map +1 -1
  27. package/dist/components/tree/TreePanel.js +6 -2
  28. package/dist/components/tree/TreePanel.js.map +1 -1
  29. package/dist/components/tree/TreeRuler.js +2 -2
  30. package/dist/components/tree/TreeRuler.js.map +1 -1
  31. package/dist/components/tree/cladeBrackets.d.ts +8 -10
  32. package/dist/components/tree/cladeBrackets.js +7 -6
  33. package/dist/components/tree/cladeBrackets.js.map +1 -1
  34. package/dist/components/tree/clickMap.d.ts +2 -0
  35. package/dist/components/tree/clickMap.js.map +1 -1
  36. package/dist/components/tree/ellipsize.d.ts +8 -0
  37. package/dist/components/tree/ellipsize.js +20 -0
  38. package/dist/components/tree/ellipsize.js.map +1 -0
  39. package/dist/components/tree/renderTreeCanvas.js +30 -26
  40. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  41. package/dist/components/tree/renderTreeMouseover.js +1 -1
  42. package/dist/components/tree/renderTreeMouseover.js.map +1 -1
  43. package/dist/constants.d.ts +6 -3
  44. package/dist/constants.js +16 -6
  45. package/dist/constants.js.map +1 -1
  46. package/dist/measureTextCanvas.js +2 -2
  47. package/dist/measureTextCanvas.js.map +1 -1
  48. package/dist/model/treeModel.d.ts +14 -20
  49. package/dist/model/treeModel.js +16 -23
  50. package/dist/model/treeModel.js.map +1 -1
  51. package/dist/model.d.ts +192 -213
  52. package/dist/model.js +112 -104
  53. package/dist/model.js.map +1 -1
  54. package/dist/renderToSvg.js +24 -22
  55. package/dist/renderToSvg.js.map +1 -1
  56. package/dist/svgTestUtil.d.ts +252 -356
  57. package/dist/tipLabels.d.ts +8 -0
  58. package/dist/tipLabels.js +46 -0
  59. package/dist/tipLabels.js.map +1 -0
  60. package/dist/version.d.ts +1 -1
  61. package/dist/version.js +1 -1
  62. package/package.json +6 -6
  63. package/src/components/MSAView.tsx +2 -2
  64. package/src/components/MSAViewer.tsx +1 -5
  65. package/src/components/ResizeHandles.tsx +1 -1
  66. package/src/components/Track.tsx +1 -1
  67. package/src/components/dialogs/ExportSVGDialog.tsx +2 -2
  68. package/src/components/header/GoToBox.tsx +18 -4
  69. package/src/components/header/settingsMenuItems.ts +8 -0
  70. package/src/components/tree/CladeLabels.tsx +3 -3
  71. package/src/components/tree/TreeCanvas.tsx +10 -4
  72. package/src/components/tree/TreeCanvasBlock.tsx +4 -4
  73. package/src/components/tree/TreeOverview.tsx +10 -5
  74. package/src/components/tree/TreePanel.tsx +8 -2
  75. package/src/components/tree/TreeRuler.tsx +7 -3
  76. package/src/components/tree/cladeBrackets.ts +10 -17
  77. package/src/components/tree/clickMap.ts +2 -0
  78. package/src/components/tree/ellipsize.ts +24 -0
  79. package/src/components/tree/renderTreeCanvas.ts +42 -30
  80. package/src/components/tree/renderTreeMouseover.ts +1 -1
  81. package/src/constants.ts +17 -6
  82. package/src/measureTextCanvas.ts +2 -2
  83. package/src/model/treeModel.ts +17 -27
  84. package/src/model.ts +133 -128
  85. package/src/renderToSvg.tsx +24 -22
  86. package/src/tipLabels.ts +51 -0
  87. package/src/version.ts +1 -1
package/dist/model.js CHANGED
@@ -15,7 +15,7 @@ import { visibleColRange } from './components/msa/visibleColRange.js';
15
15
  import TrackBlocks from './components/tracks/TrackBlocks.js';
16
16
  import { cladeGutterWidth } from './components/tree/cladeBrackets.js';
17
17
  import { scaleBarLength } from './components/tree/scaleBar.js';
18
- import { cladeHighlightAlpha, cladeHighlightColor, defaultAllowedGappyness, defaultColWidth, defaultColorSchemeName, defaultCurrentAlignment, defaultDrawMsaLetters, defaultFeaturePanelWidth, defaultHeight, defaultHideGaps, defaultRowHeight, defaultScrollX, defaultScrollY, defaultScrollZoom, defaultScrollZoomAxis, defaultShowDomainLegend, defaultShowDomains, defaultSubFeatureRows, defaultTreeWidth, labelReferenceFontSize, maxCellSize, maxInlineSnapshotBytes as defaultMaxInlineSnapshotBytes, maxNeighborJoiningRows, minColWidth, minLetterColWidth, minLetterRowHeight, minRowHeight, rowPanelHeaderHeight, rowTintAlpha, scrollZoomAxes, segmentFeatureTypes, segmentShades, treeScaleBarHeight, } from './constants.js';
18
+ import { cladeHighlightAlpha, cladeHighlightColor, defaultAllowedGappyness, defaultColWidth, defaultColorSchemeName, defaultCurrentAlignment, defaultDrawMsaLetters, defaultFeaturePanelWidth, defaultHeight, defaultHideGaps, defaultRowHeight, defaultScrollX, defaultScrollY, defaultScrollZoom, defaultScrollZoomAxis, defaultShowDomainLegend, defaultShowDomains, defaultSubFeatureRows, fontSizeFor, labelFitFontSize, maxCellSize, maxFitTreeWidth, maxTreeAreaShare, maxInlineSnapshotBytes as defaultMaxInlineSnapshotBytes, maxNeighborJoiningRows, minColWidth, minLetterColWidth, minLetterRowHeight, minRowHeight, minTreeWidth, pxPerTreeDepth, rowPanelHeaderHeight, rowTintAlpha, scrollZoomAxes, segmentFeatureTypes, segmentShades, treeScaleBarHeight, } from './constants.js';
19
19
  import { createPaletteMap } from './createPaletteMap.js';
20
20
  import { exportFileName } from './exportFileName.js';
21
21
  import { featureField, featureName } from './featureFields.js';
@@ -23,7 +23,6 @@ import { featuresToAnnotations } from './featuresLayer.js';
23
23
  import { fetchTextWithProgress, isAbortError } from './fetchUtils.js';
24
24
  import { flatToTree } from './flatToTree.js';
25
25
  import { calcDepthToLeaf, clusterLayout, collapse, find, forEachDescendant, hierarchy, layoutTree, leafIndex, leaves, maxLength, mrca, nodeCoveringRows, setBrLength, sort, sum as hierarchySum, } from './hierarchy.js';
26
- import { measureTextCanvas } from './measureTextCanvas.js';
27
26
  import { DataModelF } from './model/DataModel.js';
28
27
  import { DialogQueueSessionMixin } from './model/DialogQueue.js';
29
28
  import { MSAModelF } from './model/msaModel.js';
@@ -37,6 +36,7 @@ import { resolveScale } from './scales.js';
37
36
  import { buildSeqPosIndex } from './seqPosToGlobalCol.js';
38
37
  import { maxBitsFor } from './sequenceLogo.js';
39
38
  import { stripDefault } from './stripDefault.js';
39
+ import { treeTips, widestLabel } from './tipLabels.js';
40
40
  import { computeRowInsertions, dropBlanks, len, outlineColor, skipBlanks, withAlpha, } from './util.js';
41
41
  import { saveAs } from './vendor/fileSaver.js';
42
42
  import { writeNewick } from './writeNewick.js';
@@ -303,7 +303,6 @@ export const preservedOnReset = new Set([
303
303
  'drawNodeLabels',
304
304
  'showTreeOverview',
305
305
  'overviewHeight',
306
- 'autoTreeAreaWidth',
307
306
  'turnedOffTracks',
308
307
  'trackHeights',
309
308
  'hideGaps',
@@ -1224,25 +1223,25 @@ function stateModelFactory({ maxInlineSnapshotBytes = defaultMaxInlineSnapshotBy
1224
1223
  * #action
1225
1224
  */
1226
1225
  setMSAFilehandle(msaFilehandle) {
1227
- self.msaFilehandle = msaFilehandle;
1226
+ self.msaFilehandle = cast(msaFilehandle);
1228
1227
  },
1229
1228
  /**
1230
1229
  * #action
1231
1230
  */
1232
1231
  setTreeFilehandle(treeFilehandle) {
1233
- self.treeFilehandle = treeFilehandle;
1232
+ self.treeFilehandle = cast(treeFilehandle);
1234
1233
  },
1235
1234
  /**
1236
1235
  * #action
1237
1236
  */
1238
1237
  setTreeMetadataFilehandle(treeMetadataFilehandle) {
1239
- self.treeMetadataFilehandle = treeMetadataFilehandle;
1238
+ self.treeMetadataFilehandle = cast(treeMetadataFilehandle);
1240
1239
  },
1241
1240
  /**
1242
1241
  * #action
1243
1242
  */
1244
1243
  setGFFFilehandle(gffFilehandle) {
1245
- self.gffFilehandle = gffFilehandle;
1244
+ self.gffFilehandle = cast(gffFilehandle);
1246
1245
  },
1247
1246
  /**
1248
1247
  * #action
@@ -1420,10 +1419,10 @@ function stateModelFactory({ maxInlineSnapshotBytes = defaultMaxInlineSnapshotBy
1420
1419
  * the row table: extra fields per row, keyed by row name, which the
1421
1420
  * `encodings` channels read. It is stored as the JSON string
1422
1421
  * `data.treeMetadata`, the name that travels in existing links, so the
1423
- * inline size limit and `treeMetadataFilehandle` cover it. labelWidthMap
1424
- * reads it on every layout, so a malformed user-supplied file returns {}
1425
- * instead of throwing out of rendering, and every field is a string by
1426
- * the time a scale sorts it.
1422
+ * inline size limit and `treeMetadataFilehandle` cover it. The tree area
1423
+ * fit reads it on every layout, so a malformed user-supplied file
1424
+ * returns {} instead of throwing out of rendering, and every field is a
1425
+ * string by the time a scale sorts it.
1427
1426
  */
1428
1427
  get rowData() {
1429
1428
  const text = self.data.treeMetadata;
@@ -1544,11 +1543,93 @@ function stateModelFactory({ maxInlineSnapshotBytes = defaultMaxInlineSnapshotBy
1544
1543
  * where no clade draws a bar or a label.
1545
1544
  */
1546
1545
  get cladeGutterWidth() {
1547
- return cladeGutterWidth({
1548
- clades: this.resolvedClades,
1549
- rowHeight: self.rowHeight,
1550
- fontSize: this.fontSize,
1551
- });
1546
+ return cladeGutterWidth(self.clades);
1547
+ },
1548
+ /**
1549
+ * #getter
1550
+ * whether a tree draws beside the labels: false for a file with no
1551
+ * tree, and with drawTree off
1552
+ */
1553
+ get treeDrawn() {
1554
+ return self.drawTree && !this.noTree;
1555
+ },
1556
+ /**
1557
+ * #getter
1558
+ * the leaf names of the whole tree and its depth in levels. The fit
1559
+ * reads these, so a collapse or a focus leaves the tree area as it is
1560
+ */
1561
+ get treeTips() {
1562
+ return treeTips(this.tree);
1563
+ },
1564
+ /**
1565
+ * #getter
1566
+ * the widest tip label at labelFitFontSize, measured whether or not a
1567
+ * zoom hides the labels
1568
+ */
1569
+ get maxTipLabelWidth() {
1570
+ return widestLabel(this.treeTips.names.map(name => this.rowDataOf(name)?.genome || name), labelFitFontSize);
1571
+ },
1572
+ /**
1573
+ * #getter
1574
+ * the px the tip labels take across the tree area: the widest label at
1575
+ * labelFitFontSize and the gaps either side of it, or 0 with drawLabels
1576
+ * off
1577
+ */
1578
+ get labelColumnWidth() {
1579
+ return self.drawLabels
1580
+ ? this.maxTipLabelWidth + (this.treeDrawn ? 10 : 6)
1581
+ : 0;
1582
+ },
1583
+ /**
1584
+ * #getter
1585
+ * the tree area width while treeAreaWidth is undefined: the label column
1586
+ * beside a tree that widens with its depth, up to maxTreeAreaShare of the
1587
+ * view, or the room the row panels leave where there is no alignment.
1588
+ * Where that binds, the tree keeps minTreeWidth and the renderer
1589
+ * ellipsizes the labels
1590
+ */
1591
+ get fittedTreeAreaWidth() {
1592
+ const chrome = self.marginLeft + this.cladeGutterWidth;
1593
+ const tree = this.treeDrawn
1594
+ ? (self.treeWidth ??
1595
+ clamp(this.treeTips.depth * pxPerTreeDepth, minTreeWidth, maxFitTreeWidth))
1596
+ : 0;
1597
+ const fit = chrome + tree + this.labelColumnWidth;
1598
+ const room = self.viewInitialized
1599
+ ? this.numColumns > 0
1600
+ ? self.width * maxTreeAreaShare
1601
+ : self.width - this.rowPanelsWidth - self.resizeHandleWidth
1602
+ : Infinity;
1603
+ const cap = Math.max(room, chrome + Math.min(tree, minTreeWidth));
1604
+ return Math.ceil(Math.min(fit, cap));
1605
+ },
1606
+ /**
1607
+ * #getter
1608
+ * the width of the area the tree and its labels draw in, px:
1609
+ * treeAreaWidth where set, the fit otherwise
1610
+ */
1611
+ get effectiveTreeAreaWidth() {
1612
+ return self.treeAreaWidth ?? this.fittedTreeAreaWidth;
1613
+ },
1614
+ /**
1615
+ * #getter
1616
+ * the width of the tree, px: treeWidth where set, otherwise the tree
1617
+ * area less the label column, which a zoom hiding the labels gives to
1618
+ * the tree
1619
+ */
1620
+ get effectiveTreeWidth() {
1621
+ const labels = this.showTreeText ? this.labelColumnWidth : 0;
1622
+ return (self.treeWidth ??
1623
+ Math.max(minTreeWidth, Math.floor(this.effectiveTreeAreaWidth -
1624
+ self.marginLeft -
1625
+ this.cladeGutterWidth -
1626
+ labels)));
1627
+ },
1628
+ /**
1629
+ * #getter
1630
+ */
1631
+ get showTreeText() {
1632
+ return self.drawLabels && self.rowHeight >= minLetterRowHeight;
1552
1633
  },
1553
1634
  /**
1554
1635
  * #getter
@@ -1714,7 +1795,7 @@ function stateModelFactory({ maxInlineSnapshotBytes = defaultMaxInlineSnapshotBy
1714
1795
  */
1715
1796
  get msaAreaWidth() {
1716
1797
  return (self.width -
1717
- self.treeAreaWidth -
1798
+ this.effectiveTreeAreaWidth -
1718
1799
  this.rowPanelsWidth -
1719
1800
  self.resizeHandleWidth);
1720
1801
  },
@@ -1724,7 +1805,7 @@ function stateModelFactory({ maxInlineSnapshotBytes = defaultMaxInlineSnapshotBy
1724
1805
  * margin and the bracket gutter
1725
1806
  */
1726
1807
  get treeAreaWidthMinusMargin() {
1727
- return self.treeAreaWidth - self.marginLeft - this.cladeGutterWidth;
1808
+ return (this.effectiveTreeAreaWidth - self.marginLeft - this.cladeGutterWidth);
1728
1809
  },
1729
1810
  /**
1730
1811
  * #getter
@@ -1860,7 +1941,7 @@ function stateModelFactory({ maxInlineSnapshotBytes = defaultMaxInlineSnapshotBy
1860
1941
  * #getter
1861
1942
  */
1862
1943
  get fontSize() {
1863
- return Math.min(Math.max(6, self.rowHeight - 3), 18);
1944
+ return fontSizeFor(self.rowHeight);
1864
1945
  },
1865
1946
  /**
1866
1947
  * #getter
@@ -1959,17 +2040,18 @@ function stateModelFactory({ maxInlineSnapshotBytes = defaultMaxInlineSnapshotBy
1959
2040
  /**
1960
2041
  * #getter
1961
2042
  * `root` laid out on new nodes in row and branch-length units, read in
1962
- * pixels through `rowHeight` and `treeWidth`. A zoom leaves it and every
1963
- * node in it as they are, and an observer reading a node's `x` or `len`
1964
- * observes the size it scales by.
2043
+ * pixels through `rowHeight` and `effectiveTreeWidth`. A zoom leaves it
2044
+ * and every node in it as they are, and an observer reading a node's `x`
2045
+ * or `len` observes the size it scales by.
1965
2046
  */
1966
2047
  get treeLayout() {
2048
+ const treeWidth = () => this.effectiveTreeWidth;
1967
2049
  return layoutTree(this.root, {
1968
2050
  get rowHeight() {
1969
2051
  return self.rowHeight;
1970
2052
  },
1971
2053
  get treeWidth() {
1972
- return self.treeWidth;
2054
+ return treeWidth();
1973
2055
  },
1974
2056
  });
1975
2057
  },
@@ -2002,11 +2084,11 @@ function stateModelFactory({ maxInlineSnapshotBytes = defaultMaxInlineSnapshotBy
2002
2084
  },
2003
2085
  /**
2004
2086
  * #getter
2005
- * x-position of the farthest tip in a phylogram, px: treeWidth, or 0 for
2006
- * a tree with no branch lengths (drawn as a cladogram)
2087
+ * x-position of the farthest tip in a phylogram, px: effectiveTreeWidth,
2088
+ * or 0 for a tree with no branch lengths (drawn as a cladogram)
2007
2089
  */
2008
2090
  get maxBranchLength() {
2009
- return this.rootToTipLength ? self.treeWidth : 0;
2091
+ return this.rootToTipLength ? this.effectiveTreeWidth : 0;
2010
2092
  },
2011
2093
  /**
2012
2094
  * #getter
@@ -2015,7 +2097,9 @@ function stateModelFactory({ maxInlineSnapshotBytes = defaultMaxInlineSnapshotBy
2015
2097
  */
2016
2098
  get pxPerBranchLength() {
2017
2099
  const max = this.rootToTipLength;
2018
- return this.showBranchLenEffective && max ? self.treeWidth / max : 0;
2100
+ return this.showBranchLenEffective && max
2101
+ ? this.effectiveTreeWidth / max
2102
+ : 0;
2019
2103
  },
2020
2104
  /**
2021
2105
  * #getter
@@ -2056,12 +2140,6 @@ function stateModelFactory({ maxInlineSnapshotBytes = defaultMaxInlineSnapshotBy
2056
2140
  self.colWidth >= minLetterColWidth &&
2057
2141
  self.colWidth > self.rowHeight / 2);
2058
2142
  },
2059
- /**
2060
- * #getter
2061
- */
2062
- get showTreeText() {
2063
- return self.drawLabels && self.rowHeight >= minLetterRowHeight;
2064
- },
2065
2143
  }))
2066
2144
  .views(self => {
2067
2145
  // a spec is a frozen value, so it keys its computed until setColumnTracks
@@ -2183,48 +2261,6 @@ function stateModelFactory({ maxInlineSnapshotBytes = defaultMaxInlineSnapshotBy
2183
2261
  };
2184
2262
  })
2185
2263
  .views(self => ({
2186
- /**
2187
- * #getter
2188
- */
2189
- get labelWidthMap() {
2190
- const { showTreeText, leaves } = self;
2191
- // gated on the renderer's label condition, so hidden labels reserve no
2192
- // gutter. Measured once at a reference size and scaled by
2193
- // labelWidthScale: re-measuring per vertical-zoom frame cost ~200ms on a
2194
- // 50k-leaf tree
2195
- return showTreeText
2196
- ? new Map(leaves.map(node => {
2197
- const { name } = node.data;
2198
- // `||`, matching renderTreeLabels: an empty genome falls back
2199
- // to the row name
2200
- const displayName = self.rowDataOf(name)?.genome || name;
2201
- return [
2202
- name,
2203
- measureTextCanvas(displayName, labelReferenceFontSize),
2204
- ];
2205
- }))
2206
- : new Map();
2207
- },
2208
- /**
2209
- * #getter
2210
- * factor turning a labelWidthMap entry into its width at the current
2211
- * font size
2212
- */
2213
- get labelWidthScale() {
2214
- return self.fontSize / labelReferenceFontSize;
2215
- },
2216
- get labelsWidth() {
2217
- // a loop, not Math.max(...): spreading passes one argument per leaf,
2218
- // and the ~125k argument limit throws RangeError on the 230k-tip COVID
2219
- // tree
2220
- let max = 0;
2221
- for (const width of this.labelWidthMap.values()) {
2222
- if (width > max) {
2223
- max = width;
2224
- }
2225
- }
2226
- return max * this.labelWidthScale;
2227
- },
2228
2264
  /**
2229
2265
  * #getter
2230
2266
  */
@@ -2663,7 +2699,7 @@ function stateModelFactory({ maxInlineSnapshotBytes = defaultMaxInlineSnapshotBy
2663
2699
  * or when the tree area is too narrow for one
2664
2700
  */
2665
2701
  get treeScaleBar() {
2666
- return scaleBarLength(self.pxPerBranchLength, self.treeAreaWidth - self.marginLeft * 2);
2702
+ return scaleBarLength(self.pxPerBranchLength, self.effectiveTreeAreaWidth - self.marginLeft * 2);
2667
2703
  },
2668
2704
  /**
2669
2705
  * #getter
@@ -4166,34 +4202,6 @@ function stateModelFactory({ maxInlineSnapshotBytes = defaultMaxInlineSnapshotBy
4166
4202
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
4167
4203
  self.columns;
4168
4204
  }));
4169
- // with autoTreeAreaWidth and no tree drawn, size the tree area to the
4170
- // labels. Gated on noTree/!drawTree so it does not loop with the
4171
- // treeWidth autorun below
4172
- addDisposer(self, autorun(() => {
4173
- if (self.autoTreeAreaWidth &&
4174
- (self.noTree || !self.drawTree) &&
4175
- self.labelsWidth) {
4176
- self.setTreeAreaWidth(self.labelsWidth + self.marginLeft + 12 + self.cladeGutterWidth);
4177
- }
4178
- }));
4179
- // treeWidth follows the tree area less the labels. A non-default
4180
- // snapshot treeWidth (jbrowse-plugin-msaview opens at 100 in a 200px
4181
- // area) is kept until the tree area changes. Not a getter, because
4182
- // labelsWidth is measured off leaves laid out against treeWidth.
4183
- let pinnedAreaWidth = self.treeWidth === defaultTreeWidth ? undefined : self.treeAreaWidth;
4184
- addDisposer(self, autorun(() => {
4185
- const areaWidth = self.treeAreaWidth;
4186
- const labelsWidth = self.labelsWidth;
4187
- if (pinnedAreaWidth === areaWidth) {
4188
- return;
4189
- }
4190
- pinnedAreaWidth = undefined;
4191
- self.setTreeWidth(Math.max(50, areaWidth -
4192
- labelsWidth -
4193
- 10 -
4194
- self.marginLeft -
4195
- self.cladeGutterWidth));
4196
- }));
4197
4205
  },
4198
4206
  }))
4199
4207
  .postProcessSnapshot(({ data, columnTracks, ...rest }) => ({