@pareto-engineering/design-system 5.0.1 → 5.0.2
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/cjs/a/Charts/AreaChart/AreaChart.js +3 -13
- package/dist/cjs/a/Charts/BarChart/BarChart.js +6 -4
- package/dist/cjs/a/Charts/Common/CustomLegend/CustomLegend.js +26 -7
- package/dist/cjs/a/Charts/Common/CustomLegend/styles.scss +41 -14
- package/dist/cjs/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +18 -7
- package/dist/cjs/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.js +3 -4
- package/dist/cjs/a/Charts/Common/YLabelsDropDown/styles.scss +7 -6
- package/dist/cjs/a/Charts/PieChart/PieChart.js +99 -0
- package/dist/cjs/a/Charts/PieChart/index.js +13 -0
- package/dist/cjs/a/Charts/PieChart/styles.scss +48 -0
- package/dist/cjs/a/Charts/index.js +8 -1
- package/dist/cjs/a/index.js +6 -0
- package/dist/cjs/utils/formatting.js +10 -2
- package/dist/cjs/utils/index.js +6 -0
- package/dist/es/a/Charts/AreaChart/AreaChart.js +3 -13
- package/dist/es/a/Charts/BarChart/BarChart.js +6 -4
- package/dist/es/a/Charts/Common/CustomLegend/CustomLegend.js +38 -21
- package/dist/es/a/Charts/Common/CustomLegend/styles.scss +41 -14
- package/dist/es/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +19 -8
- package/dist/es/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.js +3 -5
- package/dist/es/a/Charts/Common/YLabelsDropDown/styles.scss +7 -6
- package/dist/es/a/Charts/PieChart/PieChart.js +89 -0
- package/dist/es/a/Charts/PieChart/index.js +1 -0
- package/dist/es/a/Charts/PieChart/styles.scss +48 -0
- package/dist/es/a/Charts/index.js +2 -1
- package/dist/es/a/index.js +1 -1
- package/dist/es/utils/formatting.js +7 -0
- package/dist/es/utils/index.js +1 -1
- package/package.json +2 -2
- package/src/stories/a/AreaChart.stories.jsx +1 -1
- package/src/stories/a/BarChart.stories.jsx +1 -1
- package/src/stories/a/PieChart.stories.jsx +53 -0
- package/src/ui/a/Charts/AreaChart/AreaChart.jsx +8 -14
- package/src/ui/a/Charts/BarChart/BarChart.jsx +4 -2
- package/src/ui/a/Charts/Common/CustomLegend/CustomLegend.jsx +54 -29
- package/src/ui/a/Charts/Common/CustomLegend/styles.scss +41 -14
- package/src/ui/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.jsx +25 -13
- package/src/ui/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.jsx +4 -4
- package/src/ui/a/Charts/Common/YLabelsDropDown/styles.scss +7 -6
- package/src/ui/a/Charts/PieChart/PieChart.jsx +125 -0
- package/src/ui/a/Charts/PieChart/index.js +1 -0
- package/src/ui/a/Charts/PieChart/styles.scss +48 -0
- package/src/ui/a/Charts/index.js +1 -0
- package/src/ui/a/index.js +1 -1
- package/src/ui/utils/formatting.js +8 -0
- package/src/ui/utils/index.js +3 -1
- package/tests/__snapshots__/Storyshots.test.js.snap +1165 -429
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import styleNames from '@pareto-engineering/bem/exports';
|
|
4
|
+
import { snakeCaseToTitleCase } from "../../../../utils";
|
|
4
5
|
import "./styles.scss";
|
|
5
6
|
const baseClassName = styleNames.base;
|
|
6
7
|
const componentClassName = 'custom-legend';
|
|
@@ -9,28 +10,28 @@ const CustomLegend = ({
|
|
|
9
10
|
className: userClassName,
|
|
10
11
|
colorsArray,
|
|
11
12
|
yKeysArray,
|
|
13
|
+
orientation,
|
|
14
|
+
getLegendItemTitle,
|
|
15
|
+
getLegendItemSubtitle,
|
|
12
16
|
capitalizedLegend
|
|
13
|
-
}) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
className: "text"
|
|
32
|
-
}, capitalizeWord(key)))));
|
|
33
|
-
};
|
|
17
|
+
}) => /*#__PURE__*/React.createElement("div", {
|
|
18
|
+
id: id,
|
|
19
|
+
className: [baseClassName, componentClassName, userClassName, orientation].filter(e => e).join(' ')
|
|
20
|
+
}, yKeysArray.map((key, index) => /*#__PURE__*/React.createElement("div", {
|
|
21
|
+
key: key,
|
|
22
|
+
className: "item"
|
|
23
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
24
|
+
className: "title"
|
|
25
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
26
|
+
className: "dot",
|
|
27
|
+
style: {
|
|
28
|
+
backgroundColor: colorsArray[index]
|
|
29
|
+
}
|
|
30
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
31
|
+
className: "text"
|
|
32
|
+
}, capitalizedLegend ? snakeCaseToTitleCase(getLegendItemTitle(key)) : getLegendItemTitle(key))), /*#__PURE__*/React.createElement("span", {
|
|
33
|
+
className: "sub-title"
|
|
34
|
+
}, getLegendItemSubtitle(key)))));
|
|
34
35
|
CustomLegend.propTypes = {
|
|
35
36
|
/**
|
|
36
37
|
* The id of the dropdown component.
|
|
@@ -48,12 +49,28 @@ CustomLegend.propTypes = {
|
|
|
48
49
|
* Array of keys for the y-axis data.
|
|
49
50
|
*/
|
|
50
51
|
yKeysArray: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
52
|
+
/**
|
|
53
|
+
* The orientation of the Legend
|
|
54
|
+
*/
|
|
55
|
+
orientation: PropTypes.oneOf(['vertical', 'horizontal']),
|
|
56
|
+
/**
|
|
57
|
+
* The function to get the legendItemKey
|
|
58
|
+
*/
|
|
59
|
+
getLegendItemTitle: PropTypes.func,
|
|
60
|
+
/**
|
|
61
|
+
* The function to get legend children
|
|
62
|
+
*/
|
|
63
|
+
getLegendItemSubtitle: PropTypes.func,
|
|
51
64
|
/**
|
|
52
65
|
* Flag on whether to capitalize legend keys
|
|
53
66
|
*/
|
|
54
67
|
capitalizedLegend: PropTypes.bool
|
|
55
68
|
};
|
|
56
69
|
CustomLegend.defaultProps = {
|
|
70
|
+
orientation: 'horizontal',
|
|
71
|
+
getLegendItemTitle: key => key,
|
|
72
|
+
/* eslint-disable no-unused-vars */
|
|
73
|
+
getLegendItemSubtitle: () => {},
|
|
57
74
|
capitalizedLegend: false
|
|
58
75
|
};
|
|
59
76
|
export default CustomLegend;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
@use "@pareto-engineering/bem";
|
|
2
2
|
|
|
3
3
|
$default-padding: 1rem;
|
|
4
|
+
$default-margin: 1rem;
|
|
4
5
|
$default-text-font-size: calc(var(--s-1) * 1rem);
|
|
5
6
|
$default-border-radius: .25rem;
|
|
6
7
|
$default-legend-gap: .625rem;
|
|
@@ -8,33 +9,59 @@ $default-legend-padding: calc($default-padding * .125) calc($default-padding * .
|
|
|
8
9
|
$default-legend-dot-width: .5rem;
|
|
9
10
|
$default-legend-dot-height: .5rem;
|
|
10
11
|
$default-legend-dot-margin-right: .3125rem;
|
|
12
|
+
$default-box-shadow: 0 4px 16px 0 var(--soft-shadow);
|
|
11
13
|
|
|
12
14
|
.#{bem.$base} {
|
|
13
15
|
&.custom-legend {
|
|
14
|
-
display: flex;
|
|
15
16
|
gap: $default-legend-gap;
|
|
16
17
|
justify-content: flex-end;
|
|
17
18
|
padding-bottom: $default-padding;
|
|
18
19
|
padding-right: calc($default-padding * .25);
|
|
19
20
|
|
|
21
|
+
&.vertical {
|
|
22
|
+
display: block;
|
|
23
|
+
margin-right: calc($default-margin * 2);
|
|
24
|
+
min-width: fit-content;
|
|
25
|
+
|
|
26
|
+
.item {
|
|
27
|
+
box-shadow: $default-box-shadow;
|
|
28
|
+
padding-top: $default-padding;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&.horizontal {
|
|
33
|
+
display: flex;
|
|
34
|
+
}
|
|
35
|
+
|
|
20
36
|
.item {
|
|
21
|
-
align-items: center;
|
|
22
37
|
border-radius: $default-border-radius;
|
|
23
|
-
display: flex;
|
|
24
38
|
padding: $default-legend-padding;
|
|
25
|
-
}
|
|
26
39
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
40
|
+
.title {
|
|
41
|
+
align-items: center;
|
|
42
|
+
display: flex;
|
|
43
|
+
|
|
44
|
+
.dot {
|
|
45
|
+
border-radius: 50%;
|
|
46
|
+
display: inline-block;
|
|
47
|
+
height: $default-legend-dot-height;
|
|
48
|
+
margin-right: $default-legend-dot-margin-right;
|
|
49
|
+
width: $default-legend-dot-width;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.text {
|
|
53
|
+
color: var(--paragraph);
|
|
54
|
+
font-size: calc($default-text-font-size * .75);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
34
57
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
58
|
+
.sub-title {
|
|
59
|
+
color: var(--heading);
|
|
60
|
+
display: flex;
|
|
61
|
+
font-size: calc($default-text-font-size * 1.2);
|
|
62
|
+
font-weight: 500;
|
|
63
|
+
justify-content: flex-end;
|
|
64
|
+
}
|
|
38
65
|
}
|
|
39
66
|
}
|
|
40
67
|
}
|
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import styleNames from '@pareto-engineering/bem/exports';
|
|
4
|
-
import { formatTime, formatDate, DATE_FORMATS } from "../../../../utils";
|
|
4
|
+
import { formatTime, formatDate, DATE_FORMATS, snakeCaseToTitleCase } from "../../../../utils";
|
|
5
5
|
import "./styles.scss";
|
|
6
6
|
const baseClassName = styleNames.base;
|
|
7
7
|
const componentClassName = 'custom-tooltip-content';
|
|
8
8
|
const CustomTooltipContent = ({
|
|
9
9
|
id,
|
|
10
10
|
className: userClassName,
|
|
11
|
-
xLabel,
|
|
12
11
|
dateFormat,
|
|
13
12
|
isTimeFormat,
|
|
13
|
+
isDateValue,
|
|
14
14
|
active,
|
|
15
15
|
payload,
|
|
16
16
|
label
|
|
17
17
|
}) => {
|
|
18
|
+
const formatLabelValue = value => {
|
|
19
|
+
if (isTimeFormat) {
|
|
20
|
+
return formatTime(value);
|
|
21
|
+
}
|
|
22
|
+
if (typeof value === 'number') {
|
|
23
|
+
if (Number.isInteger(value)) return value;
|
|
24
|
+
return value.toFixed(2);
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
};
|
|
18
28
|
if (active && payload && payload.length) {
|
|
19
29
|
const newPayload = payload.filter(item => item.name !== 'bounds');
|
|
20
30
|
return /*#__PURE__*/React.createElement("div", {
|
|
@@ -22,14 +32,14 @@ const CustomTooltipContent = ({
|
|
|
22
32
|
className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' ')
|
|
23
33
|
}, /*#__PURE__*/React.createElement("p", {
|
|
24
34
|
className: "label"
|
|
25
|
-
},
|
|
35
|
+
}, isDateValue ? formatDate(label, dateFormat) : label), newPayload.map(entry => /*#__PURE__*/React.createElement("p", {
|
|
26
36
|
className: "label",
|
|
27
37
|
key: `${entry.name}`,
|
|
28
38
|
style: {
|
|
29
39
|
color: entry.color,
|
|
30
40
|
textTransform: 'capitalize'
|
|
31
41
|
}
|
|
32
|
-
}, `${entry.name}: ${
|
|
42
|
+
}, `${snakeCaseToTitleCase(entry.name)}: ${formatLabelValue(entry.value)}`)));
|
|
33
43
|
}
|
|
34
44
|
return null;
|
|
35
45
|
};
|
|
@@ -42,10 +52,6 @@ CustomTooltipContent.propTypes = {
|
|
|
42
52
|
* Additional class names for the dropdown component.
|
|
43
53
|
*/
|
|
44
54
|
className: PropTypes.string,
|
|
45
|
-
/**
|
|
46
|
-
* The label for the x-axis.
|
|
47
|
-
*/
|
|
48
|
-
xLabel: PropTypes.string,
|
|
49
55
|
/**
|
|
50
56
|
* Flag on whether it is a timeformat or not
|
|
51
57
|
*/
|
|
@@ -54,6 +60,10 @@ CustomTooltipContent.propTypes = {
|
|
|
54
60
|
* The type of format for the datetime value
|
|
55
61
|
*/
|
|
56
62
|
dateFormat: PropTypes.oneOf(Object.values(DATE_FORMATS)),
|
|
63
|
+
/**
|
|
64
|
+
* Flag on whether the label is a date value or not
|
|
65
|
+
*/
|
|
66
|
+
isDateValue: PropTypes.bool,
|
|
57
67
|
/**
|
|
58
68
|
* If set true, the tooltip is displayed.
|
|
59
69
|
* If set false, the tooltip is hidden, usually calculated internally.
|
|
@@ -71,6 +81,7 @@ CustomTooltipContent.propTypes = {
|
|
|
71
81
|
};
|
|
72
82
|
CustomTooltipContent.defaultProps = {
|
|
73
83
|
isTimeFormat: false,
|
|
84
|
+
isDateValue: true,
|
|
74
85
|
dateFormat: DATE_FORMATS.HUMAN_READABLE
|
|
75
86
|
};
|
|
76
87
|
export default CustomTooltipContent;
|
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import styleNames from '@pareto-engineering/bem/exports';
|
|
5
|
+
import { snakeCaseToTitleCase } from "../../../../utils";
|
|
5
6
|
import "./styles.scss";
|
|
6
|
-
|
|
7
|
-
// Local Definitions
|
|
8
|
-
|
|
9
7
|
const baseClassName = styleNames.base;
|
|
10
8
|
const componentClassName = 'y-labels-dropdown';
|
|
11
9
|
const YLabelsDropDown = ({
|
|
@@ -46,7 +44,7 @@ const YLabelsDropDown = ({
|
|
|
46
44
|
style: {
|
|
47
45
|
backgroundColor: item.color
|
|
48
46
|
}
|
|
49
|
-
}), item.label, selectedYLabels.some(label => label.label === item.label) && /*#__PURE__*/React.createElement("span", {
|
|
47
|
+
}), snakeCaseToTitleCase(item.label), selectedYLabels.some(label => label.label === item.label) && /*#__PURE__*/React.createElement("span", {
|
|
50
48
|
className: "icon checkmark"
|
|
51
49
|
}, "I")))));
|
|
52
50
|
};
|
|
@@ -83,6 +81,6 @@ YLabelsDropDown.propTypes = {
|
|
|
83
81
|
}))
|
|
84
82
|
};
|
|
85
83
|
YLabelsDropDown.defaultProps = {
|
|
86
|
-
placeholder: '
|
|
84
|
+
placeholder: 'Select Item'
|
|
87
85
|
};
|
|
88
86
|
export default YLabelsDropDown;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
@use "@pareto-engineering/bem";
|
|
2
2
|
|
|
3
3
|
$default-margin: 1rem;
|
|
4
|
-
$default-border
|
|
4
|
+
$default-border: var(--theme-default-input-border);
|
|
5
|
+
$default-border-radius: var(--theme-default-input-border-radius);
|
|
5
6
|
$default-padding: 1rem;
|
|
6
7
|
$default-width: 15rem;
|
|
7
8
|
$default-box-shadow: 0 .25rem .75rem var(--ui-lines);
|
|
@@ -16,9 +17,9 @@ $default-checkmark-font-size: calc(var(--s-1) * .75rem);
|
|
|
16
17
|
|
|
17
18
|
.dropdown-button {
|
|
18
19
|
align-items: center;
|
|
19
|
-
background-color: var(--
|
|
20
|
-
border:
|
|
21
|
-
border-radius: $default-border-radius;
|
|
20
|
+
background-color: var(--background-far);
|
|
21
|
+
border: $default-border;
|
|
22
|
+
border-radius: calc($default-border-radius / 2);
|
|
22
23
|
color: var(--hard-paragraph);
|
|
23
24
|
cursor: pointer;
|
|
24
25
|
display: flex;
|
|
@@ -53,8 +54,8 @@ $default-checkmark-font-size: calc(var(--s-1) * .75rem);
|
|
|
53
54
|
|
|
54
55
|
.dropdown-item {
|
|
55
56
|
align-items: center;
|
|
56
|
-
border-radius: $default-border-radius;
|
|
57
|
-
color: var(--
|
|
57
|
+
border-radius: calc($default-border-radius / 2);
|
|
58
|
+
color: var(--paragraph);
|
|
58
59
|
cursor: pointer;
|
|
59
60
|
display: flex;
|
|
60
61
|
margin: calc($default-margin * .125);
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { PieChart as RechartsPieChart, Pie, Cell, ResponsiveContainer, Tooltip } from 'recharts';
|
|
4
|
+
import styleNames from '@pareto-engineering/bem/exports';
|
|
5
|
+
import { CustomLegend, CustomTooltipContent } from "../Common";
|
|
6
|
+
import "./styles.scss";
|
|
7
|
+
const baseClassName = styleNames.base;
|
|
8
|
+
const componentClassName = 'pie-chart';
|
|
9
|
+
const PieChart = ({
|
|
10
|
+
id,
|
|
11
|
+
className: userClassName,
|
|
12
|
+
data,
|
|
13
|
+
title,
|
|
14
|
+
valueKey,
|
|
15
|
+
labelKey,
|
|
16
|
+
colors,
|
|
17
|
+
height,
|
|
18
|
+
width,
|
|
19
|
+
innerRadius,
|
|
20
|
+
outerRadius
|
|
21
|
+
}) => {
|
|
22
|
+
const total = data.reduce((sum, item) => sum + item[valueKey], 0);
|
|
23
|
+
const formattedData = data.map(item => ({
|
|
24
|
+
...item,
|
|
25
|
+
label: item[labelKey],
|
|
26
|
+
color: colors[data.indexOf(item)],
|
|
27
|
+
percentage: (item[valueKey] / total * 100).toFixed(0)
|
|
28
|
+
}));
|
|
29
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
30
|
+
id: id,
|
|
31
|
+
className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' ')
|
|
32
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
33
|
+
className: "chart-header"
|
|
34
|
+
}, /*#__PURE__*/React.createElement("h3", null, title)), /*#__PURE__*/React.createElement("div", {
|
|
35
|
+
className: "chart-content"
|
|
36
|
+
}, /*#__PURE__*/React.createElement(ResponsiveContainer, {
|
|
37
|
+
width: width,
|
|
38
|
+
height: height
|
|
39
|
+
}, /*#__PURE__*/React.createElement(RechartsPieChart, null, /*#__PURE__*/React.createElement(Pie, {
|
|
40
|
+
data: formattedData,
|
|
41
|
+
dataKey: valueKey,
|
|
42
|
+
nameKey: labelKey,
|
|
43
|
+
cx: "50%",
|
|
44
|
+
cy: "50%",
|
|
45
|
+
innerRadius: innerRadius,
|
|
46
|
+
outerRadius: outerRadius,
|
|
47
|
+
label: false,
|
|
48
|
+
paddingAngle: 0
|
|
49
|
+
}, formattedData.map((entry, index) => /*#__PURE__*/React.createElement(Cell, {
|
|
50
|
+
key: entry[labelKey],
|
|
51
|
+
fill: colors[index],
|
|
52
|
+
strokeWidth: 0
|
|
53
|
+
}))), /*#__PURE__*/React.createElement(Tooltip, {
|
|
54
|
+
content: /*#__PURE__*/React.createElement(CustomTooltipContent, {
|
|
55
|
+
isDateValue: false
|
|
56
|
+
})
|
|
57
|
+
}))), /*#__PURE__*/React.createElement(CustomLegend, {
|
|
58
|
+
colorsArray: colors,
|
|
59
|
+
yKeysArray: formattedData,
|
|
60
|
+
capitalizedLegend: true,
|
|
61
|
+
orientation: "vertical",
|
|
62
|
+
getLegendItemTitle: entry => entry[labelKey],
|
|
63
|
+
getLegendItemSubtitle: entry => entry[valueKey]
|
|
64
|
+
})));
|
|
65
|
+
};
|
|
66
|
+
PieChart.propTypes = {
|
|
67
|
+
id: PropTypes.string,
|
|
68
|
+
className: PropTypes.string,
|
|
69
|
+
data: PropTypes.arrayOf(PropTypes.shape({
|
|
70
|
+
[PropTypes.string]: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
|
|
71
|
+
})).isRequired,
|
|
72
|
+
title: PropTypes.string.isRequired,
|
|
73
|
+
valueKey: PropTypes.string.isRequired,
|
|
74
|
+
labelKey: PropTypes.string.isRequired,
|
|
75
|
+
colors: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
76
|
+
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
77
|
+
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
78
|
+
innerRadius: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
79
|
+
outerRadius: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
|
|
80
|
+
};
|
|
81
|
+
PieChart.defaultProps = {
|
|
82
|
+
id: undefined,
|
|
83
|
+
className: undefined,
|
|
84
|
+
width: '100%',
|
|
85
|
+
height: 300,
|
|
86
|
+
innerRadius: '0%',
|
|
87
|
+
outerRadius: '100%'
|
|
88
|
+
};
|
|
89
|
+
export default PieChart;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as PieChart } from "./PieChart";
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
@use "@pareto-engineering/bem";
|
|
2
|
+
|
|
3
|
+
$default-margin: 1rem;
|
|
4
|
+
$default-padding: 1rem;
|
|
5
|
+
$default-box-shadow: 0 .25rem .75rem var(--ui-lines);
|
|
6
|
+
$default-text-font-size: calc(var(--s-1) * 1rem);
|
|
7
|
+
|
|
8
|
+
.#{bem.$base} {
|
|
9
|
+
&.pie-chart {
|
|
10
|
+
background-color: var(--background-far);
|
|
11
|
+
border-radius: var(--theme-default-border-radius);
|
|
12
|
+
box-shadow: $default-box-shadow;
|
|
13
|
+
margin: $default-margin 0;
|
|
14
|
+
padding: $default-padding;
|
|
15
|
+
|
|
16
|
+
.chart-header {
|
|
17
|
+
align-items: center;
|
|
18
|
+
display: flex;
|
|
19
|
+
justify-content: space-between;
|
|
20
|
+
margin-bottom: $default-margin;
|
|
21
|
+
|
|
22
|
+
h3 {
|
|
23
|
+
color: var(--subtitle);
|
|
24
|
+
margin: calc($default-margin / 5);
|
|
25
|
+
text-align: left;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.chart-content {
|
|
30
|
+
align-items: flex-start;
|
|
31
|
+
display: flex;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.recharts-wrapper {
|
|
35
|
+
.recharts-surface {
|
|
36
|
+
.recharts-text {
|
|
37
|
+
fill: var(--soft-paragraph);
|
|
38
|
+
font-size: calc($default-text-font-size * .75);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.recharts-text.recharts-label {
|
|
42
|
+
fill: var(--paragraph);
|
|
43
|
+
font-size: $default-text-font-size;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
package/dist/es/a/index.js
CHANGED
|
@@ -28,4 +28,4 @@ export { ToggleSwitch } from "./ToggleSwitch";
|
|
|
28
28
|
export { XMLEditor } from "./XMLEditor";
|
|
29
29
|
export { DatePicker } from "./DatePicker";
|
|
30
30
|
export { Tooltip } from "./Tooltip";
|
|
31
|
-
export { AreaChart, BarChart } from "./Charts";
|
|
31
|
+
export { AreaChart, BarChart, PieChart } from "./Charts";
|
|
@@ -37,6 +37,9 @@ export const formatTime = seconds => {
|
|
|
37
37
|
if (hours > 0) parts.push(`${hours}h`);
|
|
38
38
|
if (minutes > 0 || hours > 0 && remainingSeconds > 0) parts.push(`${minutes}m`);
|
|
39
39
|
if (remainingSeconds > 0) parts.push(`${remainingSeconds}s`);
|
|
40
|
+
|
|
41
|
+
// Cater for decimal seconds
|
|
42
|
+
if (parts.length === 0) return '0s';
|
|
40
43
|
return parts.join(' ');
|
|
41
44
|
};
|
|
42
45
|
const parseDate = input => {
|
|
@@ -99,4 +102,8 @@ export const formatDate = (input, format = DATE_FORMATS.HUMAN_READABLE) => {
|
|
|
99
102
|
} catch (error) {
|
|
100
103
|
return 'Invalid Date';
|
|
101
104
|
}
|
|
105
|
+
};
|
|
106
|
+
export const snakeCaseToTitleCase = word => {
|
|
107
|
+
const result = word.replace(/([A-Z])/g, ' $1');
|
|
108
|
+
return result.charAt(0).toUpperCase() + result.slice(1);
|
|
102
109
|
};
|
package/dist/es/utils/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { useWindowSize, useDynamicPosition, useOutsideClick } from "./hooks";
|
|
2
|
-
export { formatTime, formatDate, DATE_FORMATS } from "./formatting";
|
|
2
|
+
export { formatTime, formatDate, DATE_FORMATS, snakeCaseToTitleCase } from "./formatting";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pareto-engineering/design-system",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/es/index.js",
|
|
@@ -87,5 +87,5 @@
|
|
|
87
87
|
"remark-math": "^6.0.0"
|
|
88
88
|
},
|
|
89
89
|
"browserslist": "> 2%",
|
|
90
|
-
"gitHead": "
|
|
90
|
+
"gitHead": "af1d9f8a840222f80506834a9ed5402c4465b69a"
|
|
91
91
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { PieChart } from 'ui'
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title :'a/Charts/PieChart',
|
|
6
|
+
component:PieChart,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const data = [
|
|
10
|
+
{ status: 'pendingReview', value: 230 },
|
|
11
|
+
{ status: 'accepted', value: 350 },
|
|
12
|
+
{ status: 'rejected', value: 80 },
|
|
13
|
+
{ status: 'toRevise', value: 10 },
|
|
14
|
+
{ status: 'revised', value: 60 },
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
const Template = (args) => (
|
|
18
|
+
<div style={{ height: '100%', width: '100%' }}>
|
|
19
|
+
<PieChart {...args} />
|
|
20
|
+
</div>
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
export const Default = Template.bind({})
|
|
24
|
+
Default.args = {
|
|
25
|
+
data,
|
|
26
|
+
valueKey:'value',
|
|
27
|
+
labelKey:'status',
|
|
28
|
+
colors :['#8CB0F8', '#7F7CF6', '#FFD66E', '#E8E9ED', '#F6BC7E'],
|
|
29
|
+
height :400,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const TemplateSideBySide = (args) => (
|
|
33
|
+
<div style={{ display: 'flex', gap: '20px' }}>
|
|
34
|
+
<div style={{ flex: 1 }}>
|
|
35
|
+
{/* eslint-disable-next-line react/destructuring-assignment */}
|
|
36
|
+
<PieChart {...args[0]} />
|
|
37
|
+
</div>
|
|
38
|
+
<div style={{ flex: 1 }}>
|
|
39
|
+
{/* eslint-disable-next-line react/destructuring-assignment */}
|
|
40
|
+
<PieChart {...args[1]} />
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
export const SideBySide = TemplateSideBySide.bind({})
|
|
46
|
+
SideBySide.args = [
|
|
47
|
+
{
|
|
48
|
+
...Default.args,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
...Default.args,
|
|
52
|
+
},
|
|
53
|
+
]
|
|
@@ -50,18 +50,6 @@ const AreaChart = ({
|
|
|
50
50
|
|
|
51
51
|
const [selectedYLabels, setSelectedYLabels] = useState(allYLabels)
|
|
52
52
|
|
|
53
|
-
const processedData = data.map((item) => {
|
|
54
|
-
const yValues = yKeys.map((key) => item[key])
|
|
55
|
-
const lowerBound = Math.min(...yValues)
|
|
56
|
-
const upperBound = Math.max(...yValues)
|
|
57
|
-
const margin = (upperBound - lowerBound) * 0.1
|
|
58
|
-
return {
|
|
59
|
-
...item,
|
|
60
|
-
bounds:[lowerBound - margin, upperBound + margin],
|
|
61
|
-
isTimeFormat,
|
|
62
|
-
}
|
|
63
|
-
})
|
|
64
|
-
|
|
65
53
|
const yAxisBounds = () => {
|
|
66
54
|
const yValues = data.map((item) => yKeys.map((key) => item[key]))
|
|
67
55
|
const min = Math.min(...yValues.flat())
|
|
@@ -95,7 +83,7 @@ const AreaChart = ({
|
|
|
95
83
|
capitalizedLegend={capitalizedLegend}
|
|
96
84
|
/>
|
|
97
85
|
<ResponsiveContainer width={width} height={height}>
|
|
98
|
-
<RechartsAreaChart data={
|
|
86
|
+
<RechartsAreaChart data={data}>
|
|
99
87
|
<CartesianGrid strokeDasharray="3 3" />
|
|
100
88
|
<XAxis
|
|
101
89
|
dataKey={xKey}
|
|
@@ -126,7 +114,13 @@ const AreaChart = ({
|
|
|
126
114
|
return value.toFixed(2)
|
|
127
115
|
}}
|
|
128
116
|
/>
|
|
129
|
-
<Tooltip content={
|
|
117
|
+
<Tooltip content={(
|
|
118
|
+
<CustomTooltipContent
|
|
119
|
+
dateFormat={dateFormat}
|
|
120
|
+
isTimeFormat={isTimeFormat}
|
|
121
|
+
/>
|
|
122
|
+
)}
|
|
123
|
+
/>
|
|
130
124
|
{filled && (
|
|
131
125
|
<Area
|
|
132
126
|
id="bounds"
|
|
@@ -38,7 +38,8 @@ const BarChart = ({
|
|
|
38
38
|
colors,
|
|
39
39
|
height,
|
|
40
40
|
width,
|
|
41
|
-
|
|
41
|
+
isTimeFormat,
|
|
42
|
+
capitalizedLegend,
|
|
42
43
|
}) => {
|
|
43
44
|
const allYLabels = yKeys.map((key) => ({
|
|
44
45
|
label:key,
|
|
@@ -69,6 +70,7 @@ const BarChart = ({
|
|
|
69
70
|
<CustomLegend
|
|
70
71
|
colorsArray={selectedYLabels.map((item) => item.color)}
|
|
71
72
|
yKeysArray={selectedYLabels.map((item) => item.label)}
|
|
73
|
+
capitalizedLegend={capitalizedLegend}
|
|
72
74
|
/>
|
|
73
75
|
<ResponsiveContainer width={width} height={height}>
|
|
74
76
|
<RechartsBarChart data={data}>
|
|
@@ -87,7 +89,7 @@ const BarChart = ({
|
|
|
87
89
|
axisLine={false}
|
|
88
90
|
tickLine={false}
|
|
89
91
|
/>
|
|
90
|
-
<Tooltip content={<CustomTooltipContent
|
|
92
|
+
<Tooltip content={<CustomTooltipContent isTimeFormat={isTimeFormat} />} />
|
|
91
93
|
{selectedYLabels.map((key) => (
|
|
92
94
|
<Bar
|
|
93
95
|
stackId="a"
|