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
@ -315,36 +315,32 @@ export function hasLinks(field: Field): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getDisplayValueAlignmentFactors(values: FieldDisplay[]): DisplayValueAlignmentFactors {
|
export function getDisplayValueAlignmentFactors(values: FieldDisplay[]): DisplayValueAlignmentFactors {
|
||||||
const info: DisplayValueAlignmentFactors = {
|
let maxTitle = '';
|
||||||
title: '',
|
let maxText = '';
|
||||||
text: '',
|
let maxPrefix = '';
|
||||||
};
|
let maxSuffix = '';
|
||||||
|
|
||||||
let prefixLength = 0;
|
|
||||||
let suffixLength = 0;
|
|
||||||
|
|
||||||
for (let i = 0; i < values.length; i++) {
|
for (let i = 0; i < values.length; i++) {
|
||||||
const v = values[i].display;
|
const v = values[i].display;
|
||||||
|
|
||||||
if (v.text && v.text.length > info.text.length) {
|
if (v.text && v.text.length > maxText.length) {
|
||||||
info.text = v.text;
|
maxText = v.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.title && v.title.length > info.title.length) {
|
if (v.title && v.title.length > maxTitle.length) {
|
||||||
info.title = v.title;
|
maxTitle = v.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.prefix && v.prefix.length > prefixLength) {
|
if (v.prefix && v.prefix.length > maxPrefix.length) {
|
||||||
info.prefix = v.prefix;
|
maxPrefix = v.prefix;
|
||||||
prefixLength = v.prefix.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.suffix && v.suffix.length > suffixLength) {
|
if (v.suffix && v.suffix.length > maxSuffix.length) {
|
||||||
info.suffix = v.suffix;
|
maxSuffix = v.suffix;
|
||||||
suffixLength = v.suffix.length;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return info;
|
|
||||||
|
return { text: maxText, title: maxTitle, suffix: maxSuffix, prefix: maxPrefix };
|
||||||
}
|
}
|
||||||
|
|
||||||
function createNoValuesFieldDisplay(options: GetFieldDisplayValuesOptions): FieldDisplay {
|
function createNoValuesFieldDisplay(options: GetFieldDisplayValuesOptions): FieldDisplay {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { ScopedVars } from './ScopedVars';
|
import { ScopedVars } from './ScopedVars';
|
||||||
import { QueryResultBase, Labels, NullValueMode } from './data';
|
import { QueryResultBase, Labels, NullValueMode } from './data';
|
||||||
import { DataLink, LinkModel } from './dataLink';
|
import { DataLink, LinkModel } from './dataLink';
|
||||||
import { DecimalCount, DisplayProcessor, DisplayValue } from './displayValue';
|
import { DecimalCount, DisplayProcessor, DisplayValue, DisplayValueAlignmentFactors } from './displayValue';
|
||||||
import { FieldColor } from './fieldColor';
|
import { FieldColor } from './fieldColor';
|
||||||
import { ThresholdsConfig } from './thresholds';
|
import { ThresholdsConfig } from './thresholds';
|
||||||
import { ValueMapping } from './valueMapping';
|
import { ValueMapping } from './valueMapping';
|
||||||
@ -204,6 +204,12 @@ export interface FieldState {
|
|||||||
* this would applied more than one time.
|
* this would applied more than one time.
|
||||||
*/
|
*/
|
||||||
nullThresholdApplied?: boolean;
|
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 */
|
/** @public */
|
||||||
|
@ -32,7 +32,7 @@ export interface DisplayValue extends FormattedValue {
|
|||||||
* Used to align widths and heights when displaying multiple DisplayValues
|
* Used to align widths and heights when displaying multiple DisplayValues
|
||||||
*/
|
*/
|
||||||
export interface DisplayValueAlignmentFactors extends FormattedValue {
|
export interface DisplayValueAlignmentFactors extends FormattedValue {
|
||||||
title: string;
|
title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DecimalCount = number | null | undefined;
|
export type DecimalCount = number | null | undefined;
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
import { isFunction } from 'lodash';
|
import { isFunction } from 'lodash';
|
||||||
import React from 'react';
|
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 { BarGaugeDisplayMode, BarGaugeValueMode } from '@grafana/schema';
|
||||||
|
|
||||||
import { BarGauge } from '../BarGauge/BarGauge';
|
import { BarGauge } from '../BarGauge/BarGauge';
|
||||||
@ -57,6 +65,7 @@ export const BarGaugeCell = (props: TableCellProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const hasLinks = Boolean(getLinks().length);
|
const hasLinks = Boolean(getLinks().length);
|
||||||
|
const alignmentFactors = getAlignmentFactor(field, displayValue, cell.row.index);
|
||||||
|
|
||||||
const renderComponent = (menuProps: DataLinksContextMenuApi) => {
|
const renderComponent = (menuProps: DataLinksContextMenuApi) => {
|
||||||
const { openMenu, targetClassName } = menuProps;
|
const { openMenu, targetClassName } = menuProps;
|
||||||
@ -71,6 +80,7 @@ export const BarGaugeCell = (props: TableCellProps) => {
|
|||||||
value={displayValue}
|
value={displayValue}
|
||||||
orientation={VizOrientation.Horizontal}
|
orientation={VizOrientation.Horizontal}
|
||||||
theme={tableStyles.theme}
|
theme={tableStyles.theme}
|
||||||
|
alignmentFactors={alignmentFactors}
|
||||||
onClick={openMenu}
|
onClick={openMenu}
|
||||||
className={targetClassName}
|
className={targetClassName}
|
||||||
itemSpacing={1}
|
itemSpacing={1}
|
||||||
@ -92,3 +102,40 @@ export const BarGaugeCell = (props: TableCellProps) => {
|
|||||||
</div>
|
</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