[charts] Fix multilayer time axis styles (#116749) (#117296)

This commit fixes a set of issues to the new multilayer time axis:
- the tickLine is now removed from ticks without a label
- the axis/tick/label style is restored to the original EUI one
- the multilayer time axis style is now moved into the charts plugin and reused
- Lens: use the single-layer time axis when bars cluster is used
- TSVB: I reduced a bit the number of ticks on the Y axis, to reduce the noise of gridlines with multilayer axis
- Discover: I reduced by 8px the height of the histogram and moved the top padding to the bottom to separate a bit the time range text and the time axis

Coming from @elastic/charts update:
- multilayer time axis tick/grid is shown only when tick is inside domain (this removes the black vertical axis line at the beginning of the chart) fix(xy): show mouse cursors on charts with opaque background elastic-charts#1447
- Fix the invisible cursor on charts with opaque backgrounds fix(xy): multilayer time axis tick/grid only when tick is inside domain elastic-charts#1446
- Add missing last tick and rarify gridlines fix(xy): adding missing last tick and other tick improvements elastic-charts#1448

Co-authored-by: Marco Vettorello <vettorello.marco@gmail.com>
This commit is contained in:
Kibana Machine 2021-11-03 10:38:06 -04:00 committed by GitHub
parent 3b8a80b95b
commit 3a739875ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 124 additions and 176 deletions

View file

@ -98,7 +98,7 @@
"@elastic/apm-synthtrace": "link:bazel-bin/packages/elastic-apm-synthtrace",
"@elastic/apm-rum": "^5.9.1",
"@elastic/apm-rum-react": "^1.3.1",
"@elastic/charts": "38.1.0",
"@elastic/charts": "38.1.3",
"@elastic/datemath": "link:bazel-bin/packages/elastic-datemath",
"@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@^8.0.0-canary.35",
"@elastic/ems-client": "8.0.0",

View file

@ -34,6 +34,7 @@ export {
ColorMode,
LabelRotation,
defaultCountLabel,
MULTILAYER_TIME_AXIS_STYLE,
} from './static';
export { ColorSchemaParams, Labels, Style } from './types';

View file

@ -19,3 +19,5 @@ export {
} from './color_maps';
export { ColorMode, LabelRotation, defaultCountLabel } from './components';
export * from './styles';

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export * from './multilayer_timeaxis';

View file

@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { Position, RecursivePartial, AxisStyle } from '@elastic/charts';
export const MULTILAYER_TIME_AXIS_STYLE: RecursivePartial<AxisStyle> = {
tickLabel: {
visible: true,
padding: 0,
rotation: 0,
alignment: {
vertical: Position.Bottom,
horizontal: Position.Left,
},
},
tickLine: {
visible: true,
size: 0.0001,
padding: 4,
},
};

View file

@ -9,3 +9,4 @@
export * from './colors';
export * from './components';
export * from './utils';
export * from '../../common/static/styles';

View file

@ -23,9 +23,6 @@ import {
Settings,
TooltipType,
XYChartElementEvent,
GridLineStyle,
AxisStyle,
RecursivePartial,
} from '@elastic/charts';
import { IUiSettingsClient } from 'kibana/public';
import {
@ -38,7 +35,7 @@ import { DataCharts$, DataChartsMessage } from '../../services/use_saved_search'
import { FetchStatus } from '../../../../types';
import { DiscoverServices } from '../../../../../build_services';
import { useDataState } from '../../utils/use_data_state';
import { LEGACY_TIME_AXIS } from '../../../../../../../charts/common';
import { LEGACY_TIME_AXIS, MULTILAYER_TIME_AXIS_STYLE } from '../../../../../../../charts/common';
export interface DiscoverHistogramProps {
savedSearchData$: DataCharts$;
@ -184,46 +181,6 @@ export function DiscoverHistogram({
const xAxisFormatter = services.data.fieldFormats.deserialize(chartData.yAxisFormat);
const useLegacyTimeAxis = uiSettings.get(LEGACY_TIME_AXIS, false);
const gridLineStyle: RecursivePartial<GridLineStyle> = useLegacyTimeAxis
? {}
: { strokeWidth: 0.1, stroke: isDarkMode ? 'white' : 'black' };
const verticalAxisStyle: RecursivePartial<AxisStyle> = useLegacyTimeAxis
? {}
: {
axisLine: {
visible: false,
},
tickLabel: {
fontSize: 11,
},
};
const xAxisStyle: RecursivePartial<AxisStyle> = useLegacyTimeAxis
? {}
: {
axisLine: {
stroke: isDarkMode ? 'lightgray' : 'darkgray',
strokeWidth: 1,
},
tickLine: {
size: 12,
strokeWidth: 0.15,
stroke: isDarkMode ? 'white' : 'black',
padding: -10,
visible: true,
},
tickLabel: {
fontSize: 11,
padding: 0,
alignment: {
vertical: Position.Bottom,
horizontal: Position.Left,
},
offset: {
x: 1.5,
y: 0,
},
},
};
return (
<React.Fragment>
@ -244,16 +201,13 @@ export function DiscoverHistogram({
ticks={2}
integersOnly
tickFormat={(value) => xAxisFormatter.convert(value)}
gridLine={gridLineStyle}
style={verticalAxisStyle}
/>
<Axis
id="discover-histogram-bottom-axis"
position={Position.Bottom}
tickFormat={formatXValue}
timeAxisLayerCount={useLegacyTimeAxis ? 0 : 2}
gridLine={gridLineStyle}
style={xAxisStyle}
style={useLegacyTimeAxis ? {} : MULTILAYER_TIME_AXIS_STYLE}
/>
<CurrentTime isDarkMode={isDarkMode} domainEnd={domainEnd} />
<Endzones

View file

@ -82,8 +82,8 @@ discover-app {
}
.dscHistogram {
height: $euiSize * 8;
padding: $euiSizeS $euiSizeS $euiSizeS $euiSizeS;
height: $euiSize * 7;
padding: 0 $euiSizeS $euiSizeS * 2 $euiSizeS;
}
.dscHistogramTimeRange {

View file

@ -32,7 +32,11 @@ import { getBaseTheme, getChartClasses } from './utils/theme';
import { TOOLTIP_MODES } from '../../../../../common/enums';
import { getValueOrEmpty } from '../../../../../common/empty_label';
import { getSplitByTermsColor } from '../../../lib/get_split_by_terms_color';
import { renderEndzoneTooltip, useActiveCursor } from '../../../../../../../charts/public';
import {
MULTILAYER_TIME_AXIS_STYLE,
renderEndzoneTooltip,
useActiveCursor,
} from '../../../../../../../charts/public';
import { getAxisLabelString } from '../../../components/lib/get_axis_label_string';
import { calculateDomainForSeries } from './utils/series_domain_calculation';
@ -140,49 +144,15 @@ export const TimeSeries = ({
[palettesService, series, syncColors]
);
const darkMode = uiSettings.get('theme:darkMode');
const gridLineStyle = !useLegacyTimeAxis
? {
visible: showGrid,
strokeWidth: 0.1,
stroke: darkMode ? 'white' : 'black',
}
: {
...GRID_LINE_CONFIG,
visible: showGrid,
};
const xAxisStyle = !useLegacyTimeAxis
? {
tickLabel: {
visible: true,
fontSize: 11,
padding: 0,
alignment: {
vertical: Position.Bottom,
horizontal: Position.Left,
},
offset: {
x: 1.5,
y: 0,
},
},
axisLine: {
stroke: darkMode ? 'lightgray' : 'darkgray',
strokeWidth: 1,
},
tickLine: {
size: 12,
strokeWidth: 0.15,
stroke: darkMode ? 'white' : 'black',
padding: -10,
visible: true,
},
axisTitle: {
visible: true,
padding: 0,
},
}
: {};
const gridLineStyle = {
...GRID_LINE_CONFIG,
visible: showGrid,
};
const shouldUseNewTimeAxis =
series.every(
({ stack, bars, lines }) => (bars?.show && stack !== STACKED_OPTIONS.NONE) || lines?.show
) && !useLegacyTimeAxis;
return (
<Chart ref={chartRef} renderer="canvas" className={classes}>
@ -361,10 +331,8 @@ export const TimeSeries = ({
position={position}
domain={domain}
hide={hide}
gridLine={{
...GRID_LINE_CONFIG,
visible: showGrid,
}}
gridLine={gridLineStyle}
ticks={5}
tickFormat={tickFormatter}
/>
))}
@ -375,8 +343,8 @@ export const TimeSeries = ({
title={getAxisLabelString(interval)}
tickFormat={xAxisFormatter}
gridLine={gridLineStyle}
style={xAxisStyle}
timeAxisLayerCount={useLegacyTimeAxis ? 0 : 3}
style={shouldUseNewTimeAxis ? MULTILAYER_TIME_AXIS_STYLE : undefined}
timeAxisLayerCount={shouldUseNewTimeAxis ? 3 : 0}
/>
</Chart>
);

View file

@ -8,16 +8,11 @@
import { identity } from 'lodash';
import {
AxisSpec,
TickFormatter,
YDomainRange,
ScaleType as ECScaleType,
Position,
} from '@elastic/charts';
import { AxisSpec, TickFormatter, YDomainRange, ScaleType as ECScaleType } from '@elastic/charts';
import { LabelRotation } from '../../../../charts/public';
import { BUCKET_TYPES } from '../../../../data/public';
import { MULTILAYER_TIME_AXIS_STYLE } from '../../../../charts/common';
import {
Aspect,
@ -164,29 +159,13 @@ function getAxisStyle(
): AxisSpec['style'] {
return isMultiLayerTimeAxis
? {
...MULTILAYER_TIME_AXIS_STYLE,
tickLabel: {
...MULTILAYER_TIME_AXIS_STYLE.tickLabel,
visible: Boolean(ticks?.show),
rotation: 0, // rotation is disabled on new time axis
fontSize: 11,
padding: 0,
alignment: {
vertical: Position.Bottom,
horizontal: Position.Left,
},
offset: {
x: 1.5,
y: 0,
},
},
axisLine: {
stroke: darkMode ? 'lightgray' : 'darkgray',
strokeWidth: 1,
},
tickLine: {
size: 12,
strokeWidth: 0.15,
stroke: darkMode ? 'white' : 'black',
padding: -10,
...MULTILAYER_TIME_AXIS_STYLE.tickLine,
visible: Boolean(ticks?.show),
},
axisTitle: {
@ -198,7 +177,7 @@ function getAxisStyle(
visible: (title ?? '').trim().length > 0,
},
tickLabel: {
visible: ticks?.show,
visible: Boolean(ticks?.show),
rotation: -(ticks?.rotation ?? rotationFallback),
},
};

View file

@ -46,7 +46,7 @@ exports[`xy_expression XYChart component it renders area 1`] = `
<Connect(SpecInstance)
gridLine={
Object {
"strokeWidth": 2,
"strokeWidth": 1,
"visible": true,
}
}
@ -101,6 +101,7 @@ exports[`xy_expression XYChart component it renders area 1`] = `
}
}
tickFormat={[Function]}
ticks={5}
title="a"
/>
<XyEndzones
@ -276,7 +277,7 @@ exports[`xy_expression XYChart component it renders bar 1`] = `
<Connect(SpecInstance)
gridLine={
Object {
"strokeWidth": 2,
"strokeWidth": 1,
"visible": true,
}
}
@ -331,6 +332,7 @@ exports[`xy_expression XYChart component it renders bar 1`] = `
}
}
tickFormat={[Function]}
ticks={5}
title="a"
/>
<XyEndzones
@ -520,7 +522,7 @@ exports[`xy_expression XYChart component it renders horizontal bar 1`] = `
<Connect(SpecInstance)
gridLine={
Object {
"strokeWidth": 2,
"strokeWidth": 1,
"visible": true,
}
}
@ -575,6 +577,7 @@ exports[`xy_expression XYChart component it renders horizontal bar 1`] = `
}
}
tickFormat={[Function]}
ticks={5}
title="a"
/>
<XyEndzones
@ -764,7 +767,7 @@ exports[`xy_expression XYChart component it renders line 1`] = `
<Connect(SpecInstance)
gridLine={
Object {
"strokeWidth": 2,
"strokeWidth": 1,
"visible": true,
}
}
@ -819,6 +822,7 @@ exports[`xy_expression XYChart component it renders line 1`] = `
}
}
tickFormat={[Function]}
ticks={5}
title="a"
/>
<XyEndzones
@ -994,7 +998,7 @@ exports[`xy_expression XYChart component it renders stacked area 1`] = `
<Connect(SpecInstance)
gridLine={
Object {
"strokeWidth": 2,
"strokeWidth": 1,
"visible": true,
}
}
@ -1049,6 +1053,7 @@ exports[`xy_expression XYChart component it renders stacked area 1`] = `
}
}
tickFormat={[Function]}
ticks={5}
title="a"
/>
<XyEndzones
@ -1232,7 +1237,7 @@ exports[`xy_expression XYChart component it renders stacked bar 1`] = `
<Connect(SpecInstance)
gridLine={
Object {
"strokeWidth": 2,
"strokeWidth": 1,
"visible": true,
}
}
@ -1287,6 +1292,7 @@ exports[`xy_expression XYChart component it renders stacked bar 1`] = `
}
}
tickFormat={[Function]}
ticks={5}
title="a"
/>
<XyEndzones
@ -1484,7 +1490,7 @@ exports[`xy_expression XYChart component it renders stacked horizontal bar 1`] =
<Connect(SpecInstance)
gridLine={
Object {
"strokeWidth": 2,
"strokeWidth": 1,
"visible": true,
}
}
@ -1539,6 +1545,7 @@ exports[`xy_expression XYChart component it renders stacked horizontal bar 1`] =
}
}
tickFormat={[Function]}
ticks={5}
title="a"
/>
<XyEndzones

