@faintshadow/flarecharts 26.3.1

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 (85) hide show
  1. package/LICENSE +40 -0
  2. package/README.md +103 -0
  3. package/dist/charts/AreaChart.svelte +150 -0
  4. package/dist/charts/AreaChart.svelte.d.ts +60 -0
  5. package/dist/charts/BarChart.svelte +142 -0
  6. package/dist/charts/BarChart.svelte.d.ts +58 -0
  7. package/dist/charts/BoxPlotChart.svelte +138 -0
  8. package/dist/charts/BoxPlotChart.svelte.d.ts +56 -0
  9. package/dist/charts/DonutChart.svelte +129 -0
  10. package/dist/charts/DonutChart.svelte.d.ts +73 -0
  11. package/dist/charts/LineChart.svelte +149 -0
  12. package/dist/charts/LineChart.svelte.d.ts +63 -0
  13. package/dist/charts/Sparkline.svelte +87 -0
  14. package/dist/charts/Sparkline.svelte.d.ts +40 -0
  15. package/dist/charts/StackChart.svelte +157 -0
  16. package/dist/charts/StackChart.svelte.d.ts +69 -0
  17. package/dist/components/Arc.svelte +202 -0
  18. package/dist/components/Arc.svelte.d.ts +50 -0
  19. package/dist/components/Area.svelte +264 -0
  20. package/dist/components/Area.svelte.d.ts +54 -0
  21. package/dist/components/Axis.svelte +139 -0
  22. package/dist/components/Axis.svelte.d.ts +26 -0
  23. package/dist/components/Bars.svelte +192 -0
  24. package/dist/components/Bars.svelte.d.ts +55 -0
  25. package/dist/components/Box.svelte +287 -0
  26. package/dist/components/Box.svelte.d.ts +48 -0
  27. package/dist/components/Chart.svelte +207 -0
  28. package/dist/components/Chart.svelte.d.ts +23 -0
  29. package/dist/components/Crosshair.svelte +67 -0
  30. package/dist/components/Crosshair.svelte.d.ts +14 -0
  31. package/dist/components/Grid.svelte +38 -0
  32. package/dist/components/Grid.svelte.d.ts +14 -0
  33. package/dist/components/Labels.svelte +61 -0
  34. package/dist/components/Labels.svelte.d.ts +35 -0
  35. package/dist/components/Legend.svelte +81 -0
  36. package/dist/components/Legend.svelte.d.ts +12 -0
  37. package/dist/components/Line.svelte +192 -0
  38. package/dist/components/Line.svelte.d.ts +47 -0
  39. package/dist/components/PlotBand.svelte +68 -0
  40. package/dist/components/PlotBand.svelte.d.ts +14 -0
  41. package/dist/components/PlotLine.svelte +54 -0
  42. package/dist/components/PlotLine.svelte.d.ts +16 -0
  43. package/dist/components/Points.svelte +179 -0
  44. package/dist/components/Points.svelte.d.ts +53 -0
  45. package/dist/components/Svg.svelte +36 -0
  46. package/dist/components/Svg.svelte.d.ts +8 -0
  47. package/dist/components/Tooltip.svelte +211 -0
  48. package/dist/components/Tooltip.svelte.d.ts +44 -0
  49. package/dist/core/bisect.d.ts +5 -0
  50. package/dist/core/bisect.js +23 -0
  51. package/dist/core/context.svelte.d.ts +140 -0
  52. package/dist/core/context.svelte.js +294 -0
  53. package/dist/core/curves.d.ts +4 -0
  54. package/dist/core/curves.js +13 -0
  55. package/dist/core/hit.d.ts +34 -0
  56. package/dist/core/hit.js +43 -0
  57. package/dist/core/keynav.d.ts +20 -0
  58. package/dist/core/keynav.js +41 -0
  59. package/dist/core/labels.d.ts +39 -0
  60. package/dist/core/labels.js +27 -0
  61. package/dist/core/merge.d.ts +17 -0
  62. package/dist/core/merge.js +46 -0
  63. package/dist/core/motion.svelte.d.ts +31 -0
  64. package/dist/core/motion.svelte.js +129 -0
  65. package/dist/core/normalize.d.ts +35 -0
  66. package/dist/core/normalize.js +97 -0
  67. package/dist/core/options.d.ts +113 -0
  68. package/dist/core/options.js +36 -0
  69. package/dist/core/palette.d.ts +8 -0
  70. package/dist/core/palette.js +24 -0
  71. package/dist/core/responsive.d.ts +6 -0
  72. package/dist/core/responsive.js +19 -0
  73. package/dist/core/scales.d.ts +31 -0
  74. package/dist/core/scales.js +89 -0
  75. package/dist/core/stack.d.ts +19 -0
  76. package/dist/core/stack.js +133 -0
  77. package/dist/core/stats.d.ts +45 -0
  78. package/dist/core/stats.js +114 -0
  79. package/dist/core/symbols.d.ts +8 -0
  80. package/dist/core/symbols.js +31 -0
  81. package/dist/core/types.d.ts +28 -0
  82. package/dist/core/types.js +1 -0
  83. package/dist/index.d.ts +52 -0
  84. package/dist/index.js +42 -0
  85. package/package.json +81 -0
