@pareto-engineering/design-system 5.0.0 → 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/{AreaChart → Charts/AreaChart}/AreaChart.js +89 -73
- package/dist/cjs/a/Charts/AreaChart/styles.scss +48 -0
- package/dist/cjs/a/Charts/BarChart/BarChart.js +137 -0
- package/dist/cjs/a/Charts/BarChart/index.js +13 -0
- package/dist/cjs/a/Charts/BarChart/styles.scss +48 -0
- package/dist/cjs/a/Charts/Common/CustomLegend/CustomLegend.js +88 -0
- package/dist/cjs/a/Charts/Common/CustomLegend/index.js +13 -0
- package/dist/cjs/a/Charts/Common/CustomLegend/styles.scss +67 -0
- package/dist/cjs/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +97 -0
- package/dist/cjs/a/Charts/Common/CustomTooltipContent/index.js +13 -0
- package/dist/cjs/a/Charts/Common/CustomTooltipContent/styles.scss +22 -0
- package/dist/cjs/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.js +97 -0
- package/dist/cjs/a/Charts/Common/YLabelsDropDown/index.js +13 -0
- package/dist/cjs/a/Charts/Common/YLabelsDropDown/styles.scss +89 -0
- package/dist/cjs/a/Charts/Common/index.js +26 -0
- 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 +26 -0
- package/dist/cjs/a/Tooltip/styles.scss +1 -1
- package/dist/cjs/a/index.js +14 -2
- package/dist/cjs/f/FormInput/FormInput.js +6 -0
- package/dist/cjs/f/fields/FileUpload/FileUpload.js +18 -4
- package/dist/cjs/f/fields/LatexPreviewInput/LatexPreviewInput.js +78 -0
- package/dist/cjs/f/fields/LatexPreviewInput/convertLatexToHtml.js +46 -0
- package/dist/cjs/f/fields/LatexPreviewInput/index.js +20 -0
- package/dist/cjs/f/fields/LatexPreviewInput/styles.scss +24 -0
- package/dist/cjs/f/fields/index.js +13 -0
- package/dist/cjs/g/FormBuilder/FormBuilder.js +3 -6
- package/dist/cjs/g/FormBuilder/common/Builder/Builder.js +1 -3
- package/dist/cjs/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.js +5 -7
- package/dist/cjs/g/FormBuilder/common/Builder/common/Section/Section.js +2 -4
- package/dist/cjs/g/FormBuilder/common/Renderer/Renderer.js +2 -4
- package/dist/cjs/g/FormBuilder/common/Renderer/common/Section/Section.js +2 -10
- package/dist/cjs/utils/formatting.js +119 -0
- package/dist/cjs/utils/index.js +26 -1
- package/dist/es/a/{AreaChart → Charts/AreaChart}/AreaChart.js +88 -69
- package/dist/es/a/Charts/AreaChart/styles.scss +48 -0
- package/dist/es/a/Charts/BarChart/BarChart.js +128 -0
- package/dist/es/a/Charts/BarChart/index.js +1 -0
- package/dist/es/a/Charts/BarChart/styles.scss +48 -0
- package/dist/es/a/Charts/Common/CustomLegend/CustomLegend.js +76 -0
- package/dist/es/a/Charts/Common/CustomLegend/index.js +1 -0
- package/dist/es/a/Charts/Common/CustomLegend/styles.scss +67 -0
- package/dist/es/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +87 -0
- package/dist/es/a/Charts/Common/CustomTooltipContent/index.js +1 -0
- package/dist/es/a/Charts/Common/CustomTooltipContent/styles.scss +22 -0
- package/dist/es/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.js +86 -0
- package/dist/es/a/Charts/Common/YLabelsDropDown/index.js +1 -0
- package/dist/es/a/Charts/Common/YLabelsDropDown/styles.scss +89 -0
- package/dist/es/a/Charts/Common/index.js +3 -0
- 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 +3 -0
- package/dist/es/a/Tooltip/styles.scss +1 -1
- package/dist/es/a/index.js +1 -1
- package/dist/es/f/FormInput/FormInput.js +7 -1
- package/dist/es/f/fields/FileUpload/FileUpload.js +18 -4
- package/dist/es/f/fields/LatexPreviewInput/LatexPreviewInput.js +70 -0
- package/dist/es/f/fields/LatexPreviewInput/convertLatexToHtml.js +31 -0
- package/dist/es/f/fields/LatexPreviewInput/index.js +3 -0
- package/dist/es/f/fields/LatexPreviewInput/styles.scss +24 -0
- package/dist/es/f/fields/index.js +1 -0
- package/dist/es/g/FormBuilder/FormBuilder.js +3 -6
- package/dist/es/g/FormBuilder/common/Builder/Builder.js +1 -3
- package/dist/es/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.js +5 -7
- package/dist/es/g/FormBuilder/common/Builder/common/Section/Section.js +2 -4
- package/dist/es/g/FormBuilder/common/Renderer/Renderer.js +2 -4
- package/dist/es/g/FormBuilder/common/Renderer/common/Section/Section.js +32 -42
- package/dist/es/utils/formatting.js +109 -0
- package/dist/es/utils/index.js +2 -1
- package/jest.config.js +3 -0
- package/package.json +7 -3
- package/src/stories/a/AreaChart.stories.jsx +1 -1
- package/src/stories/a/BarChart.stories.jsx +89 -0
- package/src/stories/a/PieChart.stories.jsx +53 -0
- package/src/ui/a/{AreaChart → Charts/AreaChart}/AreaChart.jsx +114 -65
- package/src/ui/a/Charts/AreaChart/styles.scss +48 -0
- package/src/ui/a/Charts/BarChart/BarChart.jsx +167 -0
- package/src/ui/a/Charts/BarChart/index.js +1 -0
- package/src/ui/a/Charts/BarChart/styles.scss +48 -0
- package/src/ui/a/Charts/Common/CustomLegend/CustomLegend.jsx +109 -0
- package/src/ui/a/Charts/Common/CustomLegend/index.js +1 -0
- package/src/ui/a/Charts/Common/CustomLegend/styles.scss +67 -0
- package/src/ui/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.jsx +117 -0
- package/src/ui/a/Charts/Common/CustomTooltipContent/index.js +1 -0
- package/src/ui/a/Charts/Common/CustomTooltipContent/styles.scss +22 -0
- package/src/ui/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.jsx +121 -0
- package/src/ui/a/Charts/Common/YLabelsDropDown/index.js +1 -0
- package/src/ui/a/Charts/Common/YLabelsDropDown/styles.scss +89 -0
- package/src/ui/a/Charts/Common/index.js +3 -0
- 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 +3 -0
- package/src/ui/a/Tooltip/styles.scss +1 -1
- package/src/ui/a/index.js +1 -1
- package/src/ui/f/FormInput/FormInput.jsx +11 -0
- package/src/ui/f/fields/FileUpload/FileUpload.jsx +24 -4
- package/src/ui/f/fields/LatexPreviewInput/LatexPreviewInput.jsx +91 -0
- package/src/ui/f/fields/LatexPreviewInput/convertLatexToHtml.jsx +38 -0
- package/src/ui/f/fields/LatexPreviewInput/index.js +3 -0
- package/src/ui/f/fields/LatexPreviewInput/styles.scss +24 -0
- package/src/ui/f/fields/index.js +4 -0
- package/src/ui/g/FormBuilder/FormBuilder.jsx +0 -3
- package/src/ui/g/FormBuilder/common/Builder/Builder.jsx +0 -2
- package/src/ui/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.jsx +4 -7
- package/src/ui/g/FormBuilder/common/Builder/common/Section/Section.jsx +0 -2
- package/src/ui/g/FormBuilder/common/Renderer/Renderer.jsx +0 -2
- package/src/ui/g/FormBuilder/common/Renderer/common/Section/Section.jsx +49 -64
- package/src/ui/utils/formatting.js +133 -0
- package/src/ui/utils/index.js +3 -0
- package/tests/__snapshots__/Storyshots.test.js.snap +2227 -296
- package/tests/emptyMock.js +3 -0
- package/tests/mockTextEncoder.js +7 -0
- package/tests/test-setup.js +7 -0
- package/dist/cjs/a/AreaChart/styles.scss +0 -89
- package/dist/es/a/AreaChart/styles.scss +0 -89
- package/src/ui/a/AreaChart/styles.scss +0 -89
- /package/dist/cjs/a/{AreaChart → Charts/AreaChart}/index.js +0 -0
- /package/dist/es/a/{AreaChart → Charts/AreaChart}/index.js +0 -0
- /package/src/ui/a/{AreaChart → Charts/AreaChart}/index.js +0 -0
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
// front/packages/design-system/src/ui/a/AreaChart/AreaChart.jsx
|
|
2
|
-
|
|
3
1
|
import * as React from 'react';
|
|
2
|
+
import { useState } from 'react';
|
|
4
3
|
import PropTypes from 'prop-types';
|
|
5
4
|
import { AreaChart as RechartsAreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
|
6
5
|
import styleNames from '@pareto-engineering/bem/exports';
|
|
6
|
+
import { formatTime, formatDate, DATE_FORMATS } from "../../../utils";
|
|
7
|
+
import { CustomLegend, CustomTooltipContent, YLabelsDropDown } from "../Common";
|
|
7
8
|
import "./styles.scss";
|
|
8
|
-
|
|
9
|
-
// Local Definitions
|
|
10
|
-
|
|
11
9
|
const baseClassName = styleNames.base;
|
|
12
10
|
const componentClassName = 'area-chart';
|
|
13
11
|
const AreaChart = ({
|
|
@@ -22,19 +20,16 @@ const AreaChart = ({
|
|
|
22
20
|
colors,
|
|
23
21
|
filled,
|
|
24
22
|
height,
|
|
25
|
-
width
|
|
26
|
-
|
|
23
|
+
width,
|
|
24
|
+
isTimeFormat,
|
|
25
|
+
dateFormat,
|
|
26
|
+
capitalizedLegend
|
|
27
27
|
}) => {
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
...item,
|
|
35
|
-
bounds: [lowerBound - margin, upperBound + margin]
|
|
36
|
-
};
|
|
37
|
-
});
|
|
28
|
+
const allYLabels = yKeys.map(key => ({
|
|
29
|
+
label: key,
|
|
30
|
+
color: colors[yKeys.indexOf(key)]
|
|
31
|
+
}));
|
|
32
|
+
const [selectedYLabels, setSelectedYLabels] = useState(allYLabels);
|
|
38
33
|
const yAxisBounds = () => {
|
|
39
34
|
const yValues = data.map(item => yKeys.map(key => item[key]));
|
|
40
35
|
const min = Math.min(...yValues.flat());
|
|
@@ -42,54 +37,24 @@ const AreaChart = ({
|
|
|
42
37
|
const margin = (max - min) * 0.1;
|
|
43
38
|
return [min - margin, max + margin];
|
|
44
39
|
};
|
|
45
|
-
const CustomTooltipContent = ({
|
|
46
|
-
active,
|
|
47
|
-
payload,
|
|
48
|
-
label
|
|
49
|
-
}) => {
|
|
50
|
-
if (active && payload && payload.length) {
|
|
51
|
-
const newPayload = payload.filter(item => item.name !== 'bounds');
|
|
52
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
53
|
-
className: "custom-tooltip"
|
|
54
|
-
}, /*#__PURE__*/React.createElement("p", {
|
|
55
|
-
className: "label"
|
|
56
|
-
}, `${xLabel}: ${label}`), newPayload.map(entry => /*#__PURE__*/React.createElement("p", {
|
|
57
|
-
className: "label",
|
|
58
|
-
key: `${entry.name}`,
|
|
59
|
-
style: {
|
|
60
|
-
color: entry.color
|
|
61
|
-
}
|
|
62
|
-
}, `${entry.name}: ${entry.value}`)));
|
|
63
|
-
}
|
|
64
|
-
return null;
|
|
65
|
-
};
|
|
66
|
-
const CustomLegend = ({
|
|
67
|
-
colorsArray,
|
|
68
|
-
yKeysArray
|
|
69
|
-
}) => /*#__PURE__*/React.createElement("div", {
|
|
70
|
-
className: "custom-legend"
|
|
71
|
-
}, yKeysArray.map((key, index) => /*#__PURE__*/React.createElement("div", {
|
|
72
|
-
key: key,
|
|
73
|
-
className: "item"
|
|
74
|
-
}, /*#__PURE__*/React.createElement("span", {
|
|
75
|
-
className: "line",
|
|
76
|
-
style: {
|
|
77
|
-
backgroundColor: colorsArray[index]
|
|
78
|
-
}
|
|
79
|
-
}), /*#__PURE__*/React.createElement("span", {
|
|
80
|
-
className: "text"
|
|
81
|
-
}, key))));
|
|
82
40
|
return /*#__PURE__*/React.createElement("div", {
|
|
83
41
|
id: id,
|
|
84
42
|
className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' ')
|
|
85
|
-
}, /*#__PURE__*/React.createElement("
|
|
43
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
44
|
+
className: "chart-header"
|
|
45
|
+
}, /*#__PURE__*/React.createElement("h3", null, title), /*#__PURE__*/React.createElement(YLabelsDropDown, {
|
|
46
|
+
allYLabels: allYLabels,
|
|
47
|
+
selectedYLabels: selectedYLabels,
|
|
48
|
+
setSelectedYLabels: setSelectedYLabels
|
|
49
|
+
})), /*#__PURE__*/React.createElement(CustomLegend, {
|
|
86
50
|
colorsArray: colors,
|
|
87
|
-
yKeysArray: yKeys
|
|
51
|
+
yKeysArray: yKeys,
|
|
52
|
+
capitalizedLegend: capitalizedLegend
|
|
88
53
|
}), /*#__PURE__*/React.createElement(ResponsiveContainer, {
|
|
89
54
|
width: width,
|
|
90
55
|
height: height
|
|
91
56
|
}, /*#__PURE__*/React.createElement(RechartsAreaChart, {
|
|
92
|
-
data:
|
|
57
|
+
data: data
|
|
93
58
|
}, /*#__PURE__*/React.createElement(CartesianGrid, {
|
|
94
59
|
strokeDasharray: "3 3"
|
|
95
60
|
}), /*#__PURE__*/React.createElement(XAxis, {
|
|
@@ -101,7 +66,8 @@ const AreaChart = ({
|
|
|
101
66
|
},
|
|
102
67
|
axisLine: false,
|
|
103
68
|
tickLine: false,
|
|
104
|
-
tickCount: 3
|
|
69
|
+
tickCount: 3,
|
|
70
|
+
tickFormatter: value => formatDate(value, dateFormat)
|
|
105
71
|
}), /*#__PURE__*/React.createElement(YAxis, {
|
|
106
72
|
domain: yAxisBounds,
|
|
107
73
|
scale: "linear",
|
|
@@ -110,7 +76,7 @@ const AreaChart = ({
|
|
|
110
76
|
value: yLabel,
|
|
111
77
|
angle: -90,
|
|
112
78
|
position: 'left',
|
|
113
|
-
offset:
|
|
79
|
+
offset: -3,
|
|
114
80
|
style: {
|
|
115
81
|
textAnchor: 'middle'
|
|
116
82
|
}
|
|
@@ -120,10 +86,18 @@ const AreaChart = ({
|
|
|
120
86
|
bottom: 10
|
|
121
87
|
},
|
|
122
88
|
axisLine: false,
|
|
123
|
-
tickLine:
|
|
124
|
-
tickFormatter: value =>
|
|
89
|
+
tickLine: false,
|
|
90
|
+
tickFormatter: value => {
|
|
91
|
+
if (isTimeFormat) {
|
|
92
|
+
return formatTime(value);
|
|
93
|
+
}
|
|
94
|
+
return value.toFixed(2);
|
|
95
|
+
}
|
|
125
96
|
}), /*#__PURE__*/React.createElement(Tooltip, {
|
|
126
|
-
content: /*#__PURE__*/React.createElement(CustomTooltipContent,
|
|
97
|
+
content: /*#__PURE__*/React.createElement(CustomTooltipContent, {
|
|
98
|
+
dateFormat: dateFormat,
|
|
99
|
+
isTimeFormat: isTimeFormat
|
|
100
|
+
})
|
|
127
101
|
}), filled && /*#__PURE__*/React.createElement(Area, {
|
|
128
102
|
id: "bounds",
|
|
129
103
|
type: "linear",
|
|
@@ -135,12 +109,12 @@ const AreaChart = ({
|
|
|
135
109
|
dot: false,
|
|
136
110
|
label: false,
|
|
137
111
|
isAnimationActive: false
|
|
138
|
-
}),
|
|
139
|
-
id: key,
|
|
140
|
-
key: key,
|
|
112
|
+
}), selectedYLabels.map(key => /*#__PURE__*/React.createElement(Area, {
|
|
113
|
+
id: key.label,
|
|
114
|
+
key: key.label,
|
|
141
115
|
type: "linear",
|
|
142
|
-
dataKey: key,
|
|
143
|
-
stroke:
|
|
116
|
+
dataKey: key.label,
|
|
117
|
+
stroke: key.color,
|
|
144
118
|
fill: "none",
|
|
145
119
|
connectNulls: true,
|
|
146
120
|
dot: false,
|
|
@@ -151,21 +125,66 @@ const AreaChart = ({
|
|
|
151
125
|
})))));
|
|
152
126
|
};
|
|
153
127
|
AreaChart.propTypes = {
|
|
128
|
+
/**
|
|
129
|
+
* Array of data objects to be displayed in the chart.
|
|
130
|
+
*/
|
|
154
131
|
// eslint-disable-next-line react/forbid-prop-types
|
|
155
132
|
data: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
133
|
+
/**
|
|
134
|
+
* Title of the chart.
|
|
135
|
+
*/
|
|
156
136
|
title: PropTypes.string.isRequired,
|
|
137
|
+
/**
|
|
138
|
+
* Key for the x-axis data.
|
|
139
|
+
*/
|
|
157
140
|
xKey: PropTypes.string.isRequired,
|
|
141
|
+
/**
|
|
142
|
+
* Array of keys for the y-axis data.
|
|
143
|
+
*/
|
|
158
144
|
yKeys: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
145
|
+
/**
|
|
146
|
+
* Label for the x-axis.
|
|
147
|
+
*/
|
|
159
148
|
xLabel: PropTypes.string,
|
|
149
|
+
/**
|
|
150
|
+
* Label for the y-axis.
|
|
151
|
+
*/
|
|
160
152
|
yLabel: PropTypes.string,
|
|
153
|
+
/**
|
|
154
|
+
* Array of colors corresponding to the y-axis data keys.
|
|
155
|
+
*/
|
|
161
156
|
colors: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
157
|
+
/**
|
|
158
|
+
* Boolean to determine if the area under the curve should be filled.
|
|
159
|
+
*/
|
|
162
160
|
filled: PropTypes.bool,
|
|
161
|
+
/**
|
|
162
|
+
* Height of the chart.
|
|
163
|
+
*/
|
|
163
164
|
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
164
|
-
|
|
165
|
+
/**
|
|
166
|
+
* Width of the chart.
|
|
167
|
+
*/
|
|
168
|
+
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
169
|
+
/**
|
|
170
|
+
* Flag on whether to capitalize legend keys
|
|
171
|
+
*/
|
|
172
|
+
capitalizedLegend: PropTypes.bool,
|
|
173
|
+
/**
|
|
174
|
+
* Flag on whether it is a timeformat or not
|
|
175
|
+
*/
|
|
176
|
+
isTimeFormat: PropTypes.bool,
|
|
177
|
+
/**
|
|
178
|
+
* The type of format for the datetime value
|
|
179
|
+
*/
|
|
180
|
+
dateFormat: PropTypes.oneOf(Object.values(DATE_FORMATS))
|
|
165
181
|
};
|
|
166
182
|
AreaChart.defaultProps = {
|
|
167
183
|
filled: false,
|
|
168
184
|
width: '100%',
|
|
169
|
-
height: 300
|
|
185
|
+
height: 300,
|
|
186
|
+
capitalizedLegend: false,
|
|
187
|
+
isTimeFormat: false,
|
|
188
|
+
dateFormat: DATE_FORMATS.HUMAN_READABLE
|
|
170
189
|
};
|
|
171
190
|
export default AreaChart;
|
|
@@ -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
|
+
&.area-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
|
+
/* stylelint-disable selector-max-compound-selectors -- nested elements */
|
|
30
|
+
.recharts-wrapper {
|
|
31
|
+
.recharts-surface {
|
|
32
|
+
.recharts-cartesian-grid line {
|
|
33
|
+
stroke: var(--ui-lines);
|
|
34
|
+
}
|
|
35
|
+
|
|
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
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import { BarChart as RechartsBarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
|
5
|
+
import styleNames from '@pareto-engineering/bem/exports';
|
|
6
|
+
import { CustomLegend, CustomTooltipContent, YLabelsDropDown } from "../Common";
|
|
7
|
+
import "./styles.scss";
|
|
8
|
+
|
|
9
|
+
// Local Definitions
|
|
10
|
+
|
|
11
|
+
const baseClassName = styleNames.base;
|
|
12
|
+
const componentClassName = 'bar-chart';
|
|
13
|
+
const BarChart = ({
|
|
14
|
+
id,
|
|
15
|
+
className: userClassName,
|
|
16
|
+
data,
|
|
17
|
+
title,
|
|
18
|
+
xKey,
|
|
19
|
+
yKeys,
|
|
20
|
+
xLabel,
|
|
21
|
+
yLabel,
|
|
22
|
+
colors,
|
|
23
|
+
height,
|
|
24
|
+
width,
|
|
25
|
+
isTimeFormat,
|
|
26
|
+
capitalizedLegend
|
|
27
|
+
}) => {
|
|
28
|
+
const allYLabels = yKeys.map(key => ({
|
|
29
|
+
label: key,
|
|
30
|
+
color: colors[yKeys.indexOf(key)]
|
|
31
|
+
}));
|
|
32
|
+
const [selectedYLabels, setSelectedYLabels] = useState(allYLabels);
|
|
33
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
34
|
+
id: id,
|
|
35
|
+
className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' ')
|
|
36
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
37
|
+
className: "chart-header"
|
|
38
|
+
}, /*#__PURE__*/React.createElement("h3", null, title), /*#__PURE__*/React.createElement(YLabelsDropDown, {
|
|
39
|
+
allYLabels: allYLabels,
|
|
40
|
+
selectedYLabels: selectedYLabels,
|
|
41
|
+
setSelectedYLabels: setSelectedYLabels
|
|
42
|
+
})), /*#__PURE__*/React.createElement(CustomLegend, {
|
|
43
|
+
colorsArray: selectedYLabels.map(item => item.color),
|
|
44
|
+
yKeysArray: selectedYLabels.map(item => item.label),
|
|
45
|
+
capitalizedLegend: capitalizedLegend
|
|
46
|
+
}), /*#__PURE__*/React.createElement(ResponsiveContainer, {
|
|
47
|
+
width: width,
|
|
48
|
+
height: height
|
|
49
|
+
}, /*#__PURE__*/React.createElement(RechartsBarChart, {
|
|
50
|
+
data: data
|
|
51
|
+
}, /*#__PURE__*/React.createElement(CartesianGrid, {
|
|
52
|
+
vertical: false
|
|
53
|
+
}), /*#__PURE__*/React.createElement(XAxis, {
|
|
54
|
+
dataKey: xKey,
|
|
55
|
+
label: {
|
|
56
|
+
value: xLabel,
|
|
57
|
+
position: 'insideBottom',
|
|
58
|
+
offset: -5
|
|
59
|
+
} // Adjusted offset for padding
|
|
60
|
+
,
|
|
61
|
+
axisLine: false,
|
|
62
|
+
tickLine: false,
|
|
63
|
+
tickCount: 3
|
|
64
|
+
}), /*#__PURE__*/React.createElement(YAxis, {
|
|
65
|
+
label: {
|
|
66
|
+
value: yLabel,
|
|
67
|
+
angle: -90,
|
|
68
|
+
position: 'insideLeft',
|
|
69
|
+
offset: 15
|
|
70
|
+
},
|
|
71
|
+
axisLine: false,
|
|
72
|
+
tickLine: false
|
|
73
|
+
}), /*#__PURE__*/React.createElement(Tooltip, {
|
|
74
|
+
content: /*#__PURE__*/React.createElement(CustomTooltipContent, {
|
|
75
|
+
isTimeFormat: isTimeFormat
|
|
76
|
+
})
|
|
77
|
+
}), selectedYLabels.map(key => /*#__PURE__*/React.createElement(Bar, {
|
|
78
|
+
stackId: "a",
|
|
79
|
+
id: key.label,
|
|
80
|
+
key: key.label,
|
|
81
|
+
dataKey: key.label,
|
|
82
|
+
fill: key.color
|
|
83
|
+
})))));
|
|
84
|
+
};
|
|
85
|
+
BarChart.propTypes = {
|
|
86
|
+
/**
|
|
87
|
+
* Array of data objects to be displayed in the chart.
|
|
88
|
+
*/
|
|
89
|
+
// eslint-disable-next-line react/forbid-prop-types
|
|
90
|
+
data: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
91
|
+
/**
|
|
92
|
+
* Title of the chart.
|
|
93
|
+
*/
|
|
94
|
+
title: PropTypes.string.isRequired,
|
|
95
|
+
/**
|
|
96
|
+
* Key for the x-axis data.
|
|
97
|
+
*/
|
|
98
|
+
xKey: PropTypes.string.isRequired,
|
|
99
|
+
/**
|
|
100
|
+
* Array of keys for the y-axis data.
|
|
101
|
+
*/
|
|
102
|
+
yKeys: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
103
|
+
/**
|
|
104
|
+
* Label for the x-axis.
|
|
105
|
+
*/
|
|
106
|
+
xLabel: PropTypes.string,
|
|
107
|
+
/**
|
|
108
|
+
* Label for the y-axis.
|
|
109
|
+
*/
|
|
110
|
+
yLabel: PropTypes.string,
|
|
111
|
+
/**
|
|
112
|
+
* Array of colors corresponding to the y-axis data keys.
|
|
113
|
+
*/
|
|
114
|
+
colors: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
115
|
+
/**
|
|
116
|
+
* Height of the chart.
|
|
117
|
+
*/
|
|
118
|
+
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
119
|
+
/**
|
|
120
|
+
* Width of the chart.
|
|
121
|
+
*/
|
|
122
|
+
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
|
|
123
|
+
};
|
|
124
|
+
BarChart.defaultProps = {
|
|
125
|
+
width: '100%',
|
|
126
|
+
height: 300
|
|
127
|
+
};
|
|
128
|
+
export default BarChart;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as BarChart } from "./BarChart";
|
|
@@ -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
|
+
&.bar-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
|
+
/* stylelint-disable selector-max-compound-selectors -- nested elements */
|
|
30
|
+
.recharts-wrapper {
|
|
31
|
+
.recharts-surface {
|
|
32
|
+
.recharts-cartesian-grid line {
|
|
33
|
+
stroke: var(--ui-lines);
|
|
34
|
+
}
|
|
35
|
+
|
|
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
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styleNames from '@pareto-engineering/bem/exports';
|
|
4
|
+
import { snakeCaseToTitleCase } from "../../../../utils";
|
|
5
|
+
import "./styles.scss";
|
|
6
|
+
const baseClassName = styleNames.base;
|
|
7
|
+
const componentClassName = 'custom-legend';
|
|
8
|
+
const CustomLegend = ({
|
|
9
|
+
id,
|
|
10
|
+
className: userClassName,
|
|
11
|
+
colorsArray,
|
|
12
|
+
yKeysArray,
|
|
13
|
+
orientation,
|
|
14
|
+
getLegendItemTitle,
|
|
15
|
+
getLegendItemSubtitle,
|
|
16
|
+
capitalizedLegend
|
|
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)))));
|
|
35
|
+
CustomLegend.propTypes = {
|
|
36
|
+
/**
|
|
37
|
+
* The id of the dropdown component.
|
|
38
|
+
*/
|
|
39
|
+
id: PropTypes.string,
|
|
40
|
+
/**
|
|
41
|
+
* Additional class names for the dropdown component.
|
|
42
|
+
*/
|
|
43
|
+
className: PropTypes.string,
|
|
44
|
+
/**
|
|
45
|
+
* Array of colors corresponding to the y-axis data keys.
|
|
46
|
+
*/
|
|
47
|
+
colorsArray: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
48
|
+
/**
|
|
49
|
+
* Array of keys for the y-axis data.
|
|
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,
|
|
64
|
+
/**
|
|
65
|
+
* Flag on whether to capitalize legend keys
|
|
66
|
+
*/
|
|
67
|
+
capitalizedLegend: PropTypes.bool
|
|
68
|
+
};
|
|
69
|
+
CustomLegend.defaultProps = {
|
|
70
|
+
orientation: 'horizontal',
|
|
71
|
+
getLegendItemTitle: key => key,
|
|
72
|
+
/* eslint-disable no-unused-vars */
|
|
73
|
+
getLegendItemSubtitle: () => {},
|
|
74
|
+
capitalizedLegend: false
|
|
75
|
+
};
|
|
76
|
+
export default CustomLegend;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as CustomLegend } from "./CustomLegend";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
@use "@pareto-engineering/bem";
|
|
2
|
+
|
|
3
|
+
$default-padding: 1rem;
|
|
4
|
+
$default-margin: 1rem;
|
|
5
|
+
$default-text-font-size: calc(var(--s-1) * 1rem);
|
|
6
|
+
$default-border-radius: .25rem;
|
|
7
|
+
$default-legend-gap: .625rem;
|
|
8
|
+
$default-legend-padding: calc($default-padding * .125) calc($default-padding * .625);
|
|
9
|
+
$default-legend-dot-width: .5rem;
|
|
10
|
+
$default-legend-dot-height: .5rem;
|
|
11
|
+
$default-legend-dot-margin-right: .3125rem;
|
|
12
|
+
$default-box-shadow: 0 4px 16px 0 var(--soft-shadow);
|
|
13
|
+
|
|
14
|
+
.#{bem.$base} {
|
|
15
|
+
&.custom-legend {
|
|
16
|
+
gap: $default-legend-gap;
|
|
17
|
+
justify-content: flex-end;
|
|
18
|
+
padding-bottom: $default-padding;
|
|
19
|
+
padding-right: calc($default-padding * .25);
|
|
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
|
+
|
|
36
|
+
.item {
|
|
37
|
+
border-radius: $default-border-radius;
|
|
38
|
+
padding: $default-legend-padding;
|
|
39
|
+
|
|
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
|
+
}
|
|
57
|
+
|
|
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
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styleNames from '@pareto-engineering/bem/exports';
|
|
4
|
+
import { formatTime, formatDate, DATE_FORMATS, snakeCaseToTitleCase } from "../../../../utils";
|
|
5
|
+
import "./styles.scss";
|
|
6
|
+
const baseClassName = styleNames.base;
|
|
7
|
+
const componentClassName = 'custom-tooltip-content';
|
|
8
|
+
const CustomTooltipContent = ({
|
|
9
|
+
id,
|
|
10
|
+
className: userClassName,
|
|
11
|
+
dateFormat,
|
|
12
|
+
isTimeFormat,
|
|
13
|
+
isDateValue,
|
|
14
|
+
active,
|
|
15
|
+
payload,
|
|
16
|
+
label
|
|
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
|
+
};
|
|
28
|
+
if (active && payload && payload.length) {
|
|
29
|
+
const newPayload = payload.filter(item => item.name !== 'bounds');
|
|
30
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
31
|
+
id: id,
|
|
32
|
+
className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' ')
|
|
33
|
+
}, /*#__PURE__*/React.createElement("p", {
|
|
34
|
+
className: "label"
|
|
35
|
+
}, isDateValue ? formatDate(label, dateFormat) : label), newPayload.map(entry => /*#__PURE__*/React.createElement("p", {
|
|
36
|
+
className: "label",
|
|
37
|
+
key: `${entry.name}`,
|
|
38
|
+
style: {
|
|
39
|
+
color: entry.color,
|
|
40
|
+
textTransform: 'capitalize'
|
|
41
|
+
}
|
|
42
|
+
}, `${snakeCaseToTitleCase(entry.name)}: ${formatLabelValue(entry.value)}`)));
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
};
|
|
46
|
+
CustomTooltipContent.propTypes = {
|
|
47
|
+
/**
|
|
48
|
+
* The id of the dropdown component.
|
|
49
|
+
*/
|
|
50
|
+
id: PropTypes.string,
|
|
51
|
+
/**
|
|
52
|
+
* Additional class names for the dropdown component.
|
|
53
|
+
*/
|
|
54
|
+
className: PropTypes.string,
|
|
55
|
+
/**
|
|
56
|
+
* Flag on whether it is a timeformat or not
|
|
57
|
+
*/
|
|
58
|
+
isTimeFormat: PropTypes.bool,
|
|
59
|
+
/**
|
|
60
|
+
* The type of format for the datetime value
|
|
61
|
+
*/
|
|
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,
|
|
67
|
+
/**
|
|
68
|
+
* If set true, the tooltip is displayed.
|
|
69
|
+
* If set false, the tooltip is hidden, usually calculated internally.
|
|
70
|
+
*/
|
|
71
|
+
active: PropTypes.bool.isRequired,
|
|
72
|
+
/**
|
|
73
|
+
* The source data of the content to be displayed in the tooltip,
|
|
74
|
+
* always calculated internally and cannot be user set.
|
|
75
|
+
*/
|
|
76
|
+
payload: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
77
|
+
/**
|
|
78
|
+
*The label value which is active now, usually calculated internally.
|
|
79
|
+
*/
|
|
80
|
+
label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired
|
|
81
|
+
};
|
|
82
|
+
CustomTooltipContent.defaultProps = {
|
|
83
|
+
isTimeFormat: false,
|
|
84
|
+
isDateValue: true,
|
|
85
|
+
dateFormat: DATE_FORMATS.HUMAN_READABLE
|
|
86
|
+
};
|
|
87
|
+
export default CustomTooltipContent;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as CustomTooltipContent } from "./CustomTooltipContent";
|