View file

@ -32,7 +32,6 @@ import {
DisplayValueStyle,
RecursivePartial,
AxisStyle,
GridLineStyle,
ScaleType,
} from '@elastic/charts';
import { I18nProvider } from '@kbn/i18n/react';
@ -59,6 +58,7 @@ import {
SeriesLayer,
useActiveCursor,
} from '../../../../../src/plugins/charts/public';
import { MULTILAYER_TIME_AXIS_STYLE } from '../../../../../src/plugins/charts/common';
import { EmptyPlaceholder } from '../shared_components';
import { getFitOptions } from './fitting_functions';
import { getAxesConfiguration, GroupsConfiguration, validateExtent } from './axes_configuration';
@ -561,53 +561,35 @@ export function XYChart({
floatingColumns: legend?.floatingColumns ?? 1,
} as LegendPositionConfig;
// todo be moved in the chart plugin
const shouldUseNewTimeAxis = isTimeViz && !useLegacyTimeAxis && !shouldRotate;
const isHistogramModeEnabled = filteredLayers.some(
({ isHistogram, seriesType, splitAccessor }) =>
isHistogram &&
(seriesType.includes('stacked') || !splitAccessor) &&
(seriesType.includes('stacked') ||
!seriesType.includes('bar') ||
!chartHasMoreThanOneBarSeries)
);
const gridLineStyle: RecursivePartial<GridLineStyle> = shouldUseNewTimeAxis
? {
visible: gridlinesVisibilitySettings?.x,
strokeWidth: 0.1,
stroke: darkMode ? 'white' : 'black',
}
: {
visible: gridlinesVisibilitySettings?.x,
strokeWidth: 2,
};
const shouldUseNewTimeAxis =
isTimeViz && isHistogramModeEnabled && !useLegacyTimeAxis && !shouldRotate;
const gridLineStyle = {
visible: gridlinesVisibilitySettings?.x,
strokeWidth: 1,
};
const xAxisStyle: RecursivePartial<AxisStyle> = shouldUseNewTimeAxis
? {
...MULTILAYER_TIME_AXIS_STYLE,
tickLabel: {
...MULTILAYER_TIME_AXIS_STYLE.tickLabel,
visible: Boolean(tickLabelsVisibilitySettings?.x),
rotation: 0, // rotation is disabled on new time axis
fontSize: 11,
padding:
referenceLinePaddings.bottom != null ? { inner: referenceLinePaddings.bottom } : 0,
alignment: {
vertical: Position.Bottom,
horizontal: Position.Left,
},
offset: {
x: 1.5,
y: 0,
},
},
axisLine: {
stroke: darkMode ? 'lightgray' : 'darkgray',
strokeWidth: 1,
},
tickLine: {
size: 12,
strokeWidth: 0.15,
stroke: darkMode ? 'white' : 'black',
padding: -10,
...MULTILAYER_TIME_AXIS_STYLE.tickLine,
visible: Boolean(tickLabelsVisibilitySettings?.x),
},
axisTitle: {
visible: axisTitlesVisibilitySettings.x,
padding:
!tickLabelsVisibilitySettings?.x && referenceLinePaddings.bottom != null
? { inner: referenceLinePaddings.bottom }
: undefined,
},
}
: {
@ -715,6 +697,7 @@ export function XYChart({
tickFormat={(d) => axis.formatter?.convert(d) || ''}
style={getYAxesStyle(axis.groupId as 'left' | 'right')}
domain={getYAxisDomain(axis)}
ticks={5}
/>
);
})}

