diff --git a/packages/f2/src/components/guide/index.tsx b/packages/f2/src/components/guide/index.tsx index e1ef50cf4..ea02f3a73 100644 --- a/packages/f2/src/components/guide/index.tsx +++ b/packages/f2/src/components/guide/index.tsx @@ -7,6 +7,7 @@ import RectGuideView from './views/Rect'; import ImageGuideView from './views/Image'; import TagGuideView from './views/Tag'; import LottieGuideView from './views/Lottie'; +import PolylineGuideView from './views/Polyline'; const DefaultGuideView = () => null; const TextGuide = withGuide(TextGuideView); @@ -17,6 +18,7 @@ const RectGuide = withGuide(RectGuideView); const ImageGuide = withGuide(ImageGuideView); const TagGuide = withGuide(TagGuideView); const LottieGuide = withGuide(LottieGuideView); +const PolylineGuide = withGuide(PolylineGuideView); export { GuideProps }; @@ -32,4 +34,5 @@ export { ImageGuide, TagGuide, LottieGuide, + PolylineGuide, }; diff --git a/packages/f2/src/components/guide/views/Polyline.tsx b/packages/f2/src/components/guide/views/Polyline.tsx new file mode 100644 index 000000000..d89145b81 --- /dev/null +++ b/packages/f2/src/components/guide/views/Polyline.tsx @@ -0,0 +1,36 @@ +import { jsx, PolygonStyleProps } from '@antv/f-engine'; +import { GuideProps } from '../withGuide'; +import { deepMix } from '@antv/util'; + +export interface LineGuideProps extends GuideProps { + points?: { x: number; y: number }[] | null; + style?: Partial | ((record?) => Partial); + offsetX?: number | string | (number | string)[]; + offsetY?: number | string | (number | string)[]; + theme?: any; +} + +export default (props: LineGuideProps, context) => { + const { theme = {} } = props; + const { points, style, offsetX, offsetY, animation } = deepMix({ ...theme.polyline }, props); + + const checkNaN = points.some((d) => isNaN(d.x) || isNaN(d.y)); + if (checkNaN) return; + + const offsetXNum = context.px2hd(offsetX); + const offsetYNum = context.px2hd(offsetY); + + return ( + + { + return [point.x + offsetXNum, point.y + offsetYNum]; + }), + ...style, + }} + animation={animation} + /> + + ); +}; diff --git a/packages/f2/src/components/index.ts b/packages/f2/src/components/index.ts index 176705b17..0743c02bb 100644 --- a/packages/f2/src/components/index.ts +++ b/packages/f2/src/components/index.ts @@ -17,6 +17,7 @@ export { ImageGuide, TagGuide, LottieGuide, + PolylineGuide, } from './guide'; export { default as Tooltip, TooltipProps, withTooltip, TooltipView } from './tooltip'; export { default as Treemap, TreemapProps, withTreemap, TreemapView } from './treemap'; diff --git a/packages/f2/src/theme.ts b/packages/f2/src/theme.ts index 8ca1e0bae..f4a70e844 100644 --- a/packages/f2/src/theme.ts +++ b/packages/f2/src/theme.ts @@ -82,6 +82,15 @@ const guide = { stroke: '#1890ff', }, }, + polyline: { + style: { + lineWidth: '4px', + lineJoin: 'round', + lineCap: 'round', + }, + offsetX: 0, + offsetY: 0, + }, }; const chart = { diff --git a/packages/f2/test/components/guide/__image_snapshots__/polyline-test-tsx-polyline-guide-default-1-snap.png b/packages/f2/test/components/guide/__image_snapshots__/polyline-test-tsx-polyline-guide-default-1-snap.png new file mode 100644 index 000000000..9db91685c Binary files /dev/null and b/packages/f2/test/components/guide/__image_snapshots__/polyline-test-tsx-polyline-guide-default-1-snap.png differ diff --git a/packages/f2/test/components/guide/__image_snapshots__/polyline-test-tsx-polyline-guide-offset-1-snap.png b/packages/f2/test/components/guide/__image_snapshots__/polyline-test-tsx-polyline-guide-offset-1-snap.png new file mode 100644 index 000000000..a55e4a99e Binary files /dev/null and b/packages/f2/test/components/guide/__image_snapshots__/polyline-test-tsx-polyline-guide-offset-1-snap.png differ diff --git a/packages/f2/test/components/guide/polyline.test.tsx b/packages/f2/test/components/guide/polyline.test.tsx new file mode 100644 index 000000000..14f59b2a6 --- /dev/null +++ b/packages/f2/test/components/guide/polyline.test.tsx @@ -0,0 +1,61 @@ +import { jsx, Canvas, Chart } from '../../../src'; +import { Line, PolylineGuide } from '../../../src/components'; +import { createContext, delay } from '../../util'; + +const data = [ + { genre: 'Sports', sold: 275, type: 'a' }, + { genre: 'Strategy', sold: 115, type: 'a' }, + { genre: 'Action', sold: 120, type: 'a' }, + { genre: 'Shooter', sold: 350, type: 'a' }, + { genre: 'Other', sold: 150, type: 'a' }, +]; + +describe('PolylineGuide ', () => { + it('default', async () => { + const context = createContext(); + const { props } = ( + + + + + + + ); + + const chart = new Canvas(props); + await chart.render(); + + await delay(300); + expect(context).toMatchImageSnapshot(); + }); + + it('offset', async () => { + const context = createContext(); + const { props } = ( + + + + + + + ); + + const chart = new Canvas(props); + await chart.render(); + + await delay(300); + expect(context).toMatchImageSnapshot(); + }); +});