@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,128 +0,0 @@
1
- import { Chart3D } from "../../core/Chart3D.js";
2
- import { ChartFamily, DataShape, Dimension, ScaleKind } from "../../core/enums.js";
3
- import { SampleData } from "../../data/SampleData.js";
4
- import { CalendarWeekStart } from "./CalendarHeatmap.js";
5
- import { TimeRows } from "./TimeRows.js";
6
- import { rollup, scaleLinear, scalePow, sum, utcDay, utcMonday, utcSunday } from "d3";
7
- import { BoxGeometry, CylinderGeometry, InstancedMesh, Mesh, MeshStandardMaterial, Object3D, PlaneGeometry } from "three";
8
- // src/charts/timeline/CalendarSkylineChart.ts
9
- var SkylineShape = /* @__PURE__ */ function(SkylineShape) {
10
- SkylineShape["Block"] = "blocks";
11
- SkylineShape["Column"] = "columns";
12
- return SkylineShape;
13
- }({});
14
- var BASE = -.7;
15
- var MONTH_NAMES = [
16
- "Jan",
17
- "Feb",
18
- "Mar",
19
- "Apr",
20
- "May",
21
- "Jun",
22
- "Jul",
23
- "Aug",
24
- "Sep",
25
- "Oct",
26
- "Nov",
27
- "Dec"
28
- ];
29
- /** A year of daily activity as a city: weeks run along the floor and each day rises by its value. */
30
- var CalendarSkylineChart = class extends Chart3D {
31
- static meta = {
32
- id: "calendar-skyline",
33
- name: "Calendar skyline",
34
- family: ChartFamily.Temporal,
35
- dimension: Dimension.Three,
36
- shape: DataShape.Table,
37
- description: "Raises a calendar grid into 3D so that peak days stand out as towers above the year.",
38
- tags: [
39
- "contribution",
40
- "daily",
41
- "skyline",
42
- "city"
43
- ],
44
- sample: (seed) => SampleData.timeSeries(seed, 280, 1).map((row, i, rows) => ({
45
- date: row.date,
46
- value: +(.5 + Math.min(3, Math.abs(+row.value - +(rows[i - 1]?.value ?? row.value))) * (row.date.getUTCDay() % 6 ? 2 : .6)).toFixed(1)
47
- })),
48
- variants: {
49
- shape: Object.values(SkylineShape),
50
- weekStart: Object.values(CalendarWeekStart),
51
- scale: [ScaleKind.Linear, ScaleKind.Sqrt]
52
- }
53
- };
54
- defaults() {
55
- return {
56
- date: "date",
57
- value: "value",
58
- shape: "blocks",
59
- weekStart: CalendarWeekStart.Monday,
60
- scale: ScaleKind.Linear,
61
- distance: 3.7,
62
- elevation: 40,
63
- azimuth: 24
64
- };
65
- }
66
- build(ctx) {
67
- const { data, date, value, shape, weekStart, scale } = this.options;
68
- const rows = data.flatMap((row) => {
69
- const when = TimeRows.date(row[date]);
70
- return when ? [{
71
- day: +TimeRows.floorDay(when),
72
- value: Math.max(0, TimeRows.number(row[value]) ?? 0)
73
- }] : [];
74
- });
75
- const totals = rollup(rows, (list) => sum(list, (d) => d.value), (d) => d.day);
76
- const floor = new Mesh(new PlaneGeometry(2.2, 1.1), new MeshStandardMaterial({ color: ctx.theme.grid }));
77
- floor.rotation.x = -Math.PI / 2;
78
- floor.position.y = BASE;
79
- floor.receiveShadow = true;
80
- ctx.root.add(floor);
81
- if (!totals.size) return;
82
- const stamps = [...totals.keys()], first = new Date(Math.min(...stamps)), last = new Date(Math.max(...stamps));
83
- const days = utcDay.range(first, utcDay.offset(last, 1));
84
- const week = weekStart === CalendarWeekStart.Monday ? utcMonday : utcSunday;
85
- const origin = week.floor(first), weeks = week.count(origin, last) + 1;
86
- const cell = Math.min(2 / weeks, 1 / 7), gap = cell * .86;
87
- const top = Math.max(1e-9, ...totals.values());
88
- const height = scale === ScaleKind.Sqrt ? scalePow().exponent(.5).domain([0, top]).range([0, .7]) : scaleLinear([0, top], [0, .7]);
89
- const geometry = shape === "blocks" ? new BoxGeometry(gap, 1, gap) : new CylinderGeometry(gap / 2, gap / 2, 1, 12);
90
- const towers = new InstancedMesh(geometry, new MeshStandardMaterial({ roughness: .5 }), days.length);
91
- towers.castShadow = towers.receiveShadow = true;
92
- const weekday = (day) => weekStart === CalendarWeekStart.Monday ? (day.getUTCDay() + 6) % 7 : day.getUTCDay();
93
- const dummy = new Object3D();
94
- const place = (progress) => {
95
- days.forEach((day, i) => {
96
- const h = Math.max(.006, height(totals.get(+day) ?? 0) * progress);
97
- dummy.position.set((week.count(origin, day) - weeks / 2 + .5) * cell, BASE + h / 2, (weekday(day) - 3) * cell);
98
- dummy.scale.set(1, h, 1);
99
- dummy.updateMatrix();
100
- towers.setMatrixAt(i, dummy.matrix);
101
- });
102
- towers.instanceMatrix.needsUpdate = true;
103
- };
104
- days.forEach((day, i) => {
105
- const amount = totals.get(+day);
106
- towers.setColorAt(i, ctx.color(amount === void 0 ? ctx.theme.grid : ctx.palette.sequential(.15 + .85 * (amount / top))));
107
- });
108
- ctx.reveal(place);
109
- ctx.root.add(towers);
110
- ctx.pick(towers, (i) => ({
111
- title: TimeRows.long(days[i]),
112
- rows: [["Value", +(totals.get(+days[i]) ?? 0).toFixed(1)]]
113
- }));
114
- let previous = -1, labelled = -Infinity;
115
- for (const day of days) {
116
- const month = day.getUTCMonth(), at = week.count(origin, day);
117
- if (month === previous || (at - labelled) * cell < .26) continue;
118
- previous = month;
119
- labelled = at;
120
- ctx.label(MONTH_NAMES[month], [
121
- (at - weeks / 2 + .5) * cell,
122
- BASE,
123
- .6
124
- ], "secondary", 10);
125
- }
126
- }
127
- };
128
- export { CalendarSkylineChart, SkylineShape };
@@ -1,119 +0,0 @@
1
- import { Chart3D } from "../../core/Chart3D.js";
2
- import { ChartFamily, DataShape, Dimension } from "../../core/enums.js";
3
- import { TimeRows } from "./TimeRows.js";
4
- import { TimeSamples } from "./TimeSamples.js";
5
- import { scaleBand, scaleLinear, scaleUtc } from "d3";
6
- import { BoxGeometry, InstancedMesh, Mesh, MeshStandardMaterial, Object3D, PlaneGeometry } from "three";
7
- // src/charts/timeline/ScheduleBlocksChart.ts
8
- var ScheduleBlockHeight = /* @__PURE__ */ function(ScheduleBlockHeight) {
9
- ScheduleBlockHeight["Flat"] = "flat";
10
- ScheduleBlockHeight["Effort"] = "by-effort";
11
- ScheduleBlockHeight["Progress"] = "by-progress";
12
- return ScheduleBlockHeight;
13
- }({});
14
- var ScheduleBlockOrder = /* @__PURE__ */ function(ScheduleBlockOrder) {
15
- ScheduleBlockOrder["Start"] = "by-start";
16
- ScheduleBlockOrder["Group"] = "by-group";
17
- return ScheduleBlockOrder;
18
- }({});
19
- var ScheduleBlockBase = /* @__PURE__ */ function(ScheduleBlockBase) {
20
- ScheduleBlockBase["Floor"] = "on-floor";
21
- ScheduleBlockBase["Stairs"] = "stairs";
22
- return ScheduleBlockBase;
23
- }({});
24
- var FLOOR = -.7;
25
- /** A schedule as a landscape: for presenting phasing and effort together, not for reading exact dates. */
26
- var ScheduleBlocksChart = class extends Chart3D {
27
- static meta = {
28
- id: "schedule-blocks",
29
- name: "Schedule blocks",
30
- family: ChartFamily.Project,
31
- dimension: Dimension.Three,
32
- shape: DataShape.Table,
33
- description: "Extrudes schedule bars into blocks, with height carrying effort or completion on top of time and row.",
34
- tags: [
35
- "schedule",
36
- "waterfall",
37
- "phasing"
38
- ],
39
- sample: (seed) => TimeSamples.plan(seed, 12),
40
- variants: {
41
- blockHeight: Object.values(ScheduleBlockHeight),
42
- order: Object.values(ScheduleBlockOrder),
43
- base: Object.values(ScheduleBlockBase)
44
- }
45
- };
46
- defaults() {
47
- return {
48
- task: "task",
49
- start: "start",
50
- end: "end",
51
- group: "group",
52
- progress: "progress",
53
- blockHeight: "flat",
54
- order: "by-start",
55
- base: "on-floor",
56
- distance: 4.6,
57
- elevation: 30
58
- };
59
- }
60
- lift(span) {
61
- const { blockHeight, progress } = this.options;
62
- if (blockHeight === "flat") return .12;
63
- if (blockHeight === "by-effort") return .08 + .6 * Math.min(1, TimeRows.days(span.start, span.end) / 20);
64
- const done = TimeRows.number(span.row[progress]) ?? 0;
65
- return .08 + .6 * Math.max(0, Math.min(1, done > 1 ? done / 100 : done));
66
- }
67
- build(ctx) {
68
- const { data, task, start, end, group, order, base } = this.options;
69
- const spans = TimeRows.spans(data, {
70
- label: task,
71
- start,
72
- end,
73
- group
74
- });
75
- for (const span of spans) ctx.palette.color(span.group);
76
- spans.sort(order === "by-group" ? (a, b) => a.group.localeCompare(b.group) || +a.start - +b.start : (a, b) => +a.start - +b.start);
77
- const keys = TimeRows.unique(spans.map((span) => span.label));
78
- const x = scaleUtc(TimeRows.extent(spans.flatMap((span) => [span.start, span.end])), [-1, 1]);
79
- const z = scaleBand(keys, [-1, 1]).padding(.22);
80
- const rise = scaleLinear([0, Math.max(1, spans.length - 1)], [.7, 0]);
81
- const floor = new Mesh(new PlaneGeometry(2.05, 2.05), new MeshStandardMaterial({ color: ctx.theme.grid }));
82
- floor.rotation.x = -Math.PI / 2;
83
- floor.position.y = FLOOR;
84
- floor.receiveShadow = true;
85
- ctx.root.add(floor);
86
- if (!spans.length) return;
87
- const blocks = new InstancedMesh(new BoxGeometry(1, 1, 1), new MeshStandardMaterial({ roughness: .5 }), spans.length);
88
- blocks.castShadow = blocks.receiveShadow = true;
89
- const dummy = new Object3D();
90
- const place = (progress) => {
91
- spans.forEach((span, i) => {
92
- const left = x(span.start), width = Math.max(.02, x(span.end) - left) * Math.max(.001, progress), h = this.lift(span);
93
- dummy.position.set(left + width / 2, FLOOR + (base === "stairs" ? rise(i) : 0) + h / 2, z(keys[i]) + z.bandwidth() / 2);
94
- dummy.scale.set(width, h, z.bandwidth());
95
- dummy.updateMatrix();
96
- blocks.setMatrixAt(i, dummy.matrix);
97
- });
98
- blocks.instanceMatrix.needsUpdate = true;
99
- };
100
- spans.forEach((span, i) => blocks.setColorAt(i, ctx.color(ctx.palette.color(span.group))));
101
- ctx.reveal(place);
102
- ctx.root.add(blocks);
103
- ctx.pick(blocks, (i) => {
104
- const span = spans[i];
105
- return {
106
- title: span.label,
107
- color: ctx.palette.color(span.group),
108
- rows: [["Start", TimeRows.long(span.start)], ["End", TimeRows.long(span.end)]]
109
- };
110
- });
111
- const ticks = x.ticks(4);
112
- for (const tick of ticks) ctx.label(TimeRows.short(tick), [
113
- x(tick),
114
- FLOOR,
115
- 1.18
116
- ], "secondary", 10);
117
- }
118
- };
119
- export { ScheduleBlockBase, ScheduleBlockHeight, ScheduleBlockOrder, ScheduleBlocksChart };
@@ -1,154 +0,0 @@
1
- import { ChartFamily, DataShape, Dimension, LegendPosition } from "../../core/enums.js";
2
- import { RadialChart } from "../../core/RadialChart.js";
3
- import { SampleData } from "../../data/SampleData.js";
4
- import { TimeRows } from "./TimeRows.js";
5
- import { max, min, utcFormat } from "d3";
6
- // src/charts/timeline/SpiralTimeline.ts
7
- var SpiralPeriod = /* @__PURE__ */ function(SpiralPeriod) {
8
- SpiralPeriod["Fortnight"] = "fortnight";
9
- SpiralPeriod["Month"] = "month";
10
- SpiralPeriod["Quarter"] = "quarter";
11
- return SpiralPeriod;
12
- }({});
13
- var SpiralMark = /* @__PURE__ */ function(SpiralMark) {
14
- SpiralMark["Bar"] = "bars";
15
- SpiralMark["Dot"] = "dots";
16
- SpiralMark["Line"] = "line";
17
- return SpiralMark;
18
- }({});
19
- var SpiralDirection = /* @__PURE__ */ function(SpiralDirection) {
20
- SpiralDirection["Outward"] = "outward";
21
- SpiralDirection["Inward"] = "inward";
22
- return SpiralDirection;
23
- }({});
24
- var LENGTH = {
25
- ["fortnight"]: 14,
26
- ["month"]: 30.44,
27
- ["quarter"]: 91.31
28
- };
29
- var STAMP = utcFormat("%b %-d");
30
- /** Wind time into a spiral so each turn lines up with the last and a repeating cycle becomes a pattern along one spoke. */
31
- var SpiralTimeline = class extends RadialChart {
32
- static meta = {
33
- id: "spiral-timeline",
34
- name: "Spiral timeline",
35
- family: ChartFamily.Temporal,
36
- dimension: Dimension.Two,
37
- shape: DataShape.Table,
38
- description: "Winds a time series along an Archimedean spiral, with one turn per period, to expose repeating patterns.",
39
- tags: [
40
- "cyclical",
41
- "seasonal",
42
- "spiral plot"
43
- ],
44
- sample: (seed) => SampleData.timeSeries(seed, 200, 1).map((row, i) => ({
45
- date: row.date,
46
- value: +(+row.value * (1 + .6 * Math.sin(i / 30.44 * 2 * Math.PI))).toFixed(1)
47
- })),
48
- variants: {
49
- period: [
50
- "month",
51
- "fortnight",
52
- "quarter"
53
- ],
54
- mark: Object.values(SpiralMark),
55
- direction: Object.values(SpiralDirection)
56
- }
57
- };
58
- defaults() {
59
- return {
60
- date: "date",
61
- value: "value",
62
- period: "month",
63
- mark: "bars",
64
- direction: "outward",
65
- legend: LegendPosition.None
66
- };
67
- }
68
- points(radius) {
69
- const { data, date, value, period, direction } = this.options;
70
- const rows = data.flatMap((row) => {
71
- const when = TimeRows.date(row[date]), amount = TimeRows.number(row[value]);
72
- return when && amount !== null ? [{
73
- when,
74
- amount
75
- }] : [];
76
- }).sort((a, b) => +a.when - +b.when);
77
- const inner = radius * .16, days = rows.length ? TimeRows.days(rows[0].when, rows[rows.length - 1].when) || 1 : 1;
78
- const turns = days / LENGTH[period], band = (radius - inner) / (turns + 1);
79
- const low = min(rows, (row) => row.amount) ?? 0, high = max(rows, (row) => row.amount) ?? 1;
80
- return {
81
- points: rows.map(({ when, amount }) => {
82
- const elapsed = TimeRows.days(rows[0].when, when);
83
- const turn = (direction === "inward" ? days - elapsed : elapsed) / LENGTH[period];
84
- return {
85
- date: when,
86
- value: amount,
87
- angle: turn * 2 * Math.PI - Math.PI / 2,
88
- radius: inner + band * turn,
89
- share: (amount - low) / (high - low || 1)
90
- };
91
- }),
92
- band,
93
- inner
94
- };
95
- }
96
- drawRadial(ctx, { radius }) {
97
- const { mark } = this.options;
98
- const { points, band } = this.points(radius - 8);
99
- const polar = (angle, r) => `${Math.cos(angle) * r},${Math.sin(angle) * r}`;
100
- const guide = [...points].sort((a, b) => a.angle - b.angle);
101
- const coil = ctx.marks("coil", "path", guide.length > 1 ? [guide] : [], (_, i) => i).attr("fill", "none").attr("stroke", mark === "line" ? ctx.theme.grid : ctx.theme.axis).attr("stroke-width", 1);
102
- ctx.set(coil, { d: (list) => `M${list.map((p) => polar(p.angle, p.radius)).join("L")}` });
103
- const reach = (p) => Math.max(1, p.share * band * .9);
104
- const bars = ctx.marks("bars", "path", mark === "bars" ? points : [], (p) => +p.date).attr("stroke-linecap", "round").attr("fill", "none").attr("stroke-width", Math.min(3, Math.max(1.5, radius / 40))).attr("stroke", (p) => ctx.palette.sequential(.25 + p.share * .75));
105
- ctx.set(bars, { d: (p) => `M${polar(p.angle, p.radius)}L${polar(p.angle, p.radius + reach(p))}` }, { d: (p) => `M${polar(p.angle, p.radius)}L${polar(p.angle, p.radius)}` }, 2);
106
- ctx.hover(bars, (p) => this.about(p));
107
- const dots = ctx.marks("dots", "circle", mark === "dots" ? points : [], (p) => +p.date).attr("fill", (p) => ctx.palette.sequential(.25 + p.share * .75));
108
- ctx.set(dots, {
109
- cx: (p) => Math.cos(p.angle) * p.radius,
110
- cy: (p) => Math.sin(p.angle) * p.radius,
111
- r: (p) => Math.max(.8, Math.sqrt(p.share) * Math.min(band / 2, 5))
112
- }, {
113
- cx: (p) => Math.cos(p.angle) * p.radius,
114
- cy: (p) => Math.sin(p.angle) * p.radius,
115
- r: 0
116
- }, 2);
117
- ctx.hover(dots, (p) => this.about(p));
118
- const trace = ctx.marks("trace", "path", mark === "line" && guide.length > 1 ? [guide] : [], (_, i) => i).attr("fill", "none").attr("stroke", ctx.palette.color("value")).attr("stroke-width", 2).attr("stroke-linejoin", "round");
119
- ctx.set(trace, { d: (list) => `M${list.map((p) => polar(p.angle, p.radius + reach(p))).join("L")}` });
120
- ctx.drawOn(trace);
121
- const hits = ctx.marks("hits", "circle", mark === "line" ? points : [], (p) => +p.date).attr("fill", "transparent").attr("r", 5);
122
- ctx.set(hits, {
123
- cx: (p) => Math.cos(p.angle) * (p.radius + reach(p)),
124
- cy: (p) => Math.sin(p.angle) * (p.radius + reach(p))
125
- });
126
- ctx.hover(hits, (p) => this.about(p));
127
- const rim = Math.max(0, ctx.plot.width / 2 - 2), tip = guide[guide.length - 1];
128
- const out = tip ? tip.radius + (mark === "line" ? reach(tip) : 0) + 8 : 0;
129
- const tipX = tip ? Math.cos(tip.angle) * out : 0, tipY = tip ? Math.sin(tip.angle) * out : 0;
130
- const ends = tip && guide.length > 1 ? [{
131
- point: guide[0],
132
- x: 0,
133
- y: 4,
134
- anchor: "middle"
135
- }, {
136
- point: tip,
137
- x: Math.max(-rim, Math.min(rim, tipX)),
138
- y: Math.max(-radius + 8, Math.min(radius, tipY + 4)),
139
- anchor: tipX < 0 ? "end" : "start"
140
- }] : [];
141
- const stamps = ctx.marks("ends", "text", ends, (d) => d.anchor).attr("text-anchor", (d) => d.anchor).attr("font-weight", 600).text((d) => STAMP(d.point.date));
142
- ctx.text(ctx.set(stamps, {
143
- x: (d) => d.x,
144
- y: (d) => d.y
145
- }), 10, "ink");
146
- }
147
- about(point) {
148
- return {
149
- title: TimeRows.long(point.date),
150
- rows: [["Value", point.value]]
151
- };
152
- }
153
- };
154
- export { SpiralDirection, SpiralMark, SpiralPeriod, SpiralTimeline };
@@ -1,141 +0,0 @@
1
- import { Chart2D } from "../../core/Chart2D.js";
2
- import { ChartFamily, DataShape, Dimension } from "../../core/enums.js";
3
- import { SampleData } from "../../data/SampleData.js";
4
- import { TimeMarks } from "./TimeMarks.js";
5
- import { TimeRows } from "./TimeRows.js";
6
- import { area, curveBasis, curveMonotoneX, max, min, scaleLinear, scaleUtc, stack, stackOffsetExpand, stackOffsetSilhouette, stackOffsetWiggle, stackOrderAscending, stackOrderInsideOut, stackOrderNone, utcWeek } from "d3";
7
- // src/charts/timeline/StreamTimeline.ts
8
- var StreamTimelineBin = /* @__PURE__ */ function(StreamTimelineBin) {
9
- StreamTimelineBin["Day"] = "daily";
10
- StreamTimelineBin["Week"] = "weekly";
11
- return StreamTimelineBin;
12
- }({});
13
- var StreamTimelineOffset = /* @__PURE__ */ function(StreamTimelineOffset) {
14
- StreamTimelineOffset["Wiggle"] = "wiggle";
15
- StreamTimelineOffset["Silhouette"] = "silhouette";
16
- StreamTimelineOffset["Expand"] = "expand";
17
- return StreamTimelineOffset;
18
- }({});
19
- var StreamTimelineOrder = /* @__PURE__ */ function(StreamTimelineOrder) {
20
- StreamTimelineOrder["InsideOut"] = "inside-out";
21
- StreamTimelineOrder["Ascending"] = "ascending";
22
- StreamTimelineOrder["Input"] = "input-order";
23
- return StreamTimelineOrder;
24
- }({});
25
- var StreamTimelineCurve = /* @__PURE__ */ function(StreamTimelineCurve) {
26
- StreamTimelineCurve["Basis"] = "smooth";
27
- StreamTimelineCurve["Monotone"] = "monotone";
28
- return StreamTimelineCurve;
29
- }({});
30
- /** Show how many categories swell and fade over a long span, trading exact reading for overall shape. */
31
- var StreamTimeline = class extends Chart2D {
32
- static meta = {
33
- id: "stream-timeline",
34
- name: "Stream timeline",
35
- family: ChartFamily.Temporal,
36
- dimension: Dimension.Two,
37
- shape: DataShape.Table,
38
- description: "Flows stacked categories around a central baseline to show how the mix of activity changes through time.",
39
- tags: [
40
- "streamgraph",
41
- "theme river",
42
- "flow"
43
- ],
44
- sample: (seed) => SampleData.timeSeries(seed, 120, 5),
45
- variants: {
46
- offset: Object.values(StreamTimelineOffset),
47
- order: Object.values(StreamTimelineOrder),
48
- curve: Object.values(StreamTimelineCurve),
49
- bin: ["weekly", "daily"],
50
- labels: [true, false]
51
- },
52
- valid: ({ offset, order }) => offset !== "expand" || order !== "inside-out"
53
- };
54
- defaults() {
55
- return {
56
- date: "date",
57
- series: "series",
58
- value: "value",
59
- bin: "weekly",
60
- offset: "wiggle",
61
- order: "inside-out",
62
- curve: "smooth",
63
- labels: true
64
- };
65
- }
66
- plotMargin() {
67
- return {
68
- top: 8,
69
- right: 26,
70
- bottom: 26,
71
- left: 26
72
- };
73
- }
74
- layers() {
75
- const { data, date, series, value, bin, offset, order } = this.options;
76
- const rows = bin === "weekly" ? data.map((row) => {
77
- const when = TimeRows.date(row[date]);
78
- return {
79
- ...row,
80
- [date]: when ? utcWeek.floor(when) : null
81
- };
82
- }) : data;
83
- const { names, table } = TimeRows.pivot(rows, date, series, value);
84
- const offsets = {
85
- ["wiggle"]: stackOffsetWiggle,
86
- ["silhouette"]: stackOffsetSilhouette,
87
- ["expand"]: stackOffsetExpand
88
- };
89
- const orders = {
90
- ["inside-out"]: stackOrderInsideOut,
91
- ["ascending"]: stackOrderAscending,
92
- ["input-order"]: stackOrderNone
93
- };
94
- return {
95
- names,
96
- table,
97
- layers: stack().keys(names).offset(offsets[offset]).order(orders[order])(table)
98
- };
99
- }
100
- draw(ctx) {
101
- const { names, table, layers } = this.layers();
102
- const { width, height } = ctx.plot;
103
- names.forEach((name) => ctx.palette.color(name));
104
- const safe = (value) => Number.isFinite(value) ? value : 0;
105
- const low = min(layers, (layer) => min(layer, (point) => safe(point[0]))) ?? 0;
106
- const high = max(layers, (layer) => max(layer, (point) => safe(point[1]))) ?? 1;
107
- const x = scaleUtc(TimeRows.extent(table.map((row) => new Date(row.date))), [0, width]);
108
- const y = scaleLinear([low, high === low ? low + 1 : high], [height, 0]);
109
- TimeMarks.axis(ctx, x);
110
- const curve = this.options.curve === "smooth" ? curveBasis : curveMonotoneX;
111
- const at = (d) => x(new Date(d.data.date));
112
- const shape = area().x(at).y0((d) => y(safe(d[0]))).y1((d) => y(safe(d[1]))).curve(curve);
113
- const mid = area().x(at).y0((d) => y((safe(d[0]) + safe(d[1])) / 2)).y1((d) => y((safe(d[0]) + safe(d[1])) / 2)).curve(curve);
114
- const paths = ctx.marks("streams", "path", layers, (layer) => layer.key).attr("fill", (layer) => ctx.palette.color(layer.key)).attr("stroke", ctx.theme.surface).attr("stroke-width", 1.5);
115
- ctx.set(paths, { d: (layer) => shape(layer) ?? "" }, { d: (layer) => mid(layer) ?? "" }, 50);
116
- ctx.hover(paths, (layer) => {
117
- const values = layer.map((point) => point.data[layer.key] ?? 0);
118
- return {
119
- title: layer.key,
120
- color: ctx.palette.color(layer.key),
121
- rows: [["Peak", +(max(values) ?? 0).toFixed(1)], ["Latest", +(values[values.length - 1] ?? 0).toFixed(1)]]
122
- };
123
- });
124
- const tags = !this.options.labels ? [] : layers.flatMap((layer) => {
125
- const point = layer[layer.reduce((best, point, i) => point[1] - point[0] > layer[best][1] - layer[best][0] ? i : best, 0)];
126
- if (!point) return [];
127
- const thick = y(safe(point[0])) - y(safe(point[1])), place = x(new Date(point.data.date)), half = TimeRows.width(layer.key) / 2;
128
- return thick >= 14 ? [{
129
- name: layer.key,
130
- x: Math.max(half, Math.min(width - half, place)),
131
- y: (y(safe(point[0])) + y(safe(point[1]))) / 2 + 4
132
- }] : [];
133
- });
134
- const labels = ctx.marks("names", "text", tags, (d) => d.name).attr("text-anchor", "middle").style("pointer-events", "none").text((d) => d.name);
135
- ctx.set(ctx.text(labels, 11, "ink").attr("fill", (d) => ctx.palette.inkOn(ctx.palette.color(d.name))), {
136
- x: (d) => d.x,
137
- y: (d) => d.y
138
- });
139
- }
140
- };
141
- export { StreamTimeline, StreamTimelineBin, StreamTimelineCurve, StreamTimelineOffset, StreamTimelineOrder };