@automattic/charts 0.50.2 → 0.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/charts/bar-chart/index.cjs +15 -0
- package/dist/charts/bar-chart/index.cjs.map +1 -0
- package/dist/{components/bar-list-chart → charts/bar-chart}/index.css +11 -11
- package/dist/charts/bar-chart/index.css.map +1 -0
- package/dist/{components → charts}/bar-chart/index.d.cts +1 -1
- package/dist/{components → charts}/bar-chart/index.d.ts +1 -1
- package/dist/{components → charts}/bar-chart/index.js +4 -4
- package/dist/charts/bar-list-chart/index.cjs +16 -0
- package/dist/charts/bar-list-chart/index.cjs.map +1 -0
- package/dist/{components/bar-chart → charts/bar-list-chart}/index.css +11 -11
- package/dist/charts/bar-list-chart/index.css.map +1 -0
- package/dist/{components → charts}/bar-list-chart/index.d.cts +1 -1
- package/dist/{components → charts}/bar-list-chart/index.d.ts +1 -1
- package/dist/{components → charts}/bar-list-chart/index.js +5 -5
- package/dist/charts/conversion-funnel-chart/index.cjs +10 -0
- package/dist/charts/conversion-funnel-chart/index.cjs.map +1 -0
- package/dist/{components → charts}/conversion-funnel-chart/index.css +23 -23
- package/dist/charts/conversion-funnel-chart/index.css.map +1 -0
- package/dist/{components → charts}/conversion-funnel-chart/index.d.cts +1 -1
- package/dist/{components → charts}/conversion-funnel-chart/index.d.ts +1 -1
- package/dist/{components → charts}/conversion-funnel-chart/index.js +2 -2
- package/dist/charts/leaderboard-chart/index.cjs +20 -0
- package/dist/charts/leaderboard-chart/index.cjs.map +1 -0
- package/dist/{components → charts}/leaderboard-chart/index.css +16 -16
- package/dist/charts/leaderboard-chart/index.css.map +1 -0
- package/dist/{components → charts}/leaderboard-chart/index.d.cts +2 -2
- package/dist/{components → charts}/leaderboard-chart/index.d.ts +2 -2
- package/dist/{components → charts}/leaderboard-chart/index.js +5 -5
- package/dist/charts/line-chart/index.cjs +15 -0
- package/dist/charts/line-chart/index.cjs.map +1 -0
- package/dist/{components → charts}/line-chart/index.css +21 -21
- package/dist/charts/line-chart/index.css.map +1 -0
- package/dist/{components → charts}/line-chart/index.d.cts +1 -1
- package/dist/{components → charts}/line-chart/index.d.ts +1 -1
- package/dist/{components → charts}/line-chart/index.js +4 -4
- package/dist/charts/pie-chart/index.cjs +18 -0
- package/dist/charts/pie-chart/index.cjs.map +1 -0
- package/dist/{components → charts}/pie-chart/index.css +3 -3
- package/dist/charts/pie-chart/index.css.map +1 -0
- package/dist/{components → charts}/pie-chart/index.d.cts +7 -7
- package/dist/{components → charts}/pie-chart/index.d.ts +7 -7
- package/dist/{components → charts}/pie-chart/index.js +6 -6
- package/dist/charts/pie-semi-circle-chart/index.cjs +17 -0
- package/dist/charts/pie-semi-circle-chart/index.cjs.map +1 -0
- package/dist/{components → charts}/pie-semi-circle-chart/index.css +5 -5
- package/dist/charts/pie-semi-circle-chart/index.css.map +1 -0
- package/dist/{components → charts}/pie-semi-circle-chart/index.d.cts +7 -7
- package/dist/{components → charts}/pie-semi-circle-chart/index.d.ts +7 -7
- package/dist/{components → charts}/pie-semi-circle-chart/index.js +6 -6
- package/dist/{chunk-N4ZDNOPY.cjs → chunk-44EBMDFI.cjs} +107 -236
- package/dist/chunk-44EBMDFI.cjs.map +1 -0
- package/dist/{chunk-XVMWJANV.js → chunk-624IQX64.js} +27 -27
- package/dist/chunk-624IQX64.js.map +1 -0
- package/dist/{chunk-BZQFCAX7.cjs → chunk-67BAKCI2.cjs} +9 -9
- package/dist/chunk-67BAKCI2.cjs.map +1 -0
- package/dist/{chunk-3OVXJFQY.js → chunk-A3AEEGKR.js} +2 -2
- package/dist/chunk-A3AEEGKR.js.map +1 -0
- package/dist/{chunk-6SGGF26Z.js → chunk-AI6GM6HS.js} +40 -37
- package/dist/chunk-AI6GM6HS.js.map +1 -0
- package/dist/{chunk-EKVFMS3A.cjs → chunk-BMWFTOSR.cjs} +38 -38
- package/dist/chunk-BMWFTOSR.cjs.map +1 -0
- package/dist/{chunk-D3DZT2EK.js → chunk-CEZGL6YP.js} +4 -4
- package/dist/chunk-CEZGL6YP.js.map +1 -0
- package/dist/{chunk-EKVLCYHS.js → chunk-DILKZ4MP.js} +5 -5
- package/dist/chunk-DILKZ4MP.js.map +1 -0
- package/dist/{chunk-VOWX5TBY.js → chunk-E6VKSUGP.js} +16 -16
- package/dist/chunk-E6VKSUGP.js.map +1 -0
- package/dist/{chunk-7OWIZ5S7.js → chunk-EELV2LG7.js} +4 -4
- package/dist/chunk-EELV2LG7.js.map +1 -0
- package/dist/{chunk-HA7WACBI.cjs → chunk-GOZNZD3N.cjs} +9 -9
- package/dist/chunk-GOZNZD3N.cjs.map +1 -0
- package/dist/{chunk-PTEEI2QM.js → chunk-GSG54JGM.js} +19 -19
- package/dist/chunk-GSG54JGM.js.map +1 -0
- package/dist/{chunk-3Z526IL2.cjs → chunk-HIWNB5PK.cjs} +4 -4
- package/dist/chunk-HIWNB5PK.cjs.map +1 -0
- package/dist/{chunk-6WQWN5BF.js → chunk-IDTLZ7KT.js} +17 -17
- package/dist/chunk-IDTLZ7KT.js.map +1 -0
- package/dist/{chunk-6UZHWL6W.cjs → chunk-JSGCFUVQ.cjs} +34 -34
- package/dist/chunk-JSGCFUVQ.cjs.map +1 -0
- package/dist/{chunk-5NI3TGRD.cjs → chunk-MUUSZ7J5.cjs} +2 -2
- package/dist/{chunk-D3E235JJ.js.map → chunk-MUUSZ7J5.cjs.map} +1 -1
- package/dist/{chunk-3PRIZR7Y.cjs → chunk-N4NZ4VJK.cjs} +34 -34
- package/dist/chunk-N4NZ4VJK.cjs.map +1 -0
- package/dist/{chunk-D3E235JJ.js → chunk-NONODB3K.js} +2 -2
- package/dist/chunk-NONODB3K.js.map +1 -0
- package/dist/{chunk-SDNRKKBP.cjs → chunk-OTZT3MC2.cjs} +2 -2
- package/dist/chunk-OTZT3MC2.cjs.map +1 -0
- package/dist/{chunk-RUG2O62B.js → chunk-S5UDYA4M.js} +22 -22
- package/dist/chunk-S5UDYA4M.js.map +1 -0
- package/dist/{chunk-KE4EDAQI.cjs → chunk-UJIP7ICA.cjs} +34 -34
- package/dist/chunk-UJIP7ICA.cjs.map +1 -0
- package/dist/{chunk-MRCTAUHL.js → chunk-ULRFJ3IU.js} +128 -257
- package/dist/chunk-ULRFJ3IU.js.map +1 -0
- package/dist/{chunk-SLO4NLKC.cjs → chunk-VEJIPJN7.cjs} +56 -53
- package/dist/chunk-VEJIPJN7.cjs.map +1 -0
- package/dist/{chunk-PEUZZ3WY.cjs → chunk-ZOCE4WND.cjs} +34 -34
- package/dist/chunk-ZOCE4WND.cjs.map +1 -0
- package/dist/components/legend/index.cjs +3 -3
- package/dist/components/legend/index.d.cts +1 -1
- package/dist/components/legend/index.d.ts +1 -1
- package/dist/components/legend/index.js +2 -2
- package/dist/components/tooltip/index.d.cts +1 -1
- package/dist/components/tooltip/index.d.ts +1 -1
- package/dist/hooks/index.cjs +2 -2
- package/dist/hooks/index.d.cts +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/index.cjs +188 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +96 -79
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +111 -12
- package/dist/index.d.ts +111 -12
- package/dist/index.js +179 -29
- package/dist/index.js.map +1 -1
- package/dist/{leaderboard-chart-BlBexVz4.d.cts → leaderboard-chart-Bf7z7SoM.d.cts} +1 -1
- package/dist/{leaderboard-chart-B3dPiEl8.d.ts → leaderboard-chart-Bh8M5JWL.d.ts} +1 -1
- package/dist/providers/index.cjs +2 -6
- package/dist/providers/index.cjs.map +1 -1
- package/dist/providers/index.d.cts +2 -2
- package/dist/providers/index.d.ts +2 -2
- package/dist/providers/index.js +3 -7
- package/dist/{themes-CNy453Lb.d.ts → themes-09M-mQE6.d.ts} +2 -10
- package/dist/{themes-Dv70Dz7B.d.cts → themes-DYhtyXtJ.d.cts} +2 -10
- package/dist/{types-4wyyzjot.d.cts → types-BtYG-Fdk.d.cts} +19 -0
- package/dist/{types-4wyyzjot.d.ts → types-BtYG-Fdk.d.ts} +19 -0
- package/dist/utils/index.d.cts +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/package.json +38 -30
- package/src/{components → charts}/bar-chart/bar-chart.tsx +2 -2
- package/src/{components → charts}/conversion-funnel-chart/test/conversion-funnel-chart.test.tsx +0 -1
- package/src/charts/index.ts +8 -0
- package/src/{components → charts}/leaderboard-chart/hooks/use-leaderboard-legend-items.ts +1 -1
- package/src/{components → charts}/leaderboard-chart/leaderboard-chart.tsx +1 -1
- package/src/{components → charts}/line-chart/line-chart.tsx +8 -5
- package/src/{components → charts}/line-chart/test/line-chart.test.tsx +7 -9
- package/src/{components → charts}/pie-chart/pie-chart.tsx +3 -3
- package/src/{components → charts}/pie-semi-circle-chart/pie-semi-circle-chart.tsx +3 -3
- package/src/{components → charts}/private/chart-composition/types.ts +1 -1
- package/src/charts/sparkline/index.ts +2 -0
- package/src/charts/sparkline/sparkline.module.scss +18 -0
- package/src/charts/sparkline/sparkline.tsx +200 -0
- package/src/charts/sparkline/test/sparkline.test.tsx +196 -0
- package/src/charts/sparkline/types.ts +92 -0
- package/src/components/index.ts +2 -0
- package/src/components/legend/legend.tsx +1 -1
- package/src/compositions/index.ts +2 -0
- package/src/index.ts +12 -14
- package/src/providers/chart-context/test/chart-context.test.tsx +0 -35
- package/src/providers/chart-context/test/use-global-charts-theme.test.tsx +1 -23
- package/src/providers/chart-context/themes.ts +5 -127
- package/src/types.ts +19 -0
- package/dist/chunk-3OVXJFQY.js.map +0 -1
- package/dist/chunk-3PRIZR7Y.cjs.map +0 -1
- package/dist/chunk-3Z526IL2.cjs.map +0 -1
- package/dist/chunk-5NI3TGRD.cjs.map +0 -1
- package/dist/chunk-6SGGF26Z.js.map +0 -1
- package/dist/chunk-6UZHWL6W.cjs.map +0 -1
- package/dist/chunk-6WQWN5BF.js.map +0 -1
- package/dist/chunk-7OWIZ5S7.js.map +0 -1
- package/dist/chunk-BZQFCAX7.cjs.map +0 -1
- package/dist/chunk-D3DZT2EK.js.map +0 -1
- package/dist/chunk-EKVFMS3A.cjs.map +0 -1
- package/dist/chunk-EKVLCYHS.js.map +0 -1
- package/dist/chunk-HA7WACBI.cjs.map +0 -1
- package/dist/chunk-KE4EDAQI.cjs.map +0 -1
- package/dist/chunk-MRCTAUHL.js.map +0 -1
- package/dist/chunk-N4ZDNOPY.cjs.map +0 -1
- package/dist/chunk-PEUZZ3WY.cjs.map +0 -1
- package/dist/chunk-PTEEI2QM.js.map +0 -1
- package/dist/chunk-RUG2O62B.js.map +0 -1
- package/dist/chunk-SDNRKKBP.cjs.map +0 -1
- package/dist/chunk-SLO4NLKC.cjs.map +0 -1
- package/dist/chunk-VOWX5TBY.js.map +0 -1
- package/dist/chunk-XVMWJANV.js.map +0 -1
- package/dist/components/bar-chart/index.cjs +0 -15
- package/dist/components/bar-chart/index.cjs.map +0 -1
- package/dist/components/bar-chart/index.css.map +0 -1
- package/dist/components/bar-list-chart/index.cjs +0 -16
- package/dist/components/bar-list-chart/index.cjs.map +0 -1
- package/dist/components/bar-list-chart/index.css.map +0 -1
- package/dist/components/conversion-funnel-chart/index.cjs +0 -10
- package/dist/components/conversion-funnel-chart/index.cjs.map +0 -1
- package/dist/components/conversion-funnel-chart/index.css.map +0 -1
- package/dist/components/leaderboard-chart/index.cjs +0 -20
- package/dist/components/leaderboard-chart/index.cjs.map +0 -1
- package/dist/components/leaderboard-chart/index.css.map +0 -1
- package/dist/components/line-chart/index.cjs +0 -15
- package/dist/components/line-chart/index.cjs.map +0 -1
- package/dist/components/line-chart/index.css.map +0 -1
- package/dist/components/pie-chart/index.cjs +0 -18
- package/dist/components/pie-chart/index.cjs.map +0 -1
- package/dist/components/pie-chart/index.css.map +0 -1
- package/dist/components/pie-semi-circle-chart/index.cjs +0 -17
- package/dist/components/pie-semi-circle-chart/index.cjs.map +0 -1
- package/dist/components/pie-semi-circle-chart/index.css.map +0 -1
- /package/dist/{components → charts}/bar-chart/index.js.map +0 -0
- /package/dist/{components → charts}/bar-list-chart/index.js.map +0 -0
- /package/dist/{components → charts}/conversion-funnel-chart/index.js.map +0 -0
- /package/dist/{components → charts}/leaderboard-chart/index.js.map +0 -0
- /package/dist/{components → charts}/line-chart/index.js.map +0 -0
- /package/dist/{components → charts}/pie-chart/index.js.map +0 -0
- /package/dist/{components → charts}/pie-semi-circle-chart/index.js.map +0 -0
- /package/src/{components → charts}/bar-chart/bar-chart.module.scss +0 -0
- /package/src/{components → charts}/bar-chart/index.ts +0 -0
- /package/src/{components → charts}/bar-chart/private/index.ts +0 -0
- /package/src/{components → charts}/bar-chart/private/use-bar-chart-options.ts +0 -0
- /package/src/{components → charts}/bar-chart/test/bar-chart.test.tsx +0 -0
- /package/src/{components → charts}/bar-list-chart/bar-list-chart.tsx +0 -0
- /package/src/{components → charts}/bar-list-chart/index.ts +0 -0
- /package/src/{components → charts}/bar-list-chart/test/bar-list-chart.test.tsx +0 -0
- /package/src/{components → charts}/conversion-funnel-chart/conversion-funnel-chart.module.scss +0 -0
- /package/src/{components → charts}/conversion-funnel-chart/conversion-funnel-chart.tsx +0 -0
- /package/src/{components → charts}/conversion-funnel-chart/index.ts +0 -0
- /package/src/{components → charts}/conversion-funnel-chart/private/index.ts +0 -0
- /package/src/{components → charts}/conversion-funnel-chart/private/use-funnel-selection.ts +0 -0
- /package/src/{components → charts}/conversion-funnel-chart/test/use-funnel-selection.test.ts +0 -0
- /package/src/{components → charts}/conversion-funnel-chart/types.ts +0 -0
- /package/src/{components → charts}/leaderboard-chart/hooks/index.ts +0 -0
- /package/src/{components → charts}/leaderboard-chart/index.ts +0 -0
- /package/src/{components → charts}/leaderboard-chart/leaderboard-chart.module.scss +0 -0
- /package/src/{components → charts}/leaderboard-chart/test/leaderboard-chart.test.tsx +0 -0
- /package/src/{components → charts}/leaderboard-chart/test/use-leaderboard-legend-items.test.tsx +0 -0
- /package/src/{components → charts}/leaderboard-chart/types.ts +0 -0
- /package/src/{components → charts}/line-chart/index.ts +0 -0
- /package/src/{components → charts}/line-chart/line-chart.module.scss +0 -0
- /package/src/{components → charts}/line-chart/private/index.ts +0 -0
- /package/src/{components → charts}/line-chart/private/line-chart-annotation-label-popover.tsx +0 -0
- /package/src/{components → charts}/line-chart/private/line-chart-annotation.tsx +0 -0
- /package/src/{components → charts}/line-chart/private/line-chart-annotations-overlay.tsx +0 -0
- /package/src/{components → charts}/line-chart/private/line-chart-glyph.tsx +0 -0
- /package/src/{components → charts}/line-chart/test/line-chart-annotation-label-popover.test.tsx +0 -0
- /package/src/{components → charts}/line-chart/test/line-chart-annotation.test.tsx +0 -0
- /package/src/{components → charts}/line-chart/types.ts +0 -0
- /package/src/{components → charts}/pie-chart/index.ts +0 -0
- /package/src/{components → charts}/pie-chart/pie-chart.module.scss +0 -0
- /package/src/{components → charts}/pie-chart/test/composition-api.test.tsx +0 -0
- /package/src/{components → charts}/pie-chart/test/pie-chart.test.tsx +0 -0
- /package/src/{components → charts}/pie-semi-circle-chart/index.ts +0 -0
- /package/src/{components → charts}/pie-semi-circle-chart/pie-semi-circle-chart.module.scss +0 -0
- /package/src/{components → charts}/pie-semi-circle-chart/test/pie-semi-circle-chart.test.tsx +0 -0
- /package/src/{components → charts}/private/chart-composition/chart-html.tsx +0 -0
- /package/src/{components → charts}/private/chart-composition/chart-svg.tsx +0 -0
- /package/src/{components → charts}/private/chart-composition/index.ts +0 -0
- /package/src/{components → charts}/private/chart-composition/test/use-chart-children.test.tsx +0 -0
- /package/src/{components → charts}/private/chart-composition/use-chart-children.ts +0 -0
- /package/src/{components → charts}/private/default-glyph/default-glyph.tsx +0 -0
- /package/src/{components → charts}/private/default-glyph/index.ts +0 -0
- /package/src/{components → charts}/private/grid-control/grid-control.module.scss +0 -0
- /package/src/{components → charts}/private/grid-control/grid-control.tsx +0 -0
- /package/src/{components → charts}/private/grid-control/index.ts +0 -0
- /package/src/{components → charts}/private/grid-control/test/grid-control.test.tsx +0 -0
- /package/src/{components → charts}/private/radial-wipe-animation/index.ts +0 -0
- /package/src/{components → charts}/private/radial-wipe-animation/radial-wipe-animation.tsx +0 -0
- /package/src/{components → charts}/private/single-chart-context/index.ts +0 -0
- /package/src/{components → charts}/private/single-chart-context/single-chart-context.tsx +0 -0
- /package/src/{components → charts}/private/single-chart-context/use-single-chart-context.ts +0 -0
- /package/src/{components → charts}/private/with-responsive/index.ts +0 -0
- /package/src/{components → charts}/private/with-responsive/test/with-responsive.test.tsx +0 -0
- /package/src/{components → charts}/private/with-responsive/with-responsive.tsx +0 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/* eslint-disable testing-library/no-container, testing-library/no-node-access */
|
|
6
|
+
|
|
7
|
+
import { render, screen } from '@testing-library/react';
|
|
8
|
+
import { Sparkline, SparklineUnresponsive } from '../';
|
|
9
|
+
import { GlobalChartsProvider, defaultTheme } from '../../../providers';
|
|
10
|
+
import { customTheme } from '../../../stories/theme-config';
|
|
11
|
+
|
|
12
|
+
const THEME_MAP = {
|
|
13
|
+
default: defaultTheme,
|
|
14
|
+
custom: customTheme,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
describe( 'Sparkline', () => {
|
|
18
|
+
const defaultData = [ 10, 25, 15, 30, 22, 35 ];
|
|
19
|
+
|
|
20
|
+
const renderWithTheme = ( props = {}, themeName = 'default' ) => {
|
|
21
|
+
const theme = THEME_MAP[ themeName ];
|
|
22
|
+
|
|
23
|
+
return render(
|
|
24
|
+
<GlobalChartsProvider theme={ theme }>
|
|
25
|
+
<Sparkline data={ defaultData } { ...props } />
|
|
26
|
+
</GlobalChartsProvider>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const renderUnwrappedWithTheme = ( props = {}, themeName = 'default' ) => {
|
|
31
|
+
const theme = THEME_MAP[ themeName ];
|
|
32
|
+
|
|
33
|
+
return render(
|
|
34
|
+
<GlobalChartsProvider theme={ theme }>
|
|
35
|
+
<SparklineUnresponsive data={ defaultData } { ...props } />
|
|
36
|
+
</GlobalChartsProvider>
|
|
37
|
+
);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
describe( 'Basic Rendering', () => {
|
|
41
|
+
test( 'renders sparkline with valid data', () => {
|
|
42
|
+
renderUnwrappedWithTheme();
|
|
43
|
+
expect( screen.getByTestId( 'sparkline' ) ).toBeInTheDocument();
|
|
44
|
+
} );
|
|
45
|
+
|
|
46
|
+
test( 'applies custom className', () => {
|
|
47
|
+
renderUnwrappedWithTheme( { className: 'custom-class' } );
|
|
48
|
+
const sparkline = screen.getByTestId( 'sparkline' );
|
|
49
|
+
expect( sparkline ).toHaveClass( 'custom-class' );
|
|
50
|
+
} );
|
|
51
|
+
|
|
52
|
+
test( 'renders responsive variant', () => {
|
|
53
|
+
renderWithTheme();
|
|
54
|
+
// Responsive variant wraps in a div, so sparkline should exist
|
|
55
|
+
expect( screen.getByTestId( 'sparkline' ) ).toBeInTheDocument();
|
|
56
|
+
} );
|
|
57
|
+
} );
|
|
58
|
+
|
|
59
|
+
describe( 'Edge Cases', () => {
|
|
60
|
+
test( 'handles empty data array', () => {
|
|
61
|
+
renderUnwrappedWithTheme( { data: [] } );
|
|
62
|
+
expect( screen.getByTestId( 'sparkline-empty' ) ).toBeInTheDocument();
|
|
63
|
+
} );
|
|
64
|
+
|
|
65
|
+
test( 'handles single data point', () => {
|
|
66
|
+
renderUnwrappedWithTheme( { data: [ 42 ] } );
|
|
67
|
+
const singlePoint = screen.getByTestId( 'sparkline-single-point' );
|
|
68
|
+
expect( singlePoint ).toBeInTheDocument();
|
|
69
|
+
// Should render a circle
|
|
70
|
+
const circle = singlePoint.querySelector( 'circle' );
|
|
71
|
+
expect( circle ).toBeInTheDocument();
|
|
72
|
+
} );
|
|
73
|
+
|
|
74
|
+
test( 'handles two data points', () => {
|
|
75
|
+
renderUnwrappedWithTheme( { data: [ 10, 20 ] } );
|
|
76
|
+
expect( screen.getByTestId( 'sparkline' ) ).toBeInTheDocument();
|
|
77
|
+
} );
|
|
78
|
+
|
|
79
|
+
test( 'handles negative values', () => {
|
|
80
|
+
renderUnwrappedWithTheme( { data: [ -10, -5, 0, 5, 10 ] } );
|
|
81
|
+
expect( screen.getByTestId( 'sparkline' ) ).toBeInTheDocument();
|
|
82
|
+
} );
|
|
83
|
+
|
|
84
|
+
test( 'handles flat line (all same values)', () => {
|
|
85
|
+
renderUnwrappedWithTheme( { data: [ 50, 50, 50, 50 ] } );
|
|
86
|
+
expect( screen.getByTestId( 'sparkline' ) ).toBeInTheDocument();
|
|
87
|
+
} );
|
|
88
|
+
} );
|
|
89
|
+
|
|
90
|
+
describe( 'Styling Props', () => {
|
|
91
|
+
test( 'applies custom color', () => {
|
|
92
|
+
const { container } = renderUnwrappedWithTheme( { color: '#ff0000' } );
|
|
93
|
+
// Check that SVG contains a path with the custom color
|
|
94
|
+
const path = container.querySelector( 'path[stroke="#ff0000"]' );
|
|
95
|
+
expect( path ).toBeInTheDocument();
|
|
96
|
+
} );
|
|
97
|
+
|
|
98
|
+
test( 'applies custom stroke width', () => {
|
|
99
|
+
const { container } = renderUnwrappedWithTheme( { strokeWidth: 4 } );
|
|
100
|
+
const path = container.querySelector( 'path[stroke-width="4"]' );
|
|
101
|
+
expect( path ).toBeInTheDocument();
|
|
102
|
+
} );
|
|
103
|
+
|
|
104
|
+
test( 'renders with gradient fill by default', () => {
|
|
105
|
+
const { container } = renderUnwrappedWithTheme();
|
|
106
|
+
// Check for LinearGradient in SVG
|
|
107
|
+
const gradient = container.querySelector( 'linearGradient' );
|
|
108
|
+
expect( gradient ).toBeInTheDocument();
|
|
109
|
+
} );
|
|
110
|
+
|
|
111
|
+
test( 'disables gradient fill when withGradientFill is false', () => {
|
|
112
|
+
const { container } = renderUnwrappedWithTheme( { withGradientFill: false } );
|
|
113
|
+
// Should not have gradient
|
|
114
|
+
const gradient = container.querySelector( 'linearGradient' );
|
|
115
|
+
expect( gradient ).not.toBeInTheDocument();
|
|
116
|
+
} );
|
|
117
|
+
|
|
118
|
+
test( 'applies custom gradient config', () => {
|
|
119
|
+
const { container } = renderUnwrappedWithTheme( {
|
|
120
|
+
gradient: {
|
|
121
|
+
from: '#00ff00',
|
|
122
|
+
to: '#0000ff',
|
|
123
|
+
fromOpacity: 0.8,
|
|
124
|
+
toOpacity: 0.1,
|
|
125
|
+
},
|
|
126
|
+
} );
|
|
127
|
+
const gradient = container.querySelector( 'linearGradient' );
|
|
128
|
+
expect( gradient ).toBeInTheDocument();
|
|
129
|
+
// Check for color stops
|
|
130
|
+
const stops = gradient?.querySelectorAll( 'stop' );
|
|
131
|
+
expect( stops?.length ).toBeGreaterThan( 0 );
|
|
132
|
+
} );
|
|
133
|
+
} );
|
|
134
|
+
|
|
135
|
+
describe( 'Dimensions', () => {
|
|
136
|
+
test( 'applies default dimensions', () => {
|
|
137
|
+
const { container } = renderUnwrappedWithTheme();
|
|
138
|
+
const svg = container.querySelector( 'svg' );
|
|
139
|
+
expect( svg ).toHaveAttribute( 'width', '100' );
|
|
140
|
+
expect( svg ).toHaveAttribute( 'height', '40' );
|
|
141
|
+
} );
|
|
142
|
+
|
|
143
|
+
test( 'applies custom dimensions', () => {
|
|
144
|
+
const { container } = renderUnwrappedWithTheme( { width: 200, height: 80 } );
|
|
145
|
+
const svg = container.querySelector( 'svg' );
|
|
146
|
+
expect( svg ).toHaveAttribute( 'width', '200' );
|
|
147
|
+
expect( svg ).toHaveAttribute( 'height', '80' );
|
|
148
|
+
} );
|
|
149
|
+
|
|
150
|
+
test( 'applies custom margin', () => {
|
|
151
|
+
renderUnwrappedWithTheme( { margin: { top: 10, right: 10, bottom: 10, left: 10 } } );
|
|
152
|
+
expect( screen.getByTestId( 'sparkline' ) ).toBeInTheDocument();
|
|
153
|
+
} );
|
|
154
|
+
} );
|
|
155
|
+
|
|
156
|
+
describe( 'Theme Integration', () => {
|
|
157
|
+
test( 'uses default theme colors', () => {
|
|
158
|
+
const { container } = renderUnwrappedWithTheme( {}, 'default' );
|
|
159
|
+
expect( screen.getByTestId( 'sparkline' ) ).toBeInTheDocument();
|
|
160
|
+
// Should render with theme color if no color prop provided
|
|
161
|
+
const path = container.querySelector( 'path[stroke]' );
|
|
162
|
+
expect( path ).toBeInTheDocument();
|
|
163
|
+
} );
|
|
164
|
+
|
|
165
|
+
test( 'uses custom theme colors', () => {
|
|
166
|
+
const { container } = renderUnwrappedWithTheme( {}, 'custom' );
|
|
167
|
+
expect( screen.getByTestId( 'sparkline' ) ).toBeInTheDocument();
|
|
168
|
+
const path = container.querySelector( 'path[stroke]' );
|
|
169
|
+
expect( path ).toBeInTheDocument();
|
|
170
|
+
} );
|
|
171
|
+
|
|
172
|
+
test( 'color prop overrides theme color', () => {
|
|
173
|
+
const { container } = renderUnwrappedWithTheme( { color: '#custom' }, 'default' );
|
|
174
|
+
const path = container.querySelector( 'path[stroke="#custom"]' );
|
|
175
|
+
expect( path ).toBeInTheDocument();
|
|
176
|
+
} );
|
|
177
|
+
} );
|
|
178
|
+
|
|
179
|
+
describe( 'Data Transformation', () => {
|
|
180
|
+
test( 'handles large datasets', () => {
|
|
181
|
+
const largeData = Array.from( { length: 100 }, ( _, i ) => i * 2 );
|
|
182
|
+
renderUnwrappedWithTheme( { data: largeData } );
|
|
183
|
+
expect( screen.getByTestId( 'sparkline' ) ).toBeInTheDocument();
|
|
184
|
+
} );
|
|
185
|
+
|
|
186
|
+
test( 'handles small datasets', () => {
|
|
187
|
+
renderUnwrappedWithTheme( { data: [ 1, 2 ] } );
|
|
188
|
+
expect( screen.getByTestId( 'sparkline' ) ).toBeInTheDocument();
|
|
189
|
+
} );
|
|
190
|
+
|
|
191
|
+
test( 'handles data with large range', () => {
|
|
192
|
+
renderUnwrappedWithTheme( { data: [ 1, 1000, 50, 500 ] } );
|
|
193
|
+
expect( screen.getByTestId( 'sparkline' ) ).toBeInTheDocument();
|
|
194
|
+
} );
|
|
195
|
+
} );
|
|
196
|
+
} );
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export type SparklineDataPoint = number;
|
|
2
|
+
|
|
3
|
+
export type GradientConfig = {
|
|
4
|
+
/**
|
|
5
|
+
* Start color for gradient (defaults to color prop)
|
|
6
|
+
*/
|
|
7
|
+
from?: string;
|
|
8
|
+
/**
|
|
9
|
+
* End color for gradient (defaults to theme backgroundColor)
|
|
10
|
+
*/
|
|
11
|
+
to?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Start opacity (0-1)
|
|
14
|
+
* @default 0.5
|
|
15
|
+
*/
|
|
16
|
+
fromOpacity?: number;
|
|
17
|
+
/**
|
|
18
|
+
* End opacity (0-1)
|
|
19
|
+
* @default 0.0
|
|
20
|
+
*/
|
|
21
|
+
toOpacity?: number;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export interface SparklineProps {
|
|
25
|
+
/**
|
|
26
|
+
* Array of numeric values to plot
|
|
27
|
+
* @example [10, 25, 15, 30, 22, 35]
|
|
28
|
+
*/
|
|
29
|
+
data: SparklineDataPoint[];
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Width of the sparkline in pixels
|
|
33
|
+
* @default 100
|
|
34
|
+
*/
|
|
35
|
+
width?: number;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Height of the sparkline in pixels
|
|
39
|
+
* @default 40
|
|
40
|
+
*/
|
|
41
|
+
height?: number;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Size (used by responsive variant, equivalent to width for square charts)
|
|
45
|
+
*/
|
|
46
|
+
size?: number;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Color for the line stroke (hex or CSS color)
|
|
50
|
+
* @default Theme color (first color in theme.colors array)
|
|
51
|
+
*/
|
|
52
|
+
color?: string;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Line stroke width in pixels
|
|
56
|
+
* @default 1
|
|
57
|
+
*/
|
|
58
|
+
strokeWidth?: number;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Whether to render the gradient fill beneath the line
|
|
62
|
+
* @default true
|
|
63
|
+
*/
|
|
64
|
+
withGradientFill?: boolean;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Gradient configuration for area fill
|
|
68
|
+
* If not provided, uses color prop with default opacity values
|
|
69
|
+
*/
|
|
70
|
+
gradient?: GradientConfig;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Additional CSS class name
|
|
74
|
+
*/
|
|
75
|
+
className?: string;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Chart ID for unique gradient/element identification
|
|
79
|
+
*/
|
|
80
|
+
chartId?: string;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Margin around the chart
|
|
84
|
+
* @default { top: 2, right: 2, bottom: 2, left: 2 }
|
|
85
|
+
*/
|
|
86
|
+
margin?: {
|
|
87
|
+
top?: number;
|
|
88
|
+
right?: number;
|
|
89
|
+
bottom?: number;
|
|
90
|
+
left?: number;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useContext, useMemo, forwardRef } from 'react';
|
|
2
|
+
import { SingleChartContext } from '../../charts/private/single-chart-context';
|
|
2
3
|
import { GlobalChartsContext } from '../../providers';
|
|
3
|
-
import { SingleChartContext } from '../private/single-chart-context';
|
|
4
4
|
import { BaseLegend } from './private';
|
|
5
5
|
import type { LegendProps } from './types';
|
|
6
6
|
|
package/src/index.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
// Charts
|
|
2
|
-
export { BarChart, BarChartUnresponsive } from './
|
|
3
|
-
export { LineChart, LineChartUnresponsive } from './
|
|
4
|
-
export { PieChart, PieChartUnresponsive } from './
|
|
5
|
-
export {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from './
|
|
9
|
-
export {
|
|
10
|
-
export { LeaderboardChart, LeaderboardChartUnresponsive } from './components/leaderboard-chart';
|
|
11
|
-
export { ConversionFunnelChart } from './components/conversion-funnel-chart';
|
|
2
|
+
export { BarChart, BarChartUnresponsive } from './charts/bar-chart';
|
|
3
|
+
export { LineChart, LineChartUnresponsive } from './charts/line-chart';
|
|
4
|
+
export { PieChart, PieChartUnresponsive } from './charts/pie-chart';
|
|
5
|
+
export { PieSemiCircleChart, PieSemiCircleChartUnresponsive } from './charts/pie-semi-circle-chart';
|
|
6
|
+
export { BarListChart, BarListChartUnresponsive } from './charts/bar-list-chart';
|
|
7
|
+
export { LeaderboardChart, LeaderboardChartUnresponsive } from './charts/leaderboard-chart';
|
|
8
|
+
export { ConversionFunnelChart } from './charts/conversion-funnel-chart';
|
|
9
|
+
export { Sparkline, SparklineUnresponsive } from './charts/sparkline';
|
|
12
10
|
|
|
13
|
-
//
|
|
11
|
+
// Components
|
|
14
12
|
export { BaseTooltip } from './components/tooltip';
|
|
15
13
|
export { Legend, useChartLegendItems } from './components/legend';
|
|
16
14
|
export type { LegendValueDisplay, BaseLegendItem } from './components/legend';
|
|
17
15
|
|
|
16
|
+
// Compositions
|
|
17
|
+
|
|
18
18
|
// Themes
|
|
19
19
|
export { GlobalChartsProvider as ThemeProvider } from './providers';
|
|
20
20
|
|
|
@@ -25,13 +25,11 @@ export {
|
|
|
25
25
|
useGlobalChartsTheme,
|
|
26
26
|
GlobalChartsContext,
|
|
27
27
|
defaultTheme,
|
|
28
|
-
jetpackTheme,
|
|
29
|
-
wooTheme,
|
|
30
28
|
} from './providers';
|
|
31
29
|
|
|
32
30
|
// Types
|
|
33
31
|
export type * from './types';
|
|
34
32
|
export type * from './visx/types';
|
|
35
|
-
export type { PieChartProps } from './
|
|
33
|
+
export type { PieChartProps } from './charts/pie-chart';
|
|
36
34
|
|
|
37
35
|
export type { LineStyles, GridStyles, EventHandlerParams } from '@visx/xychart';
|
|
@@ -4,7 +4,6 @@ import { GlobalChartsProvider } from '../global-charts-provider';
|
|
|
4
4
|
import { useChartId } from '../hooks/use-chart-id';
|
|
5
5
|
import { useChartRegistration } from '../hooks/use-chart-registration';
|
|
6
6
|
import { useGlobalChartsContext } from '../hooks/use-global-charts-context';
|
|
7
|
-
import { wooTheme } from '../themes';
|
|
8
7
|
import type { BaseLegendItem } from '../../../components/legend';
|
|
9
8
|
import type { ChartTheme, SeriesData } from '../../../types';
|
|
10
9
|
import type { GlobalChartsContextValue } from '../types';
|
|
@@ -768,40 +767,6 @@ describe( 'ChartContext', () => {
|
|
|
768
767
|
|
|
769
768
|
expect( afterThemeChangeColor ).not.toBe( initialColor );
|
|
770
769
|
} );
|
|
771
|
-
|
|
772
|
-
it( 'generates colors with Woo theme characteristics', () => {
|
|
773
|
-
let contextValue: GlobalChartsContextValue;
|
|
774
|
-
|
|
775
|
-
const TestComponent = () => {
|
|
776
|
-
contextValue = useGlobalChartsContext();
|
|
777
|
-
return <div>Test</div>;
|
|
778
|
-
};
|
|
779
|
-
|
|
780
|
-
render(
|
|
781
|
-
<GlobalChartsProvider theme={ wooTheme }>
|
|
782
|
-
<TestComponent />
|
|
783
|
-
</GlobalChartsProvider>
|
|
784
|
-
);
|
|
785
|
-
|
|
786
|
-
// Generate colors beyond the palette
|
|
787
|
-
const generatedColors = [];
|
|
788
|
-
for ( let i = 5; i < 8; i++ ) {
|
|
789
|
-
const color = contextValue.getElementStyles( {
|
|
790
|
-
data: createMockDataWithGroup( undefined ),
|
|
791
|
-
index: i,
|
|
792
|
-
} ).color;
|
|
793
|
-
generatedColors.push( color );
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
// All generated colors should be in HSL format
|
|
797
|
-
generatedColors.forEach( color => {
|
|
798
|
-
expect( color ).toMatch( /^hsl\(\d+,\s*\d+%,\s*\d+%\)$/ );
|
|
799
|
-
} );
|
|
800
|
-
|
|
801
|
-
// All generated colors should be different
|
|
802
|
-
const uniqueColors = new Set( generatedColors );
|
|
803
|
-
expect( uniqueColors.size ).toBe( generatedColors.length );
|
|
804
|
-
} );
|
|
805
770
|
} );
|
|
806
771
|
|
|
807
772
|
describe( 'Context stability', () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { renderHook } from '@testing-library/react';
|
|
2
2
|
import { GlobalChartsProvider } from '../global-charts-provider';
|
|
3
3
|
import { useGlobalChartsTheme } from '../hooks/use-global-charts-theme';
|
|
4
|
-
import { defaultTheme
|
|
4
|
+
import { defaultTheme } from '../themes';
|
|
5
5
|
import type { ChartTheme } from '../../../types';
|
|
6
6
|
import type { ReactNode } from 'react';
|
|
7
7
|
|
|
@@ -33,28 +33,6 @@ describe( 'useGlobalChartsTheme', () => {
|
|
|
33
33
|
expect( result.current.gridStyles ).toEqual( defaultTheme.gridStyles );
|
|
34
34
|
} );
|
|
35
35
|
|
|
36
|
-
it( 'should work with predefined jetpackTheme', () => {
|
|
37
|
-
const wrapper = createWrapper( jetpackTheme );
|
|
38
|
-
|
|
39
|
-
const { result } = renderHook( () => useGlobalChartsTheme(), { wrapper } );
|
|
40
|
-
|
|
41
|
-
expect( result.current.colors ).toEqual( jetpackTheme.colors );
|
|
42
|
-
expect( result.current.leaderboardChart?.primaryColor ).toBe(
|
|
43
|
-
jetpackTheme.leaderboardChart?.primaryColor
|
|
44
|
-
);
|
|
45
|
-
} );
|
|
46
|
-
|
|
47
|
-
it( 'should work with predefined wooTheme', () => {
|
|
48
|
-
const wrapper = createWrapper( wooTheme );
|
|
49
|
-
|
|
50
|
-
const { result } = renderHook( () => useGlobalChartsTheme(), { wrapper } );
|
|
51
|
-
|
|
52
|
-
expect( result.current.colors ).toEqual( wooTheme.colors );
|
|
53
|
-
expect( result.current.leaderboardChart?.primaryColor ).toBe(
|
|
54
|
-
wooTheme.leaderboardChart?.primaryColor
|
|
55
|
-
);
|
|
56
|
-
} );
|
|
57
|
-
|
|
58
36
|
it( 'should handle empty theme object', () => {
|
|
59
37
|
const wrapper = createWrapper( {} );
|
|
60
38
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CompleteChartTheme } from '../../types';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Default theme configuration
|
|
@@ -58,132 +58,10 @@ const defaultTheme: CompleteChartTheme = {
|
|
|
58
58
|
},
|
|
59
59
|
},
|
|
60
60
|
},
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
* Jetpack theme configuration
|
|
65
|
-
*/
|
|
66
|
-
const jetpackTheme: ChartTheme = {
|
|
67
|
-
backgroundColor: '#FFFFFF', // chart background color
|
|
68
|
-
labelBackgroundColor: 'transparent', // label background color (transparent by default)
|
|
69
|
-
labelTextColor: '#FFFFFF', // label text color (white to match original behavior)
|
|
70
|
-
colors: [ '#98C8DF', '#006DAB', '#A6DC80', '#1F9828', '#FF8C8F' ],
|
|
71
|
-
gridStyles: {
|
|
72
|
-
stroke: '#DCDCDE',
|
|
73
|
-
strokeWidth: 1,
|
|
74
|
-
},
|
|
75
|
-
tickLength: 4,
|
|
76
|
-
gridColor: '',
|
|
77
|
-
gridColorDark: '',
|
|
78
|
-
xTickLineStyles: { stroke: 'black' },
|
|
79
|
-
xAxisLineStyles: { stroke: '#DCDCDE', strokeWidth: 1 },
|
|
80
|
-
legendLabelStyles: {
|
|
81
|
-
color: 'var(--jp-gray-80, #2c3338)',
|
|
82
|
-
},
|
|
83
|
-
svgLabelSmall: { fill: 'var(--jp-gray-80, #2c3338)' },
|
|
84
|
-
annotationStyles: {
|
|
85
|
-
label: {
|
|
86
|
-
anchorLineStroke: 'var(--jp-gray-80, #2c3338)',
|
|
87
|
-
backgroundFill: '#fff',
|
|
88
|
-
},
|
|
89
|
-
connector: {
|
|
90
|
-
stroke: 'var(--jp-gray-80, #2c3338)',
|
|
91
|
-
},
|
|
92
|
-
circleSubject: {
|
|
93
|
-
stroke: 'transparent',
|
|
94
|
-
fill: 'var(--jp-gray-80, #2c3338)',
|
|
95
|
-
radius: 5,
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
leaderboardChart: {
|
|
99
|
-
rowGap: 12,
|
|
100
|
-
columnGap: 4,
|
|
101
|
-
labelSpacing: 1.5,
|
|
102
|
-
primaryColor: '#006DAB',
|
|
103
|
-
secondaryColor: '#98C8DF',
|
|
104
|
-
deltaColors: [ '#FF8C8F', '#757575', '#1F9828' ], // [negative, neutral, positive]
|
|
105
|
-
},
|
|
106
|
-
conversionFunnelChart: {
|
|
107
|
-
backgroundColor: '#F3F4F6',
|
|
108
|
-
positiveChangeColor: '#1F9828',
|
|
109
|
-
negativeChangeColor: '#FF8C8F',
|
|
110
|
-
},
|
|
111
|
-
lineChart: {
|
|
112
|
-
lineStyles: {
|
|
113
|
-
comparison: {
|
|
114
|
-
strokeDasharray: '4 4',
|
|
115
|
-
strokeLinecap: 'square',
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Woo theme configuration
|
|
123
|
-
*/
|
|
124
|
-
const wooTheme: ChartTheme = {
|
|
125
|
-
backgroundColor: '#FFFFFF', // chart background color
|
|
126
|
-
labelBackgroundColor: 'transparent', // label background color (transparent by default)
|
|
127
|
-
labelTextColor: '#FFFFFF', // label text color (white to match original behavior)
|
|
128
|
-
colors: [
|
|
129
|
-
'#3858E9', // WooCommerce brand blue
|
|
130
|
-
'#66BDFF', // Light blue
|
|
131
|
-
'#873EFF', // Purple
|
|
132
|
-
'#7B90FF', // Periwinkle blue
|
|
133
|
-
'#EB6594', // Pink/rose
|
|
134
|
-
],
|
|
135
|
-
gridStyles: {
|
|
136
|
-
stroke: '#787C82',
|
|
137
|
-
strokeWidth: 1,
|
|
138
|
-
},
|
|
139
|
-
tickLength: 4,
|
|
140
|
-
gridColor: '',
|
|
141
|
-
gridColorDark: '',
|
|
142
|
-
svgLabelSmall: { fill: '#757575' },
|
|
143
|
-
xTickLineStyles: { stroke: 'black' },
|
|
144
|
-
xAxisLineStyles: { stroke: '#DCDCDE', strokeWidth: 1 },
|
|
145
|
-
legendLabelStyles: {
|
|
146
|
-
fontSize: '12px',
|
|
147
|
-
fontWeight: 400,
|
|
148
|
-
color: '#757575',
|
|
149
|
-
},
|
|
150
|
-
legendContainerStyles: {
|
|
151
|
-
gap: '8px',
|
|
152
|
-
},
|
|
153
|
-
annotationStyles: {
|
|
154
|
-
label: {
|
|
155
|
-
anchorLineStroke: 'black',
|
|
156
|
-
backgroundFill: '#fff',
|
|
157
|
-
},
|
|
158
|
-
connector: {
|
|
159
|
-
stroke: 'black',
|
|
160
|
-
},
|
|
161
|
-
circleSubject: {
|
|
162
|
-
stroke: 'transparent',
|
|
163
|
-
fill: 'black',
|
|
164
|
-
radius: 5,
|
|
165
|
-
},
|
|
166
|
-
},
|
|
167
|
-
leaderboardChart: {
|
|
168
|
-
rowGap: 12,
|
|
169
|
-
columnGap: 4,
|
|
170
|
-
labelSpacing: 1.5,
|
|
171
|
-
deltaColors: [ '#D63638', '#757575', '#008A20' ], // [negative, neutral, positive]
|
|
172
|
-
},
|
|
173
|
-
conversionFunnelChart: {
|
|
174
|
-
backgroundColor: '#F3F4F6',
|
|
175
|
-
positiveChangeColor: '#008A20',
|
|
176
|
-
negativeChangeColor: '#D63638',
|
|
177
|
-
},
|
|
178
|
-
lineChart: {
|
|
179
|
-
lineStyles: {
|
|
180
|
-
comparison: {
|
|
181
|
-
strokeDasharray: '4 4',
|
|
182
|
-
strokeWidth: 1.5,
|
|
183
|
-
strokeLinecap: 'square',
|
|
184
|
-
},
|
|
185
|
-
},
|
|
61
|
+
sparkline: {
|
|
62
|
+
margin: { top: 2, right: 2, bottom: 2, left: 2 },
|
|
63
|
+
strokeWidth: 1.5,
|
|
186
64
|
},
|
|
187
65
|
};
|
|
188
66
|
|
|
189
|
-
export { defaultTheme
|
|
67
|
+
export { defaultTheme };
|
package/src/types.ts
CHANGED
|
@@ -215,6 +215,18 @@ export type ChartTheme = {
|
|
|
215
215
|
lineChart?: {
|
|
216
216
|
lineStyles?: Partial< Record< NonNullable< SeriesDataOptions[ 'type' ] >, LineStyles > >;
|
|
217
217
|
};
|
|
218
|
+
/** Sparkline specific settings */
|
|
219
|
+
sparkline?: {
|
|
220
|
+
/** Margin around the sparkline chart */
|
|
221
|
+
margin?: {
|
|
222
|
+
top?: number;
|
|
223
|
+
right?: number;
|
|
224
|
+
bottom?: number;
|
|
225
|
+
left?: number;
|
|
226
|
+
};
|
|
227
|
+
/** Stroke width for the sparkline line */
|
|
228
|
+
strokeWidth?: number;
|
|
229
|
+
};
|
|
218
230
|
};
|
|
219
231
|
|
|
220
232
|
/**
|
|
@@ -235,6 +247,9 @@ export type CompleteChartTheme = Required< ChartTheme > & {
|
|
|
235
247
|
lineChart: {
|
|
236
248
|
lineStyles: Record< NonNullable< SeriesDataOptions[ 'type' ] >, LineStyles >;
|
|
237
249
|
};
|
|
250
|
+
sparkline: Required< NonNullable< ChartTheme[ 'sparkline' ] > > & {
|
|
251
|
+
margin: Required< NonNullable< ChartTheme[ 'sparkline' ] >[ 'margin' ] >;
|
|
252
|
+
};
|
|
238
253
|
};
|
|
239
254
|
|
|
240
255
|
declare type AxisOptions = {
|
|
@@ -245,6 +260,10 @@ declare type AxisOptions = {
|
|
|
245
260
|
labelClassName?: string;
|
|
246
261
|
tickClassName?: string;
|
|
247
262
|
tickFormat?: TickFormatter< ScaleInput< AxisScale > >;
|
|
263
|
+
/**
|
|
264
|
+
* Whether to display this axis. Defaults to true.
|
|
265
|
+
*/
|
|
266
|
+
display?: boolean;
|
|
248
267
|
/**
|
|
249
268
|
* For more control over rendering or to add event handlers to datum, pass a function as children.
|
|
250
269
|
*/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/private/radial-wipe-animation/radial-wipe-animation.tsx"],"sourcesContent":["/**\n * This animation uses the SVG self-drawing technique (source: https://www.joshwcomeau.com/svg/friendly-introduction-to-svg/),\n * leveraging stroke-dasharray and stroke-dashoffset properties to create the effect.\n *\n * Here, we reverse the animation to \"un-draw\" the circle for the revealing / radial wipe effect:\n * - Initially, the entire circle is drawn with a white mask.\n * - The circle's border (stroke) is drawn with a black stroke, wide enough to cover the circle.\n * - The stroke is then \"un-drawn,\" creating the wipe animation.\n * - A white mask makes the area visible, while a black mask makes the area invisible.\n */\n\ntype Angle = `${ number }deg` | `${ number }rad` | `${ number }grad` | `${ number }turn` | 0 | '0';\n\n/**\n * RadialWipeAnimationProps - SVG mask props that requires a radial wipe animation effect.\n *\n * @param {object} props - The properties object.\n * @param {string} props.id - The unique ID for the mask.\n * @param {number} props.radius - The outer radius of the radial wipe.\n * @param {number} [props.innerRadius=0] - The inner radius of the radial wipe.\n * @param {number} [props.durationMs=1000] - The duration of the animation in milliseconds.\n * @param {number} [props.wipePercentage=100] - The percentage of the wipe animation to complete.\n * @param {'clockwise' | 'counter-clockwise'} [props.direction='clockwise'] - The direction of the wipe animation.\n * @param {Angle} [props.startAngle='-90deg'] - The starting angle of the wipe animation.\n *\n * @return {JSX.Element} The radial wipe mask element.\n */\nexport type RadialWipeAnimationProps = {\n\tid: string;\n\tradius: number;\n\tinnerRadius?: number;\n\tdurationMs?: number;\n\tstartAngle?: Angle;\n\tdirection?: 'clockwise' | 'counter-clockwise';\n\twipePercentage?: number;\n};\n\n/**\n * Renders a SVG mask that creates a radial wipe animation effect.\n *\n * @param {RadialWipeAnimationProps} props - Component props\n * @return {JSX.Element} The rendered mask component\n */\nfunction RadialWipeAnimation( {\n\tid,\n\tradius,\n\tinnerRadius = 0,\n\tdurationMs = 1000,\n\twipePercentage = 100,\n\tdirection = 'clockwise',\n\tstartAngle = '-90deg',\n}: RadialWipeAnimationProps ) {\n\tconst strokeWidth =\n\t\t( radius - innerRadius ) * 2 + // The stroke is centered on the circumference, so we need to double the width.\n\t\t1; // Added 1 to prevent sub-pixel rendering issues.\n\n\tconst scaleY = direction === 'clockwise' ? -1 : 1;\n\n\tconst isValidWipePercentage = 0 < wipePercentage && wipePercentage <= 100;\n\tconst animationDuration = `${\n\t\t// If wipePercentage is invalid, set animation duration to 0 to disable animation.\n\t\tisValidWipePercentage ? durationMs * ( 100 / wipePercentage ) : 0\n\t}ms`;\n\n\treturn (\n\t\t<mask id={ id }>\n\t\t\t<circle\n\t\t\t\tcx={ 0 }\n\t\t\t\tcy={ 0 }\n\t\t\t\tr={ radius }\n\t\t\t\tpathLength=\"100\"\n\t\t\t\tfill=\"white\"\n\t\t\t\tstroke=\"black\" // The stroke will be un-drawn, hence 'black' mask.\n\t\t\t\tstrokeWidth={ strokeWidth }\n\t\t\t\tstrokeDasharray=\"100, 1000\"\n\t\t\t\tstrokeDashoffset=\"0\"\n\t\t\t\tstyle={ { transform: `rotate(${ startAngle }) scaleY(${ scaleY })` } }\n\t\t\t>\n\t\t\t\t<animate\n\t\t\t\t\tattributeName=\"stroke-dashoffset\"\n\t\t\t\t\tfrom=\"0\"\n\t\t\t\t\tto=\"100.1\"\n\t\t\t\t\tdur={ animationDuration }\n\t\t\t\t\tfill=\"freeze\" // Same as CSS 'forwards' to retain the final state after animation.\n\t\t\t\t\tcalcMode=\"spline\" // custom easing\n\t\t\t\t\tkeySplines=\"0.42 0 0.58 1;0 0 1 1\" // ease-in-out ; linear (unimportant)\n\t\t\t\t\tkeyTimes={ `0;${ wipePercentage / 100 };1` }\n\t\t\t\t/>\n\t\t\t</circle>\n\t\t</mask>\n\t);\n}\n\nexport default RadialWipeAnimation;\n"],"mappings":";AA8EI;AAnCJ,SAAS,oBAAqB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,aAAa;AACd,GAA8B;AAC7B,QAAM,eACH,SAAS,eAAgB;AAAA,EAC3B;AAED,QAAM,SAAS,cAAc,cAAc,KAAK;AAEhD,QAAM,wBAAwB,IAAI,kBAAkB,kBAAkB;AACtE,QAAM,oBAAoB;AAAA,EAEzB,wBAAwB,cAAe,MAAM,kBAAmB,CACjE;AAEA,SACC,oBAAC,UAAK,IACL;AAAA,IAAC;AAAA;AAAA,MACA,IAAK;AAAA,MACL,IAAK;AAAA,MACL,GAAI;AAAA,MACJ,YAAW;AAAA,MACX,MAAK;AAAA,MACL,QAAO;AAAA,MACP;AAAA,MACA,iBAAgB;AAAA,MAChB,kBAAiB;AAAA,MACjB,OAAQ,EAAE,WAAW,UAAW,UAAW,YAAa,MAAO,IAAI;AAAA,MAEnE;AAAA,QAAC;AAAA;AAAA,UACA,eAAc;AAAA,UACd,MAAK;AAAA,UACL,IAAG;AAAA,UACH,KAAM;AAAA,UACN,MAAK;AAAA,UACL,UAAS;AAAA,UACT,YAAW;AAAA,UACX,UAAW,KAAM,iBAAiB,GAAI;AAAA;AAAA,MACvC;AAAA;AAAA,EACD,GACD;AAEF;AAEA,IAAO,gCAAQ;","names":[]}
|