@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
@@ -1,174 +0,0 @@
1
- import { ChartFamily, CurveKind, DataShape, Dimension, Orientation } from "../../core/enums.js";
2
- import { Scales } from "../../core/Scales.js";
3
- import { SampleData } from "../../data/SampleData.js";
4
- import { FlowChart } from "./FlowChart.js";
5
- import { FlowTable } from "./FlowTable.js";
6
- import { area, range, scaleLinear, scalePoint, scaleTime, stack, stackOffsetExpand, stackOffsetNone, stackOffsetSilhouette, stackOffsetWiggle, stackOrderAppearance, stackOrderAscending, stackOrderDescending, stackOrderInsideOut, stackOrderNone } from "d3";
7
- // src/charts/flow/StreamFlow.ts
8
- var StreamOffset = /* @__PURE__ */ function(StreamOffset) {
9
- StreamOffset["Wiggle"] = "wiggle";
10
- StreamOffset["Silhouette"] = "silhouette";
11
- StreamOffset["Expand"] = "expand";
12
- StreamOffset["Baseline"] = "baseline";
13
- return StreamOffset;
14
- }({});
15
- var StreamOrder = /* @__PURE__ */ function(StreamOrder) {
16
- StreamOrder["InsideOut"] = "inside-out";
17
- StreamOrder["Appearance"] = "appearance";
18
- StreamOrder["Ascending"] = "ascending";
19
- StreamOrder["Descending"] = "descending";
20
- StreamOrder["Input"] = "input";
21
- return StreamOrder;
22
- }({});
23
- var OFFSET = {
24
- ["wiggle"]: stackOffsetWiggle,
25
- ["silhouette"]: stackOffsetSilhouette,
26
- ["expand"]: stackOffsetExpand,
27
- ["baseline"]: stackOffsetNone
28
- };
29
- var ORDER = {
30
- ["inside-out"]: stackOrderInsideOut,
31
- ["appearance"]: stackOrderAppearance,
32
- ["ascending"]: stackOrderAscending,
33
- ["descending"]: stackOrderDescending,
34
- ["input"]: stackOrderNone
35
- };
36
- /** Watch the composition of a total drift over time, when the shape of the whole matters more than exact values. Negative amounts count as zero. */
37
- var StreamFlow = class extends FlowChart {
38
- static meta = {
39
- id: "stream-flow",
40
- name: "Stream flow",
41
- family: ChartFamily.Flow,
42
- dimension: Dimension.Two,
43
- shape: DataShape.Table,
44
- description: "Stacks series around a flowing baseline to show how a total and its parts shift over time.",
45
- tags: [
46
- "streamgraph",
47
- "theme river",
48
- "stacked area"
49
- ],
50
- sample: (seed) => SampleData.timeSeries(seed, 36, 6).map((row, i) => {
51
- const peak = 5 + Math.floor(i / 36) * 11 % 31, day = i % 36;
52
- return {
53
- ...row,
54
- value: +(+row.value * (.12 + 1.4 * Math.exp(-(((day - peak) / 8) ** 2)))).toFixed(2)
55
- };
56
- }),
57
- variants: {
58
- offset: [
59
- "wiggle",
60
- "silhouette",
61
- "expand",
62
- "baseline"
63
- ],
64
- order: [
65
- "inside-out",
66
- "appearance",
67
- "ascending",
68
- "descending",
69
- "input"
70
- ],
71
- curve: [
72
- CurveKind.Basis,
73
- CurveKind.Monotone,
74
- CurveKind.CatmullRom,
75
- CurveKind.Linear
76
- ],
77
- orientation: [Orientation.Horizontal, Orientation.Vertical]
78
- }
79
- };
80
- defaults() {
81
- return {
82
- x: "date",
83
- series: "series",
84
- y: "value",
85
- offset: "wiggle",
86
- order: "inside-out",
87
- curve: CurveKind.Basis,
88
- orientation: Orientation.Horizontal
89
- };
90
- }
91
- plotMargin() {
92
- return this.options.orientation === Orientation.Vertical ? {
93
- top: 8,
94
- right: 8,
95
- bottom: 8,
96
- left: 58
97
- } : {
98
- top: 8,
99
- right: 16,
100
- bottom: 26,
101
- left: 16
102
- };
103
- }
104
- draw(ctx) {
105
- const { data, x, series, y, offset, order, curve, orientation } = this.options;
106
- const vertical = orientation === Orientation.Vertical;
107
- const table = FlowTable.pivot(data, x, series, y);
108
- const rows = table.columns.map((_, c) => ({
109
- c,
110
- ...Object.fromEntries(table.series.map((name) => [name, Math.max(0, table.at(c, name))]))
111
- }));
112
- const layers = stack().keys(table.series).offset(OFFSET[offset]).order(ORDER[order])(rows);
113
- const [length, breadth] = vertical ? [ctx.plot.height, ctx.plot.width] : [ctx.plot.width, ctx.plot.height];
114
- const low = Math.min(0, ...layers.flat().map((d) => d[0])), high = Math.max(1, ...layers.flat().map((d) => d[1]));
115
- const across = scaleLinear([low, high], [breadth, 0]);
116
- const first = table.columns[0];
117
- const along = first instanceof Date ? (c) => scaleTime([first, table.columns[table.columns.length - 1]], [0, length])(table.columns[c]) : typeof first === "number" ? (c) => scaleLinear([first, table.columns[table.columns.length - 1]], [0, length])(table.columns[c]) : (c) => scalePoint(range(table.columns.length).map(String), [0, length])(String(c)) ?? 0;
118
- const color = (name) => ctx.palette.color(name);
119
- for (const name of table.series) color(name);
120
- const flat = area();
121
- const shape = vertical ? flat.curve(Scales.curve(curve)).y((d) => along(d.data.c)).x0((d) => across(d[0])).x1((d) => across(d[1])) : flat.curve(Scales.curve(curve)).x((d) => along(d.data.c)).y0((d) => across(d[0])).y1((d) => across(d[1]));
122
- const zero = (layer) => shape(layer.map((d) => Object.assign([d[0], d[0]], { data: d.data }))) ?? "";
123
- const paths = ctx.marks("layers", "path", layers, (d) => d.key).attr("fill", (d) => color(d.key));
124
- ctx.set(paths, { d: (d) => shape(d) ?? "" }, { d: zero }, 30);
125
- ctx.hover(paths, (d) => ({
126
- title: d.key,
127
- color: color(d.key),
128
- rows: [["Latest", +table.at(table.columns.length - 1, d.key).toFixed(2)]]
129
- }));
130
- const count = Math.min(Math.floor(length / (vertical ? 40 : 90)) + 1, table.columns.length);
131
- const picks = count > 1 ? range(count).map((i) => Math.round(i * (table.columns.length - 1) / (count - 1))) : table.columns.length ? [0] : [];
132
- this.ticks(ctx, "dates", picks.map((c, i) => vertical ? {
133
- key: `t${c}`,
134
- x: -6,
135
- y: along(c),
136
- text: table.labels[c],
137
- anchor: "end"
138
- } : {
139
- key: `t${c}`,
140
- x: along(c),
141
- y: 0,
142
- text: table.labels[c],
143
- anchor: i === 0 ? "start" : i === picks.length - 1 ? "end" : "middle"
144
- }), vertical ? "left" : "bottom");
145
- this.labels(ctx, "names", layers.flatMap((layer) => {
146
- const best = layer.reduce((top, d, c) => {
147
- return !(c < 2 || c > layer.length - 3) && Math.abs(across(d[1]) - across(d[0])) > Math.abs(across(layer[top][1]) - across(layer[top][0])) ? c : top;
148
- }, Math.min(2, Math.max(0, layer.length - 1)));
149
- const d = layer[best];
150
- if (!d) return [];
151
- const thick = Math.abs(across(d[1]) - across(d[0])), middle = (across(d[0]) + across(d[1])) / 2;
152
- const fill = ctx.palette.inkOn(color(layer.key));
153
- if (thick < 15) return [];
154
- return [vertical ? {
155
- key: layer.key,
156
- x: middle,
157
- y: along(best),
158
- text: layer.key,
159
- anchor: "middle",
160
- fill,
161
- weight: 600
162
- } : {
163
- key: layer.key,
164
- x: along(best),
165
- y: middle,
166
- text: layer.key,
167
- anchor: "middle",
168
- fill,
169
- weight: 600
170
- }];
171
- }));
172
- }
173
- };
174
- export { StreamFlow, StreamOffset, StreamOrder };
@@ -1,106 +0,0 @@
1
- import { ChartFamily, DataShape, Dimension } from "../../core/enums.js";
2
- import { GeoClasses } from "./GeoClasses.js";
3
- import { GeoLegend } from "./GeoLegend.js";
4
- import { GeoProjectionKind } from "./GeoProjection.js";
5
- import { GeoSamples } from "./GeoSamples.js";
6
- import { PointMap } from "./PointMap.js";
7
- import { Delaunay, extent, scaleLinear } from "d3";
8
- // src/charts/geomaps/ThiessenMap.ts
9
- var GeoTessellation = /* @__PURE__ */ function(GeoTessellation) {
10
- GeoTessellation["Voronoi"] = "voronoi";
11
- GeoTessellation["Delaunay"] = "delaunay";
12
- GeoTessellation["Both"] = "both";
13
- return GeoTessellation;
14
- }({});
15
- /** Thiessen polygons: every location belongs to its nearest site, for service areas and station catchments. */
16
- var ThiessenMap = class extends PointMap {
17
- static meta = {
18
- id: "thiessen-map",
19
- name: "Thiessen map",
20
- family: ChartFamily.Geospatial,
21
- dimension: Dimension.Two,
22
- shape: DataShape.Geo,
23
- description: "Divides the map into nearest-site Voronoi cells, or its Delaunay mesh, for catchments and proximity.",
24
- tags: [
25
- "map",
26
- "voronoi",
27
- "delaunay",
28
- "proximity",
29
- "catchment"
30
- ],
31
- sample: (seed) => GeoSamples.scatter(seed, 70),
32
- variants: {
33
- tessellation: [
34
- "voronoi",
35
- "delaunay",
36
- "both"
37
- ],
38
- stations: [true, false],
39
- coast: [true, false],
40
- projection: [
41
- GeoProjectionKind.NaturalEarth,
42
- GeoProjectionKind.EqualEarth,
43
- GeoProjectionKind.Mollweide,
44
- GeoProjectionKind.Orthographic
45
- ]
46
- },
47
- valid: (values) => values.tessellation !== "delaunay" || values.coast === true
48
- };
49
- defaults() {
50
- return {
51
- ...super.defaults(),
52
- tessellation: "voronoi",
53
- stations: true,
54
- coast: true,
55
- graticule: false
56
- };
57
- }
58
- keyHeight() {
59
- return GeoLegend.height;
60
- }
61
- drawKey(ctx, frame) {
62
- const classes = new GeoClasses(this.sites(frame).map((site) => site.value));
63
- GeoLegend.classes(ctx, frame, classes, (value) => ctx.palette.sequential(.05 + .8 * classes.tone(value)));
64
- }
65
- drawMap(ctx, frame) {
66
- const { tessellation, stations, coast, value } = this.options, { theme, palette } = ctx;
67
- const sites = this.sites(frame);
68
- const seen = /* @__PURE__ */ new Set();
69
- const unique = sites.filter((d) => {
70
- const key = `${d.x.toFixed(2)},${d.y.toFixed(2)}`;
71
- return seen.has(key) ? false : !!seen.add(key);
72
- });
73
- const delaunay = Delaunay.from(unique, (d) => d.x, (d) => d.y);
74
- const voronoi = delaunay.voronoi([
75
- 0,
76
- 0,
77
- frame.width,
78
- frame.height
79
- ]);
80
- const layer = ctx.group("cells-layer").attr("clip-path", this.clip(ctx, frame.path({ type: "Sphere" }) ?? ""));
81
- const [low = 0, high = 1] = extent(unique, (d) => d.value);
82
- const tone = scaleLinear([low, high > low ? high : low + 1], [.05, .85]);
83
- const cellsOn = tessellation !== "delaunay";
84
- const cells = ctx.marks("cells", "path", cellsOn ? unique : [], (d) => d.key, layer).attr("fill", (d) => palette.sequential(tone(d.value))).attr("stroke", theme.surface).attr("stroke-width", 1);
85
- ctx.set(cells, {
86
- d: (_, i) => voronoi.renderCell(i),
87
- "fill-opacity": 1
88
- }, {
89
- d: (_, i) => voronoi.renderCell(i),
90
- "fill-opacity": 0
91
- });
92
- ctx.hover(cells, (d) => ({
93
- title: d.name,
94
- rows: [[value, d.value]]
95
- }));
96
- const mesh = tessellation === "voronoi" || unique.length < 3 ? [] : [delaunay.render()];
97
- ctx.marks("mesh", "path", mesh, void 0, layer).attr("d", (d) => d).attr("fill", "none").attr("stroke", tessellation === "both" ? theme.surface : theme.inkMuted).attr("stroke-width", 1);
98
- ctx.marks("coast", "path", coast || tessellation === "delaunay" ? [this.land] : []).attr("d", (d) => frame.path(d) ?? "").attr("fill", tessellation === "delaunay" ? theme.grid : "none").attr("stroke", theme.inkSecondary).attr("stroke-width", this.hairline(ctx)).attr("pointer-events", "none").lower();
99
- const dots = ctx.marks("stations", "circle", stations ? unique : [], (d) => d.key).attr("cx", (d) => d.x).attr("cy", (d) => d.y).attr("r", 2.5).attr("fill", theme.ink).attr("stroke", theme.surface).attr("stroke-width", 1);
100
- ctx.hover(dots, (d) => ({
101
- title: d.name,
102
- rows: [[value, d.value]]
103
- }));
104
- }
105
- };
106
- export { GeoTessellation, ThiessenMap };
@@ -1,135 +0,0 @@
1
- import { ChartFamily, DataShape, Dimension } from "../../core/enums.js";
2
- import { Hierarchy3DChart } from "./Hierarchy3DChart.js";
3
- import { BalloonAngles, ConeAxis, HierarchySort } from "./hierarchyEnums.js";
4
- import { TreeSamples } from "./TreeSamples.js";
5
- import { max, sum } from "d3";
6
- import { BufferGeometry, ConeGeometry, DoubleSide, Float32BufferAttribute, Group, InstancedMesh, LineBasicMaterial, LineSegments, Mesh, MeshStandardMaterial, Object3D, SphereGeometry } from "three";
7
- // src/charts/hierarchy/ConeTree3D.ts
8
- var LEAF = .05;
9
- var EXTENT = 1.75;
10
- var WIDTH = 1.3;
11
- /** Robertson's cone tree: each family hangs on a cone, so a big tree stays visible as it turns. */
12
- var ConeTree3D = class extends Hierarchy3DChart {
13
- static meta = {
14
- id: "cone-tree-3d",
15
- name: "3D cone tree",
16
- family: ChartFamily.Hierarchy,
17
- dimension: Dimension.Three,
18
- shape: DataShape.Hierarchy,
19
- description: "Hangs each family of children on a cone below its parent, keeping large trees visible as the view turns.",
20
- tags: [
21
- "robertson",
22
- "three dimensional tree",
23
- "cam tree"
24
- ],
25
- sample: (seed) => TreeSamples.broad(seed, 3, 4),
26
- variants: {
27
- axis: Object.values(ConeAxis),
28
- angles: Object.values(BalloonAngles),
29
- cones: [true, false],
30
- sort: [HierarchySort.ValueDescending, HierarchySort.ValueAscending]
31
- }
32
- };
33
- defaults() {
34
- return {
35
- ...super.defaults(),
36
- axis: ConeAxis.Vertical,
37
- angles: BalloonAngles.Weighted,
38
- cones: true,
39
- autoRotate: true
40
- };
41
- }
42
- layout(root) {
43
- const spots = /* @__PURE__ */ new Map();
44
- const weighted = this.options.angles === BalloonAngles.Weighted;
45
- root.eachAfter((node) => {
46
- const reaches = (node.children ?? []).map((kid) => spots.get(kid).reach);
47
- const ring = reaches.length ? Math.max(sum(reaches) / Math.PI, reaches.length > 1 ? max(reaches) : 0) : 0;
48
- spots.set(node, {
49
- reach: ring + (max(reaches) ?? LEAF),
50
- ring,
51
- x: 0,
52
- y: 0,
53
- z: 0
54
- });
55
- });
56
- const rung = EXTENT / Math.max(1, root.height);
57
- root.eachBefore((node) => {
58
- const spot = spots.get(node);
59
- const kids = node.children ?? [];
60
- const weights = kids.map((kid) => weighted ? spots.get(kid).reach : 1);
61
- const total = sum(weights) || 1;
62
- let angle = 0;
63
- kids.forEach((kid, i) => {
64
- const share = weights[i] / total * 2 * Math.PI, heading = angle + share / 2;
65
- angle += share;
66
- const child = spots.get(kid);
67
- child.x = spot.x + spot.ring * Math.cos(heading);
68
- child.z = spot.z + spot.ring * Math.sin(heading);
69
- child.y = spot.y - rung;
70
- });
71
- });
72
- const widest = max([...spots.values()], (spot) => Math.hypot(spot.x, spot.z)) || 1;
73
- for (const spot of spots.values()) {
74
- spot.x *= WIDTH / widest;
75
- spot.z *= WIDTH / widest;
76
- spot.ring *= WIDTH / widest;
77
- }
78
- return spots;
79
- }
80
- buildTree(ctx) {
81
- const { axis, cones } = this.options;
82
- const root = this.tree();
83
- const spots = this.layout(root);
84
- const nodes = root.descendants();
85
- const stage = new Group();
86
- stage.position.y = EXTENT / 2 - .05;
87
- if (axis === ConeAxis.Horizontal) {
88
- stage.rotation.z = Math.PI / 2;
89
- stage.position.set(-1.75 / 2, -.05, 0);
90
- }
91
- ctx.root.add(stage);
92
- const ball = new InstancedMesh(new SphereGeometry(1, 16, 12), new MeshStandardMaterial({ roughness: .4 }), nodes.length);
93
- ball.castShadow = true;
94
- const dummy = new Object3D();
95
- nodes.forEach((node, i) => {
96
- const spot = spots.get(node);
97
- dummy.position.set(spot.x, spot.y, spot.z);
98
- dummy.scale.setScalar(node.children ? .05 : .036);
99
- dummy.updateMatrix();
100
- ball.setMatrixAt(i, dummy.matrix);
101
- ball.setColorAt(i, ctx.color(node.depth ? this.style.branch(node) : ctx.theme.inkMuted));
102
- });
103
- stage.add(ball);
104
- ctx.pick(ball, (i) => this.style.tooltip(nodes[i]));
105
- const points = nodes.filter((node) => node.parent).flatMap((node) => {
106
- const a = spots.get(node.parent), b = spots.get(node);
107
- return [
108
- a.x,
109
- a.y,
110
- a.z,
111
- b.x,
112
- b.y,
113
- b.z
114
- ];
115
- });
116
- stage.add(new LineSegments(new BufferGeometry().setAttribute("position", new Float32BufferAttribute(points, 3)), new LineBasicMaterial({ color: ctx.theme.axis })));
117
- for (const node of cones ? nodes.filter((item) => item.children) : []) {
118
- const spot = spots.get(node);
119
- const rung = spot.y - spots.get(node.children[0]).y;
120
- const cone = new Mesh(new ConeGeometry(Math.max(.01, spot.ring), rung, 40, 1, true), new MeshStandardMaterial({
121
- color: node.depth ? this.style.branch(node) : ctx.theme.inkMuted,
122
- transparent: true,
123
- opacity: .14,
124
- side: DoubleSide,
125
- depthWrite: false
126
- }));
127
- cone.position.set(spot.x, spot.y - rung / 2, spot.z);
128
- stage.add(cone);
129
- }
130
- ctx.reveal((progress) => {
131
- stage.scale.setScalar(Math.max(.001, .7 + .3 * progress));
132
- });
133
- }
134
- };
135
- export { ConeTree3D };
@@ -1,27 +0,0 @@
1
- import { Chart3D } from "../../core/Chart3D.js";
2
- import { HierarchyColor } from "./hierarchyEnums.js";
3
- import { TreeModel, treeFieldDefaults } from "./TreeModel.js";
4
- import { TreeStyle } from "./TreeStyle.js";
5
- // src/charts/hierarchy/Hierarchy3DChart.ts
6
- /** Base of every 3D hierarchy chart: the same data handling and colour rules as the 2D family. */
7
- var Hierarchy3DChart = class extends Chart3D {
8
- style;
9
- defaults() {
10
- return {
11
- ...treeFieldDefaults,
12
- color: HierarchyColor.Branch
13
- };
14
- }
15
- build(ctx) {
16
- if (!new TreeModel(this.options.data, this.options).empty) this.buildTree(ctx);
17
- }
18
- tree(limit) {
19
- const root = new TreeModel(this.options.data, this.options).root({ limit });
20
- this.style = new TreeStyle(this.palette, this.theme, this.options.color, root, this.options.valueFormat);
21
- return root;
22
- }
23
- table() {
24
- return new TreeModel(this.options.data, this.options).table();
25
- }
26
- };
27
- export { Hierarchy3DChart };
@@ -1,81 +0,0 @@
1
- import { ChartFamily, DataShape, Dimension } from "../../core/enums.js";
2
- import { Hierarchy3DChart } from "./Hierarchy3DChart.js";
3
- import { HierarchyMeasure, SpherePackShell, SpherePackStack } from "./hierarchyEnums.js";
4
- import { TreeSamples } from "./TreeSamples.js";
5
- import { pack } from "d3";
6
- import { CylinderGeometry, InstancedMesh, Mesh, MeshStandardMaterial, Object3D, PlaneGeometry, SphereGeometry } from "three";
7
- // src/charts/hierarchy/SpherePack3D.ts
8
- var FLOOR = -.7;
9
- var RISE = .14;
10
- /** Circle packing as balls in glass domes: each ball's footprint keeps the 2D area encoding, with levels on height. */
11
- var SpherePack3D = class extends Hierarchy3DChart {
12
- static meta = {
13
- id: "sphere-pack-3d",
14
- name: "3D sphere packing",
15
- family: ChartFamily.Hierarchy,
16
- dimension: Dimension.Three,
17
- shape: DataShape.Hierarchy,
18
- description: "Places leaves as spheres inside translucent shells or on discs for each parent, lifting levels on height.",
19
- tags: [
20
- "bubble",
21
- "nested spheres",
22
- "circle packing"
23
- ],
24
- sample: (seed) => TreeSamples.broad(seed, 3, 3),
25
- variants: {
26
- stack: Object.values(SpherePackStack),
27
- shell: Object.values(SpherePackShell),
28
- measure: [HierarchyMeasure.Value, HierarchyMeasure.LeafCount]
29
- }
30
- };
31
- defaults() {
32
- return {
33
- ...super.defaults(),
34
- stack: SpherePackStack.Terraced,
35
- shell: SpherePackShell.Dome
36
- };
37
- }
38
- buildTree(ctx) {
39
- const { stack, shell } = this.options;
40
- const root = pack().size([2.1, 2.1]).padding(.02)(this.tree());
41
- const leaves = root.leaves();
42
- const parents = root.descendants().filter((node) => node.depth > 0 && node.children);
43
- const lift = (node) => stack === SpherePackStack.Terraced ? (root.height - node.height - 1) * RISE : 0;
44
- const x = (node) => node.x - 1.05, z = (node) => node.y - 1.05;
45
- const floor = new Mesh(new PlaneGeometry(2.3, 2.3), new MeshStandardMaterial({ color: ctx.theme.grid }));
46
- floor.rotation.x = -Math.PI / 2;
47
- floor.position.y = -.701;
48
- floor.receiveShadow = true;
49
- ctx.root.add(floor);
50
- for (const node of shell === SpherePackShell.None ? [] : parents) {
51
- const color = this.style.tint(this.style.branch(node), .3);
52
- const geometry = shell === SpherePackShell.Dome ? new SphereGeometry(node.r, 32, 16, 0, Math.PI * 2, 0, Math.PI / 2) : new CylinderGeometry(node.r, node.r, .02, 48);
53
- const mesh = new Mesh(geometry, new MeshStandardMaterial({
54
- color,
55
- transparent: true,
56
- opacity: shell === SpherePackShell.Dome ? .16 : .5,
57
- depthWrite: false
58
- }));
59
- mesh.position.set(x(node), FLOOR + lift(node), z(node));
60
- ctx.root.add(mesh);
61
- ctx.pick(mesh, () => this.style.tooltip(node));
62
- }
63
- const balls = new InstancedMesh(new SphereGeometry(1, 24, 16), new MeshStandardMaterial({ roughness: .35 }), leaves.length);
64
- balls.castShadow = true;
65
- const dummy = new Object3D();
66
- leaves.forEach((leaf, i) => balls.setColorAt(i, ctx.color(this.style.fill(leaf))));
67
- ctx.reveal((progress) => {
68
- leaves.forEach((leaf, i) => {
69
- const r = Math.max(.001, leaf.r * progress);
70
- dummy.position.set(x(leaf), FLOOR + lift(leaf) + r, z(leaf));
71
- dummy.scale.setScalar(r);
72
- dummy.updateMatrix();
73
- balls.setMatrixAt(i, dummy.matrix);
74
- });
75
- balls.instanceMatrix.needsUpdate = true;
76
- });
77
- ctx.root.add(balls);
78
- ctx.pick(balls, (i) => this.style.tooltip(leaves[i]));
79
- }
80
- };
81
- export { SpherePack3D };
@@ -1,93 +0,0 @@
1
- import { ChartFamily, DataShape, Dimension } from "../../core/enums.js";
2
- import { Hierarchy3DChart } from "./Hierarchy3DChart.js";
3
- import { HierarchySort, PolarSweep, TowerProfile } from "./hierarchyEnums.js";
4
- import { TreeSamples } from "./TreeSamples.js";
5
- import { max, partition } from "d3";
6
- import { ExtrudeGeometry, Mesh, MeshStandardMaterial, Shape } from "three";
7
- // src/charts/hierarchy/SunburstTower3D.ts
8
- var FLOOR = -.65;
9
- var RADIUS = 1.1;
10
- var GAP = .012;
11
- /** Sunburst with height: each ring is a solid segment, for presentations where the level structure should feel physical. */
12
- var SunburstTower3D = class extends Hierarchy3DChart {
13
- static meta = {
14
- id: "sunburst-tower-3d",
15
- name: "3D sunburst tower",
16
- family: ChartFamily.Hierarchy,
17
- dimension: Dimension.Three,
18
- shape: DataShape.Hierarchy,
19
- description: "Extrudes the rings of a sunburst into solid segments, stepping by depth or rising with value.",
20
- tags: [
21
- "extruded sunburst",
22
- "radial partition",
23
- "ring tower"
24
- ],
25
- sample: (seed) => TreeSamples.broad(seed, 3, 3),
26
- variants: {
27
- sweep: [
28
- PolarSweep.Full,
29
- PolarSweep.ThreeQuarter,
30
- PolarSweep.Half
31
- ],
32
- profile: [
33
- TowerProfile.Dome,
34
- TowerProfile.Stairs,
35
- TowerProfile.Value
36
- ],
37
- hole: [.25, .5],
38
- sort: [HierarchySort.ValueDescending, HierarchySort.Input]
39
- }
40
- };
41
- defaults() {
42
- return {
43
- ...super.defaults(),
44
- sweep: PolarSweep.Full,
45
- profile: TowerProfile.Dome,
46
- hole: .25
47
- };
48
- }
49
- buildTree(ctx) {
50
- const { sweep, profile, hole } = this.options;
51
- const whole = sweep === PolarSweep.Full ? 2 * Math.PI : sweep === PolarSweep.ThreeQuarter ? 1.5 * Math.PI : Math.PI;
52
- const root = partition().size([whole, 1])(this.tree());
53
- const levels = Math.max(1, root.height);
54
- const inner = hole * RADIUS, band = (RADIUS - inner) / levels;
55
- const peak = (node) => max(root.descendants().filter((other) => other.depth === node.depth), (other) => other.value) || 1;
56
- const tall = (node) => {
57
- if (profile === TowerProfile.Stairs) return .18 + .9 * node.depth / levels;
58
- if (profile === TowerProfile.Dome) return .18 + .9 * (levels - node.depth + 1) / levels;
59
- return .08 + (node.value ?? 0) / peak(node) * 1.1;
60
- };
61
- const segments = [];
62
- const nodes = root.descendants().filter((node) => node.depth > 0 && node.x1 - node.x0 > .002);
63
- for (const node of nodes) {
64
- const r0 = inner + band * (node.depth - 1) + GAP / 2, r1 = inner + band * node.depth - GAP / 2;
65
- const trim = Math.min((node.x1 - node.x0) / 4, GAP / r1);
66
- const a0 = node.x0 + trim, a1 = node.x1 - trim;
67
- const shape = new Shape();
68
- shape.moveTo(r1 * Math.cos(a0), r1 * Math.sin(a0));
69
- shape.absarc(0, 0, r1, a0, a1, false);
70
- shape.lineTo(r0 * Math.cos(a1), r0 * Math.sin(a1));
71
- shape.absarc(0, 0, r0, a1, a0, true);
72
- const geometry = new ExtrudeGeometry(shape, {
73
- depth: tall(node),
74
- bevelEnabled: false,
75
- curveSegments: 18
76
- });
77
- geometry.rotateX(-Math.PI / 2);
78
- const segment = new Mesh(geometry, new MeshStandardMaterial({
79
- color: this.style.fill(node),
80
- roughness: .6
81
- }));
82
- segment.position.y = FLOOR;
83
- segment.castShadow = segment.receiveShadow = true;
84
- ctx.root.add(segment);
85
- ctx.pick(segment, () => this.style.tooltip(node));
86
- segments.push(segment);
87
- }
88
- ctx.reveal((progress) => {
89
- for (const segment of segments) segment.scale.y = Math.max(.001, progress);
90
- });
91
- }
92
- };
93
- export { SunburstTower3D };