@rokkit/chart 1.0.0-next.15 → 1.0.0-next.151

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 (222) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +150 -46
  3. package/dist/Plot/index.d.ts +9 -0
  4. package/dist/PlotState.svelte.d.ts +49 -0
  5. package/dist/crossfilter/createCrossFilter.svelte.d.ts +13 -0
  6. package/dist/elements/index.d.ts +6 -0
  7. package/dist/geoms/lib/areas.d.ts +52 -0
  8. package/dist/geoms/lib/bars.d.ts +3 -0
  9. package/dist/index.d.ts +51 -0
  10. package/dist/lib/brewer.d.ts +9 -0
  11. package/dist/lib/brewing/BoxBrewer.svelte.d.ts +10 -0
  12. package/dist/lib/brewing/CartesianBrewer.svelte.d.ts +8 -0
  13. package/dist/lib/brewing/PieBrewer.svelte.d.ts +8 -0
  14. package/dist/lib/brewing/ViolinBrewer.svelte.d.ts +9 -0
  15. package/dist/lib/brewing/axes.svelte.d.ts +66 -0
  16. package/dist/lib/brewing/bars.svelte.d.ts +56 -0
  17. package/dist/lib/brewing/brewer.svelte.d.ts +114 -0
  18. package/dist/lib/brewing/colors.d.ts +17 -0
  19. package/dist/lib/brewing/dimensions.svelte.d.ts +35 -0
  20. package/dist/lib/brewing/index.svelte.d.ts +118 -0
  21. package/dist/lib/brewing/legends.svelte.d.ts +48 -0
  22. package/dist/lib/brewing/marks/arcs.d.ts +17 -0
  23. package/dist/lib/brewing/marks/areas.d.ts +31 -0
  24. package/dist/lib/brewing/marks/bars.d.ts +1 -0
  25. package/dist/lib/brewing/marks/boxes.d.ts +24 -0
  26. package/dist/lib/brewing/marks/lines.d.ts +24 -0
  27. package/dist/lib/brewing/marks/points.d.ts +40 -0
  28. package/dist/lib/brewing/marks/violins.d.ts +20 -0
  29. package/dist/lib/brewing/patterns.d.ts +14 -0
  30. package/dist/lib/brewing/scales.d.ts +28 -0
  31. package/dist/lib/brewing/scales.svelte.d.ts +24 -0
  32. package/dist/lib/brewing/stats.d.ts +23 -0
  33. package/dist/lib/brewing/symbols.d.ts +7 -0
  34. package/dist/lib/brewing/types.d.ts +162 -0
  35. package/dist/lib/chart.d.ts +38 -0
  36. package/dist/lib/context.d.ts +13 -0
  37. package/dist/lib/grid.d.ts +72 -0
  38. package/dist/lib/plot/chartProps.d.ts +177 -0
  39. package/dist/lib/plot/crossfilter.d.ts +13 -0
  40. package/dist/lib/plot/facet.d.ts +24 -0
  41. package/dist/lib/plot/frames.d.ts +47 -0
  42. package/dist/lib/plot/helpers.d.ts +3 -0
  43. package/dist/lib/plot/preset.d.ts +29 -0
  44. package/dist/lib/plot/scales.d.ts +5 -0
  45. package/dist/lib/plot/stat.d.ts +32 -0
  46. package/dist/lib/plot/types.d.ts +89 -0
  47. package/dist/lib/scales.svelte.d.ts +35 -0
  48. package/dist/lib/swatch.d.ts +12 -0
  49. package/dist/lib/ticks.d.ts +36 -0
  50. package/dist/lib/utils.d.ts +61 -0
  51. package/dist/lib/xscale.d.ts +11 -0
  52. package/dist/patterns/index.d.ts +4 -0
  53. package/dist/patterns/patterns.d.ts +72 -0
  54. package/dist/patterns/scale.d.ts +30 -0
  55. package/dist/symbols/constants/index.d.ts +1 -0
  56. package/dist/symbols/index.d.ts +5 -0
  57. package/package.json +41 -45
  58. package/src/AnimatedPlot.svelte +215 -0
  59. package/src/Chart.svelte +98 -0
  60. package/src/FacetPlot/Panel.svelte +23 -0
  61. package/src/FacetPlot.svelte +90 -0
  62. package/src/Plot/Arc.svelte +29 -0
  63. package/src/Plot/Area.svelte +25 -0
  64. package/src/Plot/Axis.svelte +73 -0
  65. package/src/Plot/Bar.svelte +96 -0
  66. package/src/Plot/Grid.svelte +30 -0
  67. package/src/Plot/Legend.svelte +167 -0
  68. package/src/Plot/Line.svelte +27 -0
  69. package/src/Plot/Point.svelte +27 -0
  70. package/src/Plot/Root.svelte +107 -0
  71. package/src/Plot/Timeline.svelte +95 -0
  72. package/src/Plot/Tooltip.svelte +81 -0
  73. package/src/Plot/index.js +9 -0
  74. package/src/Plot.svelte +181 -0
  75. package/src/PlotState.svelte.js +277 -0
  76. package/src/Sparkline.svelte +69 -0
  77. package/src/Symbol.svelte +21 -0
  78. package/src/Texture.svelte +18 -0
  79. package/src/charts/AreaChart.svelte +25 -0
  80. package/src/charts/BarChart.svelte +26 -0
  81. package/src/charts/BoxPlot.svelte +21 -0
  82. package/src/charts/BubbleChart.svelte +23 -0
  83. package/src/charts/LineChart.svelte +26 -0
  84. package/src/charts/PieChart.svelte +25 -0
  85. package/src/charts/ScatterPlot.svelte +25 -0
  86. package/src/charts/ViolinPlot.svelte +21 -0
  87. package/src/crossfilter/CrossFilter.svelte +38 -0
  88. package/src/crossfilter/FilterBar.svelte +32 -0
  89. package/src/crossfilter/FilterSlider.svelte +79 -0
  90. package/src/crossfilter/createCrossFilter.svelte.js +120 -0
  91. package/src/elements/Bar.svelte +22 -24
  92. package/src/elements/ColorRamp.svelte +20 -22
  93. package/src/elements/ContinuousLegend.svelte +20 -17
  94. package/src/elements/DefinePatterns.svelte +24 -0
  95. package/src/elements/DiscreteLegend.svelte +15 -15
  96. package/src/elements/Label.svelte +4 -8
  97. package/src/elements/SymbolGrid.svelte +22 -0
  98. package/src/elements/index.js +6 -0
  99. package/src/examples/BarChartExample.svelte +81 -0
  100. package/src/geoms/Arc.svelte +81 -0
  101. package/src/geoms/Area.svelte +50 -0
  102. package/src/geoms/Bar.svelte +142 -0
  103. package/src/geoms/Box.svelte +103 -0
  104. package/src/geoms/LabelPill.svelte +17 -0
  105. package/src/geoms/Line.svelte +99 -0
  106. package/src/geoms/Point.svelte +105 -0
  107. package/src/geoms/Violin.svelte +46 -0
  108. package/src/geoms/lib/areas.js +131 -0
  109. package/src/geoms/lib/bars.js +172 -0
  110. package/src/index.js +67 -16
  111. package/src/lib/brewer.js +25 -0
  112. package/src/lib/brewing/BoxBrewer.svelte.js +56 -0
  113. package/src/lib/brewing/CartesianBrewer.svelte.js +17 -0
  114. package/src/lib/brewing/PieBrewer.svelte.js +14 -0
  115. package/src/lib/brewing/ViolinBrewer.svelte.js +55 -0
  116. package/src/lib/brewing/axes.svelte.js +270 -0
  117. package/src/lib/brewing/bars.svelte.js +201 -0
  118. package/src/lib/brewing/brewer.svelte.js +230 -0
  119. package/src/lib/brewing/colors.js +22 -0
  120. package/src/lib/brewing/dimensions.svelte.js +56 -0
  121. package/src/lib/brewing/index.svelte.js +205 -0
  122. package/src/lib/brewing/legends.svelte.js +137 -0
  123. package/src/lib/brewing/marks/arcs.js +43 -0
  124. package/src/lib/brewing/marks/areas.js +59 -0
  125. package/src/lib/brewing/marks/bars.js +49 -0
  126. package/src/lib/brewing/marks/boxes.js +75 -0
  127. package/src/lib/brewing/marks/lines.js +48 -0
  128. package/src/lib/brewing/marks/points.js +57 -0
  129. package/src/lib/brewing/marks/violins.js +90 -0
  130. package/src/lib/brewing/patterns.js +31 -0
  131. package/src/lib/brewing/scales.js +51 -0
  132. package/src/lib/brewing/scales.svelte.js +82 -0
  133. package/src/lib/brewing/stats.js +66 -0
  134. package/src/lib/brewing/symbols.js +10 -0
  135. package/src/lib/brewing/types.js +73 -0
  136. package/src/lib/chart.js +220 -0
  137. package/src/lib/context.js +131 -0
  138. package/src/lib/grid.js +85 -0
  139. package/src/lib/plot/chartProps.js +76 -0
  140. package/src/lib/plot/crossfilter.js +16 -0
  141. package/src/lib/plot/facet.js +58 -0
  142. package/src/lib/plot/frames.js +80 -0
  143. package/src/lib/plot/helpers.js +14 -0
  144. package/src/lib/plot/preset.js +53 -0
  145. package/src/lib/plot/scales.js +56 -0
  146. package/src/lib/plot/stat.js +92 -0
  147. package/src/lib/plot/types.js +65 -0
  148. package/src/lib/scales.svelte.js +151 -0
  149. package/src/lib/swatch.js +13 -0
  150. package/src/lib/ticks.js +46 -0
  151. package/src/lib/utils.js +111 -118
  152. package/src/lib/xscale.js +31 -0
  153. package/src/patterns/DefinePatterns.svelte +32 -0
  154. package/src/patterns/PatternDef.svelte +27 -0
  155. package/src/patterns/index.js +4 -0
  156. package/src/patterns/patterns.js +208 -0
  157. package/src/patterns/scale.js +87 -0
  158. package/src/spec/chart-spec.js +29 -0
  159. package/src/symbols/RoundedSquare.svelte +33 -0
  160. package/src/symbols/Shape.svelte +37 -0
  161. package/src/symbols/constants/index.js +4 -0
  162. package/src/symbols/index.js +9 -0
  163. package/src/symbols/outline.svelte +60 -0
  164. package/src/symbols/solid.svelte +60 -0
  165. package/src/chart/FacetGrid.svelte +0 -51
  166. package/src/chart/Grid.svelte +0 -34
  167. package/src/chart/Legend.svelte +0 -16
  168. package/src/chart/PatternDefs.svelte +0 -13
  169. package/src/chart/Swatch.svelte +0 -93
  170. package/src/chart/SwatchButton.svelte +0 -29
  171. package/src/chart/SwatchGrid.svelte +0 -55
  172. package/src/chart/Symbol.svelte +0 -37
  173. package/src/chart/Texture.svelte +0 -16
  174. package/src/chart/TexturedShape.svelte +0 -27
  175. package/src/chart/TimelapseChart.svelte +0 -97
  176. package/src/chart/Timer.svelte +0 -27
  177. package/src/chart.js +0 -9
  178. package/src/components/charts/Axis.svelte +0 -66
  179. package/src/components/charts/Chart.svelte +0 -35
  180. package/src/components/index.js +0 -23
  181. package/src/components/lib/axis.js +0 -0
  182. package/src/components/lib/chart.js +0 -187
  183. package/src/components/lib/color.js +0 -327
  184. package/src/components/lib/funnel.js +0 -204
  185. package/src/components/lib/index.js +0 -19
  186. package/src/components/lib/pattern.js +0 -190
  187. package/src/components/lib/rollup.js +0 -55
  188. package/src/components/lib/shape.js +0 -199
  189. package/src/components/lib/summary.js +0 -145
  190. package/src/components/lib/theme.js +0 -23
  191. package/src/components/lib/timer.js +0 -41
  192. package/src/components/lib/utils.js +0 -165
  193. package/src/components/plots/BarPlot.svelte +0 -36
  194. package/src/components/plots/BoxPlot.svelte +0 -54
  195. package/src/components/plots/ScatterPlot.svelte +0 -30
  196. package/src/components/store.js +0 -70
  197. package/src/constants.js +0 -66
  198. package/src/elements/PatternDefs.svelte +0 -13
  199. package/src/elements/PatternMask.svelte +0 -20
  200. package/src/elements/Symbol.svelte +0 -38
  201. package/src/elements/Tooltip.svelte +0 -23
  202. package/src/funnel.svelte +0 -35
  203. package/src/geom.js +0 -105
  204. package/src/lib/axis.js +0 -75
  205. package/src/lib/colors.js +0 -32
  206. package/src/lib/geom.js +0 -4
  207. package/src/lib/shapes.js +0 -144
  208. package/src/lib/timer.js +0 -44
  209. package/src/lookup.js +0 -29
  210. package/src/plots/BarPlot.svelte +0 -55
  211. package/src/plots/BoxPlot.svelte +0 -0
  212. package/src/plots/FunnelPlot.svelte +0 -33
  213. package/src/plots/HeatMap.svelte +0 -5
  214. package/src/plots/HeatMapCalendar.svelte +0 -129
  215. package/src/plots/LinePlot.svelte +0 -55
  216. package/src/plots/Plot.svelte +0 -25
  217. package/src/plots/RankBarPlot.svelte +0 -38
  218. package/src/plots/ScatterPlot.svelte +0 -20
  219. package/src/plots/ViolinPlot.svelte +0 -11
  220. package/src/plots/heatmap.js +0 -70
  221. package/src/plots/index.js +0 -10
  222. package/src/swatch.js +0 -11
