@mstone6969/graph 0.1.0 → 0.2.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 (238) hide show
  1. package/README.md +111 -14
  2. package/dist/ExcelWriter-3ZSYUH4T.cjs +154 -0
  3. package/dist/GraphType.js +24 -38
  4. package/dist/PdfWriter-6HJFYMCO.cjs +205 -0
  5. package/dist/catalog-YWX6FHRM.cjs +8 -0
  6. package/dist/catalog.js +5 -1
  7. package/dist/charts/bars/index.js +2 -12
  8. package/dist/charts/comparison/EffectForestPlot.js +1 -1
  9. package/dist/charts/comparison/index.js +1 -8
  10. package/dist/charts/demography/Nomogram.js +3 -3
  11. package/dist/charts/density/HexbinChart.js +6 -4
  12. package/dist/charts/diagrams/ArchitectureCanvas.js +68 -0
  13. package/dist/charts/diagrams/ArchitectureDiagram.js +331 -0
  14. package/dist/charts/diagrams/ArchitectureLayout.js +106 -0
  15. package/dist/charts/diagrams/ArchitectureLinkLabels.js +78 -0
  16. package/dist/charts/diagrams/ArchitectureModel.js +108 -0
  17. package/dist/charts/diagrams/ArchitectureRouter.js +348 -0
  18. package/dist/charts/diagrams/ArchitectureSamples.js +312 -0
  19. package/dist/charts/diagrams/ArchitectureShapes.js +130 -0
  20. package/dist/charts/diagrams/ArchitectureText.js +25 -0
  21. package/dist/charts/diagrams/DiagramText.js +38 -0
  22. package/dist/charts/diagrams/EntityRelationshipDiagram.js +465 -0
  23. package/dist/charts/diagrams/ErCrowsFoot.js +33 -0
  24. package/dist/charts/diagrams/ErSamples.js +205 -0
  25. package/dist/charts/diagrams/ErSchema.js +122 -0
  26. package/dist/charts/diagrams/LogicCircuit.js +154 -0
  27. package/dist/charts/diagrams/LogicCircuitLayout.js +600 -0
  28. package/dist/charts/diagrams/LogicCircuitSamples.js +66 -0
  29. package/dist/charts/diagrams/LogicGateDiagram.js +216 -0
  30. package/dist/charts/diagrams/LogicGateSymbol.js +113 -0
  31. package/dist/charts/diagrams/NetworkTopologyDiagram.js +247 -0
  32. package/dist/charts/diagrams/SequenceDiagram.js +351 -0
  33. package/dist/charts/diagrams/SequenceLayout.js +422 -0
  34. package/dist/charts/diagrams/SequenceModel.js +221 -0
  35. package/dist/charts/diagrams/TopologyLayout.js +143 -0
  36. package/dist/charts/diagrams/architectureEnums.js +50 -0
  37. package/dist/charts/diagrams/index.js +26 -0
  38. package/dist/charts/diagrams/logicEnums.js +42 -0
  39. package/dist/charts/diagrams/sequenceEnums.js +40 -0
  40. package/dist/charts/distribution/HistogramChart.js +25 -3
  41. package/dist/charts/distribution/index.js +1 -3
  42. package/dist/charts/earthscience/HovmollerDiagram.js +477 -0
  43. package/dist/charts/earthscience/HovmollerEnums.js +42 -0
  44. package/dist/charts/earthscience/HovmollerField.js +180 -0
  45. package/dist/charts/earthscience/HovmollerSample.js +40 -0
  46. package/dist/charts/earthscience/HovmollerSpeed.js +71 -0
  47. package/dist/charts/earthscience/index.js +10 -2
  48. package/dist/charts/engineering/ConstellationDiagram.js +26 -6
  49. package/dist/charts/engineering/EyeDiagram.js +2 -1
  50. package/dist/charts/engineering/PoleZeroPlot.js +32 -8
  51. package/dist/charts/financial/RelativeStrengthRotation.js +434 -0
  52. package/dist/charts/financial/RelativeStrengthRotationMath.js +71 -0
  53. package/dist/charts/financial/RelativeStrengthRotationSamples.js +27 -0
  54. package/dist/charts/financial/index.js +5 -3
  55. package/dist/charts/flow/index.js +1 -5
  56. package/dist/charts/frameworks/AnsoffMatrix.js +523 -0
  57. package/dist/charts/frameworks/FrameworkText.js +98 -0
  58. package/dist/charts/frameworks/NpsGauge.js +279 -0
  59. package/dist/charts/frameworks/NpsSurvey.js +58 -0
  60. package/dist/charts/frameworks/PerceptualMap.js +419 -0
  61. package/dist/charts/frameworks/PerceptualProjection.js +142 -0
  62. package/dist/charts/frameworks/PositioningSamples.js +191 -0
  63. package/dist/charts/frameworks/RaciMatrix.js +458 -0
  64. package/dist/charts/frameworks/RaciPlan.js +81 -0
  65. package/dist/charts/frameworks/RaciSamples.js +76 -0
  66. package/dist/charts/frameworks/SwotMatrix.js +358 -0
  67. package/dist/charts/frameworks/SwotSamples.js +85 -0
  68. package/dist/charts/frameworks/VanWestendorpChart.js +187 -0
  69. package/dist/charts/frameworks/VanWestendorpSurvey.js +197 -0
  70. package/dist/charts/frameworks/index.js +26 -0
  71. package/dist/charts/frameworks/raciEnums.js +30 -0
  72. package/dist/charts/frameworks/swotEnums.js +34 -0
  73. package/dist/charts/genomics/CircosPlot.js +1 -1
  74. package/dist/charts/geoflows/GeoFlowChart.js +2 -2
  75. package/dist/charts/geoflows/GeoFlowSample.js +2 -1
  76. package/dist/charts/geomaps/FloorPlanMap.js +324 -0
  77. package/dist/charts/geomaps/FloorPlanModel.js +179 -0
  78. package/dist/charts/geomaps/FloorPlanSamples.js +416 -0
  79. package/dist/charts/geomaps/GeoLand.js +2 -2
  80. package/dist/charts/geomaps/GeoSamples.js +2 -1
  81. package/dist/charts/geomaps/GraticuleMap.js +2 -2
  82. package/dist/charts/geomaps/RoomLabelFit.js +200 -0
  83. package/dist/charts/geomaps/TissotMap.js +2 -2
  84. package/dist/charts/geomaps/index.js +8 -4
  85. package/dist/charts/hierarchy/SunburstChart.js +17 -10
  86. package/dist/charts/hierarchy/index.js +2 -11
  87. package/dist/charts/indicators/BulletChart.js +8 -2
  88. package/dist/charts/indicators/SpeedometerChart.js +1 -1
  89. package/dist/charts/indicators/ThermometerChart.js +1 -1
  90. package/dist/charts/lifescience/LoessFit.js +113 -0
  91. package/dist/charts/lifescience/MaPlot.js +337 -0
  92. package/dist/charts/lifescience/MaPlotSamples.js +35 -0
  93. package/dist/charts/lifescience/OncoGlyph.js +137 -0
  94. package/dist/charts/lifescience/OncoPrint.js +373 -0
  95. package/dist/charts/lifescience/OncoPrintMatrix.js +107 -0
  96. package/dist/charts/lifescience/OncoPrintSamples.js +142 -0
  97. package/dist/charts/lifescience/PedigreeChart.js +306 -0
  98. package/dist/charts/lifescience/PedigreeLayout.js +261 -0
  99. package/dist/charts/lifescience/PedigreeRows.js +70 -0
  100. package/dist/charts/lifescience/PedigreeSamples.js +161 -0
  101. package/dist/charts/lifescience/PedigreeSymbol.js +47 -0
  102. package/dist/charts/lifescience/RamachandranPlot.js +364 -0
  103. package/dist/charts/lifescience/RamachandranRegions.js +2712 -0
  104. package/dist/charts/lifescience/RamachandranSamples.js +235 -0
  105. package/dist/charts/lifescience/index.js +25 -0
  106. package/dist/charts/lifescience/pedigreeEnums.js +21 -0
  107. package/dist/charts/lifescience/ramachandranEnums.js +34 -0
  108. package/dist/charts/linesareas/DualAxisChart.js +1 -1
  109. package/dist/charts/linesareas/LineEnums.js +1 -15
  110. package/dist/charts/linesareas/MultiLineChart.js +1 -1
  111. package/dist/charts/linesareas/TrendChart.js +15 -5
  112. package/dist/charts/linesareas/index.js +2 -6
  113. package/dist/charts/massive/MassiveChart.js +3 -2
  114. package/dist/charts/mathematical/FourierSeriesChart.js +7 -1
  115. package/dist/charts/mathematical/index.js +2 -6
  116. package/dist/charts/matrix/GridPlot.js +27 -2
  117. package/dist/charts/matrix/TilegramChart.js +2 -2
  118. package/dist/charts/mlcharts/AttentionGrid.js +79 -0
  119. package/dist/charts/mlcharts/AttentionHeatmap.js +329 -0
  120. package/dist/charts/mlcharts/AttentionModel.js +132 -0
  121. package/dist/charts/mlcharts/AttentionSamples.js +82 -0
  122. package/dist/charts/mlcharts/CellNumber.js +8 -0
  123. package/dist/charts/mlcharts/CurveDiagnosticSamples.js +95 -0
  124. package/dist/charts/mlcharts/CurvePickMark.js +31 -0
  125. package/dist/charts/mlcharts/DecisionBoundaryChart.js +316 -0
  126. package/dist/charts/mlcharts/DecisionSamples.js +60 -0
  127. package/dist/charts/mlcharts/DecisionSurface.js +130 -0
  128. package/dist/charts/mlcharts/DistinctTicks.js +13 -0
  129. package/dist/charts/mlcharts/ElbowMath.js +153 -0
  130. package/dist/charts/mlcharts/ElbowPlot.js +273 -0
  131. package/dist/charts/mlcharts/ExplainabilitySamples.js +70 -0
  132. package/dist/charts/mlcharts/FeatureImportanceChart.js +150 -0
  133. package/dist/charts/mlcharts/ImportanceRanking.js +98 -0
  134. package/dist/charts/mlcharts/LearningCurveChart.js +276 -0
  135. package/dist/charts/mlcharts/LearningCurveMath.js +92 -0
  136. package/dist/charts/mlcharts/PartialDependence.js +92 -0
  137. package/dist/charts/mlcharts/PartialDependencePlot.js +225 -0
  138. package/dist/charts/mlcharts/WideLabel.js +28 -0
  139. package/dist/charts/mlcharts/curveDiagnosticEnums.js +37 -0
  140. package/dist/charts/mlcharts/index.js +32 -0
  141. package/dist/charts/proportion/index.js +5 -9
  142. package/dist/charts/scatter/CategoryScatterBase.js +1 -4
  143. package/dist/charts/scatter/ConnectedScatter.js +7 -4
  144. package/dist/charts/scatter/MarginalScatter.js +13 -8
  145. package/dist/charts/scatter/index.js +4 -17
  146. package/dist/charts/scientific/SpectrogramChart.js +9 -3
  147. package/dist/charts/scientific/index.js +2 -2
  148. package/dist/charts/signals/index.js +3 -13
  149. package/dist/charts/statistics/LorenzCurve.js +7 -4
  150. package/dist/charts/threebars/Candlestick3DChart.js +18 -2
  151. package/dist/charts/threeglobe/GlobeChart.js +2 -2
  152. package/dist/charts/threeglobe/GlobeSamples.js +2 -1
  153. package/dist/charts/threeglobe/RingGlobe.js +1 -1
  154. package/dist/charts/threenetwork/ConeTreeChart.js +2 -1
  155. package/dist/charts/threenetwork/Gantt3DChart.js +3 -2
  156. package/dist/charts/threesurfaces/Ridgeline3DChart.js +22 -4
  157. package/dist/charts/threevolume/LorenzAttractor.js +19 -0
  158. package/dist/charts/threevolume/VolumeRaycastChart.js +4 -3
  159. package/dist/charts/threevolume/volumeEnums.js +1 -0
  160. package/dist/charts/timeline/index.js +2 -10
  161. package/dist/chunk-753UBLV2.cjs +33 -0
  162. package/dist/chunk-VX54A7KA.cjs +17 -0
  163. package/dist/{chunk-W5GAAAZY.cjs → chunk-WAODDPYX.cjs} +24874 -17620
  164. package/dist/chunk-Z3JPIJSC.cjs +338 -0
  165. package/dist/core/CartesianChart.js +87 -11
  166. package/dist/core/Chart.js +63 -15
  167. package/dist/core/Chart2D.js +54 -17
  168. package/dist/core/Chart3D.js +56 -20
  169. package/dist/core/ChartExportError.js +2 -0
  170. package/dist/core/ChartExporter.js +50 -8
  171. package/dist/core/ColumnCheck.js +53 -0
  172. package/dist/core/Context2D.js +29 -15
  173. package/dist/core/Context3D.js +7 -2
  174. package/dist/core/ExcelWriter.js +152 -0
  175. package/dist/core/ExportText.js +28 -0
  176. package/dist/core/MarkOrigin.js +88 -0
  177. package/dist/core/MarkStyle.js +294 -0
  178. package/dist/core/Palette.js +27 -7
  179. package/dist/core/PdfPage.js +13 -0
  180. package/dist/core/PdfWriter.js +245 -0
  181. package/dist/core/Scales.js +52 -2
  182. package/dist/core/SceneOverlay.js +4 -4
  183. package/dist/core/TextFit.js +37 -0
  184. package/dist/core/Theme.js +28 -1
  185. package/dist/core/enums.js +33 -1
  186. package/dist/core/pathMorph.js +15 -0
  187. package/dist/data/SampleData.js +1 -17
  188. package/dist/data/WorldSample.js +23 -0
  189. package/dist/index.cjs +810 -691
  190. package/dist/index.d.cts +8390 -2925
  191. package/dist/index.d.ts +8392 -2927
  192. package/dist/index.js +106 -56
  193. package/dist/react/ChartView.js +18 -8
  194. package/dist/react/GraphHandle.js +2 -0
  195. package/dist/react/components.js +74 -116
  196. package/package.json +13 -3
  197. package/dist/catalog-4UP2YFNR.cjs +0 -7
  198. package/dist/charts/bars/BulletBar.js +0 -184
  199. package/dist/charts/bars/ErrorBarColumn.js +0 -147
  200. package/dist/charts/bars/HistogramBar.js +0 -217
  201. package/dist/charts/bars/MarimekkoBar.js +0 -191
  202. package/dist/charts/bars/ParetoBar.js +0 -143
  203. package/dist/charts/comparison/PanelChart.js +0 -70
  204. package/dist/charts/comparison/SmallMultipleBars.js +0 -134
  205. package/dist/charts/comparison/SpanChart.js +0 -118
  206. package/dist/charts/comparison/TrellisChart.js +0 -158
  207. package/dist/charts/distribution/RidgeSlabs3DChart.js +0 -169
  208. package/dist/charts/financial/Candlestick3D.js +0 -157
  209. package/dist/charts/flow/BumpFlow.js +0 -212
  210. package/dist/charts/flow/StreamFlow.js +0 -174
  211. package/dist/charts/geomaps/ThiessenMap.js +0 -106
  212. package/dist/charts/hierarchy/ConeTree3D.js +0 -135
  213. package/dist/charts/hierarchy/Hierarchy3DChart.js +0 -27
  214. package/dist/charts/hierarchy/SpherePack3D.js +0 -81
  215. package/dist/charts/hierarchy/SunburstTower3D.js +0 -93
  216. package/dist/charts/hierarchy/TreemapSkyline3D.js +0 -98
  217. package/dist/charts/linesareas/ConnectedScatterTime.js +0 -206
  218. package/dist/charts/linesareas/SmallMultipleLines.js +0 -153
  219. package/dist/charts/mathematical/ParametricSurface3D.js +0 -234
  220. package/dist/charts/mathematical/StrangeAttractor3D.js +0 -251
  221. package/dist/charts/proportion/ConeFunnel.js +0 -126
  222. package/dist/charts/proportion/ExtrudedPieChart.js +0 -123
  223. package/dist/charts/scatter/BeeswarmScatter.js +0 -151
  224. package/dist/charts/scatter/BinnedScatterBase.js +0 -51
  225. package/dist/charts/scatter/ContourScatter.js +0 -116
  226. package/dist/charts/scatter/GridBinScatter.js +0 -98
  227. package/dist/charts/scatter/HexbinScatter.js +0 -74
  228. package/dist/charts/scatter/StripScatter.js +0 -107
  229. package/dist/charts/scatter/SunflowerScatter.js +0 -109
  230. package/dist/charts/signals/ConstellationChart.js +0 -153
  231. package/dist/charts/signals/CorrelogramChart.js +0 -171
  232. package/dist/charts/signals/EyeDiagramChart.js +0 -155
  233. package/dist/charts/signals/PoleZeroChart.js +0 -164
  234. package/dist/charts/signals/SpectrogramChart.js +0 -79
  235. package/dist/charts/timeline/CalendarSkylineChart.js +0 -128
  236. package/dist/charts/timeline/ScheduleBlocksChart.js +0 -119
  237. package/dist/charts/timeline/SpiralTimeline.js +0 -154
  238. package/dist/charts/timeline/StreamTimeline.js +0 -141
