@rokkit/chart 1.6.0 → 1.8.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 (68) hide show
  1. package/README.md +13 -0
  2. package/dist/Plot.svelte +38 -10
  3. package/dist/Plot.svelte.d.ts +7 -2
  4. package/dist/PlotState.svelte.d.ts +115 -71
  5. package/dist/PlotState.svelte.js +174 -547
  6. package/dist/SparkState.svelte.d.ts +3 -1
  7. package/dist/SparkState.svelte.js +11 -41
  8. package/dist/geoms/Contour.svelte +88 -0
  9. package/dist/geoms/Contour.svelte.d.ts +19 -0
  10. package/dist/geoms/Hull.svelte +89 -0
  11. package/dist/geoms/Hull.svelte.d.ts +17 -0
  12. package/dist/geoms/Region.svelte +107 -0
  13. package/dist/geoms/Region.svelte.d.ts +27 -0
  14. package/dist/geoms/Rule.svelte +88 -26
  15. package/dist/geoms/Rule.svelte.d.ts +8 -0
  16. package/dist/geoms/lib/PlotAreaClip.svelte +18 -0
  17. package/dist/geoms/lib/PlotAreaClip.svelte.d.ts +6 -0
  18. package/dist/geoms/lib/bars.js +13 -20
  19. package/dist/geoms/lib/grouping.d.ts +35 -0
  20. package/dist/geoms/lib/grouping.js +59 -0
  21. package/dist/geoms/lib/marks/contour.d.ts +26 -0
  22. package/dist/geoms/lib/marks/contour.js +67 -0
  23. package/dist/geoms/lib/marks/hull.d.ts +26 -0
  24. package/dist/geoms/lib/marks/hull.js +36 -0
  25. package/dist/geoms/lib/marks/waterfall.js +15 -20
  26. package/dist/index.d.ts +9 -0
  27. package/dist/index.js +9 -0
  28. package/dist/lib/abline.d.ts +41 -0
  29. package/dist/lib/abline.js +51 -0
  30. package/dist/lib/brewing/colors.js +1 -1
  31. package/dist/lib/hull.d.ts +18 -0
  32. package/dist/lib/hull.js +64 -0
  33. package/dist/lib/plot/domains.d.ts +61 -0
  34. package/dist/lib/plot/domains.js +130 -0
  35. package/dist/lib/plot/preset.d.ts +1 -1
  36. package/dist/lib/plot/preset.js +1 -1
  37. package/dist/lib/plot/running.d.ts +23 -0
  38. package/dist/lib/plot/running.js +32 -0
  39. package/dist/lib/plot/stacking.d.ts +32 -0
  40. package/dist/lib/plot/stacking.js +34 -0
  41. package/dist/lib/plot/types.d.ts +8 -1
  42. package/dist/lib/plot/types.js +5 -1
  43. package/dist/lib/preset.d.ts +2 -0
  44. package/dist/lib/preset.js +76 -41
  45. package/dist/lib/region.d.ts +63 -0
  46. package/dist/lib/region.js +127 -0
  47. package/dist/lib/swatch.d.ts +1 -1
  48. package/dist/lib/swatch.js +1 -1
  49. package/dist/state/AestheticState.svelte.d.ts +43 -0
  50. package/dist/state/AestheticState.svelte.js +84 -0
  51. package/dist/state/AxisState.svelte.d.ts +26 -0
  52. package/dist/state/AxisState.svelte.js +56 -0
  53. package/dist/state/ChannelState.svelte.d.ts +34 -0
  54. package/dist/state/ChannelState.svelte.js +67 -0
  55. package/dist/state/GeomRegistry.svelte.d.ts +44 -0
  56. package/dist/state/GeomRegistry.svelte.js +86 -0
  57. package/dist/state/InteractionState.svelte.d.ts +30 -0
  58. package/dist/state/InteractionState.svelte.js +69 -0
  59. package/dist/state/OrientationState.svelte.d.ts +34 -0
  60. package/dist/state/OrientationState.svelte.js +64 -0
  61. package/dist/state/PlotConfig.svelte.d.ts +179 -0
  62. package/dist/state/PlotConfig.svelte.js +195 -0
  63. package/dist/state/PlotFrame.svelte.d.ts +17 -0
  64. package/dist/state/PlotFrame.svelte.js +18 -0
  65. package/dist/state/ScaleState.svelte.d.ts +36 -0
  66. package/dist/state/ScaleState.svelte.js +121 -0
  67. package/package.json +5 -3
  68. package/dist/lib/palette.json +0 -277
