@reltio/components 1.4.1917 → 1.4.1918
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/cjs/GaugeChart/GaugeChart.d.ts +13 -0
- package/cjs/GaugeChart/GaugeChart.js +87 -0
- package/cjs/GaugeChart/GaugeChart.test.d.ts +1 -0
- package/cjs/GaugeChart/GaugeChart.test.js +193 -0
- package/cjs/GaugeChart/constants.d.ts +6 -0
- package/cjs/GaugeChart/constants.js +9 -0
- package/cjs/GaugeChart/helpers.d.ts +9 -0
- package/cjs/GaugeChart/helpers.js +22 -0
- package/cjs/GaugeChart/helpers.test.d.ts +1 -0
- package/cjs/GaugeChart/helpers.test.js +43 -0
- package/cjs/GaugeChart/index.d.ts +1 -0
- package/cjs/GaugeChart/index.js +5 -0
- package/cjs/GaugeChart/styles.d.ts +1 -0
- package/cjs/GaugeChart/styles.js +44 -0
- package/cjs/GaugeChart/types.d.ts +5 -0
- package/cjs/GaugeChart/types.js +2 -0
- package/cjs/index.d.ts +1 -0
- package/cjs/index.js +6 -4
- package/esm/GaugeChart/GaugeChart.d.ts +13 -0
- package/esm/GaugeChart/GaugeChart.js +57 -0
- package/esm/GaugeChart/GaugeChart.test.d.ts +1 -0
- package/esm/GaugeChart/GaugeChart.test.js +188 -0
- package/esm/GaugeChart/constants.d.ts +6 -0
- package/esm/GaugeChart/constants.js +6 -0
- package/esm/GaugeChart/helpers.d.ts +9 -0
- package/esm/GaugeChart/helpers.js +18 -0
- package/esm/GaugeChart/helpers.test.d.ts +1 -0
- package/esm/GaugeChart/helpers.test.js +41 -0
- package/esm/GaugeChart/index.d.ts +1 -0
- package/esm/GaugeChart/index.js +1 -0
- package/esm/GaugeChart/styles.d.ts +1 -0
- package/esm/GaugeChart/styles.js +41 -0
- package/esm/GaugeChart/types.d.ts +5 -0
- package/esm/GaugeChart/types.js +1 -0
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { GaugeItem } from './types';
|
|
3
|
+
type Props = {
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
data: GaugeItem[];
|
|
7
|
+
value: number;
|
|
8
|
+
label?: React.ReactNode;
|
|
9
|
+
renderValue?: (value: number) => React.ReactNode;
|
|
10
|
+
isAnimationActive?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare const GaugeChart: ({ width, height, data, value, label, renderValue, isAnimationActive }: Props) => JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
30
|
+
if (mod && mod.__esModule) return mod;
|
|
31
|
+
var result = {};
|
|
32
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
33
|
+
__setModuleDefault(result, mod);
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.GaugeChart = void 0;
|
|
41
|
+
var react_1 = __importStar(require("react"));
|
|
42
|
+
var ramda_1 = require("ramda");
|
|
43
|
+
var recharts_1 = require("recharts");
|
|
44
|
+
var Typography_1 = __importDefault(require("@mui/material/Typography"));
|
|
45
|
+
var helpers_1 = require("./helpers");
|
|
46
|
+
var constants_1 = require("./constants");
|
|
47
|
+
var styles_1 = require("./styles");
|
|
48
|
+
var GaugeChart = function (_a) {
|
|
49
|
+
var width = _a.width, height = _a.height, data = _a.data, value = _a.value, label = _a.label, _b = _a.renderValue, renderValue = _b === void 0 ? ramda_1.identity : _b, _c = _a.isAnimationActive, isAnimationActive = _c === void 0 ? true : _c;
|
|
50
|
+
var styles = (0, styles_1.useStyles)();
|
|
51
|
+
var labelElRef = (0, react_1.useRef)();
|
|
52
|
+
var _d = (0, react_1.useState)(!isAnimationActive), animationIsEnd = _d[0], setAnimationIsEnd = _d[1];
|
|
53
|
+
var _e = (0, react_1.useState)({ bottom: 0, top: 0, left: 0, right: 0 }), margin = _e[0], setMargin = _e[1];
|
|
54
|
+
var _f = (0, react_1.useState)(0), textOffset = _f[0], setTextOffset = _f[1];
|
|
55
|
+
var widthWithoutMargin = width - margin.left - margin.right;
|
|
56
|
+
var heightWithoutMargin = height - margin.top - margin.bottom - (textOffset > 0 ? textOffset : 0);
|
|
57
|
+
var outerRadius = Math.min(widthWithoutMargin / 2, heightWithoutMargin, constants_1.MAX_RADIUS);
|
|
58
|
+
var innerRadius = outerRadius - constants_1.ARC_WIDTH_AS_PERCENTAGES * outerRadius;
|
|
59
|
+
var cx = widthWithoutMargin / 2 + margin.left;
|
|
60
|
+
var cy = heightWithoutMargin / 2 + outerRadius / 2 + margin.top;
|
|
61
|
+
var chartData = data.map(function (item, name) { return (__assign(__assign({}, item), { name: name })); });
|
|
62
|
+
var _g = (0, helpers_1.getGaugeIndicatorCoords)(value, chartData, cx, cy, outerRadius, innerRadius), x1 = _g.x1, y1 = _g.y1, x2 = _g.x2, y2 = _g.y2, x3 = _g.x3, y3 = _g.y3;
|
|
63
|
+
(0, react_1.useEffect)(function () {
|
|
64
|
+
var _a;
|
|
65
|
+
if (animationIsEnd) {
|
|
66
|
+
var clientHeight = ((_a = labelElRef === null || labelElRef === void 0 ? void 0 : labelElRef.current) !== null && _a !== void 0 ? _a : { clientHeight: 0 }).clientHeight;
|
|
67
|
+
var textOffset_1 = Math.ceil(clientHeight) - 16;
|
|
68
|
+
var verticalMargin_1 = Math.ceil(constants_1.TOP_INDICATOR_HEIGHT_AS_PERCENTAGES * outerRadius);
|
|
69
|
+
setTextOffset(textOffset_1);
|
|
70
|
+
setMargin(function (prevMargin) { return (__assign(__assign({}, prevMargin), { bottom: verticalMargin_1, top: verticalMargin_1 })); });
|
|
71
|
+
}
|
|
72
|
+
}, [width, height, animationIsEnd]);
|
|
73
|
+
return (react_1.default.createElement("div", { "data-reltio-id": "gauge-chart", className: styles.root, style: { width: width, height: height } },
|
|
74
|
+
react_1.default.createElement(recharts_1.PieChart, { margin: { top: 0, bottom: 0, left: 0, right: 0 }, width: width, height: height },
|
|
75
|
+
react_1.default.createElement(recharts_1.Pie, { className: styles.pie, dataKey: "value", startAngle: 180, endAngle: 0, data: chartData, cx: cx, cy: cy, innerRadius: innerRadius, outerRadius: outerRadius, stroke: "none", isAnimationActive: isAnimationActive, onAnimationEnd: function () { return setAnimationIsEnd(true); } }, data.map(function (entry, idx) { return (react_1.default.createElement(recharts_1.Cell, { key: idx, fill: entry.color })); })),
|
|
76
|
+
react_1.default.createElement("path", { "data-reltio-id": "gauge-chart-indicator", className: styles.indicator, style: { opacity: animationIsEnd ? 1 : 0 }, d: "M".concat(x1, " ").concat(y1, "L").concat(x2, " ").concat(y2, " L").concat(x3, " ").concat(y3, " L").concat(x1, " ").concat(y1) })),
|
|
77
|
+
react_1.default.createElement("div", { "data-reltio-id": "gauge-chart-text", className: styles.text, style: {
|
|
78
|
+
top: "".concat(((cy - innerRadius) / height) * 100, "%"),
|
|
79
|
+
bottom: "calc(".concat(((height - cy) / height) * 100, "% - ").concat(textOffset, "px)"),
|
|
80
|
+
left: "".concat(((width - innerRadius * 2) / width / 2) * 100, "%"),
|
|
81
|
+
right: "".concat(((width - innerRadius * 2) / width / 2) * 100, "%"),
|
|
82
|
+
opacity: animationIsEnd ? 1 : 0
|
|
83
|
+
} },
|
|
84
|
+
react_1.default.createElement(Typography_1.default, { className: styles.value }, renderValue(value)),
|
|
85
|
+
label && (react_1.default.createElement("div", { ref: labelElRef, className: styles.label }, label)))));
|
|
86
|
+
};
|
|
87
|
+
exports.GaugeChart = GaugeChart;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
24
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
+
function step(op) {
|
|
27
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
30
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
+
switch (op[0]) {
|
|
32
|
+
case 0: case 1: t = op; break;
|
|
33
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
+
default:
|
|
37
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
+
if (t[2]) _.ops.pop();
|
|
42
|
+
_.trys.pop(); continue;
|
|
43
|
+
}
|
|
44
|
+
op = body.call(thisArg, _);
|
|
45
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
50
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
51
|
+
};
|
|
52
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
|
+
var react_1 = __importDefault(require("react"));
|
|
54
|
+
var react_2 = require("@testing-library/react");
|
|
55
|
+
var GaugeChart_1 = require("./GaugeChart");
|
|
56
|
+
var defaultProps = {
|
|
57
|
+
width: 400,
|
|
58
|
+
height: 300,
|
|
59
|
+
data: [
|
|
60
|
+
{ color: 'rgba(241, 35, 35, 1)', value: 30 },
|
|
61
|
+
{ color: 'rgba(255, 109, 26, 1)', value: 40 },
|
|
62
|
+
{ color: 'rgba(255, 238, 54, 1)', value: 20 },
|
|
63
|
+
{ color: 'rgba(147, 244, 87, 1)', value: 10 }
|
|
64
|
+
],
|
|
65
|
+
value: 50,
|
|
66
|
+
label: 'Label',
|
|
67
|
+
isAnimationActive: false
|
|
68
|
+
};
|
|
69
|
+
var removeExtraSpaces = function (str) { return str.replace(/\s{2,}/g, ' '); };
|
|
70
|
+
var setUp = function (props) {
|
|
71
|
+
if (props === void 0) { props = defaultProps; }
|
|
72
|
+
var result = (0, react_2.render)(react_1.default.createElement(GaugeChart_1.GaugeChart, __assign({}, props)));
|
|
73
|
+
return __assign(__assign({}, result), { rerender: function (newProps) { return result.rerender(react_1.default.createElement(GaugeChart_1.GaugeChart, __assign({}, props, newProps))); } });
|
|
74
|
+
};
|
|
75
|
+
describe('Gauge chart behaviour', function () {
|
|
76
|
+
it('should render chart correctly in basic scenario', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
77
|
+
var rerender, text, gaugeChart, pieChart, pie, sectors, indicator, firstSector, secondSector, thirdSector, fourthSector;
|
|
78
|
+
return __generator(this, function (_a) {
|
|
79
|
+
rerender = setUp(__assign(__assign({}, defaultProps), { width: 0, height: 0 })).rerender;
|
|
80
|
+
text = react_2.screen.getByTestId('gauge-chart-text');
|
|
81
|
+
Object.defineProperty((0, react_2.within)(text).getByText('Label'), 'clientHeight', { configurable: true, value: 16 });
|
|
82
|
+
rerender(defaultProps);
|
|
83
|
+
gaugeChart = react_2.screen.getByTestId('gauge-chart');
|
|
84
|
+
pieChart = gaugeChart.querySelector('.recharts-wrapper');
|
|
85
|
+
expect(gaugeChart).toHaveStyle({ width: '400px', height: '300px' });
|
|
86
|
+
expect(pieChart).toHaveStyle({ width: '400px', height: '300px' });
|
|
87
|
+
pie = gaugeChart.querySelector('.recharts-surface');
|
|
88
|
+
expect(pie).toHaveStyle({ width: '100%', height: '100%' });
|
|
89
|
+
expect(pie).toHaveAttribute('width', '400');
|
|
90
|
+
expect(pie).toHaveAttribute('height', '300');
|
|
91
|
+
expect(pie).toHaveAttribute('cx', '50%');
|
|
92
|
+
expect(pie).toHaveAttribute('cy', '50%');
|
|
93
|
+
sectors = gaugeChart.querySelectorAll('.recharts-pie-sector');
|
|
94
|
+
indicator = react_2.screen.getByTestId('gauge-chart-indicator');
|
|
95
|
+
expect(sectors).toHaveLength(4);
|
|
96
|
+
firstSector = sectors[0].querySelector('.recharts-sector');
|
|
97
|
+
expect(firstSector).toHaveAttribute('fill', 'rgba(241, 35, 35, 1)');
|
|
98
|
+
expect(firstSector).toHaveAttribute('cx', '200');
|
|
99
|
+
expect(firstSector).toHaveAttribute('cy', '250');
|
|
100
|
+
expect(removeExtraSpaces(firstSector.getAttribute('d'))).toBe('M 0,249.99999999999997 A 200,200,0, 0,1, 82.4429495415054,88.19660112501052 L 105.95435963320432,120.55728090000841 A 160,160,0, 0,0, 40,249.99999999999997 Z');
|
|
101
|
+
secondSector = sectors[1].querySelector('.recharts-sector');
|
|
102
|
+
expect(secondSector).toHaveAttribute('fill', 'rgba(255, 109, 26, 1)');
|
|
103
|
+
expect(secondSector).toHaveAttribute('cx', '200');
|
|
104
|
+
expect(secondSector).toHaveAttribute('cy', '250');
|
|
105
|
+
expect(removeExtraSpaces(secondSector.getAttribute('d'))).toBe('M 82.4429495415054,88.19660112501052 A 200,200,0, 0,1, 317.55705045849464,88.19660112501052 L 294.04564036679574,120.55728090000841 A 160,160,0, 0,0, 105.95435963320432,120.55728090000841 Z');
|
|
106
|
+
thirdSector = sectors[2].querySelector('.recharts-sector');
|
|
107
|
+
expect(thirdSector).toHaveAttribute('fill', 'rgba(255, 238, 54, 1)');
|
|
108
|
+
expect(thirdSector).toHaveAttribute('cx', '200');
|
|
109
|
+
expect(thirdSector).toHaveAttribute('cy', '250');
|
|
110
|
+
expect(removeExtraSpaces(thirdSector.getAttribute('d'))).toBe('M 317.55705045849464,88.19660112501052 A 200,200,0, 0,1, 390.21130325903073,188.19660112501052 L 352.1690426072246,200.5572809000084 A 160,160,0, 0,0, 294.04564036679574,120.55728090000841 Z');
|
|
111
|
+
fourthSector = sectors[3].querySelector('.recharts-sector');
|
|
112
|
+
expect(fourthSector).toHaveAttribute('fill', 'rgba(147, 244, 87, 1)');
|
|
113
|
+
expect(fourthSector).toHaveAttribute('cx', '200');
|
|
114
|
+
expect(fourthSector).toHaveAttribute('cy', '250');
|
|
115
|
+
expect(removeExtraSpaces(fourthSector.getAttribute('d'))).toBe('M 390.21130325903073,188.19660112501052 A 200,200,0, 0,1, 400,250 L 360,250 A 160,160,0, 0,0, 352.1690426072246,200.5572809000084 Z');
|
|
116
|
+
expect(indicator).toHaveStyle({ opacity: 1 });
|
|
117
|
+
expect(indicator).toHaveAttribute('d', 'M198 98L202 98 L200 36 L198 98');
|
|
118
|
+
expect(text).toHaveStyle({ top: '30%', bottom: 'calc(16.666666666666664% - 0px)', left: '10%', right: '10%' });
|
|
119
|
+
(0, react_2.within)(text).getByText('50');
|
|
120
|
+
(0, react_2.within)(text).getByText('Label');
|
|
121
|
+
return [2 /*return*/];
|
|
122
|
+
});
|
|
123
|
+
}); });
|
|
124
|
+
it('should render chart correctly if the label height is more than 16 pixels', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
125
|
+
var rerender, text, gaugeChart, indicator, sectors, firstSector, secondSector, thirdSector, fourthSector;
|
|
126
|
+
return __generator(this, function (_a) {
|
|
127
|
+
rerender = setUp(__assign(__assign({}, defaultProps), { width: 0, height: 0 })).rerender;
|
|
128
|
+
text = react_2.screen.getByTestId('gauge-chart-text');
|
|
129
|
+
Object.defineProperty((0, react_2.within)(text).getByText('Label'), 'clientHeight', { configurable: true, value: 48 });
|
|
130
|
+
rerender(defaultProps);
|
|
131
|
+
gaugeChart = react_2.screen.getByTestId('gauge-chart');
|
|
132
|
+
indicator = react_2.screen.getByTestId('gauge-chart-indicator');
|
|
133
|
+
sectors = gaugeChart.querySelectorAll('.recharts-pie-sector');
|
|
134
|
+
firstSector = sectors[0].querySelector('.recharts-sector');
|
|
135
|
+
expect(firstSector).toHaveAttribute('cx', '200');
|
|
136
|
+
expect(firstSector).toHaveAttribute('cy', '234');
|
|
137
|
+
expect(removeExtraSpaces(firstSector.getAttribute('d'))).toBe('M 0,233.99999999999997 A 200,200,0, 0,1, 82.4429495415054,72.19660112501052 L 105.95435963320432,104.55728090000841 A 160,160,0, 0,0, 40,233.99999999999997 Z');
|
|
138
|
+
secondSector = sectors[1].querySelector('.recharts-sector');
|
|
139
|
+
expect(secondSector).toHaveAttribute('cx', '200');
|
|
140
|
+
expect(secondSector).toHaveAttribute('cy', '234');
|
|
141
|
+
expect(removeExtraSpaces(secondSector.getAttribute('d'))).toBe('M 82.4429495415054,72.19660112501052 A 200,200,0, 0,1, 317.55705045849464,72.19660112501052 L 294.04564036679574,104.55728090000841 A 160,160,0, 0,0, 105.95435963320432,104.55728090000841 Z');
|
|
142
|
+
thirdSector = sectors[2].querySelector('.recharts-sector');
|
|
143
|
+
expect(thirdSector).toHaveAttribute('cx', '200');
|
|
144
|
+
expect(thirdSector).toHaveAttribute('cy', '234');
|
|
145
|
+
expect(removeExtraSpaces(thirdSector.getAttribute('d'))).toBe('M 317.55705045849464,72.19660112501052 A 200,200,0, 0,1, 390.21130325903073,172.19660112501052 L 352.1690426072246,184.5572809000084 A 160,160,0, 0,0, 294.04564036679574,104.55728090000841 Z');
|
|
146
|
+
fourthSector = sectors[3].querySelector('.recharts-sector');
|
|
147
|
+
expect(fourthSector).toHaveAttribute('cx', '200');
|
|
148
|
+
expect(fourthSector).toHaveAttribute('cy', '234');
|
|
149
|
+
expect(removeExtraSpaces(fourthSector.getAttribute('d'))).toBe('M 390.21130325903073,172.19660112501052 A 200,200,0, 0,1, 400,234 L 360,234 A 160,160,0, 0,0, 352.1690426072246,184.5572809000084 Z');
|
|
150
|
+
expect(indicator).toHaveAttribute('d', 'M198 82L202 82 L200 20 L198 82');
|
|
151
|
+
expect(text).toHaveStyle({ top: '24.666666666666668%', bottom: 'calc(22% - 32px)', left: '10%', right: '10%' });
|
|
152
|
+
return [2 /*return*/];
|
|
153
|
+
});
|
|
154
|
+
}); });
|
|
155
|
+
it('should render chart correctly if the label height is less than 16 pixels', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
156
|
+
var rerender, text, gaugeChart, indicator, sectors, firstSector, secondSector, thirdSector, fourthSector;
|
|
157
|
+
return __generator(this, function (_a) {
|
|
158
|
+
rerender = setUp(__assign(__assign({}, defaultProps), { width: 0, height: 0 })).rerender;
|
|
159
|
+
text = react_2.screen.getByTestId('gauge-chart-text');
|
|
160
|
+
Object.defineProperty((0, react_2.within)(text).getByText('Label'), 'clientHeight', { configurable: true, value: 6 });
|
|
161
|
+
rerender(defaultProps);
|
|
162
|
+
gaugeChart = react_2.screen.getByTestId('gauge-chart');
|
|
163
|
+
indicator = react_2.screen.getByTestId('gauge-chart-indicator');
|
|
164
|
+
sectors = gaugeChart.querySelectorAll('.recharts-pie-sector');
|
|
165
|
+
firstSector = sectors[0].querySelector('.recharts-sector');
|
|
166
|
+
expect(firstSector).toHaveAttribute('cx', '200');
|
|
167
|
+
expect(firstSector).toHaveAttribute('cy', '250');
|
|
168
|
+
expect(removeExtraSpaces(firstSector.getAttribute('d'))).toBe('M 0,249.99999999999997 A 200,200,0, 0,1, 82.4429495415054,88.19660112501052 L 105.95435963320432,120.55728090000841 A 160,160,0, 0,0, 40,249.99999999999997 Z');
|
|
169
|
+
secondSector = sectors[1].querySelector('.recharts-sector');
|
|
170
|
+
expect(secondSector).toHaveAttribute('cx', '200');
|
|
171
|
+
expect(secondSector).toHaveAttribute('cy', '250');
|
|
172
|
+
expect(removeExtraSpaces(secondSector.getAttribute('d'))).toBe('M 82.4429495415054,88.19660112501052 A 200,200,0, 0,1, 317.55705045849464,88.19660112501052 L 294.04564036679574,120.55728090000841 A 160,160,0, 0,0, 105.95435963320432,120.55728090000841 Z');
|
|
173
|
+
thirdSector = sectors[2].querySelector('.recharts-sector');
|
|
174
|
+
expect(thirdSector).toHaveAttribute('cx', '200');
|
|
175
|
+
expect(thirdSector).toHaveAttribute('cy', '250');
|
|
176
|
+
expect(removeExtraSpaces(thirdSector.getAttribute('d'))).toBe('M 317.55705045849464,88.19660112501052 A 200,200,0, 0,1, 390.21130325903073,188.19660112501052 L 352.1690426072246,200.5572809000084 A 160,160,0, 0,0, 294.04564036679574,120.55728090000841 Z');
|
|
177
|
+
fourthSector = sectors[3].querySelector('.recharts-sector');
|
|
178
|
+
expect(fourthSector).toHaveAttribute('cx', '200');
|
|
179
|
+
expect(fourthSector).toHaveAttribute('cy', '250');
|
|
180
|
+
expect(removeExtraSpaces(fourthSector.getAttribute('d'))).toBe('M 390.21130325903073,188.19660112501052 A 200,200,0, 0,1, 400,250 L 360,250 A 160,160,0, 0,0, 352.1690426072246,200.5572809000084 Z');
|
|
181
|
+
expect(indicator).toHaveAttribute('d', 'M198 98L202 98 L200 36 L198 98');
|
|
182
|
+
expect(text).toHaveStyle({ top: '30%', bottom: 'calc(16.666666666666664% - -10px)', left: '10%', right: '10%' });
|
|
183
|
+
return [2 /*return*/];
|
|
184
|
+
});
|
|
185
|
+
}); });
|
|
186
|
+
it('should render custom label correctly', function () {
|
|
187
|
+
var props = __assign(__assign({}, defaultProps), { value: 78.4, renderValue: function (value) { return react_1.default.createElement("span", { "data-reltio-id": "custom-label" },
|
|
188
|
+
Math.round(value),
|
|
189
|
+
"%"); } });
|
|
190
|
+
setUp(props);
|
|
191
|
+
expect(react_2.screen.getByTestId('custom-label')).toHaveTextContent('78%');
|
|
192
|
+
});
|
|
193
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const MAX_RADIUS = 200;
|
|
2
|
+
export declare const RADIAN: number;
|
|
3
|
+
export declare const ARC_WIDTH_AS_PERCENTAGES = 0.2;
|
|
4
|
+
export declare const BOTTOM_INDICATOR_HEIGHT_AS_PERCENTAGES = 0.04;
|
|
5
|
+
export declare const TOP_INDICATOR_HEIGHT_AS_PERCENTAGES = 0.07;
|
|
6
|
+
export declare const INDICATOR_WIDTH_AS_PERCENTAGES = 0.01;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.INDICATOR_WIDTH_AS_PERCENTAGES = exports.TOP_INDICATOR_HEIGHT_AS_PERCENTAGES = exports.BOTTOM_INDICATOR_HEIGHT_AS_PERCENTAGES = exports.ARC_WIDTH_AS_PERCENTAGES = exports.RADIAN = exports.MAX_RADIUS = void 0;
|
|
4
|
+
exports.MAX_RADIUS = 200;
|
|
5
|
+
exports.RADIAN = Math.PI / 180;
|
|
6
|
+
exports.ARC_WIDTH_AS_PERCENTAGES = 0.2;
|
|
7
|
+
exports.BOTTOM_INDICATOR_HEIGHT_AS_PERCENTAGES = 0.04;
|
|
8
|
+
exports.TOP_INDICATOR_HEIGHT_AS_PERCENTAGES = 0.07;
|
|
9
|
+
exports.INDICATOR_WIDTH_AS_PERCENTAGES = 0.01;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getGaugeIndicatorCoords = void 0;
|
|
4
|
+
var constants_1 = require("./constants");
|
|
5
|
+
var getGaugeIndicatorCoords = function (value, data, cx, cy, oR, iR) {
|
|
6
|
+
var total = data.reduce(function (sum, _a) {
|
|
7
|
+
var value = _a.value;
|
|
8
|
+
return sum + value;
|
|
9
|
+
}, 0);
|
|
10
|
+
var angle = 180.0 * (1 - value / total);
|
|
11
|
+
var width = constants_1.INDICATOR_WIDTH_AS_PERCENTAGES * oR;
|
|
12
|
+
var sin = Math.sin(-constants_1.RADIAN * angle);
|
|
13
|
+
var cos = Math.cos(-constants_1.RADIAN * angle);
|
|
14
|
+
var x1 = cx + (iR - constants_1.BOTTOM_INDICATOR_HEIGHT_AS_PERCENTAGES * oR) * cos + width * sin;
|
|
15
|
+
var y1 = cy + (iR - constants_1.BOTTOM_INDICATOR_HEIGHT_AS_PERCENTAGES * oR) * sin - width * cos;
|
|
16
|
+
var x2 = cx + (iR - constants_1.BOTTOM_INDICATOR_HEIGHT_AS_PERCENTAGES * oR) * cos - width * sin;
|
|
17
|
+
var y2 = cy + (iR - constants_1.BOTTOM_INDICATOR_HEIGHT_AS_PERCENTAGES * oR) * sin + width * cos;
|
|
18
|
+
var x3 = cx + (oR + constants_1.TOP_INDICATOR_HEIGHT_AS_PERCENTAGES * oR) * cos;
|
|
19
|
+
var y3 = cy + (oR + constants_1.TOP_INDICATOR_HEIGHT_AS_PERCENTAGES * oR) * sin;
|
|
20
|
+
return { x1: x1, y1: y1, x2: x2, y2: y2, x3: x3, y3: y3 };
|
|
21
|
+
};
|
|
22
|
+
exports.getGaugeIndicatorCoords = getGaugeIndicatorCoords;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var helpers_1 = require("./helpers");
|
|
4
|
+
describe('gauge chart helpers behaviour', function () {
|
|
5
|
+
it('should calc gauge indicator coordinates correctly', function () {
|
|
6
|
+
expect((0, helpers_1.getGaugeIndicatorCoords)(75, [
|
|
7
|
+
{ color: 'rgba(241, 35, 35, 1)', value: 30 },
|
|
8
|
+
{ color: 'rgba(255, 109, 26, 1)', value: 40 },
|
|
9
|
+
{ color: 'rgba(255, 238, 54, 1)', value: 20 },
|
|
10
|
+
{ color: 'rgba(147, 244, 87, 1)', value: 10 }
|
|
11
|
+
], 200, 250, 200, 180)).toEqual({
|
|
12
|
+
x1: 320.2081528017131,
|
|
13
|
+
x2: 323.0365799264593,
|
|
14
|
+
x3: 351.32085117392114,
|
|
15
|
+
y1: 126.96342007354075,
|
|
16
|
+
y2: 129.79184719828694,
|
|
17
|
+
y3: 98.67914882607883
|
|
18
|
+
});
|
|
19
|
+
expect((0, helpers_1.getGaugeIndicatorCoords)(30, [
|
|
20
|
+
{ color: 'rgba(241, 35, 35, 1)', value: 50 },
|
|
21
|
+
{ color: 'rgba(255, 109, 26, 1)', value: 50 }
|
|
22
|
+
], 300, 360, 120, 130)).toEqual({
|
|
23
|
+
x1: 225.43846601973246,
|
|
24
|
+
x2: 227.38010680623233,
|
|
25
|
+
x3: 224.52837360564646,
|
|
26
|
+
y1: 259.41641460700754,
|
|
27
|
+
y2: 258.0057300015056,
|
|
28
|
+
y3: 256.1222179222567
|
|
29
|
+
});
|
|
30
|
+
expect((0, helpers_1.getGaugeIndicatorCoords)(30, [
|
|
31
|
+
{ color: 'rgba(241, 35, 35, 1)', value: 40 },
|
|
32
|
+
{ color: 'rgba(255, 109, 26, 1)', value: 50 },
|
|
33
|
+
{ color: 'rgba(147, 244, 87, 1)', value: 70 }
|
|
34
|
+
], 200, 200, 180, 150)).toEqual({
|
|
35
|
+
x1: 80.26611294376123,
|
|
36
|
+
x2: 82.2661657826318,
|
|
37
|
+
x3: 39.85895267052976,
|
|
38
|
+
y1: 122.16121602694538,
|
|
39
|
+
y2: 119.16792542265621,
|
|
40
|
+
y3: 92.99717312042462
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { GaugeChart } from './GaugeChart';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GaugeChart = void 0;
|
|
4
|
+
var GaugeChart_1 = require("./GaugeChart");
|
|
5
|
+
Object.defineProperty(exports, "GaugeChart", { enumerable: true, get: function () { return GaugeChart_1.GaugeChart; } });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"text" | "value" | "label" | "root" | "pie" | "indicator">;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useStyles = void 0;
|
|
4
|
+
var styles_1 = require("@mui/styles");
|
|
5
|
+
exports.useStyles = (0, styles_1.makeStyles)(function (theme) { return ({
|
|
6
|
+
root: {
|
|
7
|
+
position: 'relative',
|
|
8
|
+
display: 'flex'
|
|
9
|
+
},
|
|
10
|
+
pie: {
|
|
11
|
+
'& .recharts-sector:focus': {
|
|
12
|
+
outline: 'none'
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
text: {
|
|
16
|
+
position: 'absolute',
|
|
17
|
+
display: 'flex',
|
|
18
|
+
flexDirection: 'column',
|
|
19
|
+
alignItems: 'center',
|
|
20
|
+
justifyContent: 'flex-end',
|
|
21
|
+
padding: '0 10px',
|
|
22
|
+
transition: 'opacity 0.5s',
|
|
23
|
+
textAlign: 'center'
|
|
24
|
+
},
|
|
25
|
+
indicator: {
|
|
26
|
+
fill: 'rgb(0, 0, 102)',
|
|
27
|
+
stroke: 'none',
|
|
28
|
+
transition: 'opacity 0.5s'
|
|
29
|
+
},
|
|
30
|
+
value: {
|
|
31
|
+
marginBottom: '2px',
|
|
32
|
+
fontSize: '28px',
|
|
33
|
+
lineHeight: '33px',
|
|
34
|
+
fontWeight: 400,
|
|
35
|
+
color: theme.palette.text.primary
|
|
36
|
+
},
|
|
37
|
+
label: {
|
|
38
|
+
width: '100%',
|
|
39
|
+
fontSize: '14px',
|
|
40
|
+
lineHeight: '16px',
|
|
41
|
+
fontWeight: 400,
|
|
42
|
+
color: theme.palette.text.secondary
|
|
43
|
+
}
|
|
44
|
+
}); });
|
package/cjs/index.d.ts
CHANGED
|
@@ -172,6 +172,7 @@ export { LightArrowTooltip } from './LightArrowTooltip';
|
|
|
172
172
|
export { Marginator } from './Marginator';
|
|
173
173
|
export { ReltioMap } from './ReltioMap';
|
|
174
174
|
export { RelationEditor } from './RelationEditor';
|
|
175
|
+
export { GaugeChart } from './GaugeChart';
|
|
175
176
|
export { withTooltip } from './HOCs/withTooltip';
|
|
176
177
|
export { withAsyncMount } from './HOCs/withAsyncMount';
|
|
177
178
|
export { withDragHandle } from './HOCs/withDragHandle';
|
package/cjs/index.js
CHANGED
|
@@ -17,10 +17,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
exports.PieChart = exports.OvIcon = exports.NestedAttributeEditor = exports.NestedAttribute = exports.MoreAttributesButton = exports.InlineReferenceAttribute = exports.InlineNestedAttribute = exports.InlineImageAttribute = exports.InlineAttributesPager = exports.EditableImageAttributesLine = exports.FilterButton = exports.FacetViewHeader = exports.ExpandedValueTooltip = exports.EntitySelector = exports.EntityCreator = exports.AttributesPager = exports.AttributesList = exports.EditableAttribute = exports.DropDownMenuButton = exports.DescriptionIcon = exports.DefaultCellValueRenderer = exports.ControlAttributeIcon = exports.ColumnsSettingsPopup = exports.ColumnsSettings = exports.ColorBar = exports.CollapseRowButton = exports.ChartsFactory = exports.CardinalityMessage = exports.BranchDecorator = exports.BasicViewHeader = exports.BasicViewContent = exports.BasicView = exports.BasicTablePagination = exports.basicTableViewState = exports.BasicTable = exports.BasicAttributeSelector = exports.BarChart = exports.AvatarWithFallback = exports.AutoSizeList = exports.AttributesView = exports.AttributesValuesEditor = exports.AttributesFiltersButton = exports.AttributesFiltersBuilder = exports.AttributesFilterSelector = exports.AttributesErrorsPanel = exports.AttributeListItem = exports.AttributeGroupIcon = exports.ArrowExpandButton = exports.ActionsPanel = exports.ActionButton = void 0;
|
|
18
18
|
exports.ErrorMessage = exports.ConfigureColumnsPopup = exports.ConnectionEditor = exports.DropDownSelector = exports.ReactSelectOptionWithCheckIcon = exports.ReactSelectMenuWithPopper = exports.ReactSelectMenuList = exports.ReactSelectLoadMoreButton = exports.ReactSelectDropdownIndicatorWithIconButton = exports.ReactSelectDropdownIndicator = exports.Highlighter = exports.HierarchyNodeTitle = exports.HierarchicalAttributeTooltip = exports.HideOnShrink = exports.ExpandableSearchInput = exports.ErrorPopup = exports.ErrorBoundary = exports.EntityUriLink = exports.EntityTypesSelector = exports.EntityTypeIcon = exports.EntityTypeBadge = exports.EntityAvatar = exports.EMPTY_STATE_VARIANTS = exports.EMPTY_STATE_ICONS = exports.EmptyState = exports.Drawer = exports.DataTypeValue = exports.DataTenantBadge = exports.ConnectionRelationTypeSelector = exports.CollaborationItem = exports.ConfirmationDialog = exports.CommentsContainer = exports.ColoredSourceIcon = exports.CollapseButton = exports.TreeChart = exports.TableWithBars = exports.SourceIcon = exports.SmallIconButtonWithTooltip = exports.SmallIconButton = exports.SimpleAttributeEditor = exports.SimpleAttribute = exports.RowCellAutoSizer = exports.RelationTypeSelector = exports.ReferenceAttributeEditor = exports.ReferenceAttribute = exports.ImageAttributesLine = exports.ReadOnlyAttributesPager = exports.ReadOnlyAttributesList = exports.ReadOnlyAttribute = exports.ReadOnlyAttributeValuesBlock = void 0;
|
|
19
19
|
exports.PotentialMatchReviewCard = exports.PopupWithArrow = exports.Popper = exports.MultipleInput = exports.ModeSwitcherSelect = exports.ModeSwitcher = exports.TransitiveMatchBlock = exports.SimpleMatchRulesBuilder = exports.SimpleMatchRulesBlock = exports.SimpleMatchRules = exports.MatchRulesBlock = exports.LoadingSpinner = exports.Link = exports.LinearLoadIndicator = exports.ImportButton = exports.ReadableSearchQuery = exports.LogicOperator = exports.TableSkeleton = exports.StepNavigation = exports.TenantLabel = exports.RelevanceScoreBadge = exports.RequiredMark = exports.SettingsMenu = exports.TenantsDropDownSelector = exports.TenantIcon = exports.SourceSystemsSelector = exports.MatchRulesSelector = exports.MultiValueSelector = exports.ProfilesList = exports.NotMatchButton = exports.MergeButton = exports.ProfileMatchCard = exports.ImageGalleryDialog = exports.RelationTypesSelector = exports.ScreenProfileBand = exports.ProfileBandNavigation = exports.EmptyStub = exports.SaveSegmentDialog = exports.MaskingSwitcher = exports.FileTypeEditor = exports.EmptySearchResult = exports.DropDownEditor = exports.FilterValueEditor = exports.MultiValueChip = exports.TextEditor = exports.DateRangeEditor = exports.NumberEditor = exports.DataTypeValueEditor = exports.DateEditor = exports.ErrorWrapper = void 0;
|
|
20
|
-
exports.
|
|
21
|
-
exports.
|
|
22
|
-
exports.
|
|
23
|
-
exports.FakeMouseEvent = exports.rerenderWrapper = exports.mockElementSizes = exports.fixClicksOnResizablePanes = exports.mockBasicTableSizing = exports.getMuiIconsByName = exports.getMuiIconByName = exports.delayPromise = exports.deepFreeze = exports.awaitMockPromises = exports.TestStylesProvider = void 0;
|
|
20
|
+
exports.PerspectivesSettingsContext = exports.PivotingAttributeContext = exports.UsersContext = exports.InitialCollaborationContextValue = exports.CollaborationContextProvider = exports.CollaborationContext = exports.BlockImageGalleryDialogContext = exports.PopupBoundariesContext = exports.HistoryDiffContext = exports.AsyncMountContext = exports.MdmModuleProvider = exports.withTableContext = exports.withFilterAtBottom = exports.withPercents = exports.withContext = exports.withDateRangeSelector = exports.withDragHandle = exports.withAsyncMount = exports.withTooltip = exports.GaugeChart = exports.RelationEditor = exports.ReltioMap = exports.Marginator = exports.LightArrowTooltip = exports.ScrollableTabs = exports.VirtualGroupedList = exports.ViewMoreToggle = exports.VerticalHeadingsTable = exports.VerticalDivider = exports.AttributeTitle = exports.Spacer = exports.SimpleDropDownSelector = exports.SidePanelContentHeader = exports.SidePanel = exports.SidePanelEmptyState = exports.SideButtonsPanel = exports.SelectorWithOnlyOptionAutoSelect = exports.SelectionPopup = exports.WhiteSearchInput = exports.SearchInput = exports.ProfileResizablePanes = exports.ResizablePanes = exports.ReltioGridLayout = exports.reactSortableTreeHelpers = exports.ReactSortableTree = exports.MultiSelect = exports.QueryBuilderRowsGroup = exports.QueryBuilderRow = exports.ProfileCard = exports.ProfileBand = void 0;
|
|
21
|
+
exports.BasicTableContext = exports.BasicTableRowCollapseContext = exports.useUnmaskedAttributeValue = exports.useUnmaskAttributeValue = exports.useMaskAttributeValue = exports.MaskedAttributesProvider = exports.SegmentationContext = exports.useReloadData = exports.ReloadDataProvider = exports.useAttributeValueConfigPermissions = exports.ConfigPermissionsContextProvider = exports.ConfigPermissionsContext = exports.useActionsHook = exports.ActionsHookProvider = exports.PageRequestsAbortingContext = exports.DependentLookupAutopopulationContext = exports.FeaturesContext = exports.LabelsContext = exports.UrlGeneratorsContext = exports.isHighlightedAttributeType = exports.isHighlightedErrorType = exports.ScrollType = exports.ScrollToElementProvider = exports.ScrollToElementContext = exports.SearchValueContext = exports.InterceptHandlersContext = exports.HighlightedValuesContext = exports.SnackbarContext = exports.SearchFiltersContext = exports.useReloadFacet = exports.ReloadFacetProvider = exports.useReloadAllFacets = exports.SandboxAPIContext = exports.EntityContext = exports.RelatedObjectUrisContext = exports.WorkflowTasksContext = exports.useEntityLoadingIndication = exports.EntityLoadingIndicationProvider = exports.EntityMarkerContext = exports.useAttributeExpanded = exports.ExpandedAttributesProvider = exports.useHighlightedCrosswalks = exports.useCrosswalkHighlight = exports.useCrosswalkFocus = exports.useCrosswalkColor = exports.CrosswalksDisplayProvider = exports.EntitiesMapContext = exports.IdContext = exports.ProfilePerspectiveViewContext = exports.usePerspectivesSettings = void 0;
|
|
22
|
+
exports.mergeClasses = exports.isControlOrCommandPressed = exports.getValue = exports.getChecked = exports.showErrorMessage = exports.showDefaultErrorMessage = exports.enrichDataWithPercents = exports.defaultRenderRowCell = exports.defaultGetRowCellHeight = exports.columnFilterToMdmFilter = exports.buildColumnsFilter = exports.useKeyboardNavigation = exports.useDynamicRowCellHeight = exports.useClickableStyle = exports.BasicTableCellRenderer = exports.useBasicTableCellRenderer = exports.useHiddenAttributes = exports.useSavedSearchesRequest = exports.useRequestDCRReview = exports.useAutoFocus = exports.useExpandInvalidRelations = exports.useLayoutResetter = exports.useIsMountedRef = exports.useSnackbar = exports.useSavedStateForEntityType = exports.useReadableSearchState = exports.useEditableConnection = exports.useCustomScripts = exports.useMarkAsNotMatchRequest = exports.useMergeAllRequest = exports.usePagingSimulator = exports.useMatchesLoader = exports.useConfigPermissions = exports.useWhyDidYouUpdate = exports.useUsers = exports.useSavedState = exports.useSafePromise = exports.useRunOnceAfterValueInitialization = exports.useRelationsLoader = exports.useRelationTypeSelector = exports.usePrevious = exports.useDidUpdateEffect = exports.useCommentsEntitiesMap = exports.useCollaboration = exports.useAsyncMount = exports.useAPI = exports.useActions = exports.useMatchesColumnsData = exports.useScrollToAttributeError = exports.HiddenAttributesContext = void 0;
|
|
23
|
+
exports.FakeMouseEvent = exports.rerenderWrapper = exports.mockElementSizes = exports.fixClicksOnResizablePanes = exports.mockBasicTableSizing = exports.getMuiIconsByName = exports.getMuiIconByName = exports.delayPromise = exports.deepFreeze = exports.awaitMockPromises = exports.TestStylesProvider = exports.TestPerspectivesSettingsProvider = void 0;
|
|
24
24
|
// components
|
|
25
25
|
var ActionButton_1 = require("./ActionButton");
|
|
26
26
|
Object.defineProperty(exports, "ActionButton", { enumerable: true, get: function () { return ActionButton_1.ActionButton; } });
|
|
@@ -376,6 +376,8 @@ var ReltioMap_1 = require("./ReltioMap");
|
|
|
376
376
|
Object.defineProperty(exports, "ReltioMap", { enumerable: true, get: function () { return ReltioMap_1.ReltioMap; } });
|
|
377
377
|
var RelationEditor_1 = require("./RelationEditor");
|
|
378
378
|
Object.defineProperty(exports, "RelationEditor", { enumerable: true, get: function () { return RelationEditor_1.RelationEditor; } });
|
|
379
|
+
var GaugeChart_1 = require("./GaugeChart");
|
|
380
|
+
Object.defineProperty(exports, "GaugeChart", { enumerable: true, get: function () { return GaugeChart_1.GaugeChart; } });
|
|
379
381
|
// HOCs
|
|
380
382
|
var withTooltip_1 = require("./HOCs/withTooltip");
|
|
381
383
|
Object.defineProperty(exports, "withTooltip", { enumerable: true, get: function () { return withTooltip_1.withTooltip; } });
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { GaugeItem } from './types';
|
|
3
|
+
type Props = {
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
data: GaugeItem[];
|
|
7
|
+
value: number;
|
|
8
|
+
label?: React.ReactNode;
|
|
9
|
+
renderValue?: (value: number) => React.ReactNode;
|
|
10
|
+
isAnimationActive?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare const GaugeChart: ({ width, height, data, value, label, renderValue, isAnimationActive }: Props) => JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
13
|
+
import { identity } from 'ramda';
|
|
14
|
+
import { PieChart, Pie, Cell } from 'recharts';
|
|
15
|
+
import Typography from '@mui/material/Typography';
|
|
16
|
+
import { getGaugeIndicatorCoords } from './helpers';
|
|
17
|
+
import { MAX_RADIUS, ARC_WIDTH_AS_PERCENTAGES, TOP_INDICATOR_HEIGHT_AS_PERCENTAGES } from './constants';
|
|
18
|
+
import { useStyles } from './styles';
|
|
19
|
+
export var GaugeChart = function (_a) {
|
|
20
|
+
var width = _a.width, height = _a.height, data = _a.data, value = _a.value, label = _a.label, _b = _a.renderValue, renderValue = _b === void 0 ? identity : _b, _c = _a.isAnimationActive, isAnimationActive = _c === void 0 ? true : _c;
|
|
21
|
+
var styles = useStyles();
|
|
22
|
+
var labelElRef = useRef();
|
|
23
|
+
var _d = useState(!isAnimationActive), animationIsEnd = _d[0], setAnimationIsEnd = _d[1];
|
|
24
|
+
var _e = useState({ bottom: 0, top: 0, left: 0, right: 0 }), margin = _e[0], setMargin = _e[1];
|
|
25
|
+
var _f = useState(0), textOffset = _f[0], setTextOffset = _f[1];
|
|
26
|
+
var widthWithoutMargin = width - margin.left - margin.right;
|
|
27
|
+
var heightWithoutMargin = height - margin.top - margin.bottom - (textOffset > 0 ? textOffset : 0);
|
|
28
|
+
var outerRadius = Math.min(widthWithoutMargin / 2, heightWithoutMargin, MAX_RADIUS);
|
|
29
|
+
var innerRadius = outerRadius - ARC_WIDTH_AS_PERCENTAGES * outerRadius;
|
|
30
|
+
var cx = widthWithoutMargin / 2 + margin.left;
|
|
31
|
+
var cy = heightWithoutMargin / 2 + outerRadius / 2 + margin.top;
|
|
32
|
+
var chartData = data.map(function (item, name) { return (__assign(__assign({}, item), { name: name })); });
|
|
33
|
+
var _g = getGaugeIndicatorCoords(value, chartData, cx, cy, outerRadius, innerRadius), x1 = _g.x1, y1 = _g.y1, x2 = _g.x2, y2 = _g.y2, x3 = _g.x3, y3 = _g.y3;
|
|
34
|
+
useEffect(function () {
|
|
35
|
+
var _a;
|
|
36
|
+
if (animationIsEnd) {
|
|
37
|
+
var clientHeight = ((_a = labelElRef === null || labelElRef === void 0 ? void 0 : labelElRef.current) !== null && _a !== void 0 ? _a : { clientHeight: 0 }).clientHeight;
|
|
38
|
+
var textOffset_1 = Math.ceil(clientHeight) - 16;
|
|
39
|
+
var verticalMargin_1 = Math.ceil(TOP_INDICATOR_HEIGHT_AS_PERCENTAGES * outerRadius);
|
|
40
|
+
setTextOffset(textOffset_1);
|
|
41
|
+
setMargin(function (prevMargin) { return (__assign(__assign({}, prevMargin), { bottom: verticalMargin_1, top: verticalMargin_1 })); });
|
|
42
|
+
}
|
|
43
|
+
}, [width, height, animationIsEnd]);
|
|
44
|
+
return (React.createElement("div", { "data-reltio-id": "gauge-chart", className: styles.root, style: { width: width, height: height } },
|
|
45
|
+
React.createElement(PieChart, { margin: { top: 0, bottom: 0, left: 0, right: 0 }, width: width, height: height },
|
|
46
|
+
React.createElement(Pie, { className: styles.pie, dataKey: "value", startAngle: 180, endAngle: 0, data: chartData, cx: cx, cy: cy, innerRadius: innerRadius, outerRadius: outerRadius, stroke: "none", isAnimationActive: isAnimationActive, onAnimationEnd: function () { return setAnimationIsEnd(true); } }, data.map(function (entry, idx) { return (React.createElement(Cell, { key: idx, fill: entry.color })); })),
|
|
47
|
+
React.createElement("path", { "data-reltio-id": "gauge-chart-indicator", className: styles.indicator, style: { opacity: animationIsEnd ? 1 : 0 }, d: "M".concat(x1, " ").concat(y1, "L").concat(x2, " ").concat(y2, " L").concat(x3, " ").concat(y3, " L").concat(x1, " ").concat(y1) })),
|
|
48
|
+
React.createElement("div", { "data-reltio-id": "gauge-chart-text", className: styles.text, style: {
|
|
49
|
+
top: "".concat(((cy - innerRadius) / height) * 100, "%"),
|
|
50
|
+
bottom: "calc(".concat(((height - cy) / height) * 100, "% - ").concat(textOffset, "px)"),
|
|
51
|
+
left: "".concat(((width - innerRadius * 2) / width / 2) * 100, "%"),
|
|
52
|
+
right: "".concat(((width - innerRadius * 2) / width / 2) * 100, "%"),
|
|
53
|
+
opacity: animationIsEnd ? 1 : 0
|
|
54
|
+
} },
|
|
55
|
+
React.createElement(Typography, { className: styles.value }, renderValue(value)),
|
|
56
|
+
label && (React.createElement("div", { ref: labelElRef, className: styles.label }, label)))));
|
|
57
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
23
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
+
function step(op) {
|
|
26
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
+
switch (op[0]) {
|
|
31
|
+
case 0: case 1: t = op; break;
|
|
32
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
+
default:
|
|
36
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
+
if (t[2]) _.ops.pop();
|
|
41
|
+
_.trys.pop(); continue;
|
|
42
|
+
}
|
|
43
|
+
op = body.call(thisArg, _);
|
|
44
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
import React from 'react';
|
|
49
|
+
import { render, screen, within } from '@testing-library/react';
|
|
50
|
+
import { GaugeChart } from './GaugeChart';
|
|
51
|
+
var defaultProps = {
|
|
52
|
+
width: 400,
|
|
53
|
+
height: 300,
|
|
54
|
+
data: [
|
|
55
|
+
{ color: 'rgba(241, 35, 35, 1)', value: 30 },
|
|
56
|
+
{ color: 'rgba(255, 109, 26, 1)', value: 40 },
|
|
57
|
+
{ color: 'rgba(255, 238, 54, 1)', value: 20 },
|
|
58
|
+
{ color: 'rgba(147, 244, 87, 1)', value: 10 }
|
|
59
|
+
],
|
|
60
|
+
value: 50,
|
|
61
|
+
label: 'Label',
|
|
62
|
+
isAnimationActive: false
|
|
63
|
+
};
|
|
64
|
+
var removeExtraSpaces = function (str) { return str.replace(/\s{2,}/g, ' '); };
|
|
65
|
+
var setUp = function (props) {
|
|
66
|
+
if (props === void 0) { props = defaultProps; }
|
|
67
|
+
var result = render(React.createElement(GaugeChart, __assign({}, props)));
|
|
68
|
+
return __assign(__assign({}, result), { rerender: function (newProps) { return result.rerender(React.createElement(GaugeChart, __assign({}, props, newProps))); } });
|
|
69
|
+
};
|
|
70
|
+
describe('Gauge chart behaviour', function () {
|
|
71
|
+
it('should render chart correctly in basic scenario', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
72
|
+
var rerender, text, gaugeChart, pieChart, pie, sectors, indicator, firstSector, secondSector, thirdSector, fourthSector;
|
|
73
|
+
return __generator(this, function (_a) {
|
|
74
|
+
rerender = setUp(__assign(__assign({}, defaultProps), { width: 0, height: 0 })).rerender;
|
|
75
|
+
text = screen.getByTestId('gauge-chart-text');
|
|
76
|
+
Object.defineProperty(within(text).getByText('Label'), 'clientHeight', { configurable: true, value: 16 });
|
|
77
|
+
rerender(defaultProps);
|
|
78
|
+
gaugeChart = screen.getByTestId('gauge-chart');
|
|
79
|
+
pieChart = gaugeChart.querySelector('.recharts-wrapper');
|
|
80
|
+
expect(gaugeChart).toHaveStyle({ width: '400px', height: '300px' });
|
|
81
|
+
expect(pieChart).toHaveStyle({ width: '400px', height: '300px' });
|
|
82
|
+
pie = gaugeChart.querySelector('.recharts-surface');
|
|
83
|
+
expect(pie).toHaveStyle({ width: '100%', height: '100%' });
|
|
84
|
+
expect(pie).toHaveAttribute('width', '400');
|
|
85
|
+
expect(pie).toHaveAttribute('height', '300');
|
|
86
|
+
expect(pie).toHaveAttribute('cx', '50%');
|
|
87
|
+
expect(pie).toHaveAttribute('cy', '50%');
|
|
88
|
+
sectors = gaugeChart.querySelectorAll('.recharts-pie-sector');
|
|
89
|
+
indicator = screen.getByTestId('gauge-chart-indicator');
|
|
90
|
+
expect(sectors).toHaveLength(4);
|
|
91
|
+
firstSector = sectors[0].querySelector('.recharts-sector');
|
|
92
|
+
expect(firstSector).toHaveAttribute('fill', 'rgba(241, 35, 35, 1)');
|
|
93
|
+
expect(firstSector).toHaveAttribute('cx', '200');
|
|
94
|
+
expect(firstSector).toHaveAttribute('cy', '250');
|
|
95
|
+
expect(removeExtraSpaces(firstSector.getAttribute('d'))).toBe('M 0,249.99999999999997 A 200,200,0, 0,1, 82.4429495415054,88.19660112501052 L 105.95435963320432,120.55728090000841 A 160,160,0, 0,0, 40,249.99999999999997 Z');
|
|
96
|
+
secondSector = sectors[1].querySelector('.recharts-sector');
|
|
97
|
+
expect(secondSector).toHaveAttribute('fill', 'rgba(255, 109, 26, 1)');
|
|
98
|
+
expect(secondSector).toHaveAttribute('cx', '200');
|
|
99
|
+
expect(secondSector).toHaveAttribute('cy', '250');
|
|
100
|
+
expect(removeExtraSpaces(secondSector.getAttribute('d'))).toBe('M 82.4429495415054,88.19660112501052 A 200,200,0, 0,1, 317.55705045849464,88.19660112501052 L 294.04564036679574,120.55728090000841 A 160,160,0, 0,0, 105.95435963320432,120.55728090000841 Z');
|
|
101
|
+
thirdSector = sectors[2].querySelector('.recharts-sector');
|
|
102
|
+
expect(thirdSector).toHaveAttribute('fill', 'rgba(255, 238, 54, 1)');
|
|
103
|
+
expect(thirdSector).toHaveAttribute('cx', '200');
|
|
104
|
+
expect(thirdSector).toHaveAttribute('cy', '250');
|
|
105
|
+
expect(removeExtraSpaces(thirdSector.getAttribute('d'))).toBe('M 317.55705045849464,88.19660112501052 A 200,200,0, 0,1, 390.21130325903073,188.19660112501052 L 352.1690426072246,200.5572809000084 A 160,160,0, 0,0, 294.04564036679574,120.55728090000841 Z');
|
|
106
|
+
fourthSector = sectors[3].querySelector('.recharts-sector');
|
|
107
|
+
expect(fourthSector).toHaveAttribute('fill', 'rgba(147, 244, 87, 1)');
|
|
108
|
+
expect(fourthSector).toHaveAttribute('cx', '200');
|
|
109
|
+
expect(fourthSector).toHaveAttribute('cy', '250');
|
|
110
|
+
expect(removeExtraSpaces(fourthSector.getAttribute('d'))).toBe('M 390.21130325903073,188.19660112501052 A 200,200,0, 0,1, 400,250 L 360,250 A 160,160,0, 0,0, 352.1690426072246,200.5572809000084 Z');
|
|
111
|
+
expect(indicator).toHaveStyle({ opacity: 1 });
|
|
112
|
+
expect(indicator).toHaveAttribute('d', 'M198 98L202 98 L200 36 L198 98');
|
|
113
|
+
expect(text).toHaveStyle({ top: '30%', bottom: 'calc(16.666666666666664% - 0px)', left: '10%', right: '10%' });
|
|
114
|
+
within(text).getByText('50');
|
|
115
|
+
within(text).getByText('Label');
|
|
116
|
+
return [2 /*return*/];
|
|
117
|
+
});
|
|
118
|
+
}); });
|
|
119
|
+
it('should render chart correctly if the label height is more than 16 pixels', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
120
|
+
var rerender, text, gaugeChart, indicator, sectors, firstSector, secondSector, thirdSector, fourthSector;
|
|
121
|
+
return __generator(this, function (_a) {
|
|
122
|
+
rerender = setUp(__assign(__assign({}, defaultProps), { width: 0, height: 0 })).rerender;
|
|
123
|
+
text = screen.getByTestId('gauge-chart-text');
|
|
124
|
+
Object.defineProperty(within(text).getByText('Label'), 'clientHeight', { configurable: true, value: 48 });
|
|
125
|
+
rerender(defaultProps);
|
|
126
|
+
gaugeChart = screen.getByTestId('gauge-chart');
|
|
127
|
+
indicator = screen.getByTestId('gauge-chart-indicator');
|
|
128
|
+
sectors = gaugeChart.querySelectorAll('.recharts-pie-sector');
|
|
129
|
+
firstSector = sectors[0].querySelector('.recharts-sector');
|
|
130
|
+
expect(firstSector).toHaveAttribute('cx', '200');
|
|
131
|
+
expect(firstSector).toHaveAttribute('cy', '234');
|
|
132
|
+
expect(removeExtraSpaces(firstSector.getAttribute('d'))).toBe('M 0,233.99999999999997 A 200,200,0, 0,1, 82.4429495415054,72.19660112501052 L 105.95435963320432,104.55728090000841 A 160,160,0, 0,0, 40,233.99999999999997 Z');
|
|
133
|
+
secondSector = sectors[1].querySelector('.recharts-sector');
|
|
134
|
+
expect(secondSector).toHaveAttribute('cx', '200');
|
|
135
|
+
expect(secondSector).toHaveAttribute('cy', '234');
|
|
136
|
+
expect(removeExtraSpaces(secondSector.getAttribute('d'))).toBe('M 82.4429495415054,72.19660112501052 A 200,200,0, 0,1, 317.55705045849464,72.19660112501052 L 294.04564036679574,104.55728090000841 A 160,160,0, 0,0, 105.95435963320432,104.55728090000841 Z');
|
|
137
|
+
thirdSector = sectors[2].querySelector('.recharts-sector');
|
|
138
|
+
expect(thirdSector).toHaveAttribute('cx', '200');
|
|
139
|
+
expect(thirdSector).toHaveAttribute('cy', '234');
|
|
140
|
+
expect(removeExtraSpaces(thirdSector.getAttribute('d'))).toBe('M 317.55705045849464,72.19660112501052 A 200,200,0, 0,1, 390.21130325903073,172.19660112501052 L 352.1690426072246,184.5572809000084 A 160,160,0, 0,0, 294.04564036679574,104.55728090000841 Z');
|
|
141
|
+
fourthSector = sectors[3].querySelector('.recharts-sector');
|
|
142
|
+
expect(fourthSector).toHaveAttribute('cx', '200');
|
|
143
|
+
expect(fourthSector).toHaveAttribute('cy', '234');
|
|
144
|
+
expect(removeExtraSpaces(fourthSector.getAttribute('d'))).toBe('M 390.21130325903073,172.19660112501052 A 200,200,0, 0,1, 400,234 L 360,234 A 160,160,0, 0,0, 352.1690426072246,184.5572809000084 Z');
|
|
145
|
+
expect(indicator).toHaveAttribute('d', 'M198 82L202 82 L200 20 L198 82');
|
|
146
|
+
expect(text).toHaveStyle({ top: '24.666666666666668%', bottom: 'calc(22% - 32px)', left: '10%', right: '10%' });
|
|
147
|
+
return [2 /*return*/];
|
|
148
|
+
});
|
|
149
|
+
}); });
|
|
150
|
+
it('should render chart correctly if the label height is less than 16 pixels', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
151
|
+
var rerender, text, gaugeChart, indicator, sectors, firstSector, secondSector, thirdSector, fourthSector;
|
|
152
|
+
return __generator(this, function (_a) {
|
|
153
|
+
rerender = setUp(__assign(__assign({}, defaultProps), { width: 0, height: 0 })).rerender;
|
|
154
|
+
text = screen.getByTestId('gauge-chart-text');
|
|
155
|
+
Object.defineProperty(within(text).getByText('Label'), 'clientHeight', { configurable: true, value: 6 });
|
|
156
|
+
rerender(defaultProps);
|
|
157
|
+
gaugeChart = screen.getByTestId('gauge-chart');
|
|
158
|
+
indicator = screen.getByTestId('gauge-chart-indicator');
|
|
159
|
+
sectors = gaugeChart.querySelectorAll('.recharts-pie-sector');
|
|
160
|
+
firstSector = sectors[0].querySelector('.recharts-sector');
|
|
161
|
+
expect(firstSector).toHaveAttribute('cx', '200');
|
|
162
|
+
expect(firstSector).toHaveAttribute('cy', '250');
|
|
163
|
+
expect(removeExtraSpaces(firstSector.getAttribute('d'))).toBe('M 0,249.99999999999997 A 200,200,0, 0,1, 82.4429495415054,88.19660112501052 L 105.95435963320432,120.55728090000841 A 160,160,0, 0,0, 40,249.99999999999997 Z');
|
|
164
|
+
secondSector = sectors[1].querySelector('.recharts-sector');
|
|
165
|
+
expect(secondSector).toHaveAttribute('cx', '200');
|
|
166
|
+
expect(secondSector).toHaveAttribute('cy', '250');
|
|
167
|
+
expect(removeExtraSpaces(secondSector.getAttribute('d'))).toBe('M 82.4429495415054,88.19660112501052 A 200,200,0, 0,1, 317.55705045849464,88.19660112501052 L 294.04564036679574,120.55728090000841 A 160,160,0, 0,0, 105.95435963320432,120.55728090000841 Z');
|
|
168
|
+
thirdSector = sectors[2].querySelector('.recharts-sector');
|
|
169
|
+
expect(thirdSector).toHaveAttribute('cx', '200');
|
|
170
|
+
expect(thirdSector).toHaveAttribute('cy', '250');
|
|
171
|
+
expect(removeExtraSpaces(thirdSector.getAttribute('d'))).toBe('M 317.55705045849464,88.19660112501052 A 200,200,0, 0,1, 390.21130325903073,188.19660112501052 L 352.1690426072246,200.5572809000084 A 160,160,0, 0,0, 294.04564036679574,120.55728090000841 Z');
|
|
172
|
+
fourthSector = sectors[3].querySelector('.recharts-sector');
|
|
173
|
+
expect(fourthSector).toHaveAttribute('cx', '200');
|
|
174
|
+
expect(fourthSector).toHaveAttribute('cy', '250');
|
|
175
|
+
expect(removeExtraSpaces(fourthSector.getAttribute('d'))).toBe('M 390.21130325903073,188.19660112501052 A 200,200,0, 0,1, 400,250 L 360,250 A 160,160,0, 0,0, 352.1690426072246,200.5572809000084 Z');
|
|
176
|
+
expect(indicator).toHaveAttribute('d', 'M198 98L202 98 L200 36 L198 98');
|
|
177
|
+
expect(text).toHaveStyle({ top: '30%', bottom: 'calc(16.666666666666664% - -10px)', left: '10%', right: '10%' });
|
|
178
|
+
return [2 /*return*/];
|
|
179
|
+
});
|
|
180
|
+
}); });
|
|
181
|
+
it('should render custom label correctly', function () {
|
|
182
|
+
var props = __assign(__assign({}, defaultProps), { value: 78.4, renderValue: function (value) { return React.createElement("span", { "data-reltio-id": "custom-label" },
|
|
183
|
+
Math.round(value),
|
|
184
|
+
"%"); } });
|
|
185
|
+
setUp(props);
|
|
186
|
+
expect(screen.getByTestId('custom-label')).toHaveTextContent('78%');
|
|
187
|
+
});
|
|
188
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const MAX_RADIUS = 200;
|
|
2
|
+
export declare const RADIAN: number;
|
|
3
|
+
export declare const ARC_WIDTH_AS_PERCENTAGES = 0.2;
|
|
4
|
+
export declare const BOTTOM_INDICATOR_HEIGHT_AS_PERCENTAGES = 0.04;
|
|
5
|
+
export declare const TOP_INDICATOR_HEIGHT_AS_PERCENTAGES = 0.07;
|
|
6
|
+
export declare const INDICATOR_WIDTH_AS_PERCENTAGES = 0.01;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export var MAX_RADIUS = 200;
|
|
2
|
+
export var RADIAN = Math.PI / 180;
|
|
3
|
+
export var ARC_WIDTH_AS_PERCENTAGES = 0.2;
|
|
4
|
+
export var BOTTOM_INDICATOR_HEIGHT_AS_PERCENTAGES = 0.04;
|
|
5
|
+
export var TOP_INDICATOR_HEIGHT_AS_PERCENTAGES = 0.07;
|
|
6
|
+
export var INDICATOR_WIDTH_AS_PERCENTAGES = 0.01;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { RADIAN, BOTTOM_INDICATOR_HEIGHT_AS_PERCENTAGES, TOP_INDICATOR_HEIGHT_AS_PERCENTAGES, INDICATOR_WIDTH_AS_PERCENTAGES } from './constants';
|
|
2
|
+
export var getGaugeIndicatorCoords = function (value, data, cx, cy, oR, iR) {
|
|
3
|
+
var total = data.reduce(function (sum, _a) {
|
|
4
|
+
var value = _a.value;
|
|
5
|
+
return sum + value;
|
|
6
|
+
}, 0);
|
|
7
|
+
var angle = 180.0 * (1 - value / total);
|
|
8
|
+
var width = INDICATOR_WIDTH_AS_PERCENTAGES * oR;
|
|
9
|
+
var sin = Math.sin(-RADIAN * angle);
|
|
10
|
+
var cos = Math.cos(-RADIAN * angle);
|
|
11
|
+
var x1 = cx + (iR - BOTTOM_INDICATOR_HEIGHT_AS_PERCENTAGES * oR) * cos + width * sin;
|
|
12
|
+
var y1 = cy + (iR - BOTTOM_INDICATOR_HEIGHT_AS_PERCENTAGES * oR) * sin - width * cos;
|
|
13
|
+
var x2 = cx + (iR - BOTTOM_INDICATOR_HEIGHT_AS_PERCENTAGES * oR) * cos - width * sin;
|
|
14
|
+
var y2 = cy + (iR - BOTTOM_INDICATOR_HEIGHT_AS_PERCENTAGES * oR) * sin + width * cos;
|
|
15
|
+
var x3 = cx + (oR + TOP_INDICATOR_HEIGHT_AS_PERCENTAGES * oR) * cos;
|
|
16
|
+
var y3 = cy + (oR + TOP_INDICATOR_HEIGHT_AS_PERCENTAGES * oR) * sin;
|
|
17
|
+
return { x1: x1, y1: y1, x2: x2, y2: y2, x3: x3, y3: y3 };
|
|
18
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { getGaugeIndicatorCoords } from './helpers';
|
|
2
|
+
describe('gauge chart helpers behaviour', function () {
|
|
3
|
+
it('should calc gauge indicator coordinates correctly', function () {
|
|
4
|
+
expect(getGaugeIndicatorCoords(75, [
|
|
5
|
+
{ color: 'rgba(241, 35, 35, 1)', value: 30 },
|
|
6
|
+
{ color: 'rgba(255, 109, 26, 1)', value: 40 },
|
|
7
|
+
{ color: 'rgba(255, 238, 54, 1)', value: 20 },
|
|
8
|
+
{ color: 'rgba(147, 244, 87, 1)', value: 10 }
|
|
9
|
+
], 200, 250, 200, 180)).toEqual({
|
|
10
|
+
x1: 320.2081528017131,
|
|
11
|
+
x2: 323.0365799264593,
|
|
12
|
+
x3: 351.32085117392114,
|
|
13
|
+
y1: 126.96342007354075,
|
|
14
|
+
y2: 129.79184719828694,
|
|
15
|
+
y3: 98.67914882607883
|
|
16
|
+
});
|
|
17
|
+
expect(getGaugeIndicatorCoords(30, [
|
|
18
|
+
{ color: 'rgba(241, 35, 35, 1)', value: 50 },
|
|
19
|
+
{ color: 'rgba(255, 109, 26, 1)', value: 50 }
|
|
20
|
+
], 300, 360, 120, 130)).toEqual({
|
|
21
|
+
x1: 225.43846601973246,
|
|
22
|
+
x2: 227.38010680623233,
|
|
23
|
+
x3: 224.52837360564646,
|
|
24
|
+
y1: 259.41641460700754,
|
|
25
|
+
y2: 258.0057300015056,
|
|
26
|
+
y3: 256.1222179222567
|
|
27
|
+
});
|
|
28
|
+
expect(getGaugeIndicatorCoords(30, [
|
|
29
|
+
{ color: 'rgba(241, 35, 35, 1)', value: 40 },
|
|
30
|
+
{ color: 'rgba(255, 109, 26, 1)', value: 50 },
|
|
31
|
+
{ color: 'rgba(147, 244, 87, 1)', value: 70 }
|
|
32
|
+
], 200, 200, 180, 150)).toEqual({
|
|
33
|
+
x1: 80.26611294376123,
|
|
34
|
+
x2: 82.2661657826318,
|
|
35
|
+
x3: 39.85895267052976,
|
|
36
|
+
y1: 122.16121602694538,
|
|
37
|
+
y2: 119.16792542265621,
|
|
38
|
+
y3: 92.99717312042462
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { GaugeChart } from './GaugeChart';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { GaugeChart } from './GaugeChart';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"text" | "value" | "label" | "root" | "pie" | "indicator">;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { makeStyles } from '@mui/styles';
|
|
2
|
+
export var useStyles = makeStyles(function (theme) { return ({
|
|
3
|
+
root: {
|
|
4
|
+
position: 'relative',
|
|
5
|
+
display: 'flex'
|
|
6
|
+
},
|
|
7
|
+
pie: {
|
|
8
|
+
'& .recharts-sector:focus': {
|
|
9
|
+
outline: 'none'
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
text: {
|
|
13
|
+
position: 'absolute',
|
|
14
|
+
display: 'flex',
|
|
15
|
+
flexDirection: 'column',
|
|
16
|
+
alignItems: 'center',
|
|
17
|
+
justifyContent: 'flex-end',
|
|
18
|
+
padding: '0 10px',
|
|
19
|
+
transition: 'opacity 0.5s',
|
|
20
|
+
textAlign: 'center'
|
|
21
|
+
},
|
|
22
|
+
indicator: {
|
|
23
|
+
fill: 'rgb(0, 0, 102)',
|
|
24
|
+
stroke: 'none',
|
|
25
|
+
transition: 'opacity 0.5s'
|
|
26
|
+
},
|
|
27
|
+
value: {
|
|
28
|
+
marginBottom: '2px',
|
|
29
|
+
fontSize: '28px',
|
|
30
|
+
lineHeight: '33px',
|
|
31
|
+
fontWeight: 400,
|
|
32
|
+
color: theme.palette.text.primary
|
|
33
|
+
},
|
|
34
|
+
label: {
|
|
35
|
+
width: '100%',
|
|
36
|
+
fontSize: '14px',
|
|
37
|
+
lineHeight: '16px',
|
|
38
|
+
fontWeight: 400,
|
|
39
|
+
color: theme.palette.text.secondary
|
|
40
|
+
}
|
|
41
|
+
}); });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/esm/index.d.ts
CHANGED
|
@@ -172,6 +172,7 @@ export { LightArrowTooltip } from './LightArrowTooltip';
|
|
|
172
172
|
export { Marginator } from './Marginator';
|
|
173
173
|
export { ReltioMap } from './ReltioMap';
|
|
174
174
|
export { RelationEditor } from './RelationEditor';
|
|
175
|
+
export { GaugeChart } from './GaugeChart';
|
|
175
176
|
export { withTooltip } from './HOCs/withTooltip';
|
|
176
177
|
export { withAsyncMount } from './HOCs/withAsyncMount';
|
|
177
178
|
export { withDragHandle } from './HOCs/withDragHandle';
|
package/esm/index.js
CHANGED
|
@@ -173,6 +173,7 @@ export { LightArrowTooltip } from './LightArrowTooltip';
|
|
|
173
173
|
export { Marginator } from './Marginator';
|
|
174
174
|
export { ReltioMap } from './ReltioMap';
|
|
175
175
|
export { RelationEditor } from './RelationEditor';
|
|
176
|
+
export { GaugeChart } from './GaugeChart';
|
|
176
177
|
// HOCs
|
|
177
178
|
export { withTooltip } from './HOCs/withTooltip';
|
|
178
179
|
export { withAsyncMount } from './HOCs/withAsyncMount';
|