@taiv/ui 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Data/Cards/ChartCard.d.ts +9 -0
- package/dist/components/Data/Cards/ChartCard.d.ts.map +1 -0
- package/dist/components/Data/Cards/ChartCard.js +9 -0
- package/dist/components/Data/Cards/PieChartCard.d.ts +10 -0
- package/dist/components/Data/Cards/PieChartCard.d.ts.map +1 -0
- package/dist/components/Data/Cards/PieChartCard.js +9 -0
- package/dist/components/Data/Cards/StatsCard.d.ts +17 -0
- package/dist/components/Data/Cards/StatsCard.d.ts.map +1 -0
- package/dist/components/Data/Cards/StatsCard.js +38 -0
- package/dist/components/Data/Chart.d.ts +5 -24
- package/dist/components/Data/Chart.d.ts.map +1 -1
- package/dist/components/Data/Chart.js +63 -80
- package/dist/components/Data/JustChart.d.ts +23 -0
- package/dist/components/Data/JustChart.d.ts.map +1 -0
- package/dist/components/Data/JustChart.js +70 -0
- package/dist/components/Data/JustPieChart.d.ts +20 -0
- package/dist/components/Data/JustPieChart.d.ts.map +1 -0
- package/dist/components/Data/JustPieChart.js +63 -0
- package/dist/components/Data/PieChart.d.ts +9 -12
- package/dist/components/Data/PieChart.d.ts.map +1 -1
- package/dist/components/Data/PieChart.js +35 -43
- package/dist/components/Data/StatsBadge.d.ts +10 -0
- package/dist/components/Data/StatsBadge.d.ts.map +1 -0
- package/dist/components/Data/StatsBadge.js +25 -0
- package/dist/components/Data/StatsCard.d.ts +2 -2
- package/dist/components/Data/StatsCard.d.ts.map +1 -1
- package/dist/components/Data/StatsCard.js +2 -2
- package/dist/components/Data/shared/chartFormats.d.ts +8 -0
- package/dist/components/Data/shared/chartFormats.d.ts.map +1 -0
- package/dist/components/Data/shared/chartFormats.js +29 -0
- package/dist/components/Data/shared/dataFormats.d.ts +7 -33
- package/dist/components/Data/shared/dataFormats.d.ts.map +1 -1
- package/dist/components/Data/shared/dataFormats.js +15 -20
- package/dist/components/Info/Badge.d.ts +10 -0
- package/dist/components/Info/Badge.d.ts.map +1 -1
- package/dist/components/Info/Badge.js +64 -1
- package/dist/components/Info/Tooltips/FormulaTooltip.d.ts +8 -0
- package/dist/components/Info/Tooltips/FormulaTooltip.d.ts.map +1 -0
- package/dist/components/Info/Tooltips/FormulaTooltip.js +11 -0
- package/dist/components/Info/Tooltips/InfoTooltip.d.ts +2 -1
- package/dist/components/Info/Tooltips/InfoTooltip.d.ts.map +1 -1
- package/dist/components/Info/Tooltips/InfoTooltip.js +2 -2
- package/dist/components/Info/Tooltips/Tooltip.d.ts +2 -1
- package/dist/components/Info/Tooltips/Tooltip.d.ts.map +1 -1
- package/dist/components/Info/Tooltips/Tooltip.js +2 -2
- package/dist/components/Inputs/Controls/Radio.d.ts +8 -0
- package/dist/components/Inputs/Controls/Radio.d.ts.map +1 -0
- package/dist/components/Inputs/Controls/Radio.js +43 -0
- package/dist/components/Inputs/Controls/RadioList.d.ts +16 -0
- package/dist/components/Inputs/Controls/RadioList.d.ts.map +1 -0
- package/dist/components/Inputs/Controls/RadioList.js +24 -0
- package/dist/components/Inputs/DatePickers/DatePicker.d.ts.map +1 -1
- package/dist/components/Inputs/DatePickers/DatePicker.js +39 -3
- package/dist/components/Inputs/Dates/DatePicker.d.ts +12 -0
- package/dist/components/Inputs/Dates/DatePicker.d.ts.map +1 -0
- package/dist/components/Inputs/Dates/DatePicker.js +71 -0
- package/dist/components/Inputs/Dropdowns/CascadingSelect.d.ts +17 -0
- package/dist/components/Inputs/Dropdowns/CascadingSelect.d.ts.map +1 -0
- package/dist/components/Inputs/Dropdowns/CascadingSelect.js +70 -0
- package/dist/components/Inputs/Dropdowns/FontSelect.d.ts +2 -5
- package/dist/components/Inputs/Dropdowns/FontSelect.d.ts.map +1 -1
- package/dist/components/Inputs/Dropdowns/FontSelect.js +1 -1
- package/dist/components/Inputs/Dropdowns/NestedSelect.d.ts +17 -0
- package/dist/components/Inputs/Dropdowns/NestedSelect.d.ts.map +1 -0
- package/dist/components/Inputs/Dropdowns/NestedSelect.js +70 -0
- package/dist/components/Inputs/Dropdowns/Select.d.ts.map +1 -1
- package/dist/components/Inputs/Dropdowns/Select.js +2 -2
- package/dist/components/Inputs/Dropdowns/shared/fontSelectList.d.ts +1 -4
- package/dist/components/Inputs/Dropdowns/shared/fontSelectList.d.ts.map +1 -1
- package/dist/components/Inputs/Dropdowns/shared/fontSelectList.js +1 -4
- package/dist/components/Layout/Divider.d.ts +2 -1
- package/dist/components/Layout/Divider.d.ts.map +1 -1
- package/dist/components/Layout/Divider.js +2 -2
- package/dist/components/Layout/SectionCard.d.ts.map +1 -1
- package/dist/components/Layout/SectionCard.js +3 -2
- package/dist/components/Misc/IconBadge.d.ts +2 -2
- package/dist/components/Misc/IconBadge.d.ts.map +1 -1
- package/dist/components/Misc/IconBadge.js +3 -4
- package/dist/components/Typography/Formula.d.ts +10 -0
- package/dist/components/Typography/Formula.d.ts.map +1 -0
- package/dist/components/Typography/Formula.js +141 -0
- package/dist/components/Typography/Fraction.d.ts +3 -4
- package/dist/components/Typography/Fraction.d.ts.map +1 -1
- package/dist/components/Typography/Fraction.js +6 -3
- package/dist/components/Typography/Text.d.ts +1 -1
- package/dist/components/Typography/Text.d.ts.map +1 -1
- package/dist/components/Typography/Text.js +7 -0
- package/dist/components/index.d.ts +11 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +11 -2
- package/dist/constants/colors.d.ts +1 -1
- package/dist/constants/colors.d.ts.map +1 -1
- package/dist/constants/colors.js +3 -3
- package/dist/constants/data.d.ts +70 -0
- package/dist/constants/data.d.ts.map +1 -0
- package/dist/constants/data.js +15 -0
- package/dist/hooks/useDropdowns.d.ts +9 -0
- package/dist/hooks/useDropdowns.d.ts.map +1 -0
- package/dist/hooks/useDropdowns.js +12 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/types.d.ts +20 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/types.js +2 -0
- package/dist/utils/charts.d.ts +13 -0
- package/dist/utils/charts.d.ts.map +1 -0
- package/dist/utils/charts.js +48 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/select.d.ts +5 -0
- package/dist/utils/select.d.ts.map +1 -0
- package/dist/utils/select.js +12 -0
- package/package.json +6 -2
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { CardProps } from '../../Layout/Card';
|
|
3
|
+
import { ChartProps } from '../Chart';
|
|
4
|
+
export interface ChartCardProps extends ChartProps, Omit<CardProps, 'children'> {
|
|
5
|
+
title: string;
|
|
6
|
+
subtitle?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const ChartCard: React.FC<ChartCardProps>;
|
|
9
|
+
//# sourceMappingURL=ChartCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChartCard.d.ts","sourceRoot":"","sources":["../../../../src/components/Data/Cards/ChartCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAQ,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAS,UAAU,EAAE,MAAM,UAAU,CAAC;AAK7C,MAAM,WAAW,cAAe,SAAQ,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;IAC7E,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAe9C,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Card } from '../../Layout/Card';
|
|
3
|
+
import { Chart } from '../Chart';
|
|
4
|
+
import { Stack } from '../../Layout/Stack';
|
|
5
|
+
import { Title } from '../../Typography/Title';
|
|
6
|
+
import { Text } from '../../Typography/Text';
|
|
7
|
+
export const ChartCard = ({ title, subtitle, series, yAxisFormat, xAxisFormat, showLegend, loading, height = '30rem', ...cardProps }) => {
|
|
8
|
+
return (_jsxs(_Fragment, { children: [_jsx(Card, { ...cardProps, h: height, children: _jsxs(Stack, { gap: "2.4rem", h: "100%", w: "100%", children: [_jsxs(Stack, { gap: "0.5rem", children: [_jsx(Title, { variant: "cardHeader", children: title }), subtitle && _jsx(Text, { variant: "label", children: subtitle })] }), _jsx(Chart, { series: series, yAxisFormat: yAxisFormat, xAxisFormat: xAxisFormat, showLegend: showLegend, loading: loading })] }) }), _jsx("style", { children: `.recharts-surface { outline: none; }` })] }));
|
|
9
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { CardProps } from '../../Layout/Card';
|
|
3
|
+
import { PieChartProps } from '../PieChart';
|
|
4
|
+
export interface PieChartCardProps extends PieChartProps, Omit<CardProps, 'children'> {
|
|
5
|
+
title: string;
|
|
6
|
+
subtitle?: string;
|
|
7
|
+
height?: number | string;
|
|
8
|
+
}
|
|
9
|
+
export declare const PieChartCard: React.FC<PieChartCardProps>;
|
|
10
|
+
//# sourceMappingURL=PieChartCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PieChartCard.d.ts","sourceRoot":"","sources":["../../../../src/components/Data/Cards/PieChartCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAQ,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAY,aAAa,EAAE,MAAM,aAAa,CAAC;AAKtD,MAAM,WAAW,iBAAkB,SAAQ,aAAa,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;IACnF,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqCpD,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Card } from '../../Layout/Card';
|
|
3
|
+
import { PieChart } from '../PieChart';
|
|
4
|
+
import { Stack } from '../../Layout/Stack';
|
|
5
|
+
import { Title } from '../../Typography/Title';
|
|
6
|
+
import { Text } from '../../Typography/Text';
|
|
7
|
+
export const PieChartCard = ({ title, subtitle, data, height = '100%', showLegend, innerRadius, outerRadius, paddingAngle, format = 'percentage', loading, centerContent, ...cardProps }) => {
|
|
8
|
+
return (_jsxs(_Fragment, { children: [_jsx(Card, { ...cardProps, h: height, children: _jsxs(Stack, { gap: "0rem", h: "100%", w: "100%", children: [_jsxs(Stack, { gap: "0.5rem", children: [_jsx(Title, { variant: "cardHeader", children: title }), subtitle && _jsx(Text, { variant: "label", children: subtitle })] }), _jsx(PieChart, { data: data, showLegend: showLegend, innerRadius: innerRadius, outerRadius: outerRadius, paddingAngle: paddingAngle, format: format, loading: loading, centerContent: centerContent })] }) }), _jsx("style", { children: `.recharts-surface { outline: none; }` })] }));
|
|
9
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { CardProps } from '../../Layout/Card';
|
|
3
|
+
import { primitives } from '../../../constants/colors';
|
|
4
|
+
import { formats } from '../../../constants/data';
|
|
5
|
+
export interface StatsCardProps extends Omit<CardProps, 'children'> {
|
|
6
|
+
value: number;
|
|
7
|
+
title: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
format?: keyof typeof formats;
|
|
10
|
+
isDelta?: boolean;
|
|
11
|
+
icon?: React.ReactNode;
|
|
12
|
+
iconColor?: keyof typeof primitives;
|
|
13
|
+
tooltip?: React.ReactNode;
|
|
14
|
+
increaseDescription?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const StatsCard: ({ value, format, isDelta, title, description, increaseDescription, icon: Icon, iconColor, tooltip, ...cardProps }: StatsCardProps) => import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=StatsCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatsCard.d.ts","sourceRoot":"","sources":["../../../../src/components/Data/Cards/StatsCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAQ,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAOpD,OAAO,EAAE,UAAU,EAAoB,MAAM,2BAA2B,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAElD,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,OAAO,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,OAAO,UAAU,CAAC;IACpC,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,eAAO,MAAM,SAAS,GAAI,mHAAgJ,cAAc,4CA4DvL,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Card } from '../../Layout/Card';
|
|
3
|
+
import { InfoTooltip } from '../../Info/Tooltips/InfoTooltip';
|
|
4
|
+
import { Text } from '../../Typography/Text';
|
|
5
|
+
import { Title } from '../../Typography/Title';
|
|
6
|
+
import { Group } from '../../Layout/Group';
|
|
7
|
+
import { Stack } from '../../Layout/Stack';
|
|
8
|
+
import { IconBadge } from '../../Misc/IconBadge';
|
|
9
|
+
import { success, neutral } from '../../../constants/colors';
|
|
10
|
+
import { formats } from '../../../constants/data';
|
|
11
|
+
export const StatsCard = ({ value, format = 'decimal', isDelta = false, title, description, increaseDescription, icon: Icon, iconColor = 'blue', tooltip, ...cardProps }) => {
|
|
12
|
+
const getDelta = () => {
|
|
13
|
+
const currentDirection = isDelta ? (value > 0 ? 'positive' : value < 0 ? 'negative' : null) : null;
|
|
14
|
+
return {
|
|
15
|
+
direction: currentDirection,
|
|
16
|
+
color: currentDirection === 'positive' ? success[200] : currentDirection === 'negative' ? neutral[200] : undefined,
|
|
17
|
+
showIncrementalText: currentDirection === 'positive',
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
const delta = getDelta();
|
|
21
|
+
const formatValue = () => {
|
|
22
|
+
const config = formats[format];
|
|
23
|
+
const formattedNumber = value.toLocaleString('en-US', {
|
|
24
|
+
minimumFractionDigits: config.decimalPlaces,
|
|
25
|
+
maximumFractionDigits: config.decimalPlaces,
|
|
26
|
+
});
|
|
27
|
+
let result = formattedNumber;
|
|
28
|
+
if (delta.direction === 'positive') {
|
|
29
|
+
result = `+${result}`;
|
|
30
|
+
}
|
|
31
|
+
else if (delta.direction === 'negative') {
|
|
32
|
+
result = `-${result}`;
|
|
33
|
+
}
|
|
34
|
+
result = `${config.prefix}${result}${config.suffix}`;
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
return (_jsx(Card, { bg: neutral[25], animate: true, ...cardProps, children: _jsxs(Stack, { gap: "1.6rem", children: [_jsxs(Stack, { gap: "0.25rem", children: [_jsxs(Group, { position: "apart", children: [_jsx(Title, { size: "3xl", weight: "bold", children: formatValue() }), Icon && _jsx(IconBadge, { icon: Icon, color: iconColor })] }), _jsxs(Group, { gap: "0.75rem", children: [_jsx(Title, { variant: "cardHeader", color: "#6D6D6D", weight: "medium", children: title }), tooltip && _jsx(InfoTooltip, { text: tooltip, maxWidth: "600px" })] })] }), _jsxs(Stack, { gap: "0", children: [description && _jsx(Text, { variant: "label", children: description }), delta.showIncrementalText && increaseDescription && (_jsx(Text, { variant: "label", color: delta.color, children: increaseDescription }))] })] }) }));
|
|
38
|
+
};
|
|
@@ -1,32 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
export interface
|
|
5
|
-
date: string | number;
|
|
6
|
-
value: number;
|
|
7
|
-
label?: string;
|
|
8
|
-
}
|
|
9
|
-
export interface ChartSeries {
|
|
10
|
-
name: string;
|
|
11
|
-
data: ChartDataPoint[];
|
|
12
|
-
color?: string;
|
|
13
|
-
type?: 'line' | 'area' | 'bar';
|
|
14
|
-
}
|
|
15
|
-
export interface ChartProps extends Omit<CardProps, 'children'> {
|
|
16
|
-
title: string;
|
|
17
|
-
subtitle?: string;
|
|
2
|
+
import { formats } from '../../constants/data';
|
|
3
|
+
import { ChartSeries } from '../../types/types';
|
|
4
|
+
export interface ChartProps {
|
|
18
5
|
series: ChartSeries[];
|
|
6
|
+
yAxisFormat?: keyof typeof formats;
|
|
7
|
+
xAxisFormat?: keyof typeof formats;
|
|
19
8
|
height?: string | number;
|
|
20
9
|
showLegend?: boolean;
|
|
21
|
-
showGrid?: boolean;
|
|
22
|
-
xAxisLabel?: string;
|
|
23
|
-
yAxisLabel?: string;
|
|
24
|
-
format?: keyof typeof dataFormats;
|
|
25
|
-
formatYAxis?: (value: number) => string;
|
|
26
|
-
formatXAxis?: (value: string | number) => string;
|
|
27
|
-
tooltipContent?: (data: any) => React.ReactNode;
|
|
28
10
|
loading?: boolean;
|
|
29
|
-
emptyMessage?: string;
|
|
30
11
|
}
|
|
31
12
|
export declare const Chart: React.FC<ChartProps>;
|
|
32
13
|
//# sourceMappingURL=Chart.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chart.d.ts","sourceRoot":"","sources":["../../../src/components/Data/Chart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Chart.d.ts","sourceRoot":"","sources":["../../../src/components/Data/Chart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAI/C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,OAAO,OAAO,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,OAAO,OAAO,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CAkKtC,CAAC"}
|
|
@@ -1,97 +1,80 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Card } from '../Layout/Card';
|
|
3
2
|
import { Text } from '../Typography/Text';
|
|
4
|
-
import { Title } from '../Typography/Title';
|
|
5
|
-
import { Stack } from '../Layout/Stack';
|
|
6
3
|
import { Center } from '../Layout/Center';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
4
|
+
import { Box } from '../Layout/Box';
|
|
5
|
+
import { Stack } from '../Layout/Stack';
|
|
9
6
|
import { Group } from '../Layout/Group';
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const getYAxisFormatter = () => {
|
|
19
|
-
// If custom formatYAxis is provided, use it (takes priority)
|
|
20
|
-
if (formatYAxis) {
|
|
21
|
-
return formatYAxis;
|
|
22
|
-
}
|
|
23
|
-
// Otherwise, use the smart chart format
|
|
24
|
-
return chartFormats[format];
|
|
25
|
-
};
|
|
26
|
-
const yAxisFormatter = getYAxisFormatter();
|
|
7
|
+
import { Area, Bar, CartesianGrid, ComposedChart, Legend, Line, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';
|
|
8
|
+
import { getChartFormatter } from '../../utils/charts';
|
|
9
|
+
import { fontStyle } from '../../constants/font';
|
|
10
|
+
import { primary, neutral } from '../../constants/colors';
|
|
11
|
+
import { createStyles } from '@mantine/core';
|
|
12
|
+
export const Chart = ({ series, yAxisFormat = 'decimal', xAxisFormat = 'string', showLegend = true, loading = false, height = '100%' }) => {
|
|
13
|
+
const formatYAxisValue = getChartFormatter(yAxisFormat);
|
|
14
|
+
const formatXAxisValue = getChartFormatter(xAxisFormat);
|
|
27
15
|
const hasData = series.some((s) => s.data.length > 0);
|
|
28
|
-
//
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return (_jsx(Card, { ...cardProps, children: _jsxs(Stack, { gap: "1rem", children: [_jsx(Title, { variant: "cardHeader", children: title }), subtitle && _jsx(Text, { variant: "label", children: subtitle }), _jsx(Center, { style: { height, backgroundColor: neutral[25], borderRadius: '8px' }, children: _jsx(Text, { variant: "label", color: neutral[200], children: "Loading..." }) })] }) }));
|
|
39
|
-
}
|
|
40
|
-
if (!hasData) {
|
|
41
|
-
return (_jsx(Card, { ...cardProps, children: _jsxs(Stack, { gap: "1rem", children: [_jsx(Title, { variant: "cardHeader", children: title }), subtitle && _jsx(Text, { variant: "label", children: subtitle }), _jsx(Center, { style: { height, backgroundColor: neutral[25], borderRadius: '8px' }, children: _jsx(Text, { variant: "label", color: neutral[200], children: emptyMessage }) })] }) }));
|
|
42
|
-
}
|
|
43
|
-
// Transform data to match Recharts format
|
|
44
|
-
const chartData = (_a = series[0]) === null || _a === void 0 ? void 0 : _a.data.map((point, index) => {
|
|
45
|
-
const dataPoint = { date: point.date };
|
|
46
|
-
series.forEach((s, seriesIndex) => {
|
|
47
|
-
if (s.data[index]) {
|
|
48
|
-
dataPoint[s.name] = s.data[index].value;
|
|
49
|
-
}
|
|
16
|
+
// Transform our ChartSeries array to match the Recharts format (just a singular data array keyed by the series name)
|
|
17
|
+
const transformedData = (() => {
|
|
18
|
+
if (!series.length)
|
|
19
|
+
return [];
|
|
20
|
+
return series[0].data.map((_, i) => {
|
|
21
|
+
const point = { key: series[0].data[i].key };
|
|
22
|
+
series.forEach((s) => {
|
|
23
|
+
point[s.name] = s.data[i].value;
|
|
24
|
+
});
|
|
25
|
+
return point;
|
|
50
26
|
});
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const CustomTooltip = ({ active, payload, label }) => {
|
|
27
|
+
})();
|
|
28
|
+
const getTooltip = (props) => {
|
|
29
|
+
const { active, payload, label } = props;
|
|
55
30
|
if (active && payload && payload.length) {
|
|
56
|
-
return (
|
|
31
|
+
return (_jsx(Box, { sx: {
|
|
57
32
|
backgroundColor: 'white',
|
|
58
|
-
padding: '
|
|
33
|
+
padding: '1rem',
|
|
59
34
|
border: `1px solid ${neutral[100]}`,
|
|
60
35
|
borderRadius: '8px',
|
|
61
36
|
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
|
62
|
-
}, children: [_jsx(Text, { weight: "semibold", color: neutral[300], children:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
37
|
+
}, children: _jsxs(Stack, { gap: "0.25rem", children: [_jsx(Text, { weight: "semibold", color: neutral[300], children: formatXAxisValue(label) }), payload.map((entry) => (_jsxs(Group, { gap: "0.5rem", children: [_jsx("div", { style: {
|
|
38
|
+
width: '8px',
|
|
39
|
+
height: '8px',
|
|
40
|
+
borderRadius: '50%',
|
|
41
|
+
backgroundColor: entry.color,
|
|
42
|
+
} }), _jsxs(Group, { gap: "0.25rem", children: [_jsxs(Text, { variant: "label", color: neutral[300], children: [entry.name, ":"] }), _jsx(Text, { variant: "label", children: formatYAxisValue(entry.value) })] })] }, entry.name)))] }) }));
|
|
68
43
|
}
|
|
69
44
|
return null;
|
|
70
45
|
};
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
46
|
+
const { classes } = createStyles(() => ({
|
|
47
|
+
rechartsText: {
|
|
48
|
+
'& .recharts-text.recharts-cartesian-axis-tick-value tspan': {
|
|
49
|
+
...fontStyle.label,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
rechartsSurface: {
|
|
53
|
+
'& .recharts-surface': {
|
|
54
|
+
outline: 'none',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
}))();
|
|
58
|
+
return (_jsx(_Fragment, { children: loading || !hasData ? (_jsx(Center, { style: { height, backgroundColor: neutral[25], borderRadius: '8px' }, children: _jsx(Text, { variant: "label", color: neutral[200], children: loading ? 'Loading...' : 'No data available' }) })) : (_jsx(_Fragment, { children: _jsx(Center, { h: height, w: "100%", className: classes.rechartsText, children: _jsx(ResponsiveContainer, { width: "100%", height: "100%", children: _jsxs(ComposedChart, { data: transformedData, className: classes.rechartsSurface, children: [_jsx("defs", { children: series.map((s, index) => (_jsxs("linearGradient", { id: `gradient-${index}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [_jsx("stop", { offset: "0%", stopColor: s.color || primary[200], stopOpacity: 0.3 }), _jsx("stop", { offset: "99%", stopColor: s.color || primary[200], stopOpacity: 0.05 })] }, s.name))) }), _jsx(XAxis, { dataKey: "key", axisLine: { stroke: neutral[50] }, tickLine: { stroke: neutral[50] }, tickMargin: 8, tickFormatter: formatXAxisValue }), _jsx(YAxis, { width: 50, axisLine: false, tickLine: false, tickFormatter: formatYAxisValue }), _jsx(CartesianGrid, { strokeDasharray: "0", stroke: neutral[50], horizontal: true, vertical: false }), series.map((s, index) => {
|
|
59
|
+
const seriesType = s.type || 'line';
|
|
60
|
+
if (seriesType === 'area') {
|
|
61
|
+
return (_jsx(Area, { type: "monotone", dataKey: s.name, stroke: s.color || primary[200], strokeWidth: 2, fill: `url(#gradient-${index})`, baseValue: "dataMin", style: { outline: 'none' } }, s.name));
|
|
62
|
+
}
|
|
63
|
+
else if (seriesType === 'bar') {
|
|
64
|
+
return (_jsx(Bar, { dataKey: s.name, fill: s.color || primary[200], radius: [8, 8, 0, 0], style: { outline: 'none' }, onMouseEnter: (data, index, event) => {
|
|
65
|
+
const barElement = event.target;
|
|
66
|
+
if (barElement) {
|
|
67
|
+
barElement.style.opacity = '0.8';
|
|
78
68
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
69
|
+
}, onMouseLeave: (data, index, event) => {
|
|
70
|
+
const barElement = event.target;
|
|
71
|
+
if (barElement) {
|
|
72
|
+
barElement.style.opacity = '1';
|
|
82
73
|
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
outline: 'none',
|
|
90
|
-
boxShadow: 'none',
|
|
91
|
-
padding: 0,
|
|
92
|
-
margin: 0,
|
|
93
|
-
backgroundColor: 'transparent',
|
|
94
|
-
}, labelStyle: {
|
|
95
|
-
display: 'none',
|
|
96
|
-
} }), showLegend && (_jsx(Legend, { iconType: "circle", iconSize: 8, formatter: (value) => (_jsx(Text, { variant: "label", sx: { color: neutral[300], display: 'inline', whiteSpace: 'nowrap' }, children: value })) }))] }) }) })] }) }), _jsx("style", { children: `.recharts-surface { outline: none; }` })] }));
|
|
74
|
+
} }, s.name));
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
return _jsx(Line, { type: "monotone", dataKey: s.name, stroke: s.color || primary[200], strokeWidth: 2, dot: false, style: { outline: 'none' } }, s.name);
|
|
78
|
+
}
|
|
79
|
+
}), _jsx(Tooltip, { content: getTooltip, cursor: series.some((s) => s.type === 'bar') ? false : true }), showLegend && (_jsx(Legend, { iconType: "circle", iconSize: 8, wrapperStyle: { paddingTop: '0.6rem' }, formatter: (value) => (_jsx(Text, { variant: "label", sx: { color: neutral[300], display: 'inline', whiteSpace: 'nowrap' }, children: value })) }))] }) }) }) })) }));
|
|
97
80
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { formats } from '../../constants/data';
|
|
3
|
+
export interface ChartDataPoint {
|
|
4
|
+
date: string | number;
|
|
5
|
+
value: number;
|
|
6
|
+
label?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ChartSeries {
|
|
9
|
+
name: string;
|
|
10
|
+
data: ChartDataPoint[];
|
|
11
|
+
color?: string;
|
|
12
|
+
type?: 'line' | 'area' | 'bar';
|
|
13
|
+
}
|
|
14
|
+
export interface ChartProps {
|
|
15
|
+
series: ChartSeries[];
|
|
16
|
+
height?: string | number;
|
|
17
|
+
yAxisFormat?: keyof typeof formats;
|
|
18
|
+
xAxisFormat?: keyof typeof formats;
|
|
19
|
+
showLegend?: boolean;
|
|
20
|
+
loading?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare const Chart: React.FC<ChartProps>;
|
|
23
|
+
//# sourceMappingURL=JustChart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JustChart.d.ts","sourceRoot":"","sources":["../../../src/components/Data/JustChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAK/C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,OAAO,OAAO,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,OAAO,OAAO,CAAC;IACnC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CAmKtC,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from '../Typography/Text';
|
|
3
|
+
import { Center } from '../Layout/Center';
|
|
4
|
+
import { primary, neutral } from '../../constants/colors';
|
|
5
|
+
import { Area, Bar, CartesianGrid, ComposedChart, Legend, Line, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';
|
|
6
|
+
import { Group } from '../Layout/Group';
|
|
7
|
+
import { getChartFormat } from './shared/dataFormats';
|
|
8
|
+
import { Box } from '../Layout/Box';
|
|
9
|
+
import { Stack } from '../Layout/Stack';
|
|
10
|
+
export const Chart = ({ series, height = 300, yAxisFormat = 'decimal', xAxisFormat = 'string', showLegend = true, loading = false }) => {
|
|
11
|
+
var _a;
|
|
12
|
+
const formatYAxisValue = getChartFormat[yAxisFormat];
|
|
13
|
+
const formatXAxisValue = (value) => value.toString();
|
|
14
|
+
// Transform data to match Recharts format
|
|
15
|
+
// TODO: This is a hack to get the data in the correct format - we should use the data in the correct format from the start
|
|
16
|
+
const chartData = (_a = series[0]) === null || _a === void 0 ? void 0 : _a.data.map((point, index) => {
|
|
17
|
+
const dataPoint = { date: point.date };
|
|
18
|
+
series.forEach((s) => {
|
|
19
|
+
if (s.data[index]) {
|
|
20
|
+
dataPoint[s.name] = s.data[index].value;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
return dataPoint;
|
|
24
|
+
});
|
|
25
|
+
const hasData = series.some((s) => s.data.length > 0);
|
|
26
|
+
// Single reusable tick component
|
|
27
|
+
const CustomTick = ({ x, y, payload, formatter }) => {
|
|
28
|
+
return (_jsx("g", { transform: `translate(${x},${y})`, children: _jsx("foreignObject", { x: 0, y: 0, width: 100, height: 20, children: _jsx("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }, children: _jsx(Text, { variant: "label", children: formatter(payload.value) }) }) }) }));
|
|
29
|
+
};
|
|
30
|
+
const getTooltipContent = (props) => {
|
|
31
|
+
const { active, payload, label } = props;
|
|
32
|
+
if (active && payload && payload.length) {
|
|
33
|
+
return (_jsx(Box, { sx: {
|
|
34
|
+
backgroundColor: 'white',
|
|
35
|
+
padding: '1rem',
|
|
36
|
+
border: `1px solid ${neutral[100]}`,
|
|
37
|
+
borderRadius: '8px',
|
|
38
|
+
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
|
39
|
+
}, children: _jsxs(Stack, { gap: "0.25rem", children: [_jsx(Text, { weight: "semibold", color: neutral[300], children: formatXAxisValue(label) }), payload.map((entry) => (_jsxs(Group, { gap: "0.5rem", children: [_jsx("div", { style: {
|
|
40
|
+
width: '8px',
|
|
41
|
+
height: '8px',
|
|
42
|
+
borderRadius: '50%',
|
|
43
|
+
backgroundColor: entry.color,
|
|
44
|
+
} }), _jsxs(Group, { gap: "0.25rem", children: [_jsxs(Text, { variant: "label", color: neutral[300], children: [entry.name, ":"] }), _jsx(Text, { variant: "label", children: formatYAxisValue(entry.value) })] })] }, entry.name)))] }) }));
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
};
|
|
48
|
+
return (_jsx(_Fragment, { children: loading || !hasData ? (_jsx(Center, { style: { height, backgroundColor: neutral[25], borderRadius: '8px' }, children: _jsx(Text, { variant: "label", color: neutral[200], children: loading ? 'Loading...' : 'No data available' }) })) : (_jsxs(_Fragment, { children: [_jsx(Center, { style: { height, width: '100%' }, children: _jsx(ResponsiveContainer, { width: "100%", height: "100%", children: _jsxs(ComposedChart, { data: chartData, children: [_jsx("defs", { children: series.map((s, index) => (_jsxs("linearGradient", { id: `gradient-${index}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [_jsx("stop", { offset: "0%", stopColor: s.color || primary[200], stopOpacity: 0.3 }), _jsx("stop", { offset: "99%", stopColor: s.color || primary[200], stopOpacity: 0.05 })] }, s.name))) }), _jsx(XAxis, { dataKey: "date", axisLine: { stroke: neutral[50] }, tickLine: { stroke: neutral[50] }, tick: (props) => _jsx(CustomTick, { ...props, formatter: formatXAxisValue }) }), _jsx(YAxis, { width: 40, axisLine: false, tickLine: false, tick: (props) => _jsx(CustomTick, { ...props, formatter: formatYAxisValue }) }), _jsx(CartesianGrid, { strokeDasharray: "0", stroke: neutral[50], horizontal: true, vertical: false }), series.map((s, index) => {
|
|
49
|
+
const seriesType = s.type || 'line';
|
|
50
|
+
if (seriesType === 'area') {
|
|
51
|
+
return (_jsx(Area, { type: "monotone", dataKey: s.name, stroke: s.color || primary[200], strokeWidth: 2, fill: `url(#gradient-${index})`, baseValue: "dataMin", style: { outline: 'none' } }, s.name));
|
|
52
|
+
}
|
|
53
|
+
else if (seriesType === 'bar') {
|
|
54
|
+
return (_jsx(Bar, { dataKey: s.name, fill: s.color || primary[200], radius: [8, 8, 0, 0], style: { outline: 'none' }, onMouseEnter: (data, index, event) => {
|
|
55
|
+
const barElement = event.target;
|
|
56
|
+
if (barElement) {
|
|
57
|
+
barElement.style.opacity = '0.8';
|
|
58
|
+
}
|
|
59
|
+
}, onMouseLeave: (data, index, event) => {
|
|
60
|
+
const barElement = event.target;
|
|
61
|
+
if (barElement) {
|
|
62
|
+
barElement.style.opacity = '1';
|
|
63
|
+
}
|
|
64
|
+
} }, s.name));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return _jsx(Line, { type: "monotone", dataKey: s.name, stroke: s.color || primary[200], strokeWidth: 2, dot: false, style: { outline: 'none' } }, s.name);
|
|
68
|
+
}
|
|
69
|
+
}), _jsx(Tooltip, { content: getTooltipContent, cursor: series.some((s) => s.type === 'bar') ? false : true }), showLegend && (_jsx(Legend, { iconType: "circle", iconSize: 8, formatter: (value) => (_jsx(Text, { variant: "label", sx: { color: neutral[300], display: 'inline', whiteSpace: 'nowrap' }, children: value })) }))] }) }) }), _jsx("style", { children: `.recharts-surface { outline: none; }` })] })) }));
|
|
70
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { numberFormats } from '../../constants/data';
|
|
3
|
+
export interface PieChartDataPoint {
|
|
4
|
+
name: string;
|
|
5
|
+
value: number;
|
|
6
|
+
color?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface JustPieChartProps {
|
|
9
|
+
data: PieChartDataPoint[];
|
|
10
|
+
height?: string | number;
|
|
11
|
+
showLegend?: boolean;
|
|
12
|
+
innerRadius?: number;
|
|
13
|
+
outerRadius?: number;
|
|
14
|
+
paddingAngle?: number;
|
|
15
|
+
format?: keyof typeof numberFormats;
|
|
16
|
+
loading?: boolean;
|
|
17
|
+
centerTitle?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare const JustPieChart: React.FC<JustPieChartProps>;
|
|
20
|
+
//# sourceMappingURL=JustPieChart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JustPieChart.d.ts","sourceRoot":"","sources":["../../../src/components/Data/JustPieChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,iBAAiB,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,OAAO,aAAa,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA+IpD,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from '../Typography/Text';
|
|
3
|
+
import { Center } from '../Layout/Center';
|
|
4
|
+
import { Group } from '../Layout/Group';
|
|
5
|
+
import { neutral } from '../../constants/colors';
|
|
6
|
+
import { PieChart as RechartsPieChart, Pie, Cell, ResponsiveContainer, Tooltip, Legend } from 'recharts';
|
|
7
|
+
import { Title } from '../Typography/Title';
|
|
8
|
+
import { Stack } from '../Layout/Stack';
|
|
9
|
+
import { getChartFormatter } from './shared/chartFormats';
|
|
10
|
+
export const JustPieChart = ({ data, height = '30rem', showLegend = true, innerRadius = 80, outerRadius = 100, paddingAngle = 5, format = 'decimal', loading = false, centerTitle, }) => {
|
|
11
|
+
const hasData = data && data.length > 0;
|
|
12
|
+
const totalValue = hasData ? data.reduce((sum, item) => sum + item.value, 0) : 0;
|
|
13
|
+
const firstDataPoint = hasData ? data[0] : null;
|
|
14
|
+
const firstDataPercentage = firstDataPoint && totalValue > 0 ? Math.round((firstDataPoint.value / totalValue) * 100) : 0;
|
|
15
|
+
const valueFormatter = (value) => getChartFormatter(format)(value);
|
|
16
|
+
// Custom tooltip component
|
|
17
|
+
const CustomTooltip = ({ active, payload, label }) => {
|
|
18
|
+
if (active && payload && payload.length) {
|
|
19
|
+
return (_jsxs("div", { style: {
|
|
20
|
+
backgroundColor: 'white',
|
|
21
|
+
padding: '10px',
|
|
22
|
+
border: `1px solid ${neutral[100]}`,
|
|
23
|
+
borderRadius: '8px',
|
|
24
|
+
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
|
25
|
+
zIndex: 1000,
|
|
26
|
+
position: 'relative',
|
|
27
|
+
}, children: [_jsx(Text, { weight: "semibold", color: neutral[300], children: label }), payload.map((entry) => (_jsxs(Group, { children: [_jsx("div", { style: {
|
|
28
|
+
width: '8px',
|
|
29
|
+
height: '8px',
|
|
30
|
+
borderRadius: '50%',
|
|
31
|
+
backgroundColor: entry.payload.color,
|
|
32
|
+
} }), _jsxs(Group, { gap: "0.25rem", children: [_jsxs(Text, { variant: "label", color: neutral[300], children: [entry.payload.name, ":"] }), _jsx(Text, { variant: "label", children: valueFormatter(entry.payload.value) })] })] }, entry.name)))] }));
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
};
|
|
36
|
+
return (_jsxs(_Fragment, { children: [loading || !hasData ? (_jsx(Center, { style: { height, backgroundColor: neutral[25], borderRadius: '8px' }, children: _jsx(Text, { variant: "label", color: neutral[200], children: loading ? 'Loading...' : 'No data available' }) })) : (_jsxs(Center, { style: { height, width: '100%', position: 'relative' }, children: [_jsx(ResponsiveContainer, { width: "100%", height: "100%", style: { outline: 'none' }, children: _jsxs(RechartsPieChart, { style: { outline: 'none' }, children: [_jsx(Pie, { data: data, innerRadius: innerRadius, outerRadius: outerRadius, paddingAngle: paddingAngle, dataKey: "value", style: { outline: 'none' }, children: data.map((entry, index) => (_jsx(Cell, { fill: entry.color, style: { outline: 'none' } }, `cell-${entry.name}`))) }), _jsx(Tooltip, { content: _jsx(CustomTooltip, {}), wrapperStyle: {
|
|
37
|
+
border: 'none',
|
|
38
|
+
outline: 'none',
|
|
39
|
+
boxShadow: 'none',
|
|
40
|
+
zIndex: 1000,
|
|
41
|
+
}, contentStyle: {
|
|
42
|
+
border: 'none',
|
|
43
|
+
outline: 'none',
|
|
44
|
+
boxShadow: 'none',
|
|
45
|
+
padding: 0,
|
|
46
|
+
margin: 0,
|
|
47
|
+
backgroundColor: 'transparent',
|
|
48
|
+
} }), showLegend && (_jsx(Legend, { iconType: "circle", iconSize: 8, style: {
|
|
49
|
+
marginTop: '1rem',
|
|
50
|
+
}, formatter: (value) => (_jsx(Text, { variant: "label", style: {
|
|
51
|
+
color: neutral[300],
|
|
52
|
+
display: 'inline',
|
|
53
|
+
whiteSpace: 'nowrap',
|
|
54
|
+
}, children: value })) }))] }) }), _jsx(Center, { style: {
|
|
55
|
+
position: 'absolute',
|
|
56
|
+
top: '45%',
|
|
57
|
+
left: '50%',
|
|
58
|
+
transform: 'translate(-50%, -50%)',
|
|
59
|
+
textAlign: 'center',
|
|
60
|
+
zIndex: 1,
|
|
61
|
+
pointerEvents: 'none',
|
|
62
|
+
}, children: _jsxs(Stack, { gap: "0", align: "center", children: [_jsxs(Title, { variant: "cardHeader", color: neutral[300], children: [firstDataPercentage, "%"] }), _jsx(Text, { variant: "label", children: centerTitle })] }) })] })), _jsx("style", { children: `.recharts-surface { outline: none; }` })] }));
|
|
63
|
+
};
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
value: number;
|
|
6
|
-
color?: string;
|
|
7
|
-
}
|
|
8
|
-
export interface PieChartProps extends Omit<CardProps, 'children'> {
|
|
2
|
+
import { numberFormats } from '../../constants/data';
|
|
3
|
+
import { PieDataPoint } from '../../types/types';
|
|
4
|
+
export interface PieCardCenterContentProps {
|
|
9
5
|
title: string;
|
|
10
6
|
subtitle?: string;
|
|
11
|
-
|
|
7
|
+
value?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface PieChartProps {
|
|
10
|
+
data: PieDataPoint[];
|
|
11
|
+
format: keyof typeof numberFormats;
|
|
12
12
|
height?: string | number;
|
|
13
13
|
showLegend?: boolean;
|
|
14
14
|
innerRadius?: number;
|
|
15
15
|
outerRadius?: number;
|
|
16
16
|
paddingAngle?: number;
|
|
17
|
-
colors?: string[];
|
|
18
|
-
formatValue?: (value: number) => string;
|
|
19
|
-
tooltipContent?: (data: any) => React.ReactNode;
|
|
20
17
|
loading?: boolean;
|
|
21
|
-
|
|
18
|
+
centerContent?: PieCardCenterContentProps;
|
|
22
19
|
}
|
|
23
20
|
export declare const PieChart: React.FC<PieChartProps>;
|
|
24
21
|
//# sourceMappingURL=PieChart.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PieChart.d.ts","sourceRoot":"","sources":["../../../src/components/Data/PieChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"PieChart.d.ts","sourceRoot":"","sources":["../../../src/components/Data/PieChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,OAAO,aAAa,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,yBAAyB,CAAC;CAC3C;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAwH5C,CAAC"}
|