Refactor LineChart component to use generic types

This commit is contained in:
Simon Larsen 2024-03-28 11:36:40 +00:00
parent 39f0834cc2
commit c03d250a62
No known key found for this signature in database
GPG Key ID: AB45983AA9C81CDE
2 changed files with 98 additions and 36 deletions

View File

@ -1,12 +1,14 @@
import React, { FunctionComponent, ReactElement } from 'react';
import { Point, ResponsiveLine } from '@nivo/line';
import OneUptimeDate from 'Common/Types/Date';
import { Indigo500 } from 'Common/Types/BrandColors';
import { CartesianMarkerProps } from '@nivo/core';
export type XValue = string | number | Date;
export type YValue = number;
export interface LineChartDataItem {
x: string | number | Date;
y: number;
x: XValue;
y: YValue;
}
export enum ChartCurve {
@ -30,10 +32,12 @@ export enum XScalePrecision {
YEAR = 'year',
}
export type ScaleMaxMin = 'auto' | number;
export interface XScale {
type: XScaleType;
min: string | Date;
max: string | Date;
min: ScaleMaxMin;
max: ScaleMaxMin;
precision: XScalePrecision;
}
@ -48,8 +52,8 @@ export enum YScaleType {
export interface YScale {
type: YScaleType;
min: 'auto' | number;
max: 'auto' | number;
min: ScaleMaxMin;
max: ScaleMaxMin;
}
export interface AxisBottom {
@ -62,33 +66,22 @@ export interface AxisLeft {
}
export interface ComponentProps {
data: LineChartData;
data: Array<LineChartData>;
curve?: ChartCurve;
xScale: XScale;
yScale: YScale;
axisBottom: AxisBottom;
axisLeft: AxisLeft;
onHoverXAxis?: (x: string | number | Date) => void;
onHoverXAxis?: (x: XValue) => void;
xAxisMarker?: {
value: string | number | Date | undefined;
value: XValue | undefined;
};
}
const LineChart: FunctionComponent<ComponentProps> = (
props: ComponentProps
): ReactElement => {
const data = [
{
id: 'Response Time',
data: [
{ x: OneUptimeDate.getCurrentDate(), y: 10 },
{ x: OneUptimeDate.getSomeMinutesAfter(1), y: 15 },
{ x: OneUptimeDate.getSomeMinutesAfter(2), y: 12 },
{ x: OneUptimeDate.getSomeMinutesAfter(4), y: 8 },
{ x: OneUptimeDate.getSomeMinutesAfter(5), y: 11 },
],
},
];
const markers: Array<CartesianMarkerProps> = [];
@ -107,15 +100,16 @@ const LineChart: FunctionComponent<ComponentProps> = (
return (
<div className="h-96 w-full">
<ResponsiveLine
data={data}
data={props.data}
onMouseEnter={(data: Point) => {
if (props.onHoverXAxis) {
props.onHoverXAxis(data.data.x);
const xValue: XValue = ((data as any).points as Array<any>)?.[0]?.data?.x;
props.onHoverXAxis(xValue);
}
}}
onMouseLeave={(data: Point) => {
if (props.onHoverXAxis) {
props.onHoverXAxis(data.data.x);
props.onHoverXAxis(data.x);
}
}}
margin={{ bottom: 30, left: 30 }}
@ -123,8 +117,8 @@ const LineChart: FunctionComponent<ComponentProps> = (
markers={markers}
xScale={{
type: props.xScale.type,
max: props.xScale.max,
min: props.xScale.min,
max: props.xScale.max as any,
min: props.xScale.min as any,
precision: props.xScale.precision,
}}
yScale={{

View File

@ -38,7 +38,8 @@ import ProjectUtil from 'CommonUI/src/Utils/Project';
import BaseModel from 'Common/Models/BaseModel';
import { PromiseVoidFunction } from 'Common/Types/FunctionTypes';
import ServerMonitorDocumentation from '../../../Components/Monitor/ServerMonitor/Documentation';
import LineChart from 'CommonUI/src/Components/Charts/Line/LineChart';
import ChartGroup, { ChartGroupInterval, ChartType } from 'CommonUI/src/Components/Charts/ChartGroup/ChartGroup';
import { XScalePrecision, XScaleType, YScaleType } from 'CommonUI/src/Components/Charts/Line/LineChart';
const MonitorView: FunctionComponent<PageComponentProps> = (
_props: PageComponentProps
@ -183,6 +184,19 @@ const MonitorView: FunctionComponent<PageComponentProps> = (
setIsLoading(false);
};
const data = [
{
id: 'Response Time',
data: [
{ x: OneUptimeDate.getCurrentDate(), y: 10 },
{ x: OneUptimeDate.getSomeMinutesAfter(1), y: 15 },
{ x: OneUptimeDate.getSomeMinutesAfter(2), y: 12 },
{ x: OneUptimeDate.getSomeMinutesAfter(4), y: 8 },
{ x: OneUptimeDate.getSomeMinutesAfter(5), y: 11 },
],
},
];
return (
<Fragment>
<DisabledWarning monitorId={modelId} />
@ -298,7 +312,7 @@ const MonitorView: FunctionComponent<PageComponentProps> = (
color={
(
item[
'currentMonitorStatus'
'currentMonitorStatus'
] as JSONObject
)['color'] as Color
}
@ -306,7 +320,7 @@ const MonitorView: FunctionComponent<PageComponentProps> = (
text={
(
item[
'currentMonitorStatus'
'currentMonitorStatus'
] as JSONObject
)['name'] as string
}
@ -336,7 +350,7 @@ const MonitorView: FunctionComponent<PageComponentProps> = (
labels={
BaseModel.fromJSON(
(item['labels'] as JSONArray) ||
[],
[],
Label
) as Array<Label>
}
@ -355,12 +369,66 @@ const MonitorView: FunctionComponent<PageComponentProps> = (
}}
/>
<LineChart />
<ChartGroup
interval={ChartGroupInterval.ONE_HOUR}
charts={[{
id: 'chart-1',
type: ChartType.LINE,
props: {
data: data,
xScale: {
type: XScaleType.TIME,
min: 'auto',
max: 'auto',
precision: XScalePrecision.MINUTE,
},
yScale: {
type: YScaleType.LINEAR,
min: 'auto',
max: 'auto',
},
axisBottom: {
legend: 'Time',
format: 'time:%Y-%m-%d %H:%M:%S',
},
axisLeft: {
legend: 'Response Time',
}
},
sync: true
}, {
id: 'chart-2',
type: ChartType.LINE,
props: {
data: data,
xScale: {
type: XScaleType.TIME,
min: 'auto',
max: 'auto',
precision: XScalePrecision.MINUTE,
},
yScale: {
type: YScaleType.LINEAR,
min: 'auto',
max: 'auto',
},
axisBottom: {
legend: 'Time',
format: 'time:%Y-%m-%d %H:%M:%S',
},
axisLeft: {
legend: 'Response Time',
}
},
sync: true
}]}
/>
{/* Heartbeat URL */}
{monitorType === MonitorType.IncomingRequest &&
monitor?.incomingRequestSecretKey &&
!monitor.incomingRequestReceivedAt ? (
monitor?.incomingRequestSecretKey &&
!monitor.incomingRequestReceivedAt ? (
<IncomingMonitorLink
secretKey={monitor?.incomingRequestSecretKey}
/>
@ -369,8 +437,8 @@ const MonitorView: FunctionComponent<PageComponentProps> = (
)}
{monitorType === MonitorType.Server &&
monitor?.serverMonitorSecretKey &&
!monitor.serverMonitorRequestReceivedAt ? (
monitor?.serverMonitorSecretKey &&
!monitor.serverMonitorRequestReceivedAt ? (
<ServerMonitorDocumentation
secretKey={monitor?.serverMonitorSecretKey}
/>