@jbrowse/bandage-core 9.9.2 → 9.10.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 (52) hide show
  1. package/README.md +3 -0
  2. package/dist/bubbles/superbubbles.js +2 -2
  3. package/dist/chunks/{chunk-IZ3W5IU2.js → chunk-2FLBFVMO.js} +33 -33
  4. package/dist/chunks/{chunk-BQ33OOLC.js → chunk-2VTM3DHG.js} +1 -1
  5. package/dist/chunks/{chunk-F4BKWWLS.js → chunk-4IYP43W6.js} +4 -4
  6. package/dist/chunks/{chunk-RK3MF4FD.js → chunk-BDWQQK33.js} +1 -1
  7. package/dist/chunks/{chunk-HOZI3FBG.js → chunk-CXKZYLYS.js} +1 -1
  8. package/dist/chunks/{chunk-MECWJY2R.js → chunk-DMH4NL2M.js} +4 -4
  9. package/dist/chunks/{chunk-P6O4RSOQ.js → chunk-FJZ2TB46.js} +5 -5
  10. package/dist/chunks/{chunk-IJRNMO4D.js → chunk-FUUJ76KD.js} +1 -1
  11. package/dist/chunks/{chunk-FPTI3WAV.js → chunk-HRAU4VTB.js} +12 -7
  12. package/dist/chunks/{chunk-YGN4KL7W.js → chunk-IZI7KIVX.js} +1 -1
  13. package/dist/chunks/{chunk-YS7VA5SI.js → chunk-K5NYTPLC.js} +1 -1
  14. package/dist/chunks/{chunk-F5BYHLIN.js → chunk-KYY5363X.js} +1 -1
  15. package/dist/chunks/{chunk-WVBYR6Y7.js → chunk-LZWSZRUY.js} +1 -1
  16. package/dist/chunks/{chunk-EE37PVQY.js → chunk-MVMP6AGI.js} +1 -1
  17. package/dist/chunks/chunk-NGODVSCA.js +292 -0
  18. package/dist/chunks/chunk-OPPVSPEF.js +57 -0
  19. package/dist/chunks/{chunk-ZBLKAWSD.js → chunk-PT37VS5B.js} +1 -1
  20. package/dist/chunks/{chunk-YAN2ZPNV.js → chunk-Q6UIUY6X.js} +1 -1
  21. package/dist/chunks/{chunk-KJEMKHVB.js → chunk-TFAFIRZB.js} +1 -1
  22. package/dist/cli/figure.js +41 -40
  23. package/dist/cli/fold.js +4 -3
  24. package/dist/figure.js +25 -24
  25. package/dist/figureData.js +62 -0
  26. package/dist/figureSettings.js +5 -4
  27. package/dist/index.js +150 -143
  28. package/dist/layout/forceCache.js +5 -4
  29. package/dist/layout/smoothChains.js +6 -0
  30. package/dist/layout/tubeMapLayout.js +4 -4
  31. package/dist/layout/walkRowDraw.js +9 -9
  32. package/dist/layout/walkStrip.js +10 -10
  33. package/dist/layoutModes.js +7 -7
  34. package/dist/pathColors.js +3 -3
  35. package/dist/pipeline.js +4 -3
  36. package/dist/referenceRampCss.js +7 -7
  37. package/dist/referenceStrip.js +7 -7
  38. package/dist/renderer/GeometryBuilder.js +6 -6
  39. package/dist/tubeMap/bundle.js +5 -5
  40. package/dist/tubeMap/coarsen.js +4 -4
  41. package/dist/tubeMap/nodeColors.js +7 -7
  42. package/dist/types/figureData.d.ts +146 -0
  43. package/dist/types/index.d.ts +2 -0
  44. package/dist/types/layout/smoothChains.d.ts +2 -0
  45. package/dist/types/version.d.ts +1 -1
  46. package/dist/version.js +1 -1
  47. package/dist/viewport.js +5 -4
  48. package/dist/walkEncoding.js +7 -7
  49. package/dist/walkHighlight.js +8 -8
  50. package/package.json +1 -1
  51. package/dist/chunks/{chunk-ROQGMTFB.js → chunk-5GZEPPEW.js} +5 -5
  52. package/dist/chunks/{chunk-EDASNMLY.js → chunk-XZ2BLAA6.js} +3 -3