@@ -0,0 +1,89 @@
1
+ export type GeomSpec = {
2
+ /**
3
+ * - Geom type: 'bar'|'line'|'area'|'point'|'box'|'violin'|'arc' or custom
4
+ */
5
+ type: string;
6
+ x?: string | undefined;
7
+ y?: string | undefined;
8
+ color?: string | undefined;
9
+ fill?: string | undefined;
10
+ size?: string | undefined;
11
+ symbol?: string | undefined;
12
+ pattern?: string | undefined;
13
+ /**
14
+ * - Built-in or helpers.stats key
15
+ */
16
+ stat?: string | undefined;
17
+ options?: Record<string, unknown> | undefined;
18
+ };
19
+ export type PlotSpec = {
20
+ data: Record<string, unknown>[];
21
+ x?: string | undefined;
22
+ y?: string | undefined;
23
+ color?: string | undefined;
24
+ fill?: string | undefined;
25
+ size?: string | undefined;
26
+ symbol?: string | undefined;
27
+ pattern?: string | undefined;
28
+ theta?: string | undefined;
29
+ labels?: Record<string, string> | undefined;
30
+ xDomain?: unknown[] | undefined;
31
+ yDomain?: number[] | undefined;
32
+ xLabel?: string | undefined;
33
+ yLabel?: string | undefined;
34
+ axisOrigin?: [number, number] | undefined;
35
+ colorScale?: "diverging" | "sequential" | "categorical" | undefined;
36
+ colorScheme?: string | undefined;
37
+ colorMidpoint?: number | undefined;
38
+ colorDomain?: unknown[] | undefined;
39
+ geoms: GeomSpec[];
40
+ facet?: {
41
+ by: string;
42
+ cols?: number;
43
+ scales?: "fixed" | "free" | "free_x" | "free_y";
44
+ } | undefined;
45
+ animate?: {
46
+ by: string;
47
+ duration?: number;
48
+ loop?: boolean;
49
+ } | undefined;
50
+ grid?: boolean | undefined;
51
+ legend?: boolean | undefined;
52
+ tooltip?: boolean | undefined;
53
+ title?: string | undefined;
54
+ preset?: string | undefined;
55
+ width?: number | undefined;
56
+ height?: number | undefined;
57
+ mode?: "light" | "dark" | undefined;
58
+ };
59
+ export type PlotHelpers = {
60
+ stats?: Record<string, (values: unknown[]) => unknown> | undefined;
61
+ format?: Record<string, (v: unknown) => string> | undefined;
62
+ tooltip?: ((d: Record<string, unknown>) => string) | undefined;
63
+ /**
64
+ * Svelte components keyed by type name
65
+ */
66
+ geoms?: Record<string, unknown> | undefined;
67
+ /**
68
+ * d3 scale override
69
+ */
70
+ colorScale?: unknown;
71
+ preset?: {
72
+ colors: string[];
73
+ patterns: string[];
74
+ symbols: string[];
75
+ } | undefined;
76
+ presets?: Record<string, {
77
+ colors: string[];
78
+ patterns: string[];
79
+ symbols: string[];
80
+ }> | undefined;
81
+ /**
82
+ * custom SVG pattern components keyed by name
83
+ */
84
+ patterns?: Record<string, unknown> | undefined;
85
+ /**
86
+ * custom symbol shape components keyed by name
87
+ */
88
+ symbols?: Record<string, unknown> | undefined;
89
+ };
@@ -0,0 +1,35 @@
1
+ export function createScales(data: any, dimensions: any, options: any): {
2
+ xScale?: undefined;
3
+ yScale?: undefined;
4
+ colorScale?: undefined;
5
+ } | {
6
+ xScale: any;
7
+ yScale: any;
8
+ colorScale: Object | null;
9
+ };
10
+ /**
11
+ * Calculates the actual chart dimensions after applying margins
12
+ *
13
+ * @param {number} width
14
+ * @param {number} height
15
+ * @param {Object} margin
16
+ * @returns {Object} Dimensions with calculated inner width and height
17
+ */
18
+ export function calculateChartDimensions(width: number, height: number, margin: Object): Object;
19
+ /**
20
+ * Gets the axis origin value
21
+ *
22
+ * @param {Object} scale D3 scale
23
+ * @returns {number} Origin value
24
+ */
25
+ export function getOriginValue(scale: Object): number;
26
+ /**
27
+ * Creates axis ticks
28
+ *
29
+ * @param {Object} scale D3 scale
30
+ * @param {string} axis Axis type ('x' or 'y')
31
+ * @param {number} count Number of ticks
32
+ * @param {number} fontSize Font size for determining tick density
33
+ * @returns {Array} Array of tick objects
34
+ */
35
+ export function createTicks(scale: Object, axis: string, count?: number, fontSize?: number): any[];
@@ -0,0 +1,12 @@
1
+ export namespace swatch {
2
+ export { palette };
3
+ export namespace keys {
4
+ export let gray: string[];
5
+ export let color: string[];
6
+ export { shapes as symbol };
7
+ export { PATTERN_ORDER as pattern };
8
+ }
9
+ }
10
+ import palette from './palette.json';
11
+ import { shapes } from '../symbols';
12
+ import { PATTERN_ORDER } from './brewing/patterns.js';
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @typedef {Object} TickSteps
3
+ * @property {number} major - count of major ticks
4
+ * @property {number} minor - count of minor ticks
5
+ */
6
+ /**
7
+ * Generate an array of ticks for a given axis and the tick type
8
+ *
9
+ * @param {number} lower - The lower bound of the axis
10
+ * @param {number} upper - The upper bound of the axis
11
+ * @param {TickSteps} steps - The number of steps between major and minor ticks
12
+ * @param {string} type - The type of tick to generate
13
+ *
14
+ * @returns {Array} - An array of objects representing the ticks
15
+ */
16
+ export function ticksByType(lower: number, upper: number, steps: TickSteps, type: string): any[];
17
+ /**
18
+ * Generate an array of ticks for a given axis
19
+ *
20
+ * @param {number} lower - The lower bound of the axis
21
+ * @param {number} upper - The upper bound of the axis
22
+ * @param {TickSteps} steps - The number of steps between major and minor ticks
23
+ *
24
+ * @returns {Array} - An array of objects representing the ticks
25
+ */
26
+ export function getTicks(lower: number, upper: number, steps?: TickSteps): any[];
27
+ export type TickSteps = {
28
+ /**
29
+ * - count of major ticks
30
+ */
31
+ major: number;
32
+ /**
33
+ * - count of minor ticks
34
+ */
35
+ minor: number;
36
+ };
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Creates appropriate scales based on data and dimensions
3
+ *
4
+ * @param {Array} data The dataset
5
+ * @param {Object} dimensions Chart dimensions
6
+ * @param {Object} [options] Additional options
7
+ * @param {string} options.xKey Field to use for x-axis
8
+ * @param {string} options.yKey Field to use for y-axis
9
+ * @param {string} [options.colorKey] Field to use for color mapping
10
+ * @returns {Object} Object containing xScale, yScale, and colorScale
11
+ */
12
+ export function createScales(data: any[], dimensions: Object, options?: {
13
+ xKey: string;
14
+ yKey: string;
15
+ colorKey?: string | undefined;
16
+ }): Object;
17
+ /**
18
+ * Calculates the actual chart dimensions after applying margins
19
+ *
20
+ * @param {Object} dimensions Original dimensions
21
+ * @returns {Object} Dimensions with calculated inner width and height
22
+ */
23
+ export function calculateChartDimensions(dimensions: Object): Object;
24
+ /**
25
+ * Normalizes data for use with D3 charts
26
+ *
27
+ * @param {Array|Object} inputData Raw data or dataset object
28
+ * @returns {Array} Normalized data array
29
+ */
30
+ export function normalizeData(inputData: any[] | Object): any[];
31
+ /**
32
+ * Generates a unique ID for SVG elements
33
+ *
34
+ * @param {string} prefix Prefix for the ID
35
+ * @returns {string} A unique ID
36
+ */
37
+ export function uniqueId(prefix?: string): string;
38
+ /**
39
+ * Formats tooltip content for a data point
40
+ *
41
+ * @param {Object} d Data point
42
+ * @param {Object} options Tooltip format options
43
+ * @returns {string} Formatted tooltip HTML content
44
+ */
45
+ export function formatTooltipContent(d: Object, options?: Object): string;
46
+ /**
47
+ * Generates a tooltip formatter function
48
+ *
49
+ * @param {Object} options Tooltip format options
50
+ * @returns {Function} A function that formats tooltip content
51
+ */
52
+ export function createTooltipFormatter(options?: Object): Function;
53
+ /**
54
+ * Calculates the transform attribute for SVG elements
55
+ *
56
+ * @param {number} x X position
57
+ * @param {number} y Y position
58
+ * @returns {string} Transform attribute value
59
+ */
60
+ export function transform(x: number, y: number): string;
61
+ export function scaledPathCollection(paths: any): {};
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Builds an appropriate D3 x-axis scale based on value types.
3
+ * Returns scaleTime for Date values, scaleLinear for numeric values,
4
+ * or scaleBand for categorical values.
5
+ *
6
+ * @param {Array} xValues
7
+ * @param {Object} dimensions
8
+ * @param {number} padding
9
+ * @returns {import('d3-scale').ScaleContinuousNumeric|import('d3-scale').ScaleBand}
10
+ */
11
+ export function buildXScale(xValues: any[], dimensions: Object, padding: number): any | any;
@@ -0,0 +1,4 @@
1
+ export { default as PatternDef } from "./PatternDef.svelte";
2
+ export { default as DefinePatterns } from "./DefinePatterns.svelte";
3
+ export { PATTERNS } from "./patterns.js";
4
+ export { scaleMark, resolveMarkAttrs } from "./scale.js";
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Unified pattern library.
3
+ *
4
+ * Each entry is an array of mark descriptors. All geometry is in normalized
5
+ * 0–1 coordinates; the renderer scales by `size` at paint time.
6
+ *
7
+ * Mark types
8
+ * ----------
9
+ * circle { cx, cy, r }
10
+ * line { x1, y1, x2, y2 } coordinates may exceed 0–1 for seamless tiling
11
+ * polygon { points: [x,y][] }
12
+ * rect { x, y, w, h }
13
+ * path { d: [cmd, ...args][] } SVG path commands as nested arrays (H/V take one arg)
14
+ *
15
+ * Appearance
16
+ * ----------
17
+ * fill: true → element uses fill color (stroke: none)
18
+ * fill: false → element uses stroke color (fill: none) ← default
19
+ * fillOpacity: n → applied as fill-opacity on filled marks
20
+ * opacity: n → applied as opacity on any mark
21
+ */
22
+ /** @typedef {{ type: 'circle', cx: number, cy: number, r: number, fill?: boolean, fillOpacity?: number, opacity?: number }} CircleMark */
23
+ /** @typedef {{ type: 'line', x1: number, y1: number, x2: number, y2: number, fill?: false, strokeWidth?: number }} LineMark */
24
+ /** @typedef {{ type: 'polygon', points: [number,number][], fill?: boolean, fillOpacity?: number, opacity?: number }} PolygonMark */
25
+ /** @typedef {{ type: 'rect', x: number, y: number, w: number, h: number, fill?: boolean, fillOpacity?: number, opacity?: number }} RectMark */
26
+ /** @typedef {{ type: 'path', d: (string|number)[][], fill?: boolean, fillOpacity?: number, opacity?: number }} PathMark */
27
+ /** @typedef {CircleMark | LineMark | PolygonMark | RectMark | PathMark} PatternMark */
28
+ /** @type {Record<string, PatternMark[]>} */
29
+ export const PATTERNS: Record<string, PatternMark[]>;
30
+ export type CircleMark = {
31
+ type: "circle";
32
+ cx: number;
33
+ cy: number;
34
+ r: number;
35
+ fill?: boolean;
36
+ fillOpacity?: number;
37
+ opacity?: number;
38
+ };
39
+ export type LineMark = {
40
+ type: "line";
41
+ x1: number;
42
+ y1: number;
43
+ x2: number;
44
+ y2: number;
45
+ fill?: false;
46
+ strokeWidth?: number;
47
+ };
48
+ export type PolygonMark = {
49
+ type: "polygon";
50
+ points: [number, number][];
51
+ fill?: boolean;
52
+ fillOpacity?: number;
53
+ opacity?: number;
54
+ };
55
+ export type RectMark = {
56
+ type: "rect";
57
+ x: number;
58
+ y: number;
59
+ w: number;
60
+ h: number;
61
+ fill?: boolean;
62
+ fillOpacity?: number;
63
+ opacity?: number;
64
+ };
65
+ export type PathMark = {
66
+ type: "path";
67
+ d: (string | number)[][];
68
+ fill?: boolean;
69
+ fillOpacity?: number;
70
+ opacity?: number;
71
+ };
72
+ export type PatternMark = CircleMark | LineMark | PolygonMark | RectMark | PathMark;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Scale all geometric coordinates in a mark by `size`.
3
+ * Renames rect `w`/`h` to `width`/`height` and converts polygon/path to strings.
4
+ * @param {PatternMark} mark
5
+ * @param {number} size
6
+ * @returns {object}
7
+ */
8
+ export function scaleMark(mark: PatternMark, size: number): object;
9
+ /**
10
+ * Resolve a scaled mark into SVG-ready `{ type, attrs }`.
11
+ * `attrs` can be spread directly onto the SVG element.
12
+ *
13
+ * Per-mark overrides respected:
14
+ * mark.strokeWidth → `stroke-width` (takes precedence over `thickness`)
15
+ * mark.fillOpacity → `fill-opacity`
16
+ * mark.opacity → `opacity`
17
+ *
18
+ * @param {object} scaledMark Output of scaleMark
19
+ * @param {{ fill: string, stroke: string, thickness: number }} appearance
20
+ * @returns {{ type: string, attrs: object }}
21
+ */
22
+ export function resolveMarkAttrs(scaledMark: object, { fill, stroke, thickness }: {
23
+ fill: string;
24
+ stroke: string;
25
+ thickness: number;
26
+ }): {
27
+ type: string;
28
+ attrs: object;
29
+ };
30
+ import type { PatternMark } from './patterns.js';
@@ -0,0 +1 @@
1
+ export const namedShapes: {};
@@ -0,0 +1,5 @@
1
+ export const shapes: string[];
2
+ export const components: {
3
+ default: import("svelte/legacy").LegacyComponentType;
4
+ 'rounded-square': import("svelte/legacy").LegacyComponentType;
5
+ };
package/package.json CHANGED
@@ -1,63 +1,59 @@
1
1
  {
2
2
  "name": "@rokkit/chart",
3
- "version": "1.0.0-next.15",
4
- "description": "Components for making interactive charts.",
3
+ "version": "1.0.0-next.151",
4
+ "type": "module",
5
+ "description": "Data-driven chart components",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/jerrythomas/rokkit.git"
9
+ },
5
10
  "author": "Jerry Thomas <me@jerrythomas.name>",
