@jbrowse/plugin-linear-genome-view 5.0.0-beta.2 → 5.0.0-beta.20

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 (177) hide show
  1. package/esm/LinearGenomeView/afterAttach.d.ts +22 -5
  2. package/esm/LinearGenomeView/afterAttach.js +129 -106
  3. package/esm/LinearGenomeView/axisConfigSchema.d.ts +18 -0
  4. package/esm/LinearGenomeView/axisConfigSchema.js +22 -0
  5. package/esm/LinearGenomeView/components/CenterLine.js +10 -5
  6. package/esm/LinearGenomeView/components/ConnectedHoverHighlight.js +2 -3
  7. package/esm/LinearGenomeView/components/CrisprGuidePanel.js +3 -5
  8. package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +9 -4
  9. package/esm/LinearGenomeView/components/ExportSvgDialog.js +45 -8
  10. package/esm/LinearGenomeView/components/GetSequenceDialog.js +2 -2
  11. package/esm/LinearGenomeView/components/Header.js +11 -1
  12. package/esm/LinearGenomeView/components/HeaderClearHighlightButton.js +2 -2
  13. package/esm/LinearGenomeView/components/HeaderPanControls.d.ts +3 -3
  14. package/esm/LinearGenomeView/components/HeaderPanControls.js +6 -3
  15. package/esm/LinearGenomeView/components/HeaderSearchBoxes.js +4 -1
  16. package/esm/LinearGenomeView/components/HeaderZoomControls.js +6 -35
  17. package/esm/LinearGenomeView/components/Highlight.js +27 -11
  18. package/esm/LinearGenomeView/components/HighlightBand.d.ts +11 -2
  19. package/esm/LinearGenomeView/components/HighlightBand.js +32 -13
  20. package/esm/LinearGenomeView/components/HighlightChip.d.ts +3 -3
  21. package/esm/LinearGenomeView/components/HighlightChip.js +13 -8
  22. package/esm/LinearGenomeView/components/HighlightLabelDialog.d.ts +6 -0
  23. package/esm/LinearGenomeView/components/HighlightLabelDialog.js +18 -0
  24. package/esm/LinearGenomeView/components/HoverPositionHighlight.js +3 -3
  25. package/esm/LinearGenomeView/components/ImportForm.js +7 -9
  26. package/esm/LinearGenomeView/components/LinearGenomeView.js +5 -12
  27. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +13 -14
  28. package/esm/LinearGenomeView/components/MiniControls.js +11 -5
  29. package/esm/LinearGenomeView/components/OverviewHighlight.js +3 -3
  30. package/esm/LinearGenomeView/components/OverviewHighlightBand.d.ts +3 -2
  31. package/esm/LinearGenomeView/components/OverviewHighlightBand.js +6 -5
  32. package/esm/LinearGenomeView/components/OverviewRubberband.js +25 -48
  33. package/esm/LinearGenomeView/components/OverviewScalebar.js +4 -5
  34. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +5 -3
  35. package/esm/LinearGenomeView/components/PaddingBlocks.js +3 -8
  36. package/esm/LinearGenomeView/components/RangeSelectOverlay.js +5 -6
  37. package/esm/LinearGenomeView/components/RegionWidthEditorDialog.d.ts +3 -2
  38. package/esm/LinearGenomeView/components/RegionWidthEditorDialog.js +4 -4
  39. package/esm/LinearGenomeView/components/ResizeAllTracksHandle.d.ts +5 -0
  40. package/esm/LinearGenomeView/components/ResizeAllTracksHandle.js +74 -0
  41. package/esm/LinearGenomeView/components/Rubberband.d.ts +1 -2
  42. package/esm/LinearGenomeView/components/Rubberband.js +3 -2
  43. package/esm/LinearGenomeView/components/SVGHighlightBand.d.ts +10 -1
  44. package/esm/LinearGenomeView/components/SVGHighlightBand.js +16 -5
  45. package/esm/LinearGenomeView/components/Scalebar.d.ts +2 -6
  46. package/esm/LinearGenomeView/components/Scalebar.js +8 -5
  47. package/esm/LinearGenomeView/components/ScalebarRefNameLabels.js +51 -36
  48. package/esm/LinearGenomeView/components/SearchBox.js +10 -16
  49. package/esm/LinearGenomeView/components/SearchPanelForm.d.ts +3 -2
  50. package/esm/LinearGenomeView/components/SearchPanelForm.js +4 -2
  51. package/esm/LinearGenomeView/components/SearchResultsDialog.d.ts +4 -8
  52. package/esm/LinearGenomeView/components/SearchResultsDialog.js +7 -4
  53. package/esm/LinearGenomeView/components/SearchResultsTable.d.ts +4 -7
  54. package/esm/LinearGenomeView/components/SearchResultsTable.js +25 -53
  55. package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlight.js +2 -3
  56. package/esm/LinearGenomeView/components/SequenceSearchDialog.d.ts +2 -4
  57. package/esm/LinearGenomeView/components/StrandCheckboxes.d.ts +3 -2
  58. package/esm/LinearGenomeView/components/StrandCheckboxes.js +4 -2
  59. package/esm/LinearGenomeView/components/TrackContainer.d.ts +2 -3
  60. package/esm/LinearGenomeView/components/TrackContainer.js +63 -10
  61. package/esm/LinearGenomeView/components/TrackLabel.js +14 -4
  62. package/esm/LinearGenomeView/components/TrackLabelButtons.js +2 -2
  63. package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +4 -5
  64. package/esm/LinearGenomeView/components/TrackLabelMenu.js +11 -14
  65. package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.d.ts +3 -4
  66. package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.js +23 -10
  67. package/esm/LinearGenomeView/components/TrackRenderingContainer.d.ts +6 -4
  68. package/esm/LinearGenomeView/components/TrackRenderingContainer.js +12 -24
  69. package/esm/LinearGenomeView/components/TracksContainer.js +11 -23
  70. package/esm/LinearGenomeView/components/VerticalGuide.d.ts +1 -2
  71. package/esm/LinearGenomeView/components/VerticalGuide.js +3 -16
  72. package/esm/LinearGenomeView/components/fetchSequence.d.ts +1 -2
  73. package/esm/LinearGenomeView/components/fetchSequence.js +15 -7
  74. package/esm/LinearGenomeView/components/recentLocationsMenu.js +10 -0
  75. package/esm/LinearGenomeView/components/useRangeSelect.d.ts +0 -3
  76. package/esm/LinearGenomeView/components/useRangeSelect.js +26 -61
  77. package/esm/LinearGenomeView/components/useSearchBoxPrefs.d.ts +3 -1
  78. package/esm/LinearGenomeView/components/useSearchBoxPrefs.js +4 -2
  79. package/esm/LinearGenomeView/components/useSideScroll.d.ts +17 -2
  80. package/esm/LinearGenomeView/components/useSideScroll.js +156 -102
  81. package/esm/LinearGenomeView/components/util.d.ts +4 -0
  82. package/esm/LinearGenomeView/components/util.js +4 -2
  83. package/esm/LinearGenomeView/consts.d.ts +2 -0
  84. package/esm/LinearGenomeView/consts.js +3 -1
  85. package/esm/LinearGenomeView/containingLgv.d.ts +21 -0
  86. package/esm/LinearGenomeView/containingLgv.js +23 -0
  87. package/esm/LinearGenomeView/headerFit.d.ts +4 -2
  88. package/esm/LinearGenomeView/headerFit.js +20 -7
  89. package/esm/LinearGenomeView/index.d.ts +2 -7
  90. package/esm/LinearGenomeView/index.js +5 -7
  91. package/esm/LinearGenomeView/keyboardHandler.d.ts +8 -7
  92. package/esm/LinearGenomeView/keyboardHandler.js +61 -23
  93. package/esm/LinearGenomeView/launchKeys.d.ts +1 -1
  94. package/esm/LinearGenomeView/launchKeys.js +11 -6
  95. package/esm/LinearGenomeView/lazyDialogs.d.ts +16 -3
  96. package/esm/LinearGenomeView/lazyDialogs.js +1 -0
  97. package/esm/LinearGenomeView/linkedViewSync.d.ts +3 -11
  98. package/esm/LinearGenomeView/linkedViewSync.js +27 -49
  99. package/esm/LinearGenomeView/menuItems.d.ts +16 -18
  100. package/esm/LinearGenomeView/menuItems.js +264 -164
  101. package/esm/LinearGenomeView/model.d.ts +1192 -560
  102. package/esm/LinearGenomeView/model.js +805 -590
  103. package/esm/LinearGenomeView/rExport/exportLinearView.d.ts +17 -0
  104. package/esm/LinearGenomeView/rExport/exportLinearView.js +117 -0
  105. package/esm/LinearGenomeView/rExport/rScript.d.ts +110 -0
  106. package/esm/LinearGenomeView/rExport/rScript.js +524 -0
  107. package/esm/LinearGenomeView/sharedScaleContainer.d.ts +1 -1
  108. package/esm/LinearGenomeView/sharedScaleContainer.js +2 -12
  109. package/esm/LinearGenomeView/showFiles.d.ts +2 -0
  110. package/esm/LinearGenomeView/showFiles.js +19 -0
  111. package/esm/LinearGenomeView/showRegionsWithUndo.d.ts +1 -1
  112. package/esm/LinearGenomeView/showRegionsWithUndo.js +13 -5
  113. package/esm/LinearGenomeView/stickyChrome.d.ts +5 -9
  114. package/esm/LinearGenomeView/stickyChrome.js +5 -9
  115. package/esm/LinearGenomeView/svgcomponents/SVGGridlines.js +4 -4
  116. package/esm/LinearGenomeView/svgcomponents/SVGHeader.d.ts +4 -1
  117. package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +8 -21
  118. package/esm/LinearGenomeView/svgcomponents/SVGHighlights.d.ts +3 -1
  119. package/esm/LinearGenomeView/svgcomponents/SVGHighlights.js +9 -9
  120. package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.d.ts +3 -1
  121. package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.js +5 -5
  122. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +13 -18
  123. package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +2 -5
  124. package/esm/LinearGenomeView/svgcomponents/SVGRowHeader.js +5 -6
  125. package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +9 -10
  126. package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js +3 -3
  127. package/esm/LinearGenomeView/svgcomponents/SVGStackedRow.d.ts +26 -0
  128. package/esm/LinearGenomeView/svgcomponents/SVGStackedRow.js +12 -0
  129. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +21 -13
  130. package/esm/LinearGenomeView/svgcomponents/SVGTracks.d.ts +4 -5
  131. package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +7 -6
  132. package/esm/LinearGenomeView/svgcomponents/SVGView.d.ts +2 -3
  133. package/esm/LinearGenomeView/svgcomponents/SVGView.js +17 -3
  134. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.d.ts +24 -20
  135. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.js +42 -29
  136. package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.js +74 -77
  137. package/esm/LinearGenomeView/svgcomponents/util.d.ts +28 -12
  138. package/esm/LinearGenomeView/svgcomponents/util.js +41 -29
  139. package/esm/LinearGenomeView/types.d.ts +13 -10
  140. package/esm/LinearGenomeView/types.js +0 -1
  141. package/esm/LinearGenomeView/util.d.ts +103 -46
  142. package/esm/LinearGenomeView/util.js +222 -170
  143. package/esm/MultiLevelRubberband/MultiLevelRubberband.js +9 -6
  144. package/esm/MultiLevelRubberband/index.d.ts +2 -0
  145. package/esm/MultiLevelRubberband/index.js +2 -0
  146. package/esm/MultiLevelRubberband/menuItems.d.ts +34 -0
  147. package/esm/MultiLevelRubberband/menuItems.js +52 -0
  148. package/esm/MultiLevelRubberband/rowLabel.d.ts +22 -0
  149. package/esm/MultiLevelRubberband/rowLabel.js +27 -0
  150. package/esm/MultiLevelRubberband/types.d.ts +1 -0
  151. package/esm/MultiLevelRubberband/useRangeSelect.d.ts +2 -1
  152. package/esm/MultiLevelRubberband/useRangeSelect.js +45 -59
  153. package/esm/TrackModifiers/index.d.ts +83 -0
  154. package/esm/TrackModifiers/index.js +231 -0
  155. package/esm/displayKitTests/perRegionTestEnv.d.ts +244 -68
  156. package/esm/displayKitTests/perRegionTestEnv.js +30 -26
  157. package/esm/index.d.ts +21 -99
  158. package/esm/index.js +17 -38
  159. package/esm/searchUtils.d.ts +26 -10
  160. package/esm/searchUtils.js +137 -137
  161. package/esm/shared/RubberbandSpan.d.ts +3 -2
  162. package/esm/shared/RubberbandSpan.js +6 -3
  163. package/esm/shared/coordLabels.d.ts +11 -4
  164. package/esm/shared/coordLabels.js +20 -5
  165. package/esm/shared/useWindowDrag.d.ts +18 -0
  166. package/esm/shared/useWindowDrag.js +47 -0
  167. package/package.json +12 -11
  168. package/esm/FeatureTrack/configSchema.d.ts +0 -124
  169. package/esm/FeatureTrack/configSchema.js +0 -54
  170. package/esm/FeatureTrack/index.d.ts +0 -2
  171. package/esm/FeatureTrack/index.js +0 -13
  172. package/esm/LinearGenomeView/initKeys.d.ts +0 -12
  173. package/esm/LinearGenomeView/initKeys.js +0 -68
  174. package/esm/MultiLevelRubberband/VerticalGuide.d.ts +0 -6
  175. package/esm/MultiLevelRubberband/VerticalGuide.js +0 -21
  176. package/esm/lazyPluginExports.d.ts +0 -23
  177. package/esm/lazyPluginExports.js +0 -36
