@rokkit/chart 1.0.0-next.150 → 1.0.0-next.155

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 (90) hide show
  1. package/dist/PlotState.svelte.d.ts +31 -3
  2. package/dist/crossfilter/createCrossFilter.svelte.d.ts +13 -15
  3. package/dist/index.d.ts +6 -1
  4. package/dist/lib/brewing/BoxBrewer.svelte.d.ts +3 -5
  5. package/dist/lib/brewing/QuartileBrewer.svelte.d.ts +9 -0
  6. package/dist/lib/brewing/ViolinBrewer.svelte.d.ts +3 -4
  7. package/dist/lib/brewing/brewer.svelte.d.ts +5 -36
  8. package/dist/lib/brewing/colors.d.ts +10 -1
  9. package/dist/lib/brewing/marks/points.d.ts +17 -2
  10. package/dist/lib/brewing/stats.d.ts +5 -13
  11. package/dist/lib/chart.d.ts +5 -7
  12. package/dist/lib/keyboard-nav.d.ts +15 -0
  13. package/dist/lib/plot/preset.d.ts +1 -1
  14. package/dist/lib/preset.d.ts +30 -0
  15. package/package.json +2 -1
  16. package/src/AnimatedPlot.svelte +375 -206
  17. package/src/Chart.svelte +81 -87
  18. package/src/ChartProvider.svelte +10 -0
  19. package/src/FacetPlot/Panel.svelte +30 -16
  20. package/src/FacetPlot.svelte +100 -76
  21. package/src/Plot/Area.svelte +26 -19
  22. package/src/Plot/Axis.svelte +81 -59
  23. package/src/Plot/Bar.svelte +47 -89
  24. package/src/Plot/Grid.svelte +23 -19
  25. package/src/Plot/Legend.svelte +213 -147
  26. package/src/Plot/Line.svelte +31 -21
  27. package/src/Plot/Point.svelte +35 -22
  28. package/src/Plot/Root.svelte +46 -91
  29. package/src/Plot/Timeline.svelte +82 -82
  30. package/src/Plot/Tooltip.svelte +68 -62
  31. package/src/Plot.svelte +290 -182
  32. package/src/PlotState.svelte.js +339 -267
  33. package/src/Sparkline.svelte +95 -56
  34. package/src/charts/AreaChart.svelte +22 -20
  35. package/src/charts/BarChart.svelte +23 -21
  36. package/src/charts/BoxPlot.svelte +15 -15
  37. package/src/charts/BubbleChart.svelte +17 -17
  38. package/src/charts/LineChart.svelte +20 -20
  39. package/src/charts/PieChart.svelte +30 -20
  40. package/src/charts/ScatterPlot.svelte +20 -19
  41. package/src/charts/ViolinPlot.svelte +15 -15
  42. package/src/crossfilter/CrossFilter.svelte +33 -29
  43. package/src/crossfilter/FilterBar.svelte +17 -25
  44. package/src/crossfilter/FilterHistogram.svelte +290 -0
  45. package/src/crossfilter/FilterSlider.svelte +69 -65
  46. package/src/crossfilter/createCrossFilter.svelte.js +100 -89
  47. package/src/geoms/Arc.svelte +114 -69
  48. package/src/geoms/Area.svelte +67 -39
  49. package/src/geoms/Bar.svelte +184 -126
  50. package/src/geoms/Box.svelte +102 -90
  51. package/src/geoms/LabelPill.svelte +11 -11
  52. package/src/geoms/Line.svelte +110 -87
  53. package/src/geoms/Point.svelte +132 -87
  54. package/src/geoms/Violin.svelte +45 -33
  55. package/src/geoms/lib/areas.js +122 -99
  56. package/src/geoms/lib/bars.js +195 -144
  57. package/src/index.js +21 -14
  58. package/src/lib/brewing/BoxBrewer.svelte.js +8 -50
  59. package/src/lib/brewing/CartesianBrewer.svelte.js +12 -7
  60. package/src/lib/brewing/PieBrewer.svelte.js +5 -5
  61. package/src/lib/brewing/QuartileBrewer.svelte.js +51 -0
  62. package/src/lib/brewing/ViolinBrewer.svelte.js +8 -49
  63. package/src/lib/brewing/brewer.svelte.js +249 -201
  64. package/src/lib/brewing/colors.js +34 -5
  65. package/src/lib/brewing/marks/arcs.js +28 -28
  66. package/src/lib/brewing/marks/areas.js +54 -41
  67. package/src/lib/brewing/marks/bars.js +34 -34
  68. package/src/lib/brewing/marks/boxes.js +51 -51
  69. package/src/lib/brewing/marks/lines.js +37 -30
  70. package/src/lib/brewing/marks/points.js +74 -26
  71. package/src/lib/brewing/marks/violins.js +57 -57
  72. package/src/lib/brewing/patterns.js +25 -11
  73. package/src/lib/brewing/scales.js +20 -20
  74. package/src/lib/brewing/stats.js +40 -28
  75. package/src/lib/brewing/symbols.js +1 -1
  76. package/src/lib/chart.js +12 -4
  77. package/src/lib/keyboard-nav.js +37 -0
  78. package/src/lib/plot/crossfilter.js +5 -5
  79. package/src/lib/plot/facet.js +30 -30
  80. package/src/lib/plot/frames.js +30 -29
  81. package/src/lib/plot/helpers.js +4 -4
  82. package/src/lib/plot/preset.js +48 -34
  83. package/src/lib/plot/scales.js +64 -39
  84. package/src/lib/plot/stat.js +47 -47
  85. package/src/lib/preset.js +41 -0
  86. package/src/patterns/DefinePatterns.svelte +24 -24
  87. package/src/patterns/PatternDef.svelte +1 -1
  88. package/src/patterns/patterns.js +328 -176
  89. package/src/patterns/scale.js +61 -32
  90. package/src/spec/chart-spec.js +64 -21
