diff --git a/integration/server/mocks/@storybook/addon-knobs/index.ts b/integration/server/mocks/@storybook/addon-knobs/index.ts index c2d8ad522f..6e81757e06 100644 --- a/integration/server/mocks/@storybook/addon-knobs/index.ts +++ b/integration/server/mocks/@storybook/addon-knobs/index.ts @@ -59,6 +59,13 @@ export function array(name: string, dftValues: unknown[], options: any, groupId? return values; } +export function object(name: string, dftValue: unknown, options: any, groupId?: string) { + const params = getParams(); + const key = getKnobKey(name, groupId); + const value = params.get(key); + return value ? JSON.parse(value) : dftValue; +} + export function optionsKnob(name: string, values: unknown, dftValues: unknown[], options: any, groupId?: string) { return array(name, dftValues, options, groupId); } diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axes-fit-domain-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axes-fit-domain-visually-looks-correct-1-snap.png index db3d86a1a0..52620cceae 100644 Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axes-fit-domain-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axes-fit-domain-visually-looks-correct-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-included-select-annotation-y-domains-1-snap.png b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-included-select-annotation-y-domains-1-snap.png new file mode 100644 index 0000000000..5974988524 Binary files /dev/null and b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-included-select-annotation-y-domains-1-snap.png differ diff --git a/integration/tests/axis_stories.test.ts b/integration/tests/axis_stories.test.ts index b134a9504d..e5a0615eb0 100644 --- a/integration/tests/axis_stories.test.ts +++ b/integration/tests/axis_stories.test.ts @@ -23,6 +23,11 @@ describe('Axis stories', () => { 'http://localhost:9001/?path=/story/area-chart--timeslip&globals=theme:light&knob-Minor%20grid%20lines=true&knob-Shift%20time=0&knob-Shorter%20X%20axis%20minor%20whiskers=true&knob-Stretch%20time=18&knob-Time%20zoom=120&knob-X%20axis%20minor%20whiskers=true&knob-showOverlappingLabels%20time%20axis=true', ); }); + it('should included select annotation y domains', async () => { + await common.expectChartAtUrlToMatchScreenshot( + 'http://localhost:9001/?path=/story/axes--fit-domain&globals=theme:light&knob-dataset=positive&knob-fit%20Y%20domain%20to%20data=true&knob-Specs%20to%20fit%20(yDomain)[0]=theshold&knob-Specs%20to%20fit%20(yDomain)[1]=rect&knob-constrain%20padding=true&knob-domain%20padding=0.1&knob-Domain%20padding%20unit=domainRatio&knob-thesholds%20-%20line[0]=1300&knob-theshold%20-%20rect={%22y0%22:-200,%22y1%22:null}', + ); + }); it('should have st nd rd th after day-of-month numbers', async () => { await common.expectChartAtUrlToMatchScreenshot( 'http://localhost:9001/?path=/story/area-chart--timeslip&globals=theme:light&knob-Minor%20grid%20lines=true&knob-Shift%20time=-4.3&knob-Shorter%20X%20axis%20minor%20whiskers=true&knob-Stretch%20time=4.8&knob-Time%20zoom=120&knob-X%20axis%20minor%20whiskers=true&knob-showOverlappingLabels%20time%20axis=true&knob-showOverlappingTicks%20time%20axis=true', diff --git a/packages/charts/api/charts.api.md b/packages/charts/api/charts.api.md index 1464aee3fc..87e3c7d23f 100644 --- a/packages/charts/api/charts.api.md +++ b/packages/charts/api/charts.api.md @@ -1449,7 +1449,7 @@ export interface LegendStyle { export const LIGHT_THEME: Theme; // @public -export const LineAnnotation: (props: SFProps, "chartType" | "specType", "style" | "zIndex" | "groupId" | "hideLines" | "hideLinesTooltips" | "annotationType" | "hideTooltips", "offset" | "fallbackPlacements" | "placement" | "boundary" | "boundaryPadding" | "marker" | "customTooltip" | "markerBody" | "markerDimensions" | "markerPosition" | "customTooltipDetails", "id" | "dataValues" | "domainType">) => null; +export const LineAnnotation: (props: SFProps, "chartType" | "specType", "style" | "zIndex" | "groupId" | "hideLines" | "hideLinesTooltips" | "annotationType" | "hideTooltips", "offset" | "fallbackPlacements" | "placement" | "boundary" | "boundaryPadding" | "marker" | "customTooltip" | "markerBody" | "markerDimensions" | "markerPosition" | "customTooltipDetails", "id" | "domainType" | "dataValues">) => null; // @public export interface LineAnnotationDatum { @@ -2694,6 +2694,7 @@ export interface XYChartSeriesIdentifier extends Se export interface YDomainBase { constrainPadding?: boolean; fit?: boolean; + includeDataFromIds?: SpecId[]; padding?: number; paddingUnit?: DomainPaddingUnit; } diff --git a/packages/charts/src/chart_types/partition_chart/state/selectors/picked_shapes.test.ts b/packages/charts/src/chart_types/partition_chart/state/selectors/picked_shapes.test.ts index 1b8de91b9d..8a0b6b87e3 100644 --- a/packages/charts/src/chart_types/partition_chart/state/selectors/picked_shapes.test.ts +++ b/packages/charts/src/chart_types/partition_chart/state/selectors/picked_shapes.test.ts @@ -36,6 +36,7 @@ function initStore() { describe('Picked shapes selector', () => { function addSeries(store: Store, spec: PartitionSpec, settings?: Partial) { + // @ts-ignore - nesting limitation store.dispatch(upsertSpec(MockGlobalSpec.settings(settings))); store.dispatch(upsertSpec(spec)); store.dispatch(specParsed()); diff --git a/packages/charts/src/chart_types/xy_chart/annotations/line/dimensions.test.ts b/packages/charts/src/chart_types/xy_chart/annotations/line/dimensions.test.ts index 87c030bd69..76682f9a1c 100644 --- a/packages/charts/src/chart_types/xy_chart/annotations/line/dimensions.test.ts +++ b/packages/charts/src/chart_types/xy_chart/annotations/line/dimensions.test.ts @@ -10,7 +10,6 @@ import { MockAnnotationLineProps, MockAnnotationRectProps } from '../../../../mo import { MockAnnotationSpec, MockGlobalSpec, MockSeriesSpec } from '../../../../mocks/specs'; import { MockStore } from '../../../../mocks/store'; import { ScaleType } from '../../../../scales/constants'; -import { Position } from '../../../../utils/common'; import { AnnotationId } from '../../../../utils/ids'; import { DEFAULT_ANNOTATION_LINE_STYLE } from '../../../../utils/themes/merge_utils'; import { computeAnnotationDimensionsSelector } from '../../state/selectors/compute_annotations'; @@ -44,15 +43,11 @@ describe('Annotation utils', () => { ], }); - const verticalAxisSpec = MockGlobalSpec.axis({ - id: 'vertical_axis', + const defaultAxisSpec = { groupId, - hide: false, - showOverlappingTicks: false, - showOverlappingLabels: false, - position: Position.Left, + hide: true, showGridLines: true, - }); + }; test('should compute line annotation in x ordinal scale', () => { const store = MockStore.default(); @@ -130,15 +125,7 @@ describe('Annotation utils', () => { }); MockStore.addSpecs( - [ - settings, - ordinalBarChart, - lineAnnotation, - MockGlobalSpec.axis({ - ...verticalAxisSpec, - hide: true, - }), - ], + [settings, ordinalBarChart, lineAnnotation, MockGlobalSpec.yAxis(defaultAxisSpec, settings.rotation)], store, ); @@ -173,16 +160,7 @@ describe('Annotation utils', () => { }); MockStore.addSpecs( - [ - settings, - ordinalBarChart, - lineAnnotation, - MockGlobalSpec.axis({ - ...verticalAxisSpec, - position: Position.Right, - hide: true, - }), - ], + [settings, ordinalBarChart, lineAnnotation, MockGlobalSpec.yAxis(defaultAxisSpec, settings.rotation)], store, ); @@ -217,15 +195,7 @@ describe('Annotation utils', () => { }); MockStore.addSpecs( - [ - settings, - ordinalBarChart, - lineAnnotation, - MockGlobalSpec.axis({ - ...verticalAxisSpec, - hide: true, - }), - ], + [settings, ordinalBarChart, lineAnnotation, MockGlobalSpec.yAxis(defaultAxisSpec, settings.rotation)], store, ); @@ -263,8 +233,8 @@ describe('Annotation utils', () => { settings, ordinalBarChart, lineAnnotation, - MockGlobalSpec.axis({ - ...verticalAxisSpec, + MockGlobalSpec.yAxis({ + ...defaultAxisSpec, hide: true, }), ], @@ -289,16 +259,7 @@ describe('Annotation utils', () => { }); MockStore.addSpecs( - [ - settings, - ordinalBarChart, - lineAnnotation, - MockGlobalSpec.axis({ - ...verticalAxisSpec, - position: Position.Bottom, - hide: true, - }), - ], + [settings, ordinalBarChart, lineAnnotation, MockGlobalSpec.xAxis(defaultAxisSpec, settings.rotation)], store, ); @@ -332,16 +293,7 @@ describe('Annotation utils', () => { }); MockStore.addSpecs( - [ - settings, - continuousBarChart, - lineAnnotation, - MockGlobalSpec.axis({ - ...verticalAxisSpec, - position: Position.Top, - hide: true, - }), - ], + [settings, continuousBarChart, lineAnnotation, MockGlobalSpec.xAxis(defaultAxisSpec, settings.rotation)], store, ); @@ -374,16 +326,7 @@ describe('Annotation utils', () => { }); MockStore.addSpecs( - [ - settings, - continuousBarChart, - lineAnnotation, - MockGlobalSpec.axis({ - ...verticalAxisSpec, - position: Position.Bottom, - hide: true, - }), - ], + [settings, continuousBarChart, lineAnnotation, MockGlobalSpec.xAxis(defaultAxisSpec, settings.rotation)], store, ); @@ -416,16 +359,7 @@ describe('Annotation utils', () => { }); MockStore.addSpecs( - [ - settings, - ordinalBarChart, - lineAnnotation, - MockGlobalSpec.axis({ - ...verticalAxisSpec, - position: Position.Top, - hide: true, - }), - ], + [settings, ordinalBarChart, lineAnnotation, MockGlobalSpec.xAxis(defaultAxisSpec, settings.rotation)], store, ); @@ -459,16 +393,7 @@ describe('Annotation utils', () => { }); MockStore.addSpecs( - [ - settings, - continuousBarChart, - lineAnnotation, - MockGlobalSpec.axis({ - ...verticalAxisSpec, - position: Position.Top, - hide: true, - }), - ], + [settings, continuousBarChart, lineAnnotation, MockGlobalSpec.xAxis(defaultAxisSpec, settings.rotation)], store, ); @@ -503,16 +428,7 @@ describe('Annotation utils', () => { }); MockStore.addSpecs( - [ - settings, - continuousBarChart, - lineAnnotation, - MockGlobalSpec.axis({ - ...verticalAxisSpec, - position: Position.Top, - hide: true, - }), - ], + [settings, continuousBarChart, lineAnnotation, MockGlobalSpec.xAxis(defaultAxisSpec, settings.rotation)], store, ); @@ -546,16 +462,7 @@ describe('Annotation utils', () => { }); MockStore.addSpecs( - [ - settings, - continuousBarChart, - lineAnnotation, - MockGlobalSpec.axis({ - ...verticalAxisSpec, - position: Position.Top, - hide: true, - }), - ], + [settings, continuousBarChart, lineAnnotation, MockGlobalSpec.xAxis(defaultAxisSpec, settings.rotation)], store, ); @@ -589,16 +496,7 @@ describe('Annotation utils', () => { }); MockStore.addSpecs( - [ - settings, - continuousBarChart, - lineAnnotation, - MockGlobalSpec.axis({ - ...verticalAxisSpec, - position: Position.Bottom, - hide: true, - }), - ], + [settings, continuousBarChart, lineAnnotation, MockGlobalSpec.xAxis(defaultAxisSpec, settings.rotation)], store, ); diff --git a/packages/charts/src/chart_types/xy_chart/annotations/line/line.test.tsx b/packages/charts/src/chart_types/xy_chart/annotations/line/line.test.tsx index 3fec298c0d..05685f0946 100644 --- a/packages/charts/src/chart_types/xy_chart/annotations/line/line.test.tsx +++ b/packages/charts/src/chart_types/xy_chart/annotations/line/line.test.tsx @@ -56,7 +56,7 @@ describe('annotation marker', () => { [ spec, MockGlobalSpec.settingsNoMargins(), - MockGlobalSpec.axis({ position: Position.Left, hide: true }), + MockGlobalSpec.yAxis({ position: Position.Left, hide: true }), lineYDomainAnnotation, ], store, @@ -92,7 +92,7 @@ describe('annotation marker', () => { [ spec, MockGlobalSpec.settingsNoMargins({ rotation: 180 }), - MockGlobalSpec.axis({ position: Position.Left, hide: true }), + MockGlobalSpec.yAxis({ position: Position.Left, hide: true }), lineYDomainAnnotation, ], store, @@ -129,12 +129,7 @@ describe('annotation marker', () => { test('should compute line annotation dimensions with marker if defined (x domain)', () => { MockStore.addSpecs( - [ - spec, - MockGlobalSpec.settingsNoMargins(), - MockGlobalSpec.axis({ position: Position.Bottom, hide: true }), - lineXDomainAnnotation, - ], + [spec, MockGlobalSpec.settingsNoMargins(), MockGlobalSpec.xAxis({ hide: true }), lineXDomainAnnotation], store, ); diff --git a/packages/charts/src/chart_types/xy_chart/annotations/rect/dimensions.integration.test.ts b/packages/charts/src/chart_types/xy_chart/annotations/rect/dimensions.integration.test.ts index fd69cac3e2..8fde253366 100644 --- a/packages/charts/src/chart_types/xy_chart/annotations/rect/dimensions.integration.test.ts +++ b/packages/charts/src/chart_types/xy_chart/annotations/rect/dimensions.integration.test.ts @@ -267,7 +267,7 @@ describe('Render rect annotation within', () => { const heightFromStore = 200; const store = MockStore.default({ top: 0, left: 0, width: 20, height: heightFromStore }); const settings = MockGlobalSpec.settingsNoMargins(); - const yDomainFitted = MockGlobalSpec.axis({ domain: { min: NaN, max: NaN, fit: true } }); + const yDomainFitted = MockGlobalSpec.yAxis({ domain: { fit: true } }); const annotation = MockAnnotationSpec.rect({ dataValues: [{ coordinates: { x0: 2, x1: 4 } }], }); diff --git a/packages/charts/src/chart_types/xy_chart/annotations/utils.test.ts b/packages/charts/src/chart_types/xy_chart/annotations/utils.test.ts index d92ae0c873..37082a47dd 100644 --- a/packages/charts/src/chart_types/xy_chart/annotations/utils.test.ts +++ b/packages/charts/src/chart_types/xy_chart/annotations/utils.test.ts @@ -15,15 +15,13 @@ import { getAnnotationAxis, getTransformedCursor, invertTransformedCursor } from describe('Annotation utils', () => { const groupId = 'foo-group'; - const verticalAxisSpec = MockGlobalSpec.axis({ + const verticalAxisSpec = MockGlobalSpec.yAxis({ id: 'vertical_axis', groupId, - position: Position.Left, }); - const horizontalAxisSpec = MockGlobalSpec.axis({ + const horizontalAxisSpec = MockGlobalSpec.xAxis({ id: 'vertical_axis', groupId, - position: Position.Bottom, }); test('should get associated axis for an annotation', () => { diff --git a/packages/charts/src/chart_types/xy_chart/crosshair/crosshair_utils.linear_snap.test.ts b/packages/charts/src/chart_types/xy_chart/crosshair/crosshair_utils.linear_snap.test.ts index 672fed0410..3e374dd46b 100644 --- a/packages/charts/src/chart_types/xy_chart/crosshair/crosshair_utils.linear_snap.test.ts +++ b/packages/charts/src/chart_types/xy_chart/crosshair/crosshair_utils.linear_snap.test.ts @@ -93,30 +93,35 @@ describe('Crosshair utils linear scale', () => { const barSeriesDomains = computeSeriesDomains( barSeries, getScaleConfigsFromSpecs([], barSeries, MockGlobalSpec.settings()), + [], ); const multiBarSeries = [barSeries1, barSeries2]; const multiBarSeriesDomains = computeSeriesDomains( multiBarSeries, getScaleConfigsFromSpecs([], multiBarSeries, MockGlobalSpec.settings()), + [], ); const lineSeries = [lineSeries1]; const lineSeriesDomains = computeSeriesDomains( lineSeries, getScaleConfigsFromSpecs([], lineSeries, MockGlobalSpec.settings()), + [], ); const multiLineSeries = [lineSeries1, lineSeries2]; const multiLineSeriesDomains = computeSeriesDomains( multiLineSeries, getScaleConfigsFromSpecs([], multiLineSeries, MockGlobalSpec.settings()), + [], ); const mixedLinesBars = [lineSeries1, lineSeries2, barSeries1, barSeries2]; const mixedLinesBarsSeriesDomains = computeSeriesDomains( mixedLinesBars, getScaleConfigsFromSpecs([], mixedLinesBars, MockGlobalSpec.settings()), + [], ); const barSeriesScale = computeXScale({ diff --git a/packages/charts/src/chart_types/xy_chart/crosshair/crosshair_utils.ordinal_snap.test.ts b/packages/charts/src/chart_types/xy_chart/crosshair/crosshair_utils.ordinal_snap.test.ts index 4e37e7dd09..6ffa2d9ef3 100644 --- a/packages/charts/src/chart_types/xy_chart/crosshair/crosshair_utils.ordinal_snap.test.ts +++ b/packages/charts/src/chart_types/xy_chart/crosshair/crosshair_utils.ordinal_snap.test.ts @@ -92,30 +92,35 @@ describe('Crosshair utils ordinal scales', () => { const barSeriesDomains = computeSeriesDomains( barSeries, getScaleConfigsFromSpecs([], barSeries, MockGlobalSpec.settings()), + [], ); const multiBarSeries = [barSeries1, barSeries2]; const multiBarSeriesDomains = computeSeriesDomains( multiBarSeries, getScaleConfigsFromSpecs([], multiBarSeries, MockGlobalSpec.settings()), + [], ); const lineSeries = [lineSeries1]; const lineSeriesDomains = computeSeriesDomains( lineSeries, getScaleConfigsFromSpecs([], lineSeries, MockGlobalSpec.settings()), + [], ); const multiLineSeries = [lineSeries1, lineSeries2]; const multiLineSeriesDomains = computeSeriesDomains( multiLineSeries, getScaleConfigsFromSpecs([], multiLineSeries, MockGlobalSpec.settings()), + [], ); const mixedLinesBars = [lineSeries1, lineSeries2, barSeries1, barSeries2]; const mixedLinesBarsSeriesDomains = computeSeriesDomains( mixedLinesBars, getScaleConfigsFromSpecs([], mixedLinesBars, MockGlobalSpec.settings()), + [], ); const barSeriesScale = computeXScale({ diff --git a/packages/charts/src/chart_types/xy_chart/domains/x_domain.test.ts b/packages/charts/src/chart_types/xy_chart/domains/x_domain.test.ts index 43fe00392f..5e99470de7 100644 --- a/packages/charts/src/chart_types/xy_chart/domains/x_domain.test.ts +++ b/packages/charts/src/chart_types/xy_chart/domains/x_domain.test.ts @@ -667,7 +667,7 @@ describe('X Domain', () => { test('should account for custom domain when merging a linear domain: lower bounded domain', () => { const xValues = new Set([1, 2, 3, 4, 5]); - const xDomain = { min: 0, max: NaN }; + const xDomain = { min: 0 }; const specs = [MockSeriesSpec.line({ xScaleType: ScaleType.Linear })]; const mergedDomain = mergeXDomain( @@ -676,7 +676,7 @@ describe('X Domain', () => { ); expect(mergedDomain.domain).toEqual([0, 5]); - const invalidXDomain = { min: 10, max: NaN }; + const invalidXDomain = { min: 10 }; const { domain } = mergeXDomain( getScaleConfigsFromSpecs([], specs, MockGlobalSpec.settings({ xDomain: invalidXDomain })).x, xValues, @@ -689,7 +689,7 @@ describe('X Domain', () => { test('should account for custom domain when merging a linear domain: upper bounded domain', () => { const xValues = new Set([1, 2, 3, 4, 5]); - const xDomain = { min: NaN, max: 3 }; + const xDomain = { max: 3 }; const specs = [MockSeriesSpec.line({ xScaleType: ScaleType.Linear })]; const mergedDomain = mergeXDomain( @@ -698,7 +698,7 @@ describe('X Domain', () => { ); expect(mergedDomain.domain).toEqual([1, 3]); - const invalidXDomain = { min: NaN, max: -1 }; + const invalidXDomain = { max: -1 }; const { domain } = mergeXDomain( getScaleConfigsFromSpecs([], specs, MockGlobalSpec.settings({ xDomain: invalidXDomain })).x, xValues, @@ -735,7 +735,7 @@ describe('X Domain', () => { const specs = [MockSeriesSpec.bar({ xScaleType: ScaleType.Linear })]; test('with valid minInterval', () => { - const xDomain = { minInterval: 0.5, min: NaN, max: NaN }; + const xDomain = { minInterval: 0.5 }; const mergedDomain = mergeXDomain( getScaleConfigsFromSpecs([], specs, MockGlobalSpec.settings({ xDomain })).x, xValues, @@ -744,7 +744,7 @@ describe('X Domain', () => { }); test('with valid minInterval greater than computed minInterval for single datum set', () => { - const xDomain = { minInterval: 10, min: NaN, max: NaN }; + const xDomain = { minInterval: 10 }; const mergedDomain = mergeXDomain( getScaleConfigsFromSpecs([], specs, MockGlobalSpec.settings({ xDomain })).x, new Set([5]), @@ -753,7 +753,7 @@ describe('X Domain', () => { }); test('with invalid minInterval greater than computed minInterval for multi data set', () => { - const invalidXDomain = { minInterval: 10, min: NaN, max: NaN }; + const invalidXDomain = { minInterval: 10 }; const { minInterval } = mergeXDomain( getScaleConfigsFromSpecs([], specs, MockGlobalSpec.settings({ xDomain: invalidXDomain })).x, xValues, @@ -765,7 +765,7 @@ describe('X Domain', () => { }); test('with invalid minInterval less than 0', () => { - const invalidXDomain = { minInterval: -1, min: NaN, max: NaN }; + const invalidXDomain = { minInterval: -1 }; const { minInterval } = mergeXDomain( getScaleConfigsFromSpecs([], specs, MockGlobalSpec.settings({ xDomain: invalidXDomain })).x, xValues, diff --git a/packages/charts/src/chart_types/xy_chart/domains/y_domain.test.ts b/packages/charts/src/chart_types/xy_chart/domains/y_domain.test.ts index ceed87a022..dcccf9f3a9 100644 --- a/packages/charts/src/chart_types/xy_chart/domains/y_domain.test.ts +++ b/packages/charts/src/chart_types/xy_chart/domains/y_domain.test.ts @@ -12,7 +12,6 @@ import { MockStore } from '../../../mocks/store'; import { MockYDomain } from '../../../mocks/xy/domains'; import { ScaleType } from '../../../scales/constants'; import { SpecType } from '../../../specs/constants'; -import { Position } from '../../../utils/common'; import { BARCHART_1Y0G } from '../../../utils/data_samples/test_dataset'; import { Logger } from '../../../utils/logger'; import { computeSeriesDomainsSelector } from '../state/selectors/compute_series_domains'; @@ -59,10 +58,9 @@ describe('Y Domain', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y', - position: Position.Left, - domain: { fit: true, min: NaN, max: NaN }, + domain: { fit: true }, }), MockSeriesSpec.line({ ...DEMO_AREA_SPEC_1, @@ -85,10 +83,9 @@ describe('Y Domain', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y', - position: Position.Left, - domain: { fit: true, min: NaN, max: NaN }, + domain: { fit: true }, }), MockSeriesSpec.area({ ...DEMO_AREA_SPEC_1, @@ -111,17 +108,15 @@ describe('Y Domain', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y a', groupId: 'a', - position: Position.Left, - domain: { fit: true, min: NaN, max: NaN }, + domain: { fit: true }, }), - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y b', groupId: 'b', - position: Position.Left, - domain: { fit: true, min: NaN, max: NaN }, + domain: { fit: true }, }), MockSeriesSpec.line(DEMO_AREA_SPEC_1), MockSeriesSpec.line({ @@ -150,11 +145,10 @@ describe('Y Domain', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y a', groupId: 'a', - position: Position.Left, - domain: { fit: true, min: NaN, max: NaN }, + domain: { fit: true }, }), MockSeriesSpec.area(DEMO_AREA_SPEC_1), MockSeriesSpec.area({ @@ -179,11 +173,10 @@ describe('Y Domain', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y a', groupId: 'a', - position: Position.Left, - domain: { fit: true, min: NaN, max: NaN }, + domain: { fit: true }, }), MockSeriesSpec.area(DEMO_AREA_SPEC_1), MockSeriesSpec.area({ @@ -369,10 +362,9 @@ describe('Y Domain', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y a', groupId: 'a', - position: Position.Left, domain: { min: 0, max: 20, fit: true }, }), MockSeriesSpec.area(DEMO_AREA_SPEC_1), @@ -393,11 +385,10 @@ describe('Y Domain', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y a', groupId: 'a', - position: Position.Left, - domain: { min: 0, fit: true, max: NaN }, + domain: { min: 0, fit: true }, }), MockSeriesSpec.area(DEMO_AREA_SPEC_1), ], @@ -417,11 +408,10 @@ describe('Y Domain', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y a', groupId: 'a', - position: Position.Left, - domain: { min: 20, fit: true, max: NaN }, + domain: { min: 20, fit: true }, }), MockSeriesSpec.area(DEMO_AREA_SPEC_1), ], @@ -440,11 +430,10 @@ describe('Y Domain', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y a', groupId: 'a', - position: Position.Left, - domain: { min: NaN, max: 20, fit: true }, + domain: { max: 20, fit: true }, }), MockSeriesSpec.line(DEMO_AREA_SPEC_1), ], @@ -464,11 +453,10 @@ describe('Y Domain', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y a', groupId: 'a', - position: Position.Left, - domain: { min: NaN, max: -1, fit: true }, + domain: { max: -1, fit: true }, }), MockSeriesSpec.area(DEMO_AREA_SPEC_1), ], @@ -512,10 +500,9 @@ describe('Y Domain', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y a', groupId: 'a', - position: Position.Left, domain: { min: 2, max: 20, fit: true }, }), MockSeriesSpec.area({ diff --git a/packages/charts/src/chart_types/xy_chart/domains/y_domain.ts b/packages/charts/src/chart_types/xy_chart/domains/y_domain.ts index 93b39fcfc6..a36b587fed 100644 --- a/packages/charts/src/chart_types/xy_chart/domains/y_domain.ts +++ b/packages/charts/src/chart_types/xy_chart/domains/y_domain.ts @@ -25,7 +25,11 @@ export type YBasicSeriesSpec = Pick< > & { stackMode?: StackMode; enableHistogramMode?: boolean }; /** @internal */ -export function mergeYDomain(dataSeries: DataSeries[], yScaleAPIConfig: ScaleConfigs['y']): YDomain[] { +export function mergeYDomain( + yScaleAPIConfig: ScaleConfigs['y'], + dataSeries: DataSeries[], + annotationYValueMap: Map, +): YDomain[] { const dataSeriesByGroupId = groupBy(dataSeries, ({ spec }) => getSpecDomainGroupId(spec), true); return dataSeriesByGroupId.reduce((acc, groupedDataSeries) => { const stacked = groupedDataSeries.filter(({ isStacked, isFiltered }) => isStacked && !isFiltered); @@ -33,7 +37,13 @@ export function mergeYDomain(dataSeries: DataSeries[], yScaleAPIConfig: ScaleCon const hasNonZeroBaselineTypes = groupedDataSeries.some( ({ seriesType, isFiltered }) => seriesType === SeriesType.Bar || (seriesType === SeriesType.Area && !isFiltered), ); - const domain = mergeYDomainForGroup(stacked, nonStacked, hasNonZeroBaselineTypes, yScaleAPIConfig); + const domain = mergeYDomainForGroup( + stacked, + nonStacked, + annotationYValueMap, + hasNonZeroBaselineTypes, + yScaleAPIConfig, + ); return domain ? [...acc, domain] : acc; }, []); } @@ -41,6 +51,7 @@ export function mergeYDomain(dataSeries: DataSeries[], yScaleAPIConfig: ScaleCon function mergeYDomainForGroup( stacked: DataSeries[], nonStacked: DataSeries[], + annotationYValueMap: Map, hasZeroBaselineSpecs: boolean, yScaleConfig: ScaleConfigs['y'], ): YDomain | null { @@ -57,8 +68,9 @@ function mergeYDomainForGroup( if (isStacked && stackMode === StackMode.Percentage) { mergedDomain = computeContinuousDataDomain([0, 1], type, customDomain); } else { - const stackedDomain = computeYDomain(stacked, hasZeroBaselineSpecs, type, newCustomDomain); - const nonStackedDomain = computeYDomain(nonStacked, hasZeroBaselineSpecs, type, newCustomDomain); + const annotationData = annotationYValueMap.get(groupId) ?? []; + const stackedDomain = computeYDomain(stacked, annotationData, hasZeroBaselineSpecs, type, newCustomDomain); + const nonStackedDomain = computeYDomain(nonStacked, annotationData, hasZeroBaselineSpecs, type, newCustomDomain); mergedDomain = computeContinuousDataDomain([...stackedDomain, ...nonStackedDomain], type, newCustomDomain); const [computedDomainMin, computedDomainMax] = mergedDomain; @@ -98,6 +110,7 @@ function mergeYDomainForGroup( function computeYDomain( dataSeries: DataSeries[], + annotationYValues: number[], hasZeroBaselineSpecs: boolean, scaleType: ScaleType, customDomain: YDomainRange, @@ -114,7 +127,7 @@ function computeYDomain( } // padding already applied, set to 0 here to avoid duplicating const domainOptions = { ...customDomain, padding: 0 }; - return computeContinuousDataDomain([...yValues], scaleType, domainOptions); + return computeContinuousDataDomain([...yValues, ...annotationYValues], scaleType, domainOptions); } /** @internal */ diff --git a/packages/charts/src/chart_types/xy_chart/rendering/rendering.bubble.test.ts b/packages/charts/src/chart_types/xy_chart/rendering/rendering.bubble.test.ts index 9b9ac4445b..6a41ffbcae 100644 --- a/packages/charts/src/chart_types/xy_chart/rendering/rendering.bubble.test.ts +++ b/packages/charts/src/chart_types/xy_chart/rendering/rendering.bubble.test.ts @@ -9,7 +9,6 @@ import { MockGlobalSpec, MockSeriesSpec } from '../../../mocks/specs'; import { MockStore } from '../../../mocks/store'; import { ScaleType } from '../../../scales/constants'; -import { Position } from '../../../utils/common'; import { computeSeriesGeometriesSelector } from '../state/selectors/compute_series_geometries'; const SPEC_ID = 'spec_1'; @@ -386,10 +385,10 @@ describe('Rendering points - bubble', () => { yScaleType: ScaleType.Linear, }); const settings = MockGlobalSpec.settingsNoMargins({ - xDomain: { min: NaN, max: 2 }, + xDomain: { max: 2 }, theme: { colors: { vizColors: ['red', 'blue'] } }, }); - const axis = MockGlobalSpec.axis({ position: Position.Left, hide: true, domain: { min: NaN, max: 1 } }); + const axis = MockGlobalSpec.yAxis({ hide: true, domain: { max: 1 } }); const store = MockStore.default({ width: 100, height: 100, top: 0, left: 0 }); MockStore.addSpecs([pointSeriesSpec, axis, settings], store); const { diff --git a/packages/charts/src/chart_types/xy_chart/rendering/rendering.lines.test.ts b/packages/charts/src/chart_types/xy_chart/rendering/rendering.lines.test.ts index a18d5e5bd1..c80bbeeab6 100644 --- a/packages/charts/src/chart_types/xy_chart/rendering/rendering.lines.test.ts +++ b/packages/charts/src/chart_types/xy_chart/rendering/rendering.lines.test.ts @@ -10,7 +10,6 @@ import { MockGlobalSpec, MockSeriesSpec } from '../../../mocks/specs'; import { MockStore } from '../../../mocks/store'; import { ScaleContinuousType } from '../../../scales'; import { ScaleType } from '../../../scales/constants'; -import { Position } from '../../../utils/common'; import { PointGeometry } from '../../../utils/geometry'; import { LIGHT_THEME } from '../../../utils/themes/light_theme'; import { computeSeriesGeometriesSelector } from '../state/selectors/compute_series_geometries'; @@ -404,10 +403,10 @@ describe('Rendering points - line', () => { yScaleType: ScaleType.Linear, }); const settings = MockGlobalSpec.settingsNoMargins({ - xDomain: { min: NaN, max: 2 }, + xDomain: { max: 2 }, theme: { colors: { vizColors: ['red', 'blue'] } }, }); - const axis = MockGlobalSpec.axis({ position: Position.Left, hide: true, domain: { min: NaN, max: 1 } }); + const axis = MockGlobalSpec.yAxis({ hide: true, domain: { max: 1 } }); const store = MockStore.default({ width: 100, height: 100, top: 0, left: 0 }); MockStore.addSpecs([pointSeriesSpec, axis, settings], store); @@ -446,7 +445,7 @@ describe('Rendering points - line', () => { xScaleType: ScaleType.Linear, yScaleType, }); - const axis = MockGlobalSpec.axis({ position: Position.Left }); + const axis = MockGlobalSpec.yAxis(); const store = MockStore.default(); MockStore.addSpecs([pointSeriesSpec, axis], store); // eslint-disable-next-line prefer-destructuring diff --git a/packages/charts/src/chart_types/xy_chart/state/__snapshots__/chart_state.debug.test.ts.snap b/packages/charts/src/chart_types/xy_chart/state/__snapshots__/chart_state.debug.test.ts.snap index 0d9598c09b..0fb8a2c445 100644 --- a/packages/charts/src/chart_types/xy_chart/state/__snapshots__/chart_state.debug.test.ts.snap +++ b/packages/charts/src/chart_types/xy_chart/state/__snapshots__/chart_state.debug.test.ts.snap @@ -8,7 +8,7 @@ Object { "x": Array [ Object { "gridlines": Array [], - "id": "left", + "id": "xAxis", "labels": Array [ "0", "1", @@ -42,7 +42,7 @@ Object { "y": Array [ Object { "gridlines": Array [], - "id": "bottom", + "id": "yAxis", "labels": Array [ "0", "1", @@ -122,7 +122,7 @@ Object { "x": Array [ Object { "gridlines": Array [], - "id": "bottom", + "id": "xAxis", "labels": Array [ "0", "1", @@ -156,7 +156,7 @@ Object { "y": Array [ Object { "gridlines": Array [], - "id": "left", + "id": "yAxis", "labels": Array [ "0", "1", @@ -236,7 +236,7 @@ Object { "x": Array [ Object { "gridlines": Array [], - "id": "left", + "id": "xAxis", "labels": Array [ "0", "1", @@ -270,7 +270,7 @@ Object { "y": Array [ Object { "gridlines": Array [], - "id": "bottom", + "id": "yAxis", "labels": Array [ "0", "1", @@ -350,7 +350,7 @@ Object { "x": Array [ Object { "gridlines": Array [], - "id": "bottom", + "id": "xAxis", "labels": Array [ "0", "1", @@ -384,7 +384,7 @@ Object { "y": Array [ Object { "gridlines": Array [], - "id": "left", + "id": "yAxis", "labels": Array [ "0", "1", diff --git a/packages/charts/src/chart_types/xy_chart/state/chart_state.debug.test.ts b/packages/charts/src/chart_types/xy_chart/state/chart_state.debug.test.ts index 8581ad1e2d..3fdb9e0a83 100644 --- a/packages/charts/src/chart_types/xy_chart/state/chart_state.debug.test.ts +++ b/packages/charts/src/chart_types/xy_chart/state/chart_state.debug.test.ts @@ -9,7 +9,7 @@ import { MockSeriesSpec, MockGlobalSpec } from '../../../mocks/specs'; import { MockStore } from '../../../mocks/store/store'; import { ScaleType } from '../../../scales/constants'; -import { Position, Rotation } from '../../../utils/common'; +import { Rotation } from '../../../utils/common'; import { getDebugStateSelector } from './selectors/get_debug_state'; describe('XYChart - debug state', () => { @@ -29,16 +29,18 @@ describe('XYChart - debug state', () => { xScaleType: ScaleType.Linear, yScaleType: ScaleType.Linear, }), - MockGlobalSpec.axis({ - id: 'bottom', - position: Position.Bottom, - integersOnly: true, - }), - MockGlobalSpec.axis({ - id: 'left', - position: Position.Left, - integersOnly: true, - }), + MockGlobalSpec.xAxis( + { + integersOnly: true, + }, + rotation, + ), + MockGlobalSpec.yAxis( + { + integersOnly: true, + }, + rotation, + ), ], store, ); diff --git a/packages/charts/src/chart_types/xy_chart/state/selectors/compute_series_domains.ts b/packages/charts/src/chart_types/xy_chart/state/selectors/compute_series_domains.ts index 63c15e83cf..dad165d97d 100644 --- a/packages/charts/src/chart_types/xy_chart/state/selectors/compute_series_domains.ts +++ b/packages/charts/src/chart_types/xy_chart/state/selectors/compute_series_domains.ts @@ -11,7 +11,7 @@ import { createCustomCachedSelector } from '../../../../state/create_selector'; import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs'; import { computeSeriesDomains } from '../utils/utils'; import { getScaleConfigsFromSpecsSelector } from './get_api_scale_configs'; -import { getSeriesSpecsSelector, getSmallMultiplesIndexOrderSelector } from './get_specs'; +import { getAnnotationSpecsSelector, getSeriesSpecsSelector, getSmallMultiplesIndexOrderSelector } from './get_specs'; const getDeselectedSeriesSelector = (state: GlobalChartState) => state.interactions.deselectedDataSeries; @@ -20,6 +20,7 @@ export const computeSeriesDomainsSelector = createCustomCachedSelector( [ getSeriesSpecsSelector, getScaleConfigsFromSpecsSelector, + getAnnotationSpecsSelector, getDeselectedSeriesSelector, getSettingsSpecSelector, getSmallMultiplesIndexOrderSelector, diff --git a/packages/charts/src/chart_types/xy_chart/state/selectors/merge_y_custom_domains.ts b/packages/charts/src/chart_types/xy_chart/state/selectors/merge_y_custom_domains.ts index fdfbcf6697..b7f4cf491e 100644 --- a/packages/charts/src/chart_types/xy_chart/state/selectors/merge_y_custom_domains.ts +++ b/packages/charts/src/chart_types/xy_chart/state/selectors/merge_y_custom_domains.ts @@ -21,9 +21,7 @@ export function mergeYCustomDomainsByGroupId( axesSpecs.forEach((spec: AxisSpec) => { const { id, groupId, domain } = spec; - if (!domain) { - return; - } + if (!domain) return; if (isXDomain(spec.position, chartRotation)) { throw new Error(`[Axis ${id}]: custom domain for xDomain should be defined in Settings`); diff --git a/packages/charts/src/chart_types/xy_chart/state/utils/utils.test.ts b/packages/charts/src/chart_types/xy_chart/state/utils/utils.test.ts index c05dd7b958..c51ff815a9 100644 --- a/packages/charts/src/chart_types/xy_chart/state/utils/utils.test.ts +++ b/packages/charts/src/chart_types/xy_chart/state/utils/utils.test.ts @@ -68,7 +68,7 @@ describe('Chart State utils', () => { data: BARCHART_1Y0G, }); const scaleConfig = getScaleConfigsFromSpecs([], [spec1, spec2], MockGlobalSpec.settings()); - const domains = computeSeriesDomains([spec1, spec2], scaleConfig); + const domains = computeSeriesDomains([spec1, spec2], scaleConfig, []); expect(domains.xDomain).toEqual( MockXDomain.fromScaleType(ScaleType.Linear, { domain: [0, 3], @@ -120,7 +120,7 @@ describe('Chart State utils', () => { data: BARCHART_1Y1G, }); const scaleConfig = getScaleConfigsFromSpecs([], [spec1, spec2], MockGlobalSpec.settings()); - const domains = computeSeriesDomains([spec1, spec2], scaleConfig); + const domains = computeSeriesDomains([spec1, spec2], scaleConfig, []); expect(domains.xDomain).toEqual( MockXDomain.fromScaleType(ScaleType.Linear, { domain: [0, 3], diff --git a/packages/charts/src/chart_types/xy_chart/state/utils/utils.ts b/packages/charts/src/chart_types/xy_chart/state/utils/utils.ts index 9a82d83358..6ba8f49fc4 100644 --- a/packages/charts/src/chart_types/xy_chart/state/utils/utils.ts +++ b/packages/charts/src/chart_types/xy_chart/state/utils/utils.ts @@ -12,7 +12,7 @@ import { SeriesIdentifier, SeriesKey } from '../../../../common/series_id'; import { Scale } from '../../../../scales'; import { SettingsSpec, TickFormatter } from '../../../../specs'; import { TextMeasure } from '../../../../utils/bbox/canvas_text_bbox_calculator'; -import { isUniqueArray, mergePartial, Rotation } from '../../../../utils/common'; +import { isFiniteNumber, isUniqueArray, mergePartial, Rotation } from '../../../../utils/common'; import { CurveType } from '../../../../utils/curves'; import { Dimensions, Size } from '../../../../utils/dimensions'; import { @@ -46,6 +46,8 @@ import { isBandedSpec, } from '../../utils/series'; import { + AnnotationDomainType, + AnnotationSpec, AxisSpec, BasicSeriesSpec, Fit, @@ -55,6 +57,7 @@ import { isAreaSeriesSpec, isBarSeriesSpec, isBubbleSeriesSpec, + isLineAnnotation, isLineSeriesSpec, } from '../../utils/specs'; import { SmallMultipleScales } from '../selectors/compute_small_multiple_scales'; @@ -115,6 +118,7 @@ export function getCustomSeriesColors(dataSeries: DataSeries[]): Map, smallMultiples?: SmallMultiplesGroupBy, @@ -139,9 +143,10 @@ export function computeSeriesDomains( const formattedDataSeries = getFormattedDataSeries(seriesSpecs, filledDataSeries, xValues, xDomain.type).sort( seriesSortFn, ); + const annotationYValueMap = getAnnotationYValueMap(annotations, scaleConfigs.y); // let's compute the yDomains after computing all stacked values - const yDomains = mergeYDomain(formattedDataSeries, scaleConfigs.y); + const yDomains = mergeYDomain(scaleConfigs.y, formattedDataSeries, annotationYValueMap); // sort small multiples values const horizontalPredicate = smallMultiples?.horizontal?.sort ?? Predicate.DataIndex; @@ -159,6 +164,23 @@ export function computeSeriesDomains( }; } +function getAnnotationYValueMap( + annotations: AnnotationSpec[], + yScaleConfig: ScaleConfigs['y'], +): Map { + return annotations.reduce((acc, spec) => { + const { includeDataFromIds = [] } = yScaleConfig[spec.groupId]?.customDomain ?? {}; + if (!includeDataFromIds.includes(spec.id)) return acc.set(spec.groupId, []); + const yValues: number[] = isLineAnnotation(spec) + ? spec.domainType === AnnotationDomainType.YDomain + ? spec.dataValues.map(({ dataValue }) => dataValue) + : [] + : spec.dataValues.flatMap(({ coordinates: { y0, y1 } }) => [y0, y1]); + const groupValues = acc.get(spec.groupId) ?? []; + return acc.set(spec.groupId, [...groupValues, ...yValues.filter(isFiniteNumber)]); + }, new Map()); +} + /** @internal */ export function computeSeriesGeometries( seriesSpecs: BasicSeriesSpec[], diff --git a/packages/charts/src/chart_types/xy_chart/tooltip/tooltip.test.ts b/packages/charts/src/chart_types/xy_chart/tooltip/tooltip.test.ts index 8c11a34b90..df14db93f2 100644 --- a/packages/charts/src/chart_types/xy_chart/tooltip/tooltip.test.ts +++ b/packages/charts/src/chart_types/xy_chart/tooltip/tooltip.test.ts @@ -40,7 +40,7 @@ describe('Tooltip formatting', () => { ...SPEC_1, y0Accessors: [1], }); - const YAXIS_SPEC = MockGlobalSpec.axis({ + const YAXIS_SPEC = MockGlobalSpec.yAxis({ chartType: ChartType.XYAxis, specType: SpecType.Axis, id: 'axis_1', diff --git a/packages/charts/src/chart_types/xy_chart/utils/axis_utils.test.ts b/packages/charts/src/chart_types/xy_chart/utils/axis_utils.test.ts index 7f6bd7846d..7130e4bf08 100644 --- a/packages/charts/src/chart_types/xy_chart/utils/axis_utils.test.ts +++ b/packages/charts/src/chart_types/xy_chart/utils/axis_utils.test.ts @@ -9,13 +9,11 @@ import { DateTime } from 'luxon'; import moment from 'moment-timezone'; -import { ChartType } from '../..'; import { MockGlobalSpec /*, MockSeriesSpec*/ } from '../../../mocks/specs/specs'; // import { MockStore } from '../../../mocks/store/store'; import { MockXDomain, MockYDomain } from '../../../mocks/xy/domains'; import { Scale } from '../../../scales'; import { ScaleType } from '../../../scales/constants'; -import { SpecType } from '../../../specs/constants'; import { Position, mergePartial, HorizontalAlignment, VerticalAlignment } from '../../../utils/common'; import { niceTimeFormatter } from '../../../utils/data/formatters'; import { OrdinalDomain } from '../../../utils/domain'; @@ -103,37 +101,28 @@ describe('Axis computational utils', () => { maxLabelTextHeight: 10, isHidden: false, }; - const verticalAxisSpec = MockGlobalSpec.axis({ - chartType: ChartType.XYAxis, - specType: SpecType.Axis, + const verticalAxisSpec = MockGlobalSpec.yAxis({ id: 'axis_1', title: 'Axis 1', groupId: 'group_1', hide: false, - showOverlappingTicks: false, - showOverlappingLabels: false, - position: Position.Left, style, showGridLines: true, integersOnly: false, }); - const horizontalAxisSpec = MockGlobalSpec.axis({ - chartType: ChartType.XYAxis, - specType: SpecType.Axis, + const horizontalAxisSpec = MockGlobalSpec.xAxis({ id: 'axis_2', title: 'Axis 2', groupId: 'group_1', hide: false, - showOverlappingTicks: false, - showOverlappingLabels: false, position: Position.Top, style, integersOnly: false, }); /* - const verticalAxisSpecWTitle = MockGlobalSpec.axis({ + const verticalAxisSpecWTitle = MockGlobalSpec.yAxis({ chartType: ChartType.XYAxis, specType: SpecType.Axis, id: 'axis_1', @@ -1019,7 +1008,7 @@ describe('Axis computational utils', () => { [ MockGlobalSpec.settingsNoMargins(), lineSeriesSpec, - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ ...verticalAxisSpec, hide: true, gridLine: { diff --git a/packages/charts/src/chart_types/xy_chart/utils/series.test.ts b/packages/charts/src/chart_types/xy_chart/utils/series.test.ts index dba3f1567d..d3a1181e24 100644 --- a/packages/charts/src/chart_types/xy_chart/utils/series.test.ts +++ b/packages/charts/src/chart_types/xy_chart/utils/series.test.ts @@ -17,7 +17,6 @@ import { SeededDataGenerator, getRandomNumberGenerator } from '../../../mocks/ut import { ScaleType } from '../../../scales/constants'; import { SpecType } from '../../../specs/constants'; import { AccessorFn } from '../../../utils/accessor'; -import { Position } from '../../../utils/common'; import * as TestDataset from '../../../utils/data_samples/test_dataset'; import { KIBANA_METRICS } from '../../../utils/data_samples/test_dataset_kibana'; import { ColorConfig } from '../../../utils/themes/theme'; @@ -294,10 +293,9 @@ describe('Series', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y', - position: Position.Left, - domain: { fit: true, min: NaN, max: NaN }, + domain: { fit: true }, }), MockSeriesSpec.bar({ id: 'spec1', @@ -324,10 +322,9 @@ describe('Series', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y', - position: Position.Left, - domain: { fit: true, min: NaN, max: NaN }, + domain: { fit: true }, }), MockSeriesSpec.bar({ id: 'spec1', @@ -365,10 +362,9 @@ describe('Series', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y', - position: Position.Left, - domain: { fit: true, min: NaN, max: NaN }, + domain: { fit: true }, }), MockSeriesSpec.bar({ id: 'spec1', @@ -398,10 +394,9 @@ describe('Series', () => { const store = MockStore.default(); MockStore.addSpecs( [ - MockGlobalSpec.axis({ + MockGlobalSpec.yAxis({ id: 'y', - position: Position.Left, - domain: { fit: true, min: NaN, max: NaN }, + domain: { fit: true }, }), MockSeriesSpec.bar({ id: 'spec1', diff --git a/packages/charts/src/chart_types/xy_chart/utils/specs.ts b/packages/charts/src/chart_types/xy_chart/utils/specs.ts index ceef37950f..ecb2f88407 100644 --- a/packages/charts/src/chart_types/xy_chart/utils/specs.ts +++ b/packages/charts/src/chart_types/xy_chart/utils/specs.ts @@ -20,7 +20,7 @@ import { AccessorFormat, AccessorFn, Accessor } from '../../../utils/accessor'; import { RecursivePartial, Position, Datum } from '../../../utils/common'; import { CurveType } from '../../../utils/curves'; import { OrdinalDomain } from '../../../utils/domain'; -import { AxisId, GroupId } from '../../../utils/ids'; +import { AxisId, GroupId, SpecId } from '../../../utils/ids'; import { AreaSeriesStyle, BarSeriesStyle, @@ -325,6 +325,13 @@ export interface YDomainBase { * @defaultValue false */ fit?: boolean; + /** + * Specify a series of specIds to include into the domain calculation. + * Currently, it will work only for annotations, everything else is already included in the domain automatically. + * Setting `domain.max` or `domain.min` will override this functionality. + * @defaultValue [] + */ + includeDataFromIds?: SpecId[]; /** * Padding for computed domain as positive number. * Applied to domain __before__ nicing diff --git a/packages/charts/src/mocks/specs/specs.ts b/packages/charts/src/mocks/specs/specs.ts index 4ed87bc345..9ddbdf2abf 100644 --- a/packages/charts/src/mocks/specs/specs.ts +++ b/packages/charts/src/mocks/specs/specs.ts @@ -13,6 +13,7 @@ import { PartitionLayout } from '../../chart_types/partition_chart/layout/types/ import { ShapeTreeNode } from '../../chart_types/partition_chart/layout/types/viewmodel_types'; import { AGGREGATE_KEY, PrimitiveValue } from '../../chart_types/partition_chart/layout/utils/group_by_rollup'; import { PartitionSpec } from '../../chart_types/partition_chart/specs'; +import { isHorizontalRotation } from '../../chart_types/xy_chart/state/utils/common'; import { SeriesSpecs, DEFAULT_GLOBAL_ID, @@ -41,7 +42,7 @@ import { Spec, HeatmapSpec, } from '../../specs'; -import { Datum, mergePartial, Position, RecursivePartial } from '../../utils/common'; +import { Datum, mergePartial, Position, RecursivePartial, Rotation } from '../../utils/common'; import { LIGHT_THEME } from '../../utils/themes/light_theme'; /** @internal */ @@ -297,7 +298,10 @@ export class MockSeriesSpecs { /** @internal */ export class MockGlobalSpec { - private static readonly settingsBase: SettingsSpec = DEFAULT_SETTINGS_SPEC; + private static readonly settingsBase: SettingsSpec = { + ...DEFAULT_SETTINGS_SPEC, + xDomain: { min: NaN, max: NaN }, + }; private static readonly axisBase: AxisSpec = { id: 'yAxis', @@ -339,24 +343,39 @@ export class MockGlobalSpec { sort: Predicate.DataIndex, }; - static settings(partial?: Partial): SettingsSpec { + static settings(partial?: RecursivePartial): SettingsSpec { // @ts-ignore - nesting limitation return mergePartial(MockGlobalSpec.settingsBase, partial); } - static settingsNoMargins(partial?: Partial): SettingsSpec { + static settingsNoMargins(partial?: RecursivePartial): SettingsSpec { return mergePartial(MockGlobalSpec.settingsBaseNoMargings, partial); } - static axis(partial?: Partial): AxisSpec { - return mergePartial(MockGlobalSpec.axisBase, partial); + static xAxis(partial?: RecursivePartial>, rotation: Rotation = 0): AxisSpec { + return mergePartial(MockGlobalSpec.axisBase, partial, {}, [ + { + id: 'xAxis', + position: isHorizontalRotation(rotation) ? Position.Bottom : Position.Left, + }, + ]); + } + + static yAxis(partial?: RecursivePartial, rotation: Rotation = 0): AxisSpec { + return mergePartial(MockGlobalSpec.axisBase, partial, {}, [ + { + id: 'yAxis', + position: isHorizontalRotation(rotation) ? Position.Left : Position.Bottom, + domain: { min: NaN, max: NaN, includeDataFromIds: [] }, + }, + ]); } - static smallMultiple(partial?: Partial): SmallMultiplesSpec { + static smallMultiple(partial?: RecursivePartial): SmallMultiplesSpec { return mergePartial(MockGlobalSpec.smallMultipleBase, partial); } - static groupBy(partial?: Partial): GroupBySpec { + static groupBy(partial?: RecursivePartial): GroupBySpec { return mergePartial(MockGlobalSpec.groupByBase, partial); } } diff --git a/packages/charts/src/utils/common.ts b/packages/charts/src/utils/common.ts index bc1b3a48be..7e2b8d4c71 100644 --- a/packages/charts/src/utils/common.ts +++ b/packages/charts/src/utils/common.ts @@ -351,6 +351,8 @@ export function renderWithProps

>(El: ReactNode | C * * @param base structure to be duplicated, must have all props of `partial` * @param partial structure to override values from base + * @param options options to control merge behaviour + * @param additionalPartials partials to be used before base and after partial * * @returns new base structure with updated partial values * @internal diff --git a/storybook/package.json b/storybook/package.json index 6230c78be6..6a46bba287 100644 --- a/storybook/package.json +++ b/storybook/package.json @@ -4,7 +4,7 @@ "license": "Apache-2.0", "version": "0.0.1", "scripts": { - "start": "VRT=true start-storybook -s ../public -p 9001 -c . --ci --no-version-updates", + "start": "start-storybook -s ../public -p 9001 -c . --ci --no-version-updates", "build": "rm -rf ../.out && build-storybook -s ../public -c . -o ../.out", "build:firebase": "build-storybook -s ../public -c . -o ../e2e-server/public", "typecheck": "tsc -p ./tsconfig.json --noEmit" diff --git a/storybook/preload_icons.ts b/storybook/preload_icons.ts deleted file mode 100644 index 15d436b4e5..0000000000 --- a/storybook/preload_icons.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - */ - -// @ts-ignore - no type declarations -import { appendIconComponentCache } from '@elastic/eui/es/components/icon/icon'; - -/** - * Loads nessecery icons to prevent loading vrt diff - * - * https://github.com/elastic/eui/blob/b2ffddee61913202224f2967599436ca95265879/src-docs/src/views/guidelines/getting_started.md#failing-icon-imports - */ -export const preloadIcons = () => { - /* eslint-disable global-require, @typescript-eslint/no-var-requires */ - - /* - * See icon file name/path map - * https://github.com/elastic/eui/blob/b2ffddee61913202224f2967599436ca95265879/src/components/icon/icon.tsx#L39 - */ - appendIconComponentCache({ - arrowUp: require('@elastic/eui/es/components/icon/assets/arrow_up').icon, - arrowLeft: require('@elastic/eui/es/components/icon/assets/arrow_left').icon, - arrowDown: require('@elastic/eui/es/components/icon/assets/arrow_down').icon, - arrowRight: require('@elastic/eui/es/components/icon/assets/arrow_right').icon, - iInCircle: require('@elastic/eui/es/components/icon/assets/iInCircle').icon, - tokenKey: require('@elastic/eui/es/components/icon/assets/tokenKey').icon, - filter: require('@elastic/eui/es/components/icon/assets/filter').icon, - starFilled: require('@elastic/eui/es/components/icon/assets/star_filled').icon, - pencil: require('@elastic/eui/es/components/icon/assets/pencil').icon, - visualizeApp: require('@elastic/eui/es/components/icon/assets/app_visualize').icon, - }); - - /* eslint-enable global-require, @typescript-eslint/no-var-requires */ -}; diff --git a/storybook/preview.ts b/storybook/preview.ts index 3ac33ae7b9..bb874248fc 100644 --- a/storybook/preview.ts +++ b/storybook/preview.ts @@ -7,15 +7,9 @@ */ import { storybookParameters } from './parameters'; -import { preloadIcons } from './preload_icons'; import { StoryWrapper } from './story_wrapper'; import './style.scss'; -if (process.env.VRT) { - preloadIcons(); - document.querySelector('html')?.classList.add('disable-animations'); -} - export const parameters = storybookParameters; export const decorators = [StoryWrapper]; diff --git a/storybook/stories/axes/11_fit_domain_extent.story.tsx b/storybook/stories/axes/11_fit_domain_extent.story.tsx index 08256545ba..5d846db3b6 100644 --- a/storybook/stories/axes/11_fit_domain_extent.story.tsx +++ b/storybook/stories/axes/11_fit_domain_extent.story.tsx @@ -6,18 +6,29 @@ * Side Public License, v 1. */ -import { boolean, number, select } from '@storybook/addon-knobs'; +import { array, boolean, number, object, select } from '@storybook/addon-knobs'; import React from 'react'; -import { Axis, Chart, DomainPaddingUnit, LineSeries, Position, ScaleType, Settings } from '@elastic/charts'; +import { + Axis, + Chart, + DomainPaddingUnit, + LineAnnotation, + LineSeries, + Position, + RectAnnotation, + ScaleType, + Settings, +} from '@elastic/charts'; import { SeededDataGenerator } from '@elastic/charts/src/mocks/utils'; import { useBaseTheme } from '../../use_base_theme'; -import { getKnobsFromEnum } from '../utils/knobs'; +import { getKnobsFromEnum, getMultiSelectKnob } from '../utils/knobs'; + +const dg = new SeededDataGenerator(); +const base = dg.generateBasicSeries(100, 0, 50); export const Example = () => { - const dg = new SeededDataGenerator(); - const base = dg.generateBasicSeries(100, 0, 50); const positive = base.map(({ x, y }) => ({ x, y: y + 1000 })); const both = base.map(({ x, y }) => ({ x, y: y - 100 })); const negative = base.map(({ x, y }) => ({ x, y: y - 1000 })); @@ -39,6 +50,15 @@ export const Example = () => { const dataset = dataTypes[dataKey]; const fit = boolean('fit Y domain to data', true); + const includeDataFromIds = getMultiSelectKnob( + 'Specs to fit (yDomain)', + { + Lines: 'theshold', + Rects: 'rect', + }, + ['theshold', 'rect'], + 'check', + ); const constrainPadding = boolean('constrain padding', true); const padding = number('domain padding', 0.1); const paddingUnit = getKnobsFromEnum( @@ -46,6 +66,8 @@ export const Example = () => { DomainPaddingUnit, DomainPaddingUnit.DomainRatio as DomainPaddingUnit, ); + const thesholds = array('thesholds - line', ['200']).filter(Boolean).map(Number); + const rectTheshold = object('theshold - rect', { y0: 100, y1: null }); return ( @@ -56,6 +78,7 @@ export const Example = () => { min: NaN, max: NaN, fit, + includeDataFromIds, padding, paddingUnit, constrainPadding, @@ -65,7 +88,26 @@ export const Example = () => { position={Position.Left} tickFormat={(d) => Number(d).toFixed(2)} /> - + ({ dataValue }))} + domainType="yDomain" + style={{ + line: { + stroke: '#e73c45', + strokeWidth: 2, + opacity: 1, + dash: [4, 4], + }, + }} + /> + { - const knob = optionsKnob( +/** + * This throws from storybook when values array becomes empty :( + */ +export function getMultiSelectKnob( + name: string, + valuesObj: OptionsTypeOptionsProp, + value: OptionsTypeKnobValue, + display: OptionsKnobOptionsDisplay = 'multi-select', + groupId?: string, +): T[] { + const knob = optionsKnob( + name, + valuesObj, + value, + { + display, + }, + groupId, + ); + + if (Array.isArray(knob)) return knob as T[]; + if (typeof knob === 'string') return knob.split(', ') as T[]; + if (typeof knob === 'number') return [knob] as T[]; + return !knob ? [] : knob; +} + +export const getFallbackPlacementsKnob = (groupId?: string): Placement[] => { + return getMultiSelectKnob( 'Fallback Placements', { Top: Placement.Top, @@ -209,18 +241,9 @@ export const getFallbackPlacementsKnob = (): Placement[] | undefined => { AutoEnd: Placement.AutoEnd, }, [Placement.Right, Placement.Left, Placement.Top, Placement.Bottom], - { - display: 'multi-select', - }, + undefined, + groupId, ); - - if (knob.length === 0) { - return; - } - - if (typeof knob === 'string') return knob.split(', ') as Placement[]; - - return knob; }; const boundaryMap: Record = { diff --git a/storybook/webpack.config.js b/storybook/webpack.config.js index 319db0dfc1..23639035e5 100644 --- a/storybook/webpack.config.js +++ b/storybook/webpack.config.js @@ -9,7 +9,6 @@ const path = require('path'); const CircularDependencyPlugin = require('circular-dependency-plugin'); -const webpack = require('webpack'); const nonce = 'Pk1rZ1XDlMuYe8ubWV3Lh0BzwrTigJQ='; @@ -41,13 +40,6 @@ const MAX_CYCLES = 0; let numCyclesDetected = 0; module.exports = ({ config }) => { - config.plugins.push( - new webpack.EnvironmentPlugin({ - RNG_SEED: null, - VRT: process.env.VRT ?? null, - }), - ); - // Checking CI value here // eslint-disable-next-line no-console console.log(`process.env.CI =`, process.env.CI);