package/README.md CHANGED
@@ -25,6 +25,9 @@ npm install @jbrowse/bandage-core
25
25
  and the `bandage-figure` CLI makes one from a JSON spec with no browser:
26
26
  `npx -p @jbrowse/bandage-core bandage-figure spec.json -o figure.svg`. See
27
27
  [docs/figures.md](docs/figures.md)
28
+ - Figure data: `figureData` returns what `figureSvg` would paint as columnar
29
+ tables, for another graphics system to draw;
30
+ [ggbandage](https://github.com/GMOD/ggbandage) draws them in ggplot2
28
31
 
29
32
  Nothing here imports React, MobX or a JBrowse host. BandageJS's
30
33
  [`src/main.ts`](https://github.com/cmdcolin/BandageJS/blob/main/src/main.ts) is
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  graphBubbles,
3
3
  superbubblesFromGraph
4
- } from "../chunks/chunk-ROQGMTFB.js";
4
+ } from "../chunks/chunk-5GZEPPEW.js";
5
+ import "../chunks/chunk-CLOP7UVD.js";
5
6
  import "../chunks/chunk-A6PSWTLX.js";
6
7
  import "../chunks/chunk-EHUBJDDB.js";
7
8
  import "../chunks/chunk-XKWD2RY3.js";
8
- import "../chunks/chunk-CLOP7UVD.js";
9
9
  import "../chunks/chunk-FX4RDMDN.js";
10
10
  import "../chunks/chunk-HNQPEMYE.js";
11
11
  import "../chunks/chunk-IGJCTPFB.js";
@@ -5,18 +5,15 @@ import {
5
5
  stripGeneGaps,
6
6
  walkStripFrame,
7
7
  walkStripLabelsTree
8
- } from "./chunk-MECWJY2R.js";
9
- import {
10
- Canvas2DRenderer
11
- } from "./chunk-WBCOREDZ.js";
12
- import {
13
- layoutGeometryInputs
14
- } from "./chunk-LOCJN3BZ.js";
8
+ } from "./chunk-DMH4NL2M.js";
15
9
  import {
16
10
  walkRowsKey,
17
11
  walkRowsKeyTree,
18
12
  walkRowsTree
19
- } from "./chunk-P6O4RSOQ.js";
13
+ } from "./chunk-FJZ2TB46.js";
14
+ import {
15
+ Canvas2DRenderer
16
+ } from "./chunk-WBCOREDZ.js";
20
17
  import {
21
18
  genePins
22
19
  } from "./chunk-BUBZ32IC.js";
@@ -25,16 +22,31 @@ import {
25
22
  exonOutlineTree,
26
23
  exonStretches
27
24
  } from "./chunk-3S3YVOJ7.js";