View file

@ -80,6 +80,24 @@ exports[`DonutChart component passes correct props without errors for valid prop
"strokeWidth": 1,
"visible": false,
},
"lumaSteps": Array [
224,
184,
128,
96,
64,
32,
16,
8,
4,
2,
1,
0,
0,
0,
0,
0,
],
"vertical": Object {
"dash": Array [
0,

View file

@ -2337,10 +2337,10 @@
dependencies:
object-hash "^1.3.0"
"@elastic/charts@38.1.0":
version "38.1.0"
resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-38.1.0.tgz#52146564c0e399da2267c10ec4536c33e50969e4"
integrity sha512-u2hQ8+daCvqapKQiFqN8QHWTz3OXby5Xf/ta1Dv59KTDTFIinCZD/M8PyD3MapbKx4b67hL7UxbErqr4rZ8jeA==
"@elastic/charts@38.1.3":
version "38.1.3"
resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-38.1.3.tgz#0bf27021c54176e87d38269613205f3d6219da96"
integrity sha512-p6bJQWmfJ5SLkcgAoAMB3eTah/2a3/r3uo3ZskEN/xdPiqU8P+GANF8+6F4dWNfejbrpSUyCUldl7S4nWFGg3Q==
dependencies:
"@popperjs/core" "^2.4.0"
chroma-js "^2.1.0"