package/LICENSE ADDED
@@ -0,0 +1,40 @@
1
+ FlareCharts License (MIT with Attribution)
2
+
3
+ Copyright (c) 2026 Safwen TBINI
4
+
5
+ Permission is hereby granted, free of charge, to any person or organization
6
+ obtaining a copy of this software and associated documentation files
7
+ ("FlareCharts", the "Software"), to deal in the Software without restriction,
8
+ including without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to permit
10
+ persons to whom the Software is furnished to do so, subject to the following
11
+ conditions:
12
+
13
+ 1. The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ 2. Attribution. Any application, product, or distribution that uses the
17
+ Software, in whole or in part, must include a visible credit to FlareCharts
18
+ in a place accessible to end users (for example: an "About" page, a credits
19
+ or settings screen, documentation, or a page footer). The credit must show
20
+ the project name and a link to the project repository — either as a
21
+ clickable hyperlink or as plain, copyable text — for example:
22
+
23
+ FlareCharts can be found here: https://gitlab.com/FaintShadow/flarecharts
24
+
25
+ The repository URL is the one specified in the NOTICE file of the version
26
+ of the Software in use.
27
+
28
+ No commercial license is offered at this time. One may be made available in
29
+ a future version of the Software. A commercial license, when offered, removes
30
+ the attribution requirement of this condition 2, and the terms accompanying
31
+ that version apply instead. Until then, this condition 2 applies to all use,
32
+ including commercial use.
33
+
34
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
40
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ <p align="center"><img src="https://gitlab.com/FaintShadow/flarecharts/-/raw/main/static/favicon.svg" width="127" alt="Flarecharts Logo"></p>
2
+
3
+ ## About Flarecharts
4
+
5
+ Flarecharts is a composable SVG chart library for **Svelte 5** built on runes. We believe data visualization should be expressive, accessible, and easy to customize. Flarecharts takes the pain out of charting by easing common tasks used in many web projects, such as:
6
+
7
+ - **Runes-first architecture:** Built specifically for Svelte 5.
8
+ - **d3 for math only:** No d3 DOM bindings, just pure SVG components.
9
+ - **CSS-variable themed:** "Styled mode" is the only mode. Theme by setting variables on any wrapper.
10
+ - **Composable Primitives & one-tag Charts:** Eject from a wrapper to custom composition without reshaping your data.
11
+ - **Accessibility built-in:** Visually-hidden data tables, aria-live regions, and full arrow-key point navigation.
12
+ - **First-class stacking & curves:** Modelled on d3's stack generator with diverging, stream, and silhouette offsets.
13
+
14
+ ## Learning Flarecharts
15
+
16
+ Flarecharts has extensive and thorough [documentation](https://flarecharts.gitbook.io/docs). It covers everything from getting started to deep dives on stacking, curves, and accessibility.
17
+
18
+ The documentation is also available in [docs/](https://gitlab.com/FaintShadow/flarecharts/-/tree/main/docs) directory of the repository, covering:
19
+
20
+ - **Core Concepts** — the two layers, data, scales & axes, options & precedence
21
+ - **Theming** — full variable surface and class lists for plain-CSS/Tailwind restyling
22
+ - **Charts** — LineChart, AreaChart, BarChart, StackChart, DonutChart, Sparkline
23
+ - **Primitives** — Chart/Svg, marks, axes & grid, overlays
24
+ - **Guides** — stacking, curves, accessibility, responsive, interaction, etc..
25
+
26
+ ## Installation
27
+
28
+ Install Flarecharts via your preferred package manager:
29
+
30
+ ```bash
31
+ npm install @faintshadow/flarecharts
32
+ # or
33
+ bun add @faintshadow/flarecharts
34
+ ```
35
+
36
+ ## One Tag or Composed — Your Choice
37
+
38
+ Use a single `<LineChart>` tag for quick implementation:
39
+
40
+ ```svelte
41
+ <LineChart
42
+ xAxis={{ type: 'time' }}
43
+ series={[
44
+ { name: 'Revenue', data: revenue, x: (d) => d.date, y: (d) => d.value },
45
+ { name: 'Costs', data: costs, x: (d) => d.date, y: (d) => d.value }
46
+ ]}
47
+ bands={[{ from: 55, to: 70, label: 'Target' }]}
48
+ crosshair
49
+ />
50
+ ```
51
+
52
+ Or compose your own chart pixel-identically using primitives, using the exact same data shapes and defaults. When you outgrow the one-tag form, you don't have to rewrite anything:
53
+
54
+ ```svelte
55
+ <script lang="ts">
56
+ import { Chart, Svg, Axis, Grid, Line, PlotBand } from 'flarechart';
57
+
58
+ const revenue = [
59
+ { date: new Date(2025, 0, 1), value: 48 },
60
+ { date: new Date(2025, 1, 1), value: 61 }
61
+ // ...
62
+ ];
63
+ </script>
64
+
65
+ <div style="height: 280px">
66
+ <Chart x={{ type: 'time' }} label="Revenue by month">
67
+ <Svg>
68
+ <Grid y />
69
+ <PlotBand from={55} to={70} label="Target" />
70
+ <Line data={revenue} x={(d) => d.date} y={(d) => d.value} />
71
+ <Axis placement="left" />
72
+ <Axis placement="bottom" />
73
+ </Svg>
74
+ </Chart>
75
+ </div>
76
+ ```
77
+
78
+ The chart fills its container (give it a height) and resizes with it. Paint order is markup order.
79
+
80
+ ## Core Concepts
81
+
82
+ - **Two Layers:** **Primitives** (`src/lib/components/`) are composable building blocks you assemble in markup. **Charts** (`src/lib/charts/`) are one-tag wrappers built *only* from Primitives.
83
+ - **Flexible Data Shapes:** Every mark accepts the same `data` shapes (`number[]`, `[x, y][]`, `{ x?, y }[]`, or `T[]` with accessors). `null` / `NaN` values render as gaps, never zeros.
84
+ - **Theming:** Every visual attribute resolves from a CSS custom property with a built-in fallback. Dark mode is just you flipping variables — the library does nothing, by design.
85
+ - **Accessibility:** `<Chart>` renders a `role="group"` container with an aria-label, a visually-hidden data table of every visible series, and arrow-key point navigation.
86
+
87
+ ## Development
88
+
89
+ ```bash
90
+ bun install
91
+ bun run dev # demo app (routes/)
92
+ bun run test # vitest: normalizer, merge, scales, stacking, …
93
+ bun run check # svelte-check, strict
94
+ bun run package # svelte-package + publint
95
+ ```
96
+
97
+ ## Contributing
98
+
99
+ Thank you for considering contributing to Flarecharts! Please review the design rationale in the [Architecture](https://flarecharts.gitbook.io/docs/contributing/architecture) page before opening a pull request.
100
+
101
+ ## License
102
+
103
+ Flarecharts is open-sourced software licensed under the [MIT + Attribution License](https://gitlab.com/FaintShadow/flarecharts/-/blob/main/LICENSE).
@@ -0,0 +1,150 @@
1
+ <script lang="ts" generics="T">
2
+ import Chart from '../components/Chart.svelte';
3
+ import Svg from '../components/Svg.svelte';
4
+ import Axis from '../components/Axis.svelte';
5
+ import Grid from '../components/Grid.svelte';
6
+ import Area from '../components/Area.svelte';
7
+
8
+ import Labels from '../components/Labels.svelte';
9
+ import PlotBand from '../components/PlotBand.svelte';
10
+ import PlotLine from '../components/PlotLine.svelte';
11
+ import Tooltip from '../components/Tooltip.svelte';
12
+ import Crosshair from '../components/Crosshair.svelte';
13
+ import Legend from '../components/Legend.svelte';
14
+ import { resolveSeries, splitAxisOptions } from '../core/options.js';
15
+ import type {
16
+ BandSpec,
17
+ LegendSpec,
18
+ PlotLineSpec,
19
+ PlotOptions,
20
+ SeriesOptions,
21
+ SimpleAxisOptions,
22
+ TooltipSpec
23
+ } from '../core/options.js';
24
+ import { applyResponsive } from '../core/responsive.js';
25
+ import type { ResponsiveRule } from '../core/responsive.js';
26
+ import type { Padding } from '../core/types.js';
27
+
28
+ interface BaseProps {
29
+ series: SeriesOptions<T>[];
30
+ xAxis?: SimpleAxisOptions;
31
+ yAxis?: SimpleAxisOptions;
32
+ bands?: BandSpec[];
33
+ lines?: PlotLineSpec[];
34
+ grid?: boolean;
35
+ crosshair?: boolean;
36
+ tooltip?: boolean | TooltipSpec;
37
+ legend?: boolean | LegendSpec;
38
+ plotOptions?: PlotOptions<T>;
39
+ padding?: Padding;
40
+ label?: string;
41
+ /** Accessible chart description. */
42
+ description?: string;
43
+ }
44
+
45
+ interface Props extends BaseProps {
46
+ responsive?: ResponsiveRule<BaseProps>[];
47
+ class?: string;
48
+ }
49
+
50
+ let {
51
+ series,
52
+ xAxis,
53
+ yAxis,
54
+ bands,
55
+ lines,
56
+ grid = true,
57
+ crosshair = false,
58
+ tooltip = true,
59
+ legend,
60
+ plotOptions,
61
+ padding,
62
+ label = 'Area chart',
63
+ description,
64
+ responsive,
65
+ class: klass = ''
66
+ }: Props = $props();
67
+
68
+ let width = $state(0);
69
+
70
+ const eff = $derived(
71
+ applyResponsive(
72
+ { series, xAxis, yAxis, bands, lines, grid, crosshair, tooltip, legend, plotOptions, padding, label, description },
73
+ responsive,
74
+ width
75
+ )
76
+ );
77
+
78
+ const resolved = $derived(eff.series.map((s) => resolveSeries(eff.plotOptions, s)));
79
+ const xa = $derived(splitAxisOptions(eff.xAxis));
80
+ const ya = $derived(splitAxisOptions(eff.yAxis));
81
+
82
+ const legendOn = $derived(
83
+ eff.legend === undefined ? eff.series.length > 1 : eff.legend !== false
84
+ );
85
+ const legendPos = $derived(
86
+ typeof eff.legend === 'object' && eff.legend ? (eff.legend.position ?? 'bottom') : 'bottom'
87
+ );
88
+ const tooltipOn = $derived(eff.tooltip !== false);
89
+ const tip = $derived(typeof eff.tooltip === 'object' && eff.tooltip ? eff.tooltip : {});
90
+ const pad = $derived({
91
+ ...(legendOn ? (legendPos === 'top' ? { top: 48 } : { bottom: 56 }) : {}),
92
+ ...eff.padding
93
+ });
94
+ </script>
95
+
96
+ <div class="fc-simple fc-area-chart {klass}" bind:clientWidth={width}>
97
+ <Chart x={xa.scale} y={ya.scale} padding={pad} label={eff.label} description={eff.description}>
98
+ <Svg>
99
+ {#if eff.grid}<Grid y />{/if}
100
+ {#each eff.bands ?? [] as band, i (i)}
101
+ <PlotBand axis={band.axis} from={band.from} to={band.to} color={band.color} label={band.label} />
102
+ {/each}
103
+ {#each eff.lines ?? [] as pl, i (i)}
104
+ <PlotLine axis={pl.axis} value={pl.value} color={pl.color} dash={pl.dash} label={pl.label} />
105
+ {/each}
106
+ {#if eff.crosshair}<Crosshair />{/if}
107
+ {#each resolved as s, i (i)}
108
+ <Area
109
+ data={s.data}
110
+ x={s.x}
111
+ y={s.y}
112
+ color={s.color}
113
+ name={s.name}
114
+ description={s.description}
115
+ curve={s.curve}
116
+ strokeWidth={s.strokeWidth}
117
+ fillOpacity={s.fillOpacity}
118
+ stacking={s.stacking}
119
+ stack={s.stack}
120
+ index={i}
121
+ markers={s.markers}
122
+ symbol={s.symbol}
123
+ symbolSize={s.symbolSize}
124
+ />
125
+ {/each}
126
+ {#each resolved as s, i (i)}
127
+ {#if s.labels}
128
+ <Labels data={s.data} x={s.x} y={s.y} />
129
+ {/if}
130
+ {/each}
131
+ {#if xa.visible}
132
+ <Axis placement="bottom" title={xa.display.title} ticks={xa.display.ticks} format={xa.display.format} rotate={xa.display.rotate} />
133
+ {/if}
134
+ {#if ya.visible}
135
+ <Axis placement="left" title={ya.display.title} ticks={ya.display.ticks} format={ya.display.format} rotate={ya.display.rotate} />
136
+ {/if}
137
+ </Svg>
138
+ {#if tooltipOn}
139
+ <Tooltip mode={tip.mode ?? 'bisect-x'} shared={tip.shared ?? true} formatX={tip.formatX} formatY={tip.formatY} />
140
+ {/if}
141
+ {#if legendOn}<Legend position={legendPos} />{/if}
142
+ </Chart>
143
+ </div>
144
+
145
+ <style>
146
+ .fc-simple {
147
+ width: 100%;
148
+ height: 100%;
149
+ }
150
+ </style>
@@ -0,0 +1,60 @@
1
+ import type { BandSpec, LegendSpec, PlotLineSpec, PlotOptions, SeriesOptions, SimpleAxisOptions, TooltipSpec } from '../core/options.js';
2
+ import type { ResponsiveRule } from '../core/responsive.js';
3
+ import type { Padding } from '../core/types.js';
4
+ declare function $$render<T>(): {
5
+ props: {
6
+ series: SeriesOptions<T>[];
7
+ xAxis?: SimpleAxisOptions;
8
+ yAxis?: SimpleAxisOptions;
9
+ bands?: BandSpec[];
10
+ lines?: PlotLineSpec[];
11
+ grid?: boolean;
12
+ crosshair?: boolean;
13
+ tooltip?: boolean | TooltipSpec;
14
+ legend?: boolean | LegendSpec;
15
+ plotOptions?: PlotOptions<T>;
16
+ padding?: Padding;
17
+ label?: string;
18
+ /** Accessible chart description. */
19
+ description?: string;
20
+ } & {
21
+ responsive?: ResponsiveRule<{
22
+ series: SeriesOptions<T>[];
23
+ xAxis?: SimpleAxisOptions;
24
+ yAxis?: SimpleAxisOptions;
25
+ bands?: BandSpec[];
26
+ lines?: PlotLineSpec[];
27
+ grid?: boolean;
28
+ crosshair?: boolean;
29
+ tooltip?: boolean | TooltipSpec;
30
+ legend?: boolean | LegendSpec;
31
+ plotOptions?: PlotOptions<T>;
32
+ padding?: Padding;
33
+ label?: string;
34
+ /** Accessible chart description. */
35
+ description?: string;
36
+ }>[];
37
+ class?: string;
38
+ };
39
+ exports: {};
40
+ bindings: "";
41
+ slots: {};
42
+ events: {};
43
+ };
44
+ declare class __sveltets_Render<T> {
45
+ props(): ReturnType<typeof $$render<T>>['props'];
46
+ events(): ReturnType<typeof $$render<T>>['events'];
47
+ slots(): ReturnType<typeof $$render<T>>['slots'];
48
+ bindings(): "";
49
+ exports(): {};
50
+ }
51
+ interface $$IsomorphicComponent {
52
+ new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
53
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
54
+ } & ReturnType<__sveltets_Render<T>['exports']>;
55
+ <T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
56
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
57
+ }
58
+ declare const AreaChart: $$IsomorphicComponent;
59
+ type AreaChart<T> = InstanceType<typeof AreaChart<T>>;
60
+ export default AreaChart;
@@ -0,0 +1,142 @@
1
+ <script lang="ts" generics="T">
2
+ import Chart from '../components/Chart.svelte';
3
+ import Svg from '../components/Svg.svelte';
4
+ import Axis from '../components/Axis.svelte';
5
+ import Grid from '../components/Grid.svelte';
6
+ import Bars from '../components/Bars.svelte';
7
+ import Labels from '../components/Labels.svelte';
8
+ import PlotBand from '../components/PlotBand.svelte';
9
+ import PlotLine from '../components/PlotLine.svelte';
10
+ import Tooltip from '../components/Tooltip.svelte';
11
+ import Legend from '../components/Legend.svelte';
12
+ import { resolveSeries, splitAxisOptions } from '../core/options.js';
13
+ import type {
14
+ BandSpec,
15
+ LegendSpec,
16
+ PlotLineSpec,
17
+ PlotOptions,
18
+ SeriesOptions,
19
+ SimpleAxisOptions,
20
+ TooltipSpec
21
+ } from '../core/options.js';
22
+ import { applyResponsive } from '../core/responsive.js';
23
+ import type { ResponsiveRule } from '../core/responsive.js';
24
+ import type { Padding } from '../core/types.js';
25
+
26
+ interface BaseProps {
27
+ series: SeriesOptions<T>[];
28
+ xAxis?: SimpleAxisOptions;
29
+ yAxis?: SimpleAxisOptions;
30
+ bands?: BandSpec[];
31
+ lines?: PlotLineSpec[];
32
+ grid?: boolean;
33
+ tooltip?: boolean | TooltipSpec;
34
+ legend?: boolean | LegendSpec;
35
+ plotOptions?: PlotOptions<T>;
36
+ padding?: Padding;
37
+ label?: string;
38
+ /** Accessible chart description. */
39
+ description?: string;
40
+ }
41
+
42
+ interface Props extends BaseProps {
43
+ responsive?: ResponsiveRule<BaseProps>[];
44
+ class?: string;
45
+ }
46
+
47
+ let {
48
+ series,
49
+ xAxis,
50
+ yAxis,
51
+ bands,
52
+ lines,
53
+ grid = true,
54
+ tooltip = true,
55
+ legend,
56
+ plotOptions,
57
+ padding,
58
+ label = 'Bar chart',
59
+ description,
60
+ responsive,
61
+ class: klass = ''
62
+ }: Props = $props();
63
+
64
+ let width = $state(0);
65
+
66
+ const eff = $derived(
67
+ applyResponsive(
68
+ { series, xAxis, yAxis, bands, lines, grid, tooltip, legend, plotOptions, padding, label, description },
69
+ responsive,
70
+ width
71
+ )
72
+ );
73
+
74
+ const resolved = $derived(eff.series.map((s) => resolveSeries(eff.plotOptions, s)));
75
+ const xa = $derived(splitAxisOptions(eff.xAxis));
76
+ const ya = $derived(splitAxisOptions(eff.yAxis));
77
+
78
+ const legendOn = $derived(
79
+ eff.legend === undefined ? eff.series.length > 1 : eff.legend !== false
80
+ );
81
+ const legendPos = $derived(
82
+ typeof eff.legend === 'object' && eff.legend ? (eff.legend.position ?? 'bottom') : 'bottom'
83
+ );
84
+ const tooltipOn = $derived(eff.tooltip !== false);
85
+ const tip = $derived(typeof eff.tooltip === 'object' && eff.tooltip ? eff.tooltip : {});
86
+ const pad = $derived({
87
+ ...(legendOn ? (legendPos === 'top' ? { top: 48 } : { bottom: 56 }) : {}),
88
+ ...eff.padding
89
+ });
90
+ </script>
91
+
92
+ <div class="fc-simple fc-bar-chart {klass}" bind:clientWidth={width}>
93
+ <Chart x={xa.scale} y={ya.scale} padding={pad} label={eff.label} description={eff.description}>
94
+ <Svg>
95
+ {#if eff.grid}<Grid y />{/if}
96
+ {#each eff.bands ?? [] as band, i (i)}
97
+ <PlotBand axis={band.axis} from={band.from} to={band.to} color={band.color} label={band.label} />
98
+ {/each}
99
+ {#each resolved as s, i (i)}
100
+ <Bars
101
+ data={s.data}
102
+ x={s.x}
103
+ y={s.y}
104
+ color={s.color}
105
+ colorFor={s.colorFor}
106
+ name={s.name}
107
+ description={s.description}
108
+ stacking={s.stacking}
109
+ stack={s.stack}
110
+ barPadding={s.barPadding}
111
+ rx={s.rx}
112
+ index={i}
113
+ />
114
+ {/each}
115
+ {#each eff.lines ?? [] as pl, i (i)}
116
+ <PlotLine axis={pl.axis} value={pl.value} color={pl.color} dash={pl.dash} label={pl.label} />
117
+ {/each}
118
+ {#each resolved as s, i (i)}
119
+ {#if s.labels}
120
+ <Labels data={s.data} x={s.x} y={s.y} />
121
+ {/if}
122
+ {/each}
123
+ {#if xa.visible}
124
+ <Axis placement="bottom" title={xa.display.title} ticks={xa.display.ticks} format={xa.display.format} rotate={xa.display.rotate} />
125
+ {/if}
126
+ {#if ya.visible}
127
+ <Axis placement="left" title={ya.display.title} ticks={ya.display.ticks} format={ya.display.format} rotate={ya.display.rotate} />
128
+ {/if}
129
+ </Svg>
130
+ {#if tooltipOn}
131
+ <Tooltip mode={tip.mode ?? 'band'} shared={tip.shared ?? true} formatX={tip.formatX} formatY={tip.formatY} />
132
+ {/if}
133
+ {#if legendOn}<Legend position={legendPos} />{/if}
134
+ </Chart>
135
+ </div>
136
+
137
+ <style>
138
+ .fc-simple {
139
+ width: 100%;
140
+ height: 100%;
141
+ }
142
+ </style>
@@ -0,0 +1,58 @@
1
+ import type { BandSpec, LegendSpec, PlotLineSpec, PlotOptions, SeriesOptions, SimpleAxisOptions, TooltipSpec } from '../core/options.js';
2
+ import type { ResponsiveRule } from '../core/responsive.js';
3
+ import type { Padding } from '../core/types.js';
4
+ declare function $$render<T>(): {
5
+ props: {
6
+ series: SeriesOptions<T>[];
7
+ xAxis?: SimpleAxisOptions;
8
+ yAxis?: SimpleAxisOptions;
9
+ bands?: BandSpec[];
10
+ lines?: PlotLineSpec[];
11
+ grid?: boolean;
12
+ tooltip?: boolean | TooltipSpec;
13
+ legend?: boolean | LegendSpec;
14
+ plotOptions?: PlotOptions<T>;
15
+ padding?: Padding;
16
+ label?: string;
17
+ /** Accessible chart description. */
18
+ description?: string;
19
+ } & {
20
+ responsive?: ResponsiveRule<{
21
+ series: SeriesOptions<T>[];
22
+ xAxis?: SimpleAxisOptions;
23
+ yAxis?: SimpleAxisOptions;
24
+ bands?: BandSpec[];
25
+ lines?: PlotLineSpec[];
26
+ grid?: boolean;
27
+ tooltip?: boolean | TooltipSpec;
28
+ legend?: boolean | LegendSpec;
29
+ plotOptions?: PlotOptions<T>;
30
+ padding?: Padding;
31
+ label?: string;
32
+ /** Accessible chart description. */
33
+ description?: string;
34
+ }>[];
35
+ class?: string;
36
+ };
37
+ exports: {};
38
+ bindings: "";
39
+ slots: {};
40
+ events: {};
41
+ };
42
+ declare class __sveltets_Render<T> {
43
+ props(): ReturnType<typeof $$render<T>>['props'];
44
+ events(): ReturnType<typeof $$render<T>>['events'];
45
+ slots(): ReturnType<typeof $$render<T>>['slots'];
46
+ bindings(): "";
47
+ exports(): {};
48
+ }
49
+ interface $$IsomorphicComponent {
50
+ new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
51
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
52
+ } & ReturnType<__sveltets_Render<T>['exports']>;
53
+ <T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
54
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
55
+ }
56
+ declare const BarChart: $$IsomorphicComponent;
57
+ type BarChart<T> = InstanceType<typeof BarChart<T>>;
58
+ export default BarChart;
@@ -0,0 +1,138 @@
1
+ <script lang="ts" generics="T">
2
+ import Chart from '../components/Chart.svelte';
3
+ import Svg from '../components/Svg.svelte';
4
+ import Axis from '../components/Axis.svelte';
5
+ import Grid from '../components/Grid.svelte';
6
+ import Box from '../components/Box.svelte';
7
+ import PlotBand from '../components/PlotBand.svelte';
8
+ import PlotLine from '../components/PlotLine.svelte';
9
+ import Tooltip from '../components/Tooltip.svelte';
10
+ import Legend from '../components/Legend.svelte';
11
+ import { resolveSeries, splitAxisOptions } from '../core/options.js';
12
+ import type {
13
+ BandSpec,
14
+ LegendSpec,
15
+ PlotLineSpec,
16
+ PlotOptions,
17
+ SeriesOptions,
18
+ SimpleAxisOptions,
19
+ TooltipSpec
20
+ } from '../core/options.js';
21
+ import { applyResponsive } from '../core/responsive.js';
22
+ import type { ResponsiveRule } from '../core/responsive.js';
23
+ import type { Padding } from '../core/types.js';
24
+
25
+ interface BaseProps {
26
+ series: SeriesOptions<T>[];
27
+ xAxis?: SimpleAxisOptions;
28
+ yAxis?: SimpleAxisOptions;
29
+ bands?: BandSpec[];
30
+ lines?: PlotLineSpec[];
31
+ grid?: boolean;
32
+ tooltip?: boolean | TooltipSpec;
33
+ legend?: boolean | LegendSpec;
34
+ plotOptions?: PlotOptions<T>;
35
+ padding?: Padding;
36
+ label?: string;
37
+ description?: string;
38
+ }
39
+
40
+ interface Props extends BaseProps {
41
+ responsive?: ResponsiveRule<BaseProps>[];
42
+ class?: string;
43
+ }
44
+
45
+ let {
46
+ series,
47
+ xAxis,
48
+ yAxis,
49
+ bands,
50
+ lines,
51
+ grid = true,
52
+ tooltip = true,
53
+ legend,
54
+ plotOptions,
55
+ padding,
56
+ label = 'Box plot',
57
+ description,
58
+ responsive,
59
+ class: klass = ''
60
+ }: Props = $props();
61
+
62
+ let width = $state(0);
63
+
64
+ const eff = $derived(
65
+ applyResponsive(
66
+ { series, xAxis, yAxis, bands, lines, grid, tooltip, legend, plotOptions, padding, label, description },
67
+ responsive,
68
+ width
69
+ )
70
+ );
71
+
72
+ const resolved = $derived(eff.series.map((s) => resolveSeries(eff.plotOptions, s)));
73
+ const xa = $derived(splitAxisOptions(eff.xAxis));
74
+ const ya = $derived(splitAxisOptions(eff.yAxis));
75
+
76
+ const legendOn = $derived(eff.legend === undefined ? eff.series.length > 1 : eff.legend !== false);
77
+ const legendPos = $derived(
78
+ typeof eff.legend === 'object' && eff.legend ? (eff.legend.position ?? 'bottom') : 'bottom'
79
+ );
80
+ const tooltipOn = $derived(eff.tooltip !== false);
81
+ const tip = $derived(typeof eff.tooltip === 'object' && eff.tooltip ? eff.tooltip : {});
82
+ const pad = $derived({
83
+ ...(legendOn ? (legendPos === 'top' ? { top: 48 } : { bottom: 56 }) : {}),
84
+ ...eff.padding
85
+ });
86
+ </script>
87
+
88
+ <div class="fc-simple fc-box-chart {klass}" bind:clientWidth={width}>
89
+ <Chart x={xa.scale} y={ya.scale} padding={pad} label={eff.label} description={eff.description}>
90
+ <Svg>
91
+ {#if eff.grid}<Grid y />{/if}
92
+ {#each eff.bands ?? [] as band, i (i)}
93
+ <PlotBand axis={band.axis} from={band.from} to={band.to} color={band.color} label={band.label} />
94
+ {/each}
95
+ {#each resolved as s, i (i)}
96
+ <Box
97
+ data={s.data}
98
+ x={s.x}
99
+ low={s.low}
100
+ q1={s.q1}
101
+ median={s.median}
102
+ q3={s.q3}
103
+ high={s.high}
104
+ outliers={s.outliers}
105
+ samples={s.samples}
106
+ whisker={s.whisker}
107
+ whiskerK={s.whiskerK}
108
+ color={s.color}
109
+ colorFor={s.colorFor}
110
+ name={s.name}
111
+ description={s.description}
112
+ boxPadding={s.boxPadding}
113
+ index={i}
114
+ />
115
+ {/each}
116
+ {#each eff.lines ?? [] as pl, i (i)}
117
+ <PlotLine axis={pl.axis} value={pl.value} color={pl.color} dash={pl.dash} label={pl.label} />
118
+ {/each}
119
+ {#if xa.visible}
120
+ <Axis placement="bottom" title={xa.display.title} ticks={xa.display.ticks} format={xa.display.format} rotate={xa.display.rotate} />
121
+ {/if}
122
+ {#if ya.visible}
123
+ <Axis placement="left" title={ya.display.title} ticks={ya.display.ticks} format={ya.display.format} rotate={ya.display.rotate} />
124
+ {/if}
125
+ </Svg>
126
+ {#if tooltipOn}
127
+ <Tooltip mode={tip.mode ?? 'band'} shared={tip.shared ?? true} formatX={tip.formatX} formatY={tip.formatY} />
128
+ {/if}
129
+ {#if legendOn}<Legend position={legendPos} />{/if}
130
+ </Chart>
131
+ </div>
132
+
133
+ <style>
134
+ .fc-simple {
135
+ width: 100%;
136
+ height: 100%;
137
+ }
138
+ </style>