25
+ import {
26
+ geneLabelCandidates
27
+ } from "./chunk-DRG4236Y.js";
28
+ import {
29
+ nodesUnderBox
30
+ } from "./chunk-FP4H7SFT.js";
31
+ import {
32
+ serializeEl
33
+ } from "./chunk-NNODIW4U.js";
34
+ import {
35
+ layoutGeometryInputs
36
+ } from "./chunk-LOCJN3BZ.js";
37
+ import {
38
+ version
39
+ } from "./chunk-2VTM3DHG.js";
28
40
  import {
29
41
  axisScaleOf
30
- } from "./chunk-ZBLKAWSD.js";
42
+ } from "./chunk-PT37VS5B.js";
31
43
  import {
32
44
  facetLifts,
33
45
  walkLift
34
- } from "./chunk-EE37PVQY.js";
46
+ } from "./chunk-MVMP6AGI.js";
35
47
  import {
36
48
  encodingStops
37
- } from "./chunk-F5BYHLIN.js";
49
+ } from "./chunk-KYY5363X.js";
38
50
  import {
39
51
  rangeText,
40
52
  walkKey
@@ -42,10 +54,7 @@ import {
42
54
  import {
43
55
  buildGeometry,
44
56
  computeReferenceRamp
45
- } from "./chunk-F4BKWWLS.js";
46
- import {
47
- version
48
- } from "./chunk-BQ33OOLC.js";
57
+ } from "./chunk-4IYP43W6.js";
49
58
  import {
50
59
  walkRowLabels,
51
60
  walkRowsExtent
@@ -53,19 +62,18 @@ import {
53
62
  import {
54
63
  pathLegend,
55
64
  walkLabelsOf
56
- } from "./chunk-EDASNMLY.js";
65
+ } from "./chunk-XZ2BLAA6.js";
57
66
  import {
58
67
  nodeInk
59
68
  } from "./chunk-PBENCR5L.js";
69
+ import {
70
+ FIT_PADDING,
71
+ drawingBounds,
72
+ fitTransform
73
+ } from "./chunk-HRAU4VTB.js";
60
74
  import {
61
75
  referenceLabel
62
76
  } from "./chunk-RAKOB6IV.js";
63
- import {
64
- geneLabelCandidates
65
- } from "./chunk-DRG4236Y.js";
66
- import {
67
- nodesUnderBox
68
- } from "./chunk-FP4H7SFT.js";
69
77
  import {
70
78
  LABEL_CHAR_PX,
71
79
  LABEL_PAD,
@@ -77,8 +85,9 @@ import {
77
85
  resolveColorScheme
78
86
  } from "./chunk-JKJWSY4V.js";
79
87
  import {
80
- serializeEl
81
- } from "./chunk-NNODIW4U.js";
88
+ deletionDrawing,
89
+ deletionEdges
90
+ } from "./chunk-N6FECAXP.js";
82
91
  import {
83
92
  FACET_GAP_PX,
84
93
  FACET_PAD_PX,
@@ -87,15 +96,6 @@ import {
87
96
  facetGrid,
88
97
  facetSettingOf
89
98
  } from "./chunk-XV4P5KEQ.js";
90
- import {
91
- FIT_PADDING,
92
- drawingBounds,
93
- fitTransform
94
- } from "./chunk-FPTI3WAV.js";
95
- import {
96
- deletionDrawing,
97
- deletionEdges
98
- } from "./chunk-N6FECAXP.js";
99
99
 
100
100
  // src/figure.ts
101
101
  var FONT = 'font-family="Helvetica, Arial, sans-serif" font-size="11"';
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var version = "9.9.2";
2
+ var version = "9.10.0";
3
3
 
4
4
  export {
5
5
  version
@@ -3,19 +3,19 @@ import {
3
3
  fadeAbgr,
4
4
  packAbgr
5
5
  } from "./chunk-G2FD7S3C.js";
6
+ import {
7
+ baseEdgeCurves
8
+ } from "./chunk-WFB5TXRA.js";
6
9
  import {
7
10
  PATH_LIGHTNESS,
8
11
  PATH_SATURATION,
9
12
  nameHue,
10
13
  pathHueAt
11
- } from "./chunk-EDASNMLY.js";
14
+ } from "./chunk-XZ2BLAA6.js";
12
15
  import {
13
16
  meanDepth,
14
17
  nodeWidthPx
15
18
  } from "./chunk-PBENCR5L.js";
16
- import {
17
- baseEdgeCurves
18
- } from "./chunk-WFB5TXRA.js";
19
19
  import {
20
20
  referenceMidpoints
21
21
  } from "./chunk-ES2N6V56.js";
@@ -2,7 +2,7 @@ import {
2
2
  LIFT_BACKDROP_CSS,
3
3
  computeColorSchemeRange,
4
4
  getNodeColor
5
- } from "./chunk-F4BKWWLS.js";
5
+ } from "./chunk-4IYP43W6.js";
6
6
  import {
7
7
  abgrToCssRgba
8
8
  } from "./chunk-G2FD7S3C.js";
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  pathCssColor,
8
8
  pathGreyCssColor
9
- } from "./chunk-EDASNMLY.js";
9
+ } from "./chunk-XZ2BLAA6.js";
10
10
  import {
11
11
  pathOrigin
12
12
  } from "./chunk-IGJCTPFB.js";