@@ -0,0 +1,434 @@
1
+ import { CartesianChart } from "../../core/CartesianChart.js";
2
+ import { ChartFamily, CurveKind, DataShape, Dimension } from "../../core/enums.js";
3
+ import { Scales } from "../../core/Scales.js";
4
+ import { FinanceInk } from "./FinanceInk.js";
5
+ import { Quotes } from "./Quotes.js";
6
+ import { RelativeStrengthRotationMath, RotationFrame, RotationMethod, RotationQuadrant } from "./RelativeStrengthRotationMath.js";
7
+ import { RelativeStrengthRotationSamples } from "./RelativeStrengthRotationSamples.js";
8
+ import { format, group, line, precisionFixed, scaleLinear, tickStep } from "d3";
9
+ // src/charts/financial/RelativeStrengthRotation.ts
10
+ var CENTER = 100;
11
+ var PAD = 1.12;
12
+ var HEAD = 6;
13
+ var NODE = 4;
14
+ var LABEL_CHARS = 12;
15
+ var CHAR = 6.2;
16
+ /** Polarity of each quadrant: the sign is which side of the benchmark it is on, the size whether momentum agrees. The warm pole is the weak side. */
17
+ var TINT = {
18
+ [RotationQuadrant.Leading]: -.9,
19
+ [RotationQuadrant.Weakening]: -.35,
20
+ [RotationQuadrant.Improving]: .35,
21
+ [RotationQuadrant.Lagging]: .9
22
+ };
23
+ var dayLabel = (value, when) => when ? when.toISOString().slice(0, 10) : String(value ?? "");
24
+ var shorten = (text, chars) => text.length > chars ? `${text.slice(0, Math.max(1, chars - 1))}…` : text;
25
+ var wholeAtLeast = (value, floor, fallback) => Number.isFinite(value) ? Math.max(floor, Math.round(value)) : fallback;
26
+ var overlaps = (a, b) => a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom;
27
+ /**
28
+ * Relative strength rotation: use it to compare many symbols against one benchmark and see which are
29
+ * rotating through Leading, Weakening, Lagging and Improving, normally clockwise.
30
+ *
31
+ * Method: Julius de Kempenaer's RRG, whose JdK RS-Ratio and RS-Momentum formulas are proprietary and
32
+ * unpublished, so computed values are an approximation and will not match licensed RRG software.
33
+ * With relative strength `RS = 100 * price / benchmark`:
34
+ * - `RotationMethod.ZScore`, the rolling z-score recipe circulated in public reimplementations:
35
+ * `ratio = 100 + z(RS, window)`, `momentum = 100 + z(ROC(ratio, lookback), window)`.
36
+ * - `RotationMethod.RatioToAverage`, after Mansfield relative strength as in Weinstein (1988):
37
+ * `ratio = 100 * RS / SMA(RS, window)`, `momentum = 100 + ROC(ratio, lookback)`.
38
+ * RS first passes through `EMA(RS, smoothing)`, 5 by default, because RRG tails are known to be smoothed
39
+ * and an unsmoothed z-score scribbles on real prices. That default is this library's choice; 1 turns it off.
40
+ * Supply `ratio` and `momentum` columns to draw licensed or other values unchanged.
41
+ */
42
+ var RelativeStrengthRotation = class RelativeStrengthRotation extends CartesianChart {
43
+ static meta = {
44
+ id: "relative-strength-rotation",
45
+ name: "Relative strength rotation",
46
+ family: ChartFamily.Financial,
47
+ dimension: Dimension.Two,
48
+ shape: DataShape.Table,
49
+ description: "Tracks symbols against a benchmark through the Leading, Weakening, Lagging and Improving quadrants, using a documented approximation of the proprietary JdK RS-Ratio and RS-Momentum, or values you supply.",
50
+ tags: [
51
+ "rrg",
52
+ "rs-ratio",
53
+ "rs-momentum",
54
+ "sector rotation",
55
+ "relative strength",
56
+ "momentum",
57
+ "benchmark"
58
+ ],
59
+ sample: (seed) => RelativeStrengthRotationSamples.prices(seed),
60
+ variants: {
61
+ method: [RotationMethod.ZScore, RotationMethod.RatioToAverage],
62
+ tail: [
63
+ 10,
64
+ 5,
65
+ 20
66
+ ],
67
+ curve: [CurveKind.Linear, CurveKind.CatmullRom],
68
+ frame: [RotationFrame.Centered, RotationFrame.Fitted],
69
+ nodes: [true, false]
70
+ }
71
+ };
72
+ defaults() {
73
+ return {
74
+ date: "date",
75
+ series: "series",
76
+ close: "close",
77
+ benchmark: "benchmark",
78
+ ratio: "rsRatio",
79
+ momentum: "rsMomentum",
80
+ method: RotationMethod.ZScore,
81
+ window: 14,
82
+ lookback: 1,
83
+ smoothing: 5,
84
+ tail: 10,
85
+ curve: CurveKind.Linear,
86
+ frame: RotationFrame.Centered,
87
+ nodes: true,
88
+ xLabel: "RS-Ratio",
89
+ yLabel: "RS-Momentum"
90
+ };
91
+ }
92
+ get settings() {
93
+ const { method, window, lookback, smoothing } = this.options;
94
+ return {
95
+ method,
96
+ window: wholeAtLeast(window, 2, 14),
97
+ lookback: wholeAtLeast(lookback, 1, 1),
98
+ smoothing: wholeAtLeast(smoothing, 1, 5)
99
+ };
100
+ }
101
+ rows() {
102
+ const { data, date, series, close, benchmark, ratio, momentum } = this.options;
103
+ return (Array.isArray(data) ? data : []).filter((row) => row !== null && typeof row === "object").map((row, i) => {
104
+ const when = Quotes.date(row[date]);
105
+ const rsRatio = Quotes.number(row[ratio]), rsMomentum = Quotes.number(row[momentum]);
106
+ return {
107
+ name: String(row[series] ?? "Symbol"),
108
+ time: when?.getTime() ?? i,
109
+ label: dayLabel(row[date], when),
110
+ close: Quotes.number(row[close]),
111
+ base: Quotes.number(row[benchmark]),
112
+ given: Number.isFinite(rsRatio) && Number.isFinite(rsMomentum) ? {
113
+ ratio: rsRatio,
114
+ momentum: rsMomentum
115
+ } : null
116
+ };
117
+ });
118
+ }
119
+ /** Oldest first, one row per bar, with the last duplicate winning. */
120
+ static ordered(rows) {
121
+ return [...new Map(rows.map((row) => [row.time, row]))].sort((a, b) => a[0] - b[0]).map(([, row]) => row);
122
+ }
123
+ computed(rows, indexPrices) {
124
+ const priced = rows.flatMap((row) => {
125
+ const base = indexPrices.get(row.time) ?? row.base;
126
+ return row.close > 0 && base > 0 && Number.isFinite(row.close) && Number.isFinite(base) ? [{
127
+ row,
128
+ base
129
+ }] : [];
130
+ });
131
+ const points = RelativeStrengthRotationMath.rotation(priced.map(({ row }) => row.close), priced.map(({ base }) => base), this.settings);
132
+ return priced.map(({ row }, i) => ({
133
+ row,
134
+ point: points[i]
135
+ }));
136
+ }
137
+ /** Every symbol's whole path. Supplied values win over prices, symbol by symbol. */
138
+ reading() {
139
+ const { benchmarkSymbol } = this.options;
140
+ const rows = this.rows();
141
+ const indexPrices = new Map(rows.filter((row) => row.name === benchmarkSymbol && row.close > 0 && Number.isFinite(row.close)).map((row) => [row.time, row.close]));
142
+ const trails = [], skipped = [];
143
+ for (const [name, own] of group(rows.filter((row) => row.name !== benchmarkSymbol), (row) => row.name)) {
144
+ const ordered = RelativeStrengthRotation.ordered(own);
145
+ const given = ordered.filter((row) => row.given);
146
+ const stops = (given.length ? given.map((row) => ({
147
+ row,
148
+ point: row.given
149
+ })) : this.computed(ordered, indexPrices)).flatMap(({ row, point }) => point ? [{
150
+ ...point,
151
+ series: name,
152
+ when: row.label,
153
+ quadrant: RelativeStrengthRotationMath.quadrant(point),
154
+ age: 0
155
+ }] : []);
156
+ if (stops.length) trails.push({
157
+ name,
158
+ stops
159
+ });
160
+ else skipped.push(name);
161
+ }
162
+ return {
163
+ trails,
164
+ skipped
165
+ };
166
+ }
167
+ /** The head and `tail` bars behind it, with `age` counting back from the head. */
168
+ recent(trail) {
169
+ const stops = trail.stops.slice(-(wholeAtLeast(this.options.tail, 0, 10) + 1));
170
+ return {
171
+ name: trail.name,
172
+ stops: stops.map((stop, i) => ({
173
+ ...stop,
174
+ age: stops.length - 1 - i
175
+ }))
176
+ };
177
+ }
178
+ domain(values) {
179
+ const low = Math.min(CENTER, ...values), high = Math.max(CENTER, ...values);
180
+ if (low === high) return [99, 101];
181
+ if (this.options.frame === RotationFrame.Fitted) {
182
+ const pad = (high - low) * .1200000000000001;
183
+ return [low - pad, high + pad];
184
+ }
185
+ const reach = Math.max(CENTER - low, high - CENTER) * PAD;
186
+ return [CENTER - reach, CENTER + reach];
187
+ }
188
+ scales(ctx) {
189
+ const { trails, skipped } = this.reading();
190
+ const shown = trails.map((trail) => this.recent(trail));
191
+ const stops = shown.flatMap((trail) => trail.stops);
192
+ const x = scaleLinear(this.domain(stops.map((stop) => stop.ratio)), [0, ctx.plot.width]);
193
+ const y = scaleLinear(this.domain(stops.map((stop) => stop.momentum)), [ctx.plot.height, 0]);
194
+ if (this.options.frame !== RotationFrame.Fitted) {
195
+ x.nice(this.xTicks());
196
+ y.nice(this.yTicks());
197
+ }
198
+ return {
199
+ x,
200
+ y,
201
+ shown,
202
+ skipped
203
+ };
204
+ }
205
+ /** Readings sit a fraction either side of 100, so ticks take the decimals their spacing needs. */
206
+ tickFormat(scale) {
207
+ const [low, high] = scale.domain();
208
+ const print = format(`.${precisionFixed(tickStep(low, high, this.yTicks()))}f`);
209
+ return (value) => print(+value);
210
+ }
211
+ plotMarks(ctx, axes) {
212
+ const { x, y, shown } = axes;
213
+ this.drawQuadrants(ctx, axes);
214
+ const color = (name) => ctx.palette.color(name);
215
+ const path = line().curve(Scales.curve(this.options.curve)).x((stop) => x(stop.ratio)).y((stop) => y(stop.momentum));
216
+ const tails = ctx.marks("tails", "path", shown.filter((trail) => trail.stops.length > 1), (trail) => trail.name).attr("fill", "none").attr("stroke", (trail) => color(trail.name)).attr("stroke-width", 2).attr("stroke-linejoin", "round").attr("stroke-linecap", "round");
217
+ ctx.set(tails, { d: (trail) => path(trail.stops) ?? "" }, { d: (trail) => path(trail.stops) ?? "" });
218
+ ctx.drawOn(tails);
219
+ const last = wholeAtLeast(this.options.tail, 1, 10);
220
+ const stops = shown.flatMap((trail) => this.options.nodes ? trail.stops : trail.stops.slice(-1));
221
+ const dots = ctx.marks("dots", "circle", stops, (stop) => `${stop.series}/${stop.age}`).attr("fill", (stop) => color(stop.series)).attr("stroke", ctx.theme.surface).attr("stroke-width", 2).attr("opacity", (stop) => 1 - .6 * stop.age / last);
222
+ const place = {
223
+ cx: (stop) => x(stop.ratio),
224
+ cy: (stop) => y(stop.momentum)
225
+ };
226
+ ctx.set(dots, {
227
+ ...place,
228
+ r: (stop) => stop.age ? NODE : HEAD
229
+ }, {
230
+ ...place,
231
+ r: 0
232
+ }, 6);
233
+ ctx.hover(dots, (stop) => this.tipFor(stop));
234
+ this.drawLabels(ctx, axes);
235
+ this.drawNotice(ctx, axes);
236
+ }
237
+ tipFor(stop) {
238
+ return {
239
+ title: stop.when ? `${stop.series}, ${stop.when}` : stop.series,
240
+ color: this.palette.color(stop.series),
241
+ rows: [
242
+ ["RS-Ratio", stop.ratio.toFixed(2)],
243
+ ["RS-Momentum", stop.momentum.toFixed(2)],
244
+ ["Quadrant", stop.quadrant]
245
+ ]
246
+ };
247
+ }
248
+ drawQuadrants(ctx, { x, y }) {
249
+ const { width, height } = ctx.plot;
250
+ const left = Math.max(0, Math.min(width, x(CENTER))), top = Math.max(0, Math.min(height, y(CENTER)));
251
+ const areas = [
252
+ {
253
+ name: RotationQuadrant.Improving,
254
+ x: 0,
255
+ y: 0,
256
+ width: left,
257
+ height: top,
258
+ anchor: "start",
259
+ textX: 6,
260
+ textY: 14
261
+ },
262
+ {
263
+ name: RotationQuadrant.Leading,
264
+ x: left,
265
+ y: 0,
266
+ width: width - left,
267
+ height: top,
268
+ anchor: "end",
269
+ textX: width - 6,
270
+ textY: 14
271
+ },
272
+ {
273
+ name: RotationQuadrant.Lagging,
274
+ x: 0,
275
+ y: top,
276
+ width: left,
277
+ height: height - top,
278
+ anchor: "start",
279
+ textX: 6,
280
+ textY: height - 6
281
+ },
282
+ {
283
+ name: RotationQuadrant.Weakening,
284
+ x: left,
285
+ y: top,
286
+ width: width - left,
287
+ height: height - top,
288
+ anchor: "end",
289
+ textX: width - 6,
290
+ textY: height - 6
291
+ }
292
+ ];
293
+ const tiles = ctx.marks("quadrants", "rect", areas, (area) => area.name).attr("fill", (area) => ctx.palette.diverging(TINT[area.name])).attr("fill-opacity", .1);
294
+ ctx.set(tiles, {
295
+ x: (area) => area.x,
296
+ y: (area) => area.y,
297
+ width: (area) => area.width,
298
+ height: (area) => area.height
299
+ });
300
+ FinanceInk.note(ctx, "quadrant-labels", areas.filter((area) => area.width >= area.name.length * CHAR + 12 && area.height >= 20), (area) => ({
301
+ x: area.textX,
302
+ y: area.textY,
303
+ text: area.name,
304
+ anchor: area.anchor
305
+ }), 11, "muted");
306
+ const axisLines = [...x(CENTER) >= 0 && x(CENTER) <= width ? [{
307
+ key: "x",
308
+ x1: left,
309
+ x2: left,
310
+ y1: 0,
311
+ y2: height
312
+ }] : [], ...y(CENTER) >= 0 && y(CENTER) <= height ? [{
313
+ key: "y",
314
+ x1: 0,
315
+ x2: width,
316
+ y1: top,
317
+ y2: top
318
+ }] : []];
319
+ const rules = ctx.marks("center", "line", axisLines, (rule) => rule.key).attr("stroke", ctx.theme.axis).attr("stroke-width", 1);
320
+ ctx.set(rules, {
321
+ x1: (rule) => rule.x1,
322
+ x2: (rule) => rule.x2,
323
+ y1: (rule) => rule.y1,
324
+ y2: (rule) => rule.y2
325
+ });
326
+ }
327
+ /** Names sit beside their heads, on the first free side; a name with no room is left to the legend and tooltip. */
328
+ drawLabels(ctx, { x, y, shown }) {
329
+ const { width, height } = ctx.plot;
330
+ const heads = shown.flatMap((trail) => {
331
+ const head = trail.stops.at(-1);
332
+ const px = x(head.ratio), py = y(head.momentum);
333
+ return px >= 0 && px <= width && py >= 0 && py <= height ? [{
334
+ text: shorten(trail.name, LABEL_CHARS),
335
+ px,
336
+ py
337
+ }] : [];
338
+ });
339
+ const taken = heads.map(({ px, py }) => ({
340
+ left: px - HEAD,
341
+ right: px + HEAD,
342
+ top: py - HEAD,
343
+ bottom: py + HEAD
344
+ }));
345
+ const labels = heads.flatMap(({ text, px, py }) => {
346
+ const wide = text.length * CHAR, gap = 9;
347
+ const spot = [
348
+ {
349
+ x: px + gap,
350
+ y: py + 4,
351
+ anchor: "start",
352
+ box: {
353
+ left: px + gap,
354
+ right: px + gap + wide,
355
+ top: py - 7,
356
+ bottom: py + 7
357
+ }
358
+ },
359
+ {
360
+ x: px - gap,
361
+ y: py + 4,
362
+ anchor: "end",
363
+ box: {
364
+ left: px - gap - wide,
365
+ right: px - gap,
366
+ top: py - 7,
367
+ bottom: py + 7
368
+ }
369
+ },
370
+ {
371
+ x: px,
372
+ y: py - gap - 2,
373
+ anchor: "middle",
374
+ box: {
375
+ left: px - wide / 2,
376
+ right: px + wide / 2,
377
+ top: py - gap - 12,
378
+ bottom: py - gap + 2
379
+ }
380
+ },
381
+ {
382
+ x: px,
383
+ y: py + gap + 10,
384
+ anchor: "middle",
385
+ box: {
386
+ left: px - wide / 2,
387
+ right: px + wide / 2,
388
+ top: py + gap - 2,
389
+ bottom: py + gap + 12
390
+ }
391
+ }
392
+ ].find(({ box }) => box.left >= 0 && box.right <= width && box.top >= 0 && box.bottom <= height && !taken.some((other) => overlaps(box, other)));
393
+ if (!spot) return [];
394
+ taken.push(spot.box);
395
+ return [{
396
+ text,
397
+ ...spot
398
+ }];
399
+ });
400
+ FinanceInk.note(ctx, "head-labels", labels, (label) => label, 11, "ink");
401
+ }
402
+ /** A symbol without enough bars has no position, so the chart says so rather than losing it quietly. */
403
+ drawNotice(ctx, { shown, skipped }) {
404
+ const { width, height } = ctx.plot;
405
+ const need = `${RelativeStrengthRotationMath.required(this.settings)} bars`;
406
+ const text = !skipped.length ? null : shown.length ? `Too short, needs ${need}: ${skipped.join(", ")}` : `Each symbol needs ${need}`;
407
+ FinanceInk.note(ctx, "notice", text ? [shorten(text, Math.floor((width - 200) / CHAR))] : [], (note) => ({
408
+ x: width / 2,
409
+ y: height - 6,
410
+ text: note,
411
+ anchor: "middle"
412
+ }), 11, "secondary");
413
+ }
414
+ /** Exports the computed positions, not the prices that went in. */
415
+ table() {
416
+ return {
417
+ columns: [
418
+ "series",
419
+ "date",
420
+ "rsRatio",
421
+ "rsMomentum",
422
+ "quadrant"
423
+ ],
424
+ rows: this.reading().trails.flatMap((trail) => trail.stops.map((stop) => [
425
+ stop.series,
426
+ stop.when,
427
+ +stop.ratio.toFixed(4),
428
+ +stop.momentum.toFixed(4),
429
+ stop.quadrant
430
+ ]))
431
+ };
432
+ }
433
+ };
434
+ export { RelativeStrengthRotation };
@@ -0,0 +1,71 @@
1
+ import { FinanceMath } from "./FinanceMath.js";
2
+ // src/charts/financial/RelativeStrengthRotationMath.ts
3
+ /** How price and benchmark become the two rotation axes. Both are public approximations: the JdK formula is proprietary. */
4
+ var RotationMethod = /* @__PURE__ */ function(RotationMethod) {
5
+ RotationMethod["ZScore"] = "z-score";
6
+ RotationMethod["RatioToAverage"] = "ratio-to-average";
7
+ return RotationMethod;
8
+ }({});
9
+ var RotationQuadrant = /* @__PURE__ */ function(RotationQuadrant) {
10
+ RotationQuadrant["Leading"] = "Leading";
11
+ RotationQuadrant["Weakening"] = "Weakening";
12
+ RotationQuadrant["Lagging"] = "Lagging";
13
+ RotationQuadrant["Improving"] = "Improving";
14
+ return RotationQuadrant;
15
+ }({});
16
+ /** `Centered` keeps 100,100 mid-plot, the customary framing. `Fitted` follows the data but always holds 100,100. */
17
+ var RotationFrame = /* @__PURE__ */ function(RotationFrame) {
18
+ RotationFrame["Centered"] = "centered";
19
+ RotationFrame["Fitted"] = "fitted";
20
+ return RotationFrame;
21
+ }({});
22
+ /** Below this share of the mean, a rolling deviation is rounding error rather than movement. */
23
+ var FLAT = 1e-12;
24
+ /** Pure maths behind the relative rotation graph; everything is centred on 100. */
25
+ var RelativeStrengthRotationMath = class {
26
+ static relativeStrength(prices, benchmark) {
27
+ return prices.map((price, i) => 100 * price / benchmark[i]);
28
+ }
29
+ /** Rolling population z-score, `(value - mean) / deviation`. A flat window scores 0. */
30
+ static zScore(values, window) {
31
+ const means = FinanceMath.sma(values, window), spreads = FinanceMath.stdev(values, window);
32
+ return values.map((value, i) => {
33
+ const mean = means[i], spread = spreads[i];
34
+ if (value === null || mean == null || spread == null) return null;
35
+ return spread <= Math.abs(mean) * FLAT ? 0 : (value - mean) / spread;
36
+ });
37
+ }
38
+ /** Percent change over `lookback` bars. */
39
+ static rateOfChange(values, lookback) {
40
+ return values.map((value, i) => {
41
+ const before = values[i - lookback];
42
+ return value === null || before == null || before === 0 ? null : 100 * (value / before - 1);
43
+ });
44
+ }
45
+ /** Each aligned bar's position, or null while the rolling windows fill. */
46
+ static rotation(prices, benchmark, { method, window, lookback, smoothing }) {
47
+ const strength = FinanceMath.ema(this.relativeStrength(prices, benchmark), smoothing);
48
+ const zScore = method === "z-score";
49
+ const averages = FinanceMath.sma(strength, window);
50
+ const ratios = zScore ? this.zScore(strength, window).map((z) => z === null ? null : 100 + z) : strength.map((value, i) => value === null || !averages[i] ? null : 100 * value / averages[i]);
51
+ const change = this.rateOfChange(ratios, lookback);
52
+ const momenta = zScore ? this.zScore(change, window) : change;
53
+ return ratios.map((ratio, i) => {
54
+ const momentum = momenta[i];
55
+ return ratio === null || momentum == null ? null : {
56
+ ratio,
57
+ momentum: 100 + momentum
58
+ };
59
+ });
60
+ }
61
+ /** Bars a series needs before its first point appears. */
62
+ static required({ method, window, lookback, smoothing }) {
63
+ return smoothing - 1 + window + lookback + (method === "z-score" ? window - 1 : 0);
64
+ }
65
+ /** Clockwise from top right. A point exactly on 100 counts as the stronger side. */
66
+ static quadrant({ ratio, momentum }) {
67
+ if (ratio >= 100) return momentum >= 100 ? "Leading" : "Weakening";
68
+ return momentum >= 100 ? "Improving" : "Lagging";
69
+ }
70
+ };
71
+ export { RelativeStrengthRotationMath, RotationFrame, RotationMethod, RotationQuadrant };
@@ -0,0 +1,27 @@
1
+ import { SampleData } from "../../data/SampleData.js";
2
+ // src/charts/financial/RelativeStrengthRotationSamples.ts
3
+ var BARS = 90;
4
+ var SYMBOLS = 6;
5
+ /** Synthetic prices only: seeded sine waves of relative strength over a seeded walk. Not market data. */
6
+ var RelativeStrengthRotationSamples = class {
7
+ /** `{ date, series, close, benchmark }`, long form, with every symbol cycling around the benchmark at its own pace. */
8
+ static prices(seed) {
9
+ const benchmark = SampleData.ohlc(seed, BARS);
10
+ const noise = SampleData.timeSeries(seed, BARS, SYMBOLS);
11
+ return noise.map((row, i) => {
12
+ const bar = i % BARS, symbol = Math.floor(i / BARS);
13
+ const period = 42 + symbol * 5, phase = symbol * 2.1 + seed;
14
+ const previous = bar ? Number(noise[i - 1].value) : Number(row.value);
15
+ const wobble = (Number(row.value) - previous) * 6e-4;
16
+ const strength = Math.exp(.05 * Math.sin(2 * Math.PI * bar / period + phase) + wobble);
17
+ const index = Number(benchmark[bar].close);
18
+ return {
19
+ date: row.date,
20
+ series: row.series,
21
+ close: +(index * strength * (1 + symbol * .2)).toFixed(3),
22
+ benchmark: index
23
+ };
24
+ });
25
+ }
26
+ };
27
+ export { RelativeStrengthRotationSamples };
@@ -4,7 +4,6 @@ import { Quotes } from "./Quotes.js";
4
4
  import { SessionChart } from "./SessionChart.js";