6
11
  "license": "MIT",
7
- "main": "src/index.js",
8
- "svelte": "src/index.js",
9
- "module": "src/index.js",
10
- "types": "dist/index.d.ts",
11
- "type": "module",
12
+ "npm": {
13
+ "publish": false
14
+ },
12
15
  "publishConfig": {
13
16
  "access": "public"
14
17
  },
15
- "devDependencies": {
16
- "@sveltejs/vite-plugin-svelte": "^2.0.2",
17
- "@testing-library/svelte": "^3.2.2",
18
- "@vitest/ui": "~0.12.10",
19
- "eslint": "^8.33.0",
20
- "js-yaml": "^4.1.0",
21
- "jsdom": "^19.0.0",
22
- "svelte": "^3.55.1",
23
- "typescript": "^4.9.5",
24
- "vite": "^4.1.1",
25
- "vitest": "~0.19.1",
26
- "shared-config": "1.0.0",
27
- "eslint-config-shared": "1.0.0"
28
- },
29
- "dependencies": {
30
- "d3-array": "^3.2.2",
31
- "d3-collection": "^1.0.7",
32
- "d3-scale": "^4.0.2",
33
- "d3-shape": "^3.2.0",
34
- "date-fns": "^2.29.3",
35
- "ramda": "^0.28.0",
36
- "yootils": "^0.3.1",
37
- "@rokkit/core": "1.0.0-next.15"
18
+ "scripts": {
19
+ "prepublishOnly": "cp ../../LICENSE . && bun clean && bun tsc --project tsconfig.build.json",
20
+ "postpublish": "rm -f LICENSE",
21
+ "clean": "rm -rf dist",
22
+ "build": "bun prepublishOnly"
38
23
  },
39
24
  "files": [
40
25
  "src/**/*.js",
41
26
  "src/**/*.svelte",
42
- "!src/fixtures",
43
- "!src/mocks",
44
- "!src/**/*.spec.js"
27
+ "dist/**/*.d.ts",
28
+ "README.md",
29
+ "package.json",
30
+ "LICENSE"
45
31
  ],
46
32
  "exports": {
47
- "./src": "./src",
48
33
  "./package.json": "./package.json",
49
34
  ".": {
50
35
  "types": "./dist/index.d.ts",
51
- "import": "./src/index.js"
52
- }
36
+ "import": "./src/index.js",
37
+ "svelte": "./src/index.js"
38
+ },
39
+ "./patterns": "./src/patterns/index.js",
40
+ "./symbols": "./src/symbols/index.js",
41
+ "./symbols/*": "./src/symbols/*",
42
+ "./patterns/*": "./src/patterns/*",
43
+ "./charts/*": "./src/charts/*"
53
44
  },