@@ -1,16 +1,16 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { SvgClipRect } from '@jbrowse/core/svg/SvgExport';
3
3
  import { svgNodeId } from '@jbrowse/core/svg/svgId';
4
+ import { usePalette } from '@jbrowse/core/ui/PaletteContext';
4
5
  import { getStrokeProps } from '@jbrowse/core/util';
5
- import { useTheme } from '@mui/material';
6
6
  import { gridlineTickXs, vlinePath } from './util.js';
7
7
  export default function SVGGridlines({ model, height, }) {
8
8
  const { width } = model;
9
- const theme = useTheme();
9
+ const palette = usePalette();
10
10
  // share the on-screen gridline colors; getStrokeProps splits the rgba alpha
11
11
  // into strokeOpacity so the exported SVG stays renderer-safe
12
- const minorProps = getStrokeProps(theme.palette.gridlineMinor);
13
- const majorProps = getStrokeProps(theme.palette.gridlineMajor);
12
+ const minorProps = getStrokeProps(palette.gridlineMinor);
13
+ const majorProps = getStrokeProps(palette.gridlineMajor);
14
14
  const { major, minor } = gridlineTickXs(model);
15
15
  // gridlineTicks spans the whole staticBlocks frame, which overhangs the
16
16
  // viewport on both sides, so clip to the view width rather than letting ticks
@@ -1,6 +1,9 @@
1
1
  import type { LinearGenomeViewModel } from '../index.ts';
2
- export default function SVGHeader({ model, fontSize, rulerHeight, }: {
2
+ import type { HeaderLayout } from './util.ts';
3
+ export default function SVGHeader({ model, fontSize, rulerHeight, layout, showCytobands, }: {
3
4
  model: LinearGenomeViewModel;
4
5
  rulerHeight: number;
5
6
  fontSize: number;
7
+ layout: HeaderLayout;
8
+ showCytobands: boolean;
6
9
  }): import("react").JSX.Element | null;
@@ -1,18 +1,17 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { usePalette } from '@jbrowse/core/ui/PaletteContext';
2
3
  import { getSession, stripAlpha } from '@jbrowse/core/util';
3
4
  import { createOverviewLayout, getOverviewRegionPxSpan, } from '@jbrowse/core/util/Base1DUtils';
4
5
  import calculateDynamicBlocks from '@jbrowse/core/util/calculateDynamicBlocks';
5
- import { useTheme } from '@mui/material';
6
6
  import Cytobands from '../components/Cytobands.js';
7
7
  import OverviewScalebarPolygon from '../components/OverviewScalebarPolygon.js';
8
8
  import { getCytobands } from '../components/util.js';
9
9
  import { HEADER_OVERVIEW_HEIGHT } from '../consts.js';
10
10
  import SVGRuler from './SVGRuler.js';
11
11
  import SVGScalebar from './SVGScalebar.js';
12
- import { getHeaderLayout } from './util.js';
13
12
  // "you are here" cytoband overview rendered above the ruler. Self-contained so
14
13
  // the overview-layout work only runs when cytobands are actually shown.
15
- function CytobandOverview({ model, assembly, y, }) {
14
+ function CytobandOverview({ model, y, }) {
16
15
  const { width, displayedRegions, minimumBlockWidth, bpPerPx } = model;
17
16
  const overview = createOverviewLayout({
18
17
  displayedRegions,
@@ -27,27 +26,15 @@ function CytobandOverview({ model, assembly, y, }) {
27
26
  bpPerPx,
28
27
  blocks: model.dynamicBlocks.blocks,
29
28
  });
30
- return block && span ? (_jsxs("g", { transform: `translate(0 ${y})`, children: [_jsx(Cytobands, { overview: overview, cytobands: getCytobands(assembly, block.refName), block: block }), _jsx("rect", { stroke: "red", fill: "rgb(255,0,0)", fillOpacity: 0.1, width: Math.max(span.rightPx - span.leftPx, 0.5), height: HEADER_OVERVIEW_HEIGHT - 1, x: span.leftPx, y: 0.5 }), _jsx("g", { transform: `translate(0,${HEADER_OVERVIEW_HEIGHT})`, children: _jsx(OverviewScalebarPolygon, { overview: overview, model: model, exportSvg: true }) })] })) : null;
29
+ return block && span ? (_jsxs("g", { transform: `translate(0 ${y})`, children: [_jsx(Cytobands, { overview: overview, cytobands: getCytobands(getSession(model).assemblyManager.get(block.assemblyName), block.refName), block: block }), _jsx("rect", { stroke: "red", fill: "rgb(255,0,0)", fillOpacity: 0.1, width: Math.max(span.rightPx - span.leftPx, 0.5), height: HEADER_OVERVIEW_HEIGHT - 1, x: span.leftPx, y: 0.5 }), _jsx("g", { transform: `translate(0,${HEADER_OVERVIEW_HEIGHT})`, children: _jsx(OverviewScalebarPolygon, { overview: overview, model: model, exportSvg: true }) })] })) : null;
31
30
  }
32
- export default function SVGHeader({ model, fontSize, rulerHeight, }) {
33
- const { assemblyNames, effectiveShowCytobands } = model;
34
- const { assemblyManager } = getSession(model);
35
- // cytobands need a single unambiguous assembly, but the header label names
36
- // every assembly in the view
37
- const cytobandAssemblyName = assemblyNames.length === 1 ? assemblyNames[0] : undefined;
38
- const assembly = cytobandAssemblyName
39
- ? assemblyManager.get(cytobandAssemblyName)
40
- : undefined;
41
- const theme = useTheme();
42
- const fill = stripAlpha(theme.palette.text.primary);
31
+ export default function SVGHeader({ model, fontSize, rulerHeight, layout, showCytobands, }) {
32
+ const palette = usePalette();
33
+ const fill = stripAlpha(palette.text.primary);
43
34
  // nothing on screen to label: no assembly name, scalebar or ruler
44
35
  if (!model.hasVisibleContent) {
45
36
  return null;
46
37
  }
47
- const { assemblyLabelBaselineY, cytobandTop, scalebarLineY, rulerTop } = getHeaderLayout({
48
- fontSize,
49
- showCytobands: effectiveShowCytobands,
50
- rulerHeight,
51
- });
52
- return (_jsxs("g", { id: "header", children: [_jsx("text", { x: 0, y: assemblyLabelBaselineY, fontSize: fontSize, fill: fill, children: assemblyNames.join(', ') }), effectiveShowCytobands ? (_jsx(CytobandOverview, { model: model, assembly: assembly, y: cytobandTop })) : null, _jsx("g", { transform: `translate(0 ${scalebarLineY})`, children: _jsx(SVGScalebar, { model: model, fontSize: fontSize }) }), _jsx("g", { transform: `translate(0 ${rulerTop})`, children: _jsx(SVGRuler, { model: model, rulerHeight: rulerHeight }) })] }));
38
+ const { assemblyLabelBaselineY, cytobandTop, scalebarLineY, rulerTop } = layout;
39
+ return (_jsxs("g", { id: "header", children: [_jsx("text", { x: 0, y: assemblyLabelBaselineY, fontSize: fontSize, fill: fill, children: model.assemblyNames.join(', ') }), showCytobands ? (_jsx(CytobandOverview, { model: model, y: cytobandTop })) : null, _jsx("g", { transform: `translate(0 ${scalebarLineY})`, children: _jsx(SVGScalebar, { model: model, fontSize: fontSize }) }), _jsx("g", { transform: `translate(0 ${rulerTop})`, children: _jsx(SVGRuler, { model: model, rulerHeight: rulerHeight }) })] }));
53
40
  }
@@ -1,5 +1,7 @@
1
+ import type { BandGap } from '../components/SVGHighlightBand.tsx';
1
2
  import type { LinearGenomeViewModel } from '../index.ts';
2
- export default function SVGHighlights({ model, height, }: {
3
+ export default function SVGHighlights({ model, height, gaps, }: {
3
4
  model: LinearGenomeViewModel;
4
5
  height: number;
6
+ gaps: BandGap[];
5
7
  }): (import("react").JSX.Element | null)[] | null;
@@ -1,11 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useStyleTheme } from '@jbrowse/core/ui/PaletteContext';
2
3
  import { getSession } from '@jbrowse/core/util';
3
- import { useTheme } from '@mui/material';
4
4
  import SVGHighlightBand from '../components/SVGHighlightBand.js';
5
5
  import { getHighlightColor, highlightKey } from '../components/util.js';
6
- // Native LGV highlights (model.highlight) drawn as full-height bands over the
7
- // tracks area, with an optional label at the top. Bookmark highlights are added
8
- // separately via the LinearGenomeView-HighlightSVGComponent extension point.
6
+ // The view's highlights drawn as full-height bands over the tracks area, with
7
+ // an optional label at the top.
9
8
  //
10
9
  // Deliberately NOT an observer, and that is the whole of what keeps a live
11
10
  // figure coherent. `useViewSvgFigure` freezes a figure by memoizing it against
@@ -15,12 +14,13 @@ import { getHighlightColor, highlightKey } from '../components/util.js';
15
14
  // bands across track bodies that were still drawn where the snapshot left them.
16
15
  // The file export renders the whole document in one synchronous pass, so it
17
16
  // never needed the subscription either.
18
- export default function SVGHighlights({ model, height, }) {
19
- const theme = useTheme();
20
- return getSession(model).highlightsVisible
21
- ? model.highlight.map((h, idx) => {
17
+ export default function SVGHighlights({ model, height, gaps, }) {
18
+ const theme = useStyleTheme();
19
+ const session = getSession(model);
20
+ return session.highlightsVisible
21
+ ? model.highlights.map((h, idx) => {
22
22
  const coords = model.getHighlightCoords(h);
23
- return coords ? (_jsx(SVGHighlightBand, { coords: coords, height: height, color: getHighlightColor(h, theme).toRgbString(), label: model.labelsVisible ? h.label : undefined, labelColor: theme.palette.text.primary }, highlightKey(h, idx))) : null;
23
+ return coords ? (_jsx(SVGHighlightBand, { coords: coords, height: height, gaps: gaps, color: getHighlightColor(h, theme).toRgbString(), label: session.highlightLabelsVisible ? h.label : undefined, labelColor: theme.palette.text.primary }, highlightKey(h, idx))) : null;
24
24
  })
25
25
  : null;
26
26
  }
@@ -1,5 +1,7 @@
1
+ import type { BandGap } from '../components/SVGHighlightBand.tsx';
1
2
  import type { LinearGenomeViewModel } from '../index.ts';
2
- export default function SVGHighlightsOverlay({ model, tracksHeight, }: {
3
+ export default function SVGHighlightsOverlay({ model, tracksHeight, gaps, }: {
3
4
  model: LinearGenomeViewModel;
4
5
  tracksHeight: number;
6
+ gaps: BandGap[];
5
7
  }): import("react").JSX.Element;
@@ -4,10 +4,10 @@ import { svgNodeId } from '@jbrowse/core/svg/svgId';
4
4
  import { PluggableElements } from '@jbrowse/core/ui';
5
5
  import { getEnv } from '@jbrowse/core/util';
6
6
  import SVGHighlights from './SVGHighlights.js';
7
- // The highlight layer over one view's tracks area: native LGV highlights plus
8
- // whatever plugins contribute (bookmarks), clipped to the view width. Callers
9
- // translate this to the top-left of the tracks area.
10
- export default function SVGHighlightsOverlay({ model, tracksHeight, }) {
7
+ // The highlight layer over one view's tracks area: the view's highlights plus
8
+ // whatever plugins contribute, clipped to the view width. Callers translate
9
+ // this to the top-left of the tracks area.
10
+ export default function SVGHighlightsOverlay({ model, tracksHeight, gaps, }) {
11
11
  const { pluginManager } = getEnv(model);
12
- return (_jsxs(SvgClipRect, { id: `highlight-clip-${svgNodeId(model)}`, width: model.width, height: tracksHeight, children: [_jsx(SVGHighlights, { model: model, height: tracksHeight }), _jsx(PluggableElements, { pluginManager: pluginManager, name: "LinearGenomeView-HighlightSVGComponent", props: { model, height: tracksHeight } })] }));
12
+ return (_jsxs(SvgClipRect, { id: `highlight-clip-${svgNodeId(model)}`, width: model.width, height: tracksHeight, children: [_jsx(SVGHighlights, { model: model, height: tracksHeight, gaps: gaps }), _jsx(PluggableElements, { pluginManager: pluginManager, name: "LinearGenomeView-HighlightSVGComponent", props: { model, height: tracksHeight } })] }));
13
13
  }
@@ -24,38 +24,33 @@ export async function renderToSvg(model, opts) {
24
24
  const { fontSize = 13,
25
25
  // the label band scales with the font it holds; destructured after
26
26
  // fontSize so the default can read it
27
- textHeight = defaultTextHeight(fontSize), rulerHeight = 34, trackLabels = 'offset', themeName = 'default', fontFamily, showGridlines = false, Wrapper, } = opts;
27
+ textHeight = defaultTextHeight(fontSize), rulerHeight = 34, trackLabels = 'offset', themeName, fontFamily, showGridlines = false, Wrapper, } = opts;
28
28
  const session = getSession(model);
29
29
  const theme = session.getActiveThemeOptions?.(themeName);
30
- // owns the two orderings this used to spell out by hand: legendWidth before
31
- // the awaits, tracksHeight after them. Every display's `renderSvg` owns its
30
+ // owns the ordering this used to spell out by hand: the stack's height and
31
+ // legend gutter measured after the awaits. Every display's `renderSvg` owns its
32
32
  // own readiness wait — an LGV display through `renderDisplaySvg`'s
33
33
  // `awaitSvgReady`, a non-LGV one (dotplot, synteny, circular) by calling that
34
34
  // itself.
35
35
  const { tracks, displayResults, tracksHeight, legendWidth, skippedTracks } = await renderViewTracks({
36
36
  view: model,
37
- opts,
37
+ opts: { ...opts, fontSize },
38
38
  theme,
39
39
  textHeight,
40
40
  trackLabels,
41
- // the standalone export is the one with room to give: it widens its
42
- // canvas below so a legend sits beside the plot rather than over it
43
- reserveLegendWidth: true,
44
41
  });
45
- notifySkippedSvgTracks(session, skippedTracks);
46
- // The view geometry is read *after* the displays' waits, never before —
47
- // SVGHeader re-reads both of these when it renders (later still, inside
48
- // wrapSvgExport) and lays itself out with the same getHeaderLayout call, so a
49
- // value that moved during the awaits would leave the reserved `tracksTop` and
50
- // the drawn header describing different rows. Same rule the dotplot, circular
51
- // and synteny exports each shipped a violation of.
42
+ if (opts.announceSkipped !== false) {
43
+ notifySkippedSvgTracks(session, skippedTracks);
44
+ }
45
+ // read after the displays' waits, and handed to SVGHeader rather than read
46
+ // again, so the reserved `tracksTop` and the drawn header are one layout
52
47
  const { width, effectiveShowCytobands } = model;
53
- const { tracksTop } = getHeaderLayout({
48
+ const headerLayout = getHeaderLayout({
54
49
  fontSize,
55
50
  showCytobands: effectiveShowCytobands,
56
51
  rulerHeight,
57
52
  });
58
- const height = tracksHeight + tracksTop + exportMargin;
53
+ const { tracksTop } = headerLayout;
59
54
  const trackLabelOffset = trackLabelLeftOffset({
60
55
  tracks,
61
56
  trackLabels,
@@ -68,7 +63,7 @@ export async function renderToSvg(model, opts) {
68
63
  return wrapSvgExport({
69
64
  theme,
70
65
  width: w,
71
- height,
66
+ height: tracksTop + tracksHeight + exportMargin,
72
67
  fontFamily,
73
68
  Wrapper,
74
69
  children: (_jsx("g", { transform: `translate(${exportMargin} 0)`, children: _jsx(SVGView, { view: model, displayResults: displayResults,
@@ -76,6 +71,6 @@ export async function renderToSvg(model, opts) {
76
71
  // header is the full one: cytoband overview and total-bp scalebar as
77
72
  // well as the assembly name and ruler. `tracksTop` is the height
78
73
  // getHeaderLayout gave it.
79
- header: _jsx(SVGHeader, { model: model, fontSize: fontSize, rulerHeight: rulerHeight }), fontSize: fontSize, textHeight: textHeight, trackLabels: trackLabels, trackLabelOffset: trackLabelOffset, contentTop: tracksTop, tracksHeight: tracksHeight, showGridlines: showGridlines, leftBuffer: exportMargin, legendWidth: legendWidth }) })),
74
+ header: _jsx(SVGHeader, { model: model, fontSize: fontSize, rulerHeight: rulerHeight, layout: headerLayout, showCytobands: effectiveShowCytobands }), fontSize: fontSize, textHeight: textHeight, trackLabels: trackLabels, trackLabelOffset: trackLabelOffset, contentTop: tracksTop, tracksHeight: tracksHeight, showGridlines: showGridlines, leftBuffer: exportMargin }) })),
80
75
  });
81
76
  }
@@ -1,5 +1,5 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
- import { useTheme } from '@mui/material';
2
+ import { usePalette } from '@jbrowse/core/ui/PaletteContext';
3
3
  // SVG counterpart of the on-screen PaddingBlocks region separators: an opaque
4
4
  // 3px bar at the right edge of every displayed region, in the same per-mode grey
5
5
  // (a translucent fill would tint the track data it masks rather than hide it).
@@ -15,10 +15,7 @@ import { useTheme } from '@mui/material';
15
15
  // close the "divergence".
16
16
  export default function SVGRegionSeparators({ model, height, }) {
17
17
  const { dynamicBlocks, offsetPx } = model;
18
- const theme = useTheme();
19
- const fill = theme.palette.mode === 'dark'
20
- ? theme.palette.grey[500]
21
- : theme.palette.grey[600];
18
+ const fill = usePalette().regionSeparator;
22
19
  return (_jsx(_Fragment, { children: dynamicBlocks.contentBlocks
23
20
  .filter(block => block.isRightEndOfDisplayedRegion)
24
21
  .map(block => (_jsx("rect", { x: block.offsetPx + block.widthPx - offsetPx - 1, width: 3, y: 0, height: height, fill: fill }, block.key))) }));
@@ -1,6 +1,6 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { usePalette } from '@jbrowse/core/ui/PaletteContext';
2
3
  import { stripAlpha } from '@jbrowse/core/util';
3
- import { useTheme } from '@mui/material';
4
4
  import SVGRuler from './SVGRuler.js';
5
5
  import SVGScalebar from './SVGScalebar.js';
6
6
  import { getRowHeaderLayout } from './util.js';
@@ -10,9 +10,8 @@ import { getRowHeaderLayout } from './util.js';
10
10
  // draws the cytoband overview — there is room for that above a single view, and
11
11
  // none between two rows of a synteny stack.
12
12
  export default function SVGRowHeader({ view, fontSize,
13
- // Must be the height the caller also passes SVGView as `contentTop`: the
14
- // ruler hangs its ticks off the bottom of this budget so they meet the
15
- // tracks, and the tracks start at `contentTop`.
13
+ // SVGStackedRow passes the same value as SVGView's `contentTop`, so the
14
+ // ticks hanging off this budget meet the tracks
16
15
  rulerHeight,
17
16
  // Whether this row draws its assembly name. Default true, which is what a
18
17
  // stack of DIFFERENT assemblies wants — a synteny export names each row
@@ -28,10 +27,10 @@ showAssemblyName = true,
28
27
  // band and every caller has to reserve that much before asking for it. See
29
28
  // getRowHeaderLayout for what it is for.
30
29
  showScalebar = false, }) {
31
- const theme = useTheme();
30
+ const palette = usePalette();
32
31
  const { assemblyLabelBaselineY, scalebarLineY } = getRowHeaderLayout({
33
32
  fontSize,
34
33
  showScalebar,
35
34
  });
36
- return (_jsxs(_Fragment, { children: [showAssemblyName ? (_jsx("text", { x: 0, y: assemblyLabelBaselineY, fontSize: fontSize, fill: stripAlpha(theme.palette.text.primary), children: view.assemblyNames.join(', ') })) : null, scalebarLineY === undefined ? null : (_jsx("g", { transform: `translate(0 ${scalebarLineY})`, children: _jsx(SVGScalebar, { model: view, fontSize: fontSize }) })), _jsx(SVGRuler, { model: view, rulerHeight: rulerHeight })] }));
35
+ return (_jsxs(_Fragment, { children: [showAssemblyName ? (_jsx("text", { x: 0, y: assemblyLabelBaselineY, fontSize: fontSize, fill: stripAlpha(palette.text.primary), children: view.assemblyNames.join(', ') })) : null, scalebarLineY === undefined ? null : (_jsx("g", { transform: `translate(0 ${scalebarLineY})`, children: _jsx(SVGScalebar, { model: view, fontSize: fontSize }) })), _jsx(SVGRuler, { model: view, rulerHeight: rulerHeight })] }));
37
36
  }
@@ -1,11 +1,11 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { SvgClipRect } from '@jbrowse/core/svg/SvgExport';
3
3
  import { svgNodeId } from '@jbrowse/core/svg/svgId';
4
+ import { usePalette } from '@jbrowse/core/ui/PaletteContext';
4
5
  import { stripAlpha } from '@jbrowse/core/util';
5
- import { useTheme } from '@mui/material';
6
- import { REF_NAME_LABEL_FONT_SIZE, getScalebarRefNameLabels, labelFitsInBlock, refNameLabelFitsInView, tickLabelWidth, } from '../util.js';
6
+ import { REF_NAME_LABEL_FONT_SIZE, TICK_LABEL_FONT_SIZE, getScalebarRefNameLabels, labelFitsInBlock, refNameLabelFitsInView, tickLabelWidth, } from '../util.js';
7
7
  import SVGRegionSeparators from './SVGRegionSeparators.js';
8
- import { RULER_MAJOR_TICK, RULER_MINOR_TICK, RULER_TICK_FONT_SIZE, getRulerLayout, gridlineTickXs, refNameLabelBaselineY, refNameLabelBoxHeight, vlinePath, } from './util.js';
8
+ import { RULER_MAJOR_TICK, RULER_MINOR_TICK, getRulerLayout, gridlineTickXs, refNameLabelBaselineY, refNameLabelBoxHeight, vlinePath, } from './util.js';
9
9
  // Tick marks and their coordinate labels, read from the same model getters the
10
10
  // on-screen Gridlines/ScalebarCoordinateLabels use (gridlineTicks /
11
11
  // scalebarLabels), so tick pitch, label text and label placement can't drift
@@ -13,8 +13,8 @@ import { RULER_MAJOR_TICK, RULER_MINOR_TICK, RULER_TICK_FONT_SIZE, getRulerLayou
13
13
  // the viewport, so shift by the view's `staticBlocksTranslateX` and let the
14
14
  // caller's clip trim the overhang.
15
15
  function Ruler({ model, tickTopY, numbersBaselineY, }) {
16
- const theme = useTheme();
17
- const color = stripAlpha(theme.palette.text.secondary);
16
+ const palette = usePalette();
17
+ const color = stripAlpha(palette.text.secondary);
18
18
  const { scalebarLabels, width } = model;
19
19
  const { dx, major, minor } = gridlineTickXs(model);
20
20
  // major and minor marks share a stroke and differ only in length, so both
@@ -26,15 +26,14 @@ function Ruler({ model, tickTopY, numbersBaselineY, }) {
26
26
  const w = tickLabelWidth(label);
27
27
  return labelFitsInBlock(dx + x - w / 2, w, width);
28
28
  })
29
- .map(({ x, label, key }) => (_jsx("text", { x: dx + x, y: numbersBaselineY, textAnchor: "middle", fontSize: RULER_TICK_FONT_SIZE, fill: color, children: label }, key)))] }));
29
+ .map(({ x, label, key }) => (_jsx("text", { x: dx + x, y: numbersBaselineY, textAnchor: "middle", fontSize: TICK_LABEL_FONT_SIZE, fill: color, children: label }, key)))] }));
30
30
  }
31
31
  // Chromosome/refName labels along the ruler. Reuses the on-screen scalebar's
32
32
  // sticky-label logic (getScalebarRefNameLabels) so the exported name stays
33
33
  // pinned to the viewport's left edge when a region has scrolled off — otherwise
34
34
  // the name renders off-canvas whenever you export a view zoomed into a
35
35
  // chromosome interior. No assembly-name prefix here (unlike the on-screen
36
- // scalebar): the SVG export already draws a standalone assembly-name label
37
- // above the ruler, so folding it into this one too is redundant.
36
+ // scalebar): the SVG export already draws the assembly name above the ruler.
38
37
  //
39
38
  // `orientation` is not redundant, and this is the surface that needed it most.
40
39
  // A stacked export gives each row SVGRowHeader — assembly name, ruler, refName
@@ -42,8 +41,8 @@ function Ruler({ model, tickTopY, numbersBaselineY, }) {
42
41
  // counting down as the only evidence it was flipped. On screen the search box
43
42
  // says so; a figure has no search box.
44
43
  function SVGRefNameLabels({ model }) {
45
- const theme = useTheme();
46
- const fill = stripAlpha(theme.palette.text.primary);
44
+ const palette = usePalette();
45
+ const fill = stripAlpha(palette.text.primary);
47
46
  const { labels, caption } = getScalebarRefNameLabels({
48
47
  blocks: model.staticBlocks.blocks,
49
48
  offsetPx: model.offsetPx,
@@ -1,15 +1,15 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { usePalette } from '@jbrowse/core/ui/PaletteContext';
2
3
  import { getBpDisplayStr, stripAlpha } from '@jbrowse/core/util';
3
- import { useTheme } from '@mui/material';
4
4
  import { SVG_SCALEBAR_CAP } from '../consts.js';
5
5
  import { labelBaselineFromTop } from './util.js';
6
6
  export default function SVGScalebar({ model, fontSize, }) {
7
7
  const { offsetPx, dynamicBlocks: { totalWidthPxWithoutBorders: totalWidthPx, totalBp }, } = model;
8
- const theme = useTheme();
8
+ const palette = usePalette();
9
9
  const displayBp = getBpDisplayStr(totalBp);
10
10
  const x0 = Math.max(-offsetPx, 0);
11
11
  const x1 = x0 + totalWidthPx;
12
- const color = stripAlpha(theme.palette.text.secondary);
12
+ const color = stripAlpha(palette.text.secondary);
13
13
  // the bar is drawn on this component's own origin (y=0), with capped ends and
14
14
  // the bp label hanging just below; callers translate it to the desired line y
15
15
  return (_jsxs(_Fragment, { children: [_jsx("line", { x1: x0, x2: x1, y1: 0, y2: 0, stroke: color }), _jsx("line", { x1: x0, x2: x0, y1: -SVG_SCALEBAR_CAP, y2: SVG_SCALEBAR_CAP, stroke: color }), _jsx("line", { x1: x1, x2: x1, y1: -SVG_SCALEBAR_CAP, y2: SVG_SCALEBAR_CAP, stroke: color }), _jsx("text", { x: (x0 + x1) / 2, y: labelBaselineFromTop(SVG_SCALEBAR_CAP, fontSize), textAnchor: "middle", fontSize: fontSize, fill: color, children: displayBp })] }));
@@ -0,0 +1,26 @@
1
+ import type { LinearGenomeViewModel } from '../index.ts';
2
+ import type { SvgDisplayResult } from './util.ts';
3
+ import type { TrackLabelMode } from '@jbrowse/display-kit/types';
4
+ /**
5
+ * One view of a stacked export: its ruler, with the assembly name and scalebar
6
+ * above it, over its track bodies. `top` is where the ruler starts; the caller
7
+ * reserves `getRowHeaderLayout().bandHeight` above it for the header to draw
8
+ * into, and the row is `rulerHeight + rendered.tracksHeight` tall below it.
9
+ */
10
+ export default function SVGStackedRow({ view, rendered, top, margin, fontSize, textHeight, rulerHeight, trackLabels, trackLabelOffset, showGridlines, showAssemblyName, showScalebar, }: {
11
+ view: LinearGenomeViewModel;
12
+ rendered: {
13
+ displayResults: SvgDisplayResult[];
14
+ tracksHeight: number;
15
+ };
16
+ top: number;
17
+ margin: number;
18
+ fontSize: number;
19
+ textHeight: number;
20
+ rulerHeight: number;
21
+ trackLabels: TrackLabelMode;
22
+ trackLabelOffset: number;
23
+ showGridlines: boolean;
24
+ showAssemblyName?: boolean;
25
+ showScalebar?: boolean;
26
+ }): import("react").JSX.Element;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import SVGRowHeader from './SVGRowHeader.js';
3
+ import SVGView from './SVGView.js';
4
+ /**
5
+ * One view of a stacked export: its ruler, with the assembly name and scalebar
6
+ * above it, over its track bodies. `top` is where the ruler starts; the caller
7
+ * reserves `getRowHeaderLayout().bandHeight` above it for the header to draw
8
+ * into, and the row is `rulerHeight + rendered.tracksHeight` tall below it.
9
+ */
10
+ export default function SVGStackedRow({ view, rendered, top, margin, fontSize, textHeight, rulerHeight, trackLabels, trackLabelOffset, showGridlines, showAssemblyName, showScalebar, }) {
11
+ return (_jsx("g", { transform: `translate(${margin} ${top})`, children: _jsx(SVGView, { view: view, displayResults: rendered.displayResults, header: _jsx(SVGRowHeader, { view: view, fontSize: fontSize, rulerHeight: rulerHeight, showAssemblyName: showAssemblyName, showScalebar: showScalebar }), fontSize: fontSize, textHeight: textHeight, trackLabels: trackLabels, trackLabelOffset: trackLabelOffset, contentTop: rulerHeight, tracksHeight: rendered.tracksHeight, showGridlines: showGridlines, leftBuffer: margin }) }));
12
+ }
@@ -1,19 +1,18 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { usePalette } from '@jbrowse/core/ui/PaletteContext';
2
3
  import { stripAlpha } from '@jbrowse/core/util';
3
- import { useTheme } from '@mui/material';
4
4
  import { TRACK_LABEL_GAP, insetLabelBaselineY, offsetLabelBaselineY, } from './util.js';
5
5
  // Where the label sits, per mode. 'left' right-aligns in the gutter
6
- // trackLabelLeftOffset reserved (hence the shared TRACK_LABEL_GAP); the other
7
- // modes hang off the leftmost visible content at `x`, either just above the
8
- // track body ('offset') or inset over it ('overlay').
6
+ // trackLabelLeftOffset reserved (hence the shared TRACK_LABEL_GAP), beside the
7
+ // first row. The other modes hang off the leftmost visible content
8
+ // at `x`, either just above the track body ('offset') or inset over it
9
+ // ('overlapping').
9
10
  //
10
11
  // Every mode is placed on its alphabetic baseline (the SVG default, so no
11
- // dominantBaseline is emitted at all): 'offset' so its descenders land a known
12
- // distance above the track body — the band it sits in is `textHeight` tall, and
13
- // offsetLabelBaselineY owns that arithmetic — and 'left'/'overlay' so their
14
- // ascenders stay inside the track box they align with. 'left' used to be pinned
15
- // at a hardcoded y=20 on a hanging baseline, which neither scaled with fontSize
16
- // nor stayed inside a track shorter than ~35px.
12
+ // dominantBaseline is emitted at all): 'offset' so its descenders land a known distance above the track body — the band is
13
+ // `textHeight` tall, and offsetLabelBaselineY owns that arithmetic — and
14
+ // 'left'/'overlapping' so their ascenders stay inside the track box they align
15
+ // with.
17
16
  function labelPosition({ trackLabels, trackLabelOffset, textHeight, fontSize, x, }) {
18
17
  if (trackLabels === 'left') {
19
18
  return {
@@ -32,8 +31,8 @@ function labelPosition({ trackLabels, trackLabelOffset, textHeight, fontSize, x,
32
31
  return { x: x + 5, y: insetLabelBaselineY(fontSize) };
33
32
  }
34
33
  export default function SVGTrackLabel({ trackLabels, trackName, fontSize, textHeight, trackLabelOffset, x, }) {
35
- const theme = useTheme();
36
- if (trackLabels === 'none') {
34
+ const palette = usePalette();
35
+ if (trackLabels === 'hidden') {
37
36
  return null;
38
37
  }
39
38
  const pos = labelPosition({
@@ -43,5 +42,14 @@ export default function SVGTrackLabel({ trackLabels, trackName, fontSize, textHe
43
42
  fontSize,
44
43
  x,
45
44
  });
46
- return (_jsx("text", { x: pos.x, y: pos.y, textAnchor: pos.textAnchor, fontSize: fontSize, fill: stripAlpha(theme.palette.text.primary), children: trackName }));
45
+ // 'overlapping' prints over the track's own data, which the on-screen label
46
+ // clears with a paper box, so it carries the halo text over a plot needs
47
+ const halo = trackLabels === 'overlapping'
48
+ ? {
49
+ stroke: stripAlpha(palette.background.paper),
50
+ strokeWidth: 3,
51
+ paintOrder: 'stroke',
52
+ }
53
+ : {};
54
+ return (_jsx("text", { x: pos.x, y: pos.y, textAnchor: pos.textAnchor, fontSize: fontSize, fill: stripAlpha(palette.text.primary), ...halo, children: trackName }));
47
55
  }
@@ -2,14 +2,13 @@ import type { LinearGenomeViewModel } from '../index.ts';
2
2
  import type { TrackLabelMode } from '../types.ts';
3
3
  import type { SvgDisplayResult } from './util.ts';
4
4
  type LGV = LinearGenomeViewModel;
5
- export default function SVGTracks({ displayResults, model, textHeight, fontSize, trackLabels, trackLabelOffset, leftBuffer, legendWidth, }: {
5
+ export default function SVGTracks({ displayResults, model, textHeight, fontSize, trackLabels, trackLabelOffset, leftBuffer, }: {
6
6
  displayResults: SvgDisplayResult[];
7
7
  model: LGV;
8
8
  textHeight: number;
9
9
  fontSize: number;
10
- trackLabels?: TrackLabelMode;
11
- trackLabelOffset?: number;
12
- leftBuffer?: number;
13
- legendWidth?: number;
10
+ trackLabels: TrackLabelMode;
11
+ trackLabelOffset: number;
12
+ leftBuffer: number;
14
13
  }): import("react").JSX.Element;
15
14
  export {};
@@ -3,19 +3,20 @@ import { SvgClipRect } from '@jbrowse/core/svg/SvgExport';
3
3
  import { svgNodeId } from '@jbrowse/core/svg/svgId';
4
4
  import { svgTrackName } from '@jbrowse/core/svg/trackNames';
5
5
  import { getSession } from '@jbrowse/core/util';
6
+ import { SvgLegend } from '@jbrowse/display-kit/renderDisplaySvg';
6
7
  import SVGRegionSeparators from './SVGRegionSeparators.js';
7
8
  import SVGTrackLabel from './SVGTrackLabel.js';
8
- import { labelOffset, trackBoxOffsets } from './util.js';
9
- export default function SVGTracks({ displayResults, model, textHeight, fontSize, trackLabels = 'offset', trackLabelOffset = 0, leftBuffer = 0, legendWidth = 0, }) {
9
+ import { labelOffset, trackBoxOffsets, trackLabelMode } from './util.js';
10
+ export default function SVGTracks({ displayResults, model, textHeight, fontSize, trackLabels, trackLabelOffset, leftBuffer, }) {
10
11
  const session = getSession(model);
11
- const textOffset = labelOffset(trackLabels, textHeight);
12
12
  const x = Math.max(-model.offsetPx, 0);
13
- const offsets = trackBoxOffsets(displayResults.map(r => r.track), textOffset);
14
- return (_jsx(_Fragment, { children: displayResults.map(({ track, result }, i) => {
13
+ const offsets = trackBoxOffsets(displayResults.map(r => r.track), trackLabels, textHeight);
14
+ return (_jsx(_Fragment, { children: displayResults.map(({ track, result, legendHeight }, i) => {
15
15
  const conf = track.configuration;
16
16
  const trackName = svgTrackName(track, session);
17
17
  const display = track.displays[0];
18
18
  const currentOffset = offsets[i];
19
- return (_jsxs("g", { transform: `translate(0 ${currentOffset})`, children: [_jsx(SvgClipRect, { id: `track-clip-${svgNodeId(model)}-${conf.trackId}`, x: -leftBuffer, y: textOffset, width: model.width + trackLabelOffset + leftBuffer + legendWidth, height: display.height, children: _jsxs("g", { transform: `translate(${trackLabelOffset} ${textOffset})`, children: [result, _jsx(SVGRegionSeparators, { model: model, height: display.height })] }) }), _jsx(SVGTrackLabel, { trackName: trackName, fontSize: fontSize, textHeight: textHeight, trackLabels: trackLabels, trackLabelOffset: trackLabelOffset, x: x })] }, conf.trackId));
19
+ const textOffset = labelOffset(track, trackLabels, textHeight);
20
+ return (_jsxs("g", { transform: `translate(0 ${currentOffset})`, children: [_jsx(SvgClipRect, { id: `track-clip-${svgNodeId(model)}-${conf.trackId}`, x: -leftBuffer, y: textOffset, width: model.width + trackLabelOffset + leftBuffer, height: display.height, children: _jsxs("g", { transform: `translate(${trackLabelOffset} ${textOffset})`, children: [result, display.regionTooLarge ? null : (_jsx(SVGRegionSeparators, { model: model, height: display.height }))] }) }), legendHeight === undefined ? null : (_jsx("g", { transform: `translate(${trackLabelOffset} ${textOffset})`, children: _jsx(SvgLegend, { model: display, width: model.width, height: legendHeight }) })), _jsx(SVGTrackLabel, { trackName: trackName, fontSize: fontSize, textHeight: textHeight, trackLabels: trackLabelMode(track, trackLabels), trackLabelOffset: trackLabelOffset, x: x + trackLabelOffset })] }, conf.trackId));
20
21
  }) }));
21
22
  }
@@ -2,7 +2,7 @@ import type { LinearGenomeViewModel } from '../index.ts';
2
2
  import type { TrackLabelMode } from '../types.ts';
3
3
  import type { SvgDisplayResult } from './util.ts';
4
4
  import type { ReactNode } from 'react';
5
- export default function SVGView({ view, displayResults, header, fontSize, textHeight, trackLabels, trackLabelOffset, contentTop, tracksHeight, showGridlines, leftBuffer, legendWidth, }: {
5
+ export default function SVGView({ view, displayResults, header, fontSize, textHeight, trackLabels, trackLabelOffset, contentTop, tracksHeight, showGridlines, leftBuffer, }: {
6
6
  view: LinearGenomeViewModel;
7
7
  displayResults: SvgDisplayResult[];
8
8
  header: ReactNode;
@@ -13,6 +13,5 @@ export default function SVGView({ view, displayResults, header, fontSize, textHe
13
13
  contentTop: number;
14
14
  tracksHeight: number;
15
15
  showGridlines: boolean;
16
- leftBuffer?: number;
17
- legendWidth?: number;
16
+ leftBuffer: number;
18
17
  }): import("react").JSX.Element;
@@ -2,12 +2,26 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
2
2
  import SVGGridlines from './SVGGridlines.js';
3
3
  import SVGHighlightsOverlay from './SVGHighlightsOverlay.js';
4
4
  import SVGTracks from './SVGTracks.js';
5
+ import { labelOffset, trackBoxOffsets } from './util.js';
5
6
  // One LGV's worth of exported SVG: a caller-supplied header on top, then
6
7
  // optional gridlines, the track bodies, and the highlight layer over them.
7
8
  // Shared by all three exports that stack an LGV — the standalone one, and the
8
9
  // linear-synteny and breakpoint-split rows — so their per-view layout can't
9
10
  // drift. It did drift while the standalone export kept its own copy of these
10
- // four groups: only that copy widened the per-track clip by `legendWidth`.
11
- export default function SVGView({ view, displayResults, header, fontSize, textHeight, trackLabels, trackLabelOffset, contentTop, tracksHeight, showGridlines, leftBuffer = 0, legendWidth = 0, }) {
12
- return (_jsxs(_Fragment, { children: [_jsx("g", { transform: `translate(${trackLabelOffset})`, children: header }), showGridlines ? (_jsx("g", { transform: `translate(${trackLabelOffset} ${contentTop})`, children: _jsx(SVGGridlines, { model: view, height: tracksHeight }) })) : null, _jsx("g", { transform: `translate(0 ${contentTop})`, children: _jsx(SVGTracks, { textHeight: textHeight, trackLabels: trackLabels, fontSize: fontSize, model: view, displayResults: displayResults, trackLabelOffset: trackLabelOffset, leftBuffer: leftBuffer, legendWidth: legendWidth }) }), _jsx("g", { transform: `translate(${trackLabelOffset} ${contentTop})`, children: _jsx(SVGHighlightsOverlay, { model: view, tracksHeight: tracksHeight }) })] }));
11
+ // four groups.
12
+ export default function SVGView({ view, displayResults, header, fontSize, textHeight, trackLabels, trackLabelOffset, contentTop, tracksHeight, showGridlines, leftBuffer, }) {
13
+ const tracks = displayResults.map(r => r.track);
14
+ const offsets = trackBoxOffsets(tracks, trackLabels, textHeight);
15
+ const nonGenomicBands = tracks.flatMap((track, i) => {
16
+ const display = track.displays[0];
17
+ return display.drawsGenomicCoordinates === false
18
+ ? [
19
+ {
20
+ top: offsets[i] + labelOffset(track, trackLabels, textHeight),
21
+ height: display.height,
22
+ },
23
+ ]
24
+ : [];
25
+ });
26
+ return (_jsxs(_Fragment, { children: [_jsx("g", { transform: `translate(${trackLabelOffset})`, children: header }), showGridlines ? (_jsx("g", { transform: `translate(${trackLabelOffset} ${contentTop})`, children: _jsx(SVGGridlines, { model: view, height: tracksHeight }) })) : null, _jsx("g", { transform: `translate(0 ${contentTop})`, children: _jsx(SVGTracks, { textHeight: textHeight, trackLabels: trackLabels, fontSize: fontSize, model: view, displayResults: displayResults, trackLabelOffset: trackLabelOffset, leftBuffer: leftBuffer }) }), _jsx("g", { transform: `translate(${trackLabelOffset} ${contentTop})`, children: _jsx(SVGHighlightsOverlay, { model: view, tracksHeight: tracksHeight, gaps: nonGenomicBands }) })] }));
13
27
  }