Skip to content

Commit

Permalink
[pinpoint-apm#7497] ErrorAnalysis > Summary mini chart
Browse files Browse the repository at this point in the history
  • Loading branch information
jihea-park committed Oct 18, 2024
1 parent c3c8982 commit 0db4ef4
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Chart } from './common/Chart';

export namespace ErrorAnalysisGroupedErrorList {
export interface Parameters {
applicationName: string;
Expand All @@ -15,6 +17,22 @@ export namespace ErrorAnalysisGroupedErrorList {
firstOccurred: number;
lastOccurred: number;
fieldName: FieldName;
chart: Chart;
groupedFieldName: {
errorClassName: string;
};
groupFilterParams: {
errorClassName: string;
};
firstLineOfClassName: string;
firstLineOfMethodName: string;
lastTransactionSearchParams: {
applicationName: string;
agentId: string;
transactionId: string;
spanId: string;
exceptionId: string;
};
}

export interface FieldName {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export interface Chart {
title: string;
timestamp: number[];
metricValueGroups: MetricValueGroup[];
}

export interface MetricValueGroup {
groupName: string;
chartType: string;
unit: string;
metricValues: MetricValue[];
}

export interface MetricValue {
fieldName: string;
values: number[];
tags?: any[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Chart';
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './common';
export * from './ActiveThreadDump';
export * from './ActiveThreadLightDump';
export * from './AgentActiveThread';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const usePostOtlpMetricData = (
options?: UseMutationOptions<OtlpMetricData.Response, unknown, OtlpMetricData.Body, unknown>,
) => {
const postData = async (bodyData: OtlpMetricData.Body) => {
console.log('bodyData', bodyData);
try {
const response = await fetch(`${END_POINTS.OTLP_METRIC_DATA}`, {
method: 'POST',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ErrorAnalysisGroupedErrorList } from '@pinpoint-fe/constants';
import { ComposedChart, ReferenceLine } from 'recharts';
import { useRechart } from '../../../hooks/useRechart';

export interface ErrorGroupedTableVolumneChart {
chart: ErrorAnalysisGroupedErrorList.ErrorData['chart'];
}

export const ErrorGroupedTableVolumneChart = ({ chart }: ErrorGroupedTableVolumneChart) => {
const { data, maxValue, renderChartChildComponents } = useRechart(chart);

return (
<ComposedChart
width={128}
height={40}
data={data}
margin={{
top: 6,
right: 30,
bottom: 2,
left: 2,
}}
>
{data?.length && maxValue > -1 && (
<ReferenceLine
y={maxValue}
stroke="black"
strokeDasharray="3 3"
position="middle"
label={{ position: 'right', value: maxValue }}
ifOverflow="extendDomain"
/>
)}
{renderChartChildComponents()}
</ComposedChart>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { RxCross2 } from 'react-icons/rx';
import { Badge } from '../../ui';
import { ErrorAnalysisGroupedErrorList } from '@pinpoint-fe/constants';
import { addCommas, format } from '@pinpoint-fe/utils';
import { ErrorGroupedTableVolumneChart } from './ErrorGroupedTableVolumneChart';
// import { cn } from '../../../lib';

interface ErrorGroupedTableColumnProps {
Expand Down Expand Up @@ -83,6 +84,14 @@ export const errorGroupedTableColumns = ({
headerClassName: 'w-32',
},
},
{
accessorKey: 'chart',
header: 'Volume',
cell: (props) => {
const chart = props.getValue() as ErrorAnalysisGroupedErrorList.ErrorData['chart'];
return <ErrorGroupedTableVolumneChart chart={chart} />;
},
},
{
accessorKey: 'count',
header: 'Counts',
Expand Down
131 changes: 131 additions & 0 deletions web-frontend/src/main/v3/packages/ui/src/hooks/useRechart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { Chart } from '@pinpoint-fe/constants';
import {
BarChart,
Bar,
AreaChart,
Area,
LineChart,
Line,
LineProps,
BarProps,
AreaProps,
} from 'recharts';
import { colors } from '../constant/theme';
import { type ChartConfig } from '../components/ui/chart';
import { isNil } from 'lodash';
import { getRandomColorInHSL } from '../lib/colors';
import { useState, useEffect } from 'react';

export const COLORS = [
colors.blue[600],
colors.blue[200],
colors.orange[500],
colors.orange[200],
colors.green[600],
colors.green[300],
colors.red[600],
colors.red[300],
colors.purple[500],
colors.purple[300],
colors.stone[700],
colors.stone[400],
colors.pink[400],
colors.pink[200],
colors.gray[500],
colors.gray[300],
colors.lime[500],
colors.yellow[200],
colors.cyan[500],
colors.cyan[200],
];

const CHART_DEFINITION = {
line: {
ChartComponent: LineChart,
ChartChildComponent: Line as React.ComponentType<LineProps>,
chartChildProps: { type: 'monotone', dot: false },
},
bar: {
ChartComponent: BarChart,
ChartChildComponent: Bar as React.ComponentType<BarProps>,
chartChildProps: {},
},
area: {
ChartComponent: AreaChart,
ChartChildComponent: Area as React.ComponentType<AreaProps>,
chartChildProps: { type: 'natural', fillOpacity: '0.4' },
},
} as const;

export interface ChartData {
timestamp: number;
[key: string]: number;
}

export type ChartDataConfig = ChartConfig & {
[key: string]: {
chartType: string;
};
};

export function useRechart(chart: Chart) {
const [data, setData] = useState<ChartData[]>([]);
const [chartConfig, setChartConfig] = useState<ChartDataConfig>({});
const [maxValue, setMaxValue] = useState<number>(-1);

useEffect(() => {
if (!chart) {
return;
}

const tempData: ChartData[] = [];
const tempChartConfig: ChartDataConfig = {};
let tempMaxValue = -1;

chart.timestamp?.forEach((t, i) => {
const dataObj: ChartData = { timestamp: t };

chart.metricValueGroups?.forEach((mvg) => {
mvg?.metricValues?.forEach((mv, mvi) => {
const value = (mv?.values?.[i] === -1 ? null : mv?.values?.[i]) as number;
const fieldName = mv?.fieldName || '';

if (!isNil(value) && value > tempMaxValue) {
tempMaxValue = value;
}
dataObj[fieldName] = value;
tempChartConfig[fieldName] = {
chartType: mvg?.chartType,
color: COLORS[mvi] ?? getRandomColorInHSL(),
};
});
});
tempData.push(dataObj);
});

setData(tempData);
setChartConfig(tempChartConfig);
setMaxValue(tempMaxValue);
}, [chart]);

function renderChartChildComponents() {
return Object.keys(chartConfig)?.map((configKey) => {
const config = chartConfig[configKey];
const { ChartChildComponent, chartChildProps } =
CHART_DEFINITION[config?.chartType as keyof typeof CHART_DEFINITION] ||
CHART_DEFINITION['line'];

return (
<ChartChildComponent
key={configKey}
dataKey={configKey}
fill={chartConfig?.[configKey]?.color}
stroke={chartConfig?.[configKey]?.color}
{...chartChildProps}
/>
);
});
}

return { data, chartConfig, maxValue, renderChartChildComponents };
}

0 comments on commit 0db4ef4

Please sign in to comment.