package/src/Chart.svelte CHANGED
@@ -1,101 +1,95 @@
1
1
  <script>
2
- import { setContext } from 'svelte'
3
- import { ChartBrewer } from './lib/brewing/brewer.svelte.js'
2
+ import { setContext } from 'svelte'
3
+ import { ChartBrewer } from './lib/brewing/brewer.svelte.js'
4
4
 
5
- /**
6
- * @type {{
7
- * spec?: import('./spec/chart-spec.js').ChartSpec,
8
- * data?: Object[],
9
- * x?: string,
10
- * y?: string,
11
- * color?: string,
12
- * pattern?: string,
13
- * fill?: string,
14
- * size?: string,
15
- * label?: string,
16
- * symbol?: string,
17
- * width?: number,
18
- * height?: number,
19
- * mode?: 'light' | 'dark',
20
- * children?: import('svelte').Snippet
21
- * }}
22
- */
23
- let {
24
- spec = undefined,
25
- data = [],
26
- x = undefined,
27
- y = undefined,
28
- color = undefined,
29
- pattern = undefined,
30
- fill = undefined,
31
- size = undefined,
32
- label = undefined,
33
- symbol = undefined,
34
- width = 600,
35
- height = 400,
36
- mode = 'light',
37
- children
38
- } = $props()
5
+ /**
6
+ * @type {{
7
+ * spec?: import('./spec/chart-spec.js').ChartSpec,
8
+ * data?: Object[],
9
+ * x?: string,
10
+ * y?: string,
11
+ * color?: string,
12
+ * pattern?: string,
13
+ * fill?: string,
14
+ * size?: string,
15
+ * label?: string,
16
+ * symbol?: string,
17
+ * width?: number,
18
+ * height?: number,
19
+ * mode?: 'light' | 'dark',
20
+ * children?: import('svelte').Snippet
21
+ * }}
22
+ */
23
+ let {
24
+ spec = undefined,
25
+ data = [],
26
+ x = undefined,
27
+ y = undefined,
28
+ color = undefined,
29
+ pattern = undefined,
30
+ fill = undefined,
31
+ size = undefined,
32
+ label = undefined,
33
+ symbol = undefined,
34
+ width = 600,
35
+ height = 400,
36
+ mode = 'light',
37
+ children
38
+ } = $props()
39
39
 
40
- const brewer = new ChartBrewer()
41
- setContext('chart-brewer', brewer)
40
+ const brewer = new ChartBrewer()
41
+ setContext('chart-brewer', brewer)
42
42
 