5
5
  import { PriceChart } from "./PriceChart.js";
6
6
  import { BollingerBands } from "./BollingerBands.js";
7
- import { Candlestick3D } from "./Candlestick3D.js";
8
7
  import { CandlestickChart } from "./CandlestickChart.js";
9
8
  import { DepthChart } from "./DepthChart.js";
10
9
  import { EquityBase } from "./EquityBase.js";
@@ -24,6 +23,9 @@ import { OHLCChart } from "./OHLCChart.js";
24
23
  import { PayoffDiagram } from "./PayoffDiagram.js";
25
24
  import { PointFigureChart } from "./PointFigureChart.js";
26
25
  import { ProjectionCone } from "./ProjectionCone.js";
26
+ import { RelativeStrengthRotationMath, RotationFrame, RotationMethod, RotationQuadrant } from "./RelativeStrengthRotationMath.js";
27
+ import { RelativeStrengthRotationSamples } from "./RelativeStrengthRotationSamples.js";
28
+ import { RelativeStrengthRotation } from "./RelativeStrengthRotation.js";
27
29
  import { RenkoChart } from "./RenkoChart.js";
28
30
  import { ReturnCalendar } from "./ReturnCalendar.js";
29
31
  import { RSIChart } from "./RSIChart.js";
@@ -57,6 +59,6 @@ var financialCatalog = [
57
59
  ReturnCalendar,
58
60
  ProjectionCone,
59
61
  VolatilitySurface,
60
- Candlestick3D
62
+ RelativeStrengthRotation
61
63
  ];
