mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Table: Fixes table panel gauge alignment (#64994)
* Table: Fixes tables guage alignment issues * Removed console.log * Fixing
This commit is contained in:
parent
09e3faaa4c
commit
a3de3c9dde
@ -1,5 +1,5 @@
|
||||
// BETTERER RESULTS V2.
|
||||
//
|
||||
//
|
||||
// If this file contains merge conflicts, use `betterer merge` to automatically resolve them:
|
||||
// https://phenomnomnominal.github.io/betterer/docs/results-file/#merge
|
||||
//
|
||||
|
@ -315,36 +315,32 @@ export function hasLinks(field: Field): boolean {
|
||||
}
|
||||
|
||||
export function getDisplayValueAlignmentFactors(values: FieldDisplay[]): DisplayValueAlignmentFactors {
|
||||
const info: DisplayValueAlignmentFactors = {
|
||||
title: '',
|
||||
text: '',
|
||||
};
|
||||
|
||||
let prefixLength = 0;
|
||||
let suffixLength = 0;
|
||||
let maxTitle = '';
|
||||
let maxText = '';
|
||||
let maxPrefix = '';
|
||||
let maxSuffix = '';
|
||||
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
const v = values[i].display;
|
||||
|
||||
if (v.text && v.text.length > info.text.length) {
|
||||
info.text = v.text;
|
||||
if (v.text && v.text.length > maxText.length) {
|
||||
maxText = v.text;
|
||||
}
|
||||
|
||||
if (v.title && v.title.length > info.title.length) {
|
||||
info.title = v.title;
|
||||
if (v.title && v.title.length > maxTitle.length) {
|
||||
maxTitle = v.title;
|
||||
}
|
||||
|
||||
if (v.prefix && v.prefix.length > prefixLength) {
|
||||
info.prefix = v.prefix;
|
||||
prefixLength = v.prefix.length;
|
||||
if (v.prefix && v.prefix.length > maxPrefix.length) {
|
||||
maxPrefix = v.prefix;
|
||||
}
|
||||
|
||||
if (v.suffix && v.suffix.length > suffixLength) {
|
||||
info.suffix = v.suffix;
|
||||
suffixLength = v.suffix.length;
|
||||
if (v.suffix && v.suffix.length > maxSuffix.length) {
|
||||
maxSuffix = v.suffix;
|
||||
}
|
||||
}
|
||||
return info;
|
||||
|
||||
return { text: maxText, title: maxTitle, suffix: maxSuffix, prefix: maxPrefix };
|
||||
}
|
||||
|
||||
function createNoValuesFieldDisplay(options: GetFieldDisplayValuesOptions): FieldDisplay {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { ScopedVars } from './ScopedVars';
|
||||
import { QueryResultBase, Labels, NullValueMode } from './data';
|
||||
import { DataLink, LinkModel } from './dataLink';
|
||||
import { DecimalCount, DisplayProcessor, DisplayValue } from './displayValue';
|
||||
import { DecimalCount, DisplayProcessor, DisplayValue, DisplayValueAlignmentFactors } from './displayValue';
|
||||
import { FieldColor } from './fieldColor';
|
||||
import { ThresholdsConfig } from './thresholds';
|
||||
import { ValueMapping } from './valueMapping';
|
||||
@ -204,6 +204,12 @@ export interface FieldState {
|
||||
* this would applied more than one time.
|
||||
*/
|
||||
nullThresholdApplied?: boolean;
|
||||
|
||||
/**
|
||||
* Can be used by visualizations to cache max display value lengths to aid alignment.
|
||||
* It's up to each visualization to calculate and set this.
|
||||
*/
|
||||
alignmentFactors?: DisplayValueAlignmentFactors;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
|
@ -32,7 +32,7 @@ export interface DisplayValue extends FormattedValue {
|
||||
* Used to align widths and heights when displaying multiple DisplayValues
|
||||
*/
|
||||
export interface DisplayValueAlignmentFactors extends FormattedValue {
|
||||
title: string;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export type DecimalCount = number | null | undefined;
|
||||
|
@ -1,7 +1,15 @@
|
||||
import { isFunction } from 'lodash';
|
||||
import React from 'react';
|
||||
|
||||
import { ThresholdsConfig, ThresholdsMode, VizOrientation, getFieldConfigWithMinMax } from '@grafana/data';
|
||||
import {
|
||||
ThresholdsConfig,
|
||||
ThresholdsMode,
|
||||
VizOrientation,
|
||||
getFieldConfigWithMinMax,
|
||||
DisplayValueAlignmentFactors,
|
||||
Field,
|
||||
DisplayValue,
|
||||
} from '@grafana/data';
|
||||
import { BarGaugeDisplayMode, BarGaugeValueMode } from '@grafana/schema';
|
||||
|
||||
import { BarGauge } from '../BarGauge/BarGauge';
|
||||
@ -57,6 +65,7 @@ export const BarGaugeCell = (props: TableCellProps) => {
|
||||
};
|
||||
|
||||
const hasLinks = Boolean(getLinks().length);
|
||||
const alignmentFactors = getAlignmentFactor(field, displayValue, cell.row.index);
|
||||
|
||||
const renderComponent = (menuProps: DataLinksContextMenuApi) => {
|
||||
const { openMenu, targetClassName } = menuProps;
|
||||
@ -71,6 +80,7 @@ export const BarGaugeCell = (props: TableCellProps) => {
|
||||
value={displayValue}
|
||||
orientation={VizOrientation.Horizontal}
|
||||
theme={tableStyles.theme}
|
||||
alignmentFactors={alignmentFactors}
|
||||
onClick={openMenu}
|
||||
className={targetClassName}
|
||||
itemSpacing={1}
|
||||
@ -92,3 +102,40 @@ export const BarGaugeCell = (props: TableCellProps) => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Getting gauge values to align is very tricky without looking at all values and passing them trough display processor. For very large tables that
|
||||
* could pretty expensive. So this is kind of a compromise. We look at the first 1000 rows and cache the longest value.
|
||||
* If we have a cached value we just check if the current value is longer and update the alignmentFactor. This can obviously still lead to
|
||||
* unaligned gauges but it should a lot less common.
|
||||
**/
|
||||
function getAlignmentFactor(field: Field, displayValue: DisplayValue, rowIndex: number): DisplayValueAlignmentFactors {
|
||||
let alignmentFactor = field.state?.alignmentFactors;
|
||||
|
||||
if (alignmentFactor) {
|
||||
// check if current alignmentFactor is still the longest
|
||||
if (alignmentFactor.text.length < displayValue.text.length) {
|
||||
alignmentFactor.text = displayValue.text;
|
||||
}
|
||||
return alignmentFactor;
|
||||
} else {
|
||||
// look at the next 100 rows
|
||||
alignmentFactor = { ...displayValue };
|
||||
const maxIndex = Math.min(field.values.length, rowIndex + 1000);
|
||||
|
||||
for (let i = rowIndex + 1; i < maxIndex; i++) {
|
||||
const nextDisplayValue = field.display!(field.values.get(i));
|
||||
if (nextDisplayValue.text.length > alignmentFactor.text.length) {
|
||||
alignmentFactor.text = displayValue.text;
|
||||
}
|
||||
}
|
||||
|
||||
if (field.state) {
|
||||
field.state.alignmentFactors = alignmentFactor;
|
||||
} else {
|
||||
field.state = { alignmentFactors: alignmentFactor };
|
||||
}
|
||||
|
||||
return alignmentFactor;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user