@@ -0,0 +1,121 @@
1
+ import { buildUnifiedXScale, buildUnifiedYScale } from '../lib/plot/scales.js'
2
+ import { sortedBandDomain, resolveValueDomain } from '../lib/plot/domains.js'
3
+
4
+ /**
5
+ * The x and y position scales.
6
+ *
7
+ * Domains come, in order, from: the caller's override; for the value axis, the geometry of the
8
+ * mounted geoms (`resolveValueDomain` — box whiskers, stacked totals, running totals); then the
9
+ * extent of every geom's rows. Ranges come from the frame, oriented by the flip.
10
+ */
11
+ export class ScaleState {
12
+ #config
13
+ #geoms
14
+ #channels
15
+ #orientation
16
+ #frame
17
+ #interaction
18
+
19
+ /**
20
+ * @param {{
21
+ * config: import('./PlotConfig.svelte.js').PlotConfig,
22
+ * geoms: import('./GeomRegistry.svelte.js').GeomRegistry,
23
+ * channels: import('./ChannelState.svelte.js').ChannelState,
24
+ * orientation: import('./OrientationState.svelte.js').OrientationState,
25
+ * frame: import('./PlotFrame.svelte.js').PlotFrame,
26
+ * interaction: import('./InteractionState.svelte.js').InteractionState
27
+ * }} parts
28
+ */
29
+ constructor({ config, geoms, channels, orientation, frame, interaction }) {
30
+ this.#config = config
31
+ this.#geoms = geoms
32
+ this.#channels = channels
33
+ this.#orientation = orientation
34
+ this.#frame = frame
35
+ this.#interaction = interaction
36
+ }
37
+
38
+ /** Every geom's rows (post-stat) — or the raw data before any geom mounts. Shared by both axes. */
39
+ #datasets = $derived(
40
+ this.#geoms.list.length > 0
41
+ ? this.#geoms.list.map((g) => this.#geoms.data(g.id))
42
+ : [this.#config.data]
43
+ )
44
+
45
+ /**
46
+ * x is a band when a banding geom is mounted — except a CONTINUOUS category axis (a bar
47
+ * race's tweened rank), which stays linear so fractional positions tween.
48
+ */
49
+ #bandX = $derived(
50
+ this.#orientation.hasBandGeom &&
51
+ !this.#config.continuousCategory &&
52
+ (this.#orientation.orientation !== 'horizontal' || this.#orientation.flipped)
53
+ )
54
+
55
+ /** The caller's x domain, else — on a band axis — categories sorted by value when asked. */
56
+ #xDomain = $derived(
57
+ this.#config.xDomain ??
58
+ (this.#bandX
59
+ ? sortedBandDomain(
60
+ this.#datasets,
61
+ this.#channels.effective.x,
62
+ this.#channels.effective.y,
63
+ this.#config.sort
64
+ )
65
+ : null) ??
66
+ undefined
67
+ )
68
+
69
+ /** The x (category, when banded) scale. Includes zero only when x is the VALUE axis. */
70
+ x = $derived.by(() => {
71
+ const field = this.#channels.effective.x
72
+ if (!field) return null
73
+ const { orientation, flipped } = this.#orientation
74
+ const base = buildUnifiedXScale(this.#datasets, field, this.#frame.innerWidth, {
75
+ domain: this.#xDomain,
76
+ includeZero: orientation === 'horizontal' && !flipped,
77
+ band: this.#bandX,
78
+ // Flipped: the category axis stands up the screen.
79
+ range: flipped ? [this.#frame.innerHeight, 0] : undefined,
80
+ // A continuous category axis is deliberately padded — do not nice() it to whole numbers.
81
+ nice: !this.#config.continuousCategory
82
+ })
83
+ // A band cannot be zoomed; a continuous axis rescales through the transform.
84
+ return typeof base?.bandwidth === 'function' ? base : this.#zoomed(base, 'rescaleX')
85
+ })
86
+
87
+ /** The y (value) scale — a zero baseline whenever it is the value axis. */
88
+ y = $derived.by(() => {
89
+ const field = this.#channels.effective.y
90
+ if (!field) return null
91
+ const { orientation, flipped } = this.#orientation
92
+ const geomDomain = resolveValueDomain(
93
+ this.#geoms.list,
94
+ (id) => this.#geoms.data(id),
95
+ this.#channels.effective,
96
+ field
97
+ )
98
+ const base = buildUnifiedYScale(this.#datasets, field, this.#frame.innerHeight, {
99
+ domain: this.#config.yDomain ?? geomDomain ?? undefined,
100
+ includeZero: orientation === 'vertical' || flipped,
101
+ // Flipped: the value axis runs along the screen.
102
+ range: flipped ? [0, this.#frame.innerWidth] : undefined
103
+ })
104
+ return this.#zoomed(base, 'rescaleY')
105
+ })
106
+
107
+ /** @param {any} base @param {'rescaleX' | 'rescaleY'} method */
108
+ #zoomed(base, method) {
109
+ const zoom = this.#interaction.zoom
110
+ return zoom ? zoom[method](base) : base
111
+ }
112
+
113
+ /** The categorical scale, whichever screen axis it is on. */
114
+ get band() {
115
+ return this.#orientation.bandIsX ? this.x : this.y
116
+ }
117
+ /** The continuous (value) scale, whichever screen axis it is on. */
118
+ get value() {
119
+ return this.#orientation.bandIsX ? this.y : this.x
120
+ }
121
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rokkit/chart",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "type": "module",
5
5
  "description": "Data-driven chart components",
