Panel Editor: avoid updates when schema is the same (#32668)

This commit is contained in:
Ryan McKinley
2021-04-04 22:13:34 -07:00
committed by GitHub
parent daabf64aa1
commit 4a924c5ace
3 changed files with 33 additions and 5 deletions

View File

@@ -29,7 +29,7 @@ const PanelInspectorUnconnected: React.FC<Props> = ({ panel, dashboard, plugin }
}); });
const location = useLocation(); const location = useLocation();
const { data, isLoading, error } = usePanelLatestData(panel, dataOptions); const { data, isLoading, error } = usePanelLatestData(panel, dataOptions, true);
const metaDs = useDatasourceMetadata(data); const metaDs = useDatasourceMetadata(data);
const tabs = useInspectTabs(dashboard, plugin, error, metaDs); const tabs = useInspectTabs(dashboard, plugin, error, metaDs);
const defaultTab = new URLSearchParams(location.search).get('inspectTab') as InspectTab; const defaultTab = new URLSearchParams(location.search).get('inspectTab') as InspectTab;

View File

@@ -32,7 +32,7 @@ export const OptionsPane: React.FC<Props> = ({
}: Props) => { }: Props) => {
const styles = useStyles(getStyles); const styles = useStyles(getStyles);
const isVizPickerOpen = useSelector((state: StoreState) => state.panelEditor.isVizPickerOpen); const isVizPickerOpen = useSelector((state: StoreState) => state.panelEditor.isVizPickerOpen);
const { data } = usePanelLatestData(panel, { withTransforms: true, withFieldConfig: false }); const { data } = usePanelLatestData(panel, { withTransforms: true, withFieldConfig: false }, true);
return ( return (
<div className={styles.wrapper} aria-label={selectors.components.PanelEditor.OptionsPane.content}> <div className={styles.wrapper} aria-label={selectors.components.PanelEditor.OptionsPane.content}>

View File

@@ -1,4 +1,11 @@
import { DataQueryError, LoadingState, PanelData } from '@grafana/data'; import {
compareArrayValues,
compareDataFrameStructures,
DataFrame,
DataQueryError,
LoadingState,
PanelData,
} from '@grafana/data';
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import { PanelModel } from '../../state'; import { PanelModel } from '../../state';
import { Unsubscribable } from 'rxjs'; import { Unsubscribable } from 'rxjs';
@@ -14,16 +21,37 @@ interface UsePanelLatestData {
/** /**
* Subscribes and returns latest panel data from PanelQueryRunner * Subscribes and returns latest panel data from PanelQueryRunner
*/ */
export const usePanelLatestData = (panel: PanelModel, options: GetDataOptions): UsePanelLatestData => { export const usePanelLatestData = (
panel: PanelModel,
options: GetDataOptions,
checkSchema?: boolean
): UsePanelLatestData => {
const querySubscription = useRef<Unsubscribable>(); const querySubscription = useRef<Unsubscribable>();
const [latestData, setLatestData] = useState<PanelData>(); const [latestData, setLatestData] = useState<PanelData>();
useEffect(() => { useEffect(() => {
let last: DataFrame[] = [];
let lastUpdate = 0;
querySubscription.current = panel querySubscription.current = panel
.getQueryRunner() .getQueryRunner()
.getData(options) .getData(options)
.subscribe({ .subscribe({
next: (data) => setLatestData(data), next: (data) => {
if (checkSchema) {
const sameStructure = compareArrayValues(last, data.series, compareDataFrameStructures);
if (sameStructure) {
const now = Date.now();
const elapsed = now - lastUpdate;
if (elapsed < 10000) {
return; // avoid updates if the schema has not changed for 10s
}
lastUpdate = now;
}
last = data.series;
}
setLatestData(data);
},
}); });
return () => { return () => {