mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Lens] make metric visualization scrollable when too tall (#138178)
This commit is contained in:
parent
0f974620c0
commit
387469be14
3 changed files with 88 additions and 33 deletions
|
@ -754,6 +754,7 @@ describe('MetricVisComponent', function () {
|
|||
/>
|
||||
)
|
||||
.find('div')
|
||||
.at(0)
|
||||
.props() as HtmlAttributes & { css: { styles: string } }
|
||||
).css.styles;
|
||||
|
||||
|
@ -763,6 +764,7 @@ describe('MetricVisComponent', function () {
|
|||
width: 100%;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
overflow-y: auto;
|
||||
"
|
||||
`);
|
||||
|
||||
|
@ -772,6 +774,7 @@ describe('MetricVisComponent', function () {
|
|||
width: 300px;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
overflow-y: auto;
|
||||
"
|
||||
`);
|
||||
|
||||
|
@ -781,6 +784,7 @@ describe('MetricVisComponent', function () {
|
|||
width: 1000px;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
overflow-y: auto;
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import numeral from '@elastic/numeral';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
@ -34,6 +34,7 @@ import type { FieldFormatConvertFunction } from '@kbn/field-formats-plugin/commo
|
|||
import { CUSTOM_PALETTE } from '@kbn/coloring';
|
||||
import { css } from '@emotion/react';
|
||||
import { euiThemeVars } from '@kbn/ui-theme';
|
||||
import { useResizeObserver } from '@elastic/eui';
|
||||
import { VisParams } from '../../common';
|
||||
import {
|
||||
getPaletteService,
|
||||
|
@ -307,6 +308,20 @@ export const MetricVis = ({
|
|||
pixelWidth = grid[0]?.length * maxTileSideLength;
|
||||
}
|
||||
|
||||
const [scrollChildHeight, setScrollChildHeight] = useState<string>('100%');
|
||||
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
||||
const scrollDimensions = useResizeObserver(scrollContainerRef.current);
|
||||
|
||||
useEffect(() => {
|
||||
const minTileHeight = 64; // TODO - magic number from the @elastic/charts side. would be nice to deduplicate
|
||||
const minimumRequiredVerticalSpace = minTileHeight * grid.length;
|
||||
setScrollChildHeight(
|
||||
(scrollDimensions.height ?? -Infinity) > minimumRequiredVerticalSpace
|
||||
? '100%'
|
||||
: `${minimumRequiredVerticalSpace}px`
|
||||
);
|
||||
}, [grid.length, scrollDimensions.height]);
|
||||
|
||||
// force chart to re-render to circumvent a charts bug
|
||||
const magicKey = useRef(0);
|
||||
useEffect(() => {
|
||||
|
@ -315,45 +330,53 @@ export const MetricVis = ({
|
|||
|
||||
return (
|
||||
<div
|
||||
ref={scrollContainerRef}
|
||||
css={css`
|
||||
height: ${pixelHeight ? `${pixelHeight}px` : '100%'};
|
||||
width: ${pixelWidth ? `${pixelWidth}px` : '100%'};
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
overflow-y: auto;
|
||||
`}
|
||||
>
|
||||
<Chart key={magicKey.current}>
|
||||
<Settings
|
||||
theme={[
|
||||
{
|
||||
background: { color: 'transparent' },
|
||||
metric: {
|
||||
background: defaultColor,
|
||||
barBackground: euiThemeVars.euiColorLightShade,
|
||||
<div
|
||||
css={css`
|
||||
height: ${scrollChildHeight};
|
||||
`}
|
||||
>
|
||||
<Chart key={magicKey.current}>
|
||||
<Settings
|
||||
theme={[
|
||||
{
|
||||
background: { color: 'transparent' },
|
||||
metric: {
|
||||
background: defaultColor,
|
||||
barBackground: euiThemeVars.euiColorLightShade,
|
||||
},
|
||||
},
|
||||
},
|
||||
chartTheme,
|
||||
]}
|
||||
onRenderChange={onRenderChange}
|
||||
onElementClick={(events) => {
|
||||
if (!filterable) {
|
||||
return;
|
||||
}
|
||||
events.forEach((event) => {
|
||||
if (isMetricElementEvent(event)) {
|
||||
const colIdx = breakdownByColumn
|
||||
? data.columns.findIndex((col) => col === breakdownByColumn)
|
||||
: data.columns.findIndex((col) => col === primaryMetricColumn);
|
||||
const rowLength = grid[0].length;
|
||||
fireEvent(
|
||||
buildFilterEvent(event.rowIndex * rowLength + event.columnIndex, colIdx, data)
|
||||
);
|
||||
chartTheme,
|
||||
]}
|
||||
onRenderChange={onRenderChange}
|
||||
onElementClick={(events) => {
|
||||
if (!filterable) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Metric id="metric" data={grid} />
|
||||
</Chart>
|
||||
events.forEach((event) => {
|
||||
if (isMetricElementEvent(event)) {
|
||||
const colIdx = breakdownByColumn
|
||||
? data.columns.findIndex((col) => col === breakdownByColumn)
|
||||
: data.columns.findIndex((col) => col === primaryMetricColumn);
|
||||
const rowLength = grid[0].length;
|
||||
fireEvent(
|
||||
buildFilterEvent(event.rowIndex * rowLength + event.columnIndex, colIdx, data)
|
||||
);
|
||||
}
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Metric id="metric" data={grid} />
|
||||
</Chart>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -174,7 +174,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
const colorPicker = await testSubjects.find('euiColorPickerAnchor');
|
||||
|
||||
colorPicker.clearValue();
|
||||
await colorPicker.clearValue();
|
||||
await colorPicker.type('#000000');
|
||||
|
||||
await PageObjects.lens.waitForVisualization('mtrVis');
|
||||
|
@ -213,10 +213,38 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.lens.waitForVisualization('mtrVis');
|
||||
|
||||
expect((await getMetricData()).map(({ color }) => color)).to.eql(expectedDynamicColors); // colors shouldn't change
|
||||
|
||||
await PageObjects.lens.closePaletteEditor();
|
||||
await PageObjects.lens.closeDimensionEditor();
|
||||
});
|
||||
|
||||
it('makes visualization scrollable if too tall', async () => {
|
||||
await PageObjects.lens.removeDimension('lnsMetric_breakdownByDimensionPanel');
|
||||
|
||||
await PageObjects.lens.configureDimension({
|
||||
dimension: 'lnsMetric_breakdownByDimensionPanel > lns-empty-dimension',
|
||||
operation: 'date_histogram',
|
||||
field: '@timestamp',
|
||||
keepOpen: true,
|
||||
});
|
||||
|
||||
await testSubjects.setValue('lnsMetric_max_cols', '1');
|
||||
|
||||
await PageObjects.lens.closeDimensionEditor();
|
||||
|
||||
const tiles = await getMetricTiles();
|
||||
const lastTile = tiles[tiles.length - 1];
|
||||
|
||||
const initialPosition = await lastTile.getPosition();
|
||||
await lastTile.scrollIntoViewIfNecessary();
|
||||
const scrolledPosition = await lastTile.getPosition();
|
||||
expect(scrolledPosition.y).to.be.below(initialPosition.y);
|
||||
});
|
||||
|
||||
it("doesn't error with empty formula", async () => {
|
||||
await PageObjects.lens.closePaletteEditor();
|
||||
await PageObjects.lens.openDimensionEditor(
|
||||
'lnsMetric_primaryMetricDimensionPanel > lns-dimensionTrigger'
|
||||
);
|
||||
|
||||
await PageObjects.lens.switchToFormula();
|
||||
await PageObjects.lens.typeFormula('');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue