mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-13 06:19:03 +08:00
feat: added support for bar chart stacking (#5138)
* feat: stacked bars uplot poc * feat: stacked bars uplot poc * feat: reverse the legend order * fix: tooltip * feat: added bands * feat: added bands calculation function * feat: code cleanup and added toggle for stacked and unstacked bars * feat: minor fixes and better naming * feat: fix jest test cases * feat: fix data on view mode of bar chart stacked * feat: make transulecent colors * fix: build issues * fix: legend issues in bar chart edit mode * feat: added implementation details and refactored code in tooltip plugin * fix: added missing return statement * fix: eslint prettier issues * fix: legend visibility issues on view mode * fix: legend visibility issues on view mode * feat: added info text * fix: add info text only in full view mode * fix: issue with zero index
This commit is contained in:
parent
6af5aa0253
commit
f2aba5035a
@ -204,7 +204,7 @@ function FullView({
|
|||||||
<div
|
<div
|
||||||
className={cx('graph-container', {
|
className={cx('graph-container', {
|
||||||
disabled: isDashboardLocked,
|
disabled: isDashboardLocked,
|
||||||
'height-widget': widget?.mergeAllActiveQueries,
|
'height-widget': widget?.mergeAllActiveQueries || widget?.stackedBarChart,
|
||||||
'list-graph-container': isListView,
|
'list-graph-container': isListView,
|
||||||
})}
|
})}
|
||||||
ref={fullViewRef}
|
ref={fullViewRef}
|
||||||
|
@ -241,6 +241,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stack-chart {
|
||||||
|
margin-top: 16px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: var(--bg-vanilla-400);
|
||||||
|
font-family: 'Space Mono';
|
||||||
|
font-size: 13px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 18px; /* 138.462% */
|
||||||
|
letter-spacing: 0.52px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.bucket-config {
|
.bucket-config {
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -132,3 +132,17 @@ export const panelTypeVsColumnUnitPreferences: {
|
|||||||
[PANEL_TYPES.HISTOGRAM]: false,
|
[PANEL_TYPES.HISTOGRAM]: false,
|
||||||
[PANEL_TYPES.EMPTY_WIDGET]: false,
|
[PANEL_TYPES.EMPTY_WIDGET]: false,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
export const panelTypeVsStackingChartPreferences: {
|
||||||
|
[key in PANEL_TYPES]: boolean;
|
||||||
|
} = {
|
||||||
|
[PANEL_TYPES.TIME_SERIES]: false,
|
||||||
|
[PANEL_TYPES.VALUE]: false,
|
||||||
|
[PANEL_TYPES.TABLE]: false,
|
||||||
|
[PANEL_TYPES.LIST]: false,
|
||||||
|
[PANEL_TYPES.PIE]: false,
|
||||||
|
[PANEL_TYPES.BAR]: true,
|
||||||
|
[PANEL_TYPES.TRACE]: false,
|
||||||
|
[PANEL_TYPES.HISTOGRAM]: false,
|
||||||
|
[PANEL_TYPES.EMPTY_WIDGET]: false,
|
||||||
|
} as const;
|
||||||
|
@ -29,6 +29,7 @@ import {
|
|||||||
panelTypeVsFillSpan,
|
panelTypeVsFillSpan,
|
||||||
panelTypeVsPanelTimePreferences,
|
panelTypeVsPanelTimePreferences,
|
||||||
panelTypeVsSoftMinMax,
|
panelTypeVsSoftMinMax,
|
||||||
|
panelTypeVsStackingChartPreferences,
|
||||||
panelTypeVsThreshold,
|
panelTypeVsThreshold,
|
||||||
panelTypeVsYAxisUnit,
|
panelTypeVsYAxisUnit,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
@ -48,6 +49,8 @@ function RightContainer({
|
|||||||
selectedGraph,
|
selectedGraph,
|
||||||
bucketCount,
|
bucketCount,
|
||||||
bucketWidth,
|
bucketWidth,
|
||||||
|
stackedBarChart,
|
||||||
|
setStackedBarChart,
|
||||||
setBucketCount,
|
setBucketCount,
|
||||||
setBucketWidth,
|
setBucketWidth,
|
||||||
setSelectedTime,
|
setSelectedTime,
|
||||||
@ -87,6 +90,8 @@ function RightContainer({
|
|||||||
const allowYAxisUnit = panelTypeVsYAxisUnit[selectedGraph];
|
const allowYAxisUnit = panelTypeVsYAxisUnit[selectedGraph];
|
||||||
const allowCreateAlerts = panelTypeVsCreateAlert[selectedGraph];
|
const allowCreateAlerts = panelTypeVsCreateAlert[selectedGraph];
|
||||||
const allowBucketConfig = panelTypeVsBucketConfig[selectedGraph];
|
const allowBucketConfig = panelTypeVsBucketConfig[selectedGraph];
|
||||||
|
const allowStackingBarChart =
|
||||||
|
panelTypeVsStackingChartPreferences[selectedGraph];
|
||||||
const allowPanelTimePreference =
|
const allowPanelTimePreference =
|
||||||
panelTypeVsPanelTimePreferences[selectedGraph];
|
panelTypeVsPanelTimePreferences[selectedGraph];
|
||||||
|
|
||||||
@ -231,6 +236,17 @@ function RightContainer({
|
|||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{allowStackingBarChart && (
|
||||||
|
<section className="stack-chart">
|
||||||
|
<Typography.Text className="label">Stack series</Typography.Text>
|
||||||
|
<Switch
|
||||||
|
checked={stackedBarChart}
|
||||||
|
size="small"
|
||||||
|
onChange={(checked): void => setStackedBarChart(checked)}
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
|
||||||
{allowBucketConfig && (
|
{allowBucketConfig && (
|
||||||
<section className="bucket-config">
|
<section className="bucket-config">
|
||||||
<Typography.Text className="label">Number of buckets</Typography.Text>
|
<Typography.Text className="label">Number of buckets</Typography.Text>
|
||||||
@ -312,6 +328,8 @@ interface RightContainerProps {
|
|||||||
setSelectedTime: Dispatch<SetStateAction<timePreferance>>;
|
setSelectedTime: Dispatch<SetStateAction<timePreferance>>;
|
||||||
selectedTime: timePreferance;
|
selectedTime: timePreferance;
|
||||||
yAxisUnit: string;
|
yAxisUnit: string;
|
||||||
|
stackedBarChart: boolean;
|
||||||
|
setStackedBarChart: Dispatch<SetStateAction<boolean>>;
|
||||||
bucketWidth: number;
|
bucketWidth: number;
|
||||||
bucketCount: number;
|
bucketCount: number;
|
||||||
combineHistogram: boolean;
|
combineHistogram: boolean;
|
||||||
|
@ -126,6 +126,10 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
const [stacked, setStacked] = useState<boolean>(
|
const [stacked, setStacked] = useState<boolean>(
|
||||||
selectedWidget?.isStacked || false,
|
selectedWidget?.isStacked || false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [stackedBarChart, setStackedBarChart] = useState<boolean>(
|
||||||
|
selectedWidget?.stackedBarChart || false,
|
||||||
|
);
|
||||||
const [opacity, setOpacity] = useState<string>(selectedWidget?.opacity || '1');
|
const [opacity, setOpacity] = useState<string>(selectedWidget?.opacity || '1');
|
||||||
const [thresholds, setThresholds] = useState<ThresholdProps[]>(
|
const [thresholds, setThresholds] = useState<ThresholdProps[]>(
|
||||||
selectedWidget?.thresholds || [],
|
selectedWidget?.thresholds || [],
|
||||||
@ -195,6 +199,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
fillSpans: isFillSpans,
|
fillSpans: isFillSpans,
|
||||||
columnUnits,
|
columnUnits,
|
||||||
bucketCount,
|
bucketCount,
|
||||||
|
stackedBarChart,
|
||||||
bucketWidth,
|
bucketWidth,
|
||||||
mergeAllActiveQueries: combineHistogram,
|
mergeAllActiveQueries: combineHistogram,
|
||||||
selectedLogFields,
|
selectedLogFields,
|
||||||
@ -219,6 +224,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
bucketWidth,
|
bucketWidth,
|
||||||
bucketCount,
|
bucketCount,
|
||||||
combineHistogram,
|
combineHistogram,
|
||||||
|
stackedBarChart,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const closeModal = (): void => {
|
const closeModal = (): void => {
|
||||||
@ -307,6 +313,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
opacity: selectedWidget?.opacity || '1',
|
opacity: selectedWidget?.opacity || '1',
|
||||||
nullZeroValues: selectedWidget?.nullZeroValues || 'zero',
|
nullZeroValues: selectedWidget?.nullZeroValues || 'zero',
|
||||||
title: selectedWidget?.title,
|
title: selectedWidget?.title,
|
||||||
|
stackedBarChart: selectedWidget?.stackedBarChart || false,
|
||||||
yAxisUnit: selectedWidget?.yAxisUnit,
|
yAxisUnit: selectedWidget?.yAxisUnit,
|
||||||
panelTypes: graphType,
|
panelTypes: graphType,
|
||||||
query: currentQuery,
|
query: currentQuery,
|
||||||
@ -332,6 +339,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
opacity: selectedWidget?.opacity || '1',
|
opacity: selectedWidget?.opacity || '1',
|
||||||
nullZeroValues: selectedWidget?.nullZeroValues || 'zero',
|
nullZeroValues: selectedWidget?.nullZeroValues || 'zero',
|
||||||
title: selectedWidget?.title,
|
title: selectedWidget?.title,
|
||||||
|
stackedBarChart: selectedWidget?.stackedBarChart || false,
|
||||||
yAxisUnit: selectedWidget?.yAxisUnit,
|
yAxisUnit: selectedWidget?.yAxisUnit,
|
||||||
panelTypes: graphType,
|
panelTypes: graphType,
|
||||||
query: currentQuery,
|
query: currentQuery,
|
||||||
@ -532,6 +540,8 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
setDescription={setDescription}
|
setDescription={setDescription}
|
||||||
stacked={stacked}
|
stacked={stacked}
|
||||||
setStacked={setStacked}
|
setStacked={setStacked}
|
||||||
|
stackedBarChart={stackedBarChart}
|
||||||
|
setStackedBarChart={setStackedBarChart}
|
||||||
opacity={opacity}
|
opacity={opacity}
|
||||||
yAxisUnit={yAxisUnit}
|
yAxisUnit={yAxisUnit}
|
||||||
columnUnits={columnUnits}
|
columnUnits={columnUnits}
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
.info-text {
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
@ -1,3 +1,6 @@
|
|||||||
|
import './UplotPanelWrapper.styles.scss';
|
||||||
|
|
||||||
|
import { Alert } from 'antd';
|
||||||
import { ToggleGraphProps } from 'components/Graph/types';
|
import { ToggleGraphProps } from 'components/Graph/types';
|
||||||
import Uplot from 'components/Uplot';
|
import Uplot from 'components/Uplot';
|
||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
@ -8,6 +11,7 @@ import { useIsDarkMode } from 'hooks/useDarkMode';
|
|||||||
import { useResizeObserver } from 'hooks/useDimensions';
|
import { useResizeObserver } from 'hooks/useDimensions';
|
||||||
import { getUPlotChartOptions } from 'lib/uPlotLib/getUplotChartOptions';
|
import { getUPlotChartOptions } from 'lib/uPlotLib/getUplotChartOptions';
|
||||||
import { getUPlotChartData } from 'lib/uPlotLib/utils/getUplotChartData';
|
import { getUPlotChartData } from 'lib/uPlotLib/utils/getUplotChartData';
|
||||||
|
import { cloneDeep, isEqual, isUndefined } from 'lodash-es';
|
||||||
import _noop from 'lodash-es/noop';
|
import _noop from 'lodash-es/noop';
|
||||||
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
||||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
@ -35,6 +39,8 @@ function UplotPanelWrapper({
|
|||||||
const [maxTimeScale, setMaxTimeScale] = useState<number>();
|
const [maxTimeScale, setMaxTimeScale] = useState<number>();
|
||||||
const { currentQuery } = useQueryBuilder();
|
const { currentQuery } = useQueryBuilder();
|
||||||
|
|
||||||
|
const [hiddenGraph, setHiddenGraph] = useState<{ [key: string]: boolean }>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (toScrollWidgetId === widget.id) {
|
if (toScrollWidgetId === widget.id) {
|
||||||
graphRef.current?.scrollIntoView({
|
graphRef.current?.scrollIntoView({
|
||||||
@ -78,8 +84,26 @@ function UplotPanelWrapper({
|
|||||||
const chartData = getUPlotChartData(
|
const chartData = getUPlotChartData(
|
||||||
queryResponse?.data?.payload,
|
queryResponse?.data?.payload,
|
||||||
widget.fillSpans,
|
widget.fillSpans,
|
||||||
|
widget?.stackedBarChart,
|
||||||
|
hiddenGraph,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (widget.panelTypes === PANEL_TYPES.BAR && widget?.stackedBarChart) {
|
||||||
|
const graphV = cloneDeep(graphVisibility)?.slice(1);
|
||||||
|
const isSomeSelectedLegend = graphV?.some((v) => v === false);
|
||||||
|
if (isSomeSelectedLegend) {
|
||||||
|
const hiddenIndex = graphV?.findIndex((v) => v === true);
|
||||||
|
if (!isUndefined(hiddenIndex) && hiddenIndex !== -1) {
|
||||||
|
const updatedHiddenGraph = { [hiddenIndex]: true };
|
||||||
|
if (!isEqual(hiddenGraph, updatedHiddenGraph)) {
|
||||||
|
setHiddenGraph(updatedHiddenGraph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [graphVisibility, hiddenGraph, widget.panelTypes, widget?.stackedBarChart]);
|
||||||
|
|
||||||
const options = useMemo(
|
const options = useMemo(
|
||||||
() =>
|
() =>
|
||||||
getUPlotChartOptions({
|
getUPlotChartOptions({
|
||||||
@ -99,6 +123,9 @@ function UplotPanelWrapper({
|
|||||||
setGraphsVisibilityStates: setGraphVisibility,
|
setGraphsVisibilityStates: setGraphVisibility,
|
||||||
panelType: selectedGraph || widget.panelTypes,
|
panelType: selectedGraph || widget.panelTypes,
|
||||||
currentQuery,
|
currentQuery,
|
||||||
|
stackBarChart: widget?.stackedBarChart,
|
||||||
|
hiddenGraph,
|
||||||
|
setHiddenGraph,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
widget?.id,
|
widget?.id,
|
||||||
@ -107,6 +134,7 @@ function UplotPanelWrapper({
|
|||||||
widget.softMax,
|
widget.softMax,
|
||||||
widget.softMin,
|
widget.softMin,
|
||||||
widget.panelTypes,
|
widget.panelTypes,
|
||||||
|
widget?.stackedBarChart,
|
||||||
queryResponse.data?.payload,
|
queryResponse.data?.payload,
|
||||||
containerDimensions,
|
containerDimensions,
|
||||||
isDarkMode,
|
isDarkMode,
|
||||||
@ -118,15 +146,23 @@ function UplotPanelWrapper({
|
|||||||
setGraphVisibility,
|
setGraphVisibility,
|
||||||
selectedGraph,
|
selectedGraph,
|
||||||
currentQuery,
|
currentQuery,
|
||||||
|
hiddenGraph,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ height: '100%', width: '100%' }} ref={graphRef}>
|
<div style={{ height: '100%', width: '100%' }} ref={graphRef}>
|
||||||
<Uplot options={options} data={chartData} ref={lineChartRef} />
|
<Uplot options={options} data={chartData} ref={lineChartRef} />
|
||||||
{isFullViewMode && setGraphVisibility && (
|
{widget?.stackedBarChart && isFullViewMode && (
|
||||||
|
<Alert
|
||||||
|
message="Selecting multiple legends is currently not supported in case of stacked bar charts"
|
||||||
|
type="info"
|
||||||
|
className="info-text"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{isFullViewMode && setGraphVisibility && !widget?.stackedBarChart && (
|
||||||
<GraphManager
|
<GraphManager
|
||||||
data={chartData}
|
data={getUPlotChartData(queryResponse?.data?.payload, widget.fillSpans)}
|
||||||
name={widget.id}
|
name={widget.id}
|
||||||
options={options}
|
options={options}
|
||||||
yAxisUnit={widget.yAxisUnit}
|
yAxisUnit={widget.yAxisUnit}
|
||||||
|
@ -10,9 +10,11 @@ import { saveLegendEntriesToLocalStorage } from 'container/GridCardLayout/GridCa
|
|||||||
import { ThresholdProps } from 'container/NewWidget/RightContainer/Threshold/types';
|
import { ThresholdProps } from 'container/NewWidget/RightContainer/Threshold/types';
|
||||||
import { Dimensions } from 'hooks/useDimensions';
|
import { Dimensions } from 'hooks/useDimensions';
|
||||||
import { convertValue } from 'lib/getConvertedValue';
|
import { convertValue } from 'lib/getConvertedValue';
|
||||||
|
import { cloneDeep, isUndefined } from 'lodash-es';
|
||||||
import _noop from 'lodash-es/noop';
|
import _noop from 'lodash-es/noop';
|
||||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||||
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
import { QueryData, QueryDataV3 } from 'types/api/widgets/getQuery';
|
||||||
import uPlot from 'uplot';
|
import uPlot from 'uplot';
|
||||||
|
|
||||||
import onClickPlugin, { OnClickPluginOpts } from './plugins/onClickPlugin';
|
import onClickPlugin, { OnClickPluginOpts } from './plugins/onClickPlugin';
|
||||||
@ -42,6 +44,82 @@ export interface GetUPlotChartOptions {
|
|||||||
softMin: number | null;
|
softMin: number | null;
|
||||||
softMax: number | null;
|
softMax: number | null;
|
||||||
currentQuery?: Query;
|
currentQuery?: Query;
|
||||||
|
stackBarChart?: boolean;
|
||||||
|
hiddenGraph?: {
|
||||||
|
[key: string]: boolean;
|
||||||
|
};
|
||||||
|
setHiddenGraph?: Dispatch<
|
||||||
|
SetStateAction<{
|
||||||
|
[key: string]: boolean;
|
||||||
|
}>
|
||||||
|
>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** the function converts series A , series B , series C to
|
||||||
|
* series A , series A + series B , series A + series B + series C
|
||||||
|
* which helps us to always ensure the bar in the front is always
|
||||||
|
* of the smallest value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getStackedSeries(apiResponse: QueryData[]): QueryData[] {
|
||||||
|
const series = cloneDeep(apiResponse);
|
||||||
|
|
||||||
|
for (let i = series.length - 2; i >= 0; i--) {
|
||||||
|
const { values } = series[i];
|
||||||
|
for (let j = 0; j < values.length; j++) {
|
||||||
|
values[j][1] = String(
|
||||||
|
parseFloat(values[j][1]) + parseFloat(series[i + 1].values[j][1]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
series[i].values = values;
|
||||||
|
}
|
||||||
|
|
||||||
|
return series;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** this does the exact same operations as the function above for a different
|
||||||
|
* response format.
|
||||||
|
*/
|
||||||
|
function getStackedSeriesQueryFormat(apiResponse: QueryData[]): QueryData[] {
|
||||||
|
const series = cloneDeep(apiResponse);
|
||||||
|
|
||||||
|
for (let i = series.length - 2; i >= 0; i--) {
|
||||||
|
const { values } = series[i];
|
||||||
|
for (let j = 0; j < values.length; j++) {
|
||||||
|
values[j].value = String(
|
||||||
|
parseFloat(values[j].value) + parseFloat(series[i + 1].values[j].value),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
series[i].values = values;
|
||||||
|
}
|
||||||
|
|
||||||
|
return series;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStackedSeriesYAxis(apiResponse: QueryDataV3[]): QueryDataV3[] {
|
||||||
|
const series = cloneDeep(apiResponse);
|
||||||
|
|
||||||
|
for (let i = 0; i < series.length; i++) {
|
||||||
|
series[i].series = getStackedSeriesQueryFormat(series[i].series);
|
||||||
|
}
|
||||||
|
|
||||||
|
return series;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* here we define the different series bands which should get highlighted based
|
||||||
|
* on cursor hover. basically the to and the from destination of a particular band.
|
||||||
|
*/
|
||||||
|
function getBands(series): any[] {
|
||||||
|
const bands = [];
|
||||||
|
for (let i = 0; i < series.length; i++) {
|
||||||
|
bands.push({
|
||||||
|
series: [i === 0 ? -1 : i, i + 1],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return bands;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getUPlotChartOptions = ({
|
export const getUPlotChartOptions = ({
|
||||||
@ -61,9 +139,18 @@ export const getUPlotChartOptions = ({
|
|||||||
softMin,
|
softMin,
|
||||||
panelType,
|
panelType,
|
||||||
currentQuery,
|
currentQuery,
|
||||||
|
stackBarChart: stackChart,
|
||||||
|
hiddenGraph,
|
||||||
|
setHiddenGraph,
|
||||||
}: GetUPlotChartOptions): uPlot.Options => {
|
}: GetUPlotChartOptions): uPlot.Options => {
|
||||||
const timeScaleProps = getXAxisScale(minTimeScale, maxTimeScale);
|
const timeScaleProps = getXAxisScale(minTimeScale, maxTimeScale);
|
||||||
|
|
||||||
|
const stackBarChart = stackChart && isUndefined(hiddenGraph);
|
||||||
|
|
||||||
|
const series = getStackedSeries(apiResponse?.data?.result || []);
|
||||||
|
|
||||||
|
const bands = stackBarChart ? getBands(series) : null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
width: dimensions.width,
|
width: dimensions.width,
|
||||||
@ -91,6 +178,7 @@ export const getUPlotChartOptions = ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
padding: [16, 16, 8, 8],
|
padding: [16, 16, 8, 8],
|
||||||
|
bands,
|
||||||
scales: {
|
scales: {
|
||||||
x: {
|
x: {
|
||||||
spanGaps: true,
|
spanGaps: true,
|
||||||
@ -99,7 +187,9 @@ export const getUPlotChartOptions = ({
|
|||||||
y: {
|
y: {
|
||||||
...getYAxisScale({
|
...getYAxisScale({
|
||||||
thresholds,
|
thresholds,
|
||||||
series: apiResponse?.data?.newResult?.data?.result || [],
|
series: stackBarChart
|
||||||
|
? getStackedSeriesYAxis(apiResponse?.data?.newResult?.data?.result || [])
|
||||||
|
: apiResponse?.data?.newResult?.data?.result || [],
|
||||||
yAxisUnit,
|
yAxisUnit,
|
||||||
softMax,
|
softMax,
|
||||||
softMin,
|
softMin,
|
||||||
@ -107,7 +197,7 @@ export const getUPlotChartOptions = ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
tooltipPlugin({ apiResponse, yAxisUnit }),
|
tooltipPlugin({ apiResponse, yAxisUnit, stackBarChart }),
|
||||||
onClickPlugin({
|
onClickPlugin({
|
||||||
onClick: onClickHandler,
|
onClick: onClickHandler,
|
||||||
}),
|
}),
|
||||||
@ -192,6 +282,17 @@ export const getUPlotChartOptions = ({
|
|||||||
const seriesArray = Array.from(seriesEls);
|
const seriesArray = Array.from(seriesEls);
|
||||||
seriesArray.forEach((seriesEl, index) => {
|
seriesArray.forEach((seriesEl, index) => {
|
||||||
seriesEl.addEventListener('click', () => {
|
seriesEl.addEventListener('click', () => {
|
||||||
|
if (stackChart) {
|
||||||
|
setHiddenGraph((prev) => {
|
||||||
|
if (isUndefined(prev)) {
|
||||||
|
return { [index]: true };
|
||||||
|
}
|
||||||
|
if (prev[index] === true) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return { [index]: true };
|
||||||
|
});
|
||||||
|
}
|
||||||
if (graphsVisibilityStates) {
|
if (graphsVisibilityStates) {
|
||||||
setGraphsVisibilityStates?.((prev) => {
|
setGraphsVisibilityStates?.((prev) => {
|
||||||
const newGraphVisibilityStates = [...prev];
|
const newGraphVisibilityStates = [...prev];
|
||||||
@ -221,11 +322,16 @@ export const getUPlotChartOptions = ({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
series: getSeries({
|
series: getSeries({
|
||||||
apiResponse,
|
series:
|
||||||
|
stackBarChart && isUndefined(hiddenGraph)
|
||||||
|
? series
|
||||||
|
: apiResponse?.data?.result,
|
||||||
widgetMetaData: apiResponse?.data.result,
|
widgetMetaData: apiResponse?.data.result,
|
||||||
graphsVisibilityStates,
|
graphsVisibilityStates,
|
||||||
panelType,
|
panelType,
|
||||||
currentQuery,
|
currentQuery,
|
||||||
|
stackBarChart,
|
||||||
|
hiddenGraph,
|
||||||
}),
|
}),
|
||||||
axes: getAxes(isDarkMode, yAxisUnit),
|
axes: getAxes(isDarkMode, yAxisUnit),
|
||||||
};
|
};
|
||||||
|
@ -22,6 +22,19 @@ interface UplotTooltipDataProps {
|
|||||||
queryName: string;
|
queryName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTooltipBaseValue(
|
||||||
|
data: any[],
|
||||||
|
index: number,
|
||||||
|
idx: number,
|
||||||
|
stackBarChart: boolean | undefined,
|
||||||
|
): any {
|
||||||
|
if (stackBarChart && index + 1 < data.length) {
|
||||||
|
return data[index][idx] - data[index + 1][idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
return data[index][idx];
|
||||||
|
}
|
||||||
|
|
||||||
const generateTooltipContent = (
|
const generateTooltipContent = (
|
||||||
seriesList: any[],
|
seriesList: any[],
|
||||||
data: any[],
|
data: any[],
|
||||||
@ -31,6 +44,7 @@ const generateTooltipContent = (
|
|||||||
isBillingUsageGraphs?: boolean,
|
isBillingUsageGraphs?: boolean,
|
||||||
isHistogramGraphs?: boolean,
|
isHistogramGraphs?: boolean,
|
||||||
isMergedSeries?: boolean,
|
isMergedSeries?: boolean,
|
||||||
|
stackBarChart?: boolean,
|
||||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||||
): HTMLElement => {
|
): HTMLElement => {
|
||||||
const container = document.createElement('div');
|
const container = document.createElement('div');
|
||||||
@ -67,7 +81,8 @@ const generateTooltipContent = (
|
|||||||
unit = '',
|
unit = '',
|
||||||
} = seriesList[index - 1] || {};
|
} = seriesList[index - 1] || {};
|
||||||
|
|
||||||
const value = data[index][idx];
|
const value = getTooltipBaseValue(data, index, idx, stackBarChart);
|
||||||
|
|
||||||
const dataIngested = quantity[idx];
|
const dataIngested = quantity[idx];
|
||||||
const label = isMergedSeries
|
const label = isMergedSeries
|
||||||
? ''
|
? ''
|
||||||
@ -201,6 +216,7 @@ type ToolTipPluginProps = {
|
|||||||
isBillingUsageGraphs?: boolean;
|
isBillingUsageGraphs?: boolean;
|
||||||
isHistogramGraphs?: boolean;
|
isHistogramGraphs?: boolean;
|
||||||
isMergedSeries?: boolean;
|
isMergedSeries?: boolean;
|
||||||
|
stackBarChart?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const tooltipPlugin = ({
|
const tooltipPlugin = ({
|
||||||
@ -209,6 +225,7 @@ const tooltipPlugin = ({
|
|||||||
isBillingUsageGraphs,
|
isBillingUsageGraphs,
|
||||||
isHistogramGraphs,
|
isHistogramGraphs,
|
||||||
isMergedSeries,
|
isMergedSeries,
|
||||||
|
stackBarChart,
|
||||||
}: ToolTipPluginProps): any => {
|
}: ToolTipPluginProps): any => {
|
||||||
let over: HTMLElement;
|
let over: HTMLElement;
|
||||||
let bound: HTMLElement;
|
let bound: HTMLElement;
|
||||||
@ -272,6 +289,7 @@ const tooltipPlugin = ({
|
|||||||
isBillingUsageGraphs,
|
isBillingUsageGraphs,
|
||||||
isHistogramGraphs,
|
isHistogramGraphs,
|
||||||
isMergedSeries,
|
isMergedSeries,
|
||||||
|
stackBarChart,
|
||||||
);
|
);
|
||||||
overlay.appendChild(content);
|
overlay.appendChild(content);
|
||||||
placement(overlay, anchor, 'right', 'start', { bound });
|
placement(overlay, anchor, 'right', 'start', { bound });
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
import { themeColors } from 'constants/theme';
|
import { themeColors } from 'constants/theme';
|
||||||
import getLabelName from 'lib/getLabelName';
|
import getLabelName from 'lib/getLabelName';
|
||||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
import { isUndefined } from 'lodash-es';
|
||||||
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
import { QueryData } from 'types/api/widgets/getQuery';
|
import { QueryData } from 'types/api/widgets/getQuery';
|
||||||
|
|
||||||
@ -28,16 +28,18 @@ const paths = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getSeries = ({
|
const getSeries = ({
|
||||||
apiResponse,
|
series,
|
||||||
widgetMetaData,
|
widgetMetaData,
|
||||||
graphsVisibilityStates,
|
graphsVisibilityStates,
|
||||||
panelType,
|
panelType,
|
||||||
|
hiddenGraph,
|
||||||
}: GetSeriesProps): uPlot.Options['series'] => {
|
}: GetSeriesProps): uPlot.Options['series'] => {
|
||||||
const configurations: uPlot.Series[] = [
|
const configurations: uPlot.Series[] = [
|
||||||
{ label: 'Timestamp', stroke: 'purple' },
|
{ label: 'Timestamp', stroke: 'purple' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const seriesList = apiResponse?.data.result || [];
|
const seriesList = series || [];
|
||||||
|
|
||||||
const newGraphVisibilityStates = graphsVisibilityStates?.slice(1);
|
const newGraphVisibilityStates = graphsVisibilityStates?.slice(1);
|
||||||
|
|
||||||
for (let i = 0; i < seriesList?.length; i += 1) {
|
for (let i = 0; i < seriesList?.length; i += 1) {
|
||||||
@ -64,7 +66,12 @@ const getSeries = ({
|
|||||||
panelType && panelType === PANEL_TYPES.BAR
|
panelType && panelType === PANEL_TYPES.BAR
|
||||||
? null
|
? null
|
||||||
: lineInterpolations.spline,
|
: lineInterpolations.spline,
|
||||||
show: newGraphVisibilityStates ? newGraphVisibilityStates[i] : true,
|
// eslint-disable-next-line no-nested-ternary
|
||||||
|
show: newGraphVisibilityStates
|
||||||
|
? newGraphVisibilityStates[i]
|
||||||
|
: !isUndefined(hiddenGraph)
|
||||||
|
? hiddenGraph[i]
|
||||||
|
: true,
|
||||||
label,
|
label,
|
||||||
fill: panelType && panelType === PANEL_TYPES.BAR ? `${color}40` : undefined,
|
fill: panelType && panelType === PANEL_TYPES.BAR ? `${color}40` : undefined,
|
||||||
stroke: color,
|
stroke: color,
|
||||||
@ -84,11 +91,15 @@ const getSeries = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type GetSeriesProps = {
|
export type GetSeriesProps = {
|
||||||
apiResponse?: MetricRangePayloadProps;
|
series?: QueryData[];
|
||||||
widgetMetaData: QueryData[];
|
widgetMetaData: QueryData[];
|
||||||
graphsVisibilityStates?: boolean[];
|
graphsVisibilityStates?: boolean[];
|
||||||
panelType?: PANEL_TYPES;
|
panelType?: PANEL_TYPES;
|
||||||
currentQuery?: Query;
|
currentQuery?: Query;
|
||||||
|
stackBarChart?: boolean;
|
||||||
|
hiddenGraph?: {
|
||||||
|
[key: string]: boolean;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default getSeries;
|
export default getSeries;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { cloneDeep, isUndefined } from 'lodash-es';
|
||||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||||
import { QueryData } from 'types/api/widgets/getQuery';
|
import { QueryData } from 'types/api/widgets/getQuery';
|
||||||
|
|
||||||
@ -62,9 +63,25 @@ function fillMissingXAxisTimestamps(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getStackedSeries(val: any): any {
|
||||||
|
const series = cloneDeep(val) || [];
|
||||||
|
|
||||||
|
for (let i = series.length - 2; i >= 0; i--) {
|
||||||
|
for (let j = 0; j < series[i].length; j++) {
|
||||||
|
series[i][j] += series[i + 1][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return series;
|
||||||
|
}
|
||||||
|
|
||||||
export const getUPlotChartData = (
|
export const getUPlotChartData = (
|
||||||
apiResponse?: MetricRangePayloadProps,
|
apiResponse?: MetricRangePayloadProps,
|
||||||
fillSpans?: boolean,
|
fillSpans?: boolean,
|
||||||
|
stackedBarChart?: boolean,
|
||||||
|
hiddenGraph?: {
|
||||||
|
[key: string]: boolean;
|
||||||
|
},
|
||||||
): any[] => {
|
): any[] => {
|
||||||
const seriesList = apiResponse?.data?.result || [];
|
const seriesList = apiResponse?.data?.result || [];
|
||||||
const timestampArr = getXAxisTimestamps(seriesList);
|
const timestampArr = getXAxisTimestamps(seriesList);
|
||||||
@ -74,5 +91,10 @@ export const getUPlotChartData = (
|
|||||||
fillSpans || false,
|
fillSpans || false,
|
||||||
);
|
);
|
||||||
|
|
||||||
return [timestampArr, ...yAxisValuesArr];
|
return [
|
||||||
|
timestampArr,
|
||||||
|
...(stackedBarChart && isUndefined(hiddenGraph)
|
||||||
|
? getStackedSeries(yAxisValuesArr)
|
||||||
|
: yAxisValuesArr),
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
@ -3,9 +3,7 @@ import { PANEL_TYPES } from 'constants/queryBuilder';
|
|||||||
import { GetSeriesProps } from '../../getSeriesData';
|
import { GetSeriesProps } from '../../getSeriesData';
|
||||||
|
|
||||||
export const seriesBarChartData = {
|
export const seriesBarChartData = {
|
||||||
apiResponse: {
|
series: [
|
||||||
data: {
|
|
||||||
result: [
|
|
||||||
{
|
{
|
||||||
metric: {},
|
metric: {},
|
||||||
values: [
|
values: [
|
||||||
@ -89,274 +87,7 @@ export const seriesBarChartData = {
|
|||||||
legend: 'forthLength',
|
legend: 'forthLength',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
resultType: '',
|
|
||||||
newResult: {
|
|
||||||
status: 'success',
|
|
||||||
data: {
|
|
||||||
resultType: '',
|
|
||||||
result: [
|
|
||||||
{
|
|
||||||
queryName: 'A',
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
labels: {},
|
|
||||||
labelsArray: [],
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
timestamp: 1708683240000,
|
|
||||||
value: '3378',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683300000,
|
|
||||||
value: '3269',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683360000,
|
|
||||||
value: '3341',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683420000,
|
|
||||||
value: '3269',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683480000,
|
|
||||||
value: '3296',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683540000,
|
|
||||||
value: '3280',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683600000,
|
|
||||||
value: '3260',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683660000,
|
|
||||||
value: '3351',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683720000,
|
|
||||||
value: '3345',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683780000,
|
|
||||||
value: '3370',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683840000,
|
|
||||||
value: '3382',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683900000,
|
|
||||||
value: '3249',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683960000,
|
|
||||||
value: '212',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
list: null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
queryName: 'B',
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
labels: {},
|
|
||||||
labelsArray: [],
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
timestamp: 1708683840000,
|
|
||||||
value: '2878',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683240000,
|
|
||||||
value: '2873',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683780000,
|
|
||||||
value: '2867',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683660000,
|
|
||||||
value: '2837',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683720000,
|
|
||||||
value: '2831',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683360000,
|
|
||||||
value: '2828',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683300000,
|
|
||||||
value: '2773',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683480000,
|
|
||||||
value: '2772',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683540000,
|
|
||||||
value: '2745',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683420000,
|
|
||||||
value: '2732',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683180000,
|
|
||||||
value: '2729',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683600000,
|
|
||||||
value: '2709',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683900000,
|
|
||||||
value: '2706',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
list: null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
queryName: 'F2',
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
labels: {
|
|
||||||
F2: 'F2',
|
|
||||||
},
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
timestamp: 1708683840000,
|
|
||||||
value: '504',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683240000,
|
|
||||||
value: '505',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683780000,
|
|
||||||
value: '503',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683660000,
|
|
||||||
value: '514',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683720000,
|
|
||||||
value: '514',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683360000,
|
|
||||||
value: '513',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683480000,
|
|
||||||
value: '524',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683540000,
|
|
||||||
value: '535',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683300000,
|
|
||||||
value: '496',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683420000,
|
|
||||||
value: '537',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683600000,
|
|
||||||
value: '551',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683900000,
|
|
||||||
value: '543',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683180000,
|
|
||||||
value: '-1157',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
list: null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
queryName: 'F1',
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
labels: {},
|
|
||||||
labelsArray: null,
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
timestamp: 1708683840000,
|
|
||||||
value: '6260',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683240000,
|
|
||||||
value: '6251',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683780000,
|
|
||||||
value: '6237',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683660000,
|
|
||||||
value: '6188',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683720000,
|
|
||||||
value: '6176',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683360000,
|
|
||||||
value: '6169',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683480000,
|
|
||||||
value: '6068',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683540000,
|
|
||||||
value: '6025',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683300000,
|
|
||||||
value: '6042',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683420000,
|
|
||||||
value: '6001',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683600000,
|
|
||||||
value: '5969',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683900000,
|
|
||||||
value: '5955',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683180000,
|
|
||||||
value: '4301',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
list: null,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
widgetMetaData: [
|
widgetMetaData: [
|
||||||
{
|
{
|
||||||
metric: {},
|
metric: {},
|
||||||
@ -446,9 +177,7 @@ export const seriesBarChartData = {
|
|||||||
} as GetSeriesProps;
|
} as GetSeriesProps;
|
||||||
|
|
||||||
export const seriesLineChartData = {
|
export const seriesLineChartData = {
|
||||||
apiResponse: {
|
series: [
|
||||||
data: {
|
|
||||||
result: [
|
|
||||||
{
|
{
|
||||||
metric: {},
|
metric: {},
|
||||||
values: [
|
values: [
|
||||||
@ -532,274 +261,7 @@ export const seriesLineChartData = {
|
|||||||
legend: 'forthLength',
|
legend: 'forthLength',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
resultType: '',
|
|
||||||
newResult: {
|
|
||||||
status: 'success',
|
|
||||||
data: {
|
|
||||||
resultType: '',
|
|
||||||
result: [
|
|
||||||
{
|
|
||||||
queryName: 'A',
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
labels: {},
|
|
||||||
labelsArray: [],
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
timestamp: 1708683240000,
|
|
||||||
value: '3378',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683300000,
|
|
||||||
value: '3269',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683360000,
|
|
||||||
value: '3341',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683420000,
|
|
||||||
value: '3269',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683480000,
|
|
||||||
value: '3296',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683540000,
|
|
||||||
value: '3280',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683600000,
|
|
||||||
value: '3260',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683660000,
|
|
||||||
value: '3351',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683720000,
|
|
||||||
value: '3345',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683780000,
|
|
||||||
value: '3370',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683840000,
|
|
||||||
value: '3382',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683900000,
|
|
||||||
value: '3249',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683960000,
|
|
||||||
value: '212',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
list: null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
queryName: 'B',
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
labels: {},
|
|
||||||
labelsArray: [],
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
timestamp: 1708683840000,
|
|
||||||
value: '2878',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683240000,
|
|
||||||
value: '2873',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683780000,
|
|
||||||
value: '2867',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683660000,
|
|
||||||
value: '2837',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683720000,
|
|
||||||
value: '2831',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683360000,
|
|
||||||
value: '2828',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683300000,
|
|
||||||
value: '2773',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683480000,
|
|
||||||
value: '2772',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683540000,
|
|
||||||
value: '2745',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683420000,
|
|
||||||
value: '2732',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683180000,
|
|
||||||
value: '2729',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683600000,
|
|
||||||
value: '2709',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683900000,
|
|
||||||
value: '2706',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
list: null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
queryName: 'F2',
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
labels: {
|
|
||||||
F2: 'F2',
|
|
||||||
},
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
timestamp: 1708683840000,
|
|
||||||
value: '504',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683240000,
|
|
||||||
value: '505',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683780000,
|
|
||||||
value: '503',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683660000,
|
|
||||||
value: '514',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683720000,
|
|
||||||
value: '514',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683360000,
|
|
||||||
value: '513',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683480000,
|
|
||||||
value: '524',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683540000,
|
|
||||||
value: '535',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683300000,
|
|
||||||
value: '496',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683420000,
|
|
||||||
value: '537',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683600000,
|
|
||||||
value: '551',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683900000,
|
|
||||||
value: '543',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683180000,
|
|
||||||
value: '-1157',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
list: null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
queryName: 'F1',
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
labels: {},
|
|
||||||
labelsArray: null,
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
timestamp: 1708683840000,
|
|
||||||
value: '6260',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683240000,
|
|
||||||
value: '6251',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683780000,
|
|
||||||
value: '6237',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683660000,
|
|
||||||
value: '6188',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683720000,
|
|
||||||
value: '6176',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683360000,
|
|
||||||
value: '6169',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683480000,
|
|
||||||
value: '6068',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683540000,
|
|
||||||
value: '6025',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683300000,
|
|
||||||
value: '6042',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683420000,
|
|
||||||
value: '6001',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683600000,
|
|
||||||
value: '5969',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683900000,
|
|
||||||
value: '5955',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1708683180000,
|
|
||||||
value: '4301',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
list: null,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
widgetMetaData: [
|
widgetMetaData: [
|
||||||
{
|
{
|
||||||
metric: {},
|
metric: {},
|
||||||
|
@ -27,6 +27,7 @@ describe('Get Series Data', () => {
|
|||||||
test('Should return seris drawline line chart for panel type time series', () => {
|
test('Should return seris drawline line chart for panel type time series', () => {
|
||||||
const seriesData = getSeries(seriesLineChartData);
|
const seriesData = getSeries(seriesLineChartData);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
||||||
expect(seriesData[1].drawStyle).toBe('line');
|
expect(seriesData[1].drawStyle).toBe('line');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -97,6 +97,7 @@ export interface IBaseWidget {
|
|||||||
timePreferance: timePreferenceType;
|
timePreferance: timePreferenceType;
|
||||||
stepSize?: number;
|
stepSize?: number;
|
||||||
yAxisUnit?: string;
|
yAxisUnit?: string;
|
||||||
|
stackedBarChart?: boolean;
|
||||||
bucketCount?: number;
|
bucketCount?: number;
|
||||||
bucketWidth?: number;
|
bucketWidth?: number;
|
||||||
mergeAllActiveQueries?: boolean;
|
mergeAllActiveQueries?: boolean;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user