@rokkit/chart 1.0.0-next.99 → 1.0.2

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 (137) hide show
  1. package/README.md +150 -46
  2. package/package.json +40 -51
  3. package/src/AnimatedPlot.svelte +383 -0
  4. package/src/Chart.svelte +87 -59
  5. package/src/ChartExporter.svelte +125 -0
  6. package/src/ChartLegend.svelte +148 -0
  7. package/src/ChartProvider.svelte +10 -0
  8. package/src/FacetPlot/Panel.svelte +37 -0
  9. package/src/FacetPlot.svelte +114 -0
  10. package/src/Plot/Arc.svelte +29 -0
  11. package/src/Plot/Area.svelte +32 -0
  12. package/src/Plot/Axis.svelte +164 -0
  13. package/src/Plot/Bar.svelte +54 -0
  14. package/src/Plot/Grid.svelte +34 -0
  15. package/src/Plot/Legend.svelte +268 -0
  16. package/src/Plot/Line.svelte +37 -0
  17. package/src/Plot/Point.svelte +40 -0
  18. package/src/Plot/Root.svelte +62 -0
  19. package/src/Plot/Timeline.svelte +95 -0
  20. package/src/Plot/Tooltip.svelte +87 -0
  21. package/src/Plot/index.js +9 -0
  22. package/src/Plot.svelte +313 -0
  23. package/src/PlotState.svelte.js +375 -0
  24. package/src/Sparkline.svelte +108 -0
  25. package/src/Symbol.svelte +15 -11
  26. package/src/Texture.svelte +9 -7
  27. package/src/charts/AreaChart.svelte +30 -0
  28. package/src/charts/BarChart.svelte +31 -0
  29. package/src/charts/BoxPlot.svelte +24 -0
  30. package/src/charts/BubbleChart.svelte +28 -0
  31. package/src/charts/LineChart.svelte +31 -0
  32. package/src/charts/PieChart.svelte +35 -0
  33. package/src/charts/ScatterPlot.svelte +31 -0
  34. package/src/charts/ViolinPlot.svelte +24 -0
  35. package/src/crossfilter/CrossFilter.svelte +42 -0
  36. package/src/crossfilter/FilterBar.svelte +24 -0
  37. package/src/crossfilter/FilterHistogram.svelte +290 -0
  38. package/src/crossfilter/FilterSlider.svelte +83 -0
  39. package/src/crossfilter/createCrossFilter.svelte.js +124 -0
  40. package/src/elements/Bar.svelte +20 -16
  41. package/src/elements/ColorRamp.svelte +19 -19
  42. package/src/elements/ContinuousLegend.svelte +41 -19
  43. package/src/elements/DefinePatterns.svelte +9 -7
  44. package/src/elements/DiscreteLegend.svelte +13 -11
  45. package/src/elements/Label.svelte +4 -9
  46. package/src/elements/SymbolGrid.svelte +8 -9
  47. package/src/examples/BarChartExample.svelte +81 -0
  48. package/src/geoms/Arc.svelte +126 -0
  49. package/src/geoms/Area.svelte +78 -0
  50. package/src/geoms/Bar.svelte +200 -0
  51. package/src/geoms/Box.svelte +113 -0
  52. package/src/geoms/Candlestick.svelte +110 -0
  53. package/src/geoms/Heatmap.svelte +92 -0
  54. package/src/geoms/Hexbin.svelte +114 -0
  55. package/src/geoms/LabelPill.svelte +17 -0
  56. package/src/geoms/Line.svelte +123 -0
  57. package/src/geoms/Point.svelte +145 -0
  58. package/src/geoms/Ribbon.svelte +161 -0
  59. package/src/geoms/Violin.svelte +56 -0
  60. package/src/geoms/Waterfall.svelte +114 -0
  61. package/src/geoms/lib/areas.js +154 -0
  62. package/src/geoms/lib/bars.js +223 -0
  63. package/src/index.js +81 -2
  64. package/src/lib/brewing/BoxBrewer.svelte.js +14 -0
  65. package/src/lib/brewing/CartesianBrewer.svelte.js +21 -0
  66. package/src/lib/brewing/PieBrewer.svelte.js +14 -0
  67. package/src/lib/brewing/QuartileBrewer.svelte.js +51 -0
  68. package/src/lib/brewing/ViolinBrewer.svelte.js +14 -0
  69. package/src/lib/brewing/axes.svelte.js +270 -0
  70. package/src/lib/brewing/bars.svelte.js +201 -0
  71. package/src/lib/brewing/brewer.svelte.js +277 -0
  72. package/src/lib/brewing/colors.js +157 -0
  73. package/src/lib/brewing/dimensions.svelte.js +56 -0
  74. package/src/lib/brewing/index.svelte.js +205 -0
  75. package/src/lib/brewing/legends.svelte.js +137 -0
  76. package/src/lib/brewing/marks/arcs.js +43 -0
  77. package/src/lib/brewing/marks/areas.js +72 -0
  78. package/src/lib/brewing/marks/bars.js +49 -0
  79. package/src/lib/brewing/marks/boxes.js +75 -0
  80. package/src/lib/brewing/marks/lines.js +55 -0
  81. package/src/lib/brewing/marks/points.js +105 -0
  82. package/src/lib/brewing/marks/violins.js +90 -0
  83. package/src/lib/brewing/patterns.js +45 -0
  84. package/src/lib/brewing/scales.js +51 -0
  85. package/src/lib/brewing/scales.svelte.js +82 -0
  86. package/src/lib/brewing/stats.js +74 -0
  87. package/src/lib/brewing/symbols.js +10 -0
  88. package/src/lib/brewing/types.js +73 -0
  89. package/src/lib/chart.js +16 -8
  90. package/src/lib/context.js +131 -0
  91. package/src/lib/keyboard-nav.js +37 -0
  92. package/src/lib/plot/chartProps.js +76 -0
  93. package/src/lib/plot/crossfilter.js +16 -0
  94. package/src/lib/plot/facet.js +58 -0
  95. package/src/lib/plot/frames.js +81 -0
  96. package/src/lib/plot/helpers.js +14 -0
  97. package/src/lib/plot/preset.js +67 -0
  98. package/src/lib/plot/scales.js +81 -0
  99. package/src/lib/plot/stat.js +92 -0
  100. package/src/lib/plot/types.js +65 -0
  101. package/src/lib/preset.js +41 -0
  102. package/src/lib/scales.svelte.js +151 -0
  103. package/src/lib/swatch.js +4 -7
  104. package/src/lib/utils.js +142 -0
  105. package/src/lib/xscale.js +31 -0
  106. package/src/patterns/DefinePatterns.svelte +32 -0
  107. package/src/patterns/PatternDef.svelte +27 -0
  108. package/src/patterns/index.js +4 -14
  109. package/src/patterns/patterns.js +360 -0
  110. package/src/patterns/scale.js +116 -0
  111. package/src/spec/chart-spec.js +72 -0
  112. package/src/symbols/RoundedSquare.svelte +18 -12
  113. package/src/symbols/Shape.svelte +22 -16
  114. package/src/symbols/constants/index.js +1 -1
  115. package/LICENSE +0 -21
  116. package/src/lib/index.js +0 -4
  117. package/src/lib/plots.js +0 -27
  118. package/src/patterns/Brick.svelte +0 -17
  119. package/src/patterns/Circles.svelte +0 -18
  120. package/src/patterns/CrossHatch.svelte +0 -14
  121. package/src/patterns/CurvedWave.svelte +0 -9
  122. package/src/patterns/Dots.svelte +0 -19
  123. package/src/patterns/OutlineCircles.svelte +0 -15
  124. package/src/patterns/Tile.svelte +0 -17
  125. package/src/patterns/Triangles.svelte +0 -15
  126. package/src/patterns/Waves.svelte +0 -13
  127. package/src/patterns/paths/NamedPattern.svelte +0 -12
  128. package/src/patterns/paths/constants.js +0 -4
  129. package/src/plots/Plot.svelte +0 -40
  130. package/src/plots/index.js +0 -1
  131. package/src/template/Texture.svelte +0 -16
  132. package/src/template/constants.js +0 -43
  133. package/src/template/shapes/Circles.svelte +0 -16
  134. package/src/template/shapes/Lines.svelte +0 -17
  135. package/src/template/shapes/Path.svelte +0 -12
  136. package/src/template/shapes/Polygons.svelte +0 -18
  137. package/src/template/shapes/index.js +0 -4
