|
|
|
|
@ -37,6 +37,8 @@ import { |
|
|
|
|
PanelEvents, |
|
|
|
|
formattedValueToString, |
|
|
|
|
FieldType, |
|
|
|
|
DataFrame, |
|
|
|
|
getTimeField, |
|
|
|
|
} from '@grafana/data'; |
|
|
|
|
import { GraphContextMenuCtrl } from './GraphContextMenuCtrl'; |
|
|
|
|
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; |
|
|
|
|
@ -254,6 +256,7 @@ class GraphElement { |
|
|
|
|
const yAxisConfig = this.panel.yaxes[item.series.yaxis.n === 2 ? 1 : 0]; |
|
|
|
|
const dataFrame = this.ctrl.dataList[item.series.dataFrameIndex]; |
|
|
|
|
const field = dataFrame.fields[item.series.fieldIndex]; |
|
|
|
|
const dataIndex = this.getDataIndexWithNullValuesCorrection(item, dataFrame); |
|
|
|
|
|
|
|
|
|
let links = this.panel.options.dataLinks || []; |
|
|
|
|
if (field.config.links && field.config.links.length) { |
|
|
|
|
@ -267,13 +270,13 @@ class GraphElement { |
|
|
|
|
const fieldDisplay = getDisplayProcessor({ |
|
|
|
|
field: { config: fieldConfig, type: FieldType.number }, |
|
|
|
|
theme: getCurrentTheme(), |
|
|
|
|
})(field.values.get(item.dataIndex)); |
|
|
|
|
})(field.values.get(dataIndex)); |
|
|
|
|
linksSupplier = links.length |
|
|
|
|
? getFieldLinksSupplier({ |
|
|
|
|
display: fieldDisplay, |
|
|
|
|
name: field.name, |
|
|
|
|
view: new DataFrameView(dataFrame), |
|
|
|
|
rowIndex: item.dataIndex, |
|
|
|
|
rowIndex: dataIndex, |
|
|
|
|
colIndex: item.series.fieldIndex, |
|
|
|
|
field: fieldConfig, |
|
|
|
|
}) |
|
|
|
|
@ -290,6 +293,36 @@ class GraphElement { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
getDataIndexWithNullValuesCorrection(item: any, dataFrame: DataFrame): number { |
|
|
|
|
/** This is one added to handle the scenario where we have null values in |
|
|
|
|
* the time series data and the: "visualization options -> null value" |
|
|
|
|
* set to "connected". In this scenario we will get the wrong dataIndex. |
|
|
|
|
* |
|
|
|
|
* https://github.com/grafana/grafana/issues/22651
|
|
|
|
|
*/ |
|
|
|
|
const { datapoint, dataIndex } = item; |
|
|
|
|
|
|
|
|
|
if (!Array.isArray(datapoint) || datapoint.length === 0) { |
|
|
|
|
return dataIndex; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const ts = datapoint[0]; |
|
|
|
|
const { timeField } = getTimeField(dataFrame); |
|
|
|
|
|
|
|
|
|
if (!timeField || !timeField.values) { |
|
|
|
|
return dataIndex; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const field = timeField.values.get(dataIndex); |
|
|
|
|
|
|
|
|
|
if (field === ts) { |
|
|
|
|
return dataIndex; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const correctIndex = timeField.values.toArray().findIndex(value => value === ts); |
|
|
|
|
return correctIndex > -1 ? correctIndex : dataIndex; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
shouldAbortRender() { |
|
|
|
|
if (!this.data) { |
|
|
|
|
return true; |
|
|
|
|
|