From 24cbb32a97288792ae4f3719926b73a7071ac093 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 20 May 2022 16:27:14 +0300 Subject: [PATCH] [XY] `pointsRadius`, `showPoints` and `lineWidth`. (#130391) * Added pointsRadius, showPoints and lineWidth. * Added tests. Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../extended_data_layer.test.ts.snap | 6 ++ .../common_data_layer_args.ts | 12 +++ .../extended_data_layer.test.ts | 94 ++++++++++++------- .../extended_data_layer_fn.ts | 10 +- .../reference_line_layer.ts | 17 +--- .../reference_line_layer_fn.ts | 24 +++++ .../common/expression_functions/validate.ts | 51 ++++++++++ .../expression_functions/xy_vis.test.ts | 1 + .../common/expression_functions/xy_vis_fn.ts | 12 +++ .../expression_xy/common/i18n/index.tsx | 12 +++ .../common/types/expression_functions.ts | 8 +- .../public/components/xy_chart.test.tsx | 69 ++++++++++++++ .../public/helpers/data_layers.tsx | 56 ++++++++--- 13 files changed, 313 insertions(+), 59 deletions(-) create mode 100644 src/plugins/chart_expressions/expression_xy/common/expression_functions/reference_line_layer_fn.ts diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/__snapshots__/extended_data_layer.test.ts.snap b/src/plugins/chart_expressions/expression_xy/common/expression_functions/__snapshots__/extended_data_layer.test.ts.snap index 68262f8a4f3ded..9abd76c669b8f9 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/__snapshots__/extended_data_layer.test.ts.snap +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/__snapshots__/extended_data_layer.test.ts.snap @@ -1,5 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`extendedDataLayerConfig throws the error if lineWidth is provided to the not line/area chart 1`] = `"\`lineWidth\` can be applied only for line or area charts"`; + exports[`extendedDataLayerConfig throws the error if markSizeAccessor doesn't have the corresponding column in the table 1`] = `"Provided column name or index is invalid: nonsense"`; exports[`extendedDataLayerConfig throws the error if markSizeAccessor is provided to the not line/area chart 1`] = `"\`markSizeAccessor\` can't be used. Dots are applied only for line or area charts"`; + +exports[`extendedDataLayerConfig throws the error if pointsRadius is provided to the not line/area chart 1`] = `"\`pointsRadius\` can be applied only for line or area charts"`; + +exports[`extendedDataLayerConfig throws the error if showPoints is provided to the not line/area chart 1`] = `"\`showPoints\` can be applied only for line or area charts"`; diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/common_data_layer_args.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/common_data_layer_args.ts index f4543c5236ce27..c7f2da8ec15436 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/common_data_layer_args.ts +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/common_data_layer_args.ts @@ -43,6 +43,18 @@ export const commonDataLayerArgs: Omit< default: false, help: strings.getIsHistogramHelp(), }, + lineWidth: { + types: ['number'], + help: strings.getLineWidthHelp(), + }, + showPoints: { + types: ['boolean'], + help: strings.getShowPointsHelp(), + }, + pointsRadius: { + types: ['number'], + help: strings.getPointsRadiusHelp(), + }, yConfig: { types: [Y_CONFIG], help: strings.getYConfigHelp(), diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/extended_data_layer.test.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/extended_data_layer.test.ts index 5b943b0790313f..7f513168a8607e 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/extended_data_layer.test.ts +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/extended_data_layer.test.ts @@ -13,62 +13,92 @@ import { LayerTypes } from '../constants'; import { extendedDataLayerFunction } from './extended_data_layer'; describe('extendedDataLayerConfig', () => { + const args: ExtendedDataLayerArgs = { + seriesType: 'line', + xAccessor: 'c', + accessors: ['a', 'b'], + splitAccessor: 'd', + xScaleType: 'linear', + isHistogram: false, + palette: mockPaletteOutput, + }; + test('produces the correct arguments', async () => { const { data } = sampleArgs(); - const args: ExtendedDataLayerArgs = { - seriesType: 'line', - xAccessor: 'c', - accessors: ['a', 'b'], - splitAccessor: 'd', - xScaleType: 'linear', - isHistogram: false, - palette: mockPaletteOutput, + const fullArgs: ExtendedDataLayerArgs = { + ...args, markSizeAccessor: 'b', + showPoints: true, + lineWidth: 10, + pointsRadius: 10, }; - const result = await extendedDataLayerFunction.fn(data, args, createMockExecutionContext()); + const result = await extendedDataLayerFunction.fn(data, fullArgs, createMockExecutionContext()); expect(result).toEqual({ type: 'extendedDataLayer', layerType: LayerTypes.DATA, - ...args, + ...fullArgs, table: data, }); }); test('throws the error if markSizeAccessor is provided to the not line/area chart', async () => { const { data } = sampleArgs(); - const args: ExtendedDataLayerArgs = { - seriesType: 'bar', - xAccessor: 'c', - accessors: ['a', 'b'], - splitAccessor: 'd', - xScaleType: 'linear', - isHistogram: false, - palette: mockPaletteOutput, - markSizeAccessor: 'b', - }; expect( - extendedDataLayerFunction.fn(data, args, createMockExecutionContext()) + extendedDataLayerFunction.fn( + data, + { ...args, seriesType: 'bar', markSizeAccessor: 'b' }, + createMockExecutionContext() + ) ).rejects.toThrowErrorMatchingSnapshot(); }); test("throws the error if markSizeAccessor doesn't have the corresponding column in the table", async () => { const { data } = sampleArgs(); - const args: ExtendedDataLayerArgs = { - seriesType: 'line', - xAccessor: 'c', - accessors: ['a', 'b'], - splitAccessor: 'd', - xScaleType: 'linear', - isHistogram: false, - palette: mockPaletteOutput, - markSizeAccessor: 'nonsense', - }; expect( - extendedDataLayerFunction.fn(data, args, createMockExecutionContext()) + extendedDataLayerFunction.fn( + data, + { ...args, markSizeAccessor: 'nonsense' }, + createMockExecutionContext() + ) + ).rejects.toThrowErrorMatchingSnapshot(); + }); + + test('throws the error if lineWidth is provided to the not line/area chart', async () => { + const { data } = sampleArgs(); + expect( + extendedDataLayerFunction.fn( + data, + { ...args, seriesType: 'bar', lineWidth: 10 }, + createMockExecutionContext() + ) + ).rejects.toThrowErrorMatchingSnapshot(); + }); + + test('throws the error if showPoints is provided to the not line/area chart', async () => { + const { data } = sampleArgs(); + + expect( + extendedDataLayerFunction.fn( + data, + { ...args, seriesType: 'bar', showPoints: true }, + createMockExecutionContext() + ) + ).rejects.toThrowErrorMatchingSnapshot(); + }); + + test('throws the error if pointsRadius is provided to the not line/area chart', async () => { + const { data } = sampleArgs(); + + expect( + extendedDataLayerFunction.fn( + data, + { ...args, seriesType: 'bar', pointsRadius: 10 }, + createMockExecutionContext() + ) ).rejects.toThrowErrorMatchingSnapshot(); }); }); diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/extended_data_layer_fn.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/extended_data_layer_fn.ts index 8e5019e065133a..f45aea7e86d8d6 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/extended_data_layer_fn.ts +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/extended_data_layer_fn.ts @@ -10,7 +10,12 @@ import { validateAccessor } from '@kbn/visualizations-plugin/common/utils'; import { ExtendedDataLayerArgs, ExtendedDataLayerFn } from '../types'; import { EXTENDED_DATA_LAYER, LayerTypes } from '../constants'; import { getAccessors, normalizeTable } from '../helpers'; -import { validateMarkSizeForChartType } from './validate'; +import { + validateLineWidthForChartType, + validateMarkSizeForChartType, + validatePointsRadiusForChartType, + validateShowPointsForChartType, +} from './validate'; export const extendedDataLayerFn: ExtendedDataLayerFn['fn'] = async (data, args, context) => { const table = args.table ?? data; @@ -21,6 +26,9 @@ export const extendedDataLayerFn: ExtendedDataLayerFn['fn'] = async (data, args, accessors.accessors.forEach((accessor) => validateAccessor(accessor, table.columns)); validateMarkSizeForChartType(args.markSizeAccessor, args.seriesType); validateAccessor(args.markSizeAccessor, table.columns); + validateLineWidthForChartType(args.lineWidth, args.seriesType); + validateShowPointsForChartType(args.showPoints, args.seriesType); + validatePointsRadiusForChartType(args.pointsRadius, args.seriesType); const normalizedTable = normalizeTable(table, accessors.xAccessor); diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/reference_line_layer.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/reference_line_layer.ts index 6b51edd2d209e0..234001015d73a8 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/reference_line_layer.ts +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/reference_line_layer.ts @@ -6,8 +6,7 @@ * Side Public License, v 1. */ -import { validateAccessor } from '@kbn/visualizations-plugin/common/utils'; -import { LayerTypes, REFERENCE_LINE_LAYER, EXTENDED_Y_CONFIG } from '../constants'; +import { REFERENCE_LINE_LAYER, EXTENDED_Y_CONFIG } from '../constants'; import { ReferenceLineLayerFn } from '../types'; import { strings } from '../i18n'; @@ -41,16 +40,8 @@ export const referenceLineLayerFunction: ReferenceLineLayerFn = { help: strings.getLayerIdHelp(), }, }, - fn(input, args) { - const table = args.table ?? input; - const accessors = args.accessors ?? []; - accessors.forEach((accessor) => validateAccessor(accessor, table.columns)); - - return { - type: REFERENCE_LINE_LAYER, - ...args, - layerType: LayerTypes.REFERENCELINE, - table: args.table ?? input, - }; + async fn(input, args, context) { + const { referenceLineLayerFn } = await import('./reference_line_layer_fn'); + return await referenceLineLayerFn(input, args, context); }, }; diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/reference_line_layer_fn.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/reference_line_layer_fn.ts new file mode 100644 index 00000000000000..8b6d1cc5314470 --- /dev/null +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/reference_line_layer_fn.ts @@ -0,0 +1,24 @@ +/* + * 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 { validateAccessor } from '@kbn/visualizations-plugin/common/utils'; +import { LayerTypes, REFERENCE_LINE_LAYER } from '../constants'; +import { ReferenceLineLayerFn } from '../types'; + +export const referenceLineLayerFn: ReferenceLineLayerFn['fn'] = async (input, args, handlers) => { + const table = args.table ?? input; + const accessors = args.accessors ?? []; + accessors.forEach((accessor) => validateAccessor(accessor, table.columns)); + + return { + type: REFERENCE_LINE_LAYER, + ...args, + layerType: LayerTypes.REFERENCELINE, + table: args.table ?? input, + }; +}; diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/validate.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/validate.ts index df7f9ee08632e9..de01b149802b98 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/validate.ts +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/validate.ts @@ -34,6 +34,27 @@ export const errors = { i18n.translate('expressionXY.reusable.function.xyVis.errors.markSizeLimitsError', { defaultMessage: 'Mark size ratio must be greater or equal to 1 and less or equal to 100', }), + lineWidthForNonLineOrAreaChartError: () => + i18n.translate( + 'expressionXY.reusable.function.xyVis.errors.lineWidthForNonLineOrAreaChartError', + { + defaultMessage: '`lineWidth` can be applied only for line or area charts', + } + ), + showPointsForNonLineOrAreaChartError: () => + i18n.translate( + 'expressionXY.reusable.function.xyVis.errors.showPointsForNonLineOrAreaChartError', + { + defaultMessage: '`showPoints` can be applied only for line or area charts', + } + ), + pointsRadiusForNonLineOrAreaChartError: () => + i18n.translate( + 'expressionXY.reusable.function.xyVis.errors.pointsRadiusForNonLineOrAreaChartError', + { + defaultMessage: '`pointsRadius` can be applied only for line or area charts', + } + ), markSizeRatioWithoutAccessor: () => i18n.translate('expressionXY.reusable.function.xyVis.errors.markSizeRatioWithoutAccessor', { defaultMessage: 'Mark size ratio can be applied only with `markSizeAccessor`', @@ -140,6 +161,9 @@ export const validateValueLabels = ( } }; +const isAreaOrLineChart = (seriesType: SeriesType) => + seriesType.includes('line') || seriesType.includes('area'); + export const validateAddTimeMarker = ( dataLayers: Array, addTimeMarker?: boolean @@ -164,6 +188,33 @@ export const validateMarkSizeRatioLimits = (markSizeRatio?: number) => { } }; +export const validateLineWidthForChartType = ( + lineWidth: number | undefined, + seriesType: SeriesType +) => { + if (lineWidth !== undefined && !isAreaOrLineChart(seriesType)) { + throw new Error(errors.lineWidthForNonLineOrAreaChartError()); + } +}; + +export const validateShowPointsForChartType = ( + showPoints: boolean | undefined, + seriesType: SeriesType +) => { + if (showPoints !== undefined && !isAreaOrLineChart(seriesType)) { + throw new Error(errors.showPointsForNonLineOrAreaChartError()); + } +}; + +export const validatePointsRadiusForChartType = ( + pointsRadius: number | undefined, + seriesType: SeriesType +) => { + if (pointsRadius !== undefined && !isAreaOrLineChart(seriesType)) { + throw new Error(errors.pointsRadiusForNonLineOrAreaChartError()); + } +}; + export const validateMarkSizeRatioWithAccessor = ( markSizeRatio: number | undefined, markSizeAccessor: ExpressionValueVisDimension | string | undefined diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/xy_vis.test.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/xy_vis.test.ts index 8a327ccca9e200..174ff908eeaa18 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/xy_vis.test.ts +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/xy_vis.test.ts @@ -65,6 +65,7 @@ describe('xyVis', () => { ) ).rejects.toThrowErrorMatchingSnapshot(); }); + test('it should throw error if minTimeBarInterval is invalid', async () => { const { data, args } = sampleArgs(); const { layers, ...rest } = args; diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/xy_vis_fn.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/xy_vis_fn.ts index 4c25e3378d5236..afe569a86f894b 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/xy_vis_fn.ts +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/xy_vis_fn.ts @@ -29,6 +29,9 @@ import { validateMinTimeBarInterval, validateMarkSizeForChartType, validateMarkSizeRatioWithAccessor, + validateShowPointsForChartType, + validateLineWidthForChartType, + validatePointsRadiusForChartType, } from './validate'; const createDataLayer = (args: XYArgs, table: Datatable): DataLayerConfigResult => { @@ -43,6 +46,9 @@ const createDataLayer = (args: XYArgs, table: Datatable): DataLayerConfigResult isHistogram: args.isHistogram, palette: args.palette, yConfig: args.yConfig, + showPoints: args.showPoints, + pointsRadius: args.pointsRadius, + lineWidth: args.lineWidth, layerType: LayerTypes.DATA, table: normalizedTable, ...accessors, @@ -68,6 +74,9 @@ export const xyVisFn: XyVisFn['fn'] = async (data, args, handlers) => { yConfig, palette, markSizeAccessor, + showPoints, + pointsRadius, + lineWidth, ...restArgs } = args; @@ -116,6 +125,9 @@ export const xyVisFn: XyVisFn['fn'] = async (data, args, handlers) => { validateValueLabels(args.valueLabels, hasBar, hasNotHistogramBars); validateMarkSizeRatioWithAccessor(args.markSizeRatio, dataLayers[0].markSizeAccessor); validateMarkSizeRatioLimits(args.markSizeRatio); + validateLineWidthForChartType(lineWidth, args.seriesType); + validateShowPointsForChartType(showPoints, args.seriesType); + validatePointsRadiusForChartType(pointsRadius, args.seriesType); return { type: 'render', diff --git a/src/plugins/chart_expressions/expression_xy/common/i18n/index.tsx b/src/plugins/chart_expressions/expression_xy/common/i18n/index.tsx index ed2ef4a7a57cea..4f94d5805396df 100644 --- a/src/plugins/chart_expressions/expression_xy/common/i18n/index.tsx +++ b/src/plugins/chart_expressions/expression_xy/common/i18n/index.tsx @@ -181,6 +181,18 @@ export const strings = { i18n.translate('expressionXY.dataLayer.markSizeAccessor.help', { defaultMessage: 'Mark size accessor', }), + getLineWidthHelp: () => + i18n.translate('expressionXY.dataLayer.lineWidth.help', { + defaultMessage: 'Line width', + }), + getShowPointsHelp: () => + i18n.translate('expressionXY.dataLayer.showPoints.help', { + defaultMessage: 'Show points', + }), + getPointsRadiusHelp: () => + i18n.translate('expressionXY.dataLayer.pointsRadius.help', { + defaultMessage: 'Points radius', + }), getYConfigHelp: () => i18n.translate('expressionXY.dataLayer.yConfig.help', { defaultMessage: 'Additional configuration for y axes', diff --git a/src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts b/src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts index c0336fc67536f1..05447607bc1948 100644 --- a/src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts +++ b/src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts @@ -102,6 +102,9 @@ export interface DataLayerArgs { hide?: boolean; splitAccessor?: string | ExpressionValueVisDimension; markSizeAccessor?: string | ExpressionValueVisDimension; + lineWidth?: number; + showPoints?: boolean; + pointsRadius?: number; columnToLabel?: string; // Actually a JSON key-value pair xScaleType: XScaleType; isHistogram: boolean; @@ -121,6 +124,9 @@ export interface ExtendedDataLayerArgs { hide?: boolean; splitAccessor?: string; markSizeAccessor?: string; + lineWidth?: number; + showPoints?: boolean; + pointsRadius?: number; columnToLabel?: string; // Actually a JSON key-value pair xScaleType: XScaleType; isHistogram: boolean; @@ -416,7 +422,7 @@ export type ReferenceLineLayerFn = ExpressionFunctionDefinition< typeof REFERENCE_LINE_LAYER, Datatable, ReferenceLineLayerArgs, - ReferenceLineLayerConfigResult + Promise >; export type YConfigFn = ExpressionFunctionDefinition; diff --git a/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.test.tsx b/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.test.tsx index 91e5ae8ad14848..f46213fe41ba32 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.test.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.test.tsx @@ -722,6 +722,75 @@ describe('XYChart component', () => { expect(lineArea.prop('lineSeriesStyle')).toEqual(expectedSeriesStyle); }); + test('applies the line width to the chart', () => { + const { args } = sampleArgs(); + const lineWidthArg = { lineWidth: 10 }; + const component = shallow( + + ); + const dataLayers = component.find(DataLayers).dive(); + const lineArea = dataLayers.find(LineSeries).at(0); + const expectedSeriesStyle = expect.objectContaining({ + line: { strokeWidth: lineWidthArg.lineWidth }, + }); + + expect(lineArea.prop('areaSeriesStyle')).toEqual(expectedSeriesStyle); + expect(lineArea.prop('lineSeriesStyle')).toEqual(expectedSeriesStyle); + }); + + test('applies showPoints to the chart', () => { + const checkIfPointsVisibilityIsApplied = (showPoints: boolean) => { + const { args } = sampleArgs(); + const component = shallow( + + ); + const dataLayers = component.find(DataLayers).dive(); + const lineArea = dataLayers.find(LineSeries).at(0); + const expectedSeriesStyle = expect.objectContaining({ + point: expect.objectContaining({ + visible: showPoints, + }), + }); + expect(lineArea.prop('areaSeriesStyle')).toEqual(expectedSeriesStyle); + expect(lineArea.prop('lineSeriesStyle')).toEqual(expectedSeriesStyle); + }; + + checkIfPointsVisibilityIsApplied(true); + checkIfPointsVisibilityIsApplied(false); + }); + + test('applies point radius to the chart', () => { + const pointsRadius = 10; + const { args } = sampleArgs(); + const component = shallow( + + ); + const dataLayers = component.find(DataLayers).dive(); + const lineArea = dataLayers.find(LineSeries).at(0); + const expectedSeriesStyle = expect.objectContaining({ + point: expect.objectContaining({ + radius: pointsRadius, + }), + }); + expect(lineArea.prop('areaSeriesStyle')).toEqual(expectedSeriesStyle); + expect(lineArea.prop('lineSeriesStyle')).toEqual(expectedSeriesStyle); + }); + test('it renders bar', () => { const { args } = sampleArgs(); const component = shallow( diff --git a/src/plugins/chart_expressions/expression_xy/public/helpers/data_layers.tsx b/src/plugins/chart_expressions/expression_xy/public/helpers/data_layers.tsx index 08761f633f851a..34e5e36091ae1a 100644 --- a/src/plugins/chart_expressions/expression_xy/public/helpers/data_layers.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/helpers/data_layers.tsx @@ -8,6 +8,7 @@ import { AreaSeriesProps, + AreaSeriesStyle, BarSeriesProps, ColorVariant, LineSeriesProps, @@ -80,6 +81,14 @@ type GetColorFn = ( } ) => string | null; +type GetLineConfigFn = (config: { + xAccessor: string | undefined; + markSizeAccessor: string | undefined; + emphasizeFitting?: boolean; + showPoints?: boolean; + pointsRadius?: number; +}) => Partial; + export interface DatatableWithFormatInfo { table: Datatable; formattedColumns: Record; @@ -227,17 +236,26 @@ const getSeriesName: GetSeriesNameFn = ( return splitColumnId ? data.seriesKeys[0] : columnToLabelMap[data.seriesKeys[0]] ?? null; }; -const getPointConfig = ( - xAccessor: string | undefined, - markSizeAccessor: string | undefined, - emphasizeFitting?: boolean -) => ({ - visible: !xAccessor || markSizeAccessor !== undefined, - radius: xAccessor && !emphasizeFitting ? 5 : 0, +const getPointConfig: GetLineConfigFn = ({ + xAccessor, + markSizeAccessor, + emphasizeFitting, + showPoints, + pointsRadius, +}) => ({ + visible: showPoints !== undefined ? showPoints : !xAccessor || markSizeAccessor !== undefined, + radius: pointsRadius !== undefined ? pointsRadius : xAccessor && !emphasizeFitting ? 5 : 0, fill: markSizeAccessor ? ColorVariant.Series : undefined, }); -const getLineConfig = () => ({ visible: true, stroke: ColorVariant.Series, opacity: 1, dash: [] }); +const getFitLineConfig = () => ({ + visible: true, + stroke: ColorVariant.Series, + opacity: 1, + dash: [], +}); + +const getLineConfig = (strokeWidth?: number) => ({ strokeWidth }); const getColor: GetColorFn = ( { yAccessor, seriesKeys }, @@ -363,15 +381,29 @@ export const getSeriesProps: GetSeriesPropsFn = ({ stackMode: isPercentage ? StackMode.Percentage : undefined, timeZone, areaSeriesStyle: { - point: getPointConfig(xColumnId, markSizeColumnId, emphasizeFitting), + point: getPointConfig({ + xAccessor: xColumnId, + markSizeAccessor: markSizeColumnId, + emphasizeFitting, + showPoints: layer.showPoints, + pointsRadius: layer.pointsRadius, + }), ...(fillOpacity && { area: { opacity: fillOpacity } }), ...(emphasizeFitting && { - fit: { area: { opacity: fillOpacity || 0.5 }, line: getLineConfig() }, + fit: { area: { opacity: fillOpacity || 0.5 }, line: getFitLineConfig() }, }), + line: getLineConfig(layer.lineWidth), }, lineSeriesStyle: { - point: getPointConfig(xColumnId, markSizeColumnId, emphasizeFitting), - ...(emphasizeFitting && { fit: { line: getLineConfig() } }), + point: getPointConfig({ + xAccessor: xColumnId, + markSizeAccessor: markSizeColumnId, + emphasizeFitting, + showPoints: layer.showPoints, + pointsRadius: layer.pointsRadius, + }), + ...(emphasizeFitting && { fit: { line: getFitLineConfig() } }), + line: getLineConfig(layer.lineWidth), }, name(d) { return getSeriesName(d, {