@@ -0,0 +1,108 @@
1
+ <script>
2
+ import { scaleLinear } from 'd3-scale'
3
+ import { line as d3line, area as d3area, curveCatmullRom } from 'd3-shape'
4
+ import PatternDef from './patterns/PatternDef.svelte'
5
+ import { PATTERNS } from './patterns/patterns.js'
6
+
7
+ /**
8
+ * @type {number[] | object[]}
9
+ */
10
+ let {
11
+ data = [],
12
+ field = undefined,
13
+ type = 'line',
14
+ curve = 'linear',
15
+ color = 'primary',
16
+ pattern = undefined,
17
+ width = 80,
18
+ height = 24,
19
+ min = undefined,
20
+ max = undefined
21
+ } = $props()
22
+
23
+ const values = $derived(field ? data.map((d) => Number(d[field])) : data.map(Number))
24
+
25
+ const yMin = $derived(min ?? Math.min(...values))
26
+ const yMax = $derived(max ?? Math.max(...values))
27
+
28
+ const xScale = $derived(
29
+ scaleLinear()
30
+ .domain([0, values.length - 1])
31
+ .range([0, width])
32
+ )
33
+ const yScale = $derived(scaleLinear().domain([yMin, yMax]).range([height, 0]))
34
+
35
+ const linePath = $derived.by(() => {
36
+ const gen = d3line()
37
+ .x((_, i) => xScale(i))
38
+ .y((v) => yScale(v))
39
+ if (curve === 'smooth') gen.curve(curveCatmullRom)
40
+ return gen(values)
41
+ })
42
+
43
+ const areaPath = $derived.by(() => {
44
+ const gen = d3area()
45
+ .x((_, i) => xScale(i))
46
+ .y0(height)
47
+ .y1((v) => yScale(v))
48
+ if (curve === 'smooth') gen.curve(curveCatmullRom)
49
+ return gen(values)
50
+ })
51
+
52
+ const barWidth = $derived(Math.max(1, width / values.length - 1))
53
+
54
+ const strokeColor = $derived(`rgb(var(--color-${color}-500, 100,116,139))`)
55
+ const fillColor = $derived(`rgba(var(--color-${color}-300), 0.25)`)
56
+
57
+ const patternId = 'sparkline-pattern'
58
+ const patternMarks = $derived(pattern ? (PATTERNS[pattern] ?? null) : null)
59
+ </script>
60
+
61
+ <svg {width} {height} style="overflow: visible; display: block;">
62
+ {#if patternMarks}
63
+ <defs>
64
+ <PatternDef id={patternId} marks={patternMarks} stroke={strokeColor} />
65
+ </defs>
66
+ {/if}
67
+
68
+ {#if type === 'line'}
69
+ <path
70
+ d={linePath}
71
+ fill="none"
72
+ stroke={strokeColor}
73
+ stroke-width="1.5"
74
+ stroke-linejoin="round"
75
+ stroke-linecap="round"
76
+ />
77
+ {:else if type === 'area'}
78
+ <path d={areaPath} fill={patternMarks ? `url(#${patternId})` : fillColor} stroke="none" />
79
+ <path
80
+ d={linePath}
81
+ fill="none"
82
+ stroke={strokeColor}
83
+ stroke-width="1.5"
84
+ stroke-linejoin="round"
85
+ stroke-linecap="round"
86
+ />
87
+ {:else if type === 'bar'}
88
+ {#each values as v, i (i)}
89
+ <rect
90
+ x={xScale(i) - barWidth / 2}
91
+ y={yScale(v)}
92
+ width={barWidth}
93
+ height={height - yScale(v)}
94
+ fill={strokeColor}
95
+ />
96
+ {#if patternMarks}
97
+ <rect
98
+ x={xScale(i) - barWidth / 2}
99
+ y={yScale(v)}
100
+ width={barWidth}
101
+ height={height - yScale(v)}
102
+ fill="url(#{patternId})"
103
+ pointer-events="none"
104
+ />
105
+ {/if}
106
+ {/each}
107
+ {/if}
108
+ </svg>
package/src/Symbol.svelte CHANGED
@@ -1,17 +1,21 @@
1
1
  <script>
2
2
  import { components } from './symbols'
3
3
 
4
- export let x = 0
5
- export let y = 0
6
- export let size = 10
7
- export let fill = 'currentColor'
8
- export let stroke = 'currentColor'
9
- export let name = 'circle'
10
- /** @type Object<string, any> */
11
- export let using = components
4
+ let {
5
+ x = 0,
6
+ y = 0,
7
+ size = 10,
8
+ fill = 'currentColor',
9
+ stroke = 'currentColor',
10
+ name = 'circle',
11
+ ...restProps
12
+ } = $props()
12
13
 
13
- $: component = using[name] || using.default
14
- $: props = using[name] ? $$restProps : { name, ...$$restProps }
14
+ let RenderShape = $derived(components[name] ?? components.default)
15
+ let props = $derived({ ...restProps, x, y, size, fill, stroke })
15
16
  </script>
16
17
 
17
- <svelte:component this={component} {x} {y} {size} {fill} {stroke} {...props} />
18
+ <!-- {#snippet defaultSymbol(props)}
19
+ <circle cx={x} cy={y} r={size / 2} {fill} {stroke} />
20
+ {/snippet} -->
21
+ <RenderShape {...props} />
@@ -1,11 +1,13 @@
1
1
  <script>
2
- export let id
3
- export let path
4
- export let fill = 'currentColor'
5
- export let stroke = 'currentColor'
6
- export let thickness = 0.5
7
- export let patternUnits = 'userSpaceOnUse'
8
- export let size = 10
2
+ let {
3
+ id,
4
+ path,
5
+ fill = 'currentColor',
6
+ stroke = 'currentColor',
7
+ thickness = 0.5,
8
+ patternUnits = 'userSpaceOnUse',
9
+ size = 10
10
+ } = $props()
9
11
  </script>
10
12
 
11
13
  <pattern {id} {patternUnits} width={size} height={size}>
@@ -0,0 +1,30 @@
1
+ <script>
2
+ import Plot from '../Plot.svelte'
3
+ import Area from '../geoms/Area.svelte'
4
+
5
+ /** @type {import('../lib/plot/chartProps.js').LineAreaChartProps} */
6
+ let {
7
+ data = [],
8
+ x = undefined,
9
+ y = undefined,
10
+ fill = undefined,
11
+ stat = 'identity',
12
+ curve = undefined,
13
+ pattern = undefined,
14
+ stack = false,
15
+ width = 600,
16
+ height = 400,
17
+ mode = 'light',
18
+ grid = true,
19
+ legend = false,
20
+ xFormat = undefined,
21
+ yFormat = undefined,
22
+ xTicks = undefined,
23
+ yTicks = undefined,
24
+ minorTicks = false
25
+ } = $props()
26
+ </script>
27
+
28
+ <Plot {data} {width} {height} {mode} {grid} {legend} {xFormat} {yFormat} {xTicks} {yTicks} {minorTicks}>
29
+ <Area {x} {y} color={fill} {pattern} {stat} options={{ curve, stack }} />
30
+ </Plot>
@@ -0,0 +1,31 @@
1
+ <script>
2
+ import Plot from '../Plot.svelte'
3
+ import Bar from '../geoms/Bar.svelte'
4
+
5
+ /** @type {import('../lib/plot/chartProps.js').BarChartProps} */
6
+ let {
7
+ data = [],
8
+ x = undefined,
9
+ y = undefined,
10
+ fill = undefined, // mapped to color channel
11
+ pattern = undefined,
12
+ width = 600,
13
+ height = 400,
14
+ mode = 'light',
15
+ grid = true,
16
+ legend = false,
17
+ stat = 'identity',
18
+ stack = false,
19
+ label = false,
20
+ tooltip = false,
21
+ xFormat = undefined,
22
+ yFormat = undefined,
23
+ xTicks = undefined,
24
+ yTicks = undefined,
25
+ minorTicks = false
26
+ } = $props()
27
+ </script>
28
+
29
+ <Plot {data} {width} {height} {mode} {grid} {legend} {tooltip} {xFormat} {yFormat} {xTicks} {yTicks} {minorTicks}>
30
+ <Bar {x} {y} color={fill} {pattern} {label} {stat} options={{ stack }} />
31
+ </Plot>
@@ -0,0 +1,24 @@
1
+ <script>
2
+ import Plot from '../Plot.svelte'
3
+ import Box from '../geoms/Box.svelte'
4
+
5
+ /** @type {import('../lib/plot/chartProps.js').BoxViolinChartProps} */
6
+ let {
7
+ data = [],
8
+ x = undefined,
9
+ y = undefined,
10
+ fill = undefined,
11
+ width = 600,
12
+ height = 400,
13
+ mode = 'light',
14
+ grid = true,
15
+ legend = false,
16
+ yFormat = undefined,
17
+ yTicks = undefined,
18
+ minorTicks = false
19
+ } = $props()
20
+ </script>
21
+
22
+ <Plot {data} {width} {height} {mode} {grid} {legend} {yFormat} {yTicks} {minorTicks}>
23
+ <Box {x} {y} {fill} />
24
+ </Plot>
@@ -0,0 +1,28 @@
1
+ <script>
2
+ import Plot from '../Plot.svelte'
3
+ import Point from '../geoms/Point.svelte'
4
+
5
+ /** @type {import('../lib/plot/chartProps.js').ScatterBubbleChartProps} */
6
+ let {
7
+ data = [],
8
+ x = undefined,
9
+ y = undefined,
10
+ color = undefined,
11
+ symbol: _symbol = undefined,
12
+ size, // required: field name for bubble radius
13
+ width = 600,
14
+ height = 400,
15
+ mode = 'light',
16
+ grid = true,
17
+ legend = false,
18
+ xFormat = undefined,
19
+ yFormat = undefined,
20
+ xTicks = undefined,
21
+ yTicks = undefined,
22
+ minorTicks = false
23
+ } = $props()
24
+ </script>
25
+
26
+ <Plot {data} {width} {height} {mode} {grid} {legend} {xFormat} {yFormat} {xTicks} {yTicks} {minorTicks}>
27
+ <Point {x} {y} {color} {size} />
28
+ </Plot>
@@ -0,0 +1,31 @@
1
+ <script>
2
+ import Plot from '../Plot.svelte'
3
+ import Line from '../geoms/Line.svelte'
4
+
5
+ /** @type {import('../lib/plot/chartProps.js').LineAreaChartProps} */
6
+ let {
7
+ data = [],
8
+ x = undefined,
9
+ y = undefined,
10
+ color = undefined,
11
+ stat = 'identity',
12
+ symbol = undefined,
13
+ curve = undefined, // forwarded to Line options
14
+ label = false,
15
+ tooltip = false,
16
+ width = 600,
17
+ height = 400,
18
+ mode = 'light',
19
+ grid = true,
20
+ legend = false,
21
+ xFormat = undefined,
22
+ yFormat = undefined,
23
+ xTicks = undefined,
24
+ yTicks = undefined,
25
+ minorTicks = false
26
+ } = $props()
27
+ </script>
28
+
29
+ <Plot {data} {width} {height} {mode} {grid} {legend} {tooltip} {xFormat} {yFormat} {xTicks} {yTicks} {minorTicks}>
30
+ <Line {x} {y} {color} {symbol} {label} {stat} options={{ curve }} />
31
+ </Plot>
@@ -0,0 +1,35 @@
1
+ <script>
2
+ import Plot from '../Plot.svelte'
3
+ import Arc from '../geoms/Arc.svelte'
4
+
5
+ /** @type {import('../lib/plot/chartProps.js').PieChartProps} */
6
+ let {
7
+ data = [],
8
+ label = undefined,
9
+ y = undefined,
10
+ fill = undefined,
11
+ pattern = undefined,
12
+ innerRadius = 0,
13
+ labelFn = undefined,
14
+ tooltip = false,
15
+ width = 400,
16
+ height = 400,
17
+ mode = 'light',
18
+ legend = false,
19
+ stat = 'sum'
20
+ } = $props()
21
+ </script>
22
+
23
+ <Plot
24
+ {data}
25
+ {width}
26
+ {height}
27
+ {mode}
28
+ grid={false}
29
+ axes={false}
30
+ margin={{ top: 10, right: 10, bottom: 10, left: 10 }}
31
+ {legend}
32
+ {tooltip}
33
+ >
34
+ <Arc theta={y} fill={label ?? fill} {pattern} {labelFn} {stat} options={{ innerRadius }} />
35
+ </Plot>
@@ -0,0 +1,31 @@
1
+ <script>
2
+ import Plot from '../Plot.svelte'
3
+ import Point from '../geoms/Point.svelte'
4
+
5
+ /** @type {import('../lib/plot/chartProps.js').ScatterBubbleChartProps} */
6
+ let {
7
+ data = [],
8
+ x = undefined,
9
+ y = undefined,
10
+ color = undefined,
11
+ symbol = undefined,
12
+ size = undefined,
13
+ label = false,
14
+ tooltip = false,
15
+ width = 600,
16
+ height = 400,
17
+ mode = 'light',
18
+ grid = true,
19
+ legend = false,
20
+ jitter = undefined,
21
+ xFormat = undefined,
22
+ yFormat = undefined,
23
+ xTicks = undefined,
24
+ yTicks = undefined,
25
+ minorTicks = false
26
+ } = $props()
27
+ </script>
28
+
29
+ <Plot {data} {width} {height} {mode} {grid} {legend} {tooltip} {xFormat} {yFormat} {xTicks} {yTicks} {minorTicks}>
30
+ <Point {x} {y} {color} {size} {symbol} {label} options={{ jitter }} />
31
+ </Plot>
@@ -0,0 +1,24 @@
1
+ <script>
2
+ import Plot from '../Plot.svelte'
3
+ import Violin from '../geoms/Violin.svelte'
4
+
5
+ /** @type {import('../lib/plot/chartProps.js').BoxViolinChartProps} */
6
+ let {
7
+ data = [],
8
+ x = undefined,
9
+ y = undefined,
10
+ fill = undefined,
11
+ width = 600,
12
+ height = 400,
13
+ mode = 'light',
14
+ grid = true,
15
+ legend = false,
16
+ yFormat = undefined,
17
+ yTicks = undefined,
18
+ minorTicks = false
19
+ } = $props()
20
+ </script>
21
+
22
+ <Plot {data} {width} {height} {mode} {grid} {legend} {yFormat} {yTicks} {minorTicks}>
23
+ <Violin {x} {y} {fill} />
24
+ </Plot>
@@ -0,0 +1,42 @@
1
+ <script>
2
+ import { setContext, untrack } from 'svelte'
3
+ import { createCrossFilter } from './createCrossFilter.svelte.js'
4
+
5
+ /**
6
+ * @type {{
7
+ * crossfilter?: ReturnType<typeof createCrossFilter>,
8
+ * mode?: 'dim' | 'hide',
9
+ * filters?: import('./createCrossFilter.svelte.js').FilterState,
10
+ * children?: import('svelte').Snippet
11
+ * }}
12
+ */
13
+ let {
14
+ crossfilter: externalCf = undefined,
15
+ mode = 'dim',
16
+ filters = $bindable(),
17
+ children
18
+ } = $props()
19
+
20
+ // Use an externally provided instance (spec/helpers API) or create one internally.
21
+ // untrack() suppresses "captures initial value" warning — intentional: the cf
22
+ // instance is locked in at construction time and must not recreate on prop changes.
23
+ const cf = untrack(() => externalCf ?? createCrossFilter())
24
+
25
+ // Expose the reactive filters Map to callers via bind:filters
26
+ $effect(() => {
27
+ filters = cf.filters
28
+ })
29
+
30
+ setContext('crossfilter', cf)
31
+ // Use a getter object so children can read .mode reactively
32
+ const modeRef = {
33
+ get mode() {
34
+ return mode
35
+ }
36
+ }
37
+ setContext('crossfilter-mode', modeRef)
38
+ </script>
39
+
40
+ <div data-crossfilter data-crossfilter-mode={mode}>
41
+ {@render children?.()}
42
+ </div>
@@ -0,0 +1,24 @@
1
+ <script>
2
+ import PlotChart from '../Plot.svelte'
3
+ import Bar from '../geoms/Bar.svelte'
4
+
5
+ let {
6
+ data = [],
7
+ field,
8
+ valueField,
9
+ stat = 'sum',
10
+ width = 300,
11
+ height = 120,
12
+ mode = 'light'
13
+ } = $props()
14
+
15
+ const spec = $derived({
16
+ x: field,
17
+ y: valueField
18
+ })
19
+ </script>
20
+
21
+ <!-- FilterBar must be used inside a <CrossFilter> parent. Does not create its own context. -->
22
+ <PlotChart {data} {spec} {width} {height} {mode} grid={false} legend={false}>
23
+ <Bar x={field} y={valueField} {stat} filterable={true} />
24
+ </PlotChart>