62
- export { BollingerBands, BollingerPane, BoxMethod, BrickChart, CalendarCell, CalendarGrain, CalendarMeasure, CalendarTotals, Candle3DDepth, CandleBody, Candlestick3D, CandlestickChart, ConeBands, ConeModel, DepthChart, DepthCurve, DepthLayout, DepthScale, DrawdownChart, DrawdownMark, DrawdownUnit, EquityBase, EquityBasis, EquityCurve, EquityFill, FinanceMath, HeikinAshiChart, IchimokuCloud, IchimokuLines, IchimokuPeriods, KagiChart, LineBreakChart, MACDChart, MacdBasis, MacdHistogram, MacdPeriods, MarketProfileChart, MaturityScale, MovingAverageKind, OHLCChart, OhlcTicks, OptionStrategy, OscillatorChart, PayoffAxis, PayoffDiagram, PayoffHorizon, PointFigureChart, PriceChart, PriceMark, PriceOverlay, PriceScale, PriceSource, PriceTransforms, ProfileAllocation, ProfileMode, ProfileSide, ProjectionCone, Quotes, RSIChart, RenkoChart, ReturnCalendar, RsiForm, SessionChart, StochasticChart, StochasticForm, TpoBracket, TpoForm, TpoGrouping, TpoProfile, TpoStacking, VolatilitySurface, VolatilitySurfaceForm, VolumeBars, VolumeBucket, VolumeLayout, VolumeMark, VolumeMeasure, VolumeProfile, YieldCurve, YieldMode, financialCatalog };
64
+ export { BollingerBands, BollingerPane, BoxMethod, BrickChart, CalendarCell, CalendarGrain, CalendarMeasure, CalendarTotals, Candle3DDepth, CandleBody, CandlestickChart, ConeBands, ConeModel, DepthChart, DepthCurve, DepthLayout, DepthScale, DrawdownChart, DrawdownMark, DrawdownUnit, EquityBase, EquityBasis, EquityCurve, EquityFill, FinanceMath, HeikinAshiChart, IchimokuCloud, IchimokuLines, IchimokuPeriods, KagiChart, LineBreakChart, MACDChart, MacdBasis, MacdHistogram, MacdPeriods, MarketProfileChart, MaturityScale, MovingAverageKind, OHLCChart, OhlcTicks, OptionStrategy, OscillatorChart, PayoffAxis, PayoffDiagram, PayoffHorizon, PointFigureChart, PriceChart, PriceMark, PriceOverlay, PriceScale, PriceSource, PriceTransforms, ProfileAllocation, ProfileMode, ProfileSide, ProjectionCone, Quotes, RSIChart, RelativeStrengthRotation, RelativeStrengthRotationMath, RelativeStrengthRotationSamples, RenkoChart, ReturnCalendar, RotationFrame, RotationMethod, RotationQuadrant, RsiForm, SessionChart, StochasticChart, StochasticForm, TpoBracket, TpoForm, TpoGrouping, TpoProfile, TpoStacking, VolatilitySurface, VolatilitySurfaceForm, VolumeBars, VolumeBucket, VolumeLayout, VolumeMark, VolumeMeasure, VolumeProfile, YieldCurve, YieldMode, financialCatalog };
@@ -5,7 +5,6 @@ import { FlowGraph } from "./FlowGraph.js";
5
5
  import { FlowChart, FlowGraphChart } from "./FlowChart.js";
