layerchart 2.0.0-next.61 → 2.0.0-next.63
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/dist/canvas.d.ts +6 -2
- package/dist/canvas.js +6 -2
- package/dist/components/Arc/Arc.base.svelte +49 -11
- package/dist/components/Arc/Arc.shared.svelte.d.ts +2 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-full-circle--360-degree-range--1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-full-circle--360-degree-range--2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-innerRadius-of-0--pie-slice--1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-innerRadius-of-0--pie-slice--2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-negative-domain-values-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-negative-domain-values-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-partial-arc--e-g---180-degrees--1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-partial-arc--e-g---180-degrees--2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-at-max-domain-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-at-max-domain-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-below-domain-min-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-below-domain-min-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-exceeding-domain-max-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-exceeding-domain-max-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-of-0-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-of-0-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-events-should-handle-pointer-enter-events-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-events-should-handle-pointer-enter-events-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-events-should-handle-pointer-move-events-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-events-should-handle-pointer-move-events-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-events-should-handle-touch-move-events-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-events-should-handle-touch-move-events-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-custom-class-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-custom-class-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-fill-color-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-fill-color-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-fillOpacity-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-fillOpacity-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-offset-to-arc-position-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-offset-to-arc-position-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-opacity-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-opacity-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-stroke-color-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-stroke-color-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-strokeWidth-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-strokeWidth-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-zero-offset-by-default-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-zero-offset-by-default-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-call-tooltip-hide-on-pointer-leave-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-call-tooltip-hide-on-pointer-leave-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-call-tooltip-show-on-pointer-enter-with-data-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-call-tooltip-show-on-pointer-enter-with-data-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-handle-custom-start-angle-in-range-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-handle-custom-start-angle-in-range-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-have-stroke--none--by-default-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-have-stroke--none--by-default-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-an-arc-path-with-value-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-an-arc-path-with-value-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-when-track-prop-is-provided-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-when-track-prop-is-provided-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-custom-class-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-custom-class-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackCornerRadius-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackCornerRadius-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackEndAngle-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackEndAngle-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackInnerRadius-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackInnerRadius-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackInnerRadius-and-trackOuterRadius-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackInnerRadius-and-trackOuterRadius-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackOuterRadius-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackOuterRadius-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackPadAngle-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackPadAngle-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackStartAngle-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackStartAngle-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackStartAngle-and-trackEndAngle-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackStartAngle-and-trackEndAngle-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-both-startAngle-and-endAngle-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-both-startAngle-and-endAngle-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-cornerRadius-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-cornerRadius-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-custom-domain-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-custom-domain-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-custom-domain-and-range-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-custom-domain-and-range-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-custom-range-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-custom-range-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-endAngle-in-radians-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-endAngle-in-radians-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-innerRadius-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-innerRadius-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-innerRadius-and-outerRadius-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-innerRadius-and-outerRadius-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-outerRadius-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-outerRadius-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-padAngle-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-padAngle-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-startAngle-in-radians-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-startAngle-in-radians-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-should-render-Arc-element-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-should-render-Arc-element-2.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-should-render-track-1.png +0 -0
- package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-should-render-track-2.png +0 -0
- package/dist/components/ArcLabel/ArcLabel.shared.svelte.d.ts +1 -0
- package/dist/components/{ArcLabel.svelte.test.js → ArcLabel/ArcLabel.svelte.test.js} +3 -3
- package/dist/components/ArcLabel/__screenshots__/ArcLabel.svelte.test.ts/ArcLabel-renders-a-text-element-with-the-supplied-value-at-the-centroid-1.png +0 -0
- package/dist/components/ArcLabel/__screenshots__/ArcLabel.svelte.test.ts/ArcLabel-renders-a-text-element-with-the-supplied-value-at-the-centroid-2.png +0 -0
- package/dist/components/Blur/Blur.canvas.svelte +25 -0
- package/dist/components/Blur/Blur.canvas.svelte.d.ts +4 -0
- package/dist/components/Blur/Blur.html.svelte +11 -0
- package/dist/components/Blur/Blur.html.svelte.d.ts +4 -0
- package/dist/components/{Blur.svelte.d.ts → Blur/Blur.shared.svelte.d.ts} +3 -5
- package/dist/components/Blur/Blur.svelte +23 -0
- package/dist/components/Blur/Blur.svelte.d.ts +4 -0
- package/dist/components/Blur/Blur.svg.svelte +24 -0
- package/dist/components/Blur/Blur.svg.svelte.d.ts +4 -0
- package/dist/components/Chart/Chart.base.svelte +13 -7
- package/dist/components/Chart/ChartCore.svelte.test.d.ts +1 -0
- package/dist/components/{ChartCore.svelte.test.js → Chart/ChartCore.svelte.test.js} +1 -1
- package/dist/components/Circle/Circle.shared.svelte.js +24 -5
- package/dist/components/Circle/Circle.svelte.test.js +70 -0
- package/dist/components/Dodge/Dodge.shared.svelte.d.ts +132 -0
- package/dist/components/Dodge/Dodge.shared.svelte.js +240 -0
- package/dist/components/Dodge/Dodge.svelte +88 -0
- package/dist/components/Dodge/Dodge.svelte.d.ts +27 -0
- package/dist/components/Dodge/Dodge.test.d.ts +1 -0
- package/dist/components/Dodge/Dodge.test.js +128 -0
- package/dist/components/Image/Image.html.svelte +0 -8
- package/dist/components/Image/Image.svg.svelte +1 -9
- package/dist/components/Link/Link.base.svelte +15 -9
- package/dist/components/Path/Path.canvas.svelte +5 -2
- package/dist/components/Path/Path.shared.svelte.d.ts +17 -4
- package/dist/components/Path/Path.shared.svelte.js +26 -8
- package/dist/components/Path/Path.svg.svelte +75 -60
- package/dist/components/Pattern/Pattern.canvas.svelte +4 -1
- package/dist/components/Pattern/Pattern.shared.svelte.d.ts +31 -2
- package/dist/components/Pattern/Pattern.shared.svelte.js +20 -1
- package/dist/components/Pattern/Pattern.svg.svelte +17 -1
- package/dist/components/Raster/Raster.base.svelte +2 -8
- package/dist/components/Rect/Rect.canvas.svelte +2 -4
- package/dist/components/Rect/Rect.canvas.svelte.d.ts +1 -1
- package/dist/components/Rect/Rect.html.svelte +3 -9
- package/dist/components/Rect/Rect.html.svelte.d.ts +1 -1
- package/dist/components/Rect/Rect.shared.svelte.d.ts +5 -2
- package/dist/components/Rect/Rect.shared.svelte.js +26 -13
- package/dist/components/Rect/Rect.svelte.test.js +45 -0
- package/dist/components/Rect/Rect.svg.svelte +36 -21
- package/dist/components/Rect/Rect.svg.svelte.d.ts +1 -1
- package/dist/components/RectClipPath/RectClipPath.base.svelte +25 -1
- package/dist/components/RectClipPath/RectClipPath.shared.svelte.d.ts +8 -0
- package/dist/components/Spline/Spline.base.svelte +3 -2
- package/dist/components/Text/Text.canvas.svelte +9 -0
- package/dist/components/Text/Text.html.svelte +6 -0
- package/dist/components/Text/Text.shared.svelte.d.ts +25 -2
- package/dist/components/Text/Text.shared.svelte.js +36 -5
- package/dist/components/Text/Text.svelte.test.js +40 -0
- package/dist/components/Text/Text.svg.svelte +7 -1
- package/dist/components/Trail/Trail.base.svelte +10 -7
- package/dist/components/Waffle/Waffle.shared.svelte.d.ts +182 -0
- package/dist/components/Waffle/Waffle.shared.svelte.js +300 -0
- package/dist/components/Waffle/Waffle.svelte +148 -0
- package/dist/components/Waffle/Waffle.svelte.d.ts +5 -0
- package/dist/components/charts/__screenshots__/ArcChart.svelte.test.ts/ArcChart-uses-the-chart-value-accessor-for-explicit-per-series-tooltip-values-1.png +0 -0
- package/dist/components/charts/__screenshots__/ArcChart.svelte.test.ts/ArcChart-uses-the-chart-value-accessor-for-explicit-per-series-tooltip-values-2.png +0 -0
- package/dist/components/charts/__screenshots__/BarChart.svelte.test.ts/BarChart-legend-series-toggle-adjusts-group-scale-should-adjust-grouped-bar-widths-when-series-are-toggled-via-legend-1.png +0 -0
- package/dist/components/charts/__screenshots__/PieChart.svelte.test.ts/PieChart-uses-hovered-slice-identity-for-implicit-tooltip-series-1.png +0 -0
- package/dist/components/charts/__screenshots__/PieChart.svelte.test.ts/PieChart-uses-hovered-slice-identity-for-implicit-tooltip-series-2.png +0 -0
- package/dist/components/index.d.ts +6 -2
- package/dist/components/index.js +6 -2
- package/dist/html.d.ts +6 -2
- package/dist/html.js +6 -2
- package/dist/states/chart.svelte.d.ts +4 -2
- package/dist/states/chart.svelte.js +53 -22
- package/dist/states/chart.svelte.test.js +54 -1
- package/dist/states/series.svelte.js +9 -13
- package/dist/states/series.svelte.test.js +5 -1
- package/dist/svg.d.ts +6 -2
- package/dist/svg.js +6 -2
- package/dist/utils/canvas.js +54 -13
- package/dist/utils/canvas.svelte.test.js +44 -0
- package/dist/utils/download.d.ts +5 -3
- package/dist/utils/download.js +36 -16
- package/dist/utils/stack.js +10 -2
- package/package.json +1 -1
- package/dist/components/Blur.svelte +0 -49
- /package/dist/components/{ArcLabel.svelte.test.d.ts → ArcLabel/ArcLabel.svelte.test.d.ts} +0 -0
- /package/dist/components/{ChartCore.svelte.test.d.ts → Blur/Blur.shared.svelte.js} +0 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { WaffleProps, WafflePropsWithoutHTML } from './Waffle.shared.svelte.js';
|
|
2
|
+
import { type WaffleProps } from './Waffle.shared.svelte.js';
|
|
3
|
+
declare const Waffle: import("svelte").Component<WaffleProps, {}, "">;
|
|
4
|
+
type Waffle = ReturnType<typeof Waffle>;
|
|
5
|
+
export default Waffle;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -18,8 +18,8 @@ export { default as Bar } from './Bar/Bar.svelte';
|
|
|
18
18
|
export * from './Bar/Bar.svelte';
|
|
19
19
|
export { default as Bars } from './Bars/Bars.svelte';
|
|
20
20
|
export * from './Bars/Bars.svelte';
|
|
21
|
-
export { default as Blur } from './Blur.svelte';
|
|
22
|
-
export * from './Blur.svelte';
|
|
21
|
+
export { default as Blur } from './Blur/Blur.svelte';
|
|
22
|
+
export * from './Blur/Blur.svelte';
|
|
23
23
|
export { default as BoxPlot } from './BoxPlot/BoxPlot.svelte';
|
|
24
24
|
export * from './BoxPlot/BoxPlot.svelte';
|
|
25
25
|
export { default as Bounds } from './Bounds.svelte';
|
|
@@ -49,6 +49,8 @@ export { default as Contour } from './Contour/Contour.svelte';
|
|
|
49
49
|
export * from './Contour/Contour.svelte';
|
|
50
50
|
export { default as Density } from './Density/Density.svelte';
|
|
51
51
|
export * from './Density/Density.svelte';
|
|
52
|
+
export { default as Dodge } from './Dodge/Dodge.svelte';
|
|
53
|
+
export * from './Dodge/Dodge.svelte';
|
|
52
54
|
export { default as Ellipse } from './Ellipse/Ellipse.svelte';
|
|
53
55
|
export * from './Ellipse/Ellipse.svelte';
|
|
54
56
|
export { default as Frame } from './Frame/Frame.svelte';
|
|
@@ -125,5 +127,7 @@ export { default as Violin } from './Violin/Violin.svelte';
|
|
|
125
127
|
export * from './Violin/Violin.svelte';
|
|
126
128
|
export { default as Voronoi } from './Voronoi/Voronoi.svelte';
|
|
127
129
|
export * from './Voronoi/Voronoi.svelte';
|
|
130
|
+
export { default as Waffle } from './Waffle/Waffle.svelte';
|
|
131
|
+
export * from './Waffle/Waffle.svelte';
|
|
128
132
|
export { default as WebGL } from './layers/WebGL.svelte';
|
|
129
133
|
export * from './layers/WebGL.svelte';
|
package/dist/components/index.js
CHANGED
|
@@ -18,8 +18,8 @@ export { default as Bar } from './Bar/Bar.svelte';
|
|
|
18
18
|
export * from './Bar/Bar.svelte';
|
|
19
19
|
export { default as Bars } from './Bars/Bars.svelte';
|
|
20
20
|
export * from './Bars/Bars.svelte';
|
|
21
|
-
export { default as Blur } from './Blur.svelte';
|
|
22
|
-
export * from './Blur.svelte';
|
|
21
|
+
export { default as Blur } from './Blur/Blur.svelte';
|
|
22
|
+
export * from './Blur/Blur.svelte';
|
|
23
23
|
export { default as BoxPlot } from './BoxPlot/BoxPlot.svelte';
|
|
24
24
|
export * from './BoxPlot/BoxPlot.svelte';
|
|
25
25
|
export { default as Bounds } from './Bounds.svelte';
|
|
@@ -49,6 +49,8 @@ export { default as Contour } from './Contour/Contour.svelte';
|
|
|
49
49
|
export * from './Contour/Contour.svelte';
|
|
50
50
|
export { default as Density } from './Density/Density.svelte';
|
|
51
51
|
export * from './Density/Density.svelte';
|
|
52
|
+
export { default as Dodge } from './Dodge/Dodge.svelte';
|
|
53
|
+
export * from './Dodge/Dodge.svelte';
|
|
52
54
|
export { default as Ellipse } from './Ellipse/Ellipse.svelte';
|
|
53
55
|
export * from './Ellipse/Ellipse.svelte';
|
|
54
56
|
export { default as Frame } from './Frame/Frame.svelte';
|
|
@@ -125,5 +127,7 @@ export { default as Violin } from './Violin/Violin.svelte';
|
|
|
125
127
|
export * from './Violin/Violin.svelte';
|
|
126
128
|
export { default as Voronoi } from './Voronoi/Voronoi.svelte';
|
|
127
129
|
export * from './Voronoi/Voronoi.svelte';
|
|
130
|
+
export { default as Waffle } from './Waffle/Waffle.svelte';
|
|
131
|
+
export * from './Waffle/Waffle.svelte';
|
|
128
132
|
export { default as WebGL } from './layers/WebGL.svelte';
|
|
129
133
|
export * from './layers/WebGL.svelte';
|
package/dist/html.d.ts
CHANGED
|
@@ -72,8 +72,8 @@ export { default as Calendar } from './components/Calendar/Calendar.html.svelte'
|
|
|
72
72
|
export type { CalendarProps, CalendarPropsWithoutHTML, CalendarCell, } from './components/Calendar/Calendar.shared.svelte.js';
|
|
73
73
|
export { default as Month } from './components/Month/Month.html.svelte';
|
|
74
74
|
export type { MonthProps, MonthPropsWithoutHTML, MonthCell, } from './components/Month/Month.shared.svelte.js';
|
|
75
|
-
export { default as Blur } from './components/Blur.svelte';
|
|
76
|
-
export * from './components/Blur.svelte';
|
|
75
|
+
export { default as Blur } from './components/Blur/Blur.svelte';
|
|
76
|
+
export * from './components/Blur/Blur.svelte';
|
|
77
77
|
export { default as Bounds } from './components/Bounds.svelte';
|
|
78
78
|
export * from './components/Bounds.svelte';
|
|
79
79
|
export { default as BrushContext } from './components/BrushContext.svelte';
|
|
@@ -114,3 +114,7 @@ export { default as Sankey } from './components/graph/Sankey.svelte';
|
|
|
114
114
|
export * from './components/graph/Sankey.svelte';
|
|
115
115
|
export { default as ForceSimulation } from './components/force/ForceSimulation.svelte';
|
|
116
116
|
export * from './components/force/ForceSimulation.svelte';
|
|
117
|
+
export { default as Dodge } from './components/Dodge/Dodge.svelte';
|
|
118
|
+
export * from './components/Dodge/Dodge.svelte';
|
|
119
|
+
export { default as Waffle } from './components/Waffle/Waffle.svelte';
|
|
120
|
+
export * from './components/Waffle/Waffle.svelte';
|
package/dist/html.js
CHANGED
|
@@ -47,8 +47,8 @@ export { default as Month } from './components/Month/Month.html.svelte';
|
|
|
47
47
|
// helpers, context providers, or composite chart wrappers). Re-exported here
|
|
48
48
|
// so the per-layer sub-path has a complete API.
|
|
49
49
|
// Helpers / context providers
|
|
50
|
-
export { default as Blur } from './components/Blur.svelte';
|
|
51
|
-
export * from './components/Blur.svelte';
|
|
50
|
+
export { default as Blur } from './components/Blur/Blur.svelte';
|
|
51
|
+
export * from './components/Blur/Blur.svelte';
|
|
52
52
|
export { default as Bounds } from './components/Bounds.svelte';
|
|
53
53
|
export * from './components/Bounds.svelte';
|
|
54
54
|
export { default as BrushContext } from './components/BrushContext.svelte';
|
|
@@ -91,3 +91,7 @@ export { default as Sankey } from './components/graph/Sankey.svelte';
|
|
|
91
91
|
export * from './components/graph/Sankey.svelte';
|
|
92
92
|
export { default as ForceSimulation } from './components/force/ForceSimulation.svelte';
|
|
93
93
|
export * from './components/force/ForceSimulation.svelte';
|
|
94
|
+
export { default as Dodge } from './components/Dodge/Dodge.svelte';
|
|
95
|
+
export * from './components/Dodge/Dodge.svelte';
|
|
96
|
+
export { default as Waffle } from './components/Waffle/Waffle.svelte';
|
|
97
|
+
export * from './components/Waffle/Waffle.svelte';
|
|
@@ -50,7 +50,6 @@ export interface RegisterComponentOptions<T extends Element = Element> {
|
|
|
50
50
|
}
|
|
51
51
|
export declare class ChartState<TData = any, XScale extends AnyScale = AnyScale, YScale extends AnyScale = AnyScale> {
|
|
52
52
|
#private;
|
|
53
|
-
private _propsGetter;
|
|
54
53
|
props: ChartPropsWithoutHTML<TData, XScale, YScale>;
|
|
55
54
|
geoState: GeoState;
|
|
56
55
|
transformState: TransformState;
|
|
@@ -90,7 +89,10 @@ export declare class ChartState<TData = any, XScale extends AnyScale = AnyScale,
|
|
|
90
89
|
private _xDomainIsDate;
|
|
91
90
|
private _yDomainIsDate;
|
|
92
91
|
meta: Record<string, any>;
|
|
93
|
-
constructor(
|
|
92
|
+
constructor(props: ChartPropsWithoutHTML<TData, XScale, YScale>, overrides?: {
|
|
93
|
+
brushXDomain?: () => BrushDomainType | undefined;
|
|
94
|
+
brushYDomain?: () => BrushDomainType | undefined;
|
|
95
|
+
});
|
|
94
96
|
containerWidth: number;
|
|
95
97
|
containerHeight: number;
|
|
96
98
|
data: import("d3-sankey").SankeyGraph<any, any> | readonly TData[] | import("d3-hierarchy").HierarchyNode<TData>;
|
|
@@ -17,11 +17,22 @@ const defaultPadding = { top: 0, right: 0, bottom: 0, left: 0 };
|
|
|
17
17
|
const EMPTY_SERIES = [];
|
|
18
18
|
/** Svelte context key for tracking the nearest parent ComponentNode. */
|
|
19
19
|
const _ParentNodeContext = new Context('ComponentTreeParent');
|
|
20
|
+
/** Mark info is "empty" when none of the fields the chart uses for series /
|
|
21
|
+
* domain inference are populated. Pixel-mode primitives produce empty info
|
|
22
|
+
* since they have no string/function accessors and no own data. */
|
|
23
|
+
function isEmptyMarkInfo(info) {
|
|
24
|
+
return !info.x && !info.y && !info.data && !info.color && !info.seriesKey && !info.label;
|
|
25
|
+
}
|
|
20
26
|
export class ChartState {
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
//
|
|
24
|
-
props
|
|
27
|
+
// The `$props()` proxy from the host component. Reads on `this.props.X` go
|
|
28
|
+
// straight through to the underlying reactive prop — no spread / no derived
|
|
29
|
+
// wrapper needed.
|
|
30
|
+
props;
|
|
31
|
+
// Brush-domain overrides. The host component owns the brush state as local
|
|
32
|
+
// `$state` and supplies these getters so brush selections take precedence
|
|
33
|
+
// over `props.xDomain` / `props.yDomain` when reading the effective domain.
|
|
34
|
+
#brushXDomain;
|
|
35
|
+
#brushYDomain;
|
|
25
36
|
// State / contexts
|
|
26
37
|
geoState;
|
|
27
38
|
transformState = $state(null);
|
|
@@ -132,14 +143,26 @@ export class ChartState {
|
|
|
132
143
|
};
|
|
133
144
|
});
|
|
134
145
|
if (markInfo && !insideCompositeMark) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
146
|
+
// Probe once at construction: if mark info is initially empty
|
|
147
|
+
// (pixel-mode primitives where cx/cy/r are numbers), skip the
|
|
148
|
+
// tracking $effect entirely. This is the common case for
|
|
149
|
+
// mark-heavy scenes (force simulations, scatter plots with
|
|
150
|
+
// pixel coordinates) and avoids one effect frame per primitive.
|
|
151
|
+
//
|
|
152
|
+
// Trade-off: a primitive that starts in pixel mode and later
|
|
153
|
+
// flips to data mode (e.g. cx changes from number to string at
|
|
154
|
+
// runtime) won't register a mark. This is uncommon — modes are
|
|
155
|
+
// typically static — but if needed, use explicit `series` on the
|
|
156
|
+
// chart instead of relying on implicit mark-derived series.
|
|
157
|
+
const initial = untrack(markInfo);
|
|
158
|
+
if (!isEmptyMarkInfo(initial)) {
|
|
159
|
+
$effect(() => {
|
|
160
|
+
const info = markInfo();
|
|
161
|
+
if (isEmptyMarkInfo(info))
|
|
162
|
+
return;
|
|
163
|
+
return untrack(() => this.registerMark(info));
|
|
164
|
+
});
|
|
165
|
+
}
|
|
143
166
|
}
|
|
144
167
|
return node;
|
|
145
168
|
}
|
|
@@ -159,8 +182,10 @@ export class ChartState {
|
|
|
159
182
|
_yDomainIsDate = false;
|
|
160
183
|
// Meta data - reactive to props.meta changes
|
|
161
184
|
meta = $derived(this.props.meta ?? {});
|
|
162
|
-
constructor(
|
|
163
|
-
this.
|
|
185
|
+
constructor(props, overrides) {
|
|
186
|
+
this.props = props;
|
|
187
|
+
this.#brushXDomain = overrides?.brushXDomain ?? (() => undefined);
|
|
188
|
+
this.#brushYDomain = overrides?.brushYDomain ?? (() => undefined);
|
|
164
189
|
// Create GeoState instance — pass a dimensions getter so projection
|
|
165
190
|
// is available during SSR (where $effect doesn't run)
|
|
166
191
|
this.geoState = new GeoState(() => this.props.geo ?? {}, () => ({ width: this.width, height: this.height }));
|
|
@@ -272,7 +297,7 @@ export class ChartState {
|
|
|
272
297
|
}
|
|
273
298
|
});
|
|
274
299
|
// Set up domain motion if motion prop is configured
|
|
275
|
-
const motionProp =
|
|
300
|
+
const motionProp = props.motion;
|
|
276
301
|
if (motionProp) {
|
|
277
302
|
const resolved = parseMotionProp(motionProp);
|
|
278
303
|
this._xDomainMotion = createControlledMotion([], resolved);
|
|
@@ -373,7 +398,7 @@ export class ChartState {
|
|
|
373
398
|
if (this.props.bandPadding != null && this.valueAxis === 'y') {
|
|
374
399
|
return scaleBand().padding(this.props.bandPadding);
|
|
375
400
|
}
|
|
376
|
-
return autoScale(this.props.xDomain, this.flatData, this.x);
|
|
401
|
+
return autoScale(this.#brushXDomain() ?? this.props.xDomain, this.flatData, this.x);
|
|
377
402
|
});
|
|
378
403
|
_yScaleProp = $derived.by(() => {
|
|
379
404
|
if (this.props.yScale)
|
|
@@ -385,7 +410,7 @@ export class ChartState {
|
|
|
385
410
|
if (this.props.bandPadding != null && this.valueAxis === 'x') {
|
|
386
411
|
return scaleBand().padding(this.props.bandPadding);
|
|
387
412
|
}
|
|
388
|
-
return autoScale(this.props.yDomain, this.flatData, this.y);
|
|
413
|
+
return autoScale(this.#brushYDomain() ?? this.props.yDomain, this.flatData, this.y);
|
|
389
414
|
});
|
|
390
415
|
_zScaleProp = $derived.by(() => {
|
|
391
416
|
return this.props.zScale ?? autoScale(this.props.zDomain, this.flatData, this.props.z);
|
|
@@ -579,7 +604,9 @@ export class ChartState {
|
|
|
579
604
|
return undefined;
|
|
580
605
|
}
|
|
581
606
|
resolveDomain(axis) {
|
|
582
|
-
const domain = axis === 'x'
|
|
607
|
+
const domain = axis === 'x'
|
|
608
|
+
? (this.#brushXDomain() ?? this.props.xDomain)
|
|
609
|
+
: (this.#brushYDomain() ?? this.props.yDomain);
|
|
583
610
|
const interval = axis === 'x' ? this.props.xInterval : this.props.yInterval;
|
|
584
611
|
const explicitBaseline = axis === 'x' ? this.props.xBaseline : this.props.yBaseline;
|
|
585
612
|
// Use explicit baseline if provided (null means "no baseline"), otherwise auto-derive
|
|
@@ -629,11 +656,15 @@ export class ChartState {
|
|
|
629
656
|
extraMarkValues.push(...info.data.flatMap(accessor(markAccessor)));
|
|
630
657
|
}
|
|
631
658
|
}
|
|
632
|
-
const allValues = [...seriesValues, ...extraMarkValues];
|
|
633
|
-
if (
|
|
634
|
-
|
|
659
|
+
const allValues = [...seriesValues, ...extraMarkValues].filter((v) => v != null);
|
|
660
|
+
if (allValues.length > 0) {
|
|
661
|
+
if (baseline != null) {
|
|
662
|
+
return [min([baseline, ...allValues]), max([baseline, ...allValues])];
|
|
663
|
+
}
|
|
664
|
+
return extent(allValues);
|
|
635
665
|
}
|
|
636
|
-
|
|
666
|
+
// Series are metadata-only (e.g. categorical legend with no per-series
|
|
667
|
+
// values on the axis) — fall through to other resolution paths.
|
|
637
668
|
}
|
|
638
669
|
}
|
|
639
670
|
// Interval-based domain: extend to the next interval offset
|
|
@@ -9,7 +9,7 @@ function createChartState(props) {
|
|
|
9
9
|
let cleanup;
|
|
10
10
|
let state;
|
|
11
11
|
cleanup = $effect.root(() => {
|
|
12
|
-
state = new ChartState(
|
|
12
|
+
state = new ChartState(props);
|
|
13
13
|
});
|
|
14
14
|
// Access derived values after reactive graph is set up
|
|
15
15
|
flushSync();
|
|
@@ -893,6 +893,59 @@ describe('ChartState implicit series domain update on visibility toggle', () =>
|
|
|
893
893
|
}
|
|
894
894
|
});
|
|
895
895
|
});
|
|
896
|
+
describe('ChartState metadata-only series', () => {
|
|
897
|
+
it('should not produce [undefined, undefined] domain when items lack series-key properties', () => {
|
|
898
|
+
const data = [
|
|
899
|
+
{ date: '2024-01', category: 'svelte' },
|
|
900
|
+
{ date: '2024-02', category: 'sveltekit' },
|
|
901
|
+
{ date: '2024-03', category: 'ecosystem' },
|
|
902
|
+
];
|
|
903
|
+
const { state, cleanup } = createChartState({
|
|
904
|
+
data,
|
|
905
|
+
x: 'date',
|
|
906
|
+
valueAxis: 'y',
|
|
907
|
+
series: [
|
|
908
|
+
{ key: 'svelte', color: 'red' },
|
|
909
|
+
{ key: 'sveltekit', color: 'orange' },
|
|
910
|
+
{ key: 'ecosystem', color: 'blue' },
|
|
911
|
+
],
|
|
912
|
+
});
|
|
913
|
+
try {
|
|
914
|
+
expect(state._yDomain).toBeUndefined();
|
|
915
|
+
}
|
|
916
|
+
finally {
|
|
917
|
+
cleanup();
|
|
918
|
+
}
|
|
919
|
+
});
|
|
920
|
+
it('should remain stable across visibility toggles instead of throwing', () => {
|
|
921
|
+
const data = [
|
|
922
|
+
{ date: '2024-01', category: 'svelte' },
|
|
923
|
+
{ date: '2024-02', category: 'sveltekit' },
|
|
924
|
+
];
|
|
925
|
+
const { state, cleanup } = createChartState({
|
|
926
|
+
data,
|
|
927
|
+
x: 'date',
|
|
928
|
+
valueAxis: 'y',
|
|
929
|
+
series: [
|
|
930
|
+
{ key: 'svelte', color: 'red' },
|
|
931
|
+
{ key: 'sveltekit', color: 'orange' },
|
|
932
|
+
],
|
|
933
|
+
motion: { type: 'spring' },
|
|
934
|
+
});
|
|
935
|
+
try {
|
|
936
|
+
expect(state._yDomain).toBeUndefined();
|
|
937
|
+
expect(() => {
|
|
938
|
+
state.seriesState.selectedKeys.toggle('svelte');
|
|
939
|
+
flushSync();
|
|
940
|
+
}).not.toThrow();
|
|
941
|
+
expect(state._yDomain).toBeUndefined();
|
|
942
|
+
expect(state.seriesState.visibleSeries).toHaveLength(1);
|
|
943
|
+
}
|
|
944
|
+
finally {
|
|
945
|
+
cleanup();
|
|
946
|
+
}
|
|
947
|
+
});
|
|
948
|
+
});
|
|
896
949
|
describe('ChartState degenerate domain', () => {
|
|
897
950
|
it('should expand degenerate y domain [0, 0] to [0, 1]', () => {
|
|
898
951
|
const data = [
|
|
@@ -9,19 +9,6 @@ export class SeriesState {
|
|
|
9
9
|
#series = $derived(this._getSeries());
|
|
10
10
|
#stackConfig = $derived(this._getStackConfig());
|
|
11
11
|
selectedKeys;
|
|
12
|
-
/**
|
|
13
|
-
* Reactively syncs selectedKeys when series `selected` props change.
|
|
14
|
-
* When any series explicitly sets `selected: false`, the remaining series
|
|
15
|
-
* (with `selected` undefined or true) are pre-selected.
|
|
16
|
-
*/
|
|
17
|
-
#_syncSelectedFromProps = $effect.root(() => {
|
|
18
|
-
$effect(() => {
|
|
19
|
-
const keys = SeriesState.#selectedKeysFromSeries(this.#series);
|
|
20
|
-
if (keys) {
|
|
21
|
-
this.selectedKeys.current = keys;
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
12
|
/**
|
|
26
13
|
* The current highlight series key for the chart.
|
|
27
14
|
*/
|
|
@@ -32,6 +19,15 @@ export class SeriesState {
|
|
|
32
19
|
// Compute initial selectedKeys synchronously from series `selected` props
|
|
33
20
|
const initialKeys = SeriesState.#selectedKeysFromSeries(getSeries());
|
|
34
21
|
this.selectedKeys = new SelectionState({ initial: initialKeys ?? undefined });
|
|
22
|
+
// Reactively sync selectedKeys when series `selected` props change.
|
|
23
|
+
// When any series explicitly sets `selected: false`, the remaining series
|
|
24
|
+
// (with `selected` undefined or true) are pre-selected.
|
|
25
|
+
$effect(() => {
|
|
26
|
+
const keys = SeriesState.#selectedKeysFromSeries(this.#series);
|
|
27
|
+
if (keys) {
|
|
28
|
+
this.selectedKeys.current = keys;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
35
31
|
}
|
|
36
32
|
/**
|
|
37
33
|
* Extract selected keys from series definitions.
|
|
@@ -11,7 +11,11 @@ const series = [
|
|
|
11
11
|
{ key: 'oranges', color: 'orange' },
|
|
12
12
|
];
|
|
13
13
|
function createSeriesState(seriesData = series, stackConfig = null) {
|
|
14
|
-
|
|
14
|
+
let state;
|
|
15
|
+
$effect.root(() => {
|
|
16
|
+
state = new SeriesState(() => seriesData, () => stackConfig);
|
|
17
|
+
});
|
|
18
|
+
return state;
|
|
15
19
|
}
|
|
16
20
|
describe('SeriesState', () => {
|
|
17
21
|
describe('constructor and basic properties', () => {
|
package/dist/svg.d.ts
CHANGED
|
@@ -126,8 +126,8 @@ export { default as Graticule } from './components/geo/Graticule/Graticule.svg.s
|
|
|
126
126
|
export type { GraticuleProps, GraticulePropsWithoutHTML, } from './components/geo/Graticule/Graticule.shared.svelte.js';
|
|
127
127
|
export { default as Ribbon } from './components/graph/Ribbon/Ribbon.svg.svelte';
|
|
128
128
|
export type { RibbonProps, RibbonPropsWithoutHTML, } from './components/graph/Ribbon/Ribbon.shared.svelte.js';
|
|
129
|
-
export { default as Blur } from './components/Blur.svelte';
|
|
130
|
-
export * from './components/Blur.svelte';
|
|
129
|
+
export { default as Blur } from './components/Blur/Blur.svelte';
|
|
130
|
+
export * from './components/Blur/Blur.svelte';
|
|
131
131
|
export { default as Bounds } from './components/Bounds.svelte';
|
|
132
132
|
export * from './components/Bounds.svelte';
|
|
133
133
|
export { default as BrushContext } from './components/BrushContext.svelte';
|
|
@@ -168,6 +168,10 @@ export { default as Sankey } from './components/graph/Sankey.svelte';
|
|
|
168
168
|
export * from './components/graph/Sankey.svelte';
|
|
169
169
|
export { default as ForceSimulation } from './components/force/ForceSimulation.svelte';
|
|
170
170
|
export * from './components/force/ForceSimulation.svelte';
|
|
171
|
+
export { default as Dodge } from './components/Dodge/Dodge.svelte';
|
|
172
|
+
export * from './components/Dodge/Dodge.svelte';
|
|
173
|
+
export { default as Waffle } from './components/Waffle/Waffle.svelte';
|
|
174
|
+
export * from './components/Waffle/Waffle.svelte';
|
|
171
175
|
export { default as GeoLegend } from './components/geo/GeoLegend/GeoLegend.svelte';
|
|
172
176
|
export { default as GeoProjection } from './components/geo/GeoProjection/GeoProjection.svelte';
|
|
173
177
|
export { default as GeoRaster } from './components/geo/GeoRaster/GeoRaster.svelte';
|
package/dist/svg.js
CHANGED
|
@@ -77,8 +77,8 @@ export { default as Ribbon } from './components/graph/Ribbon/Ribbon.svg.svelte';
|
|
|
77
77
|
// helpers, context providers, or composite chart wrappers). Re-exported here
|
|
78
78
|
// so the per-layer sub-path has a complete API.
|
|
79
79
|
// Helpers / context providers
|
|
80
|
-
export { default as Blur } from './components/Blur.svelte';
|
|
81
|
-
export * from './components/Blur.svelte';
|
|
80
|
+
export { default as Blur } from './components/Blur/Blur.svelte';
|
|
81
|
+
export * from './components/Blur/Blur.svelte';
|
|
82
82
|
export { default as Bounds } from './components/Bounds.svelte';
|
|
83
83
|
export * from './components/Bounds.svelte';
|
|
84
84
|
export { default as BrushContext } from './components/BrushContext.svelte';
|
|
@@ -121,6 +121,10 @@ export { default as Sankey } from './components/graph/Sankey.svelte';
|
|
|
121
121
|
export * from './components/graph/Sankey.svelte';
|
|
122
122
|
export { default as ForceSimulation } from './components/force/ForceSimulation.svelte';
|
|
123
123
|
export * from './components/force/ForceSimulation.svelte';
|
|
124
|
+
export { default as Dodge } from './components/Dodge/Dodge.svelte';
|
|
125
|
+
export * from './components/Dodge/Dodge.svelte';
|
|
126
|
+
export { default as Waffle } from './components/Waffle/Waffle.svelte';
|
|
127
|
+
export * from './components/Waffle/Waffle.svelte';
|
|
124
128
|
// Geo helpers (no per-layer rendering)
|
|
125
129
|
export { default as GeoLegend } from './components/geo/GeoLegend/GeoLegend.svelte';
|
|
126
130
|
export { default as GeoProjection } from './components/geo/GeoProjection/GeoProjection.svelte';
|
package/dist/utils/canvas.js
CHANGED
|
@@ -13,6 +13,16 @@ function isTransparentFill(fill) {
|
|
|
13
13
|
// Match rgba(..., 0) - alpha channel is 0 (fully transparent)
|
|
14
14
|
return /rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*0\s*\)/.test(fill);
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Returns true if a style value cannot be assigned directly to a canvas
|
|
18
|
+
* context and must first be resolved through the hidden `<svg>` helper —
|
|
19
|
+
* specifically `var(...)` references and the `currentColor` keyword.
|
|
20
|
+
*/
|
|
21
|
+
function needsCSSResolution(value) {
|
|
22
|
+
if (typeof value !== 'string')
|
|
23
|
+
return false;
|
|
24
|
+
return value.includes('var(') || value.toLowerCase() === 'currentcolor';
|
|
25
|
+
}
|
|
16
26
|
const CANVAS_STYLES_ELEMENT_ID = '__layerchart_canvas_styles_id';
|
|
17
27
|
/**
|
|
18
28
|
* Parse an inline CSS style string into a StyleOptions object.
|
|
@@ -122,9 +132,8 @@ function render(ctx, render, styleOptions = {}, { applyText, } = {}) {
|
|
|
122
132
|
// TODO: Consider memoizing? How about reactiving to CSS variable changes (light/dark mode toggle)
|
|
123
133
|
let resolvedStyles;
|
|
124
134
|
if (typeof document === 'undefined' ||
|
|
125
|
-
(styleOptions.classes == null &&
|
|
126
|
-
|
|
127
|
-
// Skip resolving styles if running on server (no DOM), or no classes are provided and no styles are using CSS variables
|
|
135
|
+
(styleOptions.classes == null && !Object.values(mergedStyles).some(needsCSSResolution))) {
|
|
136
|
+
// Skip resolving styles if running on server (no DOM), or no classes are provided and no styles need CSS resolution (`var(...)` / `currentColor`)
|
|
128
137
|
resolvedStyles = mergedStyles;
|
|
129
138
|
// On server, provide sensible defaults for styles that would normally come from CSS
|
|
130
139
|
if (typeof document === 'undefined') {
|
|
@@ -136,12 +145,12 @@ function render(ctx, render, styleOptions = {}, { applyText, } = {}) {
|
|
|
136
145
|
else {
|
|
137
146
|
// Remove constant non-css variable properties (ex. `strokeWidth: 0.5`, `fill: #123456`) as not needed and improves memoization cache hit
|
|
138
147
|
const { constantStyles, variableStyles } = Object.entries(mergedStyles).reduce((acc, [key, value]) => {
|
|
139
|
-
if (
|
|
140
|
-
acc.constantStyles[key] = value;
|
|
141
|
-
}
|
|
142
|
-
else if (typeof value === 'string' && value.includes('var(')) {
|
|
148
|
+
if (needsCSSResolution(value)) {
|
|
143
149
|
acc.variableStyles[key] = value;
|
|
144
150
|
}
|
|
151
|
+
else if (typeof value === 'number' || typeof value === 'string') {
|
|
152
|
+
acc.constantStyles[key] = value;
|
|
153
|
+
}
|
|
145
154
|
return acc;
|
|
146
155
|
}, { constantStyles: {}, variableStyles: {} });
|
|
147
156
|
const computedStyles = getComputedStyles(ctx.canvas, {
|
|
@@ -200,7 +209,7 @@ function render(ctx, render, styleOptions = {}, { applyText, } = {}) {
|
|
|
200
209
|
styleOptions.styles?.fill instanceof CanvasGradient) ||
|
|
201
210
|
(typeof CanvasPattern !== 'undefined' &&
|
|
202
211
|
styleOptions.styles?.fill instanceof CanvasPattern) ||
|
|
203
|
-
!styleOptions.styles?.fill
|
|
212
|
+
!needsCSSResolution(styleOptions.styles?.fill))
|
|
204
213
|
? styleOptions.styles.fill
|
|
205
214
|
: resolvedStyles?.fill;
|
|
206
215
|
if (fill && !isTransparentFill(fill)) {
|
|
@@ -217,7 +226,7 @@ function render(ctx, render, styleOptions = {}, { applyText, } = {}) {
|
|
|
217
226
|
const stroke = styleOptions.styles?.stroke &&
|
|
218
227
|
((typeof CanvasGradient !== 'undefined' &&
|
|
219
228
|
styleOptions.styles?.stroke instanceof CanvasGradient) ||
|
|
220
|
-
!styleOptions.styles?.stroke
|
|
229
|
+
!needsCSSResolution(styleOptions.styles?.stroke))
|
|
221
230
|
? styleOptions.styles?.stroke
|
|
222
231
|
: resolvedStyles?.stroke;
|
|
223
232
|
if (stroke && !['none'].includes(stroke)) {
|
|
@@ -371,10 +380,18 @@ export function _createPattern(ctx, width, height, shapes, background) {
|
|
|
371
380
|
const patternCtx = patternCanvas.getContext('2d');
|
|
372
381
|
// Add pattern canvas to DOM to allow computed styles to be read (`getComputedStyles()`)
|
|
373
382
|
ctx.canvas.after(patternCanvas);
|
|
374
|
-
//
|
|
375
|
-
//
|
|
376
|
-
|
|
377
|
-
|
|
383
|
+
// Render the pattern at the device pixel ratio so the bitmap tile is
|
|
384
|
+
// sharp on high-DPI screens. Chrome samples patterns in the canvas's
|
|
385
|
+
// user (post-transform) coordinate space, so 1 source pixel = 1 user px
|
|
386
|
+
// by default — without DPR-scaling the bitmap, a 12 logical-px tile is
|
|
387
|
+
// sampled from 12 source pixels, leaving each device pixel of fill to
|
|
388
|
+
// be interpolated from a 1/dpr-th of a source pixel (blurry). Drawing
|
|
389
|
+
// at DPR resolution and scaling the pattern back down to user space at
|
|
390
|
+
// fill time keeps tiles sharp.
|
|
391
|
+
const dpr = (typeof window !== 'undefined' ? window.devicePixelRatio : 1) || 1;
|
|
392
|
+
patternCanvas.width = Math.max(1, Math.round(width * dpr));
|
|
393
|
+
patternCanvas.height = Math.max(1, Math.round(height * dpr));
|
|
394
|
+
patternCtx.scale(dpr, dpr);
|
|
378
395
|
if (background) {
|
|
379
396
|
patternCtx.fillStyle = background;
|
|
380
397
|
patternCtx.fillRect(0, 0, width, height);
|
|
@@ -389,9 +406,23 @@ export function _createPattern(ctx, width, height, shapes, background) {
|
|
|
389
406
|
styles: { stroke: shape.stroke, strokeWidth: shape.strokeWidth, opacity: shape.opacity },
|
|
390
407
|
});
|
|
391
408
|
}
|
|
409
|
+
else if (shape.type === 'rect') {
|
|
410
|
+
const rx = typeof shape.rx === 'string' ? toRectCornerPx(shape.rx, shape.width) : shape.rx;
|
|
411
|
+
const ry = typeof shape.ry === 'string' ? toRectCornerPx(shape.ry, shape.height) : (shape.ry ?? rx);
|
|
412
|
+
renderRect(patternCtx, { x: shape.x, y: shape.y, width: shape.width, height: shape.height, rx, ry }, { styles: { fill: shape.fill, opacity: shape.opacity } });
|
|
413
|
+
}
|
|
392
414
|
patternCtx.restore();
|
|
393
415
|
}
|
|
394
416
|
const pattern = ctx.createPattern(patternCanvas, 'repeat');
|
|
417
|
+
// Scale-only matrix; no translate so the pattern anchors to the path's
|
|
418
|
+
// local origin at fill time (matches SVG `patternUnits="userSpaceOnUse"`).
|
|
419
|
+
// Use the *actual* bitmap pixel dimensions for the scale so rounding
|
|
420
|
+
// `width * dpr` to an integer doesn't accumulate drift across tiles.
|
|
421
|
+
if (pattern) {
|
|
422
|
+
const sx = width / patternCanvas.width;
|
|
423
|
+
const sy = height / patternCanvas.height;
|
|
424
|
+
pattern.setTransform(new DOMMatrix([sx, 0, 0, sy, 0, 0]));
|
|
425
|
+
}
|
|
395
426
|
// Cleanup
|
|
396
427
|
ctx.canvas.parentElement?.removeChild(patternCanvas);
|
|
397
428
|
return pattern;
|
|
@@ -400,3 +431,13 @@ export function _createPattern(ctx, width, height, shapes, background) {
|
|
|
400
431
|
export const createPattern = memoize(_createPattern, {
|
|
401
432
|
cacheKey: (args) => JSON.stringify(args.slice(1)), // Ignore `ctx` argument
|
|
402
433
|
});
|
|
434
|
+
function toRectCornerPx(value, max) {
|
|
435
|
+
if (value.endsWith('%')) {
|
|
436
|
+
const pct = parseFloat(value);
|
|
437
|
+
if (!Number.isFinite(pct))
|
|
438
|
+
return 0;
|
|
439
|
+
return (max / 2) * (pct / 100);
|
|
440
|
+
}
|
|
441
|
+
const n = parseFloat(value);
|
|
442
|
+
return Number.isFinite(n) ? n : 0;
|
|
443
|
+
}
|
|
@@ -403,6 +403,33 @@ describe('renderPathData', () => {
|
|
|
403
403
|
expect(strokeSpy).toHaveBeenCalled();
|
|
404
404
|
expect(ctx.strokeStyle).toBe('#008000');
|
|
405
405
|
});
|
|
406
|
+
it('resolves currentColor stroke through the SVG helper', () => {
|
|
407
|
+
const parent = canvas.parentElement;
|
|
408
|
+
const previousColor = parent.style.color;
|
|
409
|
+
parent.style.color = 'rgb(255, 165, 0)';
|
|
410
|
+
renderPathData(ctx, 'M0,0 L100,0', {
|
|
411
|
+
styles: {
|
|
412
|
+
fill: 'none',
|
|
413
|
+
stroke: 'currentColor',
|
|
414
|
+
strokeOpacity: '1',
|
|
415
|
+
opacity: '1',
|
|
416
|
+
strokeWidth: '2',
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
// Canvas normalizes rgb(255, 165, 0) → '#ffa500'
|
|
420
|
+
expect(ctx.strokeStyle).toBe('#ffa500');
|
|
421
|
+
parent.style.color = previousColor;
|
|
422
|
+
});
|
|
423
|
+
it('resolves currentColor fill through the SVG helper', () => {
|
|
424
|
+
const parent = canvas.parentElement;
|
|
425
|
+
const previousColor = parent.style.color;
|
|
426
|
+
parent.style.color = 'rgb(128, 0, 128)';
|
|
427
|
+
renderPathData(ctx, 'M0,0 L100,0 L100,100 Z', {
|
|
428
|
+
styles: { fill: 'currentColor', fillOpacity: '1', opacity: '1', stroke: 'none' },
|
|
429
|
+
});
|
|
430
|
+
expect(ctx.fillStyle).toBe('#800080');
|
|
431
|
+
parent.style.color = previousColor;
|
|
432
|
+
});
|
|
406
433
|
});
|
|
407
434
|
// ---------------------------------------------------------------------------
|
|
408
435
|
// renderText
|
|
@@ -704,6 +731,23 @@ describe('_getComputedStyles', () => {
|
|
|
704
731
|
// 'red' resolves to 'rgb(255, 0, 0)' in the browser
|
|
705
732
|
expect(result.fill).toMatch(/rgb\(255,\s*0,\s*0\)/);
|
|
706
733
|
});
|
|
734
|
+
it('resolves currentColor for fill via inherited color', () => {
|
|
735
|
+
// Set color on the canvas's parent so the helper SVG (sibling of canvas) inherits it
|
|
736
|
+
const parent = canvas.parentElement;
|
|
737
|
+
const previousColor = parent.style.color;
|
|
738
|
+
parent.style.color = 'rgb(0, 128, 0)';
|
|
739
|
+
const result = _getComputedStyles(canvas, { styles: { fill: 'currentColor' } });
|
|
740
|
+
expect(result.fill).toMatch(/rgb\(0,\s*128,\s*0\)/);
|
|
741
|
+
parent.style.color = previousColor;
|
|
742
|
+
});
|
|
743
|
+
it('resolves currentColor for stroke via inherited color', () => {
|
|
744
|
+
const parent = canvas.parentElement;
|
|
745
|
+
const previousColor = parent.style.color;
|
|
746
|
+
parent.style.color = 'rgb(0, 0, 255)';
|
|
747
|
+
const result = _getComputedStyles(canvas, { styles: { stroke: 'currentColor' } });
|
|
748
|
+
expect(result.stroke).toMatch(/rgb\(0,\s*0,\s*255\)/);
|
|
749
|
+
parent.style.color = previousColor;
|
|
750
|
+
});
|
|
707
751
|
it('returns empty object when DOM throws (graceful error handling)', () => {
|
|
708
752
|
// Simulate error by breaking canvas.after
|
|
709
753
|
const originalAfter = canvas.after.bind(canvas);
|
package/dist/utils/download.d.ts
CHANGED
|
@@ -17,9 +17,11 @@ export type ChartImageOptions = {
|
|
|
17
17
|
*/
|
|
18
18
|
quality?: number;
|
|
19
19
|
/**
|
|
20
|
-
* Device pixel ratio to use when rasterising
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* Device pixel ratio to use when rasterising the image. Defaults to `1`
|
|
21
|
+
* so the output matches the chart's CSS dimensions (looks the same as
|
|
22
|
+
* what's on the page when viewed 1:1). Set to `window.devicePixelRatio`
|
|
23
|
+
* (or higher) to produce crisper images on retina displays at the cost
|
|
24
|
+
* of larger files.
|
|
23
25
|
*/
|
|
24
26
|
pixelRatio?: number;
|
|
25
27
|
};
|