mirror of https://github.com/grafana/grafana.git
				
				
				
			StatusHistory: Fix rendering of value-mapped null (#69033)
This commit is contained in:
		
							parent
							
								
									56812def50
								
							
						
					
					
						commit
						37e2becdd7
					
				| 
						 | 
					@ -37,4 +37,4 @@ export interface FieldColor {
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export type FieldColorSeriesByMode = 'min' | 'max' | 'last';
 | 
					export type FieldColorSeriesByMode = 'min' | 'max' | 'last';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const FALLBACK_COLOR = 'gray';
 | 
					export const FALLBACK_COLOR = '#808080';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,6 +47,7 @@ export interface TimelineCoreOptions {
 | 
				
			||||||
  showValue: VisibilityMode;
 | 
					  showValue: VisibilityMode;
 | 
				
			||||||
  mergeValues?: boolean;
 | 
					  mergeValues?: boolean;
 | 
				
			||||||
  isDiscrete: (seriesIdx: number) => boolean;
 | 
					  isDiscrete: (seriesIdx: number) => boolean;
 | 
				
			||||||
 | 
					  hasMappedNull: (seriesIdx: number) => boolean;
 | 
				
			||||||
  getValueColor: (seriesIdx: number, value: unknown) => string;
 | 
					  getValueColor: (seriesIdx: number, value: unknown) => string;
 | 
				
			||||||
  label: (seriesIdx: number) => string;
 | 
					  label: (seriesIdx: number) => string;
 | 
				
			||||||
  getTimeRange: () => TimeRange;
 | 
					  getTimeRange: () => TimeRange;
 | 
				
			||||||
| 
						 | 
					@ -64,6 +65,7 @@ export function getConfig(opts: TimelineCoreOptions) {
 | 
				
			||||||
    mode,
 | 
					    mode,
 | 
				
			||||||
    numSeries,
 | 
					    numSeries,
 | 
				
			||||||
    isDiscrete,
 | 
					    isDiscrete,
 | 
				
			||||||
 | 
					    hasMappedNull,
 | 
				
			||||||
    rowHeight = 0,
 | 
					    rowHeight = 0,
 | 
				
			||||||
    colWidth = 0,
 | 
					    colWidth = 0,
 | 
				
			||||||
    showValue,
 | 
					    showValue,
 | 
				
			||||||
| 
						 | 
					@ -210,6 +212,7 @@ export function getConfig(opts: TimelineCoreOptions) {
 | 
				
			||||||
        let strokeWidth = round((series.width || 0) * uPlot.pxRatio);
 | 
					        let strokeWidth = round((series.width || 0) * uPlot.pxRatio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let discrete = isDiscrete(sidx);
 | 
					        let discrete = isDiscrete(sidx);
 | 
				
			||||||
 | 
					        let mappedNull = discrete && hasMappedNull(sidx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        u.ctx.save();
 | 
					        u.ctx.save();
 | 
				
			||||||
        rect(u.ctx, u.bbox.left, u.bbox.top, u.bbox.width, u.bbox.height);
 | 
					        rect(u.ctx, u.bbox.left, u.bbox.top, u.bbox.width, u.bbox.height);
 | 
				
			||||||
| 
						 | 
					@ -220,7 +223,7 @@ export function getConfig(opts: TimelineCoreOptions) {
 | 
				
			||||||
            for (let ix = 0; ix < dataY.length; ix++) {
 | 
					            for (let ix = 0; ix < dataY.length; ix++) {
 | 
				
			||||||
              let yVal = dataY[ix];
 | 
					              let yVal = dataY[ix];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              if (yVal != null) {
 | 
					              if (yVal != null || mappedNull) {
 | 
				
			||||||
                let left = Math.round(valToPosX(dataX[ix], scaleX, xDim, xOff));
 | 
					                let left = Math.round(valToPosX(dataX[ix], scaleX, xDim, xOff));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let nextIx = ix;
 | 
					                let nextIx = ix;
 | 
				
			||||||
| 
						 | 
					@ -262,7 +265,9 @@ export function getConfig(opts: TimelineCoreOptions) {
 | 
				
			||||||
            //let xShift = align === 1 ? 0 : align === -1 ? barWid : barWid / 2;
 | 
					            //let xShift = align === 1 ? 0 : align === -1 ? barWid : barWid / 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (let ix = idx0; ix <= idx1; ix++) {
 | 
					            for (let ix = idx0; ix <= idx1; ix++) {
 | 
				
			||||||
              if (dataY[ix] != null) {
 | 
					              let yVal = dataY[ix];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              if (yVal != null || mappedNull) {
 | 
				
			||||||
                // TODO: all xPos can be pre-computed once for all series in aligned set
 | 
					                // TODO: all xPos can be pre-computed once for all series in aligned set
 | 
				
			||||||
                let left = valToPosX(dataX[ix], scaleX, xDim, xOff);
 | 
					                let left = valToPosX(dataX[ix], scaleX, xDim, xOff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -278,7 +283,7 @@ export function getConfig(opts: TimelineCoreOptions) {
 | 
				
			||||||
                  strokeWidth,
 | 
					                  strokeWidth,
 | 
				
			||||||
                  iy,
 | 
					                  iy,
 | 
				
			||||||
                  ix,
 | 
					                  ix,
 | 
				
			||||||
                  dataY[ix],
 | 
					                  yVal,
 | 
				
			||||||
                  discrete
 | 
					                  discrete
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
| 
						 | 
					@ -316,10 +321,13 @@ export function getConfig(opts: TimelineCoreOptions) {
 | 
				
			||||||
            (series, dataX, dataY, scaleX, scaleY, valToPosX, valToPosY, xOff, yOff, xDim, yDim) => {
 | 
					            (series, dataX, dataY, scaleX, scaleY, valToPosX, valToPosY, xOff, yOff, xDim, yDim) => {
 | 
				
			||||||
              let strokeWidth = round((series.width || 0) * uPlot.pxRatio);
 | 
					              let strokeWidth = round((series.width || 0) * uPlot.pxRatio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              let discrete = isDiscrete(sidx);
 | 
				
			||||||
 | 
					              let mappedNull = discrete && hasMappedNull(sidx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              let y = round(yOff + yMids[sidx - 1]);
 | 
					              let y = round(yOff + yMids[sidx - 1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              for (let ix = 0; ix < dataY.length; ix++) {
 | 
					              for (let ix = 0; ix < dataY.length; ix++) {
 | 
				
			||||||
                if (dataY[ix] != null) {
 | 
					                if (dataY[ix] != null || mappedNull) {
 | 
				
			||||||
                  const boxRect = boxRectsBySeries[sidx - 1][ix];
 | 
					                  const boxRect = boxRectsBySeries[sidx - 1][ix];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                  if (!boxRect || boxRect.x >= xDim) {
 | 
					                  if (!boxRect || boxRect.x >= xDim) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,7 @@ import {
 | 
				
			||||||
  VisibilityMode,
 | 
					  VisibilityMode,
 | 
				
			||||||
  TimelineValueAlignment,
 | 
					  TimelineValueAlignment,
 | 
				
			||||||
  HideableFieldConfig,
 | 
					  HideableFieldConfig,
 | 
				
			||||||
 | 
					  MappingType,
 | 
				
			||||||
} from '@grafana/schema';
 | 
					} from '@grafana/schema';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  FIXED_UNIT,
 | 
					  FIXED_UNIT,
 | 
				
			||||||
| 
						 | 
					@ -112,6 +113,14 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<UPlotConfigOptions> = (
 | 
				
			||||||
    return !(mode && field.display && mode.startsWith('continuous-'));
 | 
					    return !(mode && field.display && mode.startsWith('continuous-'));
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const hasMappedNull = (field: Field) => {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      field.config.mappings?.some(
 | 
				
			||||||
 | 
					        (mapping) => mapping.type === MappingType.SpecialValue && mapping.options.match === 'null'
 | 
				
			||||||
 | 
					      ) || false
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const getValueColorFn = (seriesIdx: number, value: unknown) => {
 | 
					  const getValueColorFn = (seriesIdx: number, value: unknown) => {
 | 
				
			||||||
    const field = frame.fields[seriesIdx];
 | 
					    const field = frame.fields[seriesIdx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -130,6 +139,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<UPlotConfigOptions> = (
 | 
				
			||||||
    mode: mode!,
 | 
					    mode: mode!,
 | 
				
			||||||
    numSeries: frame.fields.length - 1,
 | 
					    numSeries: frame.fields.length - 1,
 | 
				
			||||||
    isDiscrete: (seriesIdx) => isDiscrete(frame.fields[seriesIdx]),
 | 
					    isDiscrete: (seriesIdx) => isDiscrete(frame.fields[seriesIdx]),
 | 
				
			||||||
 | 
					    hasMappedNull: (seriesIdx) => hasMappedNull(frame.fields[seriesIdx]),
 | 
				
			||||||
    mergeValues,
 | 
					    mergeValues,
 | 
				
			||||||
    rowHeight: rowHeight,
 | 
					    rowHeight: rowHeight,
 | 
				
			||||||
    colWidth: colWidth,
 | 
					    colWidth: colWidth,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue