GraphNG: Fix tooltip displaying wrong or no data (#32312)

pull/32353/head
Dominik Prokop 4 years ago committed by GitHub
parent a0db4dce32
commit 95c65a1f4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      packages/grafana-ui/src/components/GraphNG/GraphNG.tsx
  2. 32
      packages/grafana-ui/src/components/GraphNG/hooks.ts
  3. 11
      packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin.tsx
  4. 2
      public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx

@ -188,6 +188,7 @@ class UnthemedGraphNG extends React.Component<GraphNGProps, GraphNGState> {
value={{ value={{
mapSeriesIndexToDataFrameFieldIndex: this.mapSeriesIndexToDataFrameFieldIndex, mapSeriesIndexToDataFrameFieldIndex: this.mapSeriesIndexToDataFrameFieldIndex,
dimFields: this.state.dimFields, dimFields: this.state.dimFields,
data: this.state.alignedDataFrame,
}} }}
> >
<VizLayout width={width} height={height} legend={this.renderLegend()}> <VizLayout width={width} height={height} legend={this.renderLegend()}>

@ -6,6 +6,7 @@ import React, { useCallback, useContext } from 'react';
interface GraphNGContextType { interface GraphNGContextType {
mapSeriesIndexToDataFrameFieldIndex: (index: number) => DataFrameFieldIndex; mapSeriesIndexToDataFrameFieldIndex: (index: number) => DataFrameFieldIndex;
dimFields: XYFieldMatchers; dimFields: XYFieldMatchers;
data: DataFrame;
} }
/** @alpha */ /** @alpha */
@ -16,30 +17,25 @@ export const GraphNGContext = React.createContext<GraphNGContextType>({} as Grap
* Exposes API for data frame inspection in Plot plugins * Exposes API for data frame inspection in Plot plugins
*/ */
export const useGraphNGContext = () => { export const useGraphNGContext = () => {
const graphCtx = useContext<GraphNGContextType>(GraphNGContext); const { data, dimFields, mapSeriesIndexToDataFrameFieldIndex } = useContext<GraphNGContextType>(GraphNGContext);
const getXAxisField = useCallback( const getXAxisField = useCallback(() => {
(data: DataFrame[]) => { const xFieldMatcher = dimFields.x;
const xFieldMatcher = graphCtx.dimFields.x; let xField: Field | null = null;
let xField: Field | null = null;
for (let i = 0; i < data.length; i++) { for (let j = 0; j < data.fields.length; j++) {
const frame = data[i]; if (xFieldMatcher(data.fields[j], data, [data])) {
for (let j = 0; j < frame.fields.length; j++) { xField = data.fields[j];
if (xFieldMatcher(frame.fields[j], frame, data)) { break;
xField = frame.fields[j];
break;
}
}
} }
}
return xField; return xField;
}, }, [data, dimFields]);
[graphCtx]
);
return { return {
...graphCtx, dimFields,
mapSeriesIndexToDataFrameFieldIndex,
getXAxisField, getXAxisField,
}; };
}; };

@ -29,7 +29,7 @@ export const TooltipPlugin: React.FC<TooltipPluginProps> = ({ mode = 'single', t
const plotContext = usePlotContext(); const plotContext = usePlotContext();
const graphContext = useGraphNGContext(); const graphContext = useGraphNGContext();
let xField = graphContext.getXAxisField(otherProps.data); let xField = graphContext.getXAxisField();
if (!xField) { if (!xField) {
return null; return null;
} }
@ -60,8 +60,9 @@ export const TooltipPlugin: React.FC<TooltipPluginProps> = ({ mode = 'single', t
if (mode === 'single' && originFieldIndex !== null) { if (mode === 'single' && originFieldIndex !== null) {
const field = otherProps.data[originFieldIndex.frameIndex].fields[originFieldIndex.fieldIndex]; const field = otherProps.data[originFieldIndex.frameIndex].fields[originFieldIndex.fieldIndex];
const plotSeries = plotContext.getSeries(); const plotSeries = plotContext.getSeries();
const fieldFmt = field.display || getDisplayProcessor({ field, timeZone }); const fieldFmt = field.display || getDisplayProcessor({ field, timeZone });
const value = fieldFmt(plotContext.data[focusedSeriesIdx!][focusedPointIdx]);
tooltip = ( tooltip = (
<SeriesTable <SeriesTable
series={[ series={[
@ -69,7 +70,7 @@ export const TooltipPlugin: React.FC<TooltipPluginProps> = ({ mode = 'single', t
// TODO: align with uPlot typings // TODO: align with uPlot typings
color: (plotSeries[focusedSeriesIdx!].stroke as any)(), color: (plotSeries[focusedSeriesIdx!].stroke as any)(),
label: getFieldDisplayName(field, otherProps.data[originFieldIndex.frameIndex]), label: getFieldDisplayName(field, otherProps.data[originFieldIndex.frameIndex]),
value: fieldFmt(field.values.get(focusedPointIdx)).text, value: value ? formattedValueToString(value) : null,
}, },
]} ]}
timestamp={xVal} timestamp={xVal}
@ -94,11 +95,13 @@ export const TooltipPlugin: React.FC<TooltipPluginProps> = ({ mode = 'single', t
continue; continue;
} }
const value = field.display!(plotContext.data[i][focusedPointIdx]);
series.push({ series.push({
// TODO: align with uPlot typings // TODO: align with uPlot typings
color: (plotSeries[i].stroke as any)!(), color: (plotSeries[i].stroke as any)!(),
label: getFieldDisplayName(field, frame), label: getFieldDisplayName(field, frame),
value: formattedValueToString(field.display!(field.values.get(focusedPointIdx!))), value: value ? formattedValueToString(value) : null,
isActive: originFieldIndex isActive: originFieldIndex
? dataFrameFieldIndex.frameIndex === originFieldIndex.frameIndex && ? dataFrameFieldIndex.frameIndex === originFieldIndex.frameIndex &&
dataFrameFieldIndex.fieldIndex === originFieldIndex.fieldIndex dataFrameFieldIndex.fieldIndex === originFieldIndex.fieldIndex

@ -102,7 +102,7 @@ export const ContextMenuView: React.FC<ContextMenuProps> = ({
onClose(); onClose();
}); });
const xField = graphContext.getXAxisField(data); const xField = graphContext.getXAxisField();
if (!xField) { if (!xField) {
return null; return null;

Loading…
Cancel
Save