@@ -2,16 +2,16 @@ import {
2
2
  alongRow,
3
3
  boxesGenes,
4
4
  rowPitch
5
- } from "./chunk-P6O4RSOQ.js";
6
- import {
7
- LABEL_CHAR_PX
8
- } from "./chunk-AB35TJST.js";
5
+ } from "./chunk-FJZ2TB46.js";
9
6
  import {
10
7
  el
11
8
  } from "./chunk-NNODIW4U.js";
12
9
  import {
13
10
  pathOrigin
14
11
  } from "./chunk-IGJCTPFB.js";
12
+ import {
13
+ LABEL_CHAR_PX
14
+ } from "./chunk-AB35TJST.js";
15
15
 
16
16
  // src/layout/walkStrip.ts
17
17
  function walkStripApplies(o) {
@@ -3,16 +3,16 @@ import {
3
3
  RAMP_GRADIENT_STOPS,
4
4
  rampHueCss,
5
5
  rampStops
6
- } from "./chunk-YS7VA5SI.js";
6
+ } from "./chunk-K5NYTPLC.js";
7
+ import {
8
+ el
9
+ } from "./chunk-NNODIW4U.js";
7
10
  import {
8
11
  REFERENCE_RAMP_ALT_CSS
9
- } from "./chunk-F4BKWWLS.js";
12
+ } from "./chunk-4IYP43W6.js";
10
13
  import {
11
14
  LABEL_CHAR_PX
12
15
  } from "./chunk-AB35TJST.js";
13
- import {
14
- el
15
- } from "./chunk-NNODIW4U.js";
16
16
  import {
17
17
  ROW_HEIGHT_PX
18
18
  } from "./chunk-CPMHA4W5.js";
@@ -6,7 +6,7 @@ import {
6
6
  hasTubeMapPaths,
7
7
  tubeMapLayout,
8
8
  tubeMapReferenceLayout
9
- } from "./chunk-HOZI3FBG.js";
9
+ } from "./chunk-CXKZYLYS.js";
10
10
  import {
11
11
  anchoredLayout
12
12
  } from "./chunk-L3O7AWLI.js";
@@ -1,9 +1,12 @@
1
- import {
2
- orientToReference
3
- } from "./chunk-PUG7LXDF.js";
4
1
  import {
5
2
  seededNodes
6
3
  } from "./chunk-IGVV37VI.js";
4
+ import {
5
+ smoothChain
6
+ } from "./chunk-OPPVSPEF.js";
7
+ import {
8
+ orientToReference
9
+ } from "./chunk-PUG7LXDF.js";
7
10
  import {
8
11
  convertGFAToGraph
9
12
  } from "./chunk-J7YKQ5YW.js";
@@ -148,11 +151,13 @@ async function forceLayout(graph, settings, engine) {
148
151
  const drawn = new Map(
149
152
  scaling.nodes.map((n) => [n.id, drawnNodeLength(scaling.opts, n.length)])
150
153
  );
151
- const positions = splitRuns(
152
- result.nodePositions,
153
- merged.runs,
154
- (id) => drawn.get(id) ?? 0
154
+ const smoothed = Object.fromEntries(
155
+ Object.entries(result.nodePositions).map(([id, line]) => [
156
+ id,
157
+ smoothChain(line)
158
+ ])
155
159
  );
160
+ const positions = splitRuns(smoothed, merged.runs, (id) => drawn.get(id) ?? 0);
156
161
  const { nodePositions, deletionRoutes } = takeRoutes(
157
162
  graph.nodes.some(isBackbone) ? orientToReference(graph, positions) : positions,
158
163
  routed.routes
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ENGINE_DEFAULTS
3
- } from "./chunk-FPTI3WAV.js";
3
+ } from "./chunk-HRAU4VTB.js";
4
4
 
5
5
  // src/figureSettings.ts
6
6
  var FIGURE_DEFAULTS = {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  REFERENCE_RAMP_MAX_HUE
3
- } from "./chunk-F4BKWWLS.js";
3
+ } from "./chunk-4IYP43W6.js";
4
4
 
