From 49610fdcffad6ec2acdde37ca686420e728102e5 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Wed, 29 May 2024 09:05:54 -0700 Subject: [PATCH 1/4] fix: anomaly area chart and styling Signed-off-by: Dan Smith --- .../ui/src/Metrics/Chart/AnomalyChart.tsx | 237 +++++++++--------- .../ui/src/Metrics/Chart/Chart.scss | 3 +- .../ui/src/Metrics/Chart/Chart.tsx | 8 +- .../ui/src/Metrics/Metrics.scss | 2 +- 4 files changed, 124 insertions(+), 126 deletions(-) diff --git a/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx b/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx index 9bc5198..ff078bc 100644 --- a/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx +++ b/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx @@ -1,4 +1,4 @@ -import {useMemo, useState} from "react"; +import { useMemo, useState } from "react"; import { Area, AreaChart, @@ -215,6 +215,9 @@ import { ChartDataProps } from "./types"; // }, // ]; +const highLine = 7; +const medLine = 4; + const height = 180; const colorGrades = { @@ -227,6 +230,21 @@ const truncate = (str: string, n: number): string => { return str.length > n ? str.slice(0, n - 1) + "..." : str; }; +const CustomDot = (props: any) => { + const { cx, cy, payload } = props; + console.log("props", props); + if (payload.hide) { + return null; + } + let color = colorGrades.low; + if (payload?.y > highLine) { + color = colorGrades.high; + } else if (payload?.y > medLine) { + color = colorGrades.medium; + } + return ; +}; + const CustomTooltip = ({ active, metric, @@ -242,15 +260,17 @@ const CustomTooltip = ({ .forEach((el) => (el.innerHTML = "--")); payload?.map((p: any, i: any) => { - document.getElementById(`valueId_${metric}_${p.name}`).innerText = - roundNumber(yFormatter(p.value), valueRounding) + ` ${yUnit}`; - document.getElementById(`labelId_${metric}`).textContent = moment - .unix(label) - .format("MMM D, HH:mm"); - document.getElementById(`circle_${metric}`).style.fill = - ((p?.payload?.y || 0) >= 7 && colorGrades.high) || - ((p?.payload?.y || 0) >= 3 && colorGrades.medium) || - colorGrades.low; + if (!p?.payload?.hide) { + document.getElementById(`valueId_${metric}_${p.name}`).innerText = + roundNumber(yFormatter(p.value), valueRounding) + ` ${yUnit}`; + document.getElementById(`labelId_${metric}`).textContent = moment + .unix(label) + .format("MMM D, HH:mm"); + document.getElementById(`circle_${metric}`).style.fill = + ((p?.payload?.y || 0) >= highLine && colorGrades.high) || + ((p?.payload?.y || 0) >= medLine && colorGrades.medium) || + colorGrades.low; + } }); return (
@@ -311,6 +331,35 @@ const RenderLegend = ({ payload, metric }: any) => { ); }; +const formatChartData = (data: any) => { + const formattedData: any = []; + data?.data?.map((obj: any) => { + const metricObj: any = { + ...obj, + name: obj?.metric && Object.values(obj?.metric).join(":"), + data: [], + }; + obj?.values?.map((kp: any, i: any) => { + metricObj.data.push({ + x: Math.floor(kp[0] * 1), + y: kp[1], + }); + }); + metricObj.data.unshift({ + x: metricObj.data[0].x - 1, + y: 0, + hide: true, + }); + metricObj.data.unshift({ + x: metricObj.data[0].x - 1, + y: 10, + hide: true, + }); + formattedData.push(metricObj); + }); + return formattedData; +}; + interface AnomalyChartProps { chartData: ChartDataProps; title: string; @@ -325,7 +374,7 @@ interface AnomalyChartProps { setHighlight: (arg0: {} | any) => any; labelKey: string; events: any; - description: string + description: string; } export const AnomalyChart = ({ @@ -342,27 +391,27 @@ export const AnomalyChart = ({ setHighlight, labelKey, events, - description + description, }: AnomalyChartProps) => { const [isLabelHovered, setIsLabelHovered] = useState(false); - const formatChartData = (data: any) => { - const formattedData: any = []; - data?.data?.map((obj: any) => { - const metricObj: any = { - ...obj, - name: obj?.metric && Object.values(obj?.metric).join(":"), - data: [], - }; - obj?.values?.map((kp: any, i: any) => { - metricObj.data.push({ - x: Math.floor(kp[0] * 1), - y: kp[1], - }); - }); - formattedData.push(metricObj); - }); - return formattedData; - }; + // const formatChartData = (data: any) => { + // const formattedData: any = []; + // data?.data?.map((obj: any) => { + // const metricObj: any = { + // ...obj, + // name: obj?.metric && Object.values(obj?.metric).join(":"), + // data: [], + // }; + // obj?.values?.map((kp: any, i: any) => { + // metricObj.data.push({ + // x: Math.floor(kp[0] * 1), + // y: kp[1], + // }); + // }); + // formattedData.push(metricObj); + // }); + // return formattedData; + // }; const LegendMemo = useMemo(() => { return ( @@ -378,7 +427,7 @@ export const AnomalyChart = ({ } /> ); - }, [groupBy, metric, labelKey,isLabelHovered]); + }, [groupBy, metric, labelKey, isLabelHovered]); const TooltipMemo = useMemo(() => { return ( @@ -400,41 +449,43 @@ export const AnomalyChart = ({ allowEscapeViewBox={{ x: false, y: true }} /> ); - }, [labelKey, metric, yFormatter,isLabelHovered]); + }, [labelKey, metric, yFormatter, isLabelHovered]); const CustomYLabel = ({ x, y, value, tooltipContent }: any) => { const handleMouseEnter = (e: React.MouseEvent) => { - setIsLabelHovered(true) - } + setIsLabelHovered(true); + }; const handleMouseLeave = (e: React.MouseEvent) => { - setIsLabelHovered(false) - } + setIsLabelHovered(false); + }; return ( - - - {value} - - + + + {value} + + ); }; - - - const YAxisMemo = useMemo(() => { return ( roundNumber(y, valueRounding) + ``} - ticks={[0, 3, 7, 10]} + ticks={[0, medLine, highLine, 10]} style={{ fontSize: ".9em" }} > ); - }, [labelKey,isLabelHovered]); + }, [labelKey, isLabelHovered]); const renderEventContent = ({ viewBox: { x, y } }: any, event: any) => { const d: number = 20; @@ -542,27 +593,6 @@ export const AnomalyChart = ({ }; const thisChartData = formatChartData(chartData); - const scaleGradient = ( - perc: number, - max: number, - min: number = 0 - ): number => { - return (perc - (1 - max / 10)) / ((max - min) / 10); - }; - - const maxVal = Math.max.apply( - Math, - thisChartData?.[0]?.data?.map(function (o: any) { - return o.y; - }) - ); - const minVal = Math.min.apply( - Math, - thisChartData?.[0]?.data?.map(function (o: any) { - return o.y; - }) - ); - return useMemo( () => ( <> @@ -578,7 +608,7 @@ export const AnomalyChart = ({ syncId={"o11yCharts"} syncMethod={"value"} layout={"horizontal"} - onMouseMove={(e: any) => { }} + onMouseMove={(e: any) => {}} onMouseLeave={() => { setHighlight({ ...highlight, [groupBy]: "" }); }} @@ -588,7 +618,7 @@ export const AnomalyChart = ({ left: 40, bottom: 5, }} - style={{ border: '1px dashed #DEE6EB' }} + style={{ border: "1px dashed #DEE6EB" }} > {/* */} {Object.keys(uniqueEvents(events))?.map( @@ -631,7 +661,9 @@ export const AnomalyChart = ({ /> {YAxisMemo} {TooltipMemo} -{thisChartData?.[0]?.data.length > 0 && !isLabelHovered && LegendMemo} + {thisChartData?.[0]?.data.length > 0 && + !isLabelHovered && + LegendMemo} - - - - - - - - - + @@ -693,27 +695,22 @@ export const AnomalyChart = ({ isAnimationActive={false} dataKey="y" connectNulls={false} - stroke="url(#colorUvLine)" + stroke="url(#colorUv)" fill="url(#colorUv)" strokeWidth={2} name={thisChartData?.[0]?.name} - activeDot={{ - stroke: "white", - strokeWidth: 2, - r: 4, - fill: "#666", - }} + activeDot={} key={thisChartData?.[0]?.name} animationDuration={200} /> diff --git a/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Metrics.scss b/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Metrics.scss index 8a63c15..256fb49 100644 --- a/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Metrics.scss +++ b/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Metrics.scss @@ -62,7 +62,7 @@ box-shadow: 1px 2px 3px rgb(0 0 0 / 10%); margin-bottom: 2.2em; margin-top: 4px; - padding: 1em 1.5em 1em 0em; + padding: 1em; clear: both; &:last-child { margin-bottom: 210px; From f4b8bdc92eca28b9dd425c3c06b01e66a762f06b Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Wed, 29 May 2024 09:09:26 -0700 Subject: [PATCH 2/4] chore: remove console.log Signed-off-by: Dan Smith --- .../ui/src/Metrics/Chart/AnomalyChart.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx b/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx index ff078bc..489ddf1 100644 --- a/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx +++ b/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx @@ -232,7 +232,6 @@ const truncate = (str: string, n: number): string => { const CustomDot = (props: any) => { const { cx, cy, payload } = props; - console.log("props", props); if (payload.hide) { return null; } From f99c113187b7f4b39fad2eb0c4ff3162a8b5bd8a Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Wed, 29 May 2024 09:25:03 -0700 Subject: [PATCH 3/4] fix: styling updates Signed-off-by: Dan Smith --- .../ui/src/Metrics/Chart/AnomalyChart.tsx | 275 +++++++++--------- 1 file changed, 140 insertions(+), 135 deletions(-) diff --git a/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx b/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx index 489ddf1..9c3c908 100644 --- a/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx +++ b/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx @@ -592,144 +592,149 @@ export const AnomalyChart = ({ }; const thisChartData = formatChartData(chartData); - return useMemo( - () => ( - <> -
-
- {title} -
- - {}} - onMouseLeave={() => { - setHighlight({ ...highlight, [groupBy]: "" }); - }} - margin={{ - top: 30, - right: 30, - left: 40, - bottom: 5, - }} - style={{ border: "1px dashed #DEE6EB" }} - > - {/* */} - {Object.keys(uniqueEvents(events))?.map( - (eventKey: any, i: number) => { - const event = uniqueEvents(events)[eventKey]; - if (!eventKey || !event) { - return; - } + if (!thisChartData?.[0]?.data?.length) { + return ( +
+ Metric {title} not available +
+ ); + } - return ( - renderEventContent(p, event)} - /> - } - /> - ); - } - )} - - moment(unixTime * 1000).format("HH:mm") + return ( + <> +
+
+ {title} +
+ + {}} + onMouseLeave={() => { + setHighlight({ ...highlight, [groupBy]: "" }); + }} + margin={{ + top: 30, + right: 30, + left: 20, + bottom: 5, + }} + style={{ border: "1px dashed #DEE6EB" }} + > + {/* */} + {Object.keys(uniqueEvents(events))?.map( + (eventKey: any, i: number) => { + const event = uniqueEvents(events)[eventKey]; + if (!eventKey || !event) { + return; } - type="number" - /> - {YAxisMemo} - {TooltipMemo} - {thisChartData?.[0]?.data.length > 0 && - !isLabelHovered && - LegendMemo} - - - - - - renderEventContent(p, event)} + /> + } /> - - - - - } - key={thisChartData?.[0]?.name} - animationDuration={200} - /> - - - - -
- - ), - [ - title, - events, - YAxisMemo, - TooltipMemo, - LegendMemo, - setHighlight, - highlight, - groupBy, - isLabelHovered, - ] + ); + } + )} + + moment(unixTime * 1000).format("HH:mm") + } + type="number" + /> + {YAxisMemo} + {TooltipMemo} + {thisChartData?.[0]?.data.length > 0 && + !isLabelHovered && + LegendMemo} + + + + + + + + + + + } + key={thisChartData?.[0]?.name} + animationDuration={200} + /> + + +
+
+
+ ); }; From d297ee3cbd39a77fea1c3af010e47679aa5c758b Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Wed, 29 May 2024 10:09:11 -0700 Subject: [PATCH 4/4] chore: removing comment Signed-off-by: Dan Smith --- .../ui/src/Metrics/Chart/AnomalyChart.tsx | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx b/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx index 9c3c908..6a1b96d 100644 --- a/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx +++ b/extensions/resource-metrics/resource-metrics-extention/ui/src/Metrics/Chart/AnomalyChart.tsx @@ -393,24 +393,6 @@ export const AnomalyChart = ({ description, }: AnomalyChartProps) => { const [isLabelHovered, setIsLabelHovered] = useState(false); - // const formatChartData = (data: any) => { - // const formattedData: any = []; - // data?.data?.map((obj: any) => { - // const metricObj: any = { - // ...obj, - // name: obj?.metric && Object.values(obj?.metric).join(":"), - // data: [], - // }; - // obj?.values?.map((kp: any, i: any) => { - // metricObj.data.push({ - // x: Math.floor(kp[0] * 1), - // y: kp[1], - // }); - // }); - // formattedData.push(metricObj); - // }); - // return formattedData; - // }; const LegendMemo = useMemo(() => { return (