nuxt-charts 3.0.0-beta.4 → 3.0.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.
- package/README.md +24 -0
- package/dist/module.json +1 -1
- package/dist/runtime/assets/theme.css +1 -1
- package/dist/runtime/components/DonutChart.vue +1 -1
- package/dist/runtime/components/FunnelChart.vue +2 -2
- package/dist/runtime/components/RadialBarChart.vue +25 -3
- package/dist/runtime/components/SankeyChart.vue +3 -3
- package/dist/runtime/components/internal/CartesianFrame.vue +1 -0
- package/dist/runtime/components/internal/ChartLegend.vue.d.ts +1 -1
- package/dist/runtime/types/shared.d.ts +5 -0
- package/dist/runtime/utils/categories.d.ts +1 -1
- package/dist/runtime/utils/categories.js +2 -2
- package/dist/runtime/utils/theme.js +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,11 @@ Beautiful chart components for Nuxt — Area, Bar, Line, Donut, Bubble, Radar, R
|
|
|
4
4
|
|
|
5
5
|
Powered by [vccs](https://vue-charts.com) (Vue port of Recharts). Drop-in config-prop API from nuxt-charts v2.
|
|
6
6
|
|
|
7
|
+
Nuxt UI v4 is a first-class, zero-config integration: chart series, surfaces,
|
|
8
|
+
text, borders, radius, typography, and dark mode inherit its semantic design
|
|
9
|
+
tokens. Nuxt UI is not a dependency; every token has a standalone fallback, so
|
|
10
|
+
the same components work in any Nuxt project.
|
|
11
|
+
|
|
7
12
|
## Install
|
|
8
13
|
|
|
9
14
|
```bash
|
|
@@ -179,6 +184,25 @@ evenly (preserving both endpoints) and emit one development warning. Override
|
|
|
179
184
|
this with `maxDataPoints`, but use pre-aggregation for genuinely dense data:
|
|
180
185
|
SVG creates DOM work per mark, so raising the limit can block the UI.
|
|
181
186
|
|
|
187
|
+
## Theming
|
|
188
|
+
|
|
189
|
+
With Nuxt UI, no chart-specific setup is required. Categories without an
|
|
190
|
+
explicit `color` use `--ui-primary`, `--ui-secondary`, `--ui-success`,
|
|
191
|
+
`--ui-info`, `--ui-warning`, and `--ui-error`; chart chrome follows Nuxt UI's
|
|
192
|
+
background, text, border, radius, and font tokens.
|
|
193
|
+
|
|
194
|
+
Without Nuxt UI, built-in light and dark defaults are used. Customize globally
|
|
195
|
+
with `--vc-*` variables (or the backwards-compatible `--chart-color-0` through
|
|
196
|
+
`--chart-color-7`), and customize one chart with the `theme` prop:
|
|
197
|
+
|
|
198
|
+
```vue
|
|
199
|
+
<LineChart
|
|
200
|
+
:data="data"
|
|
201
|
+
:categories="categories"
|
|
202
|
+
:theme="{ colors: ['var(--brand)', 'var(--accent)'] }"
|
|
203
|
+
/>
|
|
204
|
+
```
|
|
205
|
+
|
|
182
206
|
## Auto-imported enums & types
|
|
183
207
|
|
|
184
208
|
- Enums: `CurveType`, `LegendPosition`, `Orientation`, `DonutType`
|
package/dist/module.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer vue-chrts{.vue-chrts :focus,.vue-chrts :focus-visible,.vue-chrts:focus,.vue-chrts:focus-visible{outline:none}.vue-chrts{--vc-grid-color:var(--ui-border,var(--border,oklch(0.922 0 0)));--vc-grid-dash:3 3;--vc-grid-width:1px;--vc-axis-line-color:var(--ui-border,var(--border,oklch(0.922 0 0)));--vc-axis-line-width:1px;--vc-surface-bg:var(--ui-bg,var(--background,oklch(1 0 0)));--vc-reference-line-color:var(--ui-text-muted,var(--muted-foreground,oklch(0.556 0 0)));--vc-candle-up:var(--ui-success,oklch(0.696 0.17 162.48));--vc-candle-down:var(--ui-error,oklch(0.637 0.237 25.331));--vc-bg-pattern-color:var(--vc-grid-color);--vc-legend-size:0.75rem;--vc-legend-weight:400;--vc-tick-color:var(--ui-text-muted,var(--muted-foreground,oklch(0.556 0 0)));--vc-tick-size:var(--vc-legend-size);--vc-tick-weight:var(--vc-legend-weight);--vc-axis-label-color:var(--ui-text-highlighted,var(--foreground,oklch(0.205 0 0)));--vc-axis-label-size:var(--vc-legend-size);--vc-axis-label-weight:500}.vue-chrts .v-charts-cartesian-axis .v-charts-label{fill:var(--vc-axis-label-color);font-size:var(--vc-axis-label-size);font-weight:var(--vc-axis-label-weight)}.vue-chrts{--vc-legend-gap:0.75rem;--vc-legend-inset:0.75rem;--vc-legend-color:var(--ui-text-muted,var(--muted-foreground,oklch(0.556 0 0)));--vc-legend-dot-size:0.5rem;--vc-funnel-value-size:var(--vc-legend-size);--vc-funnel-value-color:var(--vc-axis-label-color);--vc-funnel-value-weight:600;--vc-funnel-label-color:var(--vc-tick-color);--vc-funnel-label-weight:500;--vc-funnel-badge-bg:var(--vc-surface-bg);--vc-funnel-badge-color:var(--vc-tick-color);--vc-funnel-badge-border:var(--vc-axis-line-color);--vc-funnel-badge-weight:600;--vc-funnel-badge-opacity:0.82;--vc-hover-fill:color-mix(in oklab,var(--ui-text-highlighted,var(--foreground,oklch(0.205 0 0))) 6%,transparent);--vc-hover-stroke:transparent;--vc-hover-radius:6px;--vc-tooltip-bg:var(--ui-bg,var(--popover,oklch(1 0 0)));--vc-tooltip-fg:var(--ui-text-highlighted,var(--popover-foreground,oklch(0.205 0 0)));--vc-tooltip-muted:var(--ui-text-muted,var(--muted-foreground,oklch(0.556 0 0)));--vc-tooltip-border:var(--ui-border,var(--border,oklch(0.922 0 0)));--vc-tooltip-radius:0.5rem;--vc-tooltip-padding:0.375rem 0.625rem;--vc-tooltip-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1)}.vue-chrts .v-charts-xAxis .v-charts-cartesian-axis-tick-value{fill:var(--vc-x-tick-color,var(--vc-tick-color));font-size:var(--vc-x-tick-size,var(--vc-tick-size));font-weight:var(--vc-x-tick-weight,var(--vc-tick-weight))}.vue-chrts .v-charts-yAxis .v-charts-cartesian-axis-tick-value{fill:var(--vc-y-tick-color,var(--vc-tick-color));font-size:var(--vc-y-tick-size,var(--vc-tick-size));font-weight:var(--vc-y-tick-weight,var(--vc-tick-weight))}.vue-chrts .v-charts-polar-angle-axis-tick-value,.vue-chrts .v-charts-polar-radius-axis-tick-value{fill:var(--vc-tick-color);font-size:var(--vc-tick-size);font-weight:var(--vc-tick-weight)}.vue-chrts.vc-dash-animated .v-charts-area-curve,.vue-chrts.vc-dash-animated .v-charts-line-curve{animation:vc-dash-march 1s linear infinite}@keyframes vc-dash-march{to{stroke-dashoffset:-6}}@media (prefers-reduced-motion:reduce){.vue-chrts.vc-dash-animated .v-charts-area-curve,.vue-chrts.vc-dash-animated .v-charts-line-curve{animation:none}}.vue-chrts:is(.dark,[data-theme=dark],.dark *,[data-theme=dark] *),:is(.dark,[data-theme=dark]) .vue-chrts{--vc-grid-color:var(--ui-border,var(--border,oklch(0.269 0 0)));--vc-axis-line-color:var(--ui-border,var(--border,oklch(0.269 0 0)));--vc-surface-bg:var(--ui-bg,var(--background,oklch(0.145 0 0)));--vc-tick-color:var(--ui-text-muted,var(--muted-foreground,oklch(0.708 0 0)));--vc-axis-label-color:var(--ui-text-highlighted,var(--foreground,oklch(0.985 0 0)));--vc-legend-color:var(--ui-text-muted,var(--muted-foreground,oklch(0.708 0 0)));--vc-hover-fill:color-mix(in oklab,var(--ui-text-highlighted,oklch(0.985 0 0)) 8%,transparent);--vc-tooltip-bg:var(--ui-bg,var(--popover,oklch(0.205 0 0)));--vc-tooltip-fg:var(--ui-text-highlighted,var(--popover-foreground,oklch(0.985 0 0)));--vc-tooltip-muted:var(--ui-text-muted,var(--muted-foreground,oklch(0.708 0 0)));--vc-tooltip-border:var(--ui-border,var(--border,oklch(0.269 0 0)))}}
|
|
1
|
+
@layer vue-chrts{.vue-chrts :focus,.vue-chrts :focus-visible,.vue-chrts:focus,.vue-chrts:focus-visible{outline:none}.vue-chrts{--vc-font-family:var(--font-sans,ui-sans-serif,system-ui,sans-serif);--vc-series-0:var(--chart-color-0,var(--ui-primary,oklch(0.63 0.18 155)));--vc-series-1:var(--chart-color-1,var(--ui-secondary,oklch(0.62 0.19 255)));--vc-series-2:var(--chart-color-2,var(--ui-success,oklch(0.64 0.17 145)));--vc-series-3:var(--chart-color-3,var(--ui-info,oklch(0.68 0.15 235)));--vc-series-4:var(--chart-color-4,var(--ui-warning,oklch(0.75 0.16 75)));--vc-series-5:var(--chart-color-5,var(--ui-error,oklch(0.63 0.22 25)));--vc-series-6:var(--chart-color-6,oklch(0.66 0.18 305));--vc-series-7:var(--chart-color-7,oklch(0.7 0.15 195));font-family:var(--vc-font-family);--vc-grid-color:var(--ui-border,var(--border,oklch(0.922 0 0)));--vc-grid-dash:3 3;--vc-grid-width:1px;--vc-axis-line-color:var(--ui-border,var(--border,oklch(0.922 0 0)));--vc-axis-line-width:1px;--vc-surface-bg:var(--ui-bg,var(--background,oklch(1 0 0)));--vc-reference-line-color:var(--ui-text-muted,var(--muted-foreground,oklch(0.556 0 0)));--vc-candle-up:var(--ui-success,oklch(0.696 0.17 162.48));--vc-candle-down:var(--ui-error,oklch(0.637 0.237 25.331));--vc-bg-pattern-color:var(--vc-grid-color);--vc-legend-size:0.75rem;--vc-legend-weight:400;--vc-tick-color:var(--ui-text-muted,var(--muted-foreground,oklch(0.556 0 0)));--vc-tick-size:var(--vc-legend-size);--vc-tick-weight:var(--vc-legend-weight);--vc-axis-label-color:var(--ui-text-highlighted,var(--foreground,oklch(0.205 0 0)));--vc-axis-label-size:var(--vc-legend-size);--vc-axis-label-weight:500}.vue-chrts .v-charts-cartesian-axis .v-charts-label{fill:var(--vc-axis-label-color);font-size:var(--vc-axis-label-size);font-weight:var(--vc-axis-label-weight)}.vue-chrts{--vc-legend-gap:0.75rem;--vc-legend-inset:0.75rem;--vc-legend-color:var(--ui-text-muted,var(--muted-foreground,oklch(0.556 0 0)));--vc-legend-dot-size:0.5rem;--vc-funnel-value-size:var(--vc-legend-size);--vc-funnel-value-color:var(--vc-axis-label-color);--vc-funnel-value-weight:600;--vc-funnel-label-color:var(--vc-tick-color);--vc-funnel-label-weight:500;--vc-funnel-badge-bg:var(--vc-surface-bg);--vc-funnel-badge-color:var(--vc-tick-color);--vc-funnel-badge-border:var(--vc-axis-line-color);--vc-funnel-badge-weight:600;--vc-funnel-badge-opacity:0.82;--vc-hover-fill:color-mix(in oklab,var(--ui-text-highlighted,var(--foreground,oklch(0.205 0 0))) 6%,transparent);--vc-hover-stroke:transparent;--vc-hover-radius:6px;--vc-tooltip-bg:var(--ui-bg-elevated,var(--popover,oklch(1 0 0)));--vc-tooltip-fg:var(--ui-text-highlighted,var(--popover-foreground,oklch(0.205 0 0)));--vc-tooltip-muted:var(--ui-text-muted,var(--muted-foreground,oklch(0.556 0 0)));--vc-tooltip-border:var(--ui-border,var(--border,oklch(0.922 0 0)));--vc-tooltip-radius:var(--ui-radius,0.5rem);--vc-tooltip-padding:0.375rem 0.625rem;--vc-tooltip-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1)}.vue-chrts .v-charts-xAxis .v-charts-cartesian-axis-tick-value{fill:var(--vc-x-tick-color,var(--vc-tick-color));font-size:var(--vc-x-tick-size,var(--vc-tick-size));font-weight:var(--vc-x-tick-weight,var(--vc-tick-weight))}.vue-chrts .v-charts-yAxis .v-charts-cartesian-axis-tick-value{fill:var(--vc-y-tick-color,var(--vc-tick-color));font-size:var(--vc-y-tick-size,var(--vc-tick-size));font-weight:var(--vc-y-tick-weight,var(--vc-tick-weight))}.vue-chrts .v-charts-polar-angle-axis-tick-value,.vue-chrts .v-charts-polar-radius-axis-tick-value{fill:var(--vc-tick-color);font-size:var(--vc-tick-size);font-weight:var(--vc-tick-weight)}.vue-chrts.vc-dash-animated .v-charts-area-curve,.vue-chrts.vc-dash-animated .v-charts-line-curve{animation:vc-dash-march 1s linear infinite}@keyframes vc-dash-march{to{stroke-dashoffset:-6}}@media (prefers-reduced-motion:reduce){.vue-chrts.vc-dash-animated .v-charts-area-curve,.vue-chrts.vc-dash-animated .v-charts-line-curve{animation:none}}.vue-chrts:is(.dark,[data-theme=dark],.dark *,[data-theme=dark] *),:is(.dark,[data-theme=dark]) .vue-chrts{--vc-grid-color:var(--ui-border,var(--border,oklch(0.269 0 0)));--vc-axis-line-color:var(--ui-border,var(--border,oklch(0.269 0 0)));--vc-surface-bg:var(--ui-bg,var(--background,oklch(0.145 0 0)));--vc-tick-color:var(--ui-text-muted,var(--muted-foreground,oklch(0.708 0 0)));--vc-axis-label-color:var(--ui-text-highlighted,var(--foreground,oklch(0.985 0 0)));--vc-legend-color:var(--ui-text-muted,var(--muted-foreground,oklch(0.708 0 0)));--vc-hover-fill:color-mix(in oklab,var(--ui-text-highlighted,oklch(0.985 0 0)) 8%,transparent);--vc-tooltip-bg:var(--ui-bg-elevated,var(--popover,oklch(0.205 0 0)));--vc-tooltip-fg:var(--ui-text-highlighted,var(--popover-foreground,oklch(0.985 0 0)));--vc-tooltip-muted:var(--ui-text-muted,var(--muted-foreground,oklch(0.708 0 0)));--vc-tooltip-border:var(--ui-border,var(--border,oklch(0.269 0 0)))}}
|
|
@@ -60,7 +60,7 @@ const segments = computed(() => {
|
|
|
60
60
|
warnDataLimit("DonutChart", normalized.length, limit);
|
|
61
61
|
const values = sampleData(normalized, limit);
|
|
62
62
|
return values.map(({ row, value, sourceIndex, name }) => {
|
|
63
|
-
const color = cats[sourceIndex]?.color ?? `var(--
|
|
63
|
+
const color = cats[sourceIndex]?.color ?? `var(--vc-series-${sourceIndex % 8})`;
|
|
64
64
|
return {
|
|
65
65
|
...row && typeof row === "object" ? row : {},
|
|
66
66
|
name,
|
|
@@ -64,8 +64,8 @@ const stages = computed(() => {
|
|
|
64
64
|
name,
|
|
65
65
|
value,
|
|
66
66
|
formattedValue: props.valueFormatter?.(value, sourceIndex),
|
|
67
|
-
fill: cats[sourceIndex]?.color ?? `var(--
|
|
68
|
-
color: cats[sourceIndex]?.color ?? `var(--
|
|
67
|
+
fill: cats[sourceIndex]?.color ?? `var(--vc-series-${sourceIndex % 8})`,
|
|
68
|
+
color: cats[sourceIndex]?.color ?? `var(--vc-series-${sourceIndex % 8})`
|
|
69
69
|
}));
|
|
70
70
|
});
|
|
71
71
|
const accessibleRows = computed(() => stages.value.map((stage) => ({ label: stage.name, values: [{ label: "Value", value: stage.formattedValue ?? stage.value }] })));
|
|
@@ -16,7 +16,7 @@ import PolarCenterSync from "./internal/PolarCenterSync";
|
|
|
16
16
|
import { categoriesToSeries } from "../utils/categories";
|
|
17
17
|
import { legendPositionToLegendProps, resolveLegendWrapperStyle } from "../utils/legend";
|
|
18
18
|
import { toCssProperties } from "../utils/style";
|
|
19
|
-
import { themeToVars } from "../utils/theme";
|
|
19
|
+
import { resolveHoverVisible, themeToVars } from "../utils/theme";
|
|
20
20
|
import { DEFAULT_MAX_DATA_POINTS, normalizeNamedValues, sampleData, warnDataLimit } from "../utils/data";
|
|
21
21
|
const props = defineProps({
|
|
22
22
|
data: { type: Array, required: true },
|
|
@@ -60,7 +60,7 @@ const bars = computed(() => {
|
|
|
60
60
|
...row && typeof row === "object" ? row : {},
|
|
61
61
|
name,
|
|
62
62
|
value,
|
|
63
|
-
fill: cats[sourceIndex]?.color ?? `var(--
|
|
63
|
+
fill: cats[sourceIndex]?.color ?? `var(--vc-series-${sourceIndex % 8})`
|
|
64
64
|
}));
|
|
65
65
|
});
|
|
66
66
|
const angles = computed(() => {
|
|
@@ -74,6 +74,24 @@ const tooltipContent = computed(
|
|
|
74
74
|
() => tooltipContentFor(props.tooltipVariant, props.tooltipRoundness, props.tooltipTitleFormatter)
|
|
75
75
|
);
|
|
76
76
|
const accessibleRows = computed(() => bars.value.map((bar) => ({ label: bar.name, values: [{ label: "Value", value: bar.value }] })));
|
|
77
|
+
const hiddenTooltipContent = () => null;
|
|
78
|
+
const radiusInPixels = (radius, fallback) => {
|
|
79
|
+
if (typeof radius === "number") return radius;
|
|
80
|
+
const percentage = Number.parseFloat(radius);
|
|
81
|
+
return Number.isFinite(percentage) ? props.height / 2 * percentage / 100 : fallback;
|
|
82
|
+
};
|
|
83
|
+
const hoverStrokeWidth = computed(() => {
|
|
84
|
+
const outer = radiusInPixels(props.outerRadius ?? "100%", props.height / 2);
|
|
85
|
+
const inner = radiusInPixels(props.innerRadius ?? "30%", props.height * 0.15);
|
|
86
|
+
return Math.max((outer - inner) / Math.max(bars.value.length, 1) * 0.9, 1);
|
|
87
|
+
});
|
|
88
|
+
const cursor = computed(
|
|
89
|
+
() => resolveHoverVisible(props.theme) ? {
|
|
90
|
+
fill: "none",
|
|
91
|
+
stroke: "var(--vc-hover-fill)",
|
|
92
|
+
strokeWidth: hoverStrokeWidth.value
|
|
93
|
+
} : false
|
|
94
|
+
);
|
|
77
95
|
const legend = computed(() => legendPositionToLegendProps(props.legendPosition));
|
|
78
96
|
const legendWrapperStyle = computed(
|
|
79
97
|
() => resolveLegendWrapperStyle(props.legendPosition, toCssProperties(props.legendStyle))
|
|
@@ -113,7 +131,11 @@ const onCenter = (next) => {
|
|
|
113
131
|
:is-animation-active="duration !== void 0 && duration !== 0"
|
|
114
132
|
:transition="{ duration: (duration ?? 400) / 1e3, ease: 'easeOut' }"
|
|
115
133
|
/>
|
|
116
|
-
<Tooltip
|
|
134
|
+
<Tooltip
|
|
135
|
+
:content="hideTooltip ? hiddenTooltipContent : tooltipContent"
|
|
136
|
+
:cursor="cursor"
|
|
137
|
+
:is-animation-active="false"
|
|
138
|
+
/>
|
|
117
139
|
<Legend
|
|
118
140
|
v-if="!hideLegend"
|
|
119
141
|
:align="legend.align"
|
|
@@ -55,11 +55,11 @@ const nodeLabel = (node) => {
|
|
|
55
55
|
const input = node;
|
|
56
56
|
return props.label?.(input) ?? String(input.name ?? input.id ?? "");
|
|
57
57
|
};
|
|
58
|
-
const resolvedNodeColor = (node) => props.nodeColor?.(node) ?? "var(--
|
|
58
|
+
const resolvedNodeColor = (node) => props.nodeColor?.(node) ?? "var(--vc-series-0)";
|
|
59
59
|
const resolvedLinkColor = (link) => {
|
|
60
60
|
const layoutLink = link;
|
|
61
61
|
const inputLink = layoutLink.__source === void 0 ? layoutLink : { ...layoutLink, source: layoutLink.__source };
|
|
62
|
-
return props.linkColor?.(inputLink) ?? "var(--
|
|
62
|
+
return props.linkColor?.(inputLink) ?? "var(--vc-series-0)";
|
|
63
63
|
};
|
|
64
64
|
function handleMouseEnter(item, type) {
|
|
65
65
|
activeColor.value = type === "node" ? resolvedNodeColor(item) : resolvedLinkColor(item);
|
|
@@ -135,7 +135,7 @@ const accessibleRows = computed(() => chartData.value.links.map((link) => ({
|
|
|
135
135
|
:width="nodeProps.width"
|
|
136
136
|
:height="nodeProps.height"
|
|
137
137
|
:fill="resolvedNodeColor(nodeProps.payload)"
|
|
138
|
-
stroke="var(--vc-surface, #fff)"
|
|
138
|
+
stroke="var(--vc-surface-bg, #fff)"
|
|
139
139
|
/>
|
|
140
140
|
<text
|
|
141
141
|
:x="nodeProps.payload.depth === 0 ? nodeProps.x - 8 : nodeProps.x + nodeProps.width + 8"
|
|
@@ -296,6 +296,7 @@ const resolvedYAxes = computed(() => {
|
|
|
296
296
|
v-if="showXGrid || showYGrid"
|
|
297
297
|
:horizontal="showYGrid"
|
|
298
298
|
:vertical="showXGrid"
|
|
299
|
+
:sync-with-ticks="true"
|
|
299
300
|
:stroke="gridStroke"
|
|
300
301
|
stroke-dasharray="var(--vc-grid-dash)"
|
|
301
302
|
:stroke-width="'var(--vc-grid-width)'"
|
|
@@ -27,8 +27,8 @@ type __VLS_Props = {
|
|
|
27
27
|
};
|
|
28
28
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
29
29
|
variant: LegendIndicatorVariant;
|
|
30
|
-
payload: LegendItem[];
|
|
31
30
|
colors: Record<string, string>;
|
|
31
|
+
payload: LegendItem[];
|
|
32
32
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
33
33
|
declare const _default: typeof __VLS_export;
|
|
34
34
|
export default _default;
|
|
@@ -129,6 +129,11 @@ export interface ChartPadding {
|
|
|
129
129
|
* scale legend, axis ticks, axis titles, and radar labels together.
|
|
130
130
|
*/
|
|
131
131
|
export interface ChartTheme {
|
|
132
|
+
/**
|
|
133
|
+
* Per-chart series palette. Entries override `--vc-series-0` through
|
|
134
|
+
* `--vc-series-7`; omitted entries continue to inherit host design tokens.
|
|
135
|
+
*/
|
|
136
|
+
colors?: string[];
|
|
132
137
|
/** Grid + axis (domain) lines. */
|
|
133
138
|
grid?: {
|
|
134
139
|
/** Line colour. Token: `--vc-grid-color`. */
|
|
@@ -21,7 +21,7 @@ export interface SeriesDescriptor {
|
|
|
21
21
|
dataKey: string;
|
|
22
22
|
/** Display name shown in legend / tooltip. */
|
|
23
23
|
name: string;
|
|
24
|
-
/** Resolved colour. Falls back to
|
|
24
|
+
/** Resolved colour. Falls back to the library's design-system-aware series token. */
|
|
25
25
|
color: string;
|
|
26
26
|
/** Whether the series is hidden. */
|
|
27
27
|
hidden: boolean;
|
|
@@ -4,8 +4,8 @@ export function normalizeAxisId(id) {
|
|
|
4
4
|
return /^-?\d+$/.test(id) ? Number(id) : id;
|
|
5
5
|
}
|
|
6
6
|
function resolveColor(color, index) {
|
|
7
|
-
if (Array.isArray(color)) return color[0] ?? `var(--
|
|
8
|
-
return color ?? `var(--
|
|
7
|
+
if (Array.isArray(color)) return color[0] ?? `var(--vc-series-${index % 8})`;
|
|
8
|
+
return color ?? `var(--vc-series-${index % 8})`;
|
|
9
9
|
}
|
|
10
10
|
export function categoriesToSeries(categories) {
|
|
11
11
|
return Object.entries(categories).map(([dataKey, item], index) => ({
|
|
@@ -4,6 +4,9 @@ export function themeToVars(theme) {
|
|
|
4
4
|
const set = (name, value) => {
|
|
5
5
|
if (value !== void 0) vars[name] = String(value);
|
|
6
6
|
};
|
|
7
|
+
theme.colors?.slice(0, 8).forEach((color, index) => {
|
|
8
|
+
set(`--vc-series-${index}`, color);
|
|
9
|
+
});
|
|
7
10
|
set("--vc-grid-color", theme.grid?.color);
|
|
8
11
|
set("--vc-grid-dash", theme.grid?.dash);
|
|
9
12
|
set("--vc-grid-width", theme.grid?.width);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-charts",
|
|
3
|
-
"version": "3.0.0
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Beautiful chart components for Nuxt (vccs engine) — Area, Bar, Line, Donut, Bubble, Radar, Radial Bar, Funnel, Sankey, Candlestick, Status Tracker",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Dennis Adriaansen <adriaansendennis@gmail.com>",
|