nuxt-charts 3.0.0-beta.1 → 3.0.0-beta.3
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 +77 -7
- package/dist/module.json +2 -2
- package/dist/module.mjs +20 -1
- package/dist/runtime/assets/components.css +1 -1
- package/dist/runtime/assets/theme.css +1 -1
- package/dist/runtime/components/AreaChart.d.vue.ts +5 -1
- package/dist/runtime/components/AreaChart.vue +84 -9
- package/dist/runtime/components/AreaChart.vue.d.ts +5 -1
- package/dist/runtime/components/BarChart.d.vue.ts +5 -1
- package/dist/runtime/components/BarChart.vue +125 -8
- package/dist/runtime/components/BarChart.vue.d.ts +5 -1
- package/dist/runtime/components/BubbleChart.d.vue.ts +5 -1
- package/dist/runtime/components/BubbleChart.vue +74 -13
- package/dist/runtime/components/BubbleChart.vue.d.ts +5 -1
- package/dist/runtime/components/DonutChart.vue +67 -15
- package/dist/runtime/components/FunnelChart.d.vue.ts +8 -1
- package/dist/runtime/components/FunnelChart.vue +127 -35
- package/dist/runtime/components/FunnelChart.vue.d.ts +8 -1
- package/dist/runtime/components/LineChart.d.vue.ts +5 -1
- package/dist/runtime/components/LineChart.vue +72 -7
- package/dist/runtime/components/LineChart.vue.d.ts +5 -1
- package/dist/runtime/components/RadarChart.vue +93 -12
- package/dist/runtime/components/RadialBarChart.vue +40 -8
- package/dist/runtime/components/SankeyChart.d.vue.ts +36 -0
- package/dist/runtime/components/SankeyChart.vue +146 -0
- package/dist/runtime/components/SankeyChart.vue.d.ts +36 -0
- package/dist/runtime/components/internal/AreaVariantDefs.d.ts +68 -0
- package/dist/runtime/components/internal/AreaVariantDefs.js +165 -0
- package/dist/runtime/components/internal/BarVariantDefs.d.ts +74 -0
- package/dist/runtime/components/internal/BarVariantDefs.js +200 -0
- package/dist/runtime/components/internal/CartesianFrame.d.vue.ts +18 -1
- package/dist/runtime/components/internal/CartesianFrame.vue +65 -14
- package/dist/runtime/components/internal/CartesianFrame.vue.d.ts +18 -1
- package/dist/runtime/components/internal/ChartBackground.d.ts +44 -0
- package/dist/runtime/components/internal/ChartBackground.js +53 -0
- package/dist/runtime/components/internal/ChartDot.d.ts +85 -0
- package/dist/runtime/components/internal/ChartDot.js +59 -0
- package/dist/runtime/components/internal/ChartLegend.d.vue.ts +24 -1
- package/dist/runtime/components/internal/ChartLegend.vue +11 -3
- package/dist/runtime/components/internal/ChartLegend.vue.d.ts +24 -1
- package/dist/runtime/components/internal/ChartSkeleton.d.vue.ts +18 -0
- package/dist/runtime/components/internal/ChartSkeleton.vue +64 -0
- package/dist/runtime/components/internal/ChartSkeleton.vue.d.ts +18 -0
- package/dist/runtime/components/internal/ChartTooltip.vue +8 -2
- package/dist/runtime/components/internal/CubeBarShape.d.vue.ts +9 -1
- package/dist/runtime/components/internal/CubeBarShape.vue +8 -8
- package/dist/runtime/components/internal/CubeBarShape.vue.d.ts +9 -1
- package/dist/runtime/components/internal/FunnelClassicShape.d.vue.ts +81 -0
- package/dist/runtime/components/internal/FunnelClassicShape.vue +97 -0
- package/dist/runtime/components/internal/FunnelClassicShape.vue.d.ts +81 -0
- package/dist/runtime/components/internal/FunnelLayeredShape.d.vue.ts +21 -0
- package/dist/runtime/components/internal/FunnelLayeredShape.vue +71 -37
- package/dist/runtime/components/internal/FunnelLayeredShape.vue.d.ts +21 -0
- package/dist/runtime/components/internal/FunnelTooltip.d.vue.ts +16 -0
- package/dist/runtime/components/internal/FunnelTooltip.vue +26 -0
- package/dist/runtime/components/internal/FunnelTooltip.vue.d.ts +16 -0
- package/dist/runtime/components/internal/PolarCenterSync.d.ts +38 -0
- package/dist/runtime/components/internal/PolarCenterSync.js +27 -0
- package/dist/runtime/components/internal/RadarGradientDefs.d.ts +46 -0
- package/dist/runtime/components/internal/RadarGradientDefs.js +46 -0
- package/dist/runtime/components/internal/SegmentVariantDefs.d.ts +67 -0
- package/dist/runtime/components/internal/SegmentVariantDefs.js +51 -0
- package/dist/runtime/components/internal/StrokeGradientDefs.d.ts +36 -0
- package/dist/runtime/components/internal/StrokeGradientDefs.js +35 -0
- package/dist/runtime/components/internal/VariantBarShape.d.vue.ts +36 -0
- package/dist/runtime/components/internal/VariantBarShape.vue +53 -0
- package/dist/runtime/components/internal/VariantBarShape.vue.d.ts +36 -0
- package/dist/runtime/components/internal/tooltipContent.d.ts +13 -0
- package/dist/runtime/components/internal/tooltipContent.js +5 -0
- package/dist/runtime/types/charts.d.ts +192 -12
- package/dist/runtime/types/shared.d.ts +37 -0
- package/dist/runtime/types.d.ts +3 -0
- package/dist/runtime/utils/axis.d.ts +12 -1
- package/dist/runtime/utils/axis.js +23 -0
- package/dist/runtime/utils/background.d.ts +36 -0
- package/dist/runtime/utils/background.js +140 -0
- package/dist/runtime/utils/gradient.d.ts +8 -0
- package/dist/runtime/utils/gradient.js +3 -0
- package/dist/runtime/utils/theme.js +14 -0
- package/dist/runtime/utils/variants.d.ts +101 -0
- package/dist/runtime/utils/variants.js +48 -0
- package/package.json +6 -15
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# nuxt-charts
|
|
2
2
|
|
|
3
|
-
Beautiful chart components for Nuxt — Area, Bar, Line, Donut, Bubble, Radar, Radial Bar, Funnel, Candlestick and Status Tracker.
|
|
3
|
+
Beautiful chart components for Nuxt — Area, Bar, Line, Donut, Bubble, Radar, Radial Bar, Funnel, Sankey, Candlestick and Status Tracker.
|
|
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
|
|
|
@@ -21,14 +21,15 @@ export default defineNuxtConfig({
|
|
|
21
21
|
|
|
22
22
|
| Component | Notes |
|
|
23
23
|
|---|---|
|
|
24
|
-
| `AreaChart` | Gradients, dither fills, stacked |
|
|
25
|
-
| `BarChart` | Grouped, stacked, horizontal, cube bars |
|
|
26
|
-
| `LineChart` | Multi-series, curve types |
|
|
24
|
+
| `AreaChart` | Gradients, dither fills, textured fills, stacked |
|
|
25
|
+
| `BarChart` | Grouped, stacked, horizontal, cube bars, patterned fills |
|
|
26
|
+
| `LineChart` | Multi-series, curve types, dashed / animated strokes |
|
|
27
27
|
| `DonutChart` | Center slot for labels |
|
|
28
28
|
| `BubbleChart` | Scatter with size encoding |
|
|
29
29
|
| `RadarChart` | New in v3 |
|
|
30
30
|
| `RadialBarChart` | New in v3 |
|
|
31
31
|
| `FunnelChart` | New in v3 |
|
|
32
|
+
| `SankeyChart` | New in v3 |
|
|
32
33
|
| `CandlestickChart` | New in v3 |
|
|
33
34
|
| `StatusTrackerChart` | New in v3 |
|
|
34
35
|
|
|
@@ -71,10 +72,74 @@ Each axis accepts `orientation`, `label`, `domain`, `numTicks`, `formatter`,
|
|
|
71
72
|
the top-level `yLabel` / `yDomain` / `yAxisConfig` props. Supported on
|
|
72
73
|
`LineChart`, `AreaChart` and `BarChart` (vertical orientation).
|
|
73
74
|
|
|
75
|
+
## Style variants
|
|
76
|
+
|
|
77
|
+
Every treatment below is opt-in — a chart that sets none of them renders exactly
|
|
78
|
+
as it did before. The playground's `/variants` page shows them side by side.
|
|
79
|
+
|
|
80
|
+
### Series fills
|
|
81
|
+
|
|
82
|
+
| Prop | Chart | Values |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| `variant` | `BarChart` | `solid` (default), `cubes`, `hatched`, `duotone`, `duotone-reverse`, `gradient`, `stripped` |
|
|
85
|
+
| `variant` | `AreaChart` | `gradient`, `gradient-reverse`, `solid`, `dotted`, `lines`, `hatched` |
|
|
86
|
+
| `variant` | `RadarChart` | `filled` (default), `lines`, `gradient` (inside to outside), `gradient-reverse` (outside to inside) |
|
|
87
|
+
| `variant` | `RadialBarChart` | `full` (default), `semi` |
|
|
88
|
+
| `variant` | `DonutChart` | `flat` (default), `gradient` |
|
|
89
|
+
|
|
90
|
+
On `AreaChart` the fill treatments layer over the v2 `gradient` fade and yield to
|
|
91
|
+
`dither`, which is a texture of its own.
|
|
92
|
+
|
|
93
|
+
### Series detail
|
|
94
|
+
|
|
95
|
+
- `strokeVariant` — `solid`, `dashed`, `animated-dashed` (line + area).
|
|
96
|
+
- `dotVariant` — `default`, `border`, `colored-border`, `ping` (line, area,
|
|
97
|
+
radar), sized by `dotSize`.
|
|
98
|
+
- `glow` — a soft outer glow (bar, line, area, donut).
|
|
99
|
+
- `bufferBar` — renders the final bar as a projection: a hollow hatch with an
|
|
100
|
+
outline, for a period that is still accruing.
|
|
101
|
+
- `hoverHighlight` / `maxHighlight` — dim every bar but the hovered one, or the
|
|
102
|
+
tallest.
|
|
103
|
+
- `percent` — with `stacked`, normalise each category to 100% and label the
|
|
104
|
+
value axis as percentages.
|
|
105
|
+
|
|
106
|
+
### Chart chrome
|
|
107
|
+
|
|
108
|
+
- `backgroundPattern` — one of eleven textures painted behind the plot area and
|
|
109
|
+
faded out at the edges: `dots`, `grid`, `cross-hatch`, `diagonal-lines`,
|
|
110
|
+
`plus`, `falling-triangles`, `4-pointed-star`, `tiny-checkers`,
|
|
111
|
+
`overlapping-circles`, `wiggle-lines`, `bubbles`.
|
|
112
|
+
- `legendVariant` — `square`, `circle`, `circle-outline`, `rounded-square`
|
|
113
|
+
(default), `rounded-square-outline`, `vertical-bar`, `horizontal-bar`.
|
|
114
|
+
- `tooltipVariant` (`default`, `frosted-glass`) and `tooltipRoundness`
|
|
115
|
+
(`sm`, `md`, `lg`, `xl`).
|
|
116
|
+
- `loading` — a shimmering placeholder in place of the chart, with the
|
|
117
|
+
silhouette matched to the chart type; `loadingLabel` names or hides its pill.
|
|
118
|
+
- `gridType` on `RadarChart` — `polygon` (default) or `circle`.
|
|
119
|
+
|
|
120
|
+
```vue
|
|
121
|
+
<template>
|
|
122
|
+
<BarChart
|
|
123
|
+
:data="data"
|
|
124
|
+
:categories="categories"
|
|
125
|
+
:y-axis="['desktop']"
|
|
126
|
+
x-axis="month"
|
|
127
|
+
:height="320"
|
|
128
|
+
variant="duotone"
|
|
129
|
+
background-pattern="dots"
|
|
130
|
+
legend-variant="circle"
|
|
131
|
+
tooltip-variant="frosted-glass"
|
|
132
|
+
max-highlight
|
|
133
|
+
/>
|
|
134
|
+
</template>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The animated stroke and the loading shimmer both stop when the viewer's system
|
|
138
|
+
asks for reduced motion. Every generated SVG paint is scoped to its chart, so
|
|
139
|
+
several charts on one page never collide.
|
|
140
|
+
|
|
74
141
|
### Deferred / removed
|
|
75
142
|
|
|
76
|
-
- **`SankeyChart`** — deferred: the published `vccs` release does not yet export
|
|
77
|
-
a Sankey chart. Returns once `vccs` ships it.
|
|
78
143
|
- **`DualChart`** — planned for v3.1 (maps onto the `vccs` `ComposedChart`).
|
|
79
144
|
- **`GanttChart`, `DagreGraph`, `Maps`** — removed in v3. They were Unovis /
|
|
80
145
|
d3-geo specific and have no `vccs` equivalent.
|
|
@@ -98,12 +163,17 @@ export default defineNuxtConfig({
|
|
|
98
163
|
- Enums: `CurveType`, `LegendPosition`, `Orientation`, `DonutType`
|
|
99
164
|
- Types: `AreaChartProps`, `BarChartProps`, `LineChartProps`, `BubbleChartProps`,
|
|
100
165
|
`DonutChartProps`, `RadarChartProps`, `RadialBarChartProps`, `FunnelChartProps`,
|
|
166
|
+
`CandlestickChartProps`,
|
|
167
|
+
`SankeyChartProps`, `SankeyInputNode`, `SankeyInputLink`,
|
|
101
168
|
`StatusTrackerChartProps`, `StatusTrackerDatum`, `BulletLegendItemInterface`,
|
|
102
169
|
`AxisConfig`, `TooltipConfig`, `ValueLabel`, `ReferenceLineConfig`
|
|
170
|
+
- Style variant unions: `BarVariant`, `AreaFillVariant`, `StrokeVariant`,
|
|
171
|
+
`DotVariant`, `DitherVariant`, `BackgroundVariant`, `LegendIndicatorVariant`,
|
|
172
|
+
`TooltipVariant`, `TooltipRoundness`, `RadarVariant`, `RadialVariant`
|
|
103
173
|
|
|
104
174
|
## Migrating from v2
|
|
105
175
|
|
|
106
|
-
See the [Upgrade to v3](https://nuxtcharts.com/docs/getting-started/upgrade-to-v3) guide. Specialty charts (maps, gantt, dual,
|
|
176
|
+
See the [Upgrade to v3](https://nuxtcharts.com/docs/getting-started/upgrade-to-v3) guide. Specialty charts (maps, gantt, dual, dagre) are not in v3 yet — stay on `nuxt-charts@2` if you need them.
|
|
107
177
|
|
|
108
178
|
## License
|
|
109
179
|
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -9,6 +9,7 @@ const COMPONENTS = {
|
|
|
9
9
|
RadarChart: "RadarChart",
|
|
10
10
|
RadialBarChart: "RadialBarChart",
|
|
11
11
|
FunnelChart: "FunnelChart",
|
|
12
|
+
SankeyChart: "SankeyChart",
|
|
12
13
|
CandlestickChart: "CandlestickChart",
|
|
13
14
|
StatusTrackerChart: "StatusTrackerChart"
|
|
14
15
|
};
|
|
@@ -47,6 +48,11 @@ const resolveImports = (config, resolverUrl) => {
|
|
|
47
48
|
"RadarChartProps",
|
|
48
49
|
"RadialBarChartProps",
|
|
49
50
|
"FunnelChartProps",
|
|
51
|
+
"FunnelLabelSizes",
|
|
52
|
+
"SankeyChartProps",
|
|
53
|
+
"SankeyInputNode",
|
|
54
|
+
"SankeyInputLink",
|
|
55
|
+
"SankeyNodeAlign",
|
|
50
56
|
"CandlestickChartProps",
|
|
51
57
|
"StatusTrackerChartProps",
|
|
52
58
|
"StatusTrackerDatum",
|
|
@@ -59,7 +65,20 @@ const resolveImports = (config, resolverUrl) => {
|
|
|
59
65
|
// (MarkerConfig drives line/area dot rendering; CrosshairConfig is inert
|
|
60
66
|
// but kept so old templates type-check), so keep them auto-importable.
|
|
61
67
|
"MarkerConfig",
|
|
62
|
-
"CrosshairConfig"
|
|
68
|
+
"CrosshairConfig",
|
|
69
|
+
// Style variant unions, so a consumer can annotate a variant it stores or
|
|
70
|
+
// passes around instead of widening it to `string`.
|
|
71
|
+
"BarVariant",
|
|
72
|
+
"AreaFillVariant",
|
|
73
|
+
"StrokeVariant",
|
|
74
|
+
"DotVariant",
|
|
75
|
+
"DitherVariant",
|
|
76
|
+
"BackgroundVariant",
|
|
77
|
+
"LegendIndicatorVariant",
|
|
78
|
+
"TooltipVariant",
|
|
79
|
+
"TooltipRoundness",
|
|
80
|
+
"RadarVariant",
|
|
81
|
+
"RadialVariant"
|
|
63
82
|
]
|
|
64
83
|
});
|
|
65
84
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer vue-chrts{.vc-tooltip{background:var(--vc-tooltip-bg,oklch(1 0 0));border:1px solid var(--vc-tooltip-border,oklch(.922 0 0));border-radius:var(--vc-tooltip-radius,.5rem);box-shadow:var(--vc-tooltip-shadow,0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1));font-size:var(--vc-legend-size,.75rem);line-height:1.5;min-width:8rem;padding:var(--vc-tooltip-padding,.375rem .625rem);pointer-events:none}.vc-tooltip
|
|
1
|
+
@layer vue-chrts{.vc-tooltip{background:var(--vc-tooltip-bg,oklch(1 0 0));border:1px solid var(--vc-tooltip-border,oklch(.922 0 0));border-radius:var(--vc-tooltip-radius,.5rem);box-shadow:var(--vc-tooltip-shadow,0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1));color:var(--vc-tooltip-fg,oklch(.205 0 0));font-size:var(--vc-legend-size,.75rem);line-height:1.5;min-width:8rem;padding:var(--vc-tooltip-padding,.375rem .625rem);pointer-events:none}.vc-tooltip--frosted-glass{backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);background:color-mix(in oklab,var(--vc-tooltip-bg,oklch(1 0 0)) 70%,transparent)}.vc-tooltip--sm{border-radius:.125rem}.vc-tooltip--md{border-radius:.375rem}.vc-tooltip--lg{border-radius:.5rem}.vc-tooltip--xl{border-radius:.75rem}.vc-tooltip__label{color:var(--vc-tooltip-fg,oklch(.205 0 0));font-weight:500;margin:0 0 .25rem}.vc-tooltip__list{display:flex;flex-direction:column;gap:.125rem;list-style:none;margin:0;padding:0}.vc-tooltip__item{align-items:center;display:flex;gap:.375rem}.vc-tooltip__dot{border-radius:9999px;display:inline-block;flex-shrink:0;height:.5rem;width:.5rem}.vc-tooltip__name{color:var(--vc-tooltip-muted,oklch(.556 0 0))}.vc-tooltip__value{color:var(--vc-tooltip-fg,oklch(.205 0 0));font-variant-numeric:tabular-nums;font-weight:500;margin-left:auto}.vc-legend{flex-wrap:wrap;font-size:var(--vc-legend-size,.75rem);font-weight:var(--vc-legend-weight,400);gap:var(--vc-legend-gap,.75rem);justify-content:center;line-height:1.5;list-style:none;margin:0;padding:0}.vc-legend,.vc-legend__item{align-items:center;display:flex}.vc-legend__item{gap:.375rem}.vc-legend__item--inactive{opacity:.4}.vc-legend__dot{border-radius:9999px;display:inline-block;flex-shrink:0;height:var(--vc-legend-dot-size,.5rem);width:var(--vc-legend-dot-size,.5rem)}.vc-legend__dot--square{border-radius:0}.vc-legend__dot--rounded-square{border-radius:2px}.vc-legend__dot--circle{border-radius:9999px}.vc-legend__dot--vertical-bar{border-radius:2px;height:calc(var(--vc-legend-dot-size, .5rem)*1.5);width:calc(var(--vc-legend-dot-size, .5rem)*.5)}.vc-legend__dot--horizontal-bar{border-radius:2px;height:calc(var(--vc-legend-dot-size, .5rem)*.5);width:calc(var(--vc-legend-dot-size, .5rem)*1.5)}.vc-legend__dot--circle-outline,.vc-legend__dot--rounded-square-outline{box-sizing:border-box;height:calc(var(--vc-legend-dot-size, .5rem)*1.25);-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude;padding:1.5px;width:calc(var(--vc-legend-dot-size, .5rem)*1.25)}.vc-legend__dot--circle-outline{border-radius:9999px}.vc-legend__dot--rounded-square-outline{border-radius:3px}.vc-legend__label{color:var(--vc-legend-color,oklch(.556 0 0))}.vc-skeleton{align-items:stretch;box-sizing:border-box;color:var(--vc-tick-color,oklch(.556 0 0));display:flex;overflow:hidden;padding:8% 4%;position:relative;width:100%}.vc-skeleton__bars{align-items:flex-end;display:flex;gap:2%;height:100%;width:100%}.vc-skeleton__bar{background:currentColor;border-radius:2px 2px 0 0;flex:1;opacity:.14}.vc-skeleton__wave{height:100%;opacity:.14;width:100%}.vc-skeleton__ring{aspect-ratio:1;border:1.75rem solid;border-radius:9999px;height:100%;margin:auto;opacity:.14}.vc-skeleton__shimmer{animation:vc-skeleton-sweep 1.8s linear infinite;background:linear-gradient(105deg,transparent 35%,currentColor 50%,transparent 65%);inset:0;opacity:.1;position:absolute}@keyframes vc-skeleton-sweep{0%{transform:translateX(-100%)}to{transform:translateX(100%)}}.vc-skeleton__pill{align-items:center;background:var(--vc-surface-bg,oklch(1 0 0));border:1px solid var(--vc-tooltip-border,oklch(.922 0 0));border-radius:.375rem;color:var(--vc-tick-color,oklch(.556 0 0));display:flex;font-size:var(--vc-legend-size,.75rem);gap:.375rem;height:-moz-fit-content;height:fit-content;inset:0;line-height:1.5;margin:auto;padding:.125rem .5rem;position:absolute;width:-moz-fit-content;width:fit-content}.vc-skeleton__spinner{animation:vc-skeleton-spin .7s linear infinite;border:1px solid var(--vc-tooltip-border,oklch(.922 0 0));border-radius:9999px;border-top:1px solid;height:.75rem;width:.75rem}@keyframes vc-skeleton-spin{to{transform:rotate(1turn)}}@media (prefers-reduced-motion:reduce){.vc-skeleton__shimmer,.vc-skeleton__spinner{animation:none}}.vc-candlestick-chart{cursor:crosshair;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}.vc-candlestick-chart__svg{display:block;overflow:visible;width:100%}.vc-funnel-layered{position:relative;width:100%}.vc-funnel{position:relative}.vc-funnel-layered__tooltip{align-items:center;background:var(--vc-tooltip-bg,oklch(1 0 0));border:1px solid var(--vc-tooltip-border,oklch(.922 0 0));border-radius:var(--vc-tooltip-radius,.5rem);box-shadow:var(--vc-tooltip-shadow,0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1));color:var(--vc-tooltip-fg,oklch(.205 0 0));display:flex;font-size:var(--vc-legend-size,.75rem);gap:.375rem;padding:var(--vc-tooltip-padding,.375rem .625rem);pointer-events:none;position:absolute;transform:translate(-50%,calc(-100% - 10px));white-space:nowrap}.vc-funnel-layered__name{color:var(--vc-tooltip-muted,oklch(.556 0 0))}.vc-funnel-layered__value{font-variant-numeric:tabular-nums;font-weight:600}.vc-funnel-layered__dot{border-radius:9999px;display:inline-block;flex-shrink:0;height:var(--vc-legend-dot-size,.5rem);width:var(--vc-legend-dot-size,.5rem)}.vc-funnel-layered-shape{opacity:.96;transition:opacity .15s}.vc-funnel-layered-shape:hover{opacity:1}.vc-funnel .v-charts-label-list .v-charts-label{fill:var(--vc-funnel-value-color,oklch(.205 0 0));font-size:var(--vc-funnel-value-size,.75rem);font-variant-numeric:tabular-nums;font-weight:var(--vc-funnel-value-weight,600)}.vc-funnel-classic-shape{cursor:default}.vc-funnel-classic-shape__shadow{opacity:var(--vc-funnel-shadow-opacity,.16)}.vc-funnel-classic-shape__body{opacity:var(--vc-funnel-shape-opacity,.92);transition:opacity .15s ease}.vc-funnel-classic-shape__highlight{fill:none;stroke:hsla(0,0%,100%,.24);stroke-width:1;vector-effect:non-scaling-stroke}.vc-funnel-classic-shape:hover .vc-funnel-classic-shape__body{opacity:var(--vc-funnel-shape-hover-opacity,1)}.vc-funnel-classic-shape__name,.vc-funnel-classic-shape__value{font-family:inherit;paint-order:stroke;pointer-events:none;stroke:rgba(0,0,0,.12);stroke-linejoin:round;stroke-width:2px;-webkit-user-select:none;-moz-user-select:none;user-select:none}.vc-funnel-classic-shape__value{fill:var(--vc-funnel-inside-value-color,#fff);font-variant-numeric:tabular-nums}.vc-funnel-classic-shape__name{fill:var(--vc-funnel-inside-label-color,#fff);opacity:.78}.vc-funnel-layered-shape__divider{stroke:var(--vc-surface-bg,oklch(1 0 0))}.vc-funnel-layered-shape__badge-text,.vc-funnel-layered-shape__name,.vc-funnel-layered-shape__value{font-family:inherit;pointer-events:none;stroke:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.vc-funnel-layered-shape__value{fill:var(--vc-funnel-value-color,var(--vc-axis-label-color,oklch(.205 0 0)));font-variant-numeric:tabular-nums;font-weight:var(--vc-funnel-value-weight,600)}.vc-funnel-layered-shape__badge{fill:var(--vc-funnel-badge-bg,var(--vc-surface-bg,oklch(1 0 0)));fill-opacity:var(--vc-funnel-badge-opacity,.82);stroke:var(--vc-funnel-badge-border,var(--vc-axis-line-color,oklch(.922 0 0)));stroke-opacity:.7}.vc-funnel-layered-shape__badge-text{fill:var(--vc-funnel-badge-color,var(--vc-tick-color,oklch(.556 0 0)));font-variant-numeric:tabular-nums;font-weight:var(--vc-funnel-badge-weight,600)}.vc-funnel-layered-shape__name{fill:var(--vc-funnel-label-color,var(--vc-tick-color,oklch(.556 0 0)));font-weight:var(--vc-funnel-label-weight,500)}.vc-status-tracker{color:var(--vc-axis-label-color,var(--ui-text-highlighted,var(--foreground,oklch(.205 0 0))));font-family:inherit;width:100%}.vc-status-tracker__header{align-items:baseline;display:flex;gap:1rem;justify-content:space-between;margin-bottom:.75rem}.vc-status-tracker__summary,.vc-status-tracker__title{font-size:.875rem;line-height:1.25rem;margin:0}.vc-status-tracker__title{font-weight:600}.vc-status-tracker__summary{color:var(--vc-tick-color,var(--ui-text-muted,var(--muted-foreground,oklch(.556 0 0))));font-variant-numeric:tabular-nums}.vc-status-tracker__track{display:flex;overflow:hidden;width:100%}.vc-status-tracker__bar{display:block;flex:0 0 auto;height:100%;min-width:1px;transition:opacity .16s ease}.vc-status-tracker__bar:hover{opacity:.78}.vc-status-tracker__bar--rounded-start{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.vc-status-tracker__bar--rounded-end{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.vc-status-tracker__bar--empty:hover{opacity:1}.vc-status-tracker__labels{gap:1rem;justify-content:space-between;margin-top:.5rem}.vc-status-tracker__labels,.vc-status-tracker__legend{color:var(--vc-legend-color,oklch(.556 0 0));display:flex;font-size:var(--vc-legend-size,.75rem);line-height:1rem}.vc-status-tracker__legend{flex-wrap:wrap;gap:.5rem 1rem;list-style:none;margin:var(--vc-legend-inset,.75rem) 0 0;padding:0}.vc-status-tracker__legend-item{align-items:center;display:inline-flex;gap:.375rem}.vc-status-tracker__legend-dot{border-radius:9999px;flex:0 0 auto;height:var(--vc-legend-dot-size,.5rem);width:var(--vc-legend-dot-size,.5rem)}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer vue-chrts{.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-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-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: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-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-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)))}}
|
|
@@ -5,7 +5,11 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
|
|
|
5
5
|
} ? P : {});
|
|
6
6
|
expose: (exposed: {}) => void;
|
|
7
7
|
attrs: any;
|
|
8
|
-
slots: {
|
|
8
|
+
slots: {
|
|
9
|
+
tooltip?: (props: {
|
|
10
|
+
values: T | undefined;
|
|
11
|
+
}) => unknown;
|
|
12
|
+
};
|
|
9
13
|
emit: {};
|
|
10
14
|
}>) => import("vue").VNode & {
|
|
11
15
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
@@ -3,12 +3,16 @@ import { computed, useId } from "vue";
|
|
|
3
3
|
import { Area, AreaChart as VccsAreaChart } from "vccs";
|
|
4
4
|
import CartesianFrame from "./internal/CartesianFrame.vue";
|
|
5
5
|
import GradientDefs from "./internal/GradientDefs";
|
|
6
|
+
import StrokeGradientDefs from "./internal/StrokeGradientDefs";
|
|
6
7
|
import { categoriesToSeries } from "../utils/categories";
|
|
7
8
|
import { curveTypeToVccs } from "../utils/curve";
|
|
8
9
|
import { markerToDot, normalizeMarkerConfig, toStrokeDasharray } from "../utils/marker";
|
|
9
|
-
import { DEFAULT_GRADIENT_STOPS, gradientId } from "../utils/gradient";
|
|
10
|
+
import { DEFAULT_GRADIENT_STOPS, gradientId, strokeGradientId } from "../utils/gradient";
|
|
10
11
|
import DitherDefs from "./internal/DitherDefs";
|
|
12
|
+
import AreaVariantDefs, { areaFillId } from "./internal/AreaVariantDefs";
|
|
13
|
+
import ChartDot from "./internal/ChartDot";
|
|
11
14
|
import { ditherId } from "../utils/dither";
|
|
15
|
+
import { strokeDasharrayFor, variantId } from "../utils/variants";
|
|
12
16
|
const props = defineProps({
|
|
13
17
|
xAxis: { type: null, required: false },
|
|
14
18
|
curveType: { type: String, required: false },
|
|
@@ -19,9 +23,16 @@ const props = defineProps({
|
|
|
19
23
|
ditherTile: { type: Number, required: false },
|
|
20
24
|
ditherWash: { type: Number, required: false },
|
|
21
25
|
lineWidth: { type: Number, required: false },
|
|
26
|
+
strokeGradient: { type: Array, required: false },
|
|
22
27
|
stacked: { type: Boolean, required: false },
|
|
28
|
+
percent: { type: Boolean, required: false },
|
|
23
29
|
lineDashArray: { type: [Array, String], required: false },
|
|
24
30
|
markerConfig: { type: Object, required: false },
|
|
31
|
+
variant: { type: String, required: false },
|
|
32
|
+
strokeVariant: { type: String, required: false },
|
|
33
|
+
dotVariant: { type: String, required: false },
|
|
34
|
+
dotSize: { type: Number, required: false },
|
|
35
|
+
glow: { type: Boolean, required: false },
|
|
25
36
|
data: { type: Array, required: true },
|
|
26
37
|
height: { type: Number, required: true },
|
|
27
38
|
xLabel: { type: String, required: false },
|
|
@@ -58,7 +69,13 @@ const props = defineProps({
|
|
|
58
69
|
xExplicitTicks: { type: Array, required: false },
|
|
59
70
|
yExplicitTicks: { type: Array, required: false },
|
|
60
71
|
crosshairConfig: { type: Object, required: false },
|
|
61
|
-
theme: { type: Object, required: false }
|
|
72
|
+
theme: { type: Object, required: false },
|
|
73
|
+
backgroundPattern: { type: String, required: false },
|
|
74
|
+
legendVariant: { type: String, required: false },
|
|
75
|
+
tooltipVariant: { type: String, required: false },
|
|
76
|
+
tooltipRoundness: { type: String, required: false },
|
|
77
|
+
loading: { type: Boolean, required: false },
|
|
78
|
+
loadingLabel: { type: String, required: false }
|
|
62
79
|
});
|
|
63
80
|
const gradientScope = useId();
|
|
64
81
|
const markers = computed(() => normalizeMarkerConfig(props.markerConfig));
|
|
@@ -70,16 +87,21 @@ const series = computed(
|
|
|
70
87
|
);
|
|
71
88
|
const curve = computed(() => curveTypeToVccs(props.curveType));
|
|
72
89
|
const stackId = computed(() => props.stacked ? "stack" : void 0);
|
|
90
|
+
const chartContainerProps = computed(
|
|
91
|
+
() => props.stacked && props.percent ? { stackOffset: "expand" } : {}
|
|
92
|
+
);
|
|
73
93
|
const fillOpacity = computed(() => props.hideArea ? 0 : 0.6);
|
|
74
|
-
const dashArray = computed(() => toStrokeDasharray(props.lineDashArray));
|
|
75
94
|
const useDither = computed(
|
|
76
95
|
() => !props.hideArea && props.dither !== void 0 && props.dither !== false
|
|
77
96
|
);
|
|
78
97
|
const ditherVariant = computed(
|
|
79
98
|
() => typeof props.dither === "string" ? props.dither : "bayer"
|
|
80
99
|
);
|
|
100
|
+
const useFillVariant = computed(
|
|
101
|
+
() => !props.hideArea && props.variant !== void 0 && !useDither.value
|
|
102
|
+
);
|
|
81
103
|
const useGradientFill = computed(
|
|
82
|
-
() => !props.hideArea && props.gradient !== false && !useDither.value
|
|
104
|
+
() => !props.hideArea && props.gradient !== false && !useDither.value && !useFillVariant.value
|
|
83
105
|
);
|
|
84
106
|
const useDitherFade = computed(
|
|
85
107
|
() => useDither.value && props.gradient !== false
|
|
@@ -96,16 +118,45 @@ const ditherWashStops = computed(() => {
|
|
|
96
118
|
stopOpacity: stop.stopOpacity * scale
|
|
97
119
|
}));
|
|
98
120
|
});
|
|
121
|
+
const paintedSeries = computed(
|
|
122
|
+
() => series.value.map((s) => ({ dataKey: s.dataKey, color: s.color }))
|
|
123
|
+
);
|
|
99
124
|
function fillFor(dataKey, color) {
|
|
100
125
|
if (useDither.value) return `url(#${ditherId(dataKey, gradientScope)})`;
|
|
126
|
+
if (useFillVariant.value) return `url(#${areaFillId(props.variant, dataKey, gradientScope)})`;
|
|
101
127
|
if (useGradientFill.value) return `url(#${gradientId(dataKey, gradientScope)})`;
|
|
102
128
|
return color;
|
|
103
129
|
}
|
|
130
|
+
function strokeFor(dataKey, color) {
|
|
131
|
+
return props.strokeGradient?.length ? `url(#${strokeGradientId(dataKey, gradientScope)})` : color;
|
|
132
|
+
}
|
|
133
|
+
function glowFor(dataKey) {
|
|
134
|
+
return props.glow ? `url(#${variantId("glow", dataKey, gradientScope)})` : void 0;
|
|
135
|
+
}
|
|
136
|
+
const dashArray = computed(
|
|
137
|
+
() => toStrokeDasharray(props.lineDashArray) ?? strokeDasharrayFor(props.strokeVariant)
|
|
138
|
+
);
|
|
139
|
+
const frameClass = computed(
|
|
140
|
+
() => props.strokeVariant === "animated-dashed" ? "vc-dash-animated" : void 0
|
|
141
|
+
);
|
|
142
|
+
const showDots = computed(() => props.dotVariant !== void 0);
|
|
104
143
|
const xAxisKey = computed(() => props.xAxis !== void 0 ? String(props.xAxis) : void 0);
|
|
144
|
+
defineSlots();
|
|
105
145
|
</script>
|
|
106
146
|
|
|
107
147
|
<template>
|
|
108
|
-
<CartesianFrame
|
|
148
|
+
<CartesianFrame
|
|
149
|
+
:container="VccsAreaChart"
|
|
150
|
+
:x-axis-key="xAxisKey"
|
|
151
|
+
:container-props="chartContainerProps"
|
|
152
|
+
:percent-axis="stacked === true && percent === true"
|
|
153
|
+
:frame-class="frameClass"
|
|
154
|
+
skeleton-shape="wave"
|
|
155
|
+
v-bind="props"
|
|
156
|
+
>
|
|
157
|
+
<template v-if="$slots.tooltip" #tooltip="scope">
|
|
158
|
+
<slot name="tooltip" v-bind="scope" />
|
|
159
|
+
</template>
|
|
109
160
|
<!--
|
|
110
161
|
GradientDefs builds SVG nodes with `h()` so they land in the SVG namespace
|
|
111
162
|
inside the chart surface. Do not wrap this in vccs `<Customized>`: that
|
|
@@ -118,6 +169,12 @@ const xAxisKey = computed(() => props.xAxis !== void 0 ? String(props.xAxis) : v
|
|
|
118
169
|
:stops="gradientStops"
|
|
119
170
|
:scope="gradientScope"
|
|
120
171
|
/>
|
|
172
|
+
<StrokeGradientDefs
|
|
173
|
+
v-if="strokeGradient?.length"
|
|
174
|
+
:series="paintedSeries"
|
|
175
|
+
:stops="strokeGradient"
|
|
176
|
+
:scope="gradientScope"
|
|
177
|
+
/>
|
|
121
178
|
<!-- Same namespace/`Customized` constraints as GradientDefs above. -->
|
|
122
179
|
<DitherDefs
|
|
123
180
|
v-if="useDither"
|
|
@@ -128,6 +185,13 @@ const xAxisKey = computed(() => props.xAxis !== void 0 ? String(props.xAxis) : v
|
|
|
128
185
|
:fade-stops="ditherWashStops"
|
|
129
186
|
:height="height"
|
|
130
187
|
/>
|
|
188
|
+
<AreaVariantDefs
|
|
189
|
+
v-if="useFillVariant || glow"
|
|
190
|
+
:series="paintedSeries"
|
|
191
|
+
:variant="useFillVariant ? variant : void 0"
|
|
192
|
+
:scope="gradientScope"
|
|
193
|
+
:glow="glow === true"
|
|
194
|
+
/>
|
|
131
195
|
<Area
|
|
132
196
|
v-for="s in series"
|
|
133
197
|
:key="s.dataKey"
|
|
@@ -136,14 +200,25 @@ const xAxisKey = computed(() => props.xAxis !== void 0 ? String(props.xAxis) : v
|
|
|
136
200
|
:y-axis-id="s.yAxisId"
|
|
137
201
|
:type="curve"
|
|
138
202
|
:stack-id="stackId"
|
|
139
|
-
:stroke="s.color"
|
|
203
|
+
:stroke="strokeFor(s.dataKey, s.color)"
|
|
140
204
|
:fill="fillFor(s.dataKey, s.color)"
|
|
141
|
-
:fill-opacity="useGradientFill || useDither ? 1 : fillOpacity"
|
|
205
|
+
:fill-opacity="useGradientFill || useDither || useFillVariant ? 1 : fillOpacity"
|
|
142
206
|
:stroke-width="lineWidth ?? 2"
|
|
143
207
|
:stroke-dasharray="dashArray"
|
|
144
|
-
:
|
|
208
|
+
:filter="glowFor(s.dataKey)"
|
|
209
|
+
:dot="showDots || s.dot"
|
|
145
210
|
:hide="s.hidden"
|
|
146
211
|
:is-animation-active="duration !== void 0 && duration !== 0"
|
|
147
|
-
|
|
212
|
+
>
|
|
213
|
+
<template v-if="showDots" #dot="dotProps">
|
|
214
|
+
<ChartDot
|
|
215
|
+
:cx="dotProps.cx"
|
|
216
|
+
:cy="dotProps.cy"
|
|
217
|
+
:color="s.color"
|
|
218
|
+
:variant="dotVariant"
|
|
219
|
+
:size="dotSize ?? 3"
|
|
220
|
+
/>
|
|
221
|
+
</template>
|
|
222
|
+
</Area>
|
|
148
223
|
</CartesianFrame>
|
|
149
224
|
</template>
|
|
@@ -5,7 +5,11 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
|
|
|
5
5
|
} ? P : {});
|
|
6
6
|
expose: (exposed: {}) => void;
|
|
7
7
|
attrs: any;
|
|
8
|
-
slots: {
|
|
8
|
+
slots: {
|
|
9
|
+
tooltip?: (props: {
|
|
10
|
+
values: T | undefined;
|
|
11
|
+
}) => unknown;
|
|
12
|
+
};
|
|
9
13
|
emit: {};
|
|
10
14
|
}>) => import("vue").VNode & {
|
|
11
15
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
@@ -5,7 +5,11 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
|
|
|
5
5
|
} ? P : {});
|
|
6
6
|
expose: (exposed: {}) => void;
|
|
7
7
|
attrs: any;
|
|
8
|
-
slots: {
|
|
8
|
+
slots: {
|
|
9
|
+
tooltip?: (props: {
|
|
10
|
+
values: T | undefined;
|
|
11
|
+
}) => unknown;
|
|
12
|
+
};
|
|
9
13
|
emit: {};
|
|
10
14
|
}>) => import("vue").VNode & {
|
|
11
15
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed } from "vue";
|
|
2
|
+
import { computed, ref, useId } from "vue";
|
|
3
3
|
import { Bar, BarChart as VccsBarChart, LabelList, Rectangle } from "vccs";
|
|
4
4
|
import CartesianFrame from "./internal/CartesianFrame.vue";
|
|
5
5
|
import CubeBarShape from "./internal/CubeBarShape.vue";
|
|
6
|
+
import VariantBarShape from "./internal/VariantBarShape.vue";
|
|
7
|
+
import BarVariantDefs from "./internal/BarVariantDefs";
|
|
6
8
|
import {
|
|
7
9
|
categoriesToSeries,
|
|
8
10
|
PRIMARY_Y_AXIS_ID
|
|
@@ -13,10 +15,12 @@ import {
|
|
|
13
15
|
DEFAULT_CUBE_RADIUS,
|
|
14
16
|
DEFAULT_CUBE_SIZE
|
|
15
17
|
} from "../utils/cubes";
|
|
18
|
+
import { PATTERNED_BAR_VARIANTS, variantId } from "../utils/variants";
|
|
16
19
|
const props = defineProps({
|
|
17
20
|
yAxis: { type: Array, required: true },
|
|
18
21
|
xAxis: { type: null, required: false },
|
|
19
22
|
stacked: { type: Boolean, required: false },
|
|
23
|
+
percent: { type: Boolean, required: false },
|
|
20
24
|
orientation: { type: String, required: false },
|
|
21
25
|
radius: { type: Number, required: false },
|
|
22
26
|
barGap: { type: [Number, String], required: false },
|
|
@@ -31,6 +35,10 @@ const props = defineProps({
|
|
|
31
35
|
cubeMinSize: { type: Number, required: false },
|
|
32
36
|
cubeMinOpacity: { type: Number, required: false },
|
|
33
37
|
cubeEmptyColor: { type: String, required: false, default: DEFAULT_CUBE_EMPTY_COLOR },
|
|
38
|
+
glow: { type: Boolean, required: false },
|
|
39
|
+
bufferBar: { type: Boolean, required: false },
|
|
40
|
+
hoverHighlight: { type: Boolean, required: false },
|
|
41
|
+
maxHighlight: { type: Boolean, required: false },
|
|
34
42
|
stackAndGrouped: { type: Boolean, required: false },
|
|
35
43
|
stackedGroupedSpacing: { type: Number, required: false },
|
|
36
44
|
data: { type: Array, required: true },
|
|
@@ -69,9 +77,39 @@ const props = defineProps({
|
|
|
69
77
|
xExplicitTicks: { type: Array, required: false },
|
|
70
78
|
yExplicitTicks: { type: Array, required: false },
|
|
71
79
|
crosshairConfig: { type: Object, required: false },
|
|
72
|
-
theme: { type: Object, required: false }
|
|
80
|
+
theme: { type: Object, required: false },
|
|
81
|
+
backgroundPattern: { type: String, required: false },
|
|
82
|
+
legendVariant: { type: String, required: false },
|
|
83
|
+
tooltipVariant: { type: String, required: false },
|
|
84
|
+
tooltipRoundness: { type: String, required: false },
|
|
85
|
+
loading: { type: Boolean, required: false },
|
|
86
|
+
loadingLabel: { type: String, required: false }
|
|
73
87
|
});
|
|
88
|
+
const variantScope = useId();
|
|
74
89
|
const isCubes = computed(() => props.variant === "cubes");
|
|
90
|
+
const isPatterned = computed(() => PATTERNED_BAR_VARIANTS.includes(props.variant));
|
|
91
|
+
const isStripped = computed(() => props.variant === "stripped");
|
|
92
|
+
const usesVariantShape = computed(
|
|
93
|
+
() => isStripped.value || props.bufferBar === true || props.glow === true
|
|
94
|
+
);
|
|
95
|
+
const hoveredIndex = ref(null);
|
|
96
|
+
const lastIndex = computed(() => props.data.length - 1);
|
|
97
|
+
const maxIndex = computed(() => {
|
|
98
|
+
if (!props.maxHighlight) return null;
|
|
99
|
+
let best = -1;
|
|
100
|
+
let bestTotal = Number.NEGATIVE_INFINITY;
|
|
101
|
+
props.data.forEach((row, index) => {
|
|
102
|
+
const total = series.value.reduce((sum, s) => {
|
|
103
|
+
const value = row[s.dataKey];
|
|
104
|
+
return sum + (typeof value === "number" ? value : 0);
|
|
105
|
+
}, 0);
|
|
106
|
+
if (total > bestTotal) {
|
|
107
|
+
bestTotal = total;
|
|
108
|
+
best = index;
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
return best >= 0 ? best : null;
|
|
112
|
+
});
|
|
75
113
|
const valueAccessor = computed(() => {
|
|
76
114
|
const fn = props.valueLabel?.label;
|
|
77
115
|
if (!fn) return void 0;
|
|
@@ -98,6 +136,40 @@ const series = computed(
|
|
|
98
136
|
};
|
|
99
137
|
})
|
|
100
138
|
);
|
|
139
|
+
const paintedSeries = computed(
|
|
140
|
+
() => series.value.filter((s) => typeof s.color === "string").map((s) => ({ dataKey: s.dataKey, color: s.color }))
|
|
141
|
+
);
|
|
142
|
+
const legendColors = computed(
|
|
143
|
+
() => Object.fromEntries(
|
|
144
|
+
series.value.filter((s) => s.color).map((s) => [s.name, s.color])
|
|
145
|
+
)
|
|
146
|
+
);
|
|
147
|
+
function fillFor(dataKey, color) {
|
|
148
|
+
if (!isPatterned.value || color === void 0) return color;
|
|
149
|
+
return `url(#${variantId(props.variant, dataKey, variantScope)})`;
|
|
150
|
+
}
|
|
151
|
+
function bufferFillFor(dataKey) {
|
|
152
|
+
return `url(#${variantId("buffer", dataKey, variantScope)})`;
|
|
153
|
+
}
|
|
154
|
+
function glowFor(dataKey) {
|
|
155
|
+
return props.glow ? `url(#${variantId("glow", dataKey, variantScope)})` : void 0;
|
|
156
|
+
}
|
|
157
|
+
const DIMMED_OPACITY = 0.3;
|
|
158
|
+
function opacityFor(index) {
|
|
159
|
+
if (props.hoverHighlight && hoveredIndex.value !== null) {
|
|
160
|
+
return index === hoveredIndex.value ? 1 : DIMMED_OPACITY;
|
|
161
|
+
}
|
|
162
|
+
if (maxIndex.value !== null) {
|
|
163
|
+
return index === maxIndex.value ? 1 : DIMMED_OPACITY;
|
|
164
|
+
}
|
|
165
|
+
return 1;
|
|
166
|
+
}
|
|
167
|
+
function onBarEnter(index) {
|
|
168
|
+
if (props.hoverHighlight) hoveredIndex.value = index ?? null;
|
|
169
|
+
}
|
|
170
|
+
function onBarLeave() {
|
|
171
|
+
if (props.hoverHighlight) hoveredIndex.value = null;
|
|
172
|
+
}
|
|
101
173
|
const stackIdFor = (yAxisId) => props.stacked ? `stack-${yAxisId}` : void 0;
|
|
102
174
|
const xAxisKey = computed(() => props.xAxis !== void 0 ? String(props.xAxis) : void 0);
|
|
103
175
|
const chartContainerProps = computed(() => {
|
|
@@ -105,18 +177,23 @@ const chartContainerProps = computed(() => {
|
|
|
105
177
|
const barCategoryGap = props.barCategoryGap ?? props.groupPadding;
|
|
106
178
|
return {
|
|
107
179
|
...barGap !== void 0 ? { barGap } : {},
|
|
108
|
-
...barCategoryGap !== void 0 ? { barCategoryGap } : {}
|
|
180
|
+
...barCategoryGap !== void 0 ? { barCategoryGap } : {},
|
|
181
|
+
// Normalising only means something once the series are summed into a stack.
|
|
182
|
+
...props.stacked && props.percent ? { stackOffset: "expand" } : {}
|
|
109
183
|
};
|
|
110
184
|
});
|
|
111
185
|
function barRadius(index) {
|
|
112
186
|
const r = props.radius ?? 2;
|
|
187
|
+
const horizontal = props.orientation === "horizontal";
|
|
188
|
+
if (isStripped.value && !props.stacked) {
|
|
189
|
+
return horizontal ? [0, r, r, 0] : [r, r, 0, 0];
|
|
190
|
+
}
|
|
113
191
|
if (!props.stacked) return r;
|
|
114
192
|
const isLast = index === series.value.length - 1;
|
|
115
|
-
if (
|
|
116
|
-
return isLast ? [0, r, r, 0] : 0;
|
|
117
|
-
}
|
|
193
|
+
if (horizontal) return isLast ? [0, r, r, 0] : 0;
|
|
118
194
|
return isLast ? [r, r, 0, 0] : 0;
|
|
119
195
|
}
|
|
196
|
+
defineSlots();
|
|
120
197
|
</script>
|
|
121
198
|
|
|
122
199
|
<template>
|
|
@@ -124,8 +201,25 @@ function barRadius(index) {
|
|
|
124
201
|
:container="VccsBarChart"
|
|
125
202
|
:x-axis-key="xAxisKey"
|
|
126
203
|
:container-props="chartContainerProps"
|
|
204
|
+
:percent-axis="stacked === true && percent === true"
|
|
205
|
+
:legend-colors="legendColors"
|
|
127
206
|
v-bind="props"
|
|
128
207
|
>
|
|
208
|
+
<!--
|
|
209
|
+
Same namespace/`Customized` constraints as GradientDefs: these are built
|
|
210
|
+
with `h()` so they land in the SVG namespace and `url(#…)` resolves.
|
|
211
|
+
-->
|
|
212
|
+
<BarVariantDefs
|
|
213
|
+
v-if="isPatterned || glow || bufferBar"
|
|
214
|
+
:series="paintedSeries"
|
|
215
|
+
:variant="variant"
|
|
216
|
+
:scope="variantScope"
|
|
217
|
+
:glow="glow === true"
|
|
218
|
+
:buffer="bufferBar === true"
|
|
219
|
+
/>
|
|
220
|
+
<template v-if="$slots.tooltip" #tooltip="scope">
|
|
221
|
+
<slot name="tooltip" v-bind="scope" />
|
|
222
|
+
</template>
|
|
129
223
|
<Bar
|
|
130
224
|
v-for="(s, i) in series"
|
|
131
225
|
:key="s.dataKey"
|
|
@@ -133,7 +227,7 @@ function barRadius(index) {
|
|
|
133
227
|
:name="s.name"
|
|
134
228
|
:y-axis-id="s.yAxisId"
|
|
135
229
|
:stack-id="stackIdFor(s.yAxisId)"
|
|
136
|
-
:fill="s.color"
|
|
230
|
+
:fill="fillFor(s.dataKey, s.color)"
|
|
137
231
|
:radius="isCubes ? 0 : barRadius(i)"
|
|
138
232
|
:hide="s.hidden"
|
|
139
233
|
:is-animation-active="duration !== void 0 && duration !== 0"
|
|
@@ -159,7 +253,30 @@ function barRadius(index) {
|
|
|
159
253
|
:empty-color="cubeEmptyColor"
|
|
160
254
|
:include-empty="!stacked || i === 0"
|
|
161
255
|
/>
|
|
162
|
-
<
|
|
256
|
+
<VariantBarShape
|
|
257
|
+
v-else-if="usesVariantShape"
|
|
258
|
+
:x="shapeProps.x"
|
|
259
|
+
:y="shapeProps.y"
|
|
260
|
+
:width="shapeProps.width"
|
|
261
|
+
:height="shapeProps.height"
|
|
262
|
+
:radius="barRadius(i)"
|
|
263
|
+
:fill="shapeProps.fill ?? s.color"
|
|
264
|
+
:color="s.color"
|
|
265
|
+
:capped="isStripped"
|
|
266
|
+
:is-buffer="bufferBar === true && shapeProps.index === lastIndex"
|
|
267
|
+
:buffer-fill="bufferFillFor(s.dataKey)"
|
|
268
|
+
:filter="glowFor(s.dataKey)"
|
|
269
|
+
:opacity="opacityFor(shapeProps.index)"
|
|
270
|
+
@mouseenter="onBarEnter(shapeProps.index)"
|
|
271
|
+
@mouseleave="onBarLeave"
|
|
272
|
+
/>
|
|
273
|
+
<Rectangle
|
|
274
|
+
v-else
|
|
275
|
+
v-bind="shapeProps"
|
|
276
|
+
:opacity="opacityFor(shapeProps.index)"
|
|
277
|
+
@mouseenter="onBarEnter(shapeProps.index)"
|
|
278
|
+
@mouseleave="onBarLeave"
|
|
279
|
+
/>
|
|
163
280
|
</template>
|
|
164
281
|
<LabelList
|
|
165
282
|
v-if="valueLabel && !isCubes"
|
|
@@ -5,7 +5,11 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
|
|
|
5
5
|
} ? P : {});
|
|
6
6
|
expose: (exposed: {}) => void;
|
|
7
7
|
attrs: any;
|
|
8
|
-
slots: {
|
|
8
|
+
slots: {
|
|
9
|
+
tooltip?: (props: {
|
|
10
|
+
values: T | undefined;
|
|
11
|
+
}) => unknown;
|
|
12
|
+
};
|
|
9
13
|
emit: {};
|
|
10
14
|
}>) => import("vue").VNode & {
|
|
11
15
|
__ctx?: Awaited<typeof __VLS_setup>;
|