54
- "scripts": {
55
- "lint": "prettier --check --plugin-search-dir=. . && eslint .",
56
- "format": "prettier --write --plugin-search-dir=. .",
57
- "test:ci": "vitest run",
58
- "test:ui": "vitest --ui",
59
- "test": "vitest",
60
- "coverage": "vitest run --coverage",
61
- "upgrade": "pnpm upgrade"
45
+ "dependencies": {
46
+ "@rokkit/core": "latest",
47
+ "@rokkit/data": "latest",
48
+ "@rokkit/states": "latest",
49
+ "d3-array": "^3.2.4",
50
+ "d3-axis": "^3.0.0",
51
+ "d3-format": "^3.1.2",
52
+ "d3-scale": "^4.0.2",
53
+ "d3-scale-chromatic": "^3.1.0",
54
+ "d3-selection": "^3.0.0",
55
+ "d3-shape": "^3.2.0",
56
+ "d3-transition": "^3.0.1",
57
+ "ramda": "^0.32.0"
62
58
  }
63
- }
59
+ }
@@ -0,0 +1,215 @@
1
+ <script>
2
+ import { onMount, onDestroy } from 'svelte'
3
+ import { extractFrames, completeFrames, computeStaticDomains } from './lib/plot/frames.js'
4
+ import { applyGeomStat } from './lib/plot/stat.js'
5
+ import Timeline from './Plot/Timeline.svelte'
6
+ import PlotChart from './Plot.svelte'
7
+
8
+ /**
9
+ * @type {{
10
+ * data: Object[],
11
+ * animate: { by: string, duration?: number, loop?: boolean },
12
+ * x?: string,
13
+ * y?: string,
14
+ * color?: string,
15
+ * geoms?: import('./lib/plot/types.js').GeomSpec[],
16
+ * helpers?: import('./lib/plot/types.js').PlotHelpers,
17
+ * width?: number,
18
+ * height?: number,
19
+ * mode?: 'light' | 'dark',
20
+ * grid?: boolean,
21
+ * legend?: boolean,
22
+ * children?: import('svelte').Snippet
23
+ * }}
24
+ */
25
+ let {
26
+ data = [],
27
+ animate,
28
+ x,
29
+ y,
30
+ color,
31
+ geoms = [],
32
+ helpers = {},
33
+ width = 600,
34
+ height = 400,
35
+ mode = 'light',
36
+ grid = true,
37
+ legend = false,
38
+ children
39
+ } = $props()
40
+
41
+ // Pre-aggregate and complete frames when any geom has a non-identity stat:
42
+ // 1. applyGeomStat: aggregate data by (x, color?, by) → one row per combination
43
+ // 2. completeFrames: alignBy(by) ensures all frame values appear for every (x, color?)
44
+ // group, filling missing rows with y=0 so bars animate smoothly
45
+ // Geoms are returned with stat: 'identity' so PlotChart renders the pre-aggregated values as-is.
46
+ const prepared = $derived.by(() => {
47
+ const firstNonIdentity = geoms.find((g) => g.stat && g.stat !== 'identity')
48
+ if (!firstNonIdentity) return { data, geoms }
49
+
50
+ const aggChannels = { y }
51
+ if (x) aggChannels.x = x
52
+ if (color) aggChannels.color = color
53
+ aggChannels.frame = animate.by // 'frame' is not a value channel, so it becomes a group-by
54
+
55
+ const aggregated = applyGeomStat(
56
+ data,
57
+ { stat: firstNonIdentity.stat, channels: aggChannels },
58
+ helpers
59
+ )
60
+ const completeData = completeFrames(aggregated, { x, y, color }, animate.by)
61
+
62
+ return { data: completeData, geoms: geoms.map((g) => ({ ...g, stat: 'identity' })) }
63
+ })
64
+
65
+ // Extract frames and compute stable domains from the full prepared dataset
66
+ const rawFrames = $derived(extractFrames(prepared.data, animate.by))
67
+ const frameKeys = $derived([...rawFrames.keys()])
68
+
69
+ const channels = $derived({ x, y, color })
70
+ const staticDomains = $derived(
71
+ x && y ? computeStaticDomains(prepared.data, channels) : { xDomain: undefined, yDomain: undefined }
72
+ )
73
+
74
+ // Playback state
75
+ let currentIndex = $state(0)
76
+ let playing = $state(false)
77
+ let speed = $state(1)
78
+
79
+ // Current frame data — already complete (all x/color combos present)
80
+ const currentFrameData = $derived.by(() => {
81
+ const key = frameKeys[currentIndex]
82
+ return rawFrames.get(key) ?? []
83
+ })
84
+
85
+ // Reduced motion preference
86
+ let prefersReducedMotion = $state(false)
87
+ onMount(() => {
88
+ if (typeof window.matchMedia !== 'function') return
89
+ const mq = window.matchMedia('(prefers-reduced-motion: reduce)')
90
+ prefersReducedMotion = mq.matches
91
+ const handler = (e) => { prefersReducedMotion = e.matches }
92
+ mq.addEventListener('change', handler)
93
+ return () => mq.removeEventListener('change', handler)
94
+ })
95
+
96
+ // Animation loop
97
+ const baseDuration = $derived(animate.duration ?? 800)
98
+ const msPerFrame = $derived(Math.round(baseDuration / speed))
99
+ let lastTime = 0
100
+ let rafId = 0
101
+
102
+ function advanceFrame() {
103
+ currentIndex = currentIndex + 1
104
+ if (currentIndex >= frameKeys.length) {
105
+ if (animate.loop ?? false) currentIndex = 0
106
+ else playing = false
107
+ }
108
+ }
109
+
110
+ function tick(time) {
111
+ if (!playing) return
112
+ if (time - lastTime >= msPerFrame) {
113
+ lastTime = time
114
+ advanceFrame()
115
+ if (!playing) return
116
+ }
117
+ rafId = requestAnimationFrame(tick)
118
+ }
119
+
120
+ $effect(() => {
121
+ // Reading msPerFrame here makes it a tracked dependency — effect re-runs on speed changes,
122
+ // which resets lastTime=0 to re-anchor frame pacing.
123
+ const _ms = msPerFrame
124
+ if (playing && !prefersReducedMotion) {
125
+ lastTime = 0
126
+ rafId = requestAnimationFrame(tick)
127
+ } else {
128
+ cancelAnimationFrame(rafId)
129
+ }
130
+ return () => cancelAnimationFrame(rafId)
131
+ })
132
+
133
+ // Reduced motion: step frames on interval instead
134
+ let reducedInterval = 0
135
+ $effect(() => {
136
+ if (!playing || !prefersReducedMotion) {
137
+ clearInterval(reducedInterval)
138
+ return
139
+ }
140
+ reducedInterval = setInterval(() => {
141
+ currentIndex = currentIndex + 1
142
+ if (currentIndex >= frameKeys.length) {
143
+ if (animate.loop ?? false) currentIndex = 0
144
+ else { playing = false; clearInterval(reducedInterval) }
145
+ }
146
+ }, msPerFrame)
147
+ return () => clearInterval(reducedInterval)
148
+ })
149
+
150
+ onDestroy(() => {
151
+ cancelAnimationFrame(rafId)
152
+ clearInterval(reducedInterval)
153
+ })
154
+
155
+ $effect(() => {
156
+ const len = frameKeys.length
157
+ if (currentIndex >= len && len > 0) {
158
+ currentIndex = len - 1
159
+ playing = false
160
+ } else if (len === 0) {
161
+ currentIndex = 0
162
+ playing = false
163
+ }
164
+ })
165
+
166
+ function handlePlay() { playing = true }
167
+ function handlePause() { playing = false }
168
+ function handleScrub(index) {
169
+ playing = false
170
+ currentIndex = index
171
+ }
172
+ function handleSpeed(s) { speed = s }
173
+
174
+ // Build spec for the current frame, with static domain overrides
175
+ const frameSpec = $derived({
176
+ data: currentFrameData,
177
+ x, y, color,
178
+ geoms: prepared.geoms,
179
+ xDomain: staticDomains.xDomain,
180
+ yDomain: staticDomains.yDomain
181
+ })
182
+ </script>
183
+
184
+ <div data-plot-animated>
185
+ <PlotChart
186
+ spec={frameSpec}
187
+ {helpers}
188
+ {width}
189
+ {height}
190
+ {mode}
191
+ {grid}
192
+ {legend}
193
+ >
194
+ {@render children?.()}
195
+ </PlotChart>
196
+
197
+ <Timeline
198
+ {frameKeys}
199
+ {currentIndex}
200
+ {playing}
201
+ {speed}
202
+ onplay={handlePlay}
203
+ onpause={handlePause}
204
+ onscrub={handleScrub}
205
+ onspeed={handleSpeed}
206
+ />
207
+ </div>
208
+
209
+ <style>
210
+ [data-plot-animated] {
211
+ display: flex;
212
+ flex-direction: column;
213
+ width: 100%;
214
+ }
215
+ </style>