6
6
  "repository": {
@@ -48,6 +48,7 @@
48
48
  "@rokkit/states": "latest",
49
49
  "d3-array": "^3.2.4",
50
50
  "d3-axis": "^3.0.0",
51
+ "d3-contour": "^4.0.2",
51
52
  "d3-format": "^3.1.2",
52
53
  "d3-scale": "^4.0.2",
53
54
  "d3-scale-chromatic": "^3.1.0",
@@ -65,6 +66,7 @@
65
66
  "@sveltejs/vite-plugin-svelte": "^6.2.4",
66
67
  "@types/d3-array": "^3.2.2",
67
68
  "@types/d3-axis": "^3.0.6",
69
+ "@types/d3-contour": "^3.0.6",
68
70
  "@types/d3-format": "^3.0.4",
69
71
  "@types/d3-scale": "^4.0.9",
70
72
  "@types/d3-scale-chromatic": "^3.1.0",
@@ -73,7 +75,7 @@
73
75
  "@types/d3-transition": "^3.0.9",
74
76
  "@types/d3-zoom": "^3.0.8",
75
77
  "@types/ramda": "^0.31.1",
76
- "svelte-check": "^4.7.6",
77
- "svelte": "^5.55.7"
78
+ "svelte": "^5.55.7",
79
+ "svelte-check": "^4.7.6"
78
80
  }
79
81
  }
