BarGauge: Improvements to value sizing and table inner width calculations (#30990)

* BarGauge: Increase min value width and fix height when setting manual text size

* updated snapshot

* Big improvement to bar gauge value sizing and fixing table gauge sizing

* removed unused const

* added a unit test
This commit is contained in:
Torkel Ödegaard 2021-02-09 14:18:08 +01:00 committed by GitHub
parent d963c6d868
commit 39d7ebc7d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 53 additions and 25 deletions

View File

@ -10,6 +10,7 @@ import {
getTitleStyles,
getValuePercent,
BarGaugeDisplayMode,
calculateBarAndValueDimensions,
} from './BarGauge';
import { getTheme } from '../../themes';
@ -211,4 +212,18 @@ describe('BarGauge', () => {
expect(wrapper).toMatchSnapshot();
});
});
describe('calculateBarAndValueDimensions', () => {
it('valueWidth should including paddings in valueWidth', () => {
const result = calculateBarAndValueDimensions(
getProps({
height: 30,
width: 100,
value: getValue(1, 'AA'),
orientation: VizOrientation.Horizontal,
})
);
expect(result.valueWidth).toBe(21);
});
});
});

View File

@ -30,7 +30,6 @@ import { Themeable } from '../../types';
const MIN_VALUE_HEIGHT = 18;
const MAX_VALUE_HEIGHT = 50;
const MIN_VALUE_WIDTH = 50;
const MAX_VALUE_WIDTH = 150;
const TITLE_LINE_HEIGHT = 1.5;
const VALUE_LINE_HEIGHT = 1;
@ -373,9 +372,15 @@ interface BarAndValueDimensions {
wrapperWidth: number;
}
function calculateBarAndValueDimensions(props: Props): BarAndValueDimensions {
const { height, width, orientation, text } = props;
/**
* @internal
* Only exported for unit tests
**/
export function calculateBarAndValueDimensions(props: Props): BarAndValueDimensions {
const { height, width, orientation, text, alignmentFactors } = props;
const titleDim = calculateTitleDimensions(props);
const value = alignmentFactors ?? props.value;
const valueString = formattedValueToString(value);
let maxBarHeight = 0;
let maxBarWidth = 0;
@ -384,25 +389,27 @@ function calculateBarAndValueDimensions(props: Props): BarAndValueDimensions {
let wrapperWidth = 0;
let wrapperHeight = 0;
// measure text with title font size or min 14px
const fontSizeToMeasureWith = text?.valueSize ?? Math.max(titleDim.fontSize, 12);
const realTextSize = measureText(valueString, fontSizeToMeasureWith);
const realValueWidth = realTextSize.width + VALUE_LEFT_PADDING * 2;
if (isVertical(orientation)) {
if (text?.valueSize) {
valueHeight = text.valueSize * VALUE_LINE_HEIGHT;
} else {
valueHeight = Math.min(Math.max(height * 0.1, MIN_VALUE_HEIGHT), MAX_VALUE_HEIGHT);
}
valueWidth = width;
maxBarHeight = height - (titleDim.height + valueHeight);
maxBarWidth = width;
wrapperWidth = width;
wrapperHeight = height - titleDim.height;
} else {
if (text?.valueSize) {
valueHeight = text.valueSize * VALUE_LINE_HEIGHT;
} else {
valueHeight = height - titleDim.height;
}
valueHeight = height - titleDim.height;
valueWidth = Math.max(Math.min(width * 0.2, MAX_VALUE_WIDTH), realValueWidth);
valueWidth = Math.max(Math.min(width * 0.2, MAX_VALUE_WIDTH), MIN_VALUE_WIDTH);
maxBarHeight = height - titleDim.height;
maxBarWidth = width - valueWidth - titleDim.width;
@ -479,7 +486,6 @@ export function getBasicAndGradientStyles(props: Props): BasicAndGradientStyles
if (isBasic) {
// Basic styles
barStyles.background = `${tinycolor(valueColor).setAlpha(0.35).toRgbString()}`;
barStyles.borderTop = `2px solid ${valueColor}`;
} else {
// Gradient styles
@ -499,6 +505,7 @@ export function getBasicAndGradientStyles(props: Props): BasicAndGradientStyles
// shift empty region back to fill gaps due to border radius
emptyBar.left = '-3px';
emptyBar.width = `${maxBarWidth - barWidth}px`;
if (isBasic) {
// Basic styles

View File

@ -62,6 +62,7 @@ exports[`BarGauge Render with basic options should render 1`] = `
"flexGrow": 1,
"left": "-3px",
"position": "relative",
"width": "180px",
}
}
/>

View File

@ -19,7 +19,7 @@ const defaultScale: ThresholdsConfig = {
};
export const BarGaugeCell: FC<TableCellProps> = (props) => {
const { field, column, tableStyles, cell, cellProps } = props;
const { field, innerWidth, tableStyles, cell, cellProps } = props;
let config = getFieldConfigWithMinMax(field, false);
if (!config.thresholds) {
@ -38,17 +38,10 @@ export const BarGaugeCell: FC<TableCellProps> = (props) => {
barGaugeMode = BarGaugeDisplayMode.Basic;
}
let width;
if (column.width) {
width = (column.width as number) - tableStyles.cellPadding * 2;
} else {
width = tableStyles.cellPadding * 2;
}
return (
<div {...cellProps} className={tableStyles.cellContainer}>
<BarGauge
width={width}
width={innerWidth}
height={tableStyles.cellHeightInner}
field={config}
display={field.display}

View File

@ -178,6 +178,8 @@ export const Table: FC<Props> = memo((props: Props) => {
tableStyles={tableStyles}
cell={cell}
onCellFilterAdded={onCellFilterAdded}
columnIndex={index}
columnCount={row.cells.length}
/>
))}
</div>

View File

@ -9,9 +9,11 @@ export interface Props {
field: Field;
tableStyles: TableStyles;
onCellFilterAdded?: TableFilterActionCallback;
columnIndex: number;
columnCount: number;
}
export const TableCell: FC<Props> = ({ cell, field, tableStyles, onCellFilterAdded }) => {
export const TableCell: FC<Props> = ({ cell, field, tableStyles, onCellFilterAdded, columnIndex, columnCount }) => {
const cellProps = cell.getCellProps();
if (!field.display) {
@ -23,6 +25,13 @@ export const TableCell: FC<Props> = ({ cell, field, tableStyles, onCellFilterAdd
cellProps.style.justifyContent = (cell.column as any).justifyContent;
}
let innerWidth = ((cell.column.width as number) ?? 24) - tableStyles.cellPadding * 2;
// last child sometimes have extra padding if there is a non overlay scrollbar
if (columnIndex === columnCount - 1) {
innerWidth -= tableStyles.lastChildExtraPadding;
}
return (
<>
{cell.render('Cell', {
@ -30,6 +39,7 @@ export const TableCell: FC<Props> = ({ cell, field, tableStyles, onCellFilterAdd
tableStyles,
onCellFilterAdded,
cellProps,
innerWidth,
})}
</>
);

View File

@ -13,7 +13,7 @@ export const getTableStyles = stylesFactory((theme: GrafanaTheme) => {
const bodyFontSize = 14;
const cellHeight = cellPadding * 2 + bodyFontSize * lineHeight;
const rowHoverBg = styleMixins.hoverColor(theme.colors.bg1, theme);
const scollbarWidth = getScrollbarWidth();
const lastChildExtraPadding = Math.max(getScrollbarWidth(), cellPadding);
const buildCellContainerStyle = (color?: string, background?: string) => {
return css`
@ -29,10 +29,7 @@ export const getTableStyles = stylesFactory((theme: GrafanaTheme) => {
&:last-child {
border-right: none;
> div {
padding-right: ${scollbarWidth + cellPadding}px;
}
padding-right: ${lastChildExtraPadding}px;
}
&:hover {
@ -54,6 +51,7 @@ export const getTableStyles = stylesFactory((theme: GrafanaTheme) => {
cellHeight,
buildCellContainerStyle,
cellPadding,
lastChildExtraPadding,
cellHeightInner: bodyFontSize * lineHeight,
rowHeight: cellHeight + 2,
table: css`

View File

@ -45,6 +45,7 @@ export interface TableCellProps extends CellProps<any> {
cellProps: CSSProperties;
field: Field;
onCellFilterAdded: TableFilterActionCallback;
innerWidth: number;
}
export type CellComponent = FC<TableCellProps>;

View File

@ -29,5 +29,6 @@ export function getScrollbarWidth() {
} else {
scrollbarWidth = 0;
}
return scrollbarWidth || 0;
}