mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-18 09:25:55 +08:00
Graph visibility state management. (#4632)
* refactor: change the state handling of graph visibility * refactor: removed commented code
This commit is contained in:
parent
7051831539
commit
e519539468
@ -5,7 +5,7 @@ import { CheckboxChangeEvent } from 'antd/es/checkbox';
|
|||||||
import { ResizeTable } from 'components/ResizeTable';
|
import { ResizeTable } from 'components/ResizeTable';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
||||||
import { memo, useCallback, useState } from 'react';
|
import { memo, useCallback, useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { getGraphManagerTableColumns } from './TableRender/GraphManagerColumns';
|
import { getGraphManagerTableColumns } from './TableRender/GraphManagerColumns';
|
||||||
import { ExtendedChartDataset, GraphManagerProps } from './types';
|
import { ExtendedChartDataset, GraphManagerProps } from './types';
|
||||||
@ -29,6 +29,10 @@ function GraphManager({
|
|||||||
getDefaultTableDataSet(options, data),
|
getDefaultTableDataSet(options, data),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTableDataSet(getDefaultTableDataSet(options, data));
|
||||||
|
}, [data, options]);
|
||||||
|
|
||||||
const { notifications } = useNotifications();
|
const { notifications } = useNotifications();
|
||||||
const { isDashboardLocked } = useDashboard();
|
const { isDashboardLocked } = useDashboard();
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariab
|
|||||||
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 { useDashboard } from 'providers/Dashboard/Dashboard';
|
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
@ -29,7 +29,7 @@ import uPlot from 'uplot';
|
|||||||
import { getSortedSeriesData } from 'utils/getSortedSeriesData';
|
import { getSortedSeriesData } from 'utils/getSortedSeriesData';
|
||||||
import { getTimeRange } from 'utils/getTimeRange';
|
import { getTimeRange } from 'utils/getTimeRange';
|
||||||
|
|
||||||
import { getGraphVisibilityStateOnDataChange } from '../utils';
|
import { getLocalStorageGraphVisibilityState } from '../utils';
|
||||||
import { PANEL_TYPES_VS_FULL_VIEW_TABLE } from './contants';
|
import { PANEL_TYPES_VS_FULL_VIEW_TABLE } from './contants';
|
||||||
import GraphManager from './GraphManager';
|
import GraphManager from './GraphManager';
|
||||||
import { GraphContainer, TimeContainer } from './styles';
|
import { GraphContainer, TimeContainer } from './styles';
|
||||||
@ -43,12 +43,10 @@ function FullView({
|
|||||||
version,
|
version,
|
||||||
originalName,
|
originalName,
|
||||||
yAxisUnit,
|
yAxisUnit,
|
||||||
options,
|
|
||||||
onDragSelect,
|
onDragSelect,
|
||||||
isDependedDataLoaded = false,
|
isDependedDataLoaded = false,
|
||||||
onToggleModelHandler,
|
onToggleModelHandler,
|
||||||
parentChartRef,
|
parentChartRef,
|
||||||
parentGraphVisibilityState,
|
|
||||||
}: FullViewProps): JSX.Element {
|
}: FullViewProps): JSX.Element {
|
||||||
const { selectedTime: globalSelectedTime } = useSelector<
|
const { selectedTime: globalSelectedTime } = useSelector<
|
||||||
AppState,
|
AppState,
|
||||||
@ -61,20 +59,6 @@ function FullView({
|
|||||||
|
|
||||||
const { selectedDashboard, isDashboardLocked } = useDashboard();
|
const { selectedDashboard, isDashboardLocked } = useDashboard();
|
||||||
|
|
||||||
const { graphVisibilityStates: localStoredVisibilityStates } = useMemo(
|
|
||||||
() =>
|
|
||||||
getGraphVisibilityStateOnDataChange({
|
|
||||||
options,
|
|
||||||
isExpandedName: false,
|
|
||||||
name: originalName,
|
|
||||||
}),
|
|
||||||
[options, originalName],
|
|
||||||
);
|
|
||||||
|
|
||||||
const [graphsVisibilityStates, setGraphsVisibilityStates] = useState(
|
|
||||||
localStoredVisibilityStates,
|
|
||||||
);
|
|
||||||
|
|
||||||
const getSelectedTime = useCallback(
|
const getSelectedTime = useCallback(
|
||||||
() =>
|
() =>
|
||||||
timeItems.find((e) => e.enum === (widget?.timePreferance || 'GLOBAL_TIME')),
|
timeItems.find((e) => e.enum === (widget?.timePreferance || 'GLOBAL_TIME')),
|
||||||
@ -105,6 +89,20 @@ function FullView({
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [graphsVisibilityStates, setGraphsVisibilityStates] = useState<
|
||||||
|
boolean[]
|
||||||
|
>(Array(response.data?.payload.data.result.length).fill(true));
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const {
|
||||||
|
graphVisibilityStates: localStoredVisibilityState,
|
||||||
|
} = getLocalStorageGraphVisibilityState({
|
||||||
|
apiResponse: response.data?.payload.data.result || [],
|
||||||
|
name: originalName,
|
||||||
|
});
|
||||||
|
setGraphsVisibilityStates(localStoredVisibilityState);
|
||||||
|
}, [originalName, response.data?.payload.data.result]);
|
||||||
|
|
||||||
const canModifyChart = useChartMutable({
|
const canModifyChart = useChartMutable({
|
||||||
panelType: widget.panelTypes,
|
panelType: widget.panelTypes,
|
||||||
panelTypeAndGraphManagerVisibility: PANEL_TYPES_VS_FULL_VIEW_TABLE,
|
panelTypeAndGraphManagerVisibility: PANEL_TYPES_VS_FULL_VIEW_TABLE,
|
||||||
@ -147,6 +145,7 @@ function FullView({
|
|||||||
: 300;
|
: 300;
|
||||||
|
|
||||||
const newChartOptions = getUPlotChartOptions({
|
const newChartOptions = getUPlotChartOptions({
|
||||||
|
id: originalName,
|
||||||
yAxisUnit: yAxisUnit || '',
|
yAxisUnit: yAxisUnit || '',
|
||||||
apiResponse: response.data?.payload,
|
apiResponse: response.data?.payload,
|
||||||
dimensions: {
|
dimensions: {
|
||||||
@ -174,8 +173,7 @@ function FullView({
|
|||||||
graphsVisibilityStates?.forEach((e, i) => {
|
graphsVisibilityStates?.forEach((e, i) => {
|
||||||
fullViewChartRef?.current?.toggleGraph(i, e);
|
fullViewChartRef?.current?.toggleGraph(i, e);
|
||||||
});
|
});
|
||||||
parentGraphVisibilityState(graphsVisibilityStates);
|
}, [graphsVisibilityStates]);
|
||||||
}, [graphsVisibilityStates, parentGraphVisibilityState]);
|
|
||||||
|
|
||||||
const isListView = widget.panelTypes === PANEL_TYPES.LIST;
|
const isListView = widget.panelTypes === PANEL_TYPES.LIST;
|
||||||
|
|
||||||
|
@ -52,13 +52,11 @@ export interface FullViewProps {
|
|||||||
name: string;
|
name: string;
|
||||||
version?: string;
|
version?: string;
|
||||||
originalName: string;
|
originalName: string;
|
||||||
options: uPlot.Options;
|
|
||||||
yAxisUnit?: string;
|
yAxisUnit?: string;
|
||||||
onDragSelect: (start: number, end: number) => void;
|
onDragSelect: (start: number, end: number) => void;
|
||||||
isDependedDataLoaded?: boolean;
|
isDependedDataLoaded?: boolean;
|
||||||
onToggleModelHandler?: GraphManagerProps['onToggleModelHandler'];
|
onToggleModelHandler?: GraphManagerProps['onToggleModelHandler'];
|
||||||
parentChartRef: GraphManagerProps['lineChartRef'];
|
parentChartRef: GraphManagerProps['lineChartRef'];
|
||||||
parentGraphVisibilityState: Dispatch<SetStateAction<boolean[]>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GraphManagerProps extends UplotProps {
|
export interface GraphManagerProps extends UplotProps {
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||||
|
import getLabelName from 'lib/getLabelName';
|
||||||
|
import { QueryData } from 'types/api/widgets/getQuery';
|
||||||
import uPlot from 'uplot';
|
import uPlot from 'uplot';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -55,6 +57,20 @@ export const getAbbreviatedLabel = (label: string): string => {
|
|||||||
return newLabel;
|
return newLabel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const showAllDataSetFromApiResponse = (
|
||||||
|
apiResponse: QueryData[],
|
||||||
|
): LegendEntryProps[] =>
|
||||||
|
apiResponse.map(
|
||||||
|
(item): LegendEntryProps => ({
|
||||||
|
label: getLabelName(
|
||||||
|
item.metric || {},
|
||||||
|
item.queryName || '',
|
||||||
|
item.legend || '',
|
||||||
|
),
|
||||||
|
show: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
export const showAllDataSet = (options: uPlot.Options): LegendEntryProps[] =>
|
export const showAllDataSet = (options: uPlot.Options): LegendEntryProps[] =>
|
||||||
options.series
|
options.series
|
||||||
.map(
|
.map(
|
||||||
|
@ -32,7 +32,7 @@ import WidgetHeader from '../WidgetHeader';
|
|||||||
import FullView from './FullView';
|
import FullView from './FullView';
|
||||||
import { Modal } from './styles';
|
import { Modal } from './styles';
|
||||||
import { WidgetGraphComponentProps } from './types';
|
import { WidgetGraphComponentProps } from './types';
|
||||||
import { getGraphVisibilityStateOnDataChange } from './utils';
|
import { getLocalStorageGraphVisibilityState } from './utils';
|
||||||
|
|
||||||
function WidgetGraphComponent({
|
function WidgetGraphComponent({
|
||||||
widget,
|
widget,
|
||||||
@ -63,20 +63,6 @@ function WidgetGraphComponent({
|
|||||||
const lineChartRef = useRef<ToggleGraphProps>();
|
const lineChartRef = useRef<ToggleGraphProps>();
|
||||||
const graphRef = useRef<HTMLDivElement>(null);
|
const graphRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (queryResponse.isSuccess) {
|
|
||||||
const {
|
|
||||||
graphVisibilityStates: localStoredVisibilityState,
|
|
||||||
} = getGraphVisibilityStateOnDataChange({
|
|
||||||
options,
|
|
||||||
isExpandedName: false,
|
|
||||||
name,
|
|
||||||
});
|
|
||||||
setGraphVisibility(localStoredVisibilityState);
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [queryResponse.isSuccess]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!lineChartRef.current) return;
|
if (!lineChartRef.current) return;
|
||||||
|
|
||||||
@ -219,6 +205,15 @@ function WidgetGraphComponent({
|
|||||||
const existingSearchParams = new URLSearchParams(search);
|
const existingSearchParams = new URLSearchParams(search);
|
||||||
existingSearchParams.delete(QueryParams.expandedWidgetId);
|
existingSearchParams.delete(QueryParams.expandedWidgetId);
|
||||||
const updatedQueryParams = Object.fromEntries(existingSearchParams.entries());
|
const updatedQueryParams = Object.fromEntries(existingSearchParams.entries());
|
||||||
|
if (queryResponse.data?.payload) {
|
||||||
|
const {
|
||||||
|
graphVisibilityStates: localStoredVisibilityState,
|
||||||
|
} = getLocalStorageGraphVisibilityState({
|
||||||
|
apiResponse: queryResponse.data.payload.data.result,
|
||||||
|
name,
|
||||||
|
});
|
||||||
|
setGraphVisibility(localStoredVisibilityState);
|
||||||
|
}
|
||||||
history.push({
|
history.push({
|
||||||
pathname,
|
pathname,
|
||||||
search: createQueryParams(updatedQueryParams),
|
search: createQueryParams(updatedQueryParams),
|
||||||
@ -290,9 +285,7 @@ function WidgetGraphComponent({
|
|||||||
yAxisUnit={widget.yAxisUnit}
|
yAxisUnit={widget.yAxisUnit}
|
||||||
onToggleModelHandler={onToggleModelHandler}
|
onToggleModelHandler={onToggleModelHandler}
|
||||||
parentChartRef={lineChartRef}
|
parentChartRef={lineChartRef}
|
||||||
parentGraphVisibilityState={setGraphVisibility}
|
|
||||||
onDragSelect={onDragSelect}
|
onDragSelect={onDragSelect}
|
||||||
options={options}
|
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import { getTimeRange } from 'utils/getTimeRange';
|
|||||||
import EmptyWidget from '../EmptyWidget';
|
import EmptyWidget from '../EmptyWidget';
|
||||||
import { MenuItemKeys } from '../WidgetHeader/contants';
|
import { MenuItemKeys } from '../WidgetHeader/contants';
|
||||||
import { GridCardGraphProps } from './types';
|
import { GridCardGraphProps } from './types';
|
||||||
|
import { getLocalStorageGraphVisibilityState } from './utils';
|
||||||
import WidgetGraphComponent from './WidgetGraphComponent';
|
import WidgetGraphComponent from './WidgetGraphComponent';
|
||||||
|
|
||||||
function GridCardGraph({
|
function GridCardGraph({
|
||||||
@ -186,6 +187,16 @@ function GridCardGraph({
|
|||||||
Array(queryResponse.data?.payload?.data.result.length || 0).fill(true),
|
Array(queryResponse.data?.payload?.data.result.length || 0).fill(true),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const {
|
||||||
|
graphVisibilityStates: localStoredVisibilityState,
|
||||||
|
} = getLocalStorageGraphVisibilityState({
|
||||||
|
apiResponse: queryResponse.data?.payload.data.result || [],
|
||||||
|
name,
|
||||||
|
});
|
||||||
|
setGraphVisibility(localStoredVisibilityState);
|
||||||
|
}, [name, queryResponse.data?.payload.data.result]);
|
||||||
|
|
||||||
const options = useMemo(
|
const options = useMemo(
|
||||||
() =>
|
() =>
|
||||||
getUPlotChartOptions({
|
getUPlotChartOptions({
|
||||||
|
@ -1,14 +1,78 @@
|
|||||||
/* eslint-disable sonarjs/cognitive-complexity */
|
/* eslint-disable sonarjs/cognitive-complexity */
|
||||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||||
|
import getLabelName from 'lib/getLabelName';
|
||||||
|
import { QueryData } from 'types/api/widgets/getQuery';
|
||||||
|
|
||||||
import { LegendEntryProps } from './FullView/types';
|
import { LegendEntryProps } from './FullView/types';
|
||||||
import { showAllDataSet } from './FullView/utils';
|
import {
|
||||||
|
showAllDataSet,
|
||||||
|
showAllDataSetFromApiResponse,
|
||||||
|
} from './FullView/utils';
|
||||||
import {
|
import {
|
||||||
GetGraphVisibilityStateOnLegendClickProps,
|
GetGraphVisibilityStateOnLegendClickProps,
|
||||||
GraphVisibilityLegendEntryProps,
|
GraphVisibilityLegendEntryProps,
|
||||||
ToggleGraphsVisibilityInChartProps,
|
ToggleGraphsVisibilityInChartProps,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
|
export const getLocalStorageGraphVisibilityState = ({
|
||||||
|
apiResponse,
|
||||||
|
name,
|
||||||
|
}: {
|
||||||
|
apiResponse: QueryData[];
|
||||||
|
name: string;
|
||||||
|
}): GraphVisibilityLegendEntryProps => {
|
||||||
|
const visibilityStateAndLegendEntry: GraphVisibilityLegendEntryProps = {
|
||||||
|
graphVisibilityStates: Array(apiResponse.length + 1).fill(true),
|
||||||
|
legendEntry: [
|
||||||
|
{
|
||||||
|
label: 'Timestamp',
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
...showAllDataSetFromApiResponse(apiResponse),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
if (localStorage.getItem(LOCALSTORAGE.GRAPH_VISIBILITY_STATES) !== null) {
|
||||||
|
const legendGraphFromLocalStore = localStorage.getItem(
|
||||||
|
LOCALSTORAGE.GRAPH_VISIBILITY_STATES,
|
||||||
|
);
|
||||||
|
let legendFromLocalStore: {
|
||||||
|
name: string;
|
||||||
|
dataIndex: LegendEntryProps[];
|
||||||
|
}[] = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
legendFromLocalStore = JSON.parse(legendGraphFromLocalStore || '[]');
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
'Error parsing GRAPH_VISIBILITY_STATES from local storage',
|
||||||
|
error,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newGraphVisibilityStates = Array(apiResponse.length + 1).fill(true);
|
||||||
|
legendFromLocalStore.forEach((item) => {
|
||||||
|
const newName = name;
|
||||||
|
if (item.name === newName) {
|
||||||
|
visibilityStateAndLegendEntry.legendEntry = item.dataIndex;
|
||||||
|
apiResponse.forEach((datasets, i) => {
|
||||||
|
const index = item.dataIndex.findIndex(
|
||||||
|
(dataKey) =>
|
||||||
|
dataKey.label ===
|
||||||
|
getLabelName(datasets.metric, datasets.queryName, datasets.legend || ''),
|
||||||
|
);
|
||||||
|
if (index !== -1) {
|
||||||
|
newGraphVisibilityStates[i + 1] = item.dataIndex[index].show;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
visibilityStateAndLegendEntry.graphVisibilityStates = newGraphVisibilityStates;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return visibilityStateAndLegendEntry;
|
||||||
|
};
|
||||||
|
|
||||||
export const getGraphVisibilityStateOnDataChange = ({
|
export const getGraphVisibilityStateOnDataChange = ({
|
||||||
options,
|
options,
|
||||||
isExpandedName,
|
isExpandedName,
|
||||||
|
@ -6,6 +6,7 @@ import './uPlotLib.styles.scss';
|
|||||||
|
|
||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
import { FullViewProps } from 'container/GridCardLayout/GridCard/FullView/types';
|
import { FullViewProps } from 'container/GridCardLayout/GridCard/FullView/types';
|
||||||
|
import { saveLegendEntriesToLocalStorage } from 'container/GridCardLayout/GridCard/FullView/utils';
|
||||||
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';
|
||||||
@ -203,6 +204,11 @@ export const getUPlotChartOptions = ({
|
|||||||
newGraphVisibilityStates.fill(false);
|
newGraphVisibilityStates.fill(false);
|
||||||
newGraphVisibilityStates[index + 1] = true;
|
newGraphVisibilityStates[index + 1] = true;
|
||||||
}
|
}
|
||||||
|
saveLegendEntriesToLocalStorage({
|
||||||
|
options: self,
|
||||||
|
graphVisibilityState: newGraphVisibilityStates,
|
||||||
|
name: id || '',
|
||||||
|
});
|
||||||
return newGraphVisibilityStates;
|
return newGraphVisibilityStates;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user