@@ -1,277 +0,0 @@
1
- {
2
- "gold": {
3
- "50": "#fffef7",
4
- "100": "#fffdf0",
5
- "200": "#fffadb",
6
- "300": "#fff6c4",
7
- "400": "#ffec96",
8
- "500": "#ffde6b",
9
- "600": "#e6c257",
10
- "700": "#bf953b",
11
- "800": "#996f26",
12
- "900": "#734a16",
13
- "950": "#4a2909"
14
- },
15
- "lavender": {
16
- "50": "#fffaff",
17
- "100": "#fcf2fc",
18
- "200": "#fce1fc",
19
- "300": "#facff9",
20
- "400": "#f5abf4",
21
- "500": "#ef89ee",
22
- "600": "#d96fd2",
23
- "700": "#b34da5",
24
- "800": "#8f317a",
25
- "900": "#6b1c55",
26
- "950": "#450c30"
27
- },
28
- "teal": {
29
- "50": "#f2fcfc",
30
- "100": "#e3fafa",
31
- "200": "#bdf2f1",
32
- "300": "#96ebe9",
33
- "400": "#51dbd7",
34
- "500": "#15cbc4",
35
- "600": "#11b8aa",
36
- "700": "#0b9984",
37
- "800": "#077a60",
38
- "900": "#045c41",
39
- "950": "#023b25"
40
- },
41
- "rose": {
42
- "50": "#fffbf7",
43
- "100": "#fcf6f0",
44
- "200": "#fce8dc",
45
- "300": "#fad7c8",
46
- "400": "#f5aa9d",
47
- "500": "#f07575",
48
- "600": "#d95f5f",
49
- "700": "#b34242",
50
- "800": "#8f2929",
51
- "900": "#6b1818",
52
- "950": "#450a0a"
53
- },
54
- "sky": {
55
- "50": "#f2fdff",
56
- "100": "#e6fbff",
57
- "200": "#bff3ff",
58
- "300": "#99ebff",
59
- "400": "#4fd6ff",
60
- "500": "#02b8ff",
61
- "600": "#029ee6",
62
- "700": "#027abf",
63
- "800": "#025799",
64
- "900": "#003b73",
65
- "950": "#00234a"
66
- },
67
- "yellow": {
68
- "50": "#fffef2",
69
- "100": "#fffce8",
70
- "200": "#fff8c4",
71
- "300": "#fcf09f",
72
- "400": "#fce25b",
73
- "500": "#facc15",
74
- "600": "#e0b010",
75
- "700": "#ba860b",
76
- "800": "#966208",
77
- "900": "#704304",
78
- "950": "#472601"
79
- },
80
- "pink": {
81
- "50": "#fef5ff",
82
- "100": "#fbebfc",
83
- "200": "#f9cffc",
84
- "300": "#f3b4fa",
85
- "400": "#e77af5",
86
- "500": "#d946ef",
87
- "600": "#bb38d9",
88
- "700": "#9227b3",
89
- "800": "#6b188f",
90
- "900": "#490e6b",
91
- "950": "#290645"
92
- },
93
-
94
- "lime": {
95
- "50": "#fbfcf2",
96
- "100": "#f7fae8",
97
- "200": "#eaf2c7",
98
- "300": "#ddeba7",
99
- "400": "#c2db6e",
100
- "500": "#a2cb39",
101
- "600": "#8cb82e",
102
- "700": "#6d9920",
103
- "800": "#4e7a15",
104
- "900": "#355c0c",
105
- "950": "#1e3b05"
106
- },
107
- "red": {
108
- "50": "#fff5fa",
109
- "100": "#ffebf5",
110
- "200": "#fccce3",
111
- "300": "#faafcd",
112
- "400": "#f77499",
113
- "500": "#f63a57",
114
- "600": "#db304a",
115
- "700": "#b82135",
116
- "800": "#941524",
117
- "900": "#6e0c17",
118
- "950": "#47050c"
119
- },
120
- "cyan": {
121
- "50": "#f0fbfc",
122
- "100": "#e1f8fa",
123
- "200": "#baeff5",
124
- "300": "#91e4ed",
125
- "400": "#48cce0",
126
- "500": "#06b6d4",
127
- "600": "#069abf",
128
- "700": "#03779e",
129
- "800": "#035880",
130
- "900": "#013b5e",
131
- "950": "#01223d"
132
- },
133
- "orange": {
134
- "50": "#fffdf5",
135
- "100": "#fffae8",
136
- "200": "#fcefc5",
137
- "300": "#fce3a4",
138
- "400": "#fac65f",
139
- "500": "#f79f1e",
140
- "600": "#de8818",
141
- "700": "#ba6b11",
142
- "800": "#944d0a",
143
- "900": "#703406",
144
- "950": "#471d02"
145
- },
146
- "violet": {
147
- "50": "#fdfaff",
148
- "100": "#f8f2fc",
149
- "200": "#eedefa",
150
- "300": "#e0cbf7",
151
- "400": "#c4a7f2",
152
- "500": "#9f84ec",
153
- "600": "#866bd6",
154
- "700": "#634bb3",
155
- "800": "#45318f",
156
- "900": "#2b1b6b",
157
- "950": "#150b45"
158
- },
159
- "emerald": {
160
- "50": "#f2fcf9",
161
- "100": "#e6faf3",
162
- "200": "#bdf0dc",
163
- "300": "#9be8c6",
164
- "400": "#5ad694",
165
- "500": "#22c55e",
166
- "600": "#1ab04f",
167
- "700": "#13943c",
168
- "800": "#0c752b",
169
- "900": "#07591d",
170
- "950": "#03380f"
171
- },
172
- "wood": {
173
- "50": "#faf5f0",
174
- "100": "#f2e6dc",
175
- "200": "#e3c4b1",
176
- "300": "#d19c86",
177
- "400": "#ad5140",
178
- "500": "#890e0e",
179
- "600": "#7d0b0b",
180
- "700": "#660707",
181
- "800": "#520505",
182
- "900": "#3d0202",
183
- "950": "#290101"
184
- },
185
- "blue": {
186
- "50": "#f2fcff",
187
- "100": "#e6f9ff",
188
- "200": "#bfeeff",
189
- "300": "#99e0ff",
190
- "400": "#4cbffc",
191
- "500": "#0092fd",
192
- "600": "#007de3",
193
- "700": "#0061bd",
194
- "800": "#004696",
195
- "900": "#003073",
196
- "950": "#001c4a"
197
- },
198
-
199
- "amber": {
200
- "50": "#fffbf5",
201
- "100": "#fff7eb",
202
- "200": "#ffe9cc",
203
- "300": "#ffd6ab",
204
- "400": "#ffa86e",
205
- "500": "#ff6e2f",
206
- "600": "#e65b25",
207
- "700": "#bf4519",
208
- "800": "#993111",
209
- "900": "#732009",
210
- "950": "#4a1204"
211
- },
212
- "purple": {
213
- "50": "#fdf7ff",
214
- "100": "#faedff",
215
- "200": "#f0d4fc",
216
- "300": "#e7bbfc",
217
- "400": "#ca87fa",
218
- "500": "#a855f7",
219
- "600": "#8f45de",
220
- "700": "#6d2fba",
221
- "800": "#4f1e94",
222
- "900": "#341170",
223
- "950": "#1d0747"
224
- },
225
- "zinc": {
226
- "50": "#f7f9fa",
227
- "100": "#edf2f5",
228
- "200": "#d3dde3",
229
- "300": "#bac8d1",
230
- "400": "#8d9eb0",
231
- "500": "#64748b",
232
- "600": "#536580",
233
- "700": "#384a69",
234
- "800": "#243454",
235
- "900": "#142140",
236
- "950": "#091129"
237
- },
238
- "stone": {
239
- "50": "#f7f7f7",
240
- "100": "#f2f1f0",
241
- "200": "#dedcd9",
242
- "300": "#c9c6c1",
243
- "400": "#a19b95",
244
- "500": "#78716c",
245
- "600": "#6b5f57",
246
- "700": "#59473c",
247
- "800": "#473227",
248
- "900": "#361f15",
249
- "950": "#241009"
250
- },
251
- "indigo": {
252
- "50": "#f7fbff",
253
- "100": "#f0f7ff",
254
- "200": "#d7e5fc",
255
- "300": "#bed1fa",
256
- "400": "#92a3f7",
257
- "500": "#6366f1",
258
- "600": "#5153db",
259
- "700": "#383ab5",
260
- "800": "#242691",
261
- "900": "#14156e",
262
- "950": "#090a47"
263
- },
264
- "gray": {
265
- "50": "#f7f9fa",
266
- "100": "#edf0f2",
267
- "200": "#d7dde0",
268
- "300": "#c0c6cc",
269
- "400": "#949ba6",
270
- "500": "#6b7280",
271
- "600": "#576073",
272
- "700": "#3b455e",
273
- "800": "#26304d",
274
- "900": "#151d38",
275
- "950": "#090e24"
276
- }
277
- }