Skip to content

Commit 415c9e0

Browse files
gmuralidharreddycorteggiano
authored andcommitted
feat: guage component initail commit
1 parent 6dd4b15 commit 415c9e0

17 files changed

+893
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
export const DEFAULT_GAUGE_PROGRESS_COLOR = '#0173BC';
2+
export const DEFAULT_GAUGE_SETTINGS = {
3+
series: [
4+
{
5+
type: 'gauge',
6+
center: ['50%', '50%'], //center of the gauge
7+
radius: '90%', //radius of the gauge
8+
startAngle: 190, //start angle of the gauge in degrees
9+
endAngle: -10, //end angle of the gauge in degrees
10+
min: 0, //guage default start point
11+
max: 100, //gauge default end point
12+
silent: true, //control mouse hover actions
13+
axisTick: {
14+
show: false,
15+
},
16+
splitLine: {
17+
show: false,
18+
},
19+
axisLabel: {
20+
show: false,
21+
},
22+
axisLine: {
23+
/**
24+
* make axis line wider and default color in gray
25+
*/
26+
lineStyle: {
27+
width: 30,
28+
color: [[1, '#D5DBDB']],
29+
},
30+
},
31+
},
32+
{
33+
type: 'gauge',
34+
center: ['50%', '50%'], //center of the gauge progress bar
35+
radius: '90%', //radius of the gauge progress bar
36+
startAngle: 190, //start angle of the gauge in degrees progress bar
37+
endAngle: -10, //end angle of the gauge in degrees progress bar
38+
silent: true, //control mouse hover actions
39+
min: 0, //guage progress bar default start point
40+
max: 100, //gauge progress bar default end point
41+
itemStyle: {
42+
color: DEFAULT_GAUGE_PROGRESS_COLOR, // default color for gauge progress bar
43+
},
44+
progress: {
45+
show: true,
46+
width: 30, //gauge progress bar thickness
47+
},
48+
pointer: {
49+
show: false,
50+
},
51+
axisLine: {
52+
show: false,
53+
},
54+
axisTick: {
55+
show: false,
56+
},
57+
splitLine: {
58+
show: false,
59+
},
60+
axisLabel: {
61+
show: false,
62+
},
63+
detail: {
64+
/**
65+
* center value settings for color, position, animation, value font size & font weigth and unit size & font weight etc..
66+
*/
67+
valueAnimation: true, // show animation while value changes
68+
offsetCenter: [0, '-10%'], // position of the center value
69+
fontSize: 25, // font size of the center value in px
70+
fontWeight: '500', // font weight of the center value in px
71+
formatter: '{value}', // formatter of the center value
72+
color: 'inherit', // color of the center value
73+
rich: {
74+
value: {
75+
fontWeight: 'bolder', // font weight of the value
76+
},
77+
unit: {
78+
fontWeight: 'bolder', // font weight of the unit value
79+
padding: [0, 0, -15, -5],
80+
},
81+
},
82+
},
83+
title: {
84+
/**
85+
* title settings for the position, width, overflow and ellipsis
86+
*/
87+
show: false,
88+
offsetCenter: [0, 10],
89+
width: 300, // width of the title in px
90+
overflow: 'truncate',
91+
ellipsis: '...',
92+
},
93+
},
94+
],
95+
};
96+
export const DEFAULT_GAUGE_SETTINGS_WITH_THRESHOLDS = {
97+
series: [
98+
...DEFAULT_GAUGE_SETTINGS.series,
99+
{
100+
type: 'gauge',
101+
center: ['50%', '50%'], //center of the gauge outside the arc
102+
radius: '92%', //radius of the gauge outside the arc
103+
startAngle: 190, //start angle of the gauge in degrees
104+
endAngle: -10, //end angle of the gauge in degrees
105+
min: 0, //outside the arc default start point
106+
max: 100, //outside the arc default end point
107+
silent: true, //control mouse hover actions
108+
splitNumber: 10, //number of split lines in the outside the arc
109+
progress: {
110+
show: false,
111+
},
112+
pointer: {
113+
show: false,
114+
},
115+
axisTick: {
116+
show: false,
117+
},
118+
splitLine: {
119+
/**
120+
* make split line distance to oustside arc, length, wider, and default color in white
121+
*/
122+
distance: 0,
123+
length: 3,
124+
lineStyle: {
125+
width: 1,
126+
color: '#fff',
127+
},
128+
},
129+
axisLabel: {
130+
/**
131+
* make axis label distance to oustside arc, color and font size
132+
*/
133+
distance: -30,
134+
color: 'auto',
135+
fontSize: 10,
136+
},
137+
axisLine: {
138+
/**
139+
* outside arc axis line thickness
140+
*/
141+
lineStyle: {
142+
width: 3,
143+
},
144+
},
145+
anchor: {
146+
show: false,
147+
},
148+
detail: {
149+
/**
150+
* center value settings for color, position, animation, value font size, font weigth and unit size, font weight etc..
151+
*/
152+
valueAnimation: true, // show animation while value changes
153+
offsetCenter: [0, '-10%'], // position of the center value
154+
fontSize: 25, //font size of the center value
155+
fontWeight: '500', //font weight of the center value
156+
formatter: '{value}', //formatter for the center value
157+
color: 'inherit', //color of the center value
158+
rich: {
159+
value: {
160+
fontWeight: 'bolder', //font weight of the value
161+
},
162+
unit: {
163+
fontWeight: 'bolder', //font weight of the unit
164+
padding: [0, 0, -15, -5],
165+
},
166+
},
167+
},
168+
title: {
169+
show: false, //hide title for outside arc
170+
},
171+
},
172+
],
173+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// eslint-disable-next-line import/default
2+
import React from 'react';
3+
4+
import { GaugeBase } from './gaugeBase';
5+
import { GaugeProps } from './types';
6+
import { useTimeSeriesData } from '../../hooks/useTimeSeriesData';
7+
import { useViewport } from '../../hooks/useViewport';
8+
import { widgetPropertiesFromInputs } from '../../common/widgetPropertiesFromInputs';
9+
import { DEFAULT_VIEWPORT, ECHARTS_GESTURE } from '../../common/constants';
10+
import { DataStream } from '@iot-app-kit/core';
11+
12+
export const Gauge = ({
13+
query,
14+
viewport: passedInViewport,
15+
thresholds = [],
16+
styles,
17+
settings,
18+
significantDigits,
19+
theme,
20+
}: GaugeProps) => {
21+
const { dataStreams } = useTimeSeriesData({
22+
viewport: passedInViewport,
23+
queries: [query],
24+
settings: { fetchMostRecentBeforeEnd: true },
25+
styles,
26+
});
27+
const { viewport, lastUpdatedBy } = useViewport();
28+
29+
const utilizedViewport =
30+
(lastUpdatedBy === ECHARTS_GESTURE
31+
? viewport
32+
: passedInViewport || viewport) ?? DEFAULT_VIEWPORT;
33+
34+
const { propertyPoint, alarmStream, propertyStream } =
35+
widgetPropertiesFromInputs({
36+
dataStreams,
37+
thresholds,
38+
viewport: utilizedViewport,
39+
});
40+
41+
const streamToUse = [propertyStream, alarmStream].find(Boolean) as DataStream;
42+
const name = streamToUse?.name;
43+
const unit = streamToUse?.unit;
44+
const isLoading = streamToUse?.isLoading || false;
45+
const error = streamToUse?.error;
46+
47+
return (
48+
<GaugeBase
49+
propertyPoint={propertyPoint}
50+
name={name}
51+
unit={unit}
52+
isLoading={isLoading}
53+
error={error?.msg}
54+
settings={settings}
55+
thresholds={thresholds}
56+
significantDigits={significantDigits}
57+
theme={theme}
58+
/>
59+
);
60+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// eslint-disable-next-line import/default
2+
import React from 'react';
3+
import { useECharts, useLoadableEChart } from '../../hooks/useECharts';
4+
import { GaugeBaseProperties } from './types';
5+
import { useGaugeConfiguration } from './hooks/useGaugeConfiguration';
6+
7+
/**
8+
* Renders a base gauge component.
9+
*
10+
* @param {GaugeBaseProperties} propertyPoint - The property point object.
11+
* @param {Array} thresholds - The thresholds array.
12+
* @param {Object} settings - The settings object.
13+
* @param {string} unit - The unit string.
14+
* @param {string} name - The name string.
15+
* @param {boolean} isLoading - The isLoading boolean.
16+
* @param {number} significantDigits - The significantDigits number.
17+
* @param {Object} options - The options object.
18+
* @return {ReactElement} The rendered gauge component.
19+
*/
20+
export const GaugeBase: React.FC<GaugeBaseProperties> = ({
21+
propertyPoint,
22+
thresholds = [],
23+
settings,
24+
unit,
25+
name,
26+
isLoading,
27+
significantDigits,
28+
...options
29+
}) => {
30+
const gaugeValue = propertyPoint?.y;
31+
32+
// Setup instance of echarts
33+
const { ref, chartRef } = useECharts(options?.theme);
34+
35+
// apply loading animation to echart instance
36+
useLoadableEChart(chartRef, isLoading);
37+
38+
useGaugeConfiguration(chartRef, {
39+
thresholds,
40+
gaugeValue,
41+
name,
42+
settings,
43+
unit,
44+
significantDigits,
45+
});
46+
47+
return <div ref={ref} style={{ width: '100%', height: '100%' }} />;
48+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { useMemo } from 'react';
2+
import { GaugeProps } from '../../types';
3+
4+
/**
5+
* Generates a empty bar gauge series based on the provided settings and data.
6+
*
7+
* @param {Pick<GaugeProps, 'settings'>} settings - The parameters for generating the empty bar gauge series.
8+
* @return {object} - The generated empty bar gauge series.
9+
*/
10+
export const useEmptyGaugeSeries = ({
11+
settings,
12+
}: Pick<GaugeProps, 'settings'>) => {
13+
return useMemo(() => {
14+
return {
15+
min: settings?.yMin,
16+
max: settings?.yMax,
17+
axisLine: {
18+
lineStyle: {
19+
width: settings?.gaugeThickness,
20+
},
21+
},
22+
};
23+
}, [settings?.yMax, settings?.yMin, settings?.gaugeThickness]);
24+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { useMemo } from 'react';
2+
import { Primitive } from '@iot-app-kit/core';
3+
import { GaugeProps } from '../../types';
4+
import { DEFAULT_GAUGE_PROGRESS_COLOR } from '../../constants';
5+
import { useGaugeThresholds } from '../../hooks/useGaugeThresholds';
6+
import { useGaugeFormatterValue } from '../../hooks/useGaugeFormatterValue';
7+
8+
/**
9+
* Generates a progress bar gauge series based on the provided settings and data.
10+
*
11+
* @param {Pick<GaugeProps, 'settings' | 'thresholds' | 'significantDigits'> & {
12+
* gaugeValue?: Primitive;
13+
* name?: string;
14+
* unit?: string;
15+
* hasThresholds: boolean;
16+
* }} params - The parameters for generating the progress bar gauge series.
17+
* @return {object} - The generated progress bar gauge series.
18+
*/
19+
export const useProgressBarGaugeSeries = ({
20+
settings,
21+
thresholds,
22+
significantDigits,
23+
gaugeValue,
24+
name,
25+
unit,
26+
hasThresholds,
27+
}: Pick<GaugeProps, 'settings' | 'thresholds' | 'significantDigits'> & {
28+
gaugeValue?: Primitive;
29+
name?: string;
30+
unit?: string;
31+
hasThresholds: boolean;
32+
}) => {
33+
const gaugeThresholds = useGaugeThresholds({
34+
hasThresholds,
35+
settings,
36+
thresholds,
37+
});
38+
const { getFormatterValue } = useGaugeFormatterValue({
39+
significantDigits,
40+
unit,
41+
settings,
42+
});
43+
44+
return useMemo(() => {
45+
return {
46+
min: settings?.yMin,
47+
max: settings?.yMax,
48+
itemStyle: {
49+
color: hasThresholds ? gaugeThresholds : DEFAULT_GAUGE_PROGRESS_COLOR,
50+
},
51+
progress: {
52+
width: settings?.gaugeThickness,
53+
},
54+
detail: {
55+
formatter: getFormatterValue,
56+
rich: {
57+
value: {
58+
fontSize: settings?.fontSize,
59+
},
60+
unit: {
61+
fontSize: settings?.unitFontSize,
62+
},
63+
},
64+
},
65+
title: {
66+
show: settings?.showName,
67+
},
68+
data: [
69+
{
70+
value: gaugeValue,
71+
name,
72+
},
73+
],
74+
};
75+
}, [
76+
settings?.yMin,
77+
settings?.yMax,
78+
settings?.gaugeThickness,
79+
settings?.fontSize,
80+
settings?.unitFontSize,
81+
settings?.showName,
82+
hasThresholds,
83+
gaugeThresholds,
84+
getFormatterValue,
85+
gaugeValue,
86+
name,
87+
]);
88+
};

0 commit comments

Comments
 (0)