diff --git a/src/components/react_canvas/area_geometries.test.tsx b/src/components/react_canvas/area_geometries.test.tsx new file mode 100644 index 0000000000..1bcd989d7e --- /dev/null +++ b/src/components/react_canvas/area_geometries.test.tsx @@ -0,0 +1,98 @@ +import { buildAreaLineProps, buildAreaPointProps, buildAreaProps } from './area_geometries'; + +describe('[canvas] Area Geometries', () => { + test('can build area point props', () => { + const props = buildAreaPointProps({ + areaIndex: 1, + pointIndex: 2, + x: 10, + y: 20, + radius: 30, + strokeWidth: 2, + color: 'red', + opacity: 0.5, + }); + expect(props).toEqual({ + key: 'area-point-1-2', + x: 10, + y: 20, + radius: 30, + strokeWidth: 2, + strokeEnabled: true, + stroke: 'red', + fill: 'white', + opacity: 0.5, + strokeHitEnabled: false, + perfectDrawEnabled: false, + listening: false, + }); + + const propsNoStroke = buildAreaPointProps({ + areaIndex: 1, + pointIndex: 2, + x: 10, + y: 20, + radius: 30, + strokeWidth: 0, + color: 'red', + opacity: 0.5, + }); + expect(propsNoStroke).toEqual({ + key: 'area-point-1-2', + x: 10, + y: 20, + radius: 30, + strokeWidth: 0, + strokeEnabled: false, + stroke: 'red', + fill: 'white', + opacity: 0.5, + strokeHitEnabled: false, + perfectDrawEnabled: false, + listening: false, + }); + }); + test('can build area path props', () => { + const props = buildAreaProps({ + index: 1, + areaPath: 'M0,0L10,10Z', + color: 'red', + opacity: 0.5, + }); + expect(props).toEqual({ + key: 'area-1', + data: 'M0,0L10,10Z', + fill: 'red', + lineCap: 'round', + lineJoin: 'round', + opacity: 0.5, + strokeHitEnabled: false, + perfectDrawEnabled: false, + listening: false, + }); + }); + test('can build area line path props', () => { + const props = buildAreaLineProps({ + index: 1, + linePath: 'M0,0L10,10Z', + color: 'red', + strokeWidth: 1, + geometryStyle: { + opacity: 0.5, + }, + }); + expect(props).toEqual({ + key: `area-line-1`, + data: 'M0,0L10,10Z', + stroke: 'red', + strokeWidth: 1, + lineCap: 'round', + lineJoin: 'round', + opacity: 0.5, + strokeHitEnabled: false, + perfectDrawEnabled: false, + listening: false, + }); + expect(props.fill).toBeFalsy(); + }); +}); diff --git a/src/components/react_canvas/area_geometries.tsx b/src/components/react_canvas/area_geometries.tsx index 8586b89539..92142502d9 100644 --- a/src/components/react_canvas/area_geometries.tsx +++ b/src/components/react_canvas/area_geometries.tsx @@ -3,7 +3,12 @@ import React from 'react'; import { Circle, Group, Path } from 'react-konva'; import { animated, Spring } from 'react-spring/renderprops-konva.cjs'; import { LegendItem } from '../../lib/series/legend'; -import { AreaGeometry, getGeometryStyle, PointGeometry } from '../../lib/series/rendering'; +import { + AreaGeometry, + GeometryStyle, + getGeometryStyle, + PointGeometry, +} from '../../lib/series/rendering'; import { AreaSeriesStyle, SharedGeometryStyle } from '../../lib/themes/theme'; import { GlobalKonvaElementProps } from './globals'; @@ -54,45 +59,42 @@ export class AreaGeometries extends React.PureComponent< ); } private renderPoints = (areaPoints: PointGeometry[], areaIndex: number): JSX.Element[] => { - const { radius, stroke, strokeWidth, opacity } = this.props.style.point; + const { radius, strokeWidth, opacity } = this.props.style.point; - return areaPoints.map((areaPoint, index) => { + return areaPoints.map((areaPoint, pointIndex) => { const { x, y, color, transform } = areaPoint; if (this.props.animated) { return ( - + - {(props: { y: number }) => ( - - )} + {(props: { y: number }) => { + const pointProps = buildAreaPointProps({ + areaIndex, + pointIndex, + x, + y, + radius, + strokeWidth, + color, + opacity, + }); + return ; + }} ); } else { - return ( - - ); + const pointProps = buildAreaPointProps({ + areaIndex, + pointIndex, + x: transform.x + x, + y, + radius, + strokeWidth, + color, + opacity, + }); + return ; } }); } @@ -108,32 +110,26 @@ export class AreaGeometries extends React.PureComponent< return ( - {(props: { area: string }) => ( - - )} + {(props: { area: string }) => { + const areaProps = buildAreaProps({ + index: i, + areaPath: props.area, + color, + opacity, + }); + return ; + }} ); } else { - return ( - - ); + const areaProps = buildAreaProps({ + index: i, + areaPath: area, + color, + opacity, + }); + return ; } }); } @@ -154,32 +150,109 @@ export class AreaGeometries extends React.PureComponent< return ( - {(props: { line: string }) => ( - - )} + {(props: { line: string }) => { + const lineProps = buildAreaLineProps({ + index: i, + linePath: props.line, + color, + strokeWidth, + geometryStyle, + }); + return ; + }} ); } else { - return ( - - ); + const lineProps = buildAreaLineProps({ + index: i, + linePath: line, + color, + strokeWidth, + geometryStyle, + }); + return ; } }); } } + +export function buildAreaPointProps({ + areaIndex, + pointIndex, + x, + y, + radius, + strokeWidth, + color, + opacity, +}: { + areaIndex: number; + pointIndex: number; + x: number; + y: number; + radius: number; + strokeWidth: number; + color: string; + opacity: number; +}) { + return { + key: `area-point-${areaIndex}-${pointIndex}`, + x, + y, + radius, + strokeWidth, + strokeEnabled: strokeWidth !== 0, + stroke: color, + fill: 'white', + opacity, + ...GlobalKonvaElementProps, + }; +} + +export function buildAreaProps({ + index, + areaPath, + color, + opacity, +}: { + index: number; + areaPath: string; + color: string; + opacity: number; +}) { + return { + key: `area-${index}`, + data: areaPath, + fill: color, + lineCap: 'round', + lineJoin: 'round', + opacity, + ...GlobalKonvaElementProps, + }; +} + +export function buildAreaLineProps({ + index, + linePath, + color, + strokeWidth, + geometryStyle, +}: { + index: number; + linePath: string; + color: string; + strokeWidth: number; + geometryStyle: GeometryStyle; +}) { + return { + key: `area-line-${index}`, + data: linePath, + stroke: color, + strokeWidth, + lineCap: 'round', + lineJoin: 'round', + ...geometryStyle, + ...GlobalKonvaElementProps, + }; +}