6
6
  import { StratumAxisOrder, StratumChart, StratumThreading } from "./StratumChart.js";
7
7
  import { AlluvialChart } from "./AlluvialChart.js";
8
- import { BumpFlow, BumpLeader, BumpMark, BumpSpacing } from "./BumpFlow.js";
9
8
  import { ChordDirection, ChordFlow, ChordHead, ChordLayout } from "./ChordFlow.js";
10
9
  import { CircularColumn, CircularCorner, CircularLoopSide, CircularSankey } from "./CircularSankey.js";
11
10
  import { CohortAlignment, CohortFlow, CohortForm, CohortMeasure, CohortStack } from "./CohortFlow.js";
@@ -24,7 +23,6 @@ import { RetentionExit, RetentionFlow, RetentionScale } from "./RetentionFlow.js
24
23
  import { RibbonFlow, RibbonScale } from "./RibbonFlow.js";
25
24
  import { SankeyAlign, SankeyChart } from "./SankeyChart.js";
26
25
  import { StateEdge, StateLayout, StateMark, StateTransitionChart, StateWeight } from "./StateTransitionChart.js";
27
- import { StreamFlow, StreamOffset, StreamOrder } from "./StreamFlow.js";
28
26
  import { SwimFlowChart, SwimHeader, SwimLaneOrder, SwimSpacing } from "./SwimFlowChart.js";
