@rokkit/chart 1.3.8 → 1.3.9

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 (130) hide show
  1. package/dist/Chart.svelte +50 -64
  2. package/dist/Plot/Root.svelte +4 -1
  3. package/dist/Plot/Root.svelte.d.ts +2 -0
  4. package/dist/Plot/index.d.ts +1 -1
  5. package/dist/Plot/index.js +1 -1
  6. package/dist/PlotState.svelte.d.ts +14 -2
  7. package/dist/PlotState.svelte.js +46 -4
  8. package/dist/charts/AreaChart.svelte +8 -1
  9. package/dist/charts/AreaChart.svelte.d.ts +5 -0
  10. package/dist/charts/BarChart.svelte +8 -1
  11. package/dist/charts/BarChart.svelte.d.ts +5 -0
  12. package/dist/charts/BoxPlot.svelte +3 -1
  13. package/dist/charts/BoxPlot.svelte.d.ts +1 -0
  14. package/dist/charts/BubbleChart.svelte +3 -1
  15. package/dist/charts/BubbleChart.svelte.d.ts +1 -0
  16. package/dist/charts/LineChart.svelte +3 -1
  17. package/dist/charts/LineChart.svelte.d.ts +1 -0
  18. package/dist/charts/PieChart.svelte +4 -2
  19. package/dist/charts/PieChart.svelte.d.ts +1 -0
  20. package/dist/charts/ScatterPlot.svelte +3 -1
  21. package/dist/charts/ScatterPlot.svelte.d.ts +1 -0
  22. package/dist/charts/ViolinPlot.svelte +3 -1
  23. package/dist/charts/ViolinPlot.svelte.d.ts +1 -0
  24. package/dist/geoms/Arc.svelte +21 -55
  25. package/dist/geoms/Arc.svelte.d.ts +4 -4
  26. package/dist/geoms/Area.svelte +45 -44
  27. package/dist/geoms/Area.svelte.d.ts +8 -1
  28. package/dist/geoms/Bar.svelte +33 -56
  29. package/dist/geoms/Bar.svelte.d.ts +9 -0
  30. package/dist/geoms/Box.svelte +118 -131
  31. package/dist/geoms/Box.svelte.d.ts +5 -3
  32. package/dist/geoms/Candlestick.svelte +22 -77
  33. package/dist/geoms/Candlestick.svelte.d.ts +2 -0
  34. package/dist/geoms/Heatmap.svelte +21 -66
  35. package/dist/geoms/Heatmap.svelte.d.ts +2 -0
  36. package/dist/geoms/Hexbin.svelte +20 -100
  37. package/dist/geoms/Hexbin.svelte.d.ts +2 -0
  38. package/dist/geoms/Jitter.svelte +21 -36
  39. package/dist/geoms/Jitter.svelte.d.ts +5 -3
  40. package/dist/geoms/Line.svelte +27 -31
  41. package/dist/geoms/Line.svelte.d.ts +5 -0
  42. package/dist/geoms/Point.svelte +31 -66
  43. package/dist/geoms/Point.svelte.d.ts +5 -1
  44. package/dist/geoms/Ribbon.svelte +30 -124
  45. package/dist/geoms/Ribbon.svelte.d.ts +2 -0
  46. package/dist/geoms/Rule.svelte +5 -1
  47. package/dist/geoms/Rule.svelte.d.ts +3 -0
  48. package/dist/geoms/Violin.svelte +21 -40
  49. package/dist/geoms/Violin.svelte.d.ts +5 -3
  50. package/dist/geoms/Waterfall.svelte +19 -80
  51. package/dist/geoms/Waterfall.svelte.d.ts +2 -0
  52. package/dist/geoms/lib/GeomState.svelte.d.ts +51 -0
  53. package/dist/geoms/lib/GeomState.svelte.js +79 -0
  54. package/dist/geoms/lib/aesthetics.d.ts +36 -0
  55. package/dist/geoms/lib/aesthetics.js +45 -0
  56. package/dist/geoms/lib/areas.d.ts +1 -1
  57. package/dist/geoms/lib/areas.js +4 -2
  58. package/dist/geoms/lib/bars.d.ts +2 -2
  59. package/dist/geoms/lib/bars.js +13 -8
  60. package/dist/geoms/lib/marks/arc.d.ts +24 -0
  61. package/dist/geoms/lib/marks/arc.js +28 -0
  62. package/dist/geoms/lib/marks/area.d.ts +23 -0
  63. package/dist/geoms/lib/marks/area.js +38 -0
  64. package/dist/geoms/lib/marks/bar.d.ts +16 -0
  65. package/dist/geoms/lib/marks/bar.js +43 -0
  66. package/dist/geoms/lib/marks/box.d.ts +14 -0
  67. package/dist/geoms/lib/marks/box.js +30 -0
  68. package/dist/geoms/lib/marks/candlestick.d.ts +27 -0
  69. package/dist/geoms/lib/marks/candlestick.js +52 -0
  70. package/dist/geoms/lib/marks/heatmap.d.ts +24 -0
  71. package/dist/geoms/lib/marks/heatmap.js +41 -0
  72. package/dist/geoms/lib/marks/hexbin.d.ts +29 -0
  73. package/dist/geoms/lib/marks/hexbin.js +62 -0
  74. package/dist/geoms/lib/marks/jitter.d.ts +21 -0
  75. package/dist/geoms/lib/marks/jitter.js +36 -0
  76. package/dist/geoms/lib/marks/line.d.ts +26 -0
  77. package/dist/geoms/lib/marks/line.js +25 -0
  78. package/dist/geoms/lib/marks/point.d.ts +25 -0
  79. package/dist/geoms/lib/marks/point.js +58 -0
  80. package/dist/geoms/lib/marks/ribbon.d.ts +31 -0
  81. package/dist/geoms/lib/marks/ribbon.js +77 -0
  82. package/dist/geoms/lib/marks/violin.d.ts +13 -0
  83. package/dist/geoms/lib/marks/violin.js +31 -0
  84. package/dist/geoms/lib/marks/waterfall.d.ts +25 -0
  85. package/dist/geoms/lib/marks/waterfall.js +58 -0
  86. package/dist/index.d.ts +1 -8
  87. package/dist/index.js +1 -8
  88. package/dist/lib/preset.d.ts +11 -1
  89. package/dist/lib/preset.js +16 -4
  90. package/package.json +1 -1
  91. package/dist/Plot/Arc.svelte +0 -30
  92. package/dist/Plot/Arc.svelte.d.ts +0 -18
  93. package/dist/lib/brewer.d.ts +0 -9
  94. package/dist/lib/brewer.js +0 -25
  95. package/dist/lib/brewing/BoxBrewer.svelte.d.ts +0 -8
  96. package/dist/lib/brewing/BoxBrewer.svelte.js +0 -14
  97. package/dist/lib/brewing/CartesianBrewer.svelte.d.ts +0 -8
  98. package/dist/lib/brewing/CartesianBrewer.svelte.js +0 -21
  99. package/dist/lib/brewing/PieBrewer.svelte.d.ts +0 -8
  100. package/dist/lib/brewing/PieBrewer.svelte.js +0 -14
  101. package/dist/lib/brewing/QuartileBrewer.svelte.d.ts +0 -9
  102. package/dist/lib/brewing/QuartileBrewer.svelte.js +0 -51
  103. package/dist/lib/brewing/ViolinBrewer.svelte.d.ts +0 -8
  104. package/dist/lib/brewing/ViolinBrewer.svelte.js +0 -14
  105. package/dist/lib/brewing/axes.svelte.d.ts +0 -66
  106. package/dist/lib/brewing/axes.svelte.js +0 -270
  107. package/dist/lib/brewing/bars.svelte.d.ts +0 -56
  108. package/dist/lib/brewing/bars.svelte.js +0 -201
  109. package/dist/lib/brewing/brewer.svelte.d.ts +0 -124
  110. package/dist/lib/brewing/brewer.svelte.js +0 -277
  111. package/dist/lib/brewing/dimensions.svelte.d.ts +0 -35
  112. package/dist/lib/brewing/dimensions.svelte.js +0 -56
  113. package/dist/lib/brewing/index.svelte.d.ts +0 -118
  114. package/dist/lib/brewing/index.svelte.js +0 -205
  115. package/dist/lib/brewing/legends.svelte.d.ts +0 -48
  116. package/dist/lib/brewing/legends.svelte.js +0 -137
  117. package/dist/lib/brewing/marks/areas.d.ts +0 -31
  118. package/dist/lib/brewing/marks/areas.js +0 -72
  119. package/dist/lib/brewing/marks/bars.d.ts +0 -1
  120. package/dist/lib/brewing/marks/bars.js +0 -49
  121. package/dist/lib/brewing/scales.svelte.d.ts +0 -24
  122. package/dist/lib/brewing/scales.svelte.js +0 -82
  123. package/dist/lib/context.d.ts +0 -13
  124. package/dist/lib/context.js +0 -131
  125. package/dist/lib/plot/chartProps.d.ts +0 -177
  126. package/dist/lib/plot/chartProps.js +0 -76
  127. package/dist/lib/scales.svelte.d.ts +0 -35
  128. package/dist/lib/scales.svelte.js +0 -151
  129. package/dist/lib/ticks.d.ts +0 -36
  130. package/dist/lib/ticks.js +0 -46