5
5
  // src/referenceRampCss.ts
6
6
  function rampHueCss(hue) {
@@ -2,7 +2,7 @@ import {
2
2
  REFERENCE_RAMP_ALT_COLOR,
3
3
  REFERENCE_RAMP_MAX_HUE,
4
4
  hslToRgb
5
- } from "./chunk-F4BKWWLS.js";
5
+ } from "./chunk-4IYP43W6.js";
6
6
  import {
7
7
  packAbgr
8
8
  } from "./chunk-G2FD7S3C.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pathSteps
3
- } from "./chunk-HOZI3FBG.js";
3
+ } from "./chunk-CXKZYLYS.js";
4
4
  import {
5
5
  pathOrigin
6
6
  } from "./chunk-IGJCTPFB.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  encodedColor,
3
3
  resolveEncoding
4
- } from "./chunk-F5BYHLIN.js";
4
+ } from "./chunk-KYY5363X.js";
5
5
  import {
6
6
  pathOrigin
7
7
  } from "./chunk-IGJCTPFB.js";
@@ -0,0 +1,292 @@
1
+ import {
2
+ layoutEngine
3
+ } from "./chunk-VK6XMP6B.js";
4
+ import {
5
+ layoutModeByValue
6
+ } from "./chunk-FUUJ76KD.js";
7
+ import {
8
+ parseRegion
9
+ } from "./chunk-73RSLGZT.js";
10
+ import {
11
+ layoutGeometryInputs
12
+ } from "./chunk-LOCJN3BZ.js";
13
+ import {
14
+ version
15
+ } from "./chunk-2VTM3DHG.js";
16
+ import {
17
+ axisScaleOf
18
+ } from "./chunk-PT37VS5B.js";
19
+ import {
20
+ facetLifts,
21
+ walkLift
22
+ } from "./chunk-MVMP6AGI.js";
23
+ import {
24
+ walkKey
25
+ } from "./chunk-2LQ5BWT7.js";
26
+ import {
27
+ buildGeometry,
28
+ computeReferenceRamp
29
+ } from "./chunk-4IYP43W6.js";
30
+ import {
31
+ abgrAlpha,
32
+ abgrBlue,
33
+ abgrGreen,
34
+ abgrRed
35
+ } from "./chunk-G2FD7S3C.js";
36
+ import {
37
+ pathLegend,
38
+ walkLabelsOf
39
+ } from "./chunk-XZ2BLAA6.js";
40
+ import {
41
+ drawingBounds,
42
+ engineSettingsOf,
43
+ fitTransform,
44
+ forceLayout,
45
+ loadGraph
46
+ } from "./chunk-HRAU4VTB.js";
47
+ import {
48
+ referenceLabel
49
+ } from "./chunk-RAKOB6IV.js";
50
+ import {
51
+ resolveColorScheme
52
+ } from "./chunk-JKJWSY4V.js";
53
+ import {
54
+ deletionDrawing,
55
+ deletionEdges
56
+ } from "./chunk-N6FECAXP.js";
57
+ import {
58
+ isBackbone
59
+ } from "./chunk-FYQWPEEY.js";
60
+ import {
61
+ facetCells,
62
+ facetSettingOf
63
+ } from "./chunk-XV4P5KEQ.js";
64
+
65
+ // src/figureData.ts
66
+ function columns(keys) {
67
+ const out = Object.fromEntries(
68
+ keys.map((k) => [k, []])
69
+ );
70
+ return {
71
+ out,
72
+ push(row) {
73
+ for (const k of keys) {
74
+ out[k].push(row[k]);
75
+ }
76
+ }
77
+ };
78
+ }
79
+ var hex = (v) => v.toString(16).padStart(2, "0");
80
+ var cssHex = (c) => `#${hex(abgrRed(c))}${hex(abgrGreen(c))}${hex(abgrBlue(c))}`;
81
+ var alphaOf = (c) => abgrAlpha(c) / 255;
82
+ function figureData(graph, layout, o = {}) {
83
+ if (layout.tubeMap) {
84
+ throw new Error("figure data has no tables for a tube map yet");
85
+ }
86
+ const width = o.width ?? 1200;
87
+ const height = o.height ?? 800;
88
+ const region = o.region;
89
+ const pixelRows = layout.pixelRows ?? false;
90
+ const bounds = drawingBounds(layout, {
91
+ region: o.fitToDrawing ? void 0 : region
92
+ });
93
+ const fit = fitTransform(bounds, width, height, pixelRows);
94
+ if (!fit) {
95
+ throw new Error("the layout drew nothing to fit");
96
+ }
97
+ const axis = axisScaleOf(fit.scale, pixelRows);
98
+ const nodeById = new Map(graph.nodes.map((node) => [node.id, node]));
99
+ const colorScheme = resolveColorScheme(o.colorScheme ?? "auto", graph);
100
+ const rampDomain = o.colorDomain ?? region;
101
+ const referenceRamp = colorScheme === "reference-position" ? computeReferenceRamp(graph, rampDomain) : void 0;
102
+ const drawnDeletions = deletionDrawing(
103
+ graph,
104
+ deletionEdges(graph),
105
+ o.showDeletionEdges
106
+ );
107
+ const layers = o.walks ?? [];
108
+ const walkRamp = layers.some((l) => l.color?.field === "reference") ? referenceRamp ?? computeReferenceRamp(graph, rampDomain) : void 0;
109
+ const lift = layers.length > 0 ? walkLift(graph, layers, walkRamp) : void 0;
110
+ const facet = facetSettingOf(o.facet);
111
+ const facetted = facet.field && lift && lift.walks.length > 1 ? facetLifts(graph, lift, layers, walkRamp) : void 0;
112
+ const labels = walkLabelsOf(
113
+ graph.paths?.length ? pathLegend(graph.paths) : []
114
+ );
115
+ const labelOf = (name) => labels.get(name) ?? name;
116
+ const referenceName = o.referenceName ?? referenceLabel(graph, region);
117
+ const reference = lift?.referenceDomain && {
118
+ ...lift.referenceDomain,
119
+ name: referenceName
120
+ };
121
+ const panels = [];
122
+ if (facetted) {
123
+ const place = facetCells(
124
+ facetted.map((p) => p.walks[0].name),
125
+ facet.field || "walk",
126
+ facet.domain
127
+ );
128
+ const ordered = facetted.map((panel, i) => ({ panel, cell: place.cells[i] })).sort((a, b) => a.cell - b.cell);
129
+ for (const { panel } of ordered) {
130
+ const walk = panel.walks[0];
131
+ const key = walkKey(walk, reference);
132
+ panels.push({
133
+ highlight: panel,
134
+ name: labelOf(walk.name),
135
+ key: key.delta + key.outside + key.reversed,
136
+ range: key.scale ?? ""
137
+ });
138
+ }
139
+ } else {
140
+ panels.push({ highlight: lift, name: "", key: "", range: "" });
141
+ }
142
+ const nodes = columns([
143
+ "panel",
144
+ "node",
145
+ "stroke",
146
+ "x",
147
+ "y",
148
+ "color",
149
+ "alpha",
150
+ "width"
151
+ ]);
152
+ const edges = columns([
153
+ "panel",
154
+ "edge",
155
+ "curve",
156
+ "x0",
157
+ "y0",
158
+ "cx0",
159
+ "cy0",
160
+ "cx1",
161
+ "cy1",
162
+ "x1",
163
+ "y1",
164
+ "color",
165
+ "alpha",
166
+ "width",
167
+ "deletion"
168
+ ]);
169
+ const arrows = columns([
170
+ "panel",
171
+ "edge",
172
+ "x",
173
+ "y",
174
+ "angle",
175
+ "length",
176
+ "halfWidth",
177
+ "color",
178
+ "alpha"
179
+ ]);
180
+ for (const { highlight, name: panel } of panels) {
181
+ const batch = buildGeometry({
182
+ ...layoutGeometryInputs(layout, drawnDeletions),
183
+ graph,
184
+ nodeById,
185
+ colorScheme,
186
+ contigThickness: o.contigThickness ?? 6,
187
+ connectorThickness: o.connectorThickness ?? 2,
188
+ drawPaths: false,
189
+ nodeWidth: o.nodeWidth ?? "depth",
190
+ linearLayout: o.linearLayout,
191
+ highlight,
192
+ axis,
193
+ referenceRamp
194
+ });
195
+ for (const [node, run] of batch.nodeStrokeRuns) {
196
+ for (let i = run.start; i < run.start + run.count; i++) {
197
+ const s = batch.nodeStrokes[i];
198
+ for (const p of s.points) {
199
+ nodes.push({
200
+ panel,
201
+ node,
202
+ stroke: i,
203
+ x: p.x,
204
+ y: p.y,
205
+ color: cssHex(s.color),
206
+ alpha: alphaOf(s.color),
207
+ width: s.thickness * 2
208
+ });
209
+ }
210
+ }
211
+ }
212
+ for (const [edge, run] of batch.edgeCurveRuns) {
213
+ for (let i = run.start; i < run.start + run.count; i++) {
214
+ const b = batch.edgeCurves[i];
215
+ for (const c of b.curves) {
216
+ edges.push({
217
+ panel,
218
+ edge,
219
+ curve: i,
220
+ ...c,
221
+ color: cssHex(b.color),
222
+ alpha: alphaOf(b.color),
223
+ width: b.thickness * 2,
224
+ deletion: drawnDeletions.bypassed.has(edge)
225
+ });
226
+ }
227
+ }
228
+ }
229
+ for (const [edge, run] of batch.arrowRuns) {
230
+ for (let i = run.start; i < run.start + run.count; i++) {
231
+ const a = batch.arrows[i];
232
+ arrows.push({
233
+ panel,
234
+ edge,
235
+ x: a.x,
236
+ y: a.y,
237
+ angle: a.angle,
238
+ length: a.length,
239
+ halfWidth: a.halfWidth,
240
+ color: cssHex(a.color),
241
+ alpha: alphaOf(a.color)
242
+ });
243
+ }
244
+ }
245
+ }
246
+ return {
247
+ meta: {
248
+ generator: `@jbrowse/bandage-core@${version}`,
249
+ width,
250
+ scaleX: axis.scaleX,
251
+ scaleY: axis.scaleY,
252
+ pixelRows,
253
+ referenceAxis: layout.referenceAxis ?? false,
254
+ colorScheme,
255
+ referenceName: referenceName ?? null
256
+ },
257
+ panels: {
258
+ panel: panels.map((p) => p.name),
259
+ key: panels.map((p) => p.key),
260
+ range: panels.map((p) => p.range)
261
+ },
262
+ nodes: nodes.out,
263
+ edges: edges.out,
264
+ arrows: arrows.out,
265
+ nodeInfo: {
266
+ node: graph.nodes.map((n) => n.id),
267
+ name: graph.nodes.map((n) => n.name),
268
+ length: graph.nodes.map((n) => n.length),
269
+ depth: graph.nodes.map((n) => n.depth),
270
+ backbone: graph.nodes.map((n) => isBackbone(n))
271
+ },
272
+ rowLabels: {
273
+ label: (layout.rowLabels ?? []).map((r) => r.label),
274
+ y: (layout.rowLabels ?? []).map((r) => r.y)
275
+ }
276
+ };
277
+ }
278
+ async function gfaFigureData(text, name, spec = {}) {
279
+ const region = spec.region ? parseRegion(spec.region) : void 0;
280
+ const graph = loadGraph(text, name, { referencePath: spec.referencePath });
281
+ const layout = layoutModeByValue(spec.layout ?? "force").run(graph, region) ?? (await forceLayout(graph, engineSettingsOf(spec), layoutEngine)).result;
282
+ return figureData(graph, layout, {
283
+ ...spec,
284
+ region,
285
+ walks: spec.walks?.map((w) => typeof w === "string" ? { walk: w } : w)
286
+ });
287
+ }
288
+
289
+ export {
290
+ figureData,
291
+ gfaFigureData
292
+ };
@@ -0,0 +1,57 @@
1
+ // src/layout/smoothChains.ts
2
+ var STEP_TURN = Math.PI / 24;
3
+ function turnAt(line, i) {
4
+ const a = line[i - 1];
5
+ const b = line[i];
6
+ const c = line[i + 1];
7
+ if (!a || !c) {
8
+ return 0;
9
+ }
10
+ const t = Math.abs(
11
+ Math.atan2(c.y - b.y, c.x - b.x) - Math.atan2(b.y - a.y, b.x - a.x)
12
+ );
13
+ return t > Math.PI ? 2 * Math.PI - t : t;
14
+ }
15
+ function centripetal(p0, p1, p2, p3, u) {
16
+ const knot = (a, b) => Math.max(Math.hypot(b.x - a.x, b.y - a.y) ** 0.5, 1e-9);
17
+ const t1 = knot(p0, p1);
18
+ const t2 = t1 + knot(p1, p2);
19
+ const t3 = t2 + knot(p2, p3);
20
+ const t = t1 + u * (t2 - t1);
21
+ const lerp = (a, b, ta, tb) => {
22
+ const f = (t - ta) / (tb - ta);
23
+ return { x: a.x + (b.x - a.x) * f, y: a.y + (b.y - a.y) * f };
24
+ };
25
+ const a1 = lerp(p0, p1, 0, t1);
26
+ const a2 = lerp(p1, p2, t1, t2);
27
+ const a3 = lerp(p2, p3, t2, t3);
28
+ return lerp(lerp(a1, a2, 0, t2), lerp(a2, a3, t1, t3), t1, t2);
29
+ }
30
+ var reflect = (p, about) => ({
31
+ x: 2 * about.x - p.x,
32
+ y: 2 * about.y - p.y
33
+ });
34
+ function smoothChain(line) {
35
+ if (line.length < 3) {
36
+ return line;
37
+ }
38
+ const out = [line[0]];
39
+ for (let i = 0; i + 1 < line.length; i++) {
40
+ const p1 = line[i];
41
+ const p2 = line[i + 1];
42
+ const steps = Math.ceil(
43
+ Math.max(turnAt(line, i), turnAt(line, i + 1)) / STEP_TURN
44
+ );
45
+ const p0 = line[i - 1] ?? reflect(p2, p1);
46
+ const p3 = line[i + 2] ?? reflect(p1, p2);
47
+ for (let s = 1; s < steps; s++) {
48
+ out.push(centripetal(p0, p1, p2, p3, s / steps));
49
+ }
50
+ out.push(p2);
51
+ }
52
+ return out;
53
+ }
54
+
55
+ export {
56
+ smoothChain
57
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  clampZoom
3
- } from "./chunk-FPTI3WAV.js";
3
+ } from "./chunk-HRAU4VTB.js";
4
4
 
5
5
  // src/viewport.ts
6
6
  function axisScaleOf(scale, pixelRows) {