43
- $effect(() => {
44
- if (spec) {
45
- brewer.update({
46
- data: spec.data,
47
- channels: spec.channels,
48
- width,
49
- height,
50
- mode,
51
- layers: spec.layers
52
- })
53
- } else {
54
- const channels = {}
55
- if (x) channels.x = x
56
- if (y) channels.y = y
57
- if (color) channels.color = color
58
- if (pattern) channels.pattern = pattern
59
- if (fill) channels.fill = fill
60
- if (size) channels.size = size
61
- if (label) channels.label = label
62
- if (symbol) channels.symbol = symbol
63
- brewer.update({ data, channels, width, height, mode })
64
- }
65
- })
43
+ function buildChannels() {
44
+ const channels = {}
45
+ if (x) channels.x = x
46
+ if (y) channels.y = y
47
+ if (color) channels.color = color
48
+ if (pattern) channels.pattern = pattern
49
+ if (fill) channels.fill = fill
50
+ if (size) channels.size = size
51
+ if (label) channels.label = label
52
+ if (symbol) channels.symbol = symbol
53
+ return channels
54
+ }
66
55
 
56
+ $effect(() => {
57
+ if (spec) {
58
+ brewer.update({
59
+ data: spec.data,
60
+ channels: spec.channels,
61
+ width,
62
+ height,
63
+ mode,
64
+ layers: spec.layers
65
+ })
66
+ } else {
67
+ brewer.update({ data, channels: buildChannels(), width, height, mode })
68
+ }
69
+ })
67
70
  </script>
68
71
 
69
72
  <div class="chart-container" data-chart-root>
70
- <svg
71
- {width}
72
- {height}
73
- viewBox="0 0 {width} {height}"
74
- role="img"
75
- aria-label="Chart visualization"
76
- >
77
- <g
78
- class="chart-area"
79
- data-chart-canvas
80
- >
81
- {@render children?.()}
82
- </g>
83
- </svg>
73
+ <svg {width} {height} viewBox="0 0 {width} {height}" role="img" aria-label="Chart visualization">
74
+ <g class="chart-area" data-chart-canvas>
75
+ {@render children?.()}
76
+ </g>
77
+ </svg>
84
78
  </div>
85
79
 
86
80
  <style>
87
- .chart-container {
88
- position: relative;
89
- width: 100%;
90
- height: auto;
91
- }
81
+ .chart-container {
82
+ position: relative;
83
+ width: 100%;
84
+ height: auto;
85
+ }
92
86
 
93
- svg {
94
- display: block;
95
- overflow: visible;
96
- }
87
+ svg {
88
+ display: block;
89
+ overflow: visible;
90
+ }
97
91
 
98
- .chart-area {
99
- pointer-events: all;
100
- }
92
+ .chart-area {
93
+ pointer-events: all;
94
+ }
101
95
  </style>
@@ -0,0 +1,10 @@
1
+ <script>
2
+ import { setContext } from 'svelte'
3
+ import { createChartPreset } from './lib/preset.js'
4
+
5
+ let { preset = createChartPreset(), children } = $props()
6
+
7
+ setContext('chart-preset', { get current() { return preset } })
8
+ </script>
9
+
10
+ {@render children?.()}
@@ -1,23 +1,37 @@
1
1
  <script>
2
- import PlotChart from '../Plot.svelte'
2
+ import PlotChart from '../Plot.svelte'
3
3
 
4
- let {
5
- data, x, y, color, geoms = [], helpers = {},
6
- width, height, mode, grid, legend,
7
- xDomain, yDomain, colorDomain,
8
- children
9
- } = $props()
4
+ let {
5
+ data,
6
+ x,
7
+ y,
8
+ color,
9
+ geoms = [],
10
+ helpers = {},
11
+ width,
12
+ height,
13
+ mode,
14
+ grid,
15
+ legend,
16
+ xDomain,
17
+ yDomain,
18
+ colorDomain,
19
+ children
20
+ } = $props()
10
21
 
