diff --git a/.playground/playground.tsx b/.playground/playground.tsx index 10810899bc..5332b367ea 100644 --- a/.playground/playground.tsx +++ b/.playground/playground.tsx @@ -19,27 +19,41 @@ import React from 'react'; -import { Chart, BarSeries, ScaleType, Settings } from '../src'; +import { Chart, BarSeries, ScaleType, LineAnnotation, AnnotationDomainTypes, LineAnnotationDatum } from '../src'; +function generateAnnotationData(values: any[]): LineAnnotationDatum[] { + return values.map((value, index) => ({ dataValue: value, details: `detail-${index}` })); +} export class Playground extends React.Component { render() { return ( -
+
- + hello
} + // markerPosition="top" + /> + Horizontal
} + // markerPosition="right" + /> diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-test-cases-no-axes-annotation-bug-fix-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-test-cases-no-axes-annotation-bug-fix-visually-looks-correct-1-snap.png new file mode 100644 index 0000000000..58c4d5a59d Binary files /dev/null and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-test-cases-no-axes-annotation-bug-fix-visually-looks-correct-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/test-cases-stories-test-ts-annotation-marker-rotation-should-render-marker-with-annotations-with-0-degree-rotations-1-snap.png b/integration/tests/__image_snapshots__/test-cases-stories-test-ts-annotation-marker-rotation-should-render-marker-with-annotations-with-0-degree-rotations-1-snap.png new file mode 100644 index 0000000000..58c4d5a59d Binary files /dev/null and b/integration/tests/__image_snapshots__/test-cases-stories-test-ts-annotation-marker-rotation-should-render-marker-with-annotations-with-0-degree-rotations-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/test-cases-stories-test-ts-annotation-marker-rotation-should-render-marker-with-annotations-with-180-degree-rotations-1-snap.png b/integration/tests/__image_snapshots__/test-cases-stories-test-ts-annotation-marker-rotation-should-render-marker-with-annotations-with-180-degree-rotations-1-snap.png new file mode 100644 index 0000000000..2517602b2a Binary files /dev/null and b/integration/tests/__image_snapshots__/test-cases-stories-test-ts-annotation-marker-rotation-should-render-marker-with-annotations-with-180-degree-rotations-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/test-cases-stories-test-ts-annotation-marker-rotation-should-render-marker-with-annotations-with-90-degree-rotations-1-snap.png b/integration/tests/__image_snapshots__/test-cases-stories-test-ts-annotation-marker-rotation-should-render-marker-with-annotations-with-90-degree-rotations-1-snap.png new file mode 100644 index 0000000000..fb63201d4e Binary files /dev/null and b/integration/tests/__image_snapshots__/test-cases-stories-test-ts-annotation-marker-rotation-should-render-marker-with-annotations-with-90-degree-rotations-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/test-cases-stories-test-ts-annotation-marker-rotation-should-render-marker-with-annotations-with-negative-90-degree-rotations-1-snap.png b/integration/tests/__image_snapshots__/test-cases-stories-test-ts-annotation-marker-rotation-should-render-marker-with-annotations-with-negative-90-degree-rotations-1-snap.png new file mode 100644 index 0000000000..7e6414e916 Binary files /dev/null and b/integration/tests/__image_snapshots__/test-cases-stories-test-ts-annotation-marker-rotation-should-render-marker-with-annotations-with-negative-90-degree-rotations-1-snap.png differ diff --git a/integration/tests/accessibility.test.ts b/integration/tests/accessibility.test.ts deleted file mode 100644 index 4173895c30..0000000000 --- a/integration/tests/accessibility.test.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { common } from '../page_objects/common'; - -describe('Accessibility tree', () => { - it('should show the aria-label for the canvas element in the accessibility tree', async () => { - const tree = await common.testAccessibilityTree( - 'http://localhost:9001/iframe.html?id=annotations-lines--x-continuous-domain', - '#story-root', - ); - // digging into the accessibility tree for the canvas element - const expectedAriaLabel = tree.children.filter((value) => { - return value.name === 'Chart'; - }); - expect(expectedAriaLabel[0].name).toBe('Chart'); - }); -}); diff --git a/integration/tests/test_cases_stories.test.ts b/integration/tests/test_cases_stories.test.ts index 3813ee7dde..f2123c4897 100644 --- a/integration/tests/test_cases_stories.test.ts +++ b/integration/tests/test_cases_stories.test.ts @@ -37,3 +37,15 @@ describe('Test cases stories', () => { ); }); }); + +describe('annotation marker rotation', () => { + [0, 90, -90, 180].forEach((rotation) => { + it(`should render marker with annotations with ${ + rotation === -90 ? 'negative 90' : rotation + } degree rotations`, async () => { + await common.expectChartAtUrlToMatchScreenshot( + `http://localhost:9001/iframe.html?id=test-cases--no-axes-annotation-bug-fix&knob-horizontal marker position=undefined&knob-vertical marker position=undefined&knob-chartRotation=${rotation}`, + ); + }); + }); +}); diff --git a/package.json b/package.json index 2683219307..649bd6ef7a 100644 --- a/package.json +++ b/package.json @@ -123,6 +123,7 @@ "@types/jsdom": "^16.2.5", "@types/lodash": "^4.14.121", "@types/luxon": "^1.25.0", + "@types/marked": "^2.0.1", "@types/moment-timezone": "^0.5.30", "@types/puppeteer": "^5.4.2", "@types/react-dom": "^16.9.8", diff --git a/src/chart_types/xy_chart/annotations/line/dimensions.ts b/src/chart_types/xy_chart/annotations/line/dimensions.ts index e3f29e6fe0..eb6a496dc8 100644 --- a/src/chart_types/xy_chart/annotations/line/dimensions.ts +++ b/src/chart_types/xy_chart/annotations/line/dimensions.ts @@ -25,7 +25,7 @@ import { Dimensions, Size } from '../../../../utils/dimensions'; import { GroupId } from '../../../../utils/ids'; import { mergeWithDefaultAnnotationLine } from '../../../../utils/themes/merge_utils'; import { SmallMultipleScales } from '../../state/selectors/compute_small_multiple_scales'; -import { isHorizontalRotation } from '../../state/utils/common'; +import { isHorizontalRotation, isVerticalRotation } from '../../state/utils/common'; import { computeXScaleOffset } from '../../state/utils/utils'; import { getPanelSize } from '../../utils/panel'; import { AnnotationDomainType, LineAnnotationSpec, LineAnnotationDatum } from '../../utils/specs'; @@ -52,7 +52,6 @@ function computeYDomainLineAnnotationDimensions( // let's use a default Bottom-X/Left-Y axis orientation if we are not showing an axis // but we are displaying a line annotation - const alignment = getAnchorPosition(false, isHorizontalChartRotation, specMarkerPosition, axisPosition); const lineProps: AnnotationLineProps[] = []; const [domainStart, domainEnd] = yScale.domain; @@ -84,6 +83,8 @@ function computeYDomainLineAnnotationDimensions( const width = isHorizontalChartRotation ? horizontal.bandwidth : vertical.bandwidth; const height = isHorizontalChartRotation ? vertical.bandwidth : horizontal.bandwidth; + const linePathPoints = getYLinePath({ width, height }, annotationValueYPosition); + const alignment = getAnchorPosition(false, chartRotation, axisPosition, specMarkerPosition); const position = getMarkerPositionForYAnnotation( panelSize, @@ -93,8 +94,6 @@ function computeYDomainLineAnnotationDimensions( dimension, ); - const linePathPoints = getYLinePath({ width, height }, annotationValueYPosition); - const lineProp: AnnotationLineProps = { specId, id: getAnnotationLinePropsId(specId, datum, verticalValue, horizontalValue), @@ -147,7 +146,6 @@ function computeXDomainLineAnnotationDimensions( const lineProps: AnnotationLineProps[] = []; const isHorizontalChartRotation = isHorizontalRotation(chartRotation); - const alignment = getAnchorPosition(true, isHorizontalChartRotation, specMarkerPosition, axisPosition); const panelSize = getPanelSize({ vertical, horizontal }); dataValues.forEach((datum: LineAnnotationDatum) => { @@ -197,6 +195,9 @@ function computeXDomainLineAnnotationDimensions( const width = isHorizontalChartRotation ? horizontal.bandwidth : vertical.bandwidth; const height = isHorizontalChartRotation ? vertical.bandwidth : horizontal.bandwidth; + const linePathPoints = getXLinePath({ width, height }, annotationValueXPosition); + const alignment = getAnchorPosition(true, chartRotation, axisPosition, specMarkerPosition); + const position = getMarkerPositionForXAnnotation( panelSize, chartRotation, @@ -205,8 +206,6 @@ function computeXDomainLineAnnotationDimensions( dimension, ); - const linePathPoints = getXLinePath({ width, height }, annotationValueXPosition); - const lineProp: AnnotationLineProps = { specId, id: getAnnotationLinePropsId(specId, datum, verticalValue, horizontalValue), @@ -281,22 +280,21 @@ export function computeLineAnnotationDimensions( function getAnchorPosition( isXDomain: boolean, - isChartHorizontal: boolean, - specMarkerPosition?: Position, + chartRotation: Rotation, axisPosition?: Position, + specMarkerPosition?: Position, ): Position { - const dflPositionFromAxis = getDefaultMarkerPositionFromAxis(isXDomain, isChartHorizontal, axisPosition); - + const dflPositionFromAxis = getDefaultMarkerPositionFromAxis(isXDomain, chartRotation, axisPosition); if (specMarkerPosition !== undefined) { // validate specMarkerPosition against domain - const validatedPosFromMarkerPos = validateMarkerPosition(isXDomain, isChartHorizontal, specMarkerPosition); + const validatedPosFromMarkerPos = validateMarkerPosition(isXDomain, chartRotation, specMarkerPosition); return validatedPosFromMarkerPos ?? dflPositionFromAxis; } return dflPositionFromAxis; } -function validateMarkerPosition(isXDomain: boolean, isHorizontal: boolean, position: Position): Position | undefined { - if ((isXDomain && isHorizontal) || (!isXDomain && !isHorizontal)) { +function validateMarkerPosition(isXDomain: boolean, chartRotation: Rotation, position: Position): Position | undefined { + if ((isXDomain && isHorizontalRotation(chartRotation)) || (!isXDomain && isVerticalRotation(chartRotation))) { return position === Position.Top || position === Position.Bottom ? position : undefined; } return position === Position.Left || position === Position.Right ? position : undefined; @@ -304,13 +302,13 @@ function validateMarkerPosition(isXDomain: boolean, isHorizontal: boolean, posit function getDefaultMarkerPositionFromAxis( isXDomain: boolean, - isHorizontal: boolean, + chartRotation: Rotation, axisPosition?: Position, ): Position { if (axisPosition) { return axisPosition; } - if ((isXDomain && isHorizontal) || (!isXDomain && !isHorizontal)) { + if ((isXDomain && isVerticalRotation(chartRotation)) || (!isXDomain && isHorizontalRotation(chartRotation))) { return Position.Left; } return Position.Bottom; diff --git a/stories/annotations/rects/2_ordinal_bar_chart.tsx b/stories/annotations/rects/2_ordinal_bar_chart.tsx index 4497cb9466..be3b421ee0 100644 --- a/stories/annotations/rects/2_ordinal_bar_chart.tsx +++ b/stories/annotations/rects/2_ordinal_bar_chart.tsx @@ -68,8 +68,7 @@ Example.story = { info: { text: `On Ordinal Bar charts, you can draw a rectangular annotation the same way it's done within a linear bar chart. The annotation will cover fully the extent defined by the \`coordinate\` object, extending to the max/min domain values any -missing/out-of-range parameters. - `, +missing/out-of-range parameters.`, }, }, }; diff --git a/stories/test_cases/3_no_axes_annotation.tsx b/stories/test_cases/3_no_axes_annotation.tsx new file mode 100644 index 0000000000..d59be2e095 --- /dev/null +++ b/stories/test_cases/3_no_axes_annotation.tsx @@ -0,0 +1,83 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { select } from '@storybook/addon-knobs'; +import React from 'react'; + +import { + AnnotationDomainType, + LineAnnotationDatum, + Chart, + LineAnnotation, + BarSeries, + ScaleType, + Position, + Settings, +} from '../../src'; +import { getChartRotationKnob } from '../utils/knobs'; + +function generateAnnotationData(values: any[]): LineAnnotationDatum[] { + return values.map((value, index) => ({ dataValue: value, details: `detail-${index}` })); +} + +export const Example = () => { + const markerPositionHorizontal = select( + 'horizontal marker position', + [Position.Top, Position.Left, Position.Bottom, Position.Right, 'undefined'], + 'undefined', + ); + const markerPositionVertical = select( + 'vertical marker position', + [Position.Top, Position.Left, Position.Bottom, Position.Right, 'undefined'], + 'undefined', + ); + const chartRotation = getChartRotationKnob(); + return ( + + + Vertical} + markerPosition={markerPositionVertical === 'undefined' ? undefined : markerPositionVertical} + /> + Horizontal} + markerPosition={markerPositionHorizontal === 'undefined' ? undefined : markerPositionHorizontal} + /> + + + ); +}; diff --git a/stories/test_cases/test_cases.stories.tsx b/stories/test_cases/test_cases.stories.tsx index 0b14a75eef..e4e876befe 100644 --- a/stories/test_cases/test_cases.stories.tsx +++ b/stories/test_cases/test_cases.stories.tsx @@ -28,3 +28,4 @@ export default { export { Example as noSeries } from './1_no_series'; export { Example as chromePathBugFix } from './2_chrome_path_bug_fix'; +export { Example as noAxesAnnotationBugFix } from './3_no_axes_annotation'; diff --git a/yarn.lock b/yarn.lock index f0f126a8a2..1f9615bc1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5795,6 +5795,11 @@ resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-1.25.0.tgz#3d6fe591fac874f48dd225cb5660b2b785a21a05" integrity sha512-iIJp2CP6C32gVqI08HIYnzqj55tlLnodIBMCcMf28q9ckqMfMzocCmIzd9JWI/ALLPMUiTkCu1JGv3FFtu6t3g== +"@types/marked@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/marked/-/marked-2.0.1.tgz#bbb6d1b570a54652a31953c77972f65b6f9235a4" + integrity sha512-/CFe3HvXMkh7YkJS0DGRsC0hgwWZDZbSCmY/X00bSCnZ4ukS2Glk9veIkRoPu2ElMbKpjxseXn1y9MkTwGHVjw== + "@types/mdast@^3.0.0": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.3.tgz#2d7d671b1cd1ea3deb306ea75036c2a0407d2deb"