29
27
  // src/charts/flow/index.ts
30
28
  var flowCatalog = [
@@ -32,7 +30,6 @@ var flowCatalog = [
32
30
  AlluvialChart,
33
31
  ChordFlow,
34
32
  ParallelSets,
35
- StreamFlow,
36
33
  FlowMapLess,
37
34
  CircularSankey,
38
35
  RibbonFlow,
@@ -41,11 +38,10 @@ var flowCatalog = [
41
38
  DecisionTreeChart,
42
39
  StateTransitionChart,
43
40
  SwimFlowChart,
44
- BumpFlow,
45
41
  CohortFlow,
46
42
  RetentionFlow,
47
43
  ConversionFlow,
48
44
  NetworkFlowChart,
49
45
  EnergyBalanceChart
50
46
  ];
51
- export { AlluvialChart, BumpFlow, BumpLeader, BumpMark, BumpSpacing, ChordDirection, ChordFlow, ChordHead, ChordLayout, CircularColumn, CircularCorner, CircularLoopSide, CircularSankey, CohortAlignment, CohortFlow, CohortForm, CohortMeasure, CohortStack, ConversionAlign, ConversionFlow, ConversionShape, DecisionLayout, DecisionLinkWidth, DecisionNode, DecisionTreeChart, EnergyBalanceChart, EnergyBranch, EnergyLossSide, EnergyTip, FlowBaseline, FlowChart, FlowDirection, FlowGeometry, FlowGraph, FlowGraphChart, FlowMapLess, FlowNodeMark, FlowNodeShape, FlowPaint, FlowRibbon, FlowRouter, FlowSort, FlowTable, LayeredLayout, MapLessArc, MapLessBend, MapLessLayout, MapLessMeasure, MarimekkoFlow, MaxFlow, MekkoConnector, MekkoSeriesOrder, NetworkFlowChart, NetworkFlowEncoding, NodeLinkChart, ParallelSets, ProcessDensity, ProcessFlowChart, ProcessNodeStyle, RetentionExit, RetentionFlow, RetentionScale, RibbonFlow, RibbonScale, SankeyAlign, SankeyChart, StateEdge, StateLayout, StateMark, StateTransitionChart, StateWeight, StratumAxisOrder, StratumChart, StratumThreading, StreamFlow, StreamOffset, StreamOrder, SwimFlowChart, SwimHeader, SwimLaneOrder, SwimSpacing, TreeGrowth, flowCatalog };
47
+ export { AlluvialChart, ChordDirection, ChordFlow, ChordHead, ChordLayout, CircularColumn, CircularCorner, CircularLoopSide, CircularSankey, CohortAlignment, CohortFlow, CohortForm, CohortMeasure, CohortStack, ConversionAlign, ConversionFlow, ConversionShape, DecisionLayout, DecisionLinkWidth, DecisionNode, DecisionTreeChart, EnergyBalanceChart, EnergyBranch, EnergyLossSide, EnergyTip, FlowBaseline, FlowChart, FlowDirection, FlowGeometry, FlowGraph, FlowGraphChart, FlowMapLess, FlowNodeMark, FlowNodeShape, FlowPaint, FlowRibbon, FlowRouter, FlowSort, FlowTable, LayeredLayout, MapLessArc, MapLessBend, MapLessLayout, MapLessMeasure, MarimekkoFlow, MaxFlow, MekkoConnector, MekkoSeriesOrder, NetworkFlowChart, NetworkFlowEncoding, NodeLinkChart, ParallelSets, ProcessDensity, ProcessFlowChart, ProcessNodeStyle, RetentionExit, RetentionFlow, RetentionScale, RibbonFlow, RibbonScale, SankeyAlign, SankeyChart, StateEdge, StateLayout, StateMark, StateTransitionChart, StateWeight, StratumAxisOrder, StratumChart, StratumThreading, SwimFlowChart, SwimHeader, SwimLaneOrder, SwimSpacing, TreeGrowth, flowCatalog };