@@ -1,205 +0,0 @@
1
- import { createDimensions, updateDimensions } from './dimensions.svelte.js'
2
- import { createScales, getOrigin } from './scales.svelte.js'
3
- import { createBars, filterBars, createGroupedBars } from './bars.svelte.js'
4
- import { createXAxis, createYAxis, createGrid, createTickAttributes } from './axes.svelte.js'
5
- import { createLegend, filterByLegend, createLegendItemAttributes } from './legends.svelte.js'
6
-
7
- /**
8
- * Chart Brewing - A collection of pure functions for chart data preparation
9
- */
10
- export {
11
- // Dimensions
12
- createDimensions,
13
- updateDimensions,
14
-
15
- // Scales
16
- createScales,
17
- getOrigin,
18
-
19
- // Bars
20
- createBars,
21
- filterBars,
22
- createGroupedBars,
23
-
24
- // Axes
25
- createXAxis,
26
- createYAxis,
27
- createGrid,
28
- createTickAttributes,
29
-
30
- // Legends
31
- createLegend,
32
- filterByLegend,
33
- createLegendItemAttributes
34
- }
35
-
36
- /**
37
- * Main class that manages chart state and provides access to all brewing functions
38
- */
39
- export class ChartBrewer {
40
- #data = []
41
- #dimensions = createDimensions()
42
- #scales = { x: null, y: null, color: null }
43
- #fields = { x: null, y: null, color: null }
44
- #options = {
45
- padding: 0.2,
46
- animationDuration: 300
47
- }
48
-
49
- /**
50
- * Creates a new ChartBrewer instance
51
- *
52
- * @param {Object} options Configuration options
53
- */
54
- constructor(options = {}) {
55
- this.#dimensions = createDimensions(options.width, options.height, options.margin)
56
-
57
- if (options.padding !== undefined) this.#options.padding = options.padding
58
- if (options.animationDuration !== undefined)
59
- this.#options.animationDuration = options.animationDuration
60
- }
61
-
62
- /**
63
- * Sets the data for the chart
64
- *
65
- * @param {Array} data Data array
66
- * @returns {ChartBrewer} this for method chaining
67
- */
68
- setData(data) {
69
- this.#data = Array.isArray(data) ? data : []
70
- return this
71
- }
72
-
73
- /**
74
- * Sets the field mappings for axes and color
75
- *
76
- * @param {Object} fields Field mappings
77
- * @returns {ChartBrewer} this for method chaining
78
- */
79
- setFields({ x, y, color }) {
80
- if (x !== undefined) this.#fields.x = x
81
- if (y !== undefined) this.#fields.y = y
82
- if (color !== undefined) this.#fields.color = color
83
- return this
84
- }
85
-
86
- /**
87
- * Sets the dimensions of the chart
88
- *
89
- * @param {Object} dimensions Chart dimensions
90
- * @returns {ChartBrewer} this for method chaining
91
- */
92
- setDimensions({ width, height, margin }) {
93
- this.#dimensions = updateDimensions(this.#dimensions, { width, height, margin })
94
- return this
95
- }
96
-
97
- /**
98
- * Creates scales based on data and dimensions
99
- *
100
- * @returns {ChartBrewer} this for method chaining
101
- */
102
- createScales() {
103
- this.#scales = createScales(this.#data, this.#fields, this.#dimensions, {
104
- padding: this.#options.padding
105
- })
106
- return this
107
- }
108
-
109
- /**
110
- * Creates bar data for rendering
111
- *
112
- * @returns {Array} Data for rendering bars
113
- */
114
- createBars() {
115
- return createBars(this.#data, this.#fields, this.#scales, { dimensions: this.#dimensions })
116
- }
117
-
118
- /**
119
- * Creates x-axis tick data for rendering
120
- *
121
- * @param {Object} options Axis options
122
- * @returns {Object} Axis rendering data
123
- */
124
- createXAxis(options = {}) {
125
- return createXAxis(this.#scales, this.#dimensions, options)
126
- }
127
-
128
- /**
129
- * Creates y-axis tick data for rendering
130
- *
131
- * @param {Object} options Axis options
132
- * @returns {Object} Axis rendering data
133
- */
134
- createYAxis(options = {}) {
135
- return createYAxis(this.#scales, this.#dimensions, options)
136
- }
137
-
138
- /**
139
- * Creates grid line data for rendering
140
- *
141
- * @param {Object} options Grid options
142
- * @returns {Object} Grid rendering data
143
- */
144
- createGrid(options = {}) {
145
- return createGrid(this.#scales, this.#dimensions, options)
146
- }
147
-
148
- /**
149
- * Creates legend data for rendering
150
- *
151
- * @param {Object} options Legend options
152
- * @returns {Object} Legend rendering data
153
- */
154
- createLegend(options = {}) {
155
- return createLegend(this.#data, this.#fields, this.#scales, {
156
- ...options,
157
- dimensions: this.#dimensions
158
- })
159
- }
160
-
161
- /**
162
- * Gets all chart dimensions
163
- *
164
- * @returns {Object} Chart dimensions
165
- */
166
- getDimensions() {
167
- return { ...this.#dimensions }
168
- }
169
-
170
- /**
171
- * Gets all chart scales
172
- *
173
- * @returns {Object} Chart scales
174
- */
175
- getScales() {
176
- return { ...this.#scales }
177
- }
178
-
179
- /**
180
- * Gets the animation duration
181
- *
182
- * @returns {number} Animation duration in ms
183
- */
184
- getAnimationDuration() {
185
- return this.#options.animationDuration
186
- }
187
-
188
- /**
189
- * Gets the data being used
190
- *
191
- * @returns {Array} Chart data
192
- */
193
- getData() {
194
- return [...this.#data]
195
- }
196
-
197
- /**
198
- * Gets the fields configuration
199
- *
200
- * @returns {Object} Fields configuration
201
- */
202
- getFields() {
203
- return { ...this.#fields }
204
- }
205
- }
@@ -1,48 +0,0 @@
1
- /**
2
- * Creates legend data for rendering
3
- *
4
- * @param {Array} data - Chart data
5
- * @param {Object} fields - Field mappings
6
- * @param {string} fields.color - Color field
7
- * @param {Object} scales - Chart scales
8
- * @param {Function} scales.color - Color scale
9
- * @param {Object} options - Legend options including dimensions
10
- * @param {Object} options.dimensions - Chart dimensions
11
- * @param {string} [options.title=''] - Legend title
12
- * @param {string} [options.align='right'] - Legend alignment ('left', 'center', or 'right')
13
- * @param {string} [options.shape='rect'] - Legend marker shape ('rect' or 'circle')
14
- * @param {number} [options.markerSize=10] - Size of legend markers
15
- * @returns {LegendData} Legend rendering data
16
- */
17
- export function createLegend(data: any[], fields: {
18
- color: string;
19
- }, scales: {
20
- color: Function;
21
- }, options: {
22
- dimensions: Object;
23
- title?: string | undefined;
24
- align?: string | undefined;
25
- shape?: string | undefined;
26
- markerSize?: number | undefined;
27
- }): LegendData;
28
- /**
29
- * Filter data based on legend selection
30
- *
31
- * @param {Array} data - Chart data
32
- * @param {string} colorField - Field used for color mapping
33
- * @param {Array} selectedValues - Selected legend values
34
- * @returns {Array} Filtered data
35
- */
36
- export function filterByLegend(data: any[], colorField: string, selectedValues: any[]): any[];
37
- /**
38
- * Create attributes for legend items
39
- *
40
- * @param {LegendItem} item - Legend item
41
- * @returns {Object} Attributes for the legend item
42
- */
43
- export function createLegendItemAttributes(item: LegendItem): Object;
44
- export type LegendItem = import("./types").LegendItem;
45
- export type LegendData = import("./types").LegendData;
46
- export type ScaleFields = import("./types").ScaleFields;
47
- export type ChartScales = import("./types").ChartScales;
48
- export type ChartDimensions = import("./types").ChartDimensions;
@@ -1,137 +0,0 @@
1
- import { SvelteSet } from 'svelte/reactivity'
2
- import {} from './types.js'
3
-
4
- /**
5
- * @typedef {import('./types').LegendItem} LegendItem
6
- * @typedef {import('./types').LegendData} LegendData
7
- * @typedef {import('./types').ScaleFields} ScaleFields
8
- * @typedef {import('./types').ChartScales} ChartScales
9
- * @typedef {import('./types').ChartDimensions} ChartDimensions
10
- */
11
-
12
- const LEGEND_DEFAULTS = { title: '', align: 'right', shape: 'rect', markerSize: 10 }
13
-
14
- /**
15
- * Compute the x-position for legend alignment
16
- * @param {string} align
17
- * @param {number} innerWidth
18
- * @param {number} approximateWidth
19
- * @returns {number}
20
- */
21
- function legendX(align, innerWidth, approximateWidth) {
22
- if (align === 'right') return innerWidth - approximateWidth
23
- if (align === 'center') return (innerWidth - approximateWidth) / 2
24
- return 0
25
- }
26
-
27
- /**
28
- * @param {Array} colorValues
29
- * @param {Function} colorScale
30
- * @param {{ shape: string, markerSize: number, titleOffset: number }} style
31
- * @returns {LegendItem[]}
32
- */
33
- function buildLegendItems(colorValues, colorScale, style) {
34
- const { shape, markerSize, titleOffset } = style
35
- return colorValues.map((value, index) => ({
36
- value,
37
- color: colorScale(value),
38
- y: index * (markerSize + 5) + titleOffset,
39
- shape,
40
- markerSize
41
- }))
42
- }
43
-
44
- /**
45
- * @param {Array} colorValues
46
- * @param {number} markerSize
47
- * @returns {number}
48
- */
49
- function approximateLegendWidth(colorValues, markerSize) {
50
- return Math.max(...colorValues.map((v) => v.toString().length)) * 8 + markerSize + 10
51
- }
52
-
53
- /**
54
- * @param {Object} options
55
- * @returns {{ dimensions: Object, title: string, align: string, shape: string, markerSize: number }}
56
- */
57
- function parseLegendOptions(options) {
58
- const merged = Object.assign({}, LEGEND_DEFAULTS, options || {})
59
- return {
60
- dimensions: merged.dimensions,
61
- title: merged.title,
62
- align: merged.align,
63
- shape: merged.shape,
64
- markerSize: merged.markerSize
65
- }
66
- }
67
-
68
- /**
69
- * @param {Object|undefined} dimensions
70
- * @returns {number}
71
- */
72
- function innerWidth(dimensions) {
73
- return dimensions ? dimensions.innerWidth : 0
74
- }
75
-
76
- /**
77
- * Creates legend data for rendering
78
- *
79
- * @param {Array} data - Chart data
80
- * @param {Object} fields - Field mappings
81
- * @param {string} fields.color - Color field
82
- * @param {Object} scales - Chart scales
83
- * @param {Function} scales.color - Color scale
84
- * @param {Object} options - Legend options including dimensions
85
- * @param {Object} options.dimensions - Chart dimensions
86
- * @param {string} [options.title=''] - Legend title
87
- * @param {string} [options.align='right'] - Legend alignment ('left', 'center', or 'right')
88
- * @param {string} [options.shape='rect'] - Legend marker shape ('rect' or 'circle')
89
- * @param {number} [options.markerSize=10] - Size of legend markers
90
- * @returns {LegendData} Legend rendering data
91
- */
92
- export function createLegend(data, fields, scales, options) {
93
- if (!data || !fields.color || !scales.color) {
94
- return { items: [], title: '', transform: 'translate(0, 0)' }
95
- }
96
-
97
- const { dimensions, title, align, shape, markerSize } = parseLegendOptions(options)
98
- const colorValues = [...new SvelteSet(data.map((d) => d[fields.color]))]
99
- const titleOffset = title ? 15 : 0
100
- const style = { shape, markerSize, titleOffset }
101
- const items = buildLegendItems(colorValues, scales.color, style)
102
- const approxWidth = approximateLegendWidth(colorValues, markerSize)
103
- const x = legendX(align, innerWidth(dimensions), approxWidth)
104
-
105
- return { items, title, transform: `translate(${x}, 0)` }
106
- }
107
-
108
- /**
109
- * Filter data based on legend selection
110
- *
111
- * @param {Array} data - Chart data
112
- * @param {string} colorField - Field used for color mapping
113
- * @param {Array} selectedValues - Selected legend values
114
- * @returns {Array} Filtered data
115
- */
116
- export function filterByLegend(data, colorField, selectedValues) {
117
- if (!selectedValues || selectedValues.length === 0) {
118
- return data
119
- }
120
-
121
- return data.filter((d) => selectedValues.includes(d[colorField]))
122
- }
123
-
124
- /**
125
- * Create attributes for legend items
126
- *
127
- * @param {LegendItem} item - Legend item
128
- * @returns {Object} Attributes for the legend item
129
- */
130
- export function createLegendItemAttributes(item) {
131
- return {
132
- 'data-plot-legend-item': '',
133
- transform: `translate(0, ${item.y})`,
134
- role: 'img',
135
- 'aria-label': `Legend item for ${item.value}`
136
- }
137
- }
@@ -1,31 +0,0 @@
1
- /**
2
- * @param {Object[]} data
3
- * @param {{ x: string, y: string, fill?: string, pattern?: string }} channels
4
- * `fill` is the primary aesthetic — drives grouping and interior color.
5
- * @param {Function} xScale
6
- * @param {Function} yScale
7
- * @param {Map} colors
8
- * @param {'linear'|'smooth'|'step'} [curve]
9
- * @param {Map} [patternMap]
10
- */
11
- export function buildAreas(data: Object[], channels: {
12
- x: string;
13
- y: string;
14
- fill?: string;
15
- pattern?: string;
16
- }, xScale: Function, yScale: Function, colors: Map<any, any>, curve?: "linear" | "smooth" | "step", patternMap?: Map<any, any>): {
17
- d: string | null;
18
- fill: any;
19
- stroke: string;
20
- key: any;
21
- colorKey: any;
22
- patternKey: any;
23
- patternId: string | null;
24
- }[] | {
25
- d: never;
26
- fill: any;
27
- stroke: string;
28
- colorKey: null;
29
- patternKey: null;
30
- patternId: null;
31
- }[];
@@ -1,72 +0,0 @@
1
- import { area, curveCatmullRom, curveStep } from 'd3-shape'
2
- import { toPatternId } from '../patterns.js'
3
-
4
- /**
5
- * @param {Object[]} data
6
- * @param {{ x: string, y: string, fill?: string, pattern?: string }} channels
7
- * `fill` is the primary aesthetic — drives grouping and interior color.
8
- * @param {Function} xScale
9
- * @param {Function} yScale
10
- * @param {Map} colors
11
- * @param {'linear'|'smooth'|'step'} [curve]
12
- * @param {Map} [patternMap]
13
- */
14
- export function buildAreas(data, channels, xScale, yScale, colors, curve, patternMap) {
15
- const { x: xf, y: yf, pattern: pf } = channels
16
- const cf = channels.fill // fill is the primary aesthetic for area charts
17
- const innerHeight = yScale.range()[0]
18
- const xPos = (d) =>
19
- typeof xScale.bandwidth === 'function' ? xScale(d[xf]) + xScale.bandwidth() / 2 : xScale(d[xf])
20
- const makeGen = () => {
21
- const gen = area()
22
- .x(xPos)
23
- .y0(innerHeight)
24
- .y1((d) => yScale(d[yf]))
25
- if (curve === 'smooth') gen.curve(curveCatmullRom)
26
- else if (curve === 'step') gen.curve(curveStep)
27
- return gen
28
- }
29
- if (!cf) {
30
- const colorEntry = colors?.values().next().value ?? { fill: '#888', stroke: '#444' }
31
- return [
32
- {
33
- d: makeGen()(data),
34
- fill: colorEntry.fill,
35
- stroke: 'none',
36
- colorKey: null,
37
- patternKey: null,
38
- patternId: null
39
- }
40
- ]
41
- }
42
- const groups = groupBy(data, cf)
43
- return [...groups.entries()].map(([key, rows]) => {
44
- const colorEntry = colors?.get(key) ?? { fill: '#888', stroke: '#444' }
45
- const patternKey = pf ? (pf === cf ? key : rows[0]?.[pf]) : null
46
- const patternName =
47
- patternKey !== null && patternKey !== undefined ? patternMap?.get(patternKey) : null
48
- const compositePatternKey =
49
- cf && pf && cf !== pf && patternKey !== null && patternKey !== undefined
50
- ? `${key}::${patternKey}`
51
- : patternKey
52
- return {
53
- d: makeGen()(rows),
54
- fill: colorEntry.fill,
55
- stroke: 'none',
56
- key,
57
- colorKey: key,
58
- patternKey,
59
- patternId: patternName ? toPatternId(compositePatternKey) : null
60
- }
61
- })
62
- }
63
-
64
- function groupBy(arr, field) {
65
- const map = new Map()
66
- for (const item of arr) {
67
- const key = item[field]
68
- if (!map.has(key)) map.set(key, [])
69
- map.get(key).push(item)
70
- }
71
- return map
72
- }
@@ -1 +0,0 @@
1
- export function buildBars(data: any, channels: any, xScale: any, yScale: any, colors: any, patternMap: any): any;
@@ -1,49 +0,0 @@
1
- /**
2
- * @param {Object[]} data
3
- * @param {{ x: string, y: string, fill?: string, color?: string, pattern?: string }} channels
4
- * `fill` drives the bar interior color. `color` drives the border stroke; falls back to fill.
5
- * @param {import('d3-scale').ScaleBand|import('d3-scale').ScaleLinear} xScale
6
- * @param {import('d3-scale').ScaleLinear} yScale
7
- * @param {Map} colors - value→{fill,stroke}
8
- * @param {Map} [patternMap] - value→patternName
9
- * @returns {Array}
10
- */
11
- import { toPatternId } from '../patterns.js'
12
-
13
- export function buildBars(data, channels, xScale, yScale, colors, patternMap) {
14
- const { x: xf, y: yf, fill: ff, color: cf, pattern: pf } = channels
15
- const barWidth = typeof xScale.bandwidth === 'function' ? xScale.bandwidth() : 10
16
- const innerHeight = yScale.range()[0]
17
-
18
- return data.map((d) => {
19
- const xVal = d[xf]
20
- const fillKey = ff ? d[ff] : xVal // fill channel drives interior color
21
- const strokeKey = cf ? d[cf] : null // color channel drives border; null = no border
22
- const colorEntry = colors?.get(fillKey) ?? { fill: '#888', stroke: '#444' }
23
- const strokeEntry = colors?.get(strokeKey) ?? colorEntry
24
- const patternKey = pf ? d[pf] : null
25
- const patternName =
26
- patternKey !== null && patternKey !== undefined ? patternMap?.get(patternKey) : null
27
- // When fill and pattern are different fields, bars need a composite pattern def id
28
- // so each (region, category) pair gets its uniquely colored+textured pattern.
29
- const compositePatternKey =
30
- ff && pf && ff !== pf && patternKey !== null && patternKey !== undefined
31
- ? `${d[ff]}::${patternKey}`
32
- : patternKey
33
- const barX = typeof xScale.bandwidth === 'function' ? xScale(xVal) : xScale(xVal) - barWidth / 2
34
- const barY = yScale(d[yf])
35
- return {
36
- data: d,
37
- key: `${xVal}::${fillKey ?? ''}::${patternKey ?? ''}`,
38
- x: barX,
39
- y: barY,
40
- width: barWidth,
41
- height: innerHeight - barY,
42
- fill: colorEntry.fill,
43
- stroke: strokeKey !== null ? strokeEntry.stroke : null,
44
- colorKey: fillKey,
45
- patternKey,
46
- patternId: patternName ? toPatternId(compositePatternKey) : null
47
- }
48
- })
49
- }
@@ -1,24 +0,0 @@
1
- /**
2
- * Creates scales based on data, fields, and dimensions
3
- *
4
- * @param {Array} data - Chart data
5
- * @param {ScaleFields} fields - Field mappings
6
- * @param {Object} dimensions - Chart dimensions
7
- * @param {Object} options - Scale options
8
- * @param {number} [options.padding=0.2] - Padding for band scales
9
- * @returns {ChartScales} Chart scales
10
- */
11
- export function createScales(data: any[], fields: ScaleFields, dimensions: Object, options?: {
12
- padding?: number | undefined;
13
- }): ChartScales;
14
- /**
15
- * Gets the origin coordinates for the axes
16
- *
17
- * @param {ChartScales} scales - Chart scales
18
- * @param {Object} dimensions - Chart dimensions
19
- * @returns {Object} Origin coordinates
20
- */
21
- export function getOrigin(scales: ChartScales, dimensions: Object): Object;
22
- export type ChartScales = import("./types").ChartScales;
23
- export type ScaleFields = import("./types").ScaleFields;
24
- export type ChartDimensions = import("./types").ChartDimensions;
@@ -1,82 +0,0 @@
1
- import { SvelteSet } from 'svelte/reactivity'
2
- import { min, max } from 'd3-array'
3
- import { scaleLinear, scaleOrdinal } from 'd3-scale'
4
- import { schemeCategory10 } from 'd3-scale-chromatic'
5
- import {} from './types.js'
6
- import { buildXScale } from '../xscale.js'
7
-
8
- /**
9
- * @typedef {import('./types').ChartScales} ChartScales
10
- * @typedef {import('./types').ScaleFields} ScaleFields
11
- * @typedef {import('./types').ChartDimensions} ChartDimensions
12
- */
13
-
14
- /**
15
- * @param {Array} data
16
- * @param {string} colorField
17
- * @returns {import('d3-scale').ScaleOrdinal}
18
- */
19
- function buildColorScale(data, colorField) {
20
- const colorValues = [...new SvelteSet(data.map((d) => d[colorField]))]
21
- return scaleOrdinal().domain(colorValues).range(schemeCategory10)
22
- }
23
-
24
- /**
25
- * @param {Array} data
26
- * @param {string} yField
27
- * @param {Object} dimensions
28
- * @returns {import('d3-scale').ScaleContinuousNumeric}
29
- */
30
- function buildYScale(data, yField, dimensions) {
31
- const yValues = data.map((d) => d[yField])
32
- return scaleLinear()
33
- .domain([0, max(yValues) * 1.1])
34
- .nice()
35
- .range([dimensions.innerHeight, 0])
36
- }
37
-
38
- /**
39
- * @param {Array} data
40
- * @param {ScaleFields} fields
41
- * @returns {boolean}
42
- */
43
- function hasRequiredFields(data, fields) {
44
- return Boolean(data && data.length && fields.x && fields.y)
45
- }
46
-
47
- /**
48
- * Creates scales based on data, fields, and dimensions
49
- *
50
- * @param {Array} data - Chart data
51
- * @param {ScaleFields} fields - Field mappings
52
- * @param {Object} dimensions - Chart dimensions
53
- * @param {Object} options - Scale options
54
- * @param {number} [options.padding=0.2] - Padding for band scales
55
- * @returns {ChartScales} Chart scales
56
- */
57
- export function createScales(data, fields, dimensions, options = {}) {
58
- if (!hasRequiredFields(data, fields)) return { x: null, y: null, color: null }
59
-
60
- const padding = options.padding ?? 0.2
61
- const xValues = data.map((d) => d[fields.x])
62
-
63
- return {
64
- x: buildXScale(xValues, dimensions, padding),
65
- y: buildYScale(data, fields.y, dimensions),
66
- color: fields.color ? buildColorScale(data, fields.color) : null
67
- }
68
- }
69
-
70
- /**
71
- * Gets the origin coordinates for the axes
72
- *
73
- * @param {ChartScales} scales - Chart scales
74
- * @param {Object} dimensions - Chart dimensions
75
- * @returns {Object} Origin coordinates
76
- */
77
- export function getOrigin(scales, dimensions) {
78
- return {
79
- x: scales.y ? scales.y(0) : dimensions.innerHeight,
80
- y: scales.x ? (scales.x.ticks ? scales.x(Math.max(0, min(scales.x.domain()))) : 0) : 0
81
- }
82
- }
@@ -1,13 +0,0 @@
1
- /**
2
- * Creates chart context and provides it to child components
3
- *
4
- * @param {Object} options Initial chart options
5
- * @returns {Object} Chart context with all stores and methods
6
- */
7
- export function createChartContext(options?: Object): Object;
8
- /**
9
- * Gets chart context provided by parent component
10
- *
11
- * @returns {Object} Chart context
12
- */
13
- export function getChartContext(): Object;