@centreon/ui 23.10.114 → 23.10.116
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/package.json +1 -1
- package/src/Graph/Gauge/Gauge.stories.tsx +0 -1
- package/src/Graph/HeatMap/HeatMap.stories.tsx +105 -0
- package/src/Graph/HeatMap/HeatMap.styles.tsx +28 -0
- package/src/Graph/HeatMap/HeatMap.tsx +12 -0
- package/src/Graph/HeatMap/HeatMapData.json +137 -0
- package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +94 -0
- package/src/Graph/HeatMap/index.ts +1 -0
- package/src/Graph/HeatMap/model.ts +32 -0
- package/src/Graph/index.ts +1 -0
- package/src/Typography/EllipsisTypography.tsx +18 -0
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { makeStyles } from 'tss-react/mui';
|
|
3
|
+
|
|
4
|
+
import { Box, Typography } from '@mui/material';
|
|
5
|
+
|
|
6
|
+
import EllipsisTypography from '../../Typography/EllipsisTypography';
|
|
7
|
+
|
|
8
|
+
import heatMapData from './HeatMapData.json';
|
|
9
|
+
|
|
10
|
+
import { HeatMap } from '.';
|
|
11
|
+
|
|
12
|
+
interface Data {
|
|
13
|
+
counter: number;
|
|
14
|
+
host: string;
|
|
15
|
+
service: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const meta: Meta<typeof HeatMap<Data>> = {
|
|
19
|
+
component: HeatMap
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default meta;
|
|
23
|
+
type Story = StoryObj<typeof HeatMap<Data>>;
|
|
24
|
+
|
|
25
|
+
const TileContent = ({
|
|
26
|
+
isSmallestSize,
|
|
27
|
+
data
|
|
28
|
+
}: {
|
|
29
|
+
data: Data;
|
|
30
|
+
isSmallestSize: boolean;
|
|
31
|
+
}): JSX.Element | false =>
|
|
32
|
+
!isSmallestSize && (
|
|
33
|
+
<Box
|
|
34
|
+
sx={{
|
|
35
|
+
alignItems: 'center',
|
|
36
|
+
color: 'common.black',
|
|
37
|
+
display: 'flex',
|
|
38
|
+
flexDirection: 'column',
|
|
39
|
+
width: '100%'
|
|
40
|
+
}}
|
|
41
|
+
>
|
|
42
|
+
<EllipsisTypography textAlign="center">{data.host}</EllipsisTypography>
|
|
43
|
+
<EllipsisTypography textAlign="center">{data.service}</EllipsisTypography>
|
|
44
|
+
<EllipsisTypography textAlign="center">{data.counter}</EllipsisTypography>
|
|
45
|
+
</Box>
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const TooltipContent = ({ data }: { data: Data }): JSX.Element => {
|
|
49
|
+
return (
|
|
50
|
+
<Box sx={{ backgroundColor: 'common.white', color: 'common.black' }}>
|
|
51
|
+
<Box
|
|
52
|
+
sx={{
|
|
53
|
+
backgroundColor: 'common.black',
|
|
54
|
+
color: 'common.white',
|
|
55
|
+
display: 'flex',
|
|
56
|
+
justifyContent: 'center',
|
|
57
|
+
py: 1,
|
|
58
|
+
width: '100%'
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
<Typography>{data.host}</Typography>
|
|
62
|
+
</Box>
|
|
63
|
+
<Box sx={{ px: 1, textAlign: 'center' }}>
|
|
64
|
+
<Typography>{data.service}</Typography>
|
|
65
|
+
<Typography>{data.counter}</Typography>
|
|
66
|
+
</Box>
|
|
67
|
+
</Box>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const useStyles = makeStyles()((theme) => ({
|
|
72
|
+
arrow: {
|
|
73
|
+
color: theme.palette.common.black
|
|
74
|
+
}
|
|
75
|
+
}));
|
|
76
|
+
|
|
77
|
+
const Template = (args): JSX.Element => {
|
|
78
|
+
const { classes } = useStyles();
|
|
79
|
+
|
|
80
|
+
return <HeatMap {...args} arrowClassName={classes.arrow} />;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const normal: Story = {
|
|
84
|
+
args: {
|
|
85
|
+
children: TileContent,
|
|
86
|
+
tiles: heatMapData
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const withTooltip: Story = {
|
|
91
|
+
args: {
|
|
92
|
+
children: TileContent,
|
|
93
|
+
tiles: heatMapData,
|
|
94
|
+
tooltipContent: TooltipContent
|
|
95
|
+
},
|
|
96
|
+
render: Template
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const tilesWithFixedSize: Story = {
|
|
100
|
+
args: {
|
|
101
|
+
children: TileContent,
|
|
102
|
+
tileSizeFixed: true,
|
|
103
|
+
tiles: heatMapData
|
|
104
|
+
}
|
|
105
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { makeStyles } from 'tss-react/mui';
|
|
2
|
+
|
|
3
|
+
export const useHeatMapStyles = makeStyles()((theme) => ({
|
|
4
|
+
arrow: {
|
|
5
|
+
transform: 'transled3d(0px, 8px, 0px)'
|
|
6
|
+
},
|
|
7
|
+
heatMapTile: {
|
|
8
|
+
alignItems: 'center',
|
|
9
|
+
aspectRatio: '1 / 1',
|
|
10
|
+
display: 'flex',
|
|
11
|
+
justifyContent: 'center',
|
|
12
|
+
width: '100%'
|
|
13
|
+
},
|
|
14
|
+
heatMapTileContent: {
|
|
15
|
+
height: `calc(100% - ${theme.spacing(1)})`,
|
|
16
|
+
width: `calc(100% - ${theme.spacing(1)})`
|
|
17
|
+
},
|
|
18
|
+
heatMapTooltip: {
|
|
19
|
+
backgroundColor: theme.palette.background.paper,
|
|
20
|
+
color: theme.palette.text.primary,
|
|
21
|
+
marginLeft: `${theme.spacing(1.25)} !important`,
|
|
22
|
+
padding: 0,
|
|
23
|
+
position: 'relative'
|
|
24
|
+
},
|
|
25
|
+
heatMapTooltipArrow: {
|
|
26
|
+
transform: `translate3d(0px, ${theme.spacing(1)}, 0px) !important`
|
|
27
|
+
}
|
|
28
|
+
}));
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ParentSize } from '../..';
|
|
2
|
+
|
|
3
|
+
import ResponsiveHeatMap from './ResponsiveHeatMap';
|
|
4
|
+
import { HeatMapProps } from './model';
|
|
5
|
+
|
|
6
|
+
const HeatMap = <TData,>(props: HeatMapProps<TData>): JSX.Element => (
|
|
7
|
+
<ParentSize>
|
|
8
|
+
{({ width }) => <ResponsiveHeatMap<TData> {...props} width={width} />}
|
|
9
|
+
</ParentSize>
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
export default HeatMap;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "Orbaxter",
|
|
4
|
+
"backgroundColor": "#88B922",
|
|
5
|
+
"data": {
|
|
6
|
+
"host": "Server",
|
|
7
|
+
"service": "Service Counter",
|
|
8
|
+
"counter": 53
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"id": "Interfind",
|
|
13
|
+
"backgroundColor": "#88B922",
|
|
14
|
+
"data": {
|
|
15
|
+
"host": "Server",
|
|
16
|
+
"service": "Service Counter",
|
|
17
|
+
"counter": 779
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "Ecratic",
|
|
22
|
+
"backgroundColor": "#E3E3E3",
|
|
23
|
+
"data": {
|
|
24
|
+
"host": "Server",
|
|
25
|
+
"service": "Service Counter",
|
|
26
|
+
"counter": 504
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": "Earthwax",
|
|
31
|
+
"backgroundColor": "#88B922",
|
|
32
|
+
"data": {
|
|
33
|
+
"host": "Server",
|
|
34
|
+
"service": "Service Counter",
|
|
35
|
+
"counter": 374
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "Cytrak",
|
|
40
|
+
"backgroundColor": "#FF6666",
|
|
41
|
+
"data": {
|
|
42
|
+
"host": "Server",
|
|
43
|
+
"service": "Service Counter",
|
|
44
|
+
"counter": 957
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"id": "Exiand",
|
|
49
|
+
"backgroundColor": "#1EBEB3",
|
|
50
|
+
"data": {
|
|
51
|
+
"host": "Server",
|
|
52
|
+
"service": "Service Counter",
|
|
53
|
+
"counter": 281
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "Ginkogene",
|
|
58
|
+
"backgroundColor": "#FF6666",
|
|
59
|
+
"data": {
|
|
60
|
+
"host": "Server",
|
|
61
|
+
"service": "Service Counter",
|
|
62
|
+
"counter": 472
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"id": "Quailcom",
|
|
67
|
+
"backgroundColor": "#88B922",
|
|
68
|
+
"data": {
|
|
69
|
+
"host": "Server",
|
|
70
|
+
"service": "Service Counter",
|
|
71
|
+
"counter": 770
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"id": "Cormoran",
|
|
76
|
+
"backgroundColor": "#FF6666",
|
|
77
|
+
"data": {
|
|
78
|
+
"host": "Server",
|
|
79
|
+
"service": "Service Counter",
|
|
80
|
+
"counter": 908
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "Emergent",
|
|
85
|
+
"backgroundColor": "#1EBEB3",
|
|
86
|
+
"data": {
|
|
87
|
+
"host": "Server",
|
|
88
|
+
"service": "Service Counter",
|
|
89
|
+
"counter": 969
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "Limozen",
|
|
94
|
+
"backgroundColor": "#E3E3E3",
|
|
95
|
+
"data": {
|
|
96
|
+
"host": "Server",
|
|
97
|
+
"service": "Service Counter",
|
|
98
|
+
"counter": 33
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"id": "Gogol",
|
|
103
|
+
"backgroundColor": "#1EBEB3",
|
|
104
|
+
"data": {
|
|
105
|
+
"host": "Server",
|
|
106
|
+
"service": "Service Counter",
|
|
107
|
+
"counter": 870
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"id": "Luxuria",
|
|
112
|
+
"backgroundColor": "#FD9B27",
|
|
113
|
+
"data": {
|
|
114
|
+
"host": "Server",
|
|
115
|
+
"service": "Service Counter",
|
|
116
|
+
"counter": 270
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "Fossiel",
|
|
121
|
+
"backgroundColor": "#1EBEB3",
|
|
122
|
+
"data": {
|
|
123
|
+
"host": "Server",
|
|
124
|
+
"service": "Service Counter",
|
|
125
|
+
"counter": 955
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"id": "Hawkster",
|
|
130
|
+
"backgroundColor": "#88B922",
|
|
131
|
+
"data": {
|
|
132
|
+
"host": "Server",
|
|
133
|
+
"service": "Service Counter",
|
|
134
|
+
"counter": 28
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
import { scaleLinear } from '@visx/scale';
|
|
4
|
+
import { equals, gt, lt } from 'ramda';
|
|
5
|
+
|
|
6
|
+
import { Box } from '@mui/material';
|
|
7
|
+
|
|
8
|
+
import { Tooltip } from '../../components';
|
|
9
|
+
|
|
10
|
+
import { HeatMapProps } from './model';
|
|
11
|
+
import { useHeatMapStyles } from './HeatMap.styles';
|
|
12
|
+
|
|
13
|
+
const gap = 8;
|
|
14
|
+
const maxTileSize = 120;
|
|
15
|
+
const smallestTileSize = 44;
|
|
16
|
+
|
|
17
|
+
const ResponsiveHeatMap = <TData,>({
|
|
18
|
+
width,
|
|
19
|
+
children,
|
|
20
|
+
tiles,
|
|
21
|
+
arrowClassName,
|
|
22
|
+
tooltipContent,
|
|
23
|
+
tileSizeFixed
|
|
24
|
+
}: HeatMapProps<TData> & { width: number }): JSX.Element | null => {
|
|
25
|
+
const { classes, cx } = useHeatMapStyles();
|
|
26
|
+
|
|
27
|
+
const tileSize = useMemo(() => {
|
|
28
|
+
const scaleWidth = scaleLinear({
|
|
29
|
+
clamp: true,
|
|
30
|
+
domain: [680, 1056],
|
|
31
|
+
range: [76, maxTileSize]
|
|
32
|
+
});
|
|
33
|
+
const tileWidth = scaleWidth(width);
|
|
34
|
+
|
|
35
|
+
const tilesLength = tiles.length;
|
|
36
|
+
|
|
37
|
+
const maxTotalTilesWidth =
|
|
38
|
+
tilesLength * maxTileSize + (tilesLength - 1) * gap;
|
|
39
|
+
const theoricalTotalTilesWidth =
|
|
40
|
+
tilesLength * tileWidth + (tilesLength - 1) * gap;
|
|
41
|
+
|
|
42
|
+
if (lt(width, 680) && gt(maxTotalTilesWidth, width)) {
|
|
43
|
+
return smallestTileSize;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (lt(theoricalTotalTilesWidth, width)) {
|
|
47
|
+
return maxTileSize;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return tileSizeFixed ? maxTileSize : tileWidth;
|
|
51
|
+
}, [width, tiles]);
|
|
52
|
+
|
|
53
|
+
const isSmallestSize = equals(tileSize, smallestTileSize);
|
|
54
|
+
|
|
55
|
+
if (equals(width, 0)) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<Box
|
|
61
|
+
sx={{
|
|
62
|
+
display: 'grid',
|
|
63
|
+
gap: 1,
|
|
64
|
+
gridTemplateColumns: `repeat(auto-fit, ${tileSize}px)`
|
|
65
|
+
}}
|
|
66
|
+
>
|
|
67
|
+
{tiles.map(({ backgroundColor, id, data }) => (
|
|
68
|
+
<Box className={classes.heatMapTile} key={id} sx={{ backgroundColor }}>
|
|
69
|
+
<Tooltip
|
|
70
|
+
hasCaret
|
|
71
|
+
classes={{
|
|
72
|
+
arrow: cx(classes.heatMapTooltipArrow, arrowClassName),
|
|
73
|
+
tooltip: classes.heatMapTooltip
|
|
74
|
+
}}
|
|
75
|
+
followCursor={false}
|
|
76
|
+
label={tooltipContent?.({
|
|
77
|
+
backgroundColor,
|
|
78
|
+
data,
|
|
79
|
+
id,
|
|
80
|
+
isSmallestSize
|
|
81
|
+
})}
|
|
82
|
+
position="right-start"
|
|
83
|
+
>
|
|
84
|
+
<div className={classes.heatMapTileContent}>
|
|
85
|
+
{children({ backgroundColor, data, id, isSmallestSize })}
|
|
86
|
+
</div>
|
|
87
|
+
</Tooltip>
|
|
88
|
+
</Box>
|
|
89
|
+
))}
|
|
90
|
+
</Box>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export default ResponsiveHeatMap;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as HeatMap } from './HeatMap';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
|
|
3
|
+
interface Tile<TData> {
|
|
4
|
+
backgroundColor: string;
|
|
5
|
+
data: TData;
|
|
6
|
+
id: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface ChildrenProps<TData> {
|
|
10
|
+
backgroundColor: string;
|
|
11
|
+
data: TData;
|
|
12
|
+
id: string;
|
|
13
|
+
isSmallestSize: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface HeatMapProps<TData> {
|
|
17
|
+
arrowClassName?: string;
|
|
18
|
+
children: ({
|
|
19
|
+
backgroundColor,
|
|
20
|
+
id,
|
|
21
|
+
data,
|
|
22
|
+
isSmallestSize
|
|
23
|
+
}: ChildrenProps<TData>) => ReactElement | boolean | null;
|
|
24
|
+
tileSizeFixed?: boolean;
|
|
25
|
+
tiles: Array<Tile<TData>>;
|
|
26
|
+
tooltipContent?: ({
|
|
27
|
+
backgroundColor,
|
|
28
|
+
id,
|
|
29
|
+
data,
|
|
30
|
+
isSmallestSize
|
|
31
|
+
}: ChildrenProps<TData>) => ReactElement | boolean | null;
|
|
32
|
+
}
|
package/src/Graph/index.ts
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Box, Typography, TypographyProps } from '@mui/material';
|
|
2
|
+
|
|
3
|
+
const EllipsisTypography = (props: TypographyProps): JSX.Element => {
|
|
4
|
+
return (
|
|
5
|
+
<Box sx={{ width: '100%' }}>
|
|
6
|
+
<Typography
|
|
7
|
+
sx={{
|
|
8
|
+
overflow: 'hidden',
|
|
9
|
+
textOverflow: 'ellipsis',
|
|
10
|
+
whiteSpace: 'nowrap'
|
|
11
|
+
}}
|
|
12
|
+
{...props}
|
|
13
|
+
/>
|
|
14
|
+
</Box>
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default EllipsisTypography;
|
package/src/index.ts
CHANGED
|
@@ -154,6 +154,7 @@ export type { ResponseError, CatchErrorProps } from './api/customFetch';
|
|
|
154
154
|
|
|
155
155
|
export * from './utils';
|
|
156
156
|
export { default as FluidTypography } from './Typography/FluidTypography';
|
|
157
|
+
export { default as EllipsisTypography } from './Typography/EllipsisTypography';
|
|
157
158
|
export * from './Dashboard';
|
|
158
159
|
export * from './Graph';
|
|
159
160
|
export type { LineChartData } from './Graph/common/models';
|