11
- // Build spec with domain overrides so PlotState uses them
12
- const spec = $derived({
13
- data, x, y, color,
14
- geoms,
15
- xDomain,
16
- yDomain,
17
- colorDomain
18
- })
22
+ // Build spec with domain overrides so PlotState uses them
23
+ const spec = $derived({
24
+ data,
25
+ x,
26
+ y,
27
+ color,
28
+ geoms,
29
+ xDomain,
30
+ yDomain,
31
+ colorDomain
32
+ })
19
33
  </script>
20
34
 
21
35
  <PlotChart {spec} {helpers} {width} {height} {mode} {grid} {legend}>
22
- {@render children?.()}
36
+ {@render children?.()}
23
37
  </PlotChart>
@@ -1,90 +1,114 @@
1
1
  <script>
2
- import { splitByField, getFacetDomains } from './lib/plot/facet.js'
3
- import { distinct } from './lib/brewing/colors.js'
4
- import PlotPanel from './FacetPlot/Panel.svelte'
2
+ import { splitByField, getFacetDomains } from './lib/plot/facet.js'
3
+ import { distinct } from './lib/brewing/colors.js'
4
+ import PlotPanel from './FacetPlot/Panel.svelte'
5
5
 
6
- /**
7
- * @type {{
8
- * data: Object[],
9
- * facet: { by: string, cols?: number, scales?: 'fixed'|'free'|'free_x'|'free_y' },
10
- * x?: string,
11
- * y?: string,
12
- * color?: string,
13
- * geoms?: import('./lib/plot/types.js').GeomSpec[],
14
- * helpers?: import('./lib/plot/types.js').PlotHelpers,
15
- * panelWidth?: number,
16
- * panelHeight?: number,
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
- facet,
28
- x,
29
- y,
30
- fill,
31
- color,
32
- geoms = [],
33
- helpers = {},
34
- panelWidth,
35
- panelHeight,
36
- width = 900,
37
- height = 300,
38
- mode = 'light',
39
- grid = true,
40
- legend = false,
41
- children
42
- } = $props()
6
+ /**
7
+ * @type {{
8
+ * data: Object[],
9
+ * facet: { by: string, cols?: number, scales?: 'fixed'|'free'|'free_x'|'free_y' },
10
+ * x?: string,
11
+ * y?: string,
12
+ * color?: string,
13
+ * fill?: string,
14
+ * pattern?: string,
15
+ * symbol?: string,
16
+ * geom?: string,
17
+ * stat?: string,
18
+ * geoms?: import('./lib/plot/types.js').GeomSpec[],
19
+ * helpers?: import('./lib/plot/types.js').PlotHelpers,
20
+ * panelWidth?: number,
21
+ * panelHeight?: number,
22
+ * width?: number,
23
+ * height?: number,
24
+ * mode?: 'light' | 'dark',
25
+ * grid?: boolean,
26
+ * legend?: boolean,
27
+ * children?: import('svelte').Snippet
28
+ * }}
29
+ */
30
+ let {
31
+ data = [],
32
+ facet,
33
+ x,
34
+ y,
35
+ fill = undefined,
36
+ color = undefined,
37
+ pattern = undefined,
38
+ symbol = undefined,
39
+ geom = 'bar',
40
+ stat = 'identity',
41
+ geoms = [],
42
+ helpers = {},
43
+ panelWidth,
44
+ panelHeight,
45
+ width = 900,
46
+ height = 300,
47
+ mode = 'light',
48
+ grid = true,
49
+ legend = false,
50
+ children
51
+ } = $props()
43
52
 
44
- // `fill` is accepted as an alias for `color` (bar/area semantics vs line/point)
45
- const colorChannel = $derived(fill ?? color)
53
+ // `fill` is accepted as an alias for `color` (bar/area semantics vs line/point)
54
+ const colorChannel = $derived(fill ?? color)
46
55
 
47
- const panels = $derived(splitByField(data, facet.by))
48
- const scales = $derived(facet.scales ?? 'fixed')
49
- const domains = $derived(
50
- x && y ? getFacetDomains(panels, { x, y }, scales) : new Map()
51
- )
56
+ // Effective geom list: explicit array takes precedence; otherwise build from shorthand props
57
+ const effectiveGeoms = $derived(
58
+ geoms.length > 0
59
+ ? geoms
60
+ : [
61
+ {
62
+ type: geom,
63
+ stat,
64
+ ...(pattern !== undefined && { pattern }),
65
+ ...(symbol !== undefined && { symbol })
66
+ }
67
+ ]
68
+ )
52
69
 
53
- // Global color domain ensures the same value maps to the same color in every panel.
54
- const colorDomain = $derived(colorChannel ? distinct(data, colorChannel) : undefined)
70
+ const panels = $derived(splitByField(data, facet.by))
71
+ const scales = $derived(facet.scales ?? 'fixed')
72
+ const domains = $derived(x && y ? getFacetDomains(panels, { x, y }, scales) : new Map())
55
73
 
56
- const cols = $derived(facet.cols ?? Math.min(panels.size, 3))
57
- const pw = $derived(panelWidth ?? Math.floor(width / cols))
58
- const ph = $derived(panelHeight ?? height)
74
+ // Global color domain ensures the same value maps to the same color in every panel.
75
+ const colorDomain = $derived(colorChannel ? distinct(data, colorChannel) : undefined)
76
+
77
+ const cols = $derived(facet.cols ?? Math.min(panels.size, 3))
78
+ const pw = $derived(panelWidth ?? Math.floor(width / cols))
79
+ const ph = $derived(panelHeight ?? height)
59
80
  </script>
60
81
 
61
82
  <div data-facet-grid style:--facet-cols={cols}>
62
- {#each [...panels.entries()] as [facetValue, panelData] (`${facetValue}`)}
63
- <div data-facet-panel data-facet-value={facetValue}>
64
- <div data-facet-title>{facetValue}</div>
65
- <PlotPanel
66
- data={panelData}
67
- {x} {y} color={colorChannel}
68
- {geoms} {helpers}
69
- width={pw}
70
- height={ph}
71
- {mode} {grid}
72
- legend={false}
73
- xDomain={domains.get(facetValue)?.xDomain}
74
- yDomain={domains.get(facetValue)?.yDomain}
75
- {colorDomain}
76
- >
77
- <!-- Render caller-supplied geoms inside every panel (each gets its own PlotState context) -->
78
- {@render children?.()}
79
- </PlotPanel>
80
- </div>
81
- {/each}
83
+ {#each [...panels.entries()] as [facetValue, panelData] (`${facetValue}`)}
84
+ <div data-facet-panel data-facet-value={facetValue}>
85
+ <div data-facet-title>{facetValue}</div>
86
+ <PlotPanel
87
+ data={panelData}
88
+ {x}
89
+ {y}
90
+ color={colorChannel}
91
+ geoms={effectiveGeoms}
92
+ {helpers}
93
+ width={pw}
94
+ height={ph}
95
+ {mode}
96
+ {grid}
97
+ legend={false}
98
+ xDomain={domains.get(facetValue)?.xDomain}
99
+ yDomain={domains.get(facetValue)?.yDomain}
100
+ {colorDomain}
101
+ >
102
+ <!-- Render caller-supplied geoms inside every panel (each gets its own PlotState context) -->
103
+ {@render children?.()}
104
+ </PlotPanel>
105
+ </div>
106
+ {/each}
82
107
  </div>
83
108
 
84
109
  <!-- Single shared legend outside the grid -->
85
110
  {#if legend}
86
- <div data-facet-legend>
87
- <!-- Legend content rendered by first panel; simplified for now -->
88
- </div>
111
+ <div data-facet-legend>
112
+ <!-- Legend content rendered by first panel; simplified for now -->
113
+ </div>
89
114
  {/if}
90
-
@@ -1,25 +1,32 @@
1
1
  <script>
2
2
  import { getContext } from 'svelte'
3
+ import { area as d3Area } from 'd3-shape'
3
4
 
4
- const brewer = getContext('chart-brewer')
5
+ let {
6
+ data = [],
7
+ x = undefined,
8
+ y = undefined,
9
+ y0 = undefined,
10
+ fill = 'steelblue',
11
+ opacity = 0.7,
12
+ curve = undefined
13
+ } = $props()
14
+
15
+ const state = getContext('plot-state')
16
+
17
+ const path = $derived.by(() => {
18
+ if (!state?.xScale || !state?.yScale || !data?.length) return null
19
+ const innerHeight = state.innerHeight
20
+ const areaGen = d3Area()
21
+ .x((d) => state.xScale(x ? d[x] : d) ?? 0)
22
+ .y1((d) => state.yScale(y ? d[y] : d) ?? 0)
23
+ .y0((d) => (y0 !== undefined ? state.yScale(d[y0] ?? y0) : innerHeight) ?? innerHeight)
24
+ .defined((d) => d != null)
25
+ if (curve) areaGen.curve(curve)
26
+ return areaGen(data)
27
+ })
5
28
  </script>
6
29
 
7
- {#if brewer && brewer.areas && brewer.areas.length > 0}
8
- <g class="chart-areas" data-plot-type="area">
9
- {#each brewer.areas as seg (seg.key ?? seg.d)}
10
- <path
11
- d={seg.d}
12
- fill={seg.fill}
13
- stroke={seg.stroke}
14
- opacity="0.7"
15
- data-plot-element="area"
16
- />
17
- {/each}
18
- </g>
30
+ {#if path}
31
+ <path d={path} {fill} {opacity} stroke="none" data-plot-element="area" />
19
32
  {/if}
20
-
21
- <style>
22
- .chart-areas {
23
- pointer-events: none;
24
- }
25
- </style>
@@ -1,73 +1,95 @@
1
1
  <script>
2
- import { getContext } from 'svelte'
2
+ import { getContext } from 'svelte'
3
3
 
4
- /** @type {'x' | 'y'} */
5
- let { type = 'x', label = '' } = $props()
4
+ /** @type {'x' | 'y'} */
5
+ let { type = 'x', label = '', format = undefined } = $props()
6
6
 
7
- const state = getContext('plot-state')
7
+ const state = getContext('plot-state')
8
8
 
9
- const xTicks = $derived.by(() => {
10
- const s = state.xScale
11
- if (!s) return []
12
- if (typeof s.bandwidth === 'function') {
13
- return s.domain().map((val) => ({
14
- value: val,
15
- pos: (s(val) ?? 0) + s.bandwidth() / 2
16
- }))
17
- }
18
- return s.ticks(6).map((val) => ({ value: val, pos: s(val) }))
19
- })
9
+ const xTicks = $derived.by(() => {
10
+ const s = state.xScale
11
+ if (!s) return []
12
+ if (typeof s.bandwidth === 'function') {
13
+ return s.domain().map((val) => ({
14
+ value: val,
15
+ pos: (s(val) ?? 0) + s.bandwidth() / 2
16
+ }))
17
+ }
18
+ return s.ticks(6).map((val) => ({ value: val, pos: s(val) }))
19
+ })
20
20
 
21
- const yTicks = $derived.by(() => {
22
- const s = state.yScale
23
- if (!s) return []
24
- if (typeof s.bandwidth === 'function') {
25
- return s.domain().map((val) => ({
26
- value: val,
27
- pos: (s(val) ?? 0) + s.bandwidth() / 2
28
- }))
29
- }
30
- return s.ticks(6).map((val) => ({ value: val, pos: s(val) }))
31
- })
21
+ const yTicks = $derived.by(() => {
22
+ const s = state.yScale
23
+ if (!s) return []
24
+ if (typeof s.bandwidth === 'function') {
25
+ return s.domain().map((val) => ({
26
+ value: val,
27
+ pos: (s(val) ?? 0) + s.bandwidth() / 2
28
+ }))
29
+ }
30
+ return s.ticks(6).map((val) => ({ value: val, pos: s(val) }))
31
+ })
32
32
 
33
- const xTransform = $derived(`translate(0, ${state.xAxisY ?? state.innerHeight})`)
34
- const yTransform = $derived(`translate(${state.yAxisX ?? 0}, 0)`)
33
+ const xTransform = $derived(`translate(0, ${state.xAxisY ?? state.innerHeight})`)
34
+ const yTransform = $derived(`translate(${state.yAxisX ?? 0}, 0)`)
35
35
  </script>
36
36
 
37
37
  {#if type === 'x'}
38
- <g class="axis x-axis" transform={xTransform} data-plot-axis="x">
39
- <line x1="0" y1="0" x2={state.innerWidth} y2="0" data-plot-axis-line />
40
- {#each xTicks as tick (tick.value)}
41
- <g transform="translate({tick.pos}, 0)" data-plot-tick>
42
- <line x1="0" y1="0" x2="0" y2="6" stroke="currentColor" />
43
- <text x="0" y="9" text-anchor="middle" dominant-baseline="hanging" data-plot-tick-label>
44
- {tick.value}
45
- </text>
46
- </g>
47
- {/each}
48
- {#if label}
49
- <text x={state.innerWidth / 2} y="36" text-anchor="middle" class="axis-label" data-plot-axis-label>{label}</text>
50
- {/if}
51
- </g>
38
+ <g class="axis x-axis" transform={xTransform} data-plot-axis="x">
39
+ <line x1="0" y1="0" x2={state.innerWidth} y2="0" data-plot-axis-line />
40
+ {#each xTicks as tick (tick.value)}
41
+ <g transform="translate({tick.pos}, 0)" data-plot-tick>
42
+ <line x1="0" y1="0" x2="0" y2="6" stroke="currentColor" />
43
+ <text x="0" y="9" text-anchor="middle" dominant-baseline="hanging" data-plot-tick-label>
44
+ {format ? format(tick.value) : tick.value}
45
+ </text>
46
+ </g>
47
+ {/each}
48
+ {#if label}
49
+ <text
50
+ x={state.innerWidth / 2}
51
+ y="36"
52
+ text-anchor="middle"
53
+ class="axis-label"
54
+ data-plot-axis-label>{label}</text
55
+ >
56
+ {/if}
57
+ </g>
52
58
  {:else}
53
- <g class="axis y-axis" transform={yTransform} data-plot-axis="y">
54
- <line x1="0" y1="0" x2="0" y2={state.innerHeight} data-plot-axis-line />
55
- {#each yTicks as tick (tick.value)}
56
- <g transform="translate(0, {tick.pos})" data-plot-tick>
57
- <line x1="-6" y1="0" x2="0" y2="0" stroke="currentColor" />
58
- <text x="-9" y="0" text-anchor="end" dominant-baseline="middle" data-plot-tick-label>
59
- {tick.value}
60
- </text>
61
- </g>
62
- {/each}
63
- {#if label}
64
- <text transform="rotate(-90)" x={-(state.innerHeight / 2)} y="-40" text-anchor="middle" class="axis-label" data-plot-axis-label>{label}</text>
65
- {/if}
66
- </g>
59
+ <g class="axis y-axis" transform={yTransform} data-plot-axis="y">
60
+ <line x1="0" y1="0" x2="0" y2={state.innerHeight} data-plot-axis-line />
61
+ {#each yTicks as tick (tick.value)}
62
+ <g transform="translate(0, {tick.pos})" data-plot-tick>
63
+ <line x1="-6" y1="0" x2="0" y2="0" stroke="currentColor" />
64
+ <text x="-9" y="0" text-anchor="end" dominant-baseline="middle" data-plot-tick-label>
65
+ {format ? format(tick.value) : tick.value}
66
+ </text>
67
+ </g>
68
+ {/each}
69
+ {#if label}
70
+ <text
71
+ transform="rotate(-90)"
72
+ x={-(state.innerHeight / 2)}
73
+ y="-40"
74
+ text-anchor="middle"
75
+ class="axis-label"
76
+ data-plot-axis-label>{label}</text
77
+ >
78
+ {/if}
79
+ </g>
67
80
  {/if}
68
81
 
69
82
  <style>
70
- .axis { font-size: 11px; fill: currentColor; stroke: currentColor; }
71
- .axis-label { font-size: 13px; font-weight: 500; }
72
- [data-plot-axis-line] { stroke: currentColor; }
83
+ .axis {
84
+ font-size: 11px;
85
+ fill: currentColor;
86
+ stroke: currentColor;
87
+ }
88
+ .axis-label {
89
+ font-size: 13px;
90
+ font-weight: 500;
91
+ }
92
+ [data-plot-axis-line] {
93
+ stroke: currentColor;
94
+ }
73
95
  </style>