├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .github └── workflows │ └── build.yml ├── .gitignore ├── .husky ├── .gitignore ├── commit-msg └── pre-commit ├── .prettierignore ├── .prettierrc ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── __tests__ ├── bugs │ ├── issue-1.spec.ts │ ├── issue-g2-6373.spec.ts │ └── issue-legend.spec.ts ├── integration │ ├── animation │ │ ├── index.ts │ │ ├── transition-1.ts │ │ └── transition-2.ts │ ├── canvas.ts │ ├── components │ │ ├── axis │ │ │ ├── axis-animation-disable.ts │ │ │ ├── axis-animation-update-1.ts │ │ │ ├── axis-animation-update-10.ts │ │ │ ├── axis-animation-update-11.ts │ │ │ ├── axis-animation-update-12.ts │ │ │ ├── axis-animation-update-13.ts │ │ │ ├── axis-animation-update-2.ts │ │ │ ├── axis-animation-update-3.ts │ │ │ ├── axis-animation-update-4.ts │ │ │ ├── axis-animation-update-5.ts │ │ │ ├── axis-animation-update-6.ts │ │ │ ├── axis-animation-update-7.ts │ │ │ ├── axis-animation-update-8.ts │ │ │ ├── axis-animation-update-9.ts │ │ │ ├── axis-arc-basis-1.ts │ │ │ ├── axis-arc-basis-2.ts │ │ │ ├── axis-arc-basis-3.ts │ │ │ ├── axis-arc-basis-4.ts │ │ │ ├── axis-arc-direction-1.ts │ │ │ ├── axis-arc-direction-10.ts │ │ │ ├── axis-arc-direction-11.ts │ │ │ ├── axis-arc-direction-12.ts │ │ │ ├── axis-arc-direction-13.ts │ │ │ ├── axis-arc-direction-14.ts │ │ │ ├── axis-arc-direction-15.ts │ │ │ ├── axis-arc-direction-16.ts │ │ │ ├── axis-arc-direction-17.ts │ │ │ ├── axis-arc-direction-18.ts │ │ │ ├── axis-arc-direction-19.ts │ │ │ ├── axis-arc-direction-2.ts │ │ │ ├── axis-arc-direction-20.ts │ │ │ ├── axis-arc-direction-3.ts │ │ │ ├── axis-arc-direction-4.ts │ │ │ ├── axis-arc-direction-5.ts │ │ │ ├── axis-arc-direction-6.ts │ │ │ ├── axis-arc-direction-7.ts │ │ │ ├── axis-arc-direction-8.ts │ │ │ ├── axis-arc-direction-9.ts │ │ │ ├── axis-arc-label-rotate-1.ts │ │ │ ├── axis-arc-label-rotate-2.ts │ │ │ ├── axis-arc-label-rotate-3.ts │ │ │ ├── axis-arc-label-rotate-4.ts │ │ │ ├── axis-arc-title-1.ts │ │ │ ├── axis-arc-title-2.ts │ │ │ ├── axis-arc-title-3.ts │ │ │ ├── axis-arc-title-4.ts │ │ │ ├── axis-arc-title-5.ts │ │ │ ├── axis-arc-title-6.ts │ │ │ ├── axis-arc-title-7.ts │ │ │ ├── axis-arc-title-8.ts │ │ │ ├── axis-arc-title-9.ts │ │ │ ├── axis-arc.ts │ │ │ ├── axis-grid-1.ts │ │ │ ├── axis-grid-10.ts │ │ │ ├── axis-grid-11.ts │ │ │ ├── axis-grid-12.ts │ │ │ ├── axis-grid-2.ts │ │ │ ├── axis-grid-3.ts │ │ │ ├── axis-grid-4.ts │ │ │ ├── axis-grid-5.ts │ │ │ ├── axis-grid-6.ts │ │ │ ├── axis-grid-7.ts │ │ │ ├── axis-grid-8.ts │ │ │ ├── axis-grid-9.ts │ │ │ ├── axis-linear-basis-1.ts │ │ │ ├── axis-linear-basis-2.ts │ │ │ ├── axis-linear-basis-3.ts │ │ │ ├── axis-linear-basis-4.ts │ │ │ ├── axis-linear-basis-5.ts │ │ │ ├── axis-linear-basis-6.ts │ │ │ ├── axis-linear-basis-7.ts │ │ │ ├── axis-linear-basis-8.ts │ │ │ ├── axis-linear-basis-z.ts │ │ │ ├── axis-linear-custom-tick.ts │ │ │ ├── axis-linear-label-align-1.ts │ │ │ ├── axis-linear-label-align-10.ts │ │ │ ├── axis-linear-label-align-11.ts │ │ │ ├── axis-linear-label-align-12.ts │ │ │ ├── axis-linear-label-align-13.ts │ │ │ ├── axis-linear-label-align-14.ts │ │ │ ├── axis-linear-label-align-15.ts │ │ │ ├── axis-linear-label-align-16.ts │ │ │ ├── axis-linear-label-align-17.ts │ │ │ ├── axis-linear-label-align-18.ts │ │ │ ├── axis-linear-label-align-19.ts │ │ │ ├── axis-linear-label-align-2.ts │ │ │ ├── axis-linear-label-align-20.ts │ │ │ ├── axis-linear-label-align-3.ts │ │ │ ├── axis-linear-label-align-4.ts │ │ │ ├── axis-linear-label-align-5.ts │ │ │ ├── axis-linear-label-align-6.ts │ │ │ ├── axis-linear-label-align-7.ts │ │ │ ├── axis-linear-label-align-8.ts │ │ │ ├── axis-linear-label-align-9.ts │ │ │ ├── axis-linear-label-overlap-2.ts │ │ │ ├── axis-linear-label-overlap-cross-size-vertical.ts │ │ │ ├── axis-linear-label-overlap-cross-size.ts │ │ │ ├── axis-linear-label-overlap-multiple.ts │ │ │ ├── axis-linear-label-overlap-wrap-vertical.ts │ │ │ ├── axis-linear-label-overlap-wrap.ts │ │ │ ├── axis-linear-label-overlap.ts │ │ │ ├── axis-linear-label-rotate.ts │ │ │ ├── axis-linear-label-spacing.ts │ │ │ ├── axis-linear-label.ts │ │ │ ├── axis-linear-time-1.ts │ │ │ ├── axis-linear-time-2.ts │ │ │ ├── axis-linear-title-end.ts │ │ │ ├── axis-linear-title-position.ts │ │ │ ├── axis-linear-title-start.ts │ │ │ ├── axis-linear-title.ts │ │ │ ├── axis-linear-vertical.ts │ │ │ └── index.ts │ │ ├── bugs │ │ │ ├── axis-label-ellipsis-update.ts │ │ │ ├── axis-label-hide-update.ts │ │ │ ├── axis-label-overlap-update.ts │ │ │ ├── axis-label-position.ts │ │ │ ├── axis-label-rotate-update.ts │ │ │ ├── axis-label-rotate.ts │ │ │ ├── axis-label-wrap.ts │ │ │ ├── axis-title-position.ts │ │ │ ├── category-give-shape-1.ts │ │ │ ├── category-give-shape-2.ts │ │ │ ├── category-give-shape-3.ts │ │ │ ├── category-item-update-1.ts │ │ │ ├── category-items-update-1.ts │ │ │ ├── category-items-update-2.ts │ │ │ ├── category-items-update-3.ts │ │ │ ├── category-label-display.ts │ │ │ ├── category-marker.ts │ │ │ ├── category-update-1.ts │ │ │ ├── category-update-2.ts │ │ │ ├── category-update-3.ts │ │ │ ├── category-update-4.ts │ │ │ ├── category-update-5.ts │ │ │ ├── category-update-6.ts │ │ │ └── index.ts │ │ ├── button │ │ │ ├── button-1.ts │ │ │ └── index.ts │ │ ├── checkbox │ │ │ ├── checkbox1.ts │ │ │ └── index.ts │ │ ├── crosshair │ │ │ ├── circle.ts │ │ │ ├── index.ts │ │ │ ├── line.ts │ │ │ └── polygon.ts │ │ ├── index.ts │ │ ├── indicator │ │ │ ├── index.ts │ │ │ ├── indicator-radius.ts │ │ │ └── indicator.ts │ │ ├── layout │ │ │ ├── index.ts │ │ │ ├── layout-continuous-1.ts │ │ │ ├── layout-continuous-2.ts │ │ │ ├── layout-continuous-3.ts │ │ │ ├── layout-continuous-4.ts │ │ │ ├── layout-continuous-5.ts │ │ │ ├── layout-continuous-6.ts │ │ │ ├── layout-continuous-7.ts │ │ │ ├── layout-continuous-8.ts │ │ │ ├── layout-continuous-9.ts │ │ │ ├── layout-flex-align-items-center.ts │ │ │ ├── layout-flex-align-items-flex-end.ts │ │ │ ├── layout-flex-align-items-flex-start.ts │ │ │ ├── layout-flex-direction-column.ts │ │ │ ├── layout-flex-direction-row.ts │ │ │ ├── layout-flex-justify-content-center.ts │ │ │ ├── layout-flex-justify-content-flex-end.ts │ │ │ ├── layout-flex-justify-content-flex-start.ts │ │ │ ├── layout-flex-manipulate-children.ts │ │ │ ├── layout-flex-nest.ts │ │ │ ├── layout-flex-position-bottom-left.ts │ │ │ ├── layout-flex-position-bottom-right.ts │ │ │ ├── layout-flex-position-bottom.ts │ │ │ ├── layout-flex-position-center.ts │ │ │ ├── layout-flex-position-left.ts │ │ │ ├── layout-flex-position-right.ts │ │ │ ├── layout-flex-position-top-left.ts │ │ │ ├── layout-flex-position-top-right.ts │ │ │ ├── layout-flex-position-top.ts │ │ │ ├── layout-flex-update-layout.ts │ │ │ ├── layout-legend-1.ts │ │ │ ├── layout-legend-2.ts │ │ │ ├── layout-legend-3.ts │ │ │ ├── layout-legend-4.ts │ │ │ ├── layout-legend-5.ts │ │ │ ├── layout-legend-6.ts │ │ │ ├── layout-legend-7.ts │ │ │ ├── layout-legend-8.ts │ │ │ ├── layout-legend-9.ts │ │ │ ├── layout-legend-multiple.ts │ │ │ ├── layout-update-attr-2.ts │ │ │ └── layout-update-attr.ts │ │ ├── legend │ │ │ ├── category-item-1.ts │ │ │ ├── category-item-10.ts │ │ │ ├── category-item-2.ts │ │ │ ├── category-item-3.ts │ │ │ ├── category-item-4.ts │ │ │ ├── category-item-5.ts │ │ │ ├── category-item-6.ts │ │ │ ├── category-item-7.ts │ │ │ ├── category-item-8.ts │ │ │ ├── category-item-9.ts │ │ │ ├── category-item-marker-1.ts │ │ │ ├── category-item-marker-2.ts │ │ │ ├── category-items-1.ts │ │ │ ├── category-items-10.ts │ │ │ ├── category-items-11.ts │ │ │ ├── category-items-12.ts │ │ │ ├── category-items-2.ts │ │ │ ├── category-items-3.ts │ │ │ ├── category-items-4.ts │ │ │ ├── category-items-5.ts │ │ │ ├── category-items-6.ts │ │ │ ├── category-items-7.ts │ │ │ ├── category-items-8.ts │ │ │ ├── category-items-9.ts │ │ │ ├── category-layout-1.ts │ │ │ ├── category-layout-10.ts │ │ │ ├── category-layout-11.ts │ │ │ ├── category-layout-12.ts │ │ │ ├── category-layout-13.ts │ │ │ ├── category-layout-14.ts │ │ │ ├── category-layout-15.ts │ │ │ ├── category-layout-16.ts │ │ │ ├── category-layout-17.ts │ │ │ ├── category-layout-18.ts │ │ │ ├── category-layout-19.ts │ │ │ ├── category-layout-2.ts │ │ │ ├── category-layout-20.ts │ │ │ ├── category-layout-21.ts │ │ │ ├── category-layout-22.ts │ │ │ ├── category-layout-23.ts │ │ │ ├── category-layout-24.ts │ │ │ ├── category-layout-25.ts │ │ │ ├── category-layout-26.ts │ │ │ ├── category-layout-27.ts │ │ │ ├── category-layout-28.ts │ │ │ ├── category-layout-29.ts │ │ │ ├── category-layout-3.ts │ │ │ ├── category-layout-30.ts │ │ │ ├── category-layout-31.ts │ │ │ ├── category-layout-32.ts │ │ │ ├── category-layout-33.ts │ │ │ ├── category-layout-34.ts │ │ │ ├── category-layout-4.ts │ │ │ ├── category-layout-5.ts │ │ │ ├── category-layout-6.ts │ │ │ ├── category-layout-7.ts │ │ │ ├── category-layout-8.ts │ │ │ ├── category-layout-9.ts │ │ │ ├── category-marker.ts │ │ │ ├── category-position-1.ts │ │ │ ├── category-position-2.ts │ │ │ ├── category-position-3.ts │ │ │ ├── continuous-1.ts │ │ │ ├── continuous-2.ts │ │ │ ├── continuous-3.ts │ │ │ ├── continuous-4.ts │ │ │ ├── continuous-5.ts │ │ │ ├── continuous-d3-color-legend.ts │ │ │ ├── continuous.ts │ │ │ ├── data.ts │ │ │ ├── handle.ts │ │ │ ├── index.ts │ │ │ ├── ribbon-color.ts │ │ │ ├── ribbon.ts │ │ │ └── utils.ts │ │ ├── marker │ │ │ ├── index.ts │ │ │ ├── marker-1.ts │ │ │ └── marker-update.ts │ │ ├── navigator │ │ │ ├── index.ts │ │ │ ├── navigator-null.ts │ │ │ ├── navigator-over-pages.ts │ │ │ ├── navigator-single.ts │ │ │ ├── navigator-style.ts │ │ │ ├── navigator-update.ts │ │ │ ├── navigator-without-shape.ts │ │ │ └── navigator.ts │ │ ├── scrollbar │ │ │ ├── index.ts │ │ │ ├── scrollbar-1.ts │ │ │ ├── scrollbar-2.ts │ │ │ └── scrollbar-3.ts │ │ ├── select │ │ │ ├── index.ts │ │ │ ├── select-basic.ts │ │ │ ├── select-default-value.ts │ │ │ ├── select-demo-speed.ts │ │ │ ├── select-events.ts │ │ │ ├── select-invalid-default-value.ts │ │ │ ├── select-no-border.ts │ │ │ └── select-open.ts │ │ ├── slider │ │ │ ├── handle-1.ts │ │ │ ├── handle-2.ts │ │ │ ├── handle-update.ts │ │ │ ├── index.ts │ │ │ ├── slider-1.ts │ │ │ ├── slider-10.ts │ │ │ ├── slider-11.ts │ │ │ ├── slider-12.ts │ │ │ ├── slider-2.ts │ │ │ ├── slider-3.ts │ │ │ ├── slider-4.ts │ │ │ ├── slider-5.ts │ │ │ ├── slider-6.ts │ │ │ ├── slider-7.ts │ │ │ ├── slider-8.ts │ │ │ ├── slider-9.ts │ │ │ ├── slider-invert.ts │ │ │ ├── slider-timebar.ts │ │ │ └── slider-value-type.ts │ │ ├── sparkline │ │ │ ├── index.ts │ │ │ ├── sparkline-1.ts │ │ │ ├── sparkline-10.ts │ │ │ ├── sparkline-11.ts │ │ │ ├── sparkline-12.ts │ │ │ ├── sparkline-2.ts │ │ │ ├── sparkline-3.ts │ │ │ ├── sparkline-4.ts │ │ │ ├── sparkline-5.ts │ │ │ ├── sparkline-6.ts │ │ │ ├── sparkline-7.ts │ │ │ ├── sparkline-8.ts │ │ │ ├── sparkline-9.ts │ │ │ ├── sparkline-scale-column.ts │ │ │ └── sparkline-scale-line.ts │ │ ├── switch │ │ │ ├── index.ts │ │ │ └── switch-1.ts │ │ ├── tag │ │ │ ├── index.ts │ │ │ └── tag-1.ts │ │ ├── text │ │ │ ├── index.ts │ │ │ └── text-1.ts │ │ ├── timebar │ │ │ ├── controller.ts │ │ │ ├── handle.ts │ │ │ ├── icons.ts │ │ │ ├── index.ts │ │ │ ├── timebar-basic.ts │ │ │ ├── timebar-chart.ts │ │ │ └── timebar-time.ts │ │ ├── title │ │ │ ├── index.ts │ │ │ └── title.ts │ │ └── tooltip │ │ │ ├── index.ts │ │ │ ├── tooltip-1.ts │ │ │ ├── tooltip-10.ts │ │ │ ├── tooltip-2.ts │ │ │ ├── tooltip-3.ts │ │ │ ├── tooltip-4.ts │ │ │ ├── tooltip-5.tsx │ │ │ ├── tooltip-6.tsx │ │ │ ├── tooltip-7.tsx │ │ │ ├── tooltip-8.tsx │ │ │ └── tooltip-9.tsx │ ├── fetch.ts │ ├── index.html │ ├── main.tsx │ ├── snapshot.spec.ts │ ├── snapshots │ │ ├── AxisAnimationDisable.svg │ │ ├── AxisAnimationUpdate1.svg │ │ ├── AxisAnimationUpdate10.svg │ │ ├── AxisAnimationUpdate11.svg │ │ ├── AxisAnimationUpdate12.svg │ │ ├── AxisAnimationUpdate2.svg │ │ ├── AxisAnimationUpdate3.svg │ │ ├── AxisAnimationUpdate4.svg │ │ ├── AxisAnimationUpdate5.svg │ │ ├── AxisAnimationUpdate6.svg │ │ ├── AxisAnimationUpdate7.svg │ │ ├── AxisAnimationUpdate8.svg │ │ ├── AxisAnimationUpdate9.svg │ │ ├── AxisArc.svg │ │ ├── AxisArcBasis1.svg │ │ ├── AxisArcBasis2.svg │ │ ├── AxisArcBasis3.svg │ │ ├── AxisArcBasis4.svg │ │ ├── AxisArcDirection1.svg │ │ ├── AxisArcDirection10.svg │ │ ├── AxisArcDirection11.svg │ │ ├── AxisArcDirection12.svg │ │ ├── AxisArcDirection13.svg │ │ ├── AxisArcDirection14.svg │ │ ├── AxisArcDirection15.svg │ │ ├── AxisArcDirection16.svg │ │ ├── AxisArcDirection17.svg │ │ ├── AxisArcDirection18.svg │ │ ├── AxisArcDirection19.svg │ │ ├── AxisArcDirection2.svg │ │ ├── AxisArcDirection20.svg │ │ ├── AxisArcDirection3.svg │ │ ├── AxisArcDirection4.svg │ │ ├── AxisArcDirection5.svg │ │ ├── AxisArcDirection6.svg │ │ ├── AxisArcDirection7.svg │ │ ├── AxisArcDirection8.svg │ │ ├── AxisArcDirection9.svg │ │ ├── AxisArcLabelRotate1.svg │ │ ├── AxisArcLabelRotate2.svg │ │ ├── AxisArcLabelRotate3.svg │ │ ├── AxisArcLabelRotate4.svg │ │ ├── AxisArcTitle1.svg │ │ ├── AxisArcTitle2.svg │ │ ├── AxisArcTitle3.svg │ │ ├── AxisArcTitle4.svg │ │ ├── AxisArcTitle5.svg │ │ ├── AxisArcTitle6.svg │ │ ├── AxisArcTitle7.svg │ │ ├── AxisArcTitle8.svg │ │ ├── AxisArcTitle9.svg │ │ ├── AxisGrid1.svg │ │ ├── AxisGrid10.svg │ │ ├── AxisGrid11.svg │ │ ├── AxisGrid12.svg │ │ ├── AxisGrid2.svg │ │ ├── AxisGrid3.svg │ │ ├── AxisGrid4.svg │ │ ├── AxisGrid5.svg │ │ ├── AxisGrid6.svg │ │ ├── AxisGrid7.svg │ │ ├── AxisGrid8.svg │ │ ├── AxisGrid9.svg │ │ ├── AxisLabelEllipsisUpdate.svg │ │ ├── AxisLabelHideUpdate.svg │ │ ├── AxisLabelOverlapUpdate.svg │ │ ├── AxisLabelRotateUpdate.svg │ │ ├── AxisLinearBasis1.svg │ │ ├── AxisLinearBasis2.svg │ │ ├── AxisLinearBasis3.svg │ │ ├── AxisLinearBasis4.svg │ │ ├── AxisLinearBasis5.svg │ │ ├── AxisLinearBasis6.svg │ │ ├── AxisLinearBasis7.svg │ │ ├── AxisLinearBasis8.svg │ │ ├── AxisLinearBasisZ.svg │ │ ├── AxisLinearCustomTick.svg │ │ ├── AxisLinearLabel.svg │ │ ├── AxisLinearLabelAlign1.svg │ │ ├── AxisLinearLabelAlign10.svg │ │ ├── AxisLinearLabelAlign11.svg │ │ ├── AxisLinearLabelAlign2.svg │ │ ├── AxisLinearLabelAlign3.svg │ │ ├── AxisLinearLabelAlign4.svg │ │ ├── AxisLinearLabelAlign5.svg │ │ ├── AxisLinearLabelAlign6.svg │ │ ├── AxisLinearLabelAlign7.svg │ │ ├── AxisLinearLabelAlign8.svg │ │ ├── AxisLinearLabelAlign9.svg │ │ ├── AxisLinearLabelOverlap.svg │ │ ├── AxisLinearLabelOverlap2.svg │ │ ├── AxisLinearLabelOverlapCrossSize.svg │ │ ├── AxisLinearLabelOverlapCrossSizeVertical.svg │ │ ├── AxisLinearLabelOverlapMultiple.svg │ │ ├── AxisLinearLabelOverlapWrap.svg │ │ ├── AxisLinearLabelOverlapWrapVertical.svg │ │ ├── AxisLinearLabelRotate.svg │ │ ├── AxisLinearLabelSpacing.svg │ │ ├── AxisLinearTime1.svg │ │ ├── AxisLinearTime2.svg │ │ ├── AxisLinearTitle.svg │ │ ├── AxisLinearTitleEnd.svg │ │ ├── AxisLinearTitlePosition.svg │ │ ├── AxisLinearTitleStart.svg │ │ ├── AxisLinearVertical.svg │ │ ├── BugAxisLabelPosition.svg │ │ ├── BugAxisLabelRotate.svg │ │ ├── BugAxisLabelWrap.svg │ │ ├── BugAxisTitlePosition.svg │ │ ├── BugCategoryItemUpdate1.svg │ │ ├── BugCategoryItemsUpdate1.svg │ │ ├── BugCategoryItemsUpdate2.svg │ │ ├── BugCategoryItemsUpdate3.svg │ │ ├── BugCategoryLabelDisplay.svg │ │ ├── BugCategoryMarker.svg │ │ ├── BugCategoryUpdate1.svg │ │ ├── BugCategoryUpdate2.svg │ │ ├── BugCategoryUpdate3.svg │ │ ├── BugCategoryUpdate4.svg │ │ ├── BugCategoryUpdate5.svg │ │ ├── BugCategoryUpdate6.svg │ │ ├── BugCategoryWithShape1.svg │ │ ├── BugCategoryWithShape2.svg │ │ ├── BugCategoryWithShape3.svg │ │ ├── Button1.svg │ │ ├── CategoryItem1.svg │ │ ├── CategoryItem10.svg │ │ ├── CategoryItem2.svg │ │ ├── CategoryItem3.svg │ │ ├── CategoryItem4.svg │ │ ├── CategoryItem5.svg │ │ ├── CategoryItem6.svg │ │ ├── CategoryItem7.svg │ │ ├── CategoryItem8.svg │ │ ├── CategoryItem9.svg │ │ ├── CategoryItemMarker1.svg │ │ ├── CategoryItemMarker2.svg │ │ ├── CategoryItems1.svg │ │ ├── CategoryItems10.svg │ │ ├── CategoryItems11.svg │ │ ├── CategoryItems12.svg │ │ ├── CategoryItems2.svg │ │ ├── CategoryItems3.svg │ │ ├── CategoryItems4.svg │ │ ├── CategoryItems5.svg │ │ ├── CategoryItems6.svg │ │ ├── CategoryItems7.svg │ │ ├── CategoryItems8.svg │ │ ├── CategoryItems9.svg │ │ ├── CategoryLayout1.svg │ │ ├── CategoryLayout10.svg │ │ ├── CategoryLayout11.svg │ │ ├── CategoryLayout12.svg │ │ ├── CategoryLayout13.svg │ │ ├── CategoryLayout14.svg │ │ ├── CategoryLayout15.svg │ │ ├── CategoryLayout16.svg │ │ ├── CategoryLayout17.svg │ │ ├── CategoryLayout18.svg │ │ ├── CategoryLayout19.svg │ │ ├── CategoryLayout2.svg │ │ ├── CategoryLayout20.svg │ │ ├── CategoryLayout21.svg │ │ ├── CategoryLayout22.svg │ │ ├── CategoryLayout23.svg │ │ ├── CategoryLayout24.svg │ │ ├── CategoryLayout25.svg │ │ ├── CategoryLayout26.svg │ │ ├── CategoryLayout27.svg │ │ ├── CategoryLayout28.svg │ │ ├── CategoryLayout29.svg │ │ ├── CategoryLayout3.svg │ │ ├── CategoryLayout30.svg │ │ ├── CategoryLayout31.svg │ │ ├── CategoryLayout32.svg │ │ ├── CategoryLayout33.svg │ │ ├── CategoryLayout34.svg │ │ ├── CategoryLayout4.svg │ │ ├── CategoryLayout5.svg │ │ ├── CategoryLayout6.svg │ │ ├── CategoryLayout7.svg │ │ ├── CategoryLayout8.svg │ │ ├── CategoryLayout9.svg │ │ ├── CategoryMarker.svg │ │ ├── CategoryPosition1.svg │ │ ├── CategoryPosition2.svg │ │ ├── CategoryPosition3.svg │ │ ├── Checkbox1.svg │ │ ├── Continuous1.svg │ │ ├── Continuous2.svg │ │ ├── Continuous3.svg │ │ ├── Continuous4.svg │ │ ├── Continuous5.svg │ │ ├── ContinuousD3ColorLegend.svg │ │ ├── ContinuousDemo.svg │ │ ├── CrosshairCircle.svg │ │ ├── CrosshairLine.svg │ │ ├── CrosshairPolygon.svg │ │ ├── Handle1.svg │ │ ├── Handle2.svg │ │ ├── HandleDemo.svg │ │ ├── HandleUpdate.svg │ │ ├── IndicatorDemo.svg │ │ ├── IndicatorRadius.svg │ │ ├── LayoutContinuous1.svg │ │ ├── LayoutContinuous2.svg │ │ ├── LayoutContinuous3.svg │ │ ├── LayoutContinuous4.svg │ │ ├── LayoutContinuous5.svg │ │ ├── LayoutContinuous6.svg │ │ ├── LayoutContinuous7.svg │ │ ├── LayoutContinuous8.svg │ │ ├── LayoutContinuous9.svg │ │ ├── LayoutFlexAlignItemsFlexCenter.svg │ │ ├── LayoutFlexAlignItemsFlexEnd.svg │ │ ├── LayoutFlexAlignItemsFlexStart.svg │ │ ├── LayoutFlexDirectionColumn.svg │ │ ├── LayoutFlexDirectionRow.svg │ │ ├── LayoutFlexJustifyContentCenter.svg │ │ ├── LayoutFlexJustifyContentFlexEnd.svg │ │ ├── LayoutFlexJustifyContentFlexStart.svg │ │ ├── LayoutFlexManipulateChildren.svg │ │ ├── LayoutFlexNest.svg │ │ ├── LayoutFlexPositionBottom.svg │ │ ├── LayoutFlexPositionBottomLeft.svg │ │ ├── LayoutFlexPositionBottomRight.svg │ │ ├── LayoutFlexPositionCenter.svg │ │ ├── LayoutFlexPositionLeft.svg │ │ ├── LayoutFlexPositionRight.svg │ │ ├── LayoutFlexPositionTop.svg │ │ ├── LayoutFlexPositionTopLeft.svg │ │ ├── LayoutFlexPositionTopRight.svg │ │ ├── LayoutFlexUpdateLayout.svg │ │ ├── LayoutLegend1.svg │ │ ├── LayoutLegend2.svg │ │ ├── LayoutLegend3.svg │ │ ├── LayoutLegend4.svg │ │ ├── LayoutLegend5.svg │ │ ├── LayoutLegend6.svg │ │ ├── LayoutLegend7.svg │ │ ├── LayoutLegend8.svg │ │ ├── LayoutLegend9.svg │ │ ├── LayoutLegendMultiple.svg │ │ ├── LayoutUpdateAttr.svg │ │ ├── LayoutUpdateAttr2.svg │ │ ├── Marker1.svg │ │ ├── MarkerUpdate.svg │ │ ├── NavigatorDemo.svg │ │ ├── NavigatorNull.svg │ │ ├── NavigatorOverPages.svg │ │ ├── NavigatorSingle.svg │ │ ├── NavigatorStyle.svg │ │ ├── NavigatorUpdate.svg │ │ ├── NavigatorWithoutShape.svg │ │ ├── RibbonColor.svg │ │ ├── RibbonDemo.svg │ │ ├── Scrollbar1.svg │ │ ├── Scrollbar2.svg │ │ ├── Scrollbar3.svg │ │ ├── SelectBasic.svg │ │ ├── SelectDefaultValue.svg │ │ ├── SelectDemoSpeed.svg │ │ ├── SelectEvents.svg │ │ ├── SelectInvalidDefaultValue.svg │ │ ├── SelectNoBorder.svg │ │ ├── SelectOpen.svg │ │ ├── Slider1.svg │ │ ├── Slider10.svg │ │ ├── Slider11.svg │ │ ├── Slider12.svg │ │ ├── Slider2.svg │ │ ├── Slider3.svg │ │ ├── Slider4.svg │ │ ├── Slider5.svg │ │ ├── Slider6.svg │ │ ├── Slider7.svg │ │ ├── Slider8.svg │ │ ├── Slider9.svg │ │ ├── SliderInvert.svg │ │ ├── SliderTimebar.svg │ │ ├── SliderValueType.svg │ │ ├── Sparkline1.svg │ │ ├── Sparkline10.svg │ │ ├── Sparkline11.svg │ │ ├── Sparkline12.svg │ │ ├── Sparkline2.svg │ │ ├── Sparkline3.svg │ │ ├── Sparkline4.svg │ │ ├── Sparkline5.svg │ │ ├── Sparkline6.svg │ │ ├── Sparkline7.svg │ │ ├── Sparkline8.svg │ │ ├── Sparkline9.svg │ │ ├── SparklineScaleColumn.svg │ │ ├── SparklineScaleLine.svg │ │ ├── Switch1.svg │ │ ├── Tag1.svg │ │ ├── Text1.svg │ │ ├── TimebarBasic.svg │ │ ├── TimebarChart.svg │ │ ├── TimebarController.svg │ │ ├── TimebarHandle.svg │ │ ├── TimebarIcons.svg │ │ ├── TimebarTime.svg │ │ ├── TitleDemo.svg │ │ ├── Tooltip1.svg │ │ ├── Tooltip10.svg │ │ ├── Tooltip2.svg │ │ ├── Tooltip3.svg │ │ ├── Tooltip4.svg │ │ ├── Tooltip5.svg │ │ ├── Tooltip6.svg │ │ ├── Tooltip7.svg │ │ ├── Tooltip8.svg │ │ └── Tooltip9.svg │ └── utils │ │ ├── color.ts │ │ ├── create-axis.ts │ │ ├── grid.ts │ │ ├── index.ts │ │ ├── it.ts │ │ ├── mock-data.ts │ │ ├── offscreen-canvas-context.ts │ │ └── time.ts ├── performance │ ├── .eslintrc.js │ ├── README.md │ ├── analysis.html │ ├── index.html │ ├── package.json │ ├── preview.html │ ├── report.html │ ├── reports │ │ ├── 1677118688224-ab79d0bfb7cc82333f2937b88b7cd4457f0489aa.json │ │ ├── 1677123639394-d8e692a1fc6ba6ce1944c23f66d27035e100bdc5.json │ │ ├── 1677228228368-158c79a24ad612f1f6004eef3855487e6adfce7c.json │ │ ├── 1677230360572-2087fb1a766773ab1df48498402a5563f0a87388.json │ │ ├── 1677580879072-8005408d6642e03663031f179a9027bb41fe3e69.json │ │ ├── 1678163237878-9f477cde3337fdcb7103a9a938bafae520d8d911.json │ │ └── 1680101820882-32c9d404bfe42cb1d1f2821a068a20b80263e3f3.json │ ├── scripts │ │ ├── main.ts │ │ ├── report.ts │ │ └── runner.ts │ ├── server.ts │ ├── tsconfig.json │ └── vite.config.js ├── unit │ ├── index-spec.ts │ ├── ui │ │ ├── axis │ │ │ └── is-point-inside-rectangle.spec.ts │ │ ├── marker │ │ │ └── parse-marker-spec.ts │ │ ├── sparkline │ │ │ ├── path-spec.ts │ │ │ └── util-spec.ts │ │ └── timeline │ │ │ └── data.ts │ └── util │ │ ├── deep-assign.spec.ts │ │ ├── geometry.ts │ │ ├── line-length-spec.ts │ │ └── lines-intersection-spec.ts │ │ ├── group-by.spec.ts │ │ ├── in-range.spec.ts │ │ ├── interpolate.spec.ts │ │ ├── layout.ts │ │ ├── flex.spec.ts │ │ └── utils.spec.ts │ │ ├── number-spec.ts │ │ ├── padding-spec.ts │ │ ├── scale-to-pixel.spec.ts │ │ ├── string.spec.ts │ │ ├── style-spec.ts │ │ ├── time-spec.ts │ │ └── transpose.spec.ts └── utils │ ├── delay.ts │ ├── dom.ts │ ├── index.ts │ └── render.ts ├── commitlint.config.js ├── docs ├── api.md └── components │ ├── axis.md │ ├── breadcrumb.md │ ├── button.md │ ├── checkbox.md │ ├── crosshair.md │ ├── legend.md │ ├── marker.md │ ├── navigator.md │ ├── poptip.md │ ├── scrollbar.md │ ├── select.md │ ├── slider.md │ ├── sparkline.md │ ├── statistic.md │ ├── switch.md │ ├── tag.md │ ├── timebar.md │ └── tooltip.md ├── jest.config.js ├── package.json ├── src ├── animation │ ├── fadeIn.ts │ ├── fadeOut.ts │ ├── index.ts │ ├── types.ts │ └── utils.ts ├── constant.ts ├── core │ ├── component.ts │ ├── index.ts │ └── types.ts ├── index.ts ├── shapes │ ├── Circle.ts │ ├── CustomElement.ts │ ├── DisplayObject.ts │ ├── Ellipse.ts │ ├── Group.ts │ ├── HTML.ts │ ├── Image.ts │ ├── Line.ts │ ├── Path.ts │ ├── Polygon.ts │ ├── Polyline.ts │ ├── Rect.ts │ ├── Text.ts │ ├── index.ts │ └── types.ts ├── types │ ├── index.ts │ ├── prefix.ts │ └── styles.ts ├── ui │ ├── axis │ │ ├── axis.ts │ │ ├── constant.ts │ │ ├── guides │ │ │ ├── grid.ts │ │ │ ├── labels.ts │ │ │ ├── line.ts │ │ │ ├── ticks.ts │ │ │ ├── title.ts │ │ │ └── utils.ts │ │ ├── index.ts │ │ ├── overlap │ │ │ ├── autoEllipsis.ts │ │ │ ├── autoHide.ts │ │ │ ├── autoRotate.ts │ │ │ ├── autoWrap.ts │ │ │ └── index.ts │ │ ├── types.ts │ │ └── utils │ │ │ ├── bounds.ts │ │ │ ├── contain.ts │ │ │ ├── index.ts │ │ │ ├── intersect.ts │ │ │ └── test.ts │ ├── breadcrumb │ │ ├── index.ts │ │ └── type.ts │ ├── button │ │ ├── constant.ts │ │ ├── index.ts │ │ └── types.ts │ ├── checkbox │ │ ├── constant.ts │ │ ├── index.ts │ │ └── types.ts │ ├── crosshair │ │ ├── base.ts │ │ ├── circle.ts │ │ ├── constant.ts │ │ ├── index.ts │ │ ├── line.ts │ │ ├── polygon.ts │ │ └── types.ts │ ├── grid │ │ ├── index.ts │ │ └── types.ts │ ├── index.ts │ ├── indicator │ │ ├── constant.ts │ │ ├── index.ts │ │ ├── indicator.ts │ │ └── types.ts │ ├── layout │ │ ├── index.ts │ │ ├── layout.ts │ │ └── types.ts │ ├── legend │ │ ├── base.ts │ │ ├── category.ts │ │ ├── category │ │ │ ├── item.ts │ │ │ └── items.ts │ │ ├── constant.ts │ │ ├── continuous.ts │ │ ├── continuous │ │ │ ├── handle.ts │ │ │ ├── ribbon.ts │ │ │ └── utils.ts │ │ ├── index.ts │ │ ├── types.ts │ │ └── utils.ts │ ├── marker │ │ ├── index.ts │ │ ├── symbol.ts │ │ ├── types.ts │ │ └── utils.ts │ ├── navigator │ │ ├── index.ts │ │ └── types.ts │ ├── poptip │ │ ├── constant.ts │ │ ├── index.ts │ │ ├── types.ts │ │ └── utils.ts │ ├── scrollbar │ │ ├── index.ts │ │ └── types.ts │ ├── select │ │ ├── index.ts │ │ ├── option.ts │ │ ├── select.ts │ │ └── types.ts │ ├── slider │ │ ├── constant.ts │ │ ├── handle.ts │ │ ├── index.ts │ │ └── types.ts │ ├── sparkline │ │ ├── columns.ts │ │ ├── index.ts │ │ ├── lines.ts │ │ ├── path.ts │ │ ├── types.ts │ │ └── utils.ts │ ├── switch │ │ ├── constant.ts │ │ ├── index.ts │ │ └── types.ts │ ├── tag │ │ ├── index.ts │ │ └── types.ts │ ├── timebar │ │ ├── controller.ts │ │ ├── handle.ts │ │ ├── icons.ts │ │ ├── index.ts │ │ ├── timebar.ts │ │ ├── types.ts │ │ └── utils.ts │ ├── timeline │ │ ├── button.ts │ │ ├── cellAxis.ts │ │ ├── checkbox.ts │ │ ├── constants.ts │ │ ├── index.ts │ │ ├── playAxis.ts │ │ ├── sliderAxis.ts │ │ ├── speedcontrol.ts │ │ └── types.ts │ ├── title │ │ ├── index.ts │ │ └── types.ts │ └── tooltip │ │ ├── constant.ts │ │ ├── index.ts │ │ └── types.ts └── util │ ├── angle-converter.ts │ ├── bbox.ts │ ├── callback.ts │ ├── classnames.ts │ ├── deep-assign.ts │ ├── defined.ts │ ├── ellipsis.ts │ ├── event.ts │ ├── extend-display-object.ts │ ├── geometry │ ├── index.ts │ ├── line-length.ts │ └── lines-intersection.ts │ ├── group-by.ts │ ├── group.ts │ ├── html.ts │ ├── if-show.ts │ ├── in-range.ts │ ├── index.ts │ ├── interpolate.ts │ ├── keyframe-interpolate.ts │ ├── layout │ ├── executer.ts │ ├── flex │ │ ├── index.ts │ │ └── types.ts │ ├── grid │ │ ├── index.ts │ │ └── types.ts │ ├── index.ts │ ├── types.ts │ └── utils │ │ ├── helper.ts │ │ └── index.ts │ ├── matrix.ts │ ├── number.ts │ ├── offscreen.ts │ ├── omit.ts │ ├── path.ts │ ├── primitive.ts │ ├── replace-children.ts │ ├── sampling.ts │ ├── scale-to-pixel.ts │ ├── selection.ts │ ├── series.ts │ ├── shape.ts │ ├── string.ts │ ├── style.ts │ ├── svg2marker.ts │ ├── text.ts │ ├── throttle.ts │ ├── time.ts │ ├── timer.ts │ ├── transform.ts │ ├── transpose.ts │ ├── traverse.ts │ ├── visibility.ts │ └── wrap.ts ├── tsconfig.json ├── vite.config.js └── webpack.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | charset = utf-8 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [Makefile] 16 | indent_style = tab 17 | indent_size = 1 18 | 19 | [*.md] 20 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist/ 3 | build/ 4 | examples/ -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: macos-latest 8 | 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v2.3.4 12 | 13 | - name: Setup Node.js environment 14 | uses: actions/setup-node@v2.1.5 15 | with: 16 | node-version: '16' 17 | - name: Run ci 18 | run: | 19 | npm install --legacy-peer-deps 20 | npm run ci 21 | 22 | - name: Upload blob report to GitHub Actions Artifacts 23 | if: always() 24 | uses: actions/upload-artifact@v4 25 | with: 26 | name: snapshots 27 | path: | 28 | __tests__/integration/snapshots/*-actual.svg 29 | retention-days: 1 30 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no-install commitlint --edit "$1" 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | __tests__/performance/reports -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true, 4 | "trailingComma": "es5", 5 | "bracketSpacing": true, 6 | "printWidth": 120, 7 | "arrowParens": "always" 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": ["bbox", "Sparkline", "timebar"], 3 | "svg.preview.background": "white" 4 | } 5 | -------------------------------------------------------------------------------- /__tests__/bugs/issue-1.spec.ts: -------------------------------------------------------------------------------- 1 | describe('issue-1', () => { 2 | test('#1', () => { 3 | expect(1).toBe(1); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /__tests__/integration/animation/index.ts: -------------------------------------------------------------------------------- 1 | export * from './transition-1'; 2 | export * from './transition-2'; 3 | -------------------------------------------------------------------------------- /__tests__/integration/animation/transition-1.ts: -------------------------------------------------------------------------------- 1 | import { Group, Rect } from '@antv/g'; 2 | import { transition } from '../../../src/animation'; 3 | 4 | export function Transition1() { 5 | const group = new Group(); 6 | 7 | const rect = group.appendChild( 8 | new Rect({ 9 | style: { 10 | x: 0, 11 | y: 0, 12 | width: 100, 13 | height: 100, 14 | fill: 'red', 15 | }, 16 | }) 17 | ); 18 | 19 | setTimeout(() => { 20 | transition(rect, { x: 100, y: 100, fill: 'green', width: 50, height: 50 }, { duration: 1000, fill: 'both' }); 21 | }); 22 | 23 | return group; 24 | } 25 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-basis-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcBasis1 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | class: 'axis-class', 13 | style: { 14 | data: data(12), 15 | showArrow: false, 16 | center: [150, 150], 17 | endAngle: 135, 18 | labelSpacing: 10, 19 | lineLineWidth: 5, 20 | lineStroke: 'red', 21 | radius: 80, 22 | startAngle: -135, 23 | tickLength: 10, 24 | tickStroke: 'red', 25 | type: 'arc', 26 | }, 27 | }) 28 | ); 29 | 30 | return group; 31 | }; 32 | 33 | AxisArcBasis1.tags = ['极坐标系', '红色轴线', '隐藏箭头']; 34 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-basis-2.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcBasis2 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(12), 14 | center: [150, 150], 15 | endAngle: 135, 16 | labelSpacing: 10, 17 | lineLineWidth: 5, 18 | lineStroke: 'orange', 19 | radius: 80, 20 | startAngle: -135, 21 | tickDirection: 'negative', 22 | tickLength: 10, 23 | type: 'arc', 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | AxisArcBasis2.tags = ['极坐标系', '橙色轴线', '刻度朝外']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-basis-3.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcBasis3 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(12), 14 | type: 'arc', 15 | startAngle: -135, 16 | endAngle: 135, 17 | center: [150, 150], 18 | tickDirection: 'negative', 19 | labelDirection: 'negative', 20 | lineStroke: 'green', 21 | radius: 80, 22 | lineLineWidth: 5, 23 | tickLength: 10, 24 | labelSpacing: 10, 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcBasis3.tags = ['极坐标系', '刻度朝外', '标签在外']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-basis-4.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcBasis4 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(12), 14 | center: [150, 150], 15 | endAngle: 270, 16 | labelDirection: 'negative', 17 | labelSpacing: 10, 18 | lineLineWidth: 5, 19 | lineStroke: 'blue', 20 | radius: 80, 21 | startAngle: -90, 22 | tickLength: 10, 23 | type: 'arc', 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | AxisArcBasis4.tags = ['极坐标系', '360度圆形', '标签在外']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection1 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(8), 14 | center: [150, 150], 15 | endAngle: 270, 16 | labelSpacing: 15, 17 | lineLineWidth: 5, 18 | radius: 80, 19 | startAngle: -90, 20 | tickLength: 10, 21 | type: 'arc', 22 | }, 23 | }) 24 | ); 25 | 26 | return group; 27 | }; 28 | 29 | AxisArcDirection1.tags = ['极坐标系', '刻度朝内', '标签在内', '标签垂直于轴线']; 30 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-10.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection10 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(6), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 10, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | tickDirection: 'positive', 23 | labelDirection: 'negative', 24 | labelAlign: 'horizontal', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcDirection10.tags = ['极坐标系', '刻度朝内', '标签在外', '标签水平']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-11.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection11 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(6), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 10, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | tickDirection: 'negative', 23 | labelDirection: 'positive', 24 | labelAlign: 'horizontal', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcDirection11.tags = ['极坐标系', '刻度朝内', '标签在外', '标签水平']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-12.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection12 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(6), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 10, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | tickDirection: 'negative', 23 | labelDirection: 'negative', 24 | labelAlign: 'horizontal', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcDirection12.tags = ['极坐标系', '刻度朝外', '标签在外', '标签水平']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-13.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection13 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(6), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 10, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | }, 23 | }) 24 | ); 25 | 26 | return group; 27 | }; 28 | 29 | AxisArcDirection13.tags = ['极坐标系', '刻度朝内', '标签在内', '标签垂直于刻度']; 30 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-14.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection14 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(6), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 10, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | tickDirection: 'positive', 23 | labelDirection: 'negative', 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | AxisArcDirection14.tags = ['极坐标系', '刻度朝内', '标签在外', '标签垂直于刻度']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-15.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection15 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(6), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 10, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | tickDirection: 'negative', 23 | labelDirection: 'positive', 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | AxisArcDirection15.tags = ['极坐标系', '刻度朝外', '标签在内', '标签垂直于刻度']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-16.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection16 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(6), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 10, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | tickDirection: 'negative', 23 | labelDirection: 'negative', 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | AxisArcDirection16.tags = ['极坐标系', '刻度朝外', '标签在外', '标签垂直于刻度']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-17.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection17 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(12), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 0, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | tickDirection: 'positive', 23 | labelDirection: 'positive', 24 | labelAlign: 'perpendicular', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcDirection17.tags = ['极坐标系', '刻度朝内', '标签在内', '标签平行于刻度']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-18.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection18 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(12), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 0, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | tickDirection: 'positive', 23 | labelDirection: 'negative', 24 | labelAlign: 'perpendicular', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcDirection18.tags = ['极坐标系', '刻度朝内', '标签在外', '标签平行于刻度']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-19.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection19 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(12), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 0, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | tickDirection: 'negative', 23 | labelDirection: 'positive', 24 | labelAlign: 'perpendicular', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcDirection19.tags = ['极坐标系', '刻度朝外', '标签在内', '标签平行于刻度']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-2.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection2 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(8), 14 | center: [150, 150], 15 | endAngle: 270, 16 | labelAlign: 'perpendicular', 17 | labelDirection: 'positive', 18 | labelSpacing: 15, 19 | lineLineWidth: 5, 20 | radius: 80, 21 | startAngle: -90, 22 | tickDirection: 'positive', 23 | tickLength: 10, 24 | type: 'arc', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcDirection2.tags = ['极坐标系', '刻度朝内', '标签在内', '标签平行于轴线']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-20.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection20 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(12), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 0, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | tickDirection: 'negative', 23 | labelDirection: 'negative', 24 | labelAlign: 'perpendicular', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcDirection20.tags = ['极坐标系', '刻度朝外', '标签在外', '标签平行于刻度']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-3.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection3 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(8), 14 | center: [150, 150], 15 | endAngle: 270, 16 | labelAlign: 'horizontal', 17 | labelDirection: 'negative', 18 | labelSpacing: 15, 19 | lineLineWidth: 5, 20 | radius: 80, 21 | startAngle: -90, 22 | tickDirection: 'positive', 23 | tickLength: 10, 24 | type: 'arc', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcDirection3.tags = ['极坐标系', '刻度朝内', '标签在外', '标签水平']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-4.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection4 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(8), 14 | center: [150, 150], 15 | endAngle: 270, 16 | labelAlign: 'perpendicular', 17 | labelDirection: 'positive', 18 | labelSpacing: 15, 19 | lineLineWidth: 5, 20 | radius: 80, 21 | startAngle: -90, 22 | tickDirection: 'negative', 23 | tickLength: 10, 24 | type: 'arc', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcDirection4.tags = ['极坐标系', '刻度朝外', '标签在内', '标签平行于轴线']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-5.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection5 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(12), 14 | center: [150, 150], 15 | endAngle: 270, 16 | labelDirection: 'negative', 17 | labelSpacing: 10, 18 | lineLineWidth: 5, 19 | radius: 80, 20 | startAngle: -90, 21 | tickDirection: 'negative', 22 | tickLength: 10, 23 | type: 'arc', 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | AxisArcDirection5.tags = ['极坐标系', '刻度朝外', '标签在外', '标签垂直于轴线']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-6.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection6 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(12), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 10, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | tickDirection: 'negative', 23 | labelDirection: 'negative', 24 | labelAlign: 'perpendicular', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcDirection6.tags = ['极坐标系', '刻度朝外', '标签在外', '标签平行于轴线']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-7.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection7 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(12), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 10, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | tickDirection: 'negative', 23 | labelDirection: 'negative', 24 | labelAlign: 'horizontal', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcDirection7.tags = ['极坐标系', '刻度朝外', '标签在外', '标签水平']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-8.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection8 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(12), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 10, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | tickDirection: 'negative', 23 | labelDirection: 'positive', 24 | labelAlign: 'perpendicular', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcDirection8.tags = ['极坐标系', '刻度朝外', '标签在内', '标签平行于轴线']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-direction-9.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcDirection9 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(6), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 10, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | tickDirection: 'positive', 23 | labelDirection: 'positive', 24 | labelAlign: 'horizontal', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArcDirection9.tags = ['极坐标系', '刻度朝内', '标签在内', '标签水平']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-label-rotate-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { data } from '../../utils'; 3 | import { Axis } from '../../../../src/ui/axis'; 4 | 5 | export const AxisArcLabelRotate1 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(10), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 15, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | }, 23 | }) 24 | ); 25 | 26 | return group; 27 | }; 28 | 29 | AxisArcLabelRotate1.tags = ['极坐标系', '标签在内', '无预设值']; 30 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-label-rotate-2.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { data } from '../../utils'; 3 | import { Axis } from '../../../../src/ui/axis'; 4 | 5 | export const AxisArcLabelRotate2 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(10), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 15, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | labelTransform: 'rotate(45)', 23 | }, 24 | }) 25 | ); 26 | 27 | return group; 28 | }; 29 | 30 | AxisArcLabelRotate2.tags = ['极坐标系', '标签在内', '45度']; 31 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-label-rotate-3.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { data } from '../../utils'; 3 | import { Axis } from '../../../../src/ui/axis'; 4 | 5 | export const AxisArcLabelRotate3 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(10), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 15, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | labelTransform: 'rotate(0)', 23 | }, 24 | }) 25 | ); 26 | 27 | return group; 28 | }; 29 | 30 | AxisArcLabelRotate3.tags = ['极坐标系', '标签在内', '0度']; 31 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-label-rotate-4.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { data } from '../../utils'; 3 | import { Axis } from '../../../../src/ui/axis'; 4 | 5 | export const AxisArcLabelRotate4 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(10), 14 | type: 'arc', 15 | radius: 80, 16 | lineLineWidth: 5, 17 | tickLength: 10, 18 | labelSpacing: 15, 19 | startAngle: -90, 20 | endAngle: 270, 21 | center: [150, 150], 22 | labelTransform: 'rotate(-45)', 23 | }, 24 | }) 25 | ); 26 | 27 | return group; 28 | }; 29 | 30 | AxisArcLabelRotate4.tags = ['极坐标系', '标签在内', '-45度']; 31 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-title-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcTitle1 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(8), 14 | type: 'arc', 15 | radius: 80, 16 | titleText: 'title', 17 | lineLineWidth: 5, 18 | titleFill: 'red', 19 | titleFontSize: 16, 20 | titleFontWeight: 'bold', 21 | titleSpacing: 10, 22 | tickLength: 10, 23 | labelSpacing: 15, 24 | startAngle: -90, 25 | endAngle: 270, 26 | center: [150, 150], 27 | titleTransform: 'translate(100%, 0)', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | AxisArcTitle1.tags = ['极坐标系', '标题', '左下']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-title-2.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcTitle2 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(8), 14 | type: 'arc', 15 | radius: 80, 16 | titleText: 'title', 17 | lineLineWidth: 5, 18 | titleFill: 'red', 19 | titleFontSize: 16, 20 | titleFontWeight: 'bold', 21 | titleSpacing: 10, 22 | tickLength: 10, 23 | labelSpacing: 15, 24 | startAngle: -90, 25 | endAngle: 270, 26 | center: [150, 150], 27 | titlePosition: 'b', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | AxisArcTitle2.tags = ['极坐标系', '标题', '正下', '居中']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-title-4.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcTitle4 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(8), 14 | type: 'arc', 15 | radius: 80, 16 | titleText: 'title', 17 | lineLineWidth: 5, 18 | titleFill: 'red', 19 | titleFontSize: 16, 20 | titleFontWeight: 'bold', 21 | titleSpacing: 10, 22 | tickLength: 10, 23 | labelSpacing: 15, 24 | startAngle: -90, 25 | endAngle: 270, 26 | center: [150, 150], 27 | titlePosition: 'inner', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | AxisArcTitle4.tags = ['极坐标系', '标题', '中心', '内部', '居中']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-title-6.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcTitle6 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(8), 14 | type: 'arc', 15 | radius: 80, 16 | titleText: 'title', 17 | lineLineWidth: 5, 18 | titleFill: 'red', 19 | titleFontSize: 16, 20 | titleFontWeight: 'bold', 21 | titleSpacing: 10, 22 | tickLength: 10, 23 | labelSpacing: 15, 24 | startAngle: -90, 25 | endAngle: 270, 26 | center: [150, 150], 27 | titlePosition: 'l', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | AxisArcTitle6.tags = ['极坐标系', '标题', '居左']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc-title-7.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArcTitle7 = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(8), 14 | type: 'arc', 15 | radius: 80, 16 | titleText: 'title', 17 | lineLineWidth: 5, 18 | titleFill: 'red', 19 | titleFontSize: 16, 20 | titleFontWeight: 'bold', 21 | titleSpacing: 10, 22 | tickLength: 10, 23 | labelSpacing: 15, 24 | startAngle: -90, 25 | endAngle: 270, 26 | center: [150, 150], 27 | titlePosition: 'r', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | AxisArcTitle7.tags = ['极坐标系', '标题', '居右']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-arc.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisArc = () => { 6 | const group = new Group({ 7 | style: { width: 400, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: data(60), 14 | labelFormatter: (d: any, i: number) => (i % 5 === 0 ? i / 5 : ''), 15 | type: 'arc', 16 | radius: 80, 17 | startAngle: -90, 18 | endAngle: 270, 19 | center: [150, 150], 20 | titleText: '极坐标系', 21 | titleSpacing: 10, 22 | lineLineWidth: 1, 23 | tickLength: (d: any, i: number) => (i % 5 === 0 ? 10 : 5), 24 | labelSpacing: 10, 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | AxisArc.tags = ['极坐标系']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-grid-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisGrid1 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 550, 9 | height: 300, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | showLabel: false, 17 | data: data(12), 18 | type: 'linear', 19 | startPos: [50, 50], 20 | endPos: [500, 50], 21 | tickDirection: 'negative', 22 | gridLength: 200, 23 | gridAreaFill: 'rgba(0,0,0,0.05)', 24 | gridLineWidth: 0, 25 | lineLineWidth: 1, 26 | tickLength: 10, 27 | labelSpacing: 10, 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | AxisGrid1.tags = ['笛卡尔坐标系', '条形网格线', '间隔颜色填充']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-grid-2.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisGrid2 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 550, 9 | height: 300, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | showTick: false, 17 | showLabel: false, 18 | data: data(12), 19 | type: 'linear', 20 | startPos: [50, 50], 21 | endPos: [500, 50], 22 | tickDirection: 'negative', 23 | gridLength: 200, 24 | gridLineWidth: 1, 25 | gridStroke: 'rgba(0,0,0,0.5)', 26 | lineLineWidth: 1, 27 | tickLength: 10, 28 | labelSpacing: 10, 29 | }, 30 | }) 31 | ); 32 | 33 | return group; 34 | }; 35 | 36 | AxisGrid2.tags = ['笛卡尔坐标系', '条形网格线', '无填充']; 37 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-grid-4.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisGrid4 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 300, 9 | height: 400, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | data: data(6), 17 | type: 'linear', 18 | startPos: [50, 50], 19 | endPos: [50, 350], 20 | tickDirection: 'positive', 21 | gridLength: 200, 22 | gridDirection: 'negative', 23 | gridAreaFill: ['#f2cea5', '#f8dea3', '#c6cf93', '#95b5c0'], 24 | lineLineWidth: 1, 25 | tickLength: 10, 26 | labelSpacing: 10, 27 | }, 28 | }) 29 | ); 30 | 31 | return group; 32 | }; 33 | 34 | AxisGrid4.tags = ['笛卡尔坐标系', '条形网格线', '顺序颜色填充', '纵向']; 35 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-basis-3.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { mockData } from '../../utils/mock-data'; 3 | import { Axis } from '../../../../src/ui/axis'; 4 | 5 | export const AxisLinearBasis3 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 600, 9 | height: 600, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | data: mockData, 17 | startPos: [50, 100], 18 | endPos: [450, 500], 19 | lineLineWidth: 5, 20 | lineStroke: 'orange', 21 | tickStroke: 'black', 22 | tickLength: 10, 23 | tickLineWidth: 5, 24 | labelDirection: 'negative', 25 | labelSpacing: 5, 26 | labelTransform: 'rotate(-45)', 27 | type: 'linear', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | AxisLinearBasis3.tags = ['笛卡尔坐标系', '倾斜', '正向']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-basis-4.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { mockData } from '../../utils/mock-data'; 3 | import { Axis } from '../../../../src/ui/axis'; 4 | 5 | export const AxisLinearBasis4 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 650, 9 | height: 550, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | data: mockData, 17 | startPos: [550, 500], 18 | endPos: [100, 50], 19 | lineLineWidth: 5, 20 | lineStroke: 'blue', 21 | tickStroke: 'blue', 22 | tickLength: 10, 23 | labelSpacing: 5, 24 | labelTransform: 'rotate(-45)', 25 | type: 'linear', 26 | tickLineWidth: 5, 27 | }, 28 | }) 29 | ); 30 | 31 | return group; 32 | }; 33 | 34 | AxisLinearBasis4.tags = ['笛卡尔坐标系', '倾斜', '反向']; 35 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-basis-6.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { mockData } from '../../utils/mock-data'; 3 | import { Axis } from '../../../../src/ui/axis'; 4 | 5 | export const AxisLinearBasis6 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 200, 9 | height: 550, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | data: mockData, 17 | startPos: [50, 500], 18 | endPos: [50, 50], 19 | lineLineWidth: 5, 20 | lineStroke: 'purple', 21 | tickLength: 10, 22 | labelSpacing: 5, 23 | labelAlign: 'horizontal', 24 | type: 'linear', 25 | tickLineWidth: 5, 26 | }, 27 | }) 28 | ); 29 | 30 | return group; 31 | }; 32 | 33 | AxisLinearBasis6.tags = ['笛卡尔坐标系', '垂直', '反向']; 34 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisLinearLabelAlign1 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 550, 9 | height: 150, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | data: data(12), 17 | labelFormatter: (_: any, index: number) => 'ABC', 18 | type: 'linear', 19 | lineLineWidth: 5, 20 | tickLineWidth: 5, 21 | labelSpacing: 5, 22 | tickLength: 10, 23 | startPos: [50, 50], 24 | endPos: [500, 50], 25 | tickDirection: 'negative', 26 | }, 27 | }) 28 | ); 29 | 30 | return group; 31 | }; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-10.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisLinearLabelAlign10 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 1000, 9 | height: 1000, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | data: data(12), 17 | labelFormatter: (_: any, index: number) => 'ABC', 18 | type: 'linear', 19 | lineLineWidth: 5, 20 | tickLineWidth: 5, 21 | labelSpacing: 5, 22 | tickLength: 10, 23 | startPos: [950, 500], 24 | endPos: [550, 100], 25 | tickDirection: 'negative', 26 | labelDirection: 'positive', 27 | labelAlign: 'horizontal', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-11.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Text } from '../../../../src/shapes'; 3 | import { Axis } from '../../../../src/ui/axis'; 4 | import { data } from '../../utils'; 5 | 6 | export const AxisLinearLabelAlign11 = () => { 7 | const group = new Group({ 8 | style: { 9 | width: 550, 10 | height: 100, 11 | }, 12 | }); 13 | const axis = group.appendChild( 14 | new Axis({ 15 | style: { 16 | data: data(12), 17 | labelFormatter: (_: any, index: number) => new Text({ style: { text: '666' } }), 18 | type: 'linear', 19 | lineLineWidth: 5, 20 | tickLineWidth: 5, 21 | labelSpacing: 5, 22 | tickLength: 10, 23 | startPos: [50, 50], 24 | endPos: [500, 50], 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-12.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { Text } from '../../../../src/shapes'; 4 | import { data } from '../../utils'; 5 | 6 | export const AxisLinearLabelAlign12 = () => { 7 | const group = new Group({}); 8 | group.appendChild( 9 | new Axis({ 10 | style: { 11 | data: data(12), 12 | labelFormatter: (_: any, index: number) => new Text({ style: { text: '666' } }), 13 | type: 'linear', 14 | lineLineWidth: 5, 15 | tickLineWidth: 5, 16 | labelSpacing: 5, 17 | tickLength: 10, 18 | startPos: [500, 550], 19 | endPos: [50, 550], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-13.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { Text } from '../../../../src/shapes'; 4 | import { data } from '../../utils'; 5 | 6 | export const AxisLinearLabelAlign13 = () => { 7 | const group = new Group({}); 8 | group.appendChild( 9 | new Axis({ 10 | style: { 11 | data: data(12), 12 | labelFormatter: (_: any, index: number) => new Text({ style: { text: '666' } }), 13 | type: 'linear', 14 | lineLineWidth: 5, 15 | tickLineWidth: 5, 16 | labelSpacing: 5, 17 | tickLength: 10, 18 | startPos: [50, 150], 19 | endPos: [50, 500], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-14.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { Text } from '../../../../src/shapes'; 4 | import { data } from '../../utils'; 5 | 6 | export const AxisLinearLabelAlign14 = () => { 7 | const group = new Group({}); 8 | group.appendChild( 9 | new Axis({ 10 | style: { 11 | data: data(12), 12 | labelFormatter: (_: any, index: number) => new Text({ style: { text: '666' } }), 13 | type: 'linear', 14 | lineLineWidth: 5, 15 | tickLineWidth: 5, 16 | labelSpacing: 5, 17 | tickLength: 10, 18 | startPos: [100, 500], 19 | endPos: [100, 200], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-15.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { Text } from '../../../../src/shapes'; 4 | import { data } from '../../utils'; 5 | 6 | export const AxisLinearLabelAlign15 = () => { 7 | const group = new Group({}); 8 | group.appendChild( 9 | new Axis({ 10 | style: { 11 | data: data(12), 12 | labelFormatter: (_: any, index: number) => new Text({ style: { text: '666' } }), 13 | type: 'linear', 14 | lineLineWidth: 5, 15 | tickLineWidth: 5, 16 | labelSpacing: 5, 17 | tickLength: 10, 18 | startPos: [50, 100], 19 | endPos: [450, 500], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-16.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { Text } from '../../../../src/shapes'; 4 | import { data } from '../../utils'; 5 | 6 | export const AxisLinearLabelAlign16 = () => { 7 | const group = new Group({}); 8 | group.appendChild( 9 | new Axis({ 10 | style: { 11 | data: data(12), 12 | labelFormatter: (_: any, index: number) => new Text({ style: { text: '666' } }), 13 | type: 'linear', 14 | lineLineWidth: 5, 15 | tickLineWidth: 5, 16 | labelSpacing: 5, 17 | tickLength: 10, 18 | startPos: [150, 100], 19 | endPos: [550, 500], 20 | labelAlign: 'perpendicular', 21 | }, 22 | }) 23 | ); 24 | 25 | return group; 26 | }; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-17.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { Text } from '../../../../src/shapes'; 4 | import { data } from '../../utils'; 5 | 6 | export const AxisLinearLabelAlign17 = () => { 7 | const group = new Group({}); 8 | group.appendChild( 9 | new Axis({ 10 | style: { 11 | data: data(12), 12 | labelFormatter: (_: any, index: number) => new Text({ style: { text: '666' } }), 13 | type: 'linear', 14 | lineLineWidth: 5, 15 | tickLineWidth: 5, 16 | labelSpacing: 5, 17 | tickLength: 10, 18 | startPos: [250, 100], 19 | endPos: [650, 500], 20 | labelAlign: 'horizontal', 21 | }, 22 | }) 23 | ); 24 | 25 | return group; 26 | }; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-18.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { Text } from '../../../../src/shapes'; 4 | import { data } from '../../utils'; 5 | 6 | export const AxisLinearLabelAlign18 = () => { 7 | const group = new Group({}); 8 | group.appendChild( 9 | new Axis({ 10 | style: { 11 | data: data(12), 12 | labelFormatter: (_: any, index: number) => new Text({ style: { text: '666' } }), 13 | type: 'linear', 14 | lineLineWidth: 5, 15 | tickLineWidth: 5, 16 | labelSpacing: 5, 17 | tickLength: 10, 18 | startPos: [750, 500], 19 | endPos: [350, 100], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-19.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { Text } from '../../../../src/shapes'; 4 | import { data } from '../../utils'; 5 | 6 | export const AxisLinearLabelAlign19 = () => { 7 | const group = new Group({}); 8 | group.appendChild( 9 | new Axis({ 10 | style: { 11 | data: data(12), 12 | labelFormatter: (_: any, index: number) => new Text({ style: { text: '666' } }), 13 | type: 'linear', 14 | lineLineWidth: 5, 15 | tickLineWidth: 5, 16 | labelSpacing: 5, 17 | tickLength: 10, 18 | startPos: [850, 500], 19 | endPos: [450, 100], 20 | labelAlign: 'perpendicular', 21 | }, 22 | }) 23 | ); 24 | 25 | return group; 26 | }; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-2.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisLinearLabelAlign2 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 550, 9 | height: 600, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | data: data(12), 17 | labelFormatter: (_: any, index: number) => 'ABC', 18 | type: 'linear', 19 | lineLineWidth: 5, 20 | tickLineWidth: 5, 21 | labelSpacing: 5, 22 | tickLength: 10, 23 | startPos: [500, 550], 24 | endPos: [50, 550], 25 | tickDirection: 'negative', 26 | }, 27 | }) 28 | ); 29 | 30 | return group; 31 | }; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-20.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { Text } from '../../../../src/shapes'; 4 | import { data } from '../../utils'; 5 | 6 | export const AxisLinearLabelAlign20 = () => { 7 | const group = new Group({}); 8 | group.appendChild( 9 | new Axis({ 10 | style: { 11 | data: data(12), 12 | labelFormatter: (_: any, index: number) => new Text({ style: { text: '666' } }), 13 | type: 'linear', 14 | lineLineWidth: 5, 15 | tickLineWidth: 5, 16 | labelSpacing: 5, 17 | tickLength: 10, 18 | startPos: [950, 500], 19 | endPos: [550, 100], 20 | labelAlign: 'horizontal', 21 | }, 22 | }) 23 | ); 24 | 25 | return group; 26 | }; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-3.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisLinearLabelAlign3 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 100, 9 | height: 550, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | data: data(12), 17 | labelFormatter: (_: any, index: number) => 'ABC', 18 | type: 'linear', 19 | lineLineWidth: 5, 20 | tickLineWidth: 5, 21 | labelSpacing: 5, 22 | tickLength: 10, 23 | startPos: [50, 150], 24 | endPos: [50, 500], 25 | tickDirection: 'positive', 26 | labelDirection: 'negative', 27 | }, 28 | }) 29 | ); 30 | 31 | return group; 32 | }; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-4.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisLinearLabelAlign4 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 150, 9 | height: 550, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | data: data(12), 17 | labelFormatter: (_: any, index: number) => 'ABC', 18 | type: 'linear', 19 | lineLineWidth: 5, 20 | tickLineWidth: 5, 21 | labelSpacing: 5, 22 | tickLength: 10, 23 | startPos: [100, 500], 24 | endPos: [100, 200], 25 | tickDirection: 'negative', 26 | labelDirection: 'negative', 27 | }, 28 | }) 29 | ); 30 | 31 | return group; 32 | }; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-5.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisLinearLabelAlign5 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 1000, 9 | height: 1000, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | data: data(12), 17 | labelFormatter: (_: any, index: number) => 'ABC', 18 | type: 'linear', 19 | lineLineWidth: 5, 20 | tickLineWidth: 5, 21 | labelSpacing: 5, 22 | tickLength: 10, 23 | startPos: [50, 100], 24 | endPos: [450, 500], 25 | tickDirection: 'negative', 26 | }, 27 | }) 28 | ); 29 | 30 | return group; 31 | }; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-6.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisLinearLabelAlign6 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 1000, 9 | height: 1000, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | data: data(12), 17 | labelFormatter: (_: any, index: number) => 'ABC', 18 | type: 'linear', 19 | lineLineWidth: 5, 20 | tickLineWidth: 5, 21 | labelSpacing: 5, 22 | tickLength: 10, 23 | startPos: [150, 100], 24 | endPos: [550, 500], 25 | tickDirection: 'negative', 26 | labelDirection: 'positive', 27 | labelAlign: 'perpendicular', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-7.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisLinearLabelAlign7 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 1000, 9 | height: 1000, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | data: data(12), 17 | labelFormatter: (_: any, index: number) => 'ABC', 18 | type: 'linear', 19 | lineLineWidth: 5, 20 | tickLineWidth: 5, 21 | labelSpacing: 5, 22 | tickLength: 10, 23 | startPos: [250, 100], 24 | endPos: [650, 500], 25 | tickDirection: 'negative', 26 | labelDirection: 'positive', 27 | labelAlign: 'horizontal', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-8.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisLinearLabelAlign8 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 1000, 9 | height: 1000, 10 | }, 11 | }); 12 | group.appendChild( 13 | new Axis({ 14 | style: { 15 | data: data(12), 16 | labelFormatter: (_: any, index: number) => 'ABC', 17 | type: 'linear', 18 | lineLineWidth: 5, 19 | tickLineWidth: 5, 20 | labelSpacing: 5, 21 | tickLength: 10, 22 | startPos: [750, 500], 23 | endPos: [350, 100], 24 | tickDirection: 'negative', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | -------------------------------------------------------------------------------- /__tests__/integration/components/axis/axis-linear-label-align-9.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { data } from '../../utils'; 4 | 5 | export const AxisLinearLabelAlign9 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 1000, 9 | height: 1000, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Axis({ 15 | style: { 16 | data: data(12), 17 | labelFormatter: (_: any, index: number) => 'ABC', 18 | type: 'linear', 19 | lineLineWidth: 5, 20 | tickLineWidth: 5, 21 | labelSpacing: 5, 22 | tickLength: 10, 23 | startPos: [850, 500], 24 | endPos: [450, 100], 25 | tickDirection: 'negative', 26 | labelDirection: 'positive', 27 | labelAlign: 'perpendicular', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | -------------------------------------------------------------------------------- /__tests__/integration/components/bugs/axis-label-wrap.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Axis } from '../../../../src/ui/axis'; 3 | import { mockData } from '../../utils/mock-data'; 4 | 5 | export const BugAxisLabelWrap = () => { 6 | const group = new Group({ 7 | style: { width: 1000, height: 300 }, 8 | }); 9 | 10 | group.appendChild( 11 | new Axis({ 12 | style: { 13 | data: mockData, 14 | labelOverlap: [ 15 | { 16 | type: 'wrap', 17 | wordWrapWidth: 30, 18 | maxLines: 2, 19 | recoverWhenFailed: false, 20 | }, 21 | ], 22 | startPos: [50, 50], 23 | endPos: [900, 50], 24 | lineLineWidth: 2, 25 | lineStroke: 'black', 26 | tickLineWidth: 2, 27 | tickStroke: 'black', 28 | labelSpacing: 10, 29 | type: 'linear', 30 | }, 31 | }) 32 | ); 33 | 34 | return group; 35 | }; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/bugs/category-give-shape-3.ts: -------------------------------------------------------------------------------- 1 | import { Group, Rect } from '@antv/g'; 2 | import { Category } from '../../../../src/ui/legend'; 3 | 4 | export const BugCategoryWithShape3 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Category({ 9 | style: { 10 | x: 50, 11 | y: 50, 12 | width: 300, 13 | height: 300, 14 | gridRow: undefined, 15 | gridCol: 1, 16 | itemMarkerFill: '#d3d2d3', 17 | data: [ 18 | { label: 'Under 5 Years' }, 19 | { label: '5 to 13 Years' }, 20 | { label: '14 to 17 Years' }, 21 | { label: '18 to 24 Years' }, 22 | { label: '25 to 44 Years' }, 23 | { label: '25 to 44 Years' }, 24 | { label: '45 to 64 Years' }, 25 | { label: '65 Years and Over' }, 26 | ], 27 | }, 28 | }) 29 | ); 30 | 31 | return group; 32 | }; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/bugs/category-item-update-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { CategoryItem } from '../../../../src/ui/legend/category/item'; 3 | import { timeout } from '../../utils'; 4 | 5 | export const BugCategoryItemUpdate1 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 100, 9 | height: 20, 10 | }, 11 | }); 12 | 13 | const item = group.appendChild( 14 | new CategoryItem({ 15 | style: { 16 | labelText: 'label', 17 | valueText: 'value', 18 | spacing: [5, 5], 19 | markerFill: 'green', 20 | labelFill: 'green', 21 | valueFill: 'green', 22 | backgroundFill: '#f7f7f7', 23 | }, 24 | }) 25 | ); 26 | 27 | timeout(() => { 28 | // 期望变成红色 29 | item.update({ markerFill: 'red', labelFill: 'red', valueFill: 'red' }); 30 | }, 1000); 31 | 32 | return group; 33 | }; 34 | 35 | BugCategoryItemUpdate1.tags = ['BUG', '不更新']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/bugs/category-update-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Category } from '../../../../src/ui/legend'; 3 | import { timeout } from '../../utils'; 4 | import { flowItemData, colors } from '../legend/data'; 5 | 6 | export const BugCategoryUpdate1 = () => { 7 | const group = new Group(); 8 | 9 | const category = group.appendChild( 10 | new Category({ 11 | className: 'category-legend', 12 | style: { 13 | data: flowItemData, 14 | y: 30, 15 | layout: 'flex', 16 | width: 400, 17 | height: 100, 18 | gridRow: 2, 19 | itemLabelFill: 'green', 20 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 21 | }, 22 | }) 23 | ); 24 | 25 | timeout(() => { 26 | // 期望变成红色 27 | category.update({ itemLabelFill: 'red' }); 28 | }, 1000); 29 | 30 | return group; 31 | }; 32 | 33 | BugCategoryUpdate1.tags = ['BUG', '更新样式']; 34 | -------------------------------------------------------------------------------- /__tests__/integration/components/button/button-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Button } from '../../../../src'; 3 | 4 | export function Button1() { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Button({ 9 | style: { 10 | x: 100, 11 | y: 100, 12 | text: 'Hello', 13 | }, 14 | }) 15 | ); 16 | 17 | return group; 18 | } 19 | -------------------------------------------------------------------------------- /__tests__/integration/components/button/index.ts: -------------------------------------------------------------------------------- 1 | export * from './button-1'; 2 | -------------------------------------------------------------------------------- /__tests__/integration/components/checkbox/checkbox1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Checkbox } from '../../../../src'; 3 | 4 | export function Checkbox1() { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Checkbox({ 9 | style: { 10 | transform: 'translate(10, 10)', 11 | labelText: 'Checkbox', 12 | }, 13 | }) 14 | ); 15 | 16 | const ck = group.appendChild( 17 | new Checkbox({ 18 | style: { 19 | transform: 'translate(10, 30)', 20 | labelText: 'Checkbox', 21 | checked: true, 22 | }, 23 | }) 24 | ); 25 | 26 | ck.addEventListener('click', () => { 27 | ck.update({ 28 | checked: !ck.attr('checked'), 29 | }); 30 | }); 31 | 32 | return group; 33 | } 34 | -------------------------------------------------------------------------------- /__tests__/integration/components/checkbox/index.ts: -------------------------------------------------------------------------------- 1 | export * from './checkbox1'; 2 | -------------------------------------------------------------------------------- /__tests__/integration/components/crosshair/circle.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { CircleCrosshair } from '../../../../src/ui/crosshair'; 3 | import { createGrid } from '../../utils/grid'; 4 | 5 | export const CrosshairCircle = () => { 6 | const group = new Group({}); 7 | createGrid(group); 8 | const circle = group.appendChild( 9 | new CircleCrosshair({ 10 | style: { 11 | center: [200, 200], 12 | defaultRadius: 50, 13 | }, 14 | }) 15 | ); 16 | group.addEventListener('mousemove', (e: MouseEvent) => { 17 | circle.setPointer([e.offsetX, e.offsetY]); 18 | }); 19 | return group; 20 | }; 21 | -------------------------------------------------------------------------------- /__tests__/integration/components/crosshair/index.ts: -------------------------------------------------------------------------------- 1 | export * from './line'; 2 | export * from './circle'; 3 | export * from './polygon'; 4 | -------------------------------------------------------------------------------- /__tests__/integration/components/crosshair/line.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { LineCrosshair } from '../../../../src/ui/crosshair'; 3 | import { createGrid } from '../../utils/grid'; 4 | 5 | export const CrosshairLine = () => { 6 | const group = new Group({}); 7 | createGrid(group); 8 | const line = group.appendChild( 9 | new LineCrosshair({ 10 | style: { 11 | startPos: [50, 50], 12 | endPos: [50, 400], 13 | tagText: 'tag', 14 | }, 15 | }) 16 | ); 17 | group.addEventListener('mousemove', (e: MouseEvent) => { 18 | line.setPointer([e.offsetX, e.offsetY]); 19 | }); 20 | return group; 21 | }; 22 | -------------------------------------------------------------------------------- /__tests__/integration/components/crosshair/polygon.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { PolygonCrosshair } from '../../../../src/ui/crosshair'; 3 | import { createGrid } from '../../utils/grid'; 4 | 5 | export const CrosshairPolygon = () => { 6 | const group = new Group(); 7 | createGrid(group); 8 | const polygon = group.appendChild( 9 | new PolygonCrosshair({ 10 | style: { 11 | center: [200, 200], 12 | sides: 8, 13 | defaultRadius: 50, 14 | }, 15 | }) 16 | ); 17 | group.addEventListener('mousemove', (e: MouseEvent) => { 18 | polygon.setPointer([e.offsetX, e.offsetY]); 19 | }); 20 | return group; 21 | }; 22 | -------------------------------------------------------------------------------- /__tests__/integration/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './axis'; 2 | export * from './legend'; 3 | export * from './navigator'; 4 | export * from './title'; 5 | export * from './indicator'; 6 | export * from './crosshair'; 7 | export * from './bugs'; 8 | export * from './slider'; 9 | export * from './sparkline'; 10 | export * from './scrollbar'; 11 | export * from './tooltip'; 12 | export * from './layout'; 13 | export * from './button'; 14 | export * from './checkbox'; 15 | export * from './switch'; 16 | export * from './marker'; 17 | export * from './text'; 18 | export * from './timebar'; 19 | export * from './select'; 20 | export * from './tag'; 21 | -------------------------------------------------------------------------------- /__tests__/integration/components/indicator/index.ts: -------------------------------------------------------------------------------- 1 | export { IndicatorDemo } from './indicator'; 2 | export { IndicatorRadius } from './indicator-radius'; 3 | -------------------------------------------------------------------------------- /__tests__/integration/components/layout/layout-flex-position-bottom-left.ts: -------------------------------------------------------------------------------- 1 | import { Group, Rect } from '@antv/g'; 2 | import { Layout } from '../../../../src/ui/layout'; 3 | import { createGrid } from '../../utils'; 4 | 5 | export const LayoutFlexPositionBottomLeft = () => { 6 | const group = new Group(); 7 | 8 | createGrid(group, 100); 9 | 10 | const box = group.appendChild( 11 | new Layout({ 12 | style: { 13 | width: 100, 14 | height: 100, 15 | display: 'flex', 16 | justifyContent: 'flex-start', 17 | alignItems: 'flex-end', 18 | }, 19 | }) 20 | ); 21 | 22 | box.appendChild( 23 | new Rect({ 24 | style: { 25 | width: 10, 26 | height: 10, 27 | fill: 'red', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | LayoutFlexPositionBottomLeft.tags = ['布局', 'Position', 'BottomLeft']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/layout/layout-flex-position-bottom-right.ts: -------------------------------------------------------------------------------- 1 | import { Group, Rect } from '@antv/g'; 2 | import { Layout } from '../../../../src/ui/layout'; 3 | import { createGrid } from '../../utils'; 4 | 5 | export const LayoutFlexPositionBottomRight = () => { 6 | const group = new Group(); 7 | 8 | createGrid(group, 100); 9 | 10 | const box = group.appendChild( 11 | new Layout({ 12 | style: { 13 | width: 100, 14 | height: 100, 15 | display: 'flex', 16 | justifyContent: 'flex-end', 17 | alignItems: 'flex-end', 18 | }, 19 | }) 20 | ); 21 | 22 | box.appendChild( 23 | new Rect({ 24 | style: { 25 | width: 10, 26 | height: 10, 27 | fill: 'red', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | LayoutFlexPositionBottomRight.tags = ['布局', 'Position', 'BottomRight']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/layout/layout-flex-position-bottom.ts: -------------------------------------------------------------------------------- 1 | import { Group, Rect } from '@antv/g'; 2 | import { Layout } from '../../../../src/ui/layout'; 3 | import { createGrid } from '../../utils'; 4 | 5 | export const LayoutFlexPositionBottom = () => { 6 | const group = new Group(); 7 | 8 | createGrid(group, 100); 9 | 10 | const box = group.appendChild( 11 | new Layout({ 12 | style: { 13 | width: 100, 14 | height: 100, 15 | display: 'flex', 16 | justifyContent: 'center', 17 | alignItems: 'flex-end', 18 | }, 19 | }) 20 | ); 21 | 22 | box.appendChild( 23 | new Rect({ 24 | style: { 25 | width: 10, 26 | height: 10, 27 | fill: 'red', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | LayoutFlexPositionBottom.tags = ['布局', 'Position', 'Bottom']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/layout/layout-flex-position-center.ts: -------------------------------------------------------------------------------- 1 | import { Group, Rect } from '@antv/g'; 2 | import { Layout } from '../../../../src/ui/layout'; 3 | import { createGrid } from '../../utils'; 4 | 5 | export const LayoutFlexPositionCenter = () => { 6 | const group = new Group(); 7 | 8 | createGrid(group, 100); 9 | 10 | const box = group.appendChild( 11 | new Layout({ 12 | style: { 13 | width: 100, 14 | height: 100, 15 | display: 'flex', 16 | justifyContent: 'center', 17 | alignItems: 'center', 18 | }, 19 | }) 20 | ); 21 | 22 | box.appendChild( 23 | new Rect({ 24 | style: { 25 | width: 10, 26 | height: 10, 27 | fill: 'red', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | LayoutFlexPositionCenter.tags = ['布局', 'Position', 'Center']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/layout/layout-flex-position-left.ts: -------------------------------------------------------------------------------- 1 | import { Group, Rect } from '@antv/g'; 2 | import { Layout } from '../../../../src/ui/layout'; 3 | import { createGrid } from '../../utils'; 4 | 5 | export const LayoutFlexPositionLeft = () => { 6 | const group = new Group(); 7 | 8 | createGrid(group, 100); 9 | 10 | const box = group.appendChild( 11 | new Layout({ 12 | style: { 13 | width: 100, 14 | height: 100, 15 | display: 'flex', 16 | justifyContent: 'flex-start', 17 | alignItems: 'center', 18 | }, 19 | }) 20 | ); 21 | 22 | box.appendChild( 23 | new Rect({ 24 | style: { 25 | width: 10, 26 | height: 10, 27 | fill: 'red', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | LayoutFlexPositionLeft.tags = ['布局', 'Position', 'Left']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/layout/layout-flex-position-right.ts: -------------------------------------------------------------------------------- 1 | import { Group, Rect } from '@antv/g'; 2 | import { Layout } from '../../../../src/ui/layout'; 3 | import { createGrid } from '../../utils'; 4 | 5 | export const LayoutFlexPositionRight = () => { 6 | const group = new Group(); 7 | 8 | createGrid(group, 100); 9 | 10 | const box = group.appendChild( 11 | new Layout({ 12 | style: { 13 | width: 100, 14 | height: 100, 15 | display: 'flex', 16 | justifyContent: 'flex-end', 17 | alignItems: 'center', 18 | }, 19 | }) 20 | ); 21 | 22 | box.appendChild( 23 | new Rect({ 24 | style: { 25 | width: 10, 26 | height: 10, 27 | fill: 'red', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | LayoutFlexPositionRight.tags = ['布局', 'Position', 'Right']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/layout/layout-flex-position-top-left.ts: -------------------------------------------------------------------------------- 1 | import { Group, Rect } from '@antv/g'; 2 | import { Layout } from '../../../../src/ui/layout'; 3 | import { createGrid } from '../../utils'; 4 | 5 | export const LayoutFlexPositionTopLeft = () => { 6 | const group = new Group(); 7 | 8 | createGrid(group, 100); 9 | 10 | const box = group.appendChild( 11 | new Layout({ 12 | style: { 13 | width: 100, 14 | height: 100, 15 | display: 'flex', 16 | justifyContent: 'flex-start', 17 | alignItems: 'flex-start', 18 | }, 19 | }) 20 | ); 21 | 22 | box.appendChild( 23 | new Rect({ 24 | style: { 25 | width: 10, 26 | height: 10, 27 | fill: 'red', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | LayoutFlexPositionTopLeft.tags = ['布局', 'Position', 'TopLeft']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/layout/layout-flex-position-top-right.ts: -------------------------------------------------------------------------------- 1 | import { Group, Rect } from '@antv/g'; 2 | import { Layout } from '../../../../src/ui/layout'; 3 | import { createGrid } from '../../utils'; 4 | 5 | export const LayoutFlexPositionTopRight = () => { 6 | const group = new Group(); 7 | 8 | createGrid(group, 100); 9 | 10 | const box = group.appendChild( 11 | new Layout({ 12 | style: { 13 | width: 100, 14 | height: 100, 15 | display: 'flex', 16 | justifyContent: 'flex-end', 17 | alignItems: 'flex-start', 18 | }, 19 | }) 20 | ); 21 | 22 | box.appendChild( 23 | new Rect({ 24 | style: { 25 | width: 10, 26 | height: 10, 27 | fill: 'red', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | LayoutFlexPositionTopRight.tags = ['布局', 'Position', 'TopRight']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/layout/layout-flex-position-top.ts: -------------------------------------------------------------------------------- 1 | import { Group, Rect } from '@antv/g'; 2 | import { Layout } from '../../../../src/ui/layout'; 3 | import { createGrid } from '../../utils'; 4 | 5 | export const LayoutFlexPositionTop = () => { 6 | const group = new Group(); 7 | 8 | createGrid(group, 100); 9 | 10 | const box = group.appendChild( 11 | new Layout({ 12 | style: { 13 | width: 100, 14 | height: 100, 15 | display: 'flex', 16 | justifyContent: 'center', 17 | alignItems: 'flex-start', 18 | }, 19 | }) 20 | ); 21 | 22 | box.appendChild( 23 | new Rect({ 24 | style: { 25 | width: 10, 26 | height: 10, 27 | fill: 'red', 28 | }, 29 | }) 30 | ); 31 | 32 | return group; 33 | }; 34 | 35 | LayoutFlexPositionTop.tags = ['布局', 'Position', 'Top']; 36 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-item-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { CategoryItem } from './utils'; 3 | 4 | export const CategoryItem1 = () => { 5 | const group = new Group({ 6 | style: { 7 | width: 200, 8 | height: 20, 9 | }, 10 | }); 11 | 12 | group.appendChild( 13 | new CategoryItem({ 14 | style: { 15 | labelText: 'pre-colonial Americas1', 16 | valueText: '100%', 17 | labelFill: 'red', 18 | valueFill: 'green', 19 | markerFill: 'red', 20 | spacing: [5, 5], 21 | backgroundFill: '#f7f7f7', 22 | }, 23 | }) 24 | ); 25 | 26 | return group; 27 | }; 28 | 29 | CategoryItem1.tags = ['分类图例', '图例项', '样式自定义', '宽度自适应']; 30 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-item-2.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { CategoryItem } from './utils'; 3 | 4 | export const CategoryItem2 = () => { 5 | const group = new Group({ 6 | style: { 7 | width: 100, 8 | height: 20, 9 | }, 10 | }); 11 | 12 | group.appendChild( 13 | new CategoryItem({ 14 | style: { 15 | labelText: 'label', 16 | valueText: 'value', 17 | width: 80, 18 | markerFill: 'red', 19 | labelFill: 'red', 20 | valueFill: 'green', 21 | backgroundFill: '#f7f7f7', 22 | }, 23 | }) 24 | ); 25 | 26 | return group; 27 | }; 28 | 29 | CategoryItem2.tags = ['分类图例', '图例项', '固定宽度', '80px']; 30 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-item-3.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { CategoryItem } from './utils'; 3 | 4 | export const CategoryItem3 = () => { 5 | const group = new Group({ 6 | style: { 7 | width: 100, 8 | height: 20, 9 | }, 10 | }); 11 | 12 | group.appendChild( 13 | new CategoryItem({ 14 | style: { 15 | labelText: 'label', 16 | valueText: 'value', 17 | spacing: [5, 5], 18 | markerFill: 'red', 19 | labelFill: 'red', 20 | valueFill: 'green', 21 | backgroundFill: '#f7f7f7', 22 | }, 23 | }) 24 | ); 25 | 26 | return group; 27 | }; 28 | 29 | CategoryItem3.tags = ['分类图例', '图例项', '自适应宽度', '设置间隔']; 30 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-item-4.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { CategoryItem } from './utils'; 3 | 4 | export const CategoryItem4 = () => { 5 | const group = new Group({ 6 | style: { 7 | width: 100, 8 | height: 20, 9 | }, 10 | }); 11 | 12 | group.appendChild( 13 | new CategoryItem({ 14 | style: { 15 | labelText: 'label', 16 | spacing: [5, 5], 17 | markerFill: 'red', 18 | labelFill: 'red', 19 | valueFill: 'green', 20 | backgroundFill: '#f7f7f7', 21 | }, 22 | }) 23 | ); 24 | 25 | return group; 26 | }; 27 | 28 | CategoryItem4.tags = ['分类图例', '图例项', '自适应宽度', '无value']; 29 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-item-6.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { CategoryItem } from './utils'; 3 | 4 | export const CategoryItem6 = () => { 5 | const group = new Group({ 6 | style: { 7 | width: 100, 8 | height: 20, 9 | }, 10 | }); 11 | 12 | group.appendChild( 13 | new CategoryItem({ 14 | style: { 15 | labelText: 'this is a long label text', 16 | width: 50, 17 | spacing: [5, 5], 18 | markerFill: 'orange', 19 | labelFill: 'red', 20 | valueFill: 'green', 21 | backgroundFill: '#f7f7f7', 22 | }, 23 | }) 24 | ); 25 | 26 | return group; 27 | }; 28 | 29 | CategoryItem6.tags = ['分类图例', '图例项', '标签缩略']; 30 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-item-7.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { CategoryItem } from './utils'; 3 | 4 | export const CategoryItem7 = () => { 5 | const group = new Group({ 6 | style: { 7 | width: 100, 8 | height: 20, 9 | }, 10 | }); 11 | 12 | group.appendChild( 13 | new CategoryItem({ 14 | style: { 15 | labelText: 'this is a long label text', 16 | valueText: 'this is a long value text', 17 | width: 100, 18 | spacing: [5, 5], 19 | markerFill: 'orange', 20 | labelFill: 'red', 21 | valueFill: 'green', 22 | backgroundFill: '#f7f7f7', 23 | }, 24 | }) 25 | ); 26 | 27 | return group; 28 | }; 29 | 30 | CategoryItem7.tags = ['分类图例', '图例项', '标签缩略', '值缩略']; 31 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-item-8.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { CategoryItem } from './utils'; 3 | 4 | export const CategoryItem8 = () => { 5 | const group = new Group({ 6 | style: { 7 | width: 100, 8 | height: 20, 9 | }, 10 | }); 11 | 12 | group.appendChild( 13 | new CategoryItem({ 14 | style: { 15 | labelText: 'this is a long label text', 16 | valueText: 'this is a long value text', 17 | width: 100, 18 | spacing: [5, 5], 19 | span: [1, 2], 20 | markerFill: 'orange', 21 | labelFill: 'red', 22 | valueFill: 'green', 23 | backgroundFill: '#f7f7f7', 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | CategoryItem8.tags = ['分类图例', '图例项', '比例划分', 'span 1:2']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-item-9.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { CategoryItem } from './utils'; 3 | 4 | export const CategoryItem9 = () => { 5 | const group = new Group({ 6 | style: { 7 | width: 200, 8 | height: 50, 9 | }, 10 | }); 11 | 12 | group.appendChild( 13 | new CategoryItem({ 14 | style: { 15 | labelText: 'this is a long label text', 16 | width: 200, 17 | spacing: [5, 5], 18 | markerFill: 'orange', 19 | markerStroke: 'green', 20 | markerStrokeWidth: 2, 21 | markerStrokeOpacity: 0.5, 22 | markerSize: 50, 23 | labelFill: 'red', 24 | backgroundFill: 'pink', 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | CategoryItem9.tags = ['分类图例', '图例项', '描边样式']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-items-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { CategoryItems, createItemData } from './utils'; 3 | 4 | export const CategoryItems1 = () => { 5 | const group = new Group(); 6 | 7 | const colors = ['red', 'orange', 'green', 'blue', 'purple']; 8 | const width = 355; 9 | const height = 90; 10 | const gridRow = 3; 11 | const gridCol = 3; 12 | 13 | group.appendChild( 14 | new CategoryItems({ 15 | style: { 16 | data: createItemData(20), 17 | width, 18 | height, 19 | gridRow, 20 | gridCol, 21 | layout: 'grid', 22 | itemLabelFill: 'red', 23 | itemValueFill: 'green', 24 | colPadding: 10, 25 | rowPadding: 5, 26 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 27 | }, 28 | }) 29 | ); 30 | 31 | return group; 32 | }; 33 | 34 | CategoryItems1.tags = ['分类图例', '图例组', '网格布局', '横向分页', '图标样式回调']; 35 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-items-5.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { CategoryItems, createItemData } from './utils'; 3 | 4 | export const CategoryItems5 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new CategoryItems({ 9 | style: { 10 | width: 555, 11 | height: 50, 12 | layout: 'grid', 13 | orientation: 'horizontal', 14 | gridRow: 2, 15 | gridCol: 8, 16 | itemMarkerFill: '#d3d2d3', 17 | data: createItemData(20).map(({ value, ...rest }) => ({ ...rest })), 18 | }, 19 | }) 20 | ); 21 | 22 | return group; 23 | }; 24 | 25 | CategoryItems5.tags = ['分类图例', '图例组', '网格布局', '无样式', '横向分页']; 26 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-items-6.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { flowItemData } from './data'; 3 | import { CategoryItems } from './utils'; 4 | 5 | export const CategoryItems6 = () => { 6 | const group = new Group(); 7 | 8 | const colors = ['red', 'orange', 'green', 'blue', 'purple']; 9 | 10 | group.appendChild( 11 | new CategoryItems({ 12 | style: { 13 | data: flowItemData, 14 | layout: 'flex', 15 | itemLabelFill: 'red', 16 | itemValueFill: 'green', 17 | width: 1000, 18 | height: 100, 19 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | 27 | CategoryItems6.tags = ['分类图例', '图例组', '流式布局', '单行布局']; 28 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-items-7.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { flowItemData } from './data'; 3 | import { CategoryItems } from './utils'; 4 | 5 | export const CategoryItems7 = () => { 6 | const group = new Group(); 7 | 8 | const colors = ['red', 'orange', 'green', 'blue', 'purple']; 9 | 10 | group.appendChild( 11 | new CategoryItems({ 12 | style: { 13 | data: flowItemData, 14 | layout: 'flex', 15 | itemLabelFill: 'red', 16 | itemValueFill: 'green', 17 | colPadding: 10, 18 | itemSpacing: [0, 10], 19 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | 27 | CategoryItems7.tags = ['分类图例', '图例组', '流式布局', '单行布局', '列间隔', '项目间隔']; 28 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-items-8.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { flowItemData } from './data'; 3 | import { CategoryItems } from './utils'; 4 | 5 | export const CategoryItems8 = () => { 6 | const group = new Group(); 7 | const colors = ['red', 'orange', 'green', 'blue', 'purple']; 8 | 9 | group.appendChild( 10 | new CategoryItems({ 11 | style: { 12 | data: flowItemData, 13 | layout: 'flex', 14 | itemLabelFill: 'red', 15 | itemValueFill: 'green', 16 | colPadding: 10, 17 | gridRow: 2, 18 | gridCol: 5, 19 | width: 650, 20 | height: 50, 21 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 22 | }, 23 | }) 24 | ); 25 | 26 | return group; 27 | }; 28 | 29 | CategoryItems8.tags = ['分类图例', '图例组', '流式布局', '换行']; 30 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-items-9.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { flowItemData } from './data'; 3 | import { CategoryItems } from './utils'; 4 | 5 | export const CategoryItems9 = () => { 6 | const group = new Group(); 7 | 8 | const colors = ['red', 'orange', 'green', 'blue', 'purple']; 9 | 10 | group.appendChild( 11 | new CategoryItems({ 12 | style: { 13 | data: flowItemData.slice(0, 5), 14 | layout: 'flex', 15 | itemLabelFill: 'red', 16 | itemValueFill: 'green', 17 | colPadding: 10, 18 | gridRow: 2, 19 | gridCol: 2, 20 | width: 500, 21 | height: 50, 22 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 23 | }, 24 | }) 25 | ); 26 | 27 | return group; 28 | }; 29 | 30 | CategoryItems9.tags = ['分类图例', '图例组', '流式布局', '换行', '分页']; 31 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout1 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | layout: 'flex', 13 | height: 40, 14 | titleText: 'Legend Title', 15 | width: 1000, 16 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 17 | }, 18 | }) 19 | ); 20 | 21 | return group; 22 | }; 23 | 24 | CategoryLayout1.tags = ['分类图例', '布局', '流式布局', '横向布局']; 25 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-10.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout10 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | y: 30, 13 | layout: 'flex', 14 | width: 400, 15 | height: 100, 16 | gridRow: 2, 17 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 18 | }, 19 | }) 20 | ); 21 | 22 | return group; 23 | }; 24 | 25 | CategoryLayout10.tags = ['分类图例', '图例组', '流式布局', '宽度限制', '换行']; 26 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-11.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout11 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | y: 30, 13 | layout: 'flex', 14 | width: 600, 15 | height: 100, 16 | gridRow: 2, 17 | gridCol: 4, 18 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 19 | }, 20 | }) 21 | ); 22 | 23 | return group; 24 | }; 25 | 26 | CategoryLayout11.tags = ['分类图例', '图例组', '流式布局', '列数限制', '换行']; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-12.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout12 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | y: 30, 13 | layout: 'flex', 14 | width: 500, 15 | height: 100, 16 | gridRow: 1, 17 | gridCol: 4, 18 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 19 | }, 20 | }) 21 | ); 22 | 23 | return group; 24 | }; 25 | 26 | CategoryLayout12.tags = ['分类图例', '图例组', '流式布局', '横向布局', '横向分页']; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-13.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout13 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | y: 30, 13 | layout: 'flex', 14 | orientation: 'vertical', 15 | width: 600, 16 | height: 100, 17 | gridRow: 1, 18 | gridCol: 4, 19 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | 27 | CategoryLayout13.tags = ['分类图例', '图例组', '流式布局', '横向布局', '纵向分页']; 28 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-14.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout14 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | y: 30, 13 | layout: 'flex', 14 | width: 600, 15 | height: 100, 16 | gridRow: 2, 17 | gridCol: 3, 18 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 19 | }, 20 | }) 21 | ); 22 | 23 | return group; 24 | }; 25 | 26 | CategoryLayout14.tags = ['分类图例', '图例组', '流式布局', '横向布局', '纵向分页', '换行']; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-15.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout15 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | y: 30, 13 | layout: 'flex', 14 | width: 200, 15 | height: 300, 16 | gridRow: 10, 17 | gridCol: 1, 18 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 19 | }, 20 | }) 21 | ); 22 | 23 | return group; 24 | }; 25 | 26 | CategoryLayout15.tags = ['分类图例', '图例组', '流式布局', '单列布局']; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-16.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout16 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 230, 9 | height: 330, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Category({ 15 | style: { 16 | data: flowItemData, 17 | y: 30, 18 | layout: 'flex', 19 | width: 200, 20 | height: 300, 21 | gridRow: 5, 22 | gridCol: 1, 23 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | CategoryLayout16.tags = ['分类图例', '图例组', '流式布局', '纵向布局', '横向分页', '行数限制']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-17.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout17 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 210, 9 | height: 110, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Category({ 15 | style: { 16 | data: flowItemData, 17 | y: 30, 18 | layout: 'flex', 19 | orientation: 'vertical', 20 | width: 200, 21 | height: 80, 22 | gridRow: 10, 23 | gridCol: 1, 24 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 25 | }, 26 | }) 27 | ); 28 | 29 | return group; 30 | }; 31 | 32 | CategoryLayout17.tags = ['分类图例', '图例组', '流式布局', '纵向布局', '纵向分页', '行高限制']; 33 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-18.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout18 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | y: 30, 13 | layout: 'flex', 14 | orientation: 'vertical', 15 | width: 400, 16 | height: 300, 17 | gridRow: 3, 18 | gridCol: 2, 19 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | 27 | CategoryLayout18.tags = ['分类图例', '图例组', '流式布局', '纵向分页', '分页']; 28 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-19.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout19 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | y: 30, 13 | layout: 'grid', 14 | orientation: 'vertical', 15 | width: 500, 16 | height: 30, 17 | gridRow: 1, 18 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 19 | }, 20 | }) 21 | ); 22 | 23 | return group; 24 | }; 25 | 26 | CategoryLayout19.tags = ['分类图例', '图例组', '网格布局', '横向布局']; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-2.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { flowItemData, colors } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout2 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | layout: 'flex', 13 | height: 40, 14 | titleText: 'Legend Title', 15 | width: 600, 16 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 17 | }, 18 | }) 19 | ); 20 | 21 | return group; 22 | }; 23 | 24 | CategoryLayout2.tags = ['分类图例', '布局', '流式布局', '横向布局', '分页']; 25 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-20.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout20 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | y: 30, 13 | layout: 'grid', 14 | orientation: 'vertical', 15 | width: 300, 16 | height: 60, 17 | gridRow: 2, 18 | gridCol: 4, 19 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | 27 | CategoryLayout20.tags = ['分类图例', '图例组', '网格布局', '换行', '缩略', '列数限制']; 28 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-21.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout21 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | y: 30, 13 | layout: 'grid', 14 | width: 300, 15 | height: 60, 16 | gridRow: 2, 17 | gridCol: 3, 18 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 19 | }, 20 | }) 21 | ); 22 | 23 | return group; 24 | }; 25 | 26 | CategoryLayout21.tags = ['分类图例', '图例组', '网格布局', '换行', '缩略', '行数限制']; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-22.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout22 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | y: 30, 13 | layout: 'grid', 14 | orientation: 'vertical', 15 | width: 200, 16 | height: 200, 17 | gridRow: 10, 18 | gridCol: 1, 19 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | 27 | CategoryLayout22.tags = ['分类图例', '图例组', '网格布局', '单列布局']; 28 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-23.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout23 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: new Array(20).fill(0).map((_, index) => ({ 12 | label: flowItemData[index % flowItemData.length].label, 13 | })), 14 | y: 30, 15 | layout: 'grid', 16 | width: 500, 17 | height: 100, 18 | gridCol: 5, 19 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | 27 | CategoryLayout23.tags = ['分类图例', '图例组', '网格布局', '单列布局', '横向堆叠', 'BUG']; 28 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-24.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout24 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | y: 30, 13 | layout: 'grid', 14 | orientation: 'vertical', 15 | width: 300, 16 | height: 80, 17 | gridRow: 4, 18 | gridCol: 2, 19 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | 27 | CategoryLayout24.tags = ['分类图例', '图例组', '网格布局', '换列', '多列']; 28 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-25.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout25 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | y: 30, 13 | layout: 'grid', 14 | orientation: 'vertical', 15 | width: 300, 16 | height: 80, 17 | gridRow: 3, 18 | gridCol: 2, 19 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | 27 | CategoryLayout25.tags = ['分类图例', '图例组', '网格布局', '换列', '分页']; 28 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-26.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { flowItemData, colors } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout26 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | layout: 'flex', 13 | width: 500, 14 | height: 100, 15 | gridRow: 2, 16 | gridCol: 4, 17 | // itemSpan: [1, 10, 0], 18 | orientation: 'vertical', 19 | titleText: 'Legend Title', 20 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 21 | }, 22 | }) 23 | ); 24 | 25 | return group; 26 | }; 27 | 28 | CategoryLayout26.tags = ['分类图例', '流式布局', '单行布局']; 29 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-27.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { flowItemData, colors } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout27 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | layout: 'flex', 13 | gridRow: 2, 14 | gridCol: undefined, 15 | height: 100, 16 | width: 300, 17 | titleText: 'Legend Title', 18 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 19 | }, 20 | }) 21 | ); 22 | 23 | return group; 24 | }; 25 | 26 | CategoryLayout27.tags = ['分类图例', '流式布局', '列数无限制']; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-28.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { flowItemData, colors } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout28 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | layout: 'flex', 13 | gridRow: 2, 14 | gridCol: 4, 15 | height: 100, 16 | width: 500, 17 | titleText: 'Legend Title', 18 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 19 | }, 20 | }) 21 | ); 22 | 23 | return group; 24 | }; 25 | 26 | CategoryLayout28.tags = ['分类图例', '流式布局', '列数限制']; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-29.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { flowItemData, colors } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout29 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | layout: 'flex', 13 | width: 200, 14 | height: 300, 15 | gridRow: 10, 16 | gridCol: 1, 17 | titleText: 'Legend Title', 18 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 19 | }, 20 | }) 21 | ); 22 | 23 | return group; 24 | }; 25 | 26 | CategoryLayout29.tags = ['分类图例', '流式布局', '单列布局']; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-30.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { flowItemData, colors } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout30 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 230, 9 | height: 300, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Category({ 15 | style: { 16 | data: flowItemData, 17 | layout: 'flex', 18 | width: 200, 19 | height: 300, 20 | gridRow: 5, 21 | gridCol: 1, 22 | titleText: 'Legend Title', 23 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | CategoryLayout30.tags = ['分类图例', '流式布局', '单列布局', '分页', '行数不足']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-31.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { flowItemData, colors } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout31 = () => { 6 | const group = new Group({ 7 | style: { 8 | width: 200, 9 | height: 110, 10 | }, 11 | }); 12 | 13 | group.appendChild( 14 | new Category({ 15 | style: { 16 | data: flowItemData, 17 | layout: 'flex', 18 | width: 200, 19 | height: 80, 20 | gridRow: 10, 21 | gridCol: 1, 22 | titleText: 'Legend Title', 23 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | CategoryLayout31.tags = ['分类图例', '流式布局', '单列布局', '分页', '高度不足']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-32.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { flowItemData, colors } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout32 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | layout: 'flex', 13 | gridRow: 2, 14 | gridCol: 4, 15 | height: 100, 16 | width: 500, 17 | titleText: 'Legend Title', 18 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 19 | }, 20 | }) 21 | ); 22 | 23 | return group; 24 | }; 25 | 26 | CategoryLayout32.tags = ['分类图例', '流式布局', '单行布局']; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-33.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { flowItemData, colors } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout33 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | layout: 'flex', 13 | gridRow: 2, 14 | gridCol: 4, 15 | height: 100, 16 | width: 500, 17 | titleText: 'Legend Title', 18 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 19 | }, 20 | }) 21 | ); 22 | 23 | return group; 24 | }; 25 | 26 | CategoryLayout33.tags = ['分类图例', '流式布局', '单行布局']; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-4.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Category, createItemData } from './utils'; 3 | import { colors } from './data'; 4 | 5 | export const CategoryLayout4 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: createItemData(20), 12 | layout: 'grid', 13 | titleText: 'Legend Title', 14 | width: 455, 15 | height: 50, 16 | gridCol: 6, 17 | gridRow: 1, 18 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 19 | itemValueText: '', 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | 27 | CategoryLayout4.tags = ['分类图例', '布局', '网格布局', '横向布局', '分页']; 28 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-5.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Category, createItemData } from './utils'; 3 | import { colors } from './data'; 4 | 5 | export const CategoryLayout5 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: createItemData(6), 12 | layout: 'grid', 13 | titleText: 'Legend Title', 14 | width: 455, 15 | height: 50, 16 | gridCol: 6, 17 | gridRow: 1, 18 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 19 | itemValueText: '', 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | 27 | CategoryLayout5.tags = ['分类图例', '布局', '网格布局', '横向布局', '单行布局']; 28 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-6.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Category, createItemData } from './utils'; 3 | import { colors } from './data'; 4 | 5 | export const CategoryLayout6 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: createItemData(20), 12 | layout: 'grid', 13 | titleText: 'Legend Title', 14 | width: 455, 15 | height: 50, 16 | gridCol: 6, 17 | gridRow: 2, 18 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 19 | itemValueText: '', 20 | }, 21 | }) 22 | ); 23 | return group; 24 | }; 25 | 26 | CategoryLayout6.tags = ['分类图例', '布局', '网格布局', '横向布局', '换行', '横向分页']; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-8.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Category, createItemData } from './utils'; 3 | import { colors } from './data'; 4 | 5 | export const CategoryLayout8 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: createItemData(20), 12 | layout: 'grid', 13 | orientation: 'vertical', 14 | width: 120, 15 | height: 128, 16 | navLoop: true, 17 | gridRow: 8, 18 | gridCol: 1, 19 | itemSpacing: 5, 20 | itemMarkerStroke: (_: any, i: number) => colors[i % colors.length], 21 | itemMarkerLineWidth: 3, 22 | itemMarkerFill: 'transparent', 23 | itemValueText: '', 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | CategoryLayout8.tags = ['分类图例', '布局', '网格布局', '自定义图标', '单列布局', '纵向分页']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-layout-9.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { colors, flowItemData } from './data'; 3 | import { Category } from './utils'; 4 | 5 | export const CategoryLayout9 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: flowItemData, 12 | layout: 'flex', 13 | width: 1000, 14 | height: 100, 15 | gridRow: 1, 16 | gridCol: undefined, 17 | itemMarkerFill: (_: any, index: number) => colors[index % colors.length], 18 | }, 19 | }) 20 | ); 21 | 22 | return group; 23 | }; 24 | 25 | CategoryLayout9.tags = ['分类图例', '图例组', '流式布局', '单行布局']; 26 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-marker.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Category, createItemData } from './utils'; 3 | import { colors } from './data'; 4 | 5 | export const CategoryMarker = () => { 6 | const group = new Group(); 7 | 8 | const g1 = group.appendChild(new Group()); 9 | 10 | g1.appendChild( 11 | new Category({ 12 | style: { 13 | data: createItemData(1), 14 | layout: 'grid', 15 | titleText: 'Legend Title', 16 | width: 455, 17 | height: 50, 18 | gridCol: 4, 19 | gridRow: 1, 20 | itemMarker: 'square', 21 | click: () => console.log('click'), 22 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 23 | }, 24 | }) 25 | ); 26 | return group; 27 | }; 28 | 29 | CategoryMarker.tags = ['分类图例', '图例位置', '无偏移']; 30 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-position-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Category, createItemData } from './utils'; 3 | import { colors } from './data'; 4 | 5 | export const CategoryPosition1 = () => { 6 | const group = new Group(); 7 | 8 | const g1 = group.appendChild(new Group()); 9 | 10 | g1.appendChild( 11 | new Category({ 12 | style: { 13 | data: createItemData(20), 14 | layout: 'grid', 15 | titleText: 'Legend Title', 16 | width: 455, 17 | height: 50, 18 | gridCol: 4, 19 | gridRow: 1, 20 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 21 | }, 22 | }) 23 | ); 24 | 25 | return group; 26 | }; 27 | 28 | CategoryPosition1.tags = ['分类图例', '图例位置', '无偏移']; 29 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-position-2.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Category, createItemData } from './utils'; 3 | import { colors } from './data'; 4 | 5 | export const CategoryPosition2 = () => { 6 | const group = new Group(); 7 | 8 | const g = group.appendChild( 9 | new Group({ 10 | style: { 11 | transform: 'translate(50, 50)', 12 | }, 13 | }) 14 | ); 15 | 16 | g.appendChild( 17 | new Category({ 18 | style: { 19 | showTitle: false, 20 | data: createItemData(20), 21 | x: 50, 22 | y: 50, 23 | layout: 'grid', 24 | titleText: 'Legend Title', 25 | width: 455, 26 | height: 50, 27 | gridCol: 4, 28 | gridRow: 1, 29 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 30 | }, 31 | }) 32 | ); 33 | 34 | return group; 35 | }; 36 | 37 | CategoryPosition2.tags = ['分类图例', '图例位置', '嵌套分组', '偏移']; 38 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/category-position-3.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Category, createItemData } from './utils'; 3 | import { colors } from './data'; 4 | 5 | export const CategoryPosition3 = () => { 6 | const group = new Group(); 7 | 8 | group.appendChild( 9 | new Category({ 10 | style: { 11 | data: createItemData(20), 12 | x: 100, 13 | y: 100, 14 | layout: 'grid', 15 | titleText: 'Legend Title', 16 | width: 455, 17 | height: 50, 18 | gridCol: 4, 19 | gridRow: 1, 20 | itemMarkerFill: (_: any, i: number) => colors[i % colors.length], 21 | }, 22 | }) 23 | ); 24 | 25 | return group; 26 | }; 27 | 28 | CategoryPosition3.tags = ['分类图例', '图例位置', '偏移']; 29 | -------------------------------------------------------------------------------- /__tests__/integration/components/legend/utils.ts: -------------------------------------------------------------------------------- 1 | export { Category, Continuous } from '../../../../src/ui/legend'; 2 | export { CategoryItem } from '../../../../src/ui/legend/category/item'; 3 | export { CategoryItems } from '../../../../src/ui/legend/category/items'; 4 | export { smooth } from '../../../../src/ui/marker/symbol'; 5 | 6 | export const createItemData = (num: number) => { 7 | return new Array(num).fill(0).map((d: any, i: number) => ({ 8 | id: `${i + 1}`, 9 | label: `${i + 1}-label`, 10 | value: `${i + 1}-value`, 11 | extInfo: 'further text', 12 | })); 13 | }; 14 | -------------------------------------------------------------------------------- /__tests__/integration/components/marker/index.ts: -------------------------------------------------------------------------------- 1 | export * from './marker-1'; 2 | export * from './marker-update'; 3 | -------------------------------------------------------------------------------- /__tests__/integration/components/marker/marker-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Marker } from '../../../../src'; 3 | 4 | export const Marker1 = () => { 5 | const group = new Group(); 6 | 7 | const markers = Marker.getSymbols(); 8 | 9 | markers.forEach((marker, index) => { 10 | const x = 20 + (index % 10) * 50; 11 | const y = 150 + Math.floor(index / 10) * 50; 12 | group.appendChild( 13 | new Marker({ 14 | style: { 15 | x, 16 | y, 17 | // transform: `translate(${x}, ${y}) rotate(45deg) translate(${-x}, ${-y})`, 18 | // transformOrigin: `0 0`, 19 | transform: 'rotate(45deg)', 20 | transformOrigin: `${x} ${y}`, 21 | symbol: marker, 22 | size: 16, 23 | stroke: 'blue', 24 | lineWidth: 2, 25 | }, 26 | }) 27 | ); 28 | }); 29 | 30 | return group; 31 | }; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/marker/marker-update.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Marker } from '../../../../src'; 3 | 4 | export const MarkerUpdate = () => { 5 | const group = new Group(); 6 | 7 | const marker = group.appendChild( 8 | new Marker({ 9 | style: { 10 | x: 50, 11 | y: 50, 12 | symbol: 'circle', 13 | size: 16, 14 | stroke: 'blue', 15 | lineWidth: 2, 16 | }, 17 | }) 18 | ); 19 | 20 | marker.update({ symbol: 'square' }); 21 | 22 | return group; 23 | }; 24 | -------------------------------------------------------------------------------- /__tests__/integration/components/navigator/index.ts: -------------------------------------------------------------------------------- 1 | export { NavigatorDemo } from './navigator'; 2 | export { NavigatorWithoutShape } from './navigator-without-shape'; 3 | export { NavigatorUpdate } from './navigator-update'; 4 | export { NavigatorSingle } from './navigator-single'; 5 | export { NavigatorNull } from './navigator-null'; 6 | export { NavigatorOverPages } from './navigator-over-pages'; 7 | export { NavigatorStyle } from './navigator-style'; 8 | -------------------------------------------------------------------------------- /__tests__/integration/components/scrollbar/index.ts: -------------------------------------------------------------------------------- 1 | export { Scrollbar1 } from './scrollbar-1'; 2 | export { Scrollbar2 } from './scrollbar-2'; 3 | export { Scrollbar3 } from './scrollbar-3'; 4 | -------------------------------------------------------------------------------- /__tests__/integration/components/scrollbar/scrollbar-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Scrollbar } from '../../../../src/ui/scrollbar'; 3 | 4 | export const Scrollbar1 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Scrollbar({ 9 | style: { x: 20, y: 20, value: 0.5, contentLength: 1000, viewportLength: 300 }, 10 | }) 11 | ); 12 | 13 | return group; 14 | }; 15 | 16 | Scrollbar1.tags = ['滚动条', '默认', '垂直']; 17 | -------------------------------------------------------------------------------- /__tests__/integration/components/scrollbar/scrollbar-2.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Scrollbar } from '../../../../src/ui/scrollbar'; 3 | 4 | export const Scrollbar2 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Scrollbar({ 9 | style: { x: 20, y: 20, value: 0.5, orientation: 'horizontal', contentLength: 1000, viewportLength: 300 }, 10 | }) 11 | ); 12 | 13 | return group; 14 | }; 15 | 16 | Scrollbar2.tags = ['滚动条', '默认', '水平']; 17 | -------------------------------------------------------------------------------- /__tests__/integration/components/scrollbar/scrollbar-3.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Scrollbar } from '../../../../src/ui/scrollbar'; 3 | 4 | export const Scrollbar3 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Scrollbar({ 9 | style: { x: 20, y: 20, value: 0.5, isRound: false, contentLength: 1000, viewportLength: 300 }, 10 | }) 11 | ); 12 | 13 | return group; 14 | }; 15 | 16 | Scrollbar3.tags = ['滚动条', '默认', '直角']; 17 | -------------------------------------------------------------------------------- /__tests__/integration/components/select/index.ts: -------------------------------------------------------------------------------- 1 | export * from './select-basic'; 2 | export * from './select-open'; 3 | export * from './select-default-value'; 4 | export * from './select-invalid-default-value'; 5 | export * from './select-events'; 6 | export * from './select-no-border'; 7 | export * from './select-demo-speed'; 8 | -------------------------------------------------------------------------------- /__tests__/integration/components/select/select-demo-speed.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Select } from '../../../../src/ui/select'; 3 | 4 | export const SelectDemoSpeed = () => { 5 | const group = new Group({ 6 | style: { 7 | width: 50, 8 | height: 100, 9 | }, 10 | }); 11 | 12 | group.appendChild( 13 | new Select({ 14 | style: { 15 | x: 10, 16 | y: 10, 17 | width: 30, 18 | height: 20, 19 | open: true, 20 | defaultValue: 1, 21 | bordered: false, 22 | showDropdownIcon: false, 23 | selectRadius: 2, 24 | dropdownPadding: 2, 25 | dropdownRadius: 2, 26 | optionPadding: 0, 27 | optionBackgroundRadius: 1, 28 | options: [ 29 | { label: '1x', value: 1 }, 30 | { label: '1.5x', value: 1.5 }, 31 | { label: '2x', value: 2 }, 32 | ], 33 | }, 34 | }) 35 | ); 36 | return group; 37 | }; 38 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/handle-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Handle } from '../../../../src/ui/slider/handle'; 3 | 4 | export const Handle1 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Handle({ 9 | style: { 10 | x: 150, 11 | y: 150, 12 | labelText: 'LabelText', 13 | }, 14 | }) 15 | ); 16 | 17 | return group; 18 | }; 19 | 20 | Handle1.tags = ['手柄', '默认', '水平']; 21 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/handle-2.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Handle } from '../../../../src/ui/slider/handle'; 3 | 4 | export const Handle2 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Handle({ 9 | style: { 10 | x: 150, 11 | y: 150, 12 | orientation: 'vertical', 13 | labelText: 'LabelText', 14 | }, 15 | }) 16 | ); 17 | 18 | return group; 19 | }; 20 | 21 | Handle2.tags = ['手柄', '垂直']; 22 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/handle-update.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Handle } from '../../../../src/ui/slider/handle'; 3 | import { timeout } from '../../utils'; 4 | 5 | export const HandleUpdate = () => { 6 | const group = new Group({ style: { width: 200, height: 200 } }); 7 | 8 | const handle = group.appendChild( 9 | new Handle({ 10 | style: { 11 | x: 150, 12 | y: 150, 13 | orientation: 'vertical', 14 | labelText: 'LabelText', 15 | }, 16 | }) 17 | ); 18 | 19 | timeout(() => { 20 | handle.update(); 21 | }, 100); 22 | 23 | return group; 24 | }; 25 | 26 | HandleUpdate.tags = ['手柄', '垂直']; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/index.ts: -------------------------------------------------------------------------------- 1 | export { Slider1 } from './slider-1'; 2 | export { Slider2 } from './slider-2'; 3 | export { Slider3 } from './slider-3'; 4 | export { Slider4 } from './slider-4'; 5 | export { Slider5 } from './slider-5'; 6 | export { Slider6 } from './slider-6'; 7 | export { Slider7 } from './slider-7'; 8 | export { Slider8 } from './slider-8'; 9 | export { Slider9 } from './slider-9'; 10 | export { Slider10 } from './slider-10'; 11 | export { Slider11 } from './slider-11'; 12 | export { Slider12 } from './slider-12'; 13 | export { SliderInvert } from './slider-invert'; 14 | export { Handle1 } from './handle-1'; 15 | export { Handle2 } from './handle-2'; 16 | export { HandleUpdate } from './handle-update'; 17 | export { SliderValueType } from './slider-value-type'; 18 | export { SliderTimebar } from './slider-timebar'; 19 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/slider-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Slider } from '../../../../src/ui/slider'; 3 | 4 | export const Slider1 = () => { 5 | const group = new Group(); 6 | 7 | const slider = group.appendChild( 8 | new Slider({ 9 | style: { 10 | x: 10, 11 | y: 10, 12 | trackLength: 300, 13 | trackSize: 50, 14 | }, 15 | }) 16 | ); 17 | 18 | return group; 19 | }; 20 | 21 | Slider1.tags = ['缩略条', '默认']; 22 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/slider-10.ts: -------------------------------------------------------------------------------- 1 | import { Group, Circle } from '@antv/g'; 2 | import { Slider } from '../../../../src/ui/slider'; 3 | 4 | export const Slider10 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Slider({ 9 | style: { 10 | brushable: false, 11 | handleIconShape: () => new Circle({ style: { r: 5, fill: '#4e76b1' } }), 12 | padding: 2, 13 | selectionRadius: 5, 14 | showHandle: false, 15 | showLabel: false, 16 | trackFill: '#d8e8fb', 17 | trackLength: 300, 18 | trackOpacity: 0.5, 19 | trackRadius: 5, 20 | trackSize: 10, 21 | values: [0.25, 0.75], 22 | x: 10, 23 | y: 10, 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | Slider10.tags = ['缩略条', '迷你图', '滚动条', '水平']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/slider-11.ts: -------------------------------------------------------------------------------- 1 | import { Group, Circle } from '@antv/g'; 2 | import { Slider } from '../../../../src/ui/slider'; 3 | 4 | export const Slider11 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Slider({ 9 | style: { 10 | brushable: false, 11 | orientation: 'vertical', 12 | padding: 2, 13 | selectionRadius: 5, 14 | showHandle: false, 15 | showLabel: false, 16 | trackFill: '#d8e8fb', 17 | trackLength: 300, 18 | trackOpacity: 0.5, 19 | trackRadius: 5, 20 | trackSize: 10, 21 | values: [0.25, 0.75], 22 | x: 10, 23 | y: 10, 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | Slider11.tags = ['缩略条', '迷你图', '滚动条', '垂直']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/slider-2.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Slider } from '../../../../src/ui/slider'; 3 | 4 | export const Slider2 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Slider({ 9 | style: { x: 10, y: 10, trackLength: 300, trackSize: 50, orientation: 'vertical' }, 10 | }) 11 | ); 12 | 13 | return group; 14 | }; 15 | 16 | Slider2.tags = ['缩略条', '垂直']; 17 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/slider-3.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Slider } from '../../../../src/ui/slider'; 3 | 4 | export const Slider3 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Slider({ 9 | style: { 10 | x: 10, 11 | y: 10, 12 | values: [0.25, 0.75], 13 | trackLength: 300, 14 | trackSize: 50, 15 | }, 16 | }) 17 | ); 18 | 19 | return group; 20 | }; 21 | 22 | Slider3.tags = ['缩略条', '初始值']; 23 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/slider-4.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Slider } from '../../../../src/ui/slider'; 3 | 4 | export const Slider4 = () => { 5 | const group = new Group(); 6 | 7 | const slider = group.appendChild( 8 | new Slider({ 9 | style: { 10 | x: 10, 11 | y: 10, 12 | trackLength: 300, 13 | trackSize: 50, 14 | }, 15 | }) 16 | ); 17 | 18 | slider.addEventListener('valuechange', (e: any) => { 19 | console.log('value change', e); 20 | }); 21 | 22 | return group; 23 | }; 24 | 25 | Slider4.tags = ['缩略条', '事件']; 26 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/slider-5.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Slider } from '../../../../src/ui/slider'; 3 | 4 | export const Slider5 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Slider({ 9 | style: { 10 | sparklineIsStack: true, 11 | sparklineSmooth: false, 12 | sparklineType: 'line', 13 | trackLength: 300, 14 | trackSize: 50, 15 | x: 10, 16 | y: 10, 17 | sparklineData: [ 18 | [10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 19 | [5, 7, 10, 3, 10, 6, 10, 1, 5, 0], 20 | [1, 3, 4, 10, 15, 13, 3, 3, 10, 12], 21 | ], 22 | }, 23 | }) 24 | ); 25 | 26 | return group; 27 | }; 28 | 29 | Slider5.tags = ['缩略条', '迷你图']; 30 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/slider-6.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Slider } from '../../../../src/ui/slider'; 3 | 4 | export const Slider6 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Slider({ 9 | style: { 10 | sparklineIsStack: true, 11 | sparklineSmooth: false, 12 | sparklineType: 'line', 13 | trackLength: 300, 14 | trackSize: 50, 15 | x: 10, 16 | y: 10, 17 | sparklineData: [ 18 | [10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 19 | [5, 7, 10, 3, 10, 6, 10, 1, 5, 0], 20 | [1, 3, 4, 10, 15, 13, 3, 3, 10, 12], 21 | ], 22 | formatter: (value: any) => `${value}°C`, 23 | }, 24 | }) 25 | ); 26 | 27 | return group; 28 | }; 29 | 30 | Slider6.tags = ['缩略条', '迷你图', '文本']; 31 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/slider-7.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Slider } from '../../../../src/ui/slider'; 3 | 4 | export const Slider7 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Slider({ 9 | style: { 10 | x: 10, 11 | y: 10, 12 | trackLength: 300, 13 | trackSize: 50, 14 | orientation: 'vertical', 15 | sparklineType: 'line', 16 | sparklineSmooth: false, 17 | sparklineIsStack: true, 18 | sparklineData: [ 19 | [10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 20 | [5, 7, 10, 3, 10, 6, 10, 1, 5, 0], 21 | [1, 3, 4, 10, 15, 13, 3, 3, 10, 12], 22 | ], 23 | formatter: (value: any) => `${value}°C`, 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | Slider7.tags = ['缩略条', '迷你图', '文本']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/slider-8.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Slider } from '../../../../src/ui/slider'; 3 | 4 | export const Slider8 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Slider({ 9 | style: { 10 | showHandle: false, 11 | sparklineData: [ 12 | [10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 13 | [5, 7, 10, 3, 10, 6, 10, 1, 5, 0], 14 | [1, 3, 4, 10, 15, 13, 3, 3, 10, 12], 15 | ], 16 | x: 10, 17 | y: 10, 18 | trackLength: 300, 19 | trackSize: 50, 20 | values: [0, 0], 21 | sparklineType: 'line', 22 | sparklineSmooth: false, 23 | sparklineIsStack: true, 24 | }, 25 | }) 26 | ); 27 | 28 | return group; 29 | }; 30 | 31 | Slider8.tags = ['缩略条', '迷你图', '隐藏手柄']; 32 | -------------------------------------------------------------------------------- /__tests__/integration/components/slider/slider-9.ts: -------------------------------------------------------------------------------- 1 | import { Circle, Group } from '@antv/g'; 2 | import { Slider } from '../../../../src/ui/slider'; 3 | 4 | export const Slider9 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Slider({ 9 | style: { 10 | handleIconShape: () => new Circle({ style: { r: 5, fill: '#4e76b1' } }), 11 | showLabel: false, 12 | trackFill: '#d8e8fb', 13 | trackLength: 300, 14 | trackOpacity: 0.5, 15 | trackRadius: 5, 16 | trackSize: 10, 17 | values: [0.25, 0.75], 18 | x: 10, 19 | y: 10, 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | 27 | Slider9.tags = ['缩略条', '迷你图', '自定义手柄']; 28 | -------------------------------------------------------------------------------- /__tests__/integration/components/sparkline/index.ts: -------------------------------------------------------------------------------- 1 | export { Sparkline1 } from './sparkline-1'; 2 | export { Sparkline2 } from './sparkline-2'; 3 | export { Sparkline3 } from './sparkline-3'; 4 | export { Sparkline4 } from './sparkline-4'; 5 | export { Sparkline5 } from './sparkline-5'; 6 | export { Sparkline6 } from './sparkline-6'; 7 | export { Sparkline7 } from './sparkline-7'; 8 | export { Sparkline8 } from './sparkline-8'; 9 | export { Sparkline9 } from './sparkline-9'; 10 | export { Sparkline10 } from './sparkline-10'; 11 | export { Sparkline11 } from './sparkline-11'; 12 | export { Sparkline12 } from './sparkline-12'; 13 | export { SparklineScaleLine } from './sparkline-scale-line'; 14 | export { SparklineScaleColumn } from './sparkline-scale-column'; 15 | -------------------------------------------------------------------------------- /__tests__/integration/components/sparkline/sparkline-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Sparkline } from '../../../../src/ui/sparkline'; 3 | 4 | export const Sparkline1 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Sparkline({ 9 | style: { 10 | x: 10, 11 | y: 10, 12 | type: 'line', 13 | width: 300, 14 | height: 50, 15 | smooth: false, 16 | data: [ 17 | [10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 18 | [5, 7, 10, 3, 10, 6, 10, 1, 5, 0], 19 | [-10, 3, 4, 10, 15, 13, 3, 3, 10, 12], 20 | ], 21 | }, 22 | }) 23 | ); 24 | 25 | return group; 26 | }; 27 | 28 | Sparkline1.tags = ['迷你图', '折线图']; 29 | -------------------------------------------------------------------------------- /__tests__/integration/components/sparkline/sparkline-10.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Sparkline } from '../../../../src/ui/sparkline'; 3 | 4 | export const Sparkline10 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Sparkline({ 9 | style: { 10 | transform: 'translate(10, 10)', 11 | type: 'column', 12 | width: 300, 13 | height: 50, 14 | isStack: false, 15 | isGroup: true, 16 | data: [ 17 | [-10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 18 | [5, 7, 10, 3, 10, 6, 10, 1, 5, 0], 19 | [1, 3, 4, 10, 15, 13, 3, 3, 10, 12], 20 | ], 21 | }, 22 | }) 23 | ); 24 | 25 | return group; 26 | }; 27 | 28 | Sparkline10.tags = ['迷你图', '条形图图', '分组', 'BUG']; 29 | -------------------------------------------------------------------------------- /__tests__/integration/components/sparkline/sparkline-11.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Sparkline } from '../../../../src/ui/sparkline'; 3 | 4 | export const Sparkline11 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Sparkline({ 9 | style: { 10 | transform: 'translate(10, 10)', 11 | type: 'column', 12 | width: 300, 13 | height: 50, 14 | isStack: true, 15 | isGroup: true, 16 | spacing: 0.1, 17 | data: [ 18 | [10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 19 | [5, 7, 10, 3, 10, 6, 10, 1, 5, 0], 20 | [1, 3, 4, 10, 15, 13, 3, 3, 10, 12], 21 | ], 22 | }, 23 | }) 24 | ); 25 | 26 | return group; 27 | }; 28 | 29 | Sparkline11.tags = ['迷你图', '条形图图', '分组', '堆叠', 'BUG']; 30 | -------------------------------------------------------------------------------- /__tests__/integration/components/sparkline/sparkline-2.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Sparkline } from '../../../../src/ui/sparkline'; 3 | 4 | export const Sparkline2 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Sparkline({ 9 | style: { 10 | transform: 'translate(10, 10)', 11 | type: 'line', 12 | width: 300, 13 | height: 50, 14 | smooth: false, 15 | isStack: true, 16 | data: [ 17 | [10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 18 | [5, 7, 10, 3, 10, 6, 10, 1, 5, 0], 19 | [1, 3, 4, 10, 15, 13, 3, 3, 10, 12], 20 | ], 21 | }, 22 | }) 23 | ); 24 | 25 | return group; 26 | }; 27 | 28 | Sparkline2.tags = ['迷你图', '折线图', '堆叠']; 29 | -------------------------------------------------------------------------------- /__tests__/integration/components/sparkline/sparkline-3.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Sparkline } from '../../../../src/ui/sparkline'; 3 | 4 | export const Sparkline3 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Sparkline({ 9 | style: { 10 | transform: 'translate(10, 10)', 11 | type: 'line', 12 | width: 300, 13 | height: 50, 14 | smooth: true, 15 | isStack: true, 16 | data: [ 17 | [10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 18 | [5, 7, 10, 3, 10, 6, 10, 1, 5, 0], 19 | [1, 3, 4, 10, 15, 13, 3, 3, 10, 12], 20 | ], 21 | }, 22 | }) 23 | ); 24 | 25 | return group; 26 | }; 27 | 28 | Sparkline3.tags = ['迷你图', '折线图', '堆叠', '平滑曲线']; 29 | -------------------------------------------------------------------------------- /__tests__/integration/components/sparkline/sparkline-4.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Sparkline } from '../../../../src/ui/sparkline'; 3 | 4 | export const Sparkline4 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Sparkline({ 9 | style: { 10 | transform: 'translate(10, 10)', 11 | type: 'line', 12 | width: 300, 13 | height: 50, 14 | smooth: false, 15 | areaLineWidth: 0, 16 | areaOpacity: 0.5, 17 | data: [ 18 | [10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 19 | [5, 7, 10, 3, 10, 6, 10, 1, 5, 0], 20 | [1, 3, 4, 10, 15, 13, 3, 3, 10, 12], 21 | ], 22 | }, 23 | }) 24 | ); 25 | 26 | return group; 27 | }; 28 | 29 | Sparkline4.tags = ['迷你图', '折线图', '区域填充']; 30 | -------------------------------------------------------------------------------- /__tests__/integration/components/sparkline/sparkline-5.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Sparkline } from '../../../../src/ui/sparkline'; 3 | 4 | export const Sparkline5 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Sparkline({ 9 | style: { 10 | transform: 'translate(10, 10)', 11 | type: 'line', 12 | width: 300, 13 | height: 50, 14 | smooth: true, 15 | areaLineWidth: 0, 16 | areaOpacity: 0.5, 17 | data: [ 18 | [10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 19 | [5, 7, 10, 3, 10, 6, 10, 1, 5, 0], 20 | [1, 3, 4, 10, 15, 13, 3, 3, 10, 12], 21 | ], 22 | }, 23 | }) 24 | ); 25 | 26 | return group; 27 | }; 28 | 29 | Sparkline5.tags = ['迷你图', '折线图', '区域填充', '平滑曲线']; 30 | -------------------------------------------------------------------------------- /__tests__/integration/components/sparkline/sparkline-6.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Sparkline } from '../../../../src/ui/sparkline'; 3 | 4 | export const Sparkline6 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Sparkline({ 9 | style: { 10 | transform: 'translate(10, 10)', 11 | type: 'line', 12 | width: 300, 13 | height: 50, 14 | smooth: false, 15 | isStack: true, 16 | areaLineWidth: 0, 17 | areaOpacity: 0.5, 18 | data: [ 19 | [10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 20 | [5, 7, 10, 3, 10, 6, 10, 1, 5, 0], 21 | [1, 3, 4, 10, 15, 13, 3, 3, 10, 12], 22 | ], 23 | }, 24 | }) 25 | ); 26 | 27 | return group; 28 | }; 29 | 30 | Sparkline6.tags = ['迷你图', '折线图', '堆叠', '区域填充']; 31 | -------------------------------------------------------------------------------- /__tests__/integration/components/sparkline/sparkline-7.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Sparkline } from '../../../../src/ui/sparkline'; 3 | 4 | export const Sparkline7 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Sparkline({ 9 | style: { 10 | transform: 'translate(10, 10)', 11 | type: 'line', 12 | width: 300, 13 | height: 50, 14 | smooth: true, 15 | isStack: true, 16 | areaLineWidth: 0, 17 | areaOpacity: 0.5, 18 | data: [ 19 | [10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 20 | [5, 7, 10, 3, 10, 6, 10, 1, 5, 0], 21 | [1, 3, 4, 10, 15, 13, 3, 3, 10, 12], 22 | ], 23 | }, 24 | }) 25 | ); 26 | 27 | return group; 28 | }; 29 | 30 | Sparkline7.tags = ['迷你图', '折线图', '堆叠', '区域填充', '平滑曲线']; 31 | -------------------------------------------------------------------------------- /__tests__/integration/components/sparkline/sparkline-8.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Sparkline } from '../../../../src/ui/sparkline'; 3 | 4 | export const Sparkline8 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Sparkline({ 9 | style: { 10 | transform: 'translate(10, 10)', 11 | type: 'column', 12 | width: 300, 13 | height: 50, 14 | data: [ 15 | [10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 16 | [5, 7, 10, 3, 10, 6, 10, 1, 5, 0], 17 | [1, 3, 4, 10, 15, 13, 3, 3, 10, 12], 18 | ], 19 | }, 20 | }) 21 | ); 22 | 23 | return group; 24 | }; 25 | 26 | Sparkline8.tags = ['迷你图', '条形图图', 'BUG']; 27 | -------------------------------------------------------------------------------- /__tests__/integration/components/sparkline/sparkline-9.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Sparkline } from '../../../../src/ui/sparkline'; 3 | 4 | export const Sparkline9 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Sparkline({ 9 | style: { 10 | transform: 'translate(10, 10)', 11 | type: 'column', 12 | width: 300, 13 | height: 50, 14 | isStack: true, 15 | data: [ 16 | [10, 2, 3, 4, 15, 10, 5, 0, 3, 1], 17 | [5, 7, 10, 3, -10, 6, 10, 1, 5, 0], 18 | [1, 3, 4, 10, -15, 13, 3, 3, -10, 12], 19 | ], 20 | }, 21 | }) 22 | ); 23 | 24 | return group; 25 | }; 26 | 27 | Sparkline9.tags = ['迷你图', '条形图图', '堆叠']; 28 | -------------------------------------------------------------------------------- /__tests__/integration/components/switch/index.ts: -------------------------------------------------------------------------------- 1 | export * from './switch-1'; 2 | -------------------------------------------------------------------------------- /__tests__/integration/components/switch/switch-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Switch } from '../../../../src'; 3 | 4 | export const Switch1 = () => { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Switch({ 9 | style: { 10 | checked: false, 11 | }, 12 | }) 13 | ); 14 | 15 | group.appendChild( 16 | new Switch({ 17 | style: { 18 | transform: 'translateY(40)', 19 | checked: true, 20 | }, 21 | }) 22 | ); 23 | 24 | const sw = group.appendChild( 25 | new Switch({ 26 | style: { 27 | transform: 'translateY(80)', 28 | checked: false, 29 | }, 30 | }) 31 | ); 32 | 33 | sw.addEventListener('click', () => { 34 | sw.update({ 35 | checked: !sw.attributes.checked, 36 | }); 37 | }); 38 | 39 | return group; 40 | }; 41 | -------------------------------------------------------------------------------- /__tests__/integration/components/tag/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tag-1'; 2 | -------------------------------------------------------------------------------- /__tests__/integration/components/text/index.ts: -------------------------------------------------------------------------------- 1 | export { Text1 } from './text-1'; 2 | -------------------------------------------------------------------------------- /__tests__/integration/components/text/text-1.ts: -------------------------------------------------------------------------------- 1 | import { Group } from '@antv/g'; 2 | import { Text } from '../../../../src/shapes'; 3 | 4 | export function Text1() { 5 | const group = new Group(); 6 | 7 | group.appendChild( 8 | new Text({ 9 | style: { 10 | x: 100, 11 | y: 100, 12 | text: 'Hello', 13 | }, 14 | }) 15 | ); 16 | 17 | return group; 18 | } 19 | -------------------------------------------------------------------------------- /__tests__/integration/components/timebar/handle.ts: -------------------------------------------------------------------------------- 1 | import { Rect } from '@antv/g'; 2 | import { ChartModeHandle, TimeModeHandle } from '../../../../src/ui/timebar/handle'; 3 | import { it } from '../../utils'; 4 | 5 | export const TimebarHandle = it({ width: 50, height: 80 }, (group) => { 6 | group.appendChild( 7 | new Rect({ 8 | style: { 9 | width: 50, 10 | height: 80, 11 | fill: '#72cdf6', 12 | }, 13 | }) 14 | ); 15 | 16 | group.appendChild(new TimeModeHandle({ style: { cx: 10, cy: 10 } })); 17 | 18 | group.appendChild(new ChartModeHandle({ style: { x: 10, y: 50, type: 'start' } })); 19 | 20 | group.appendChild(new ChartModeHandle({ style: { x: 25, y: 50, type: 'end' } })); 21 | 22 | group.appendChild(new ChartModeHandle({ style: { x: 40, y: 50, type: 'end', iconSize: 20 } })); 23 | 24 | return group; 25 | }); 26 | -------------------------------------------------------------------------------- /__tests__/integration/components/timebar/index.ts: -------------------------------------------------------------------------------- 1 | export * from './icons'; 2 | export * from './handle'; 3 | export * from './controller'; 4 | export * from './timebar-basic'; 5 | export * from './timebar-time'; 6 | export * from './timebar-chart'; 7 | -------------------------------------------------------------------------------- /__tests__/integration/components/title/index.ts: -------------------------------------------------------------------------------- 1 | export * from './title'; 2 | -------------------------------------------------------------------------------- /__tests__/integration/components/tooltip/index.ts: -------------------------------------------------------------------------------- 1 | export { Tooltip1 } from './tooltip-1'; 2 | export { Tooltip2 } from './tooltip-2'; 3 | export { Tooltip3 } from './tooltip-3'; 4 | export { Tooltip4 } from './tooltip-4'; 5 | export { Tooltip5 } from './tooltip-5'; 6 | export { Tooltip6 } from './tooltip-6'; 7 | export { Tooltip7 } from './tooltip-7'; 8 | export { Tooltip8 } from './tooltip-8'; 9 | export { Tooltip9 } from './tooltip-9'; 10 | export { Tooltip10 } from './tooltip-10'; 11 | -------------------------------------------------------------------------------- /__tests__/integration/fetch.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import { promises as fs } from 'fs'; 3 | 4 | function createResponse(url: string) { 5 | return { 6 | ok: true, 7 | status: 200, 8 | async text() { 9 | return fs.readFile(url, { encoding: 'utf-8' }); 10 | }, 11 | async json() { 12 | return JSON.parse(await this.text()); 13 | }, 14 | }; 15 | } 16 | 17 | export async function fetch(url: string) { 18 | return createResponse(path.resolve('__tests__/integration', url)); 19 | } 20 | -------------------------------------------------------------------------------- /__tests__/integration/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Component: Preview 7 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /__tests__/integration/snapshots/Button1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Hello 12 | 13 | 14 | 15 | 16 | 17 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 2 | 3 | 4 | 5 | 6 | Hello 7 | 8 | 9 | 10 | 11 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | { 6 | return (extraParams: any) => { 7 | return group.appendChild( 8 | new Axis( 9 | deepAssign( 10 | { style: { radius: 80, lineLineWidth: 1, tickLength: 10, labelSpacing: 10 } }, 11 | { style: baseParams }, 12 | { style: extraParams } 13 | ) 14 | ) 15 | ); 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /__tests__/integration/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './create-axis'; 2 | export * from './mock-data'; 3 | export * from './grid'; 4 | export * from './color'; 5 | export * from './time'; 6 | export * from './it'; 7 | -------------------------------------------------------------------------------- /__tests__/integration/utils/it.ts: -------------------------------------------------------------------------------- 1 | import { Group, GroupStyleProps } from '@antv/g'; 2 | 3 | type GroupTest = (group: Group) => void; 4 | type GroupTestReturn = { (): Group; [keys: string]: any }; 5 | 6 | export function it(test: GroupTest): GroupTestReturn; 7 | export function it(options: GroupStyleProps, test: GroupTest): GroupTestReturn; 8 | export function it(argv1: GroupTest | GroupStyleProps, argv2?: GroupTest): GroupTestReturn { 9 | return () => { 10 | const group = new Group(); 11 | 12 | if (typeof argv1 === 'object') { 13 | group.attr(argv1); 14 | argv2?.(group); 15 | } else argv1(group); 16 | 17 | return group; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /__tests__/integration/utils/time.ts: -------------------------------------------------------------------------------- 1 | const isTestEnv = () => typeof process !== 'undefined' && process.env?.NODE_ENV === 'test'; 2 | const canSetInterval = () => !isTestEnv() && !(globalThis as any)?.disableInterval; 3 | 4 | export function interval(cb: Function, time?: number, runInTest?: boolean) { 5 | if (isTestEnv() && runInTest) cb(); 6 | else if (canSetInterval()) setInterval(cb, time); 7 | } 8 | 9 | export function timeout(cb: Function, time?: number, runInTest?: boolean) { 10 | if (isTestEnv() && runInTest) cb(); 11 | else if (canSetInterval()) setTimeout(cb, time); 12 | } 13 | -------------------------------------------------------------------------------- /__tests__/performance/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rules: { 3 | 'no-await-in-loop': 'off', 4 | 'no-alert': 'off', 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /__tests__/performance/README.md: -------------------------------------------------------------------------------- 1 | ## Performance Tests 2 | 3 | ### Usage 4 | 5 | 1. Run `npm install` to install the dependencies. 6 | 2. Run `npm start` in the root directory of the project. 7 | 3. Follow the guide at the page that opens automatically. 8 | 4. You can view the history test results at 'http://localhost:8000/report.html' 9 | -------------------------------------------------------------------------------- /__tests__/performance/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "performance", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "NODE_ENV=\"test\" && ts-node server.ts & vite dev && fg" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@antv/g": "^5.15.15", 13 | "@antv/g-canvas": "^1.9.33", 14 | "cors": "^2.8.5", 15 | "express": "^4.18.2", 16 | "vite": "^4.1.4" 17 | }, 18 | "devDependencies": { 19 | "@types/express": "^4.17.17" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /__tests__/performance/report.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Statistic 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /__tests__/performance/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "target": "esnext", 5 | // "module": "ESNext", 6 | "baseUrl": ".", 7 | "forceConsistentCasingInFileNames": true, 8 | "moduleResolution": "node", 9 | "resolveJsonModule": true, 10 | "esModuleInterop": true, 11 | "paths": { 12 | "@antv/component": ["../../src/index.ts"] 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /__tests__/performance/vite.config.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import { defineConfig } from 'vite'; 3 | 4 | export default defineConfig({ 5 | server: { 6 | port: 8000, 7 | open: '/', 8 | }, 9 | resolve: { 10 | alias: [{ find: '@antv/component', replacement: path.resolve('../../src/index.ts') }], 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /__tests__/unit/index-spec.ts: -------------------------------------------------------------------------------- 1 | describe('component', () => { 2 | test('example', () => { 3 | expect(1).toBe(1); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /__tests__/unit/ui/axis/is-point-inside-rectangle.spec.ts: -------------------------------------------------------------------------------- 1 | import { isPointInsideRectangle } from '../../../../src/ui/axis/utils/contain'; 2 | 3 | describe('isPointInsideRectangle', () => { 4 | const bbox1: any = [ 5 | [0, 0], 6 | [100, 0], 7 | [100, 100], 8 | [0, 100], 9 | ]; 10 | 11 | const bbox2: any = [ 12 | [50, 50], 13 | [150, 50], 14 | [150, 150], 15 | [50, 150], 16 | ]; 17 | 18 | test('isPointInsideRectangle', async () => { 19 | expect(isPointInsideRectangle(bbox1, [50, 50])).toBe(true); 20 | expect(isPointInsideRectangle(bbox1, [-1, -1])).toBe(false); 21 | expect(isPointInsideRectangle(bbox2, [100, 100])).toBe(true); 22 | expect(isPointInsideRectangle(bbox2, [49, 49])).toBe(false); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /__tests__/unit/ui/marker/parse-marker-spec.ts: -------------------------------------------------------------------------------- 1 | import { parseMarker } from '../../../../src/ui/marker/utils'; 2 | 3 | describe('parseMarker', () => { 4 | test('symbol', async () => { 5 | expect(parseMarker('square')).toBe('symbol'); 6 | expect( 7 | parseMarker((x, y, r) => { 8 | return []; 9 | }) 10 | ).toBe('symbol'); 11 | }); 12 | 13 | test('img', async () => { 14 | expect( 15 | parseMarker( 16 | 'data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7' 17 | ) 18 | ).toBe('base64'); 19 | 20 | expect(parseMarker('https://gw.alipayobjects.com/zos/rmsportal/fSPDqijMJrYFdODpgEBV.png')).toBe('url'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /__tests__/unit/ui/timeline/data.ts: -------------------------------------------------------------------------------- 1 | import { Time } from '@antv/scale'; 2 | 3 | export const TIME_DATA = (() => { 4 | const scale = new Time({ 5 | tickCount: 10, 6 | range: [0, 11], 7 | domain: [new Date(2000, 0, 1), new Date(2000, 0, 10)], 8 | }); 9 | const formatter = scale.getFormatter(); 10 | 11 | return scale.getTicks().map((d: any) => ({ date: formatter(d) })); 12 | })(); 13 | 14 | export const generateTimeData = (count = 20) => { 15 | const scale = new Time({ 16 | tickCount: count, 17 | range: [0, count], 18 | utc: true, 19 | domain: [new Date(2000, 0, 1), new Date(2000, 3, 1)], 20 | }); 21 | const formatter = scale.getFormatter(); 22 | 23 | return scale.getTicks().map((d: any) => ({ date: formatter(d) })); 24 | }; 25 | -------------------------------------------------------------------------------- /__tests__/unit/util/geometry.ts/line-length-spec.ts: -------------------------------------------------------------------------------- 1 | import { lineLen } from '../../../../src'; 2 | 3 | describe('length', () => { 4 | test('length', () => { 5 | expect(lineLen([0, 0], [30, 40])).toBeCloseTo(50); 6 | expect(lineLen([0, 0], [-30, 40])).toBeCloseTo(50); 7 | expect(lineLen([0, 0], [30, -40])).toBeCloseTo(50); 8 | expect(lineLen([0, 0], [-30, -40])).toBeCloseTo(50); 9 | 10 | expect(lineLen([30, 40], [0, 0])).toBeCloseTo(50); 11 | expect(lineLen([-30, 40], [0, 0])).toBeCloseTo(50); 12 | expect(lineLen([30, -40], [0, 0])).toBeCloseTo(50); 13 | expect(lineLen([-30, -40], [0, 0])).toBeCloseTo(50); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /__tests__/unit/util/geometry.ts/lines-intersection-spec.ts: -------------------------------------------------------------------------------- 1 | import { intersection } from '../../../../src'; 2 | 3 | describe('Intersection', () => { 4 | test('intersection', () => { 5 | expect(intersection([0, 2], [2, 0], [0, 0], [2, 2])).toStrictEqual([1, 1]); 6 | expect(intersection([-2, -2], [2, 2], [-2, 2], [2, -2])).toStrictEqual([0, 0]); 7 | expect(intersection([-2, 2], [3, 2], [2, -3], [2, 10])).toStrictEqual([2, 2]); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /__tests__/unit/util/padding-spec.ts: -------------------------------------------------------------------------------- 1 | import { parseSeriesAttr } from '../../../src/util'; 2 | 3 | describe('padding', () => { 4 | test('number', async () => { 5 | expect(parseSeriesAttr(1)).toStrictEqual([1, 1, 1, 1]); 6 | }); 7 | 8 | test('array1', async () => { 9 | expect(parseSeriesAttr([2])).toStrictEqual([2, 2, 2, 2]); 10 | }); 11 | 12 | test('array2', async () => { 13 | expect(parseSeriesAttr([1, 2])).toStrictEqual([1, 2, 1, 2]); 14 | }); 15 | 16 | test('array3', async () => { 17 | expect(parseSeriesAttr([1, 2, 3])).toStrictEqual([1, 2, 3, 2]); 18 | }); 19 | 20 | test('array4', async () => { 21 | expect(parseSeriesAttr([1, 2, 3, 4])).toStrictEqual([1, 2, 3, 4]); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /__tests__/unit/util/transpose.spec.ts: -------------------------------------------------------------------------------- 1 | import { transpose } from '../../../src/util'; 2 | 3 | describe('transpose', () => { 4 | it('transpose', () => { 5 | expect( 6 | transpose([ 7 | [1, 2, 3], 8 | [4, 5, 6], 9 | ]) 10 | ).toEqual([ 11 | [1, 4], 12 | [2, 5], 13 | [3, 6], 14 | ]); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /__tests__/utils/delay.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 延迟函数 3 | * @param ms 4 | * @returns 5 | */ 6 | export async function delay(ms: number = 1000) { 7 | return new Promise((resolve) => { 8 | setTimeout(() => { 9 | resolve(true); 10 | }, ms); 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /__tests__/utils/dom.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 创建一个 div 节点,并放到 container,默认放到 body 上 3 | * @param container 4 | */ 5 | export function createDiv(container: HTMLElement = document.body): HTMLElement { 6 | const div = document.createElement('div'); 7 | 8 | container.appendChild(div); 9 | 10 | return div; 11 | } 12 | 13 | /** 14 | * 移除一个 DOM 15 | * @param dom 16 | */ 17 | export function removeDom(dom: HTMLElement) { 18 | const parent = dom.parentNode; 19 | 20 | if (parent) { 21 | parent.removeChild(dom); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /__tests__/utils/index.ts: -------------------------------------------------------------------------------- 1 | export { createDiv, removeDom } from './dom'; 2 | export { delay } from './delay'; 3 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { extends: ['@commitlint/config-conventional'] }; 2 | -------------------------------------------------------------------------------- /docs/api.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/component/105051aeaf7a339202c9825a7a9f6634dda06f9b/docs/api.md -------------------------------------------------------------------------------- /docs/components/crosshair.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Crosshair 3 | order: 8 4 | --- 5 | 6 | `markdown:docs/api/ui/crosshair.en.md` 7 | -------------------------------------------------------------------------------- /docs/components/marker.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Marker 3 | order: 0 4 | --- 5 | 6 | `markdown:docs/api/ui/marker.en.md` 7 | -------------------------------------------------------------------------------- /docs/components/poptip.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Poptip 3 | order: 10 4 | --- 5 | 6 | # 气泡提示框 7 | 8 | ## 使用 9 | 10 | ```ts 11 | import { Poptip } from '@antv/component'; 12 | ``` 13 | 14 | -------------------------------------------------------------------------------- /docs/components/tag.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tag 3 | order: 1 4 | --- 5 | 6 | `markdown:docs/api/ui/tag.en.md` 7 | -------------------------------------------------------------------------------- /src/animation/fadeIn.ts: -------------------------------------------------------------------------------- 1 | import type { DisplayObject } from '../shapes'; 2 | import { transition } from './utils'; 3 | import type { GenericAnimation } from '.'; 4 | 5 | export default function (element: DisplayObject, options: GenericAnimation) { 6 | if (!element.style.opacity) element.style.opacity = 0; 7 | return transition(element, { opacity: 1 }, options); 8 | } 9 | -------------------------------------------------------------------------------- /src/animation/fadeOut.ts: -------------------------------------------------------------------------------- 1 | import type { DisplayObject } from '../shapes'; 2 | import { transition } from './utils'; 3 | import type { GenericAnimation } from '.'; 4 | 5 | export default function (element: DisplayObject, options: GenericAnimation) { 6 | if (!element.style.opacity) element.style.opacity = 1; 7 | return transition(element, { opacity: 0 }, options); 8 | } 9 | -------------------------------------------------------------------------------- /src/animation/index.ts: -------------------------------------------------------------------------------- 1 | export { default as fadeIn } from './fadeIn'; 2 | export { default as fadeOut } from './fadeOut'; 3 | export type { StandardAnimationOption, AnimationOption, GenericAnimation, AnimationResult } from './types'; 4 | export * from './utils'; 5 | -------------------------------------------------------------------------------- /src/animation/types.ts: -------------------------------------------------------------------------------- 1 | /* global KeyframeAnimationOptions */ 2 | 3 | import type { IAnimation } from '@antv/g'; 4 | 5 | export type GenericAnimation = false | KeyframeAnimationOptions; 6 | 7 | export type StandardAnimationOption = { 8 | enter: GenericAnimation; 9 | update: GenericAnimation; 10 | exit: GenericAnimation; 11 | }; 12 | 13 | export type AnimationOption = GenericAnimation | StandardAnimationOption; 14 | 15 | export type AnimationResult = IAnimation | null; 16 | -------------------------------------------------------------------------------- /src/constant.ts: -------------------------------------------------------------------------------- 1 | // 混合样式状态 2 | export const STATE_LIST = ['default', 'active', 'selected', 'disabled', 'inactive'] as const; 3 | -------------------------------------------------------------------------------- /src/core/index.ts: -------------------------------------------------------------------------------- 1 | export { Component } from './component'; 2 | export * from './types'; 3 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | // ui 2 | export * from './ui'; 3 | 4 | // 方法 5 | export * from './util'; 6 | -------------------------------------------------------------------------------- /src/shapes/Circle.ts: -------------------------------------------------------------------------------- 1 | import type { CircleStyleProps as GCircleStyleProps } from '@antv/g'; 2 | import { OmitConflictStyleProps } from './types'; 3 | 4 | export { Circle } from '@antv/g'; 5 | export type CircleStyleProps = OmitConflictStyleProps; 6 | -------------------------------------------------------------------------------- /src/shapes/CustomElement.ts: -------------------------------------------------------------------------------- 1 | import type { BaseCustomElementStyleProps as GBaseCustomElementStyleProps } from '@antv/g'; 2 | import { OmitConflictStyleProps } from './types'; 3 | 4 | export { CustomElement } from '@antv/g'; 5 | export type BaseCustomElementStyleProps = OmitConflictStyleProps; 6 | -------------------------------------------------------------------------------- /src/shapes/DisplayObject.ts: -------------------------------------------------------------------------------- 1 | export { DisplayObject } from '@antv/g'; 2 | export type { BaseStyleProps, DisplayObjectConfig } from '@antv/g'; 3 | -------------------------------------------------------------------------------- /src/shapes/Ellipse.ts: -------------------------------------------------------------------------------- 1 | import type { EllipseStyleProps as GEllipseStyleProps } from '@antv/g'; 2 | import { OmitConflictStyleProps } from './types'; 3 | 4 | export { Ellipse } from '@antv/g'; 5 | export type EllipseStyleProps = OmitConflictStyleProps; 6 | -------------------------------------------------------------------------------- /src/shapes/Group.ts: -------------------------------------------------------------------------------- 1 | import type { GroupStyleProps as GGroupStyleProps } from '@antv/g'; 2 | import { OmitConflictStyleProps } from './types'; 3 | 4 | export { Group } from '@antv/g'; 5 | export type GroupStyleProps = OmitConflictStyleProps; 6 | -------------------------------------------------------------------------------- /src/shapes/HTML.ts: -------------------------------------------------------------------------------- 1 | import type { HTMLStyleProps as GHTMLStyleProps } from '@antv/g'; 2 | import { OmitConflictStyleProps } from './types'; 3 | 4 | export { HTML } from '@antv/g'; 5 | export type HTMLStyleProps = OmitConflictStyleProps; 6 | -------------------------------------------------------------------------------- /src/shapes/Image.ts: -------------------------------------------------------------------------------- 1 | import type { ImageStyleProps as GImageStyleProps } from '@antv/g'; 2 | import { OmitConflictStyleProps } from './types'; 3 | 4 | export { Image } from '@antv/g'; 5 | export type ImageStyleProps = OmitConflictStyleProps; 6 | -------------------------------------------------------------------------------- /src/shapes/Line.ts: -------------------------------------------------------------------------------- 1 | import type { LineStyleProps as GLineStyleProps } from '@antv/g'; 2 | import { OmitConflictStyleProps } from './types'; 3 | 4 | export { Line } from '@antv/g'; 5 | export type LineStyleProps = OmitConflictStyleProps; 6 | -------------------------------------------------------------------------------- /src/shapes/Path.ts: -------------------------------------------------------------------------------- 1 | import type { PathStyleProps as GPathStyleProps } from '@antv/g'; 2 | import { OmitConflictStyleProps } from './types'; 3 | 4 | export { Path } from '@antv/g'; 5 | export type PathStyleProps = OmitConflictStyleProps; 6 | -------------------------------------------------------------------------------- /src/shapes/Polygon.ts: -------------------------------------------------------------------------------- 1 | import type { PolygonStyleProps as GPolygonStyleProps } from '@antv/g'; 2 | import { OmitConflictStyleProps } from './types'; 3 | 4 | export { Polygon } from '@antv/g'; 5 | export type PolygonStyleProps = OmitConflictStyleProps; 6 | -------------------------------------------------------------------------------- /src/shapes/Polyline.ts: -------------------------------------------------------------------------------- 1 | import type { PolylineStyleProps as GPolylineStyleProps } from '@antv/g'; 2 | import { OmitConflictStyleProps } from './types'; 3 | 4 | export { Polyline } from '@antv/g'; 5 | export type PolylineStyleProps = OmitConflictStyleProps; 6 | -------------------------------------------------------------------------------- /src/shapes/Rect.ts: -------------------------------------------------------------------------------- 1 | import type { RectStyleProps as GRectStyleProps } from '@antv/g'; 2 | import { OmitConflictStyleProps } from './types'; 3 | 4 | export { Rect } from '@antv/g'; 5 | export type RectStyleProps = OmitConflictStyleProps; 6 | -------------------------------------------------------------------------------- /src/shapes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Circle'; 2 | export * from './CustomElement'; 3 | export * from './DisplayObject'; 4 | export * from './Ellipse'; 5 | export * from './Group'; 6 | export * from './HTML'; 7 | export * from './Image'; 8 | export * from './Line'; 9 | export * from './Path'; 10 | export * from './Polygon'; 11 | export * from './Polyline'; 12 | export * from './Rect'; 13 | export * from './Text'; 14 | -------------------------------------------------------------------------------- /src/shapes/types.ts: -------------------------------------------------------------------------------- 1 | import type { BaseStyleProps } from '@antv/g'; 2 | 3 | type ConflictStyleProps = 'filter'; 4 | 5 | export type OmitConflictStyleProps = { 6 | [K in keyof T as K extends ConflictStyleProps ? never : K]: T[K]; 7 | }; 8 | -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | import { DisplayObject } from '@antv/g'; 2 | 3 | export type Point = [number, number]; 4 | 5 | export type Vector2 = [number, number]; 6 | 7 | export type ExtendDisplayObject = string | number | DisplayObject | (() => DisplayObject); 8 | 9 | export type Callable = T | ((...args: P) => T); 10 | 11 | export type CallbackParameter = [datum: T, index: number, data: T[], ...args: E]; 12 | 13 | export type CallableObject = { 14 | [K in keyof T]: Callable; 15 | }; 16 | 17 | export type BBox = { 18 | x: number; 19 | y: number; 20 | width: number; 21 | height: number; 22 | }; 23 | 24 | export * from './prefix'; 25 | export * from './styles'; 26 | -------------------------------------------------------------------------------- /src/types/prefix.ts: -------------------------------------------------------------------------------- 1 | export type PrefixObject, P extends string> = { 2 | [K in keyof T as K extends string ? `${P}${Capitalize}` : never]?: T[K]; 3 | }; 4 | -------------------------------------------------------------------------------- /src/types/styles.ts: -------------------------------------------------------------------------------- 1 | import { STATE_LIST } from '../constant'; 2 | 3 | export type StyleState = (typeof STATE_LIST)[number]; 4 | 5 | export type MixAttrs = { 6 | [state in StyleState]?: T; 7 | }; 8 | -------------------------------------------------------------------------------- /src/ui/axis/index.ts: -------------------------------------------------------------------------------- 1 | export { Axis } from './axis'; 2 | export type { ArcAxisOptions, ArcAxisStyleProps, AxisOptions, LinearAxisOptions, LinearAxisStyleProps } from './axis'; 3 | export type { AxisStyleProps } from './types'; 4 | -------------------------------------------------------------------------------- /src/ui/axis/utils/index.ts: -------------------------------------------------------------------------------- 1 | import type { VerticalFactor, Direction } from '../types'; 2 | 3 | export * from './test'; 4 | 5 | export function getFactor(...args: Direction[]): VerticalFactor { 6 | const fn = (str: (typeof args)[number]): VerticalFactor => (str === 'positive' ? -1 : 1); 7 | return args.reduce((acc, cur) => acc * fn(cur), 1) as unknown as VerticalFactor; 8 | } 9 | -------------------------------------------------------------------------------- /src/ui/checkbox/types.ts: -------------------------------------------------------------------------------- 1 | import type { GroupStyleProps, RectStyleProps, TextStyleProps } from '../../shapes'; 2 | import type { ComponentOptions } from '../../core'; 3 | import type { PrefixObject } from '../../types'; 4 | 5 | export type CheckboxStyleProps = GroupStyleProps & 6 | PrefixObject, 'box'> & 7 | PrefixObject, 'checked'> & 8 | PrefixObject & { 9 | /** 10 | * @title 是否选中 11 | * @description 指定当前是否选中 12 | */ 13 | checked?: boolean; 14 | /** 15 | * @title label chebox 间距 16 | * @description label 与 chebox 的方块的间距 17 | * @default 2 18 | */ 19 | spacing?: number; 20 | }; 21 | 22 | export type CheckboxOptions = ComponentOptions; 23 | -------------------------------------------------------------------------------- /src/ui/crosshair/index.ts: -------------------------------------------------------------------------------- 1 | export * from './base'; 2 | export * from './line'; 3 | export * from './circle'; 4 | export * from './polygon'; 5 | -------------------------------------------------------------------------------- /src/ui/grid/types.ts: -------------------------------------------------------------------------------- 1 | import type { BaseStyleProps } from '../../shapes'; 2 | import type { StandardAnimationOption } from '../../animation'; 3 | import type { ComponentOptions } from '../../core'; 4 | import type { Point } from '../../types'; 5 | 6 | export type GridStyle = BaseStyleProps; 7 | 8 | export type GridStyleProps = GridStyle & { 9 | animate: StandardAnimationOption; 10 | data: { id: string | number; points: Point[] }[]; 11 | /** the connect way of two lines, if arc, center is necessary */ 12 | type?: 'segment' | 'surround'; 13 | connect?: 'line' | 'arc'; 14 | // If type is 'circle', should specify the center. 15 | center?: Point; 16 | // If type is 'circle', determine whether to close path. 17 | closed?: boolean; 18 | /** FillColors between lines. */ 19 | areaFill?: string | string[] | null; 20 | isBillboard?: boolean; 21 | }; 22 | 23 | export type GridOptions = ComponentOptions; 24 | -------------------------------------------------------------------------------- /src/ui/indicator/constant.ts: -------------------------------------------------------------------------------- 1 | import type { IndicatorStyleProps } from './types'; 2 | 3 | export const DEFAULT_INDICATOR_STYLE_PROPS: Partial = { 4 | backgroundFill: '#262626', 5 | backgroundLineCap: 'round', 6 | backgroundLineWidth: 1, 7 | backgroundStroke: '#333', 8 | backgroundZIndex: -1, 9 | formatter: (val) => val.toString(), 10 | labelFill: '#fff', 11 | labelFontSize: 12, 12 | labelTextBaseline: 'middle', 13 | padding: [2, 4], 14 | position: 'right', 15 | radius: 0, 16 | zIndex: 999, 17 | }; 18 | -------------------------------------------------------------------------------- /src/ui/indicator/index.ts: -------------------------------------------------------------------------------- 1 | export * from './indicator'; 2 | -------------------------------------------------------------------------------- /src/ui/indicator/types.ts: -------------------------------------------------------------------------------- 1 | import type { GroupStyleProps, PathStyleProps, TextStyleProps } from '../../shapes'; 2 | import type { ComponentOptions } from '../../core'; 3 | import type { ExtendDisplayObject, PrefixObject } from '../../types'; 4 | import type { SeriesAttr } from '../../util'; 5 | 6 | export type Position = 'top' | 'right' | 'bottom' | 'left'; 7 | 8 | export type IndicatorStyleProps = GroupStyleProps & 9 | PrefixObject & 10 | PrefixObject, 'label'> & { 11 | x: number; 12 | y: number; 13 | labelText?: T; 14 | /** position of indicator related to pointer */ 15 | position?: Position; 16 | padding?: SeriesAttr; 17 | /** 圆角半径 */ 18 | radius?: number; 19 | formatter?: (val: T) => ExtendDisplayObject; 20 | }; 21 | 22 | export type IndicatorOptions = ComponentOptions; 23 | -------------------------------------------------------------------------------- /src/ui/layout/index.ts: -------------------------------------------------------------------------------- 1 | export { Layout } from './layout'; 2 | export type { LayoutOptions, LayoutStyleProps } from './layout'; 3 | -------------------------------------------------------------------------------- /src/ui/layout/types.ts: -------------------------------------------------------------------------------- 1 | import type { GroupStyleProps, DisplayObjectConfig } from '../../shapes'; 2 | import type { LayoutElementConfig } from '../../util/layout'; 3 | import type { SeriesAttr } from '../../util/series'; 4 | 5 | export type LayoutStyleProps = GroupStyleProps & 6 | LayoutElementConfig & { 7 | x?: number; 8 | y?: number; 9 | width: number; 10 | height: number; 11 | margin?: SeriesAttr; 12 | border?: SeriesAttr; 13 | padding?: SeriesAttr; 14 | }; 15 | 16 | export type LayoutOptions = DisplayObjectConfig; 17 | -------------------------------------------------------------------------------- /src/ui/legend/index.ts: -------------------------------------------------------------------------------- 1 | import type { CategoryOptions } from './category'; 2 | import { Category } from './category'; 3 | import type { ContinuousOptions } from './continuous'; 4 | import { Continuous } from './continuous'; 5 | 6 | export { Category, Continuous }; 7 | export type { CategoryOptions, ContinuousOptions }; 8 | -------------------------------------------------------------------------------- /src/ui/marker/types.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentOptions } from '../../core'; 2 | import type { BaseCustomElementStyleProps } from '../../shapes'; 3 | 4 | export type FunctionalSymbol = (x: number, y: number, r: number) => any; 5 | 6 | export type MarkerStyleProps = BaseCustomElementStyleProps & { 7 | x?: number; 8 | y?: number; 9 | size?: number; 10 | symbol: string | FunctionalSymbol; 11 | }; 12 | 13 | export type MarkerOptions = ComponentOptions; 14 | -------------------------------------------------------------------------------- /src/ui/marker/utils.ts: -------------------------------------------------------------------------------- 1 | import { isObject, isString, isFunction } from '@antv/util'; 2 | import type { MarkerStyleProps } from './types'; 3 | /** 4 | * 解析marker类型 5 | */ 6 | export function parseMarker(icon: MarkerStyleProps['symbol'] | string) { 7 | let type = 'default'; 8 | if (isObject(icon) && icon instanceof Image) type = 'image'; 9 | else if (isFunction(icon)) type = 'symbol'; 10 | else if (isString(icon)) { 11 | const dataURLsPattern = new RegExp('data:(image|text)'); 12 | if (icon.match(dataURLsPattern)) { 13 | type = 'base64'; 14 | } else if (/^(https?:\/\/(([a-zA-Z0-9]+-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+)(:\d+)?(\/.*)?(\?.*)?(#.*)?$/.test(icon)) { 15 | type = 'url'; 16 | } else { 17 | // 不然就当作symbol string 处理 18 | type = 'symbol'; 19 | } 20 | } 21 | return type; 22 | } 23 | -------------------------------------------------------------------------------- /src/ui/select/index.ts: -------------------------------------------------------------------------------- 1 | export { Select } from './select'; 2 | export type { SelectOptions, SelectStyleProps } from './types'; 3 | -------------------------------------------------------------------------------- /src/ui/slider/constant.ts: -------------------------------------------------------------------------------- 1 | import { classNames } from '../../util'; 2 | 3 | export const HANDLE_ICON_DEFAULT_CFG = { 4 | fill: '#fff', 5 | lineWidth: 1, 6 | radius: 2, 7 | size: 10, 8 | stroke: '#bfbfbf', 9 | strokeOpacity: 1, 10 | zIndex: 0, 11 | } as const; 12 | 13 | export const HANDLE_LABEL_DEFAULT_CFG = { 14 | fill: '#000', 15 | fillOpacity: 0.45, 16 | fontSize: 12, 17 | textAlign: 'center', 18 | textBaseline: 'middle', 19 | zIndex: 1, 20 | } as const; 21 | 22 | export const HANDLE_DEFAULT_CFG = { 23 | x: 0, 24 | y: 0, 25 | orientation: 'horizontal', 26 | showLabel: true, 27 | type: 'start', 28 | } as const; 29 | 30 | export const CLASS_NAMES = classNames( 31 | { 32 | foreground: 'foreground', 33 | handle: 'handle', 34 | selection: 'selection', 35 | sparkline: 'sparkline', 36 | sparklineGroup: 'sparkline-group', 37 | track: 'track', 38 | brushArea: 'brush-area', 39 | }, 40 | 'slider' 41 | ); 42 | -------------------------------------------------------------------------------- /src/ui/timebar/index.ts: -------------------------------------------------------------------------------- 1 | export { Timebar } from './timebar'; 2 | export type { TimebarStyleProps, TimebarOptions } from './types'; 3 | -------------------------------------------------------------------------------- /src/util/angle-converter.ts: -------------------------------------------------------------------------------- 1 | export function degToRad(deg: number) { 2 | return (deg * Math.PI) / 180; 3 | } 4 | 5 | export function radToDeg(rad: number) { 6 | return Number(((rad * 180) / Math.PI).toPrecision(5)); 7 | } 8 | -------------------------------------------------------------------------------- /src/util/callback.ts: -------------------------------------------------------------------------------- 1 | import { isFunction } from '@antv/util'; 2 | 3 | export function getCallbackValue(value: any, params: any[]): T { 4 | return isFunction(value) ? value(...params) : value; 5 | } 6 | -------------------------------------------------------------------------------- /src/util/classnames.ts: -------------------------------------------------------------------------------- 1 | export const classNames = (cls: T, prefix: string) => { 2 | const PREFIX = (str: string) => `${prefix}-${str}`; 3 | const obj = Object.fromEntries( 4 | Object.entries(cls).map(([k, v]) => { 5 | const name = PREFIX(v); 6 | return [ 7 | k, 8 | { 9 | name, 10 | class: `.${name}`, 11 | id: `#${name}`, 12 | toString() { 13 | return name; 14 | }, 15 | }, 16 | ]; 17 | }) 18 | ); 19 | Object.assign(obj, { prefix: PREFIX }); 20 | return obj as { 21 | [K in keyof T]: { 22 | name: string; 23 | class: string; 24 | id: string; 25 | }; 26 | }; 27 | }; 28 | -------------------------------------------------------------------------------- /src/util/defined.ts: -------------------------------------------------------------------------------- 1 | export const defined = (x: any) => x !== undefined && x != null && !Number.isNaN(x); 2 | -------------------------------------------------------------------------------- /src/util/ellipsis.ts: -------------------------------------------------------------------------------- 1 | import { Text } from '../shapes'; 2 | import { applyToText } from './text'; 3 | 4 | export function ellipsisIt(node: Text, w: number, suffix = '...') { 5 | applyToText(node, { wordWrap: true, wordWrapWidth: w, maxLines: 1, textOverflow: suffix }); 6 | } 7 | -------------------------------------------------------------------------------- /src/util/event.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 获得触发事件的坐标 3 | */ 4 | export function getEventPos(e: any): [number, number] { 5 | const { canvas, touches, offsetX, offsetY } = e; 6 | if (canvas) { 7 | const { x, y } = canvas; 8 | return [x, y]; 9 | } 10 | if (touches) { 11 | const { clientX, clientY } = touches[0]; 12 | return [clientX, clientY]; 13 | } 14 | if (offsetX && offsetY) return [offsetX, offsetY]; 15 | return [0, 0]; 16 | } 17 | -------------------------------------------------------------------------------- /src/util/extend-display-object.ts: -------------------------------------------------------------------------------- 1 | import { isNumber, isString } from '@antv/util'; 2 | import type { DisplayObject } from '../shapes'; 3 | import { Text } from '../shapes'; 4 | import type { ExtendDisplayObject } from '../types'; 5 | 6 | export function renderExtDo(el: ExtendDisplayObject): DisplayObject { 7 | if (typeof el === 'function') return el(); 8 | return isString(el) || isNumber(el) ? new Text({ style: { text: String(el) } }) : el; 9 | } 10 | -------------------------------------------------------------------------------- /src/util/geometry/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lines-intersection'; 2 | export * from './line-length'; 3 | -------------------------------------------------------------------------------- /src/util/geometry/line-length.ts: -------------------------------------------------------------------------------- 1 | import type { Point } from '../../types'; 2 | 3 | /** 4 | * 计算线段长度 5 | */ 6 | export function lineLen([x1, y1]: Point, [x2, y2]: Point) { 7 | return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5; 8 | } 9 | -------------------------------------------------------------------------------- /src/util/group-by.ts: -------------------------------------------------------------------------------- 1 | export function groupBy(source: T[], by: keyof T) { 2 | return source.reduce((acc, curr) => { 3 | (acc[curr[by]] = acc[curr[by]] || []).push(curr); 4 | return acc; 5 | }, {} as { [key in T[keyof T]]: T[] }); 6 | } 7 | -------------------------------------------------------------------------------- /src/util/group.ts: -------------------------------------------------------------------------------- 1 | export function group(array: any[], keyFunc: Function) { 2 | const grouped = new Map(); 3 | 4 | array.forEach((item) => { 5 | const key = keyFunc(item); 6 | if (!grouped.has(key)) { 7 | grouped.set(key, []); 8 | } 9 | grouped.get(key).push(item); 10 | }); 11 | 12 | return grouped; 13 | } 14 | -------------------------------------------------------------------------------- /src/util/html.ts: -------------------------------------------------------------------------------- 1 | export function stringToHTML(str: string): HTMLElement | undefined { 2 | const tempNode = document.createElement('div'); 3 | tempNode.innerHTML = str; 4 | return tempNode.firstChild as HTMLElement; 5 | } 6 | 7 | export function parseHTML(element: string | HTMLElement): HTMLElement | undefined { 8 | if (typeof element === 'string') { 9 | return stringToHTML(element); 10 | } 11 | return element; 12 | } 13 | -------------------------------------------------------------------------------- /src/util/if-show.ts: -------------------------------------------------------------------------------- 1 | import { Selection } from './selection'; 2 | 3 | export function ifShow( 4 | show: boolean, 5 | container: T, 6 | creator: (group: T) => R, 7 | removeChildren: boolean = true, 8 | removeHandler: (group: T) => any = (g) => { 9 | g.node().removeChildren(); 10 | } 11 | ): null | R { 12 | if (show) { 13 | return creator(container); 14 | } 15 | if (removeChildren) removeHandler(container); 16 | return null; 17 | } 18 | -------------------------------------------------------------------------------- /src/util/in-range.ts: -------------------------------------------------------------------------------- 1 | export function inRange( 2 | n: number, 3 | start: number, 4 | end: number, 5 | includeLeft: boolean = true, 6 | includeRight: boolean = false 7 | ) { 8 | if ((includeLeft && n === start) || (includeRight && n === end)) return true; 9 | return n > start && n < end; 10 | } 11 | -------------------------------------------------------------------------------- /src/util/keyframe-interpolate.ts: -------------------------------------------------------------------------------- 1 | import type { GenericAnimation } from '../animation'; 2 | import type { DisplayObject } from '../shapes'; 3 | import type { Interpolatable } from './interpolate'; 4 | import { interpolate } from './interpolate'; 5 | 6 | export function keyframeInterpolate( 7 | element: DisplayObject, 8 | from: T, 9 | to: T, 10 | options: GenericAnimation 11 | ) { 12 | if (!options) { 13 | element.attr('__keyframe_data__', to); 14 | return null; 15 | } 16 | const { duration = 0 } = options; 17 | const int = interpolate(from, to); 18 | const count = Math.ceil(+duration / 16); 19 | const keyframes = new Array(count) 20 | .fill(0) 21 | .map((datum, index, array) => ({ __keyframe_data__: int(index / (array.length - 1)) })); 22 | // @ts-ignore 23 | return element.animate(keyframes, { fill: 'both', ...options }); 24 | } 25 | -------------------------------------------------------------------------------- /src/util/layout/executer.ts: -------------------------------------------------------------------------------- 1 | import { flex } from './flex'; 2 | import { grid } from './grid'; 3 | import type { LayoutConfig, LayoutItem } from './types'; 4 | 5 | export default (container: LayoutItem, children: LayoutItem[], config: LayoutConfig) => { 6 | if (children.length === 0) return []; 7 | const callers = { flex, grid }; 8 | const caller = config.display in callers ? callers[config.display] : null; 9 | // @ts-ignore 10 | return caller?.call(null, container, children, config) || []; 11 | }; 12 | -------------------------------------------------------------------------------- /src/util/layout/grid/index.ts: -------------------------------------------------------------------------------- 1 | import type { LayoutExecuter } from '../types'; 2 | import type { GridLayoutConfig } from './types'; 3 | 4 | export const grid: LayoutExecuter = function (container, children, config) { 5 | // todo 6 | return []; 7 | }; 8 | -------------------------------------------------------------------------------- /src/util/layout/grid/types.ts: -------------------------------------------------------------------------------- 1 | export interface GridItemConfig {} 2 | 3 | export interface GridContainerConfig {} 4 | 5 | export interface GridElementConfig extends GridItemConfig, GridContainerConfig {} 6 | export interface GridLayoutConfig extends Partial, Partial { 7 | display: 'grid'; 8 | } 9 | -------------------------------------------------------------------------------- /src/util/layout/index.ts: -------------------------------------------------------------------------------- 1 | export * from './flex'; 2 | export * from './grid'; 3 | export { default as calcLayout } from './executer'; 4 | export * from './types'; 5 | -------------------------------------------------------------------------------- /src/util/layout/types.ts: -------------------------------------------------------------------------------- 1 | import type { FlexElementConfig, FlexLayoutConfig } from './flex/types'; 2 | import type { GridContainerConfig, GridLayoutConfig } from './grid/types'; 3 | 4 | export type LayoutItem = DOMRect; 5 | export type LayoutElementConfig = FlexElementConfig | GridContainerConfig; 6 | export type LayoutConfig = FlexLayoutConfig | GridLayoutConfig; 7 | export type LayoutType = LayoutConfig['display']; 8 | export type LayoutReturns = DOMRect[]; 9 | export type LayoutExecuter = ( 10 | container: LayoutItem, 11 | children: LayoutItem[], 12 | config: T 13 | ) => LayoutReturns; 14 | -------------------------------------------------------------------------------- /src/util/layout/utils/helper.ts: -------------------------------------------------------------------------------- 1 | import type { LayoutItem } from '../types'; 2 | import { BBox } from '../../bbox'; 3 | 4 | export function getItemsBBox(items: LayoutItem[]) { 5 | let minX = Infinity; 6 | let minY = Infinity; 7 | let maxX = -Infinity; 8 | let maxY = -Infinity; 9 | 10 | for (let i = 0; i < items.length; i++) { 11 | const { x, y, width, height } = items[i]; 12 | const [X, Y] = [x + width, y + height]; 13 | if (x < minX) minX = x; 14 | if (y < minY) minY = y; 15 | if (X > maxX) maxX = X; 16 | if (Y > maxY) maxY = Y; 17 | } 18 | return new BBox(minX, minY, maxX - minX, maxY - minY); 19 | } 20 | -------------------------------------------------------------------------------- /src/util/layout/utils/index.ts: -------------------------------------------------------------------------------- 1 | export { getItemsBBox } from './helper'; 2 | -------------------------------------------------------------------------------- /src/util/omit.ts: -------------------------------------------------------------------------------- 1 | export function omit(obj: Record, keys: string | string[]) { 2 | const res: Record = {}; 3 | const innerKeys = Array.isArray(keys) ? keys : [keys]; 4 | for (const key in obj) { 5 | if (!innerKeys.includes(key)) { 6 | res[key] = obj[key]; 7 | } 8 | } 9 | return res; 10 | } 11 | -------------------------------------------------------------------------------- /src/util/replace-children.ts: -------------------------------------------------------------------------------- 1 | export const replaceChildren = (el: HTMLElement, content: string | HTMLElement | HTMLElement[]) => { 2 | if (content == null) { 3 | el.innerHTML = ''; 4 | return; 5 | } 6 | if (el.replaceChildren) { 7 | if (Array.isArray(content)) { 8 | el.replaceChildren(...content); 9 | } else { 10 | el.replaceChildren(content); 11 | } 12 | } else { 13 | el.innerHTML = ''; 14 | if (Array.isArray(content)) { 15 | content.forEach((child) => el.appendChild(child)); 16 | } else { 17 | el.appendChild(content as HTMLElement); 18 | } 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /src/util/sampling.ts: -------------------------------------------------------------------------------- 1 | export function sampling(data: T, size: number): T { 2 | if (data.length <= size) return data; 3 | const step = Math.floor(data.length / size); 4 | const result: T = [] as any; 5 | for (let i = 0; i < data.length; i += step) { 6 | result.push(data[i]); 7 | } 8 | return result; 9 | } 10 | -------------------------------------------------------------------------------- /src/util/scale-to-pixel.ts: -------------------------------------------------------------------------------- 1 | import type { DisplayObject } from '../shapes'; 2 | 3 | /** 4 | * scale a shape to a given size 5 | */ 6 | export function scaleToPixel(el: DisplayObject, size: number, applyScale = false) { 7 | const { width, height } = el.getBBox(); 8 | const scale = size / Math.max(width, height); 9 | if (applyScale) { 10 | el.style.transform = `scale(${scale})`; 11 | } 12 | return scale; 13 | } 14 | -------------------------------------------------------------------------------- /src/util/series.ts: -------------------------------------------------------------------------------- 1 | import { isNumber, isArray } from '@antv/util'; 2 | 3 | export type SeriesAttr = number | number[]; 4 | 5 | export type StandardSeriesAttr = [number, number, number, number]; 6 | 7 | /** 8 | * 规范化padding 9 | */ 10 | export function parseSeriesAttr(series?: SeriesAttr): StandardSeriesAttr { 11 | if (isNumber(series)) { 12 | return [series, series, series, series]; 13 | } 14 | if (isArray(series)) { 15 | const len = (series as number[]).length; 16 | 17 | if (len === 1) { 18 | return [series[0], series[0], series[0], series[0]]; 19 | } 20 | if (len === 2) { 21 | return [series[0], series[1], series[0], series[1]]; 22 | } 23 | if (len === 3) { 24 | return [series[0], series[1], series[2], series[1]]; 25 | } 26 | if (len === 4) { 27 | return series as StandardSeriesAttr; 28 | } 29 | } 30 | return [0, 0, 0, 0]; 31 | } 32 | -------------------------------------------------------------------------------- /src/util/string.ts: -------------------------------------------------------------------------------- 1 | export function toUppercaseFirstLetter(string: string) { 2 | return string.toString().charAt(0).toUpperCase() + string.toString().slice(1); 3 | } 4 | 5 | export function toLowercaseFirstLetter(string: string) { 6 | return string.toString().charAt(0).toLowerCase() + string.toString().slice(1); 7 | } 8 | 9 | export function addPrefix(string: string, prefix: string) { 10 | return `${prefix}${toUppercaseFirstLetter(string)}`; 11 | } 12 | 13 | export function removePrefix(string: string, prefix?: string, lowercaseFirstLetter: boolean = true) { 14 | const inferPrefix = prefix || string.match(/^([a-z][a-z0-9]+)/)?.[0] || ''; 15 | const withoutPrefix = string.replace(new RegExp(`^(${inferPrefix})`), ''); 16 | return lowercaseFirstLetter ? toLowercaseFirstLetter(withoutPrefix) : withoutPrefix; 17 | } 18 | -------------------------------------------------------------------------------- /src/util/throttle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 节流修饰器 3 | * @param delay 节流时间 4 | */ 5 | export function throttle(delay: number = 0, rightNow: boolean = false) { 6 | return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => { 7 | const func = descriptor.value; 8 | let timeout: number | null; 9 | if (typeof func === 'function') { 10 | // eslint-disable-next-line 11 | descriptor.value = function (...args: any[]) { 12 | if (timeout) return; 13 | const context = this; 14 | if (rightNow) func.apply(context, args); 15 | timeout = window.setTimeout(() => { 16 | func.apply(context, args); 17 | timeout = null; 18 | }, delay); 19 | }; 20 | } 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /src/util/timer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 计时装饰器 3 | */ 4 | export function timer(label?: string) { 5 | const debug = localStorage.getItem('__debug__'); 6 | 7 | return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => { 8 | const timerLabel = `[${propertyKey}] ${label}`; 9 | const func = descriptor.value; 10 | if (typeof func === 'function') { 11 | // eslint-disable-next-line 12 | descriptor.value = function (...args: any[]) { 13 | debug && console.time(timerLabel); 14 | func.apply(this, args); 15 | debug && console.timeEnd(timerLabel); 16 | }; 17 | } 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /src/util/transform.ts: -------------------------------------------------------------------------------- 1 | import { DisplayObject } from '../shapes'; 2 | 3 | export function getTranslate(node: DisplayObject, x: string, y: string) { 4 | const { width, height } = node.getBBox(); 5 | const [tx, ty] = [x, y].map((v, i) => { 6 | return v.includes('%') 7 | ? (parseFloat(v.match(/[+-]?([0-9]*[.])?[0-9]+/)?.[0] || '0') / 100) * (i === 0 ? width : height) 8 | : v; 9 | }); 10 | return [tx, ty]; 11 | } 12 | 13 | /** 14 | * transform that support translate percent value 15 | */ 16 | export function percentTransform(node: DisplayObject, val: string) { 17 | if (!val) return; 18 | try { 19 | const reg = /translate\(([+-]*[\d]+[%]*),[ ]*([+-]*[\d]+[%]*)\)/g; 20 | 21 | const computedVal = val.replace(reg, (match, x, y) => `translate(${getTranslate(node, x, y)})`); 22 | node.attr('transform', computedVal); 23 | } catch (e) { 24 | // do nothing 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/util/transpose.ts: -------------------------------------------------------------------------------- 1 | export function transpose(m: number[][]) { 2 | return m[0]?.map((x, i) => m.map((x) => x[i])) || []; 3 | } 4 | -------------------------------------------------------------------------------- /src/util/traverse.ts: -------------------------------------------------------------------------------- 1 | import { DisplayObject } from '../shapes/DisplayObject'; 2 | 3 | export function traverse(element: DisplayObject, callback: (node: DisplayObject) => void) { 4 | callback(element); 5 | if (element.children) { 6 | element.children.forEach((child) => { 7 | if (child) traverse(child as DisplayObject, callback); 8 | }); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/util/visibility.ts: -------------------------------------------------------------------------------- 1 | import { DisplayObject } from '../shapes/DisplayObject'; 2 | import { traverse } from './traverse'; 3 | 4 | export function show(element: DisplayObject) { 5 | visibility(element, true); 6 | } 7 | 8 | export function hide(element: DisplayObject) { 9 | visibility(element, false); 10 | } 11 | 12 | export function visibility(element: DisplayObject, visible: boolean) { 13 | const value = visible ? 'visible' : 'hidden'; 14 | traverse(element, (node) => { 15 | node.attr('visibility', value); 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /src/util/wrap.ts: -------------------------------------------------------------------------------- 1 | import type { Text } from '../shapes'; 2 | import { applyToText } from './text'; 3 | 4 | export function wrapIt(node: Text, wordWrapWidth: number, maxLines = 2, textBaseline: string = 'top') { 5 | applyToText(node, { wordWrap: true, wordWrapWidth, maxLines, textBaseline }); 6 | } 7 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "lib", 4 | "module": "ESNext", 5 | "target": "ESNext", 6 | "jsx": "preserve", 7 | "moduleResolution": "node", 8 | "experimentalDecorators": true, 9 | "declaration": true, 10 | "sourceMap": true, 11 | "allowSyntheticDefaultImports": true, 12 | "esModuleInterop": true, 13 | "pretty": true, 14 | "lib": ["dom", "DOM.Iterable", "esnext"], 15 | "skipLibCheck": true, 16 | "baseUrl": ".", 17 | "strict": true, 18 | "importHelpers": true, 19 | "downlevelIteration": true, 20 | "noImplicitThis": false 21 | }, 22 | "include": ["src/**/*"], 23 | "exclude": ["node_modules", "examples"] 24 | } 25 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { defineConfig } from 'vite'; 3 | // eslint-disable-next-line import/no-extraneous-dependencies 4 | import react from '@vitejs/plugin-react'; 5 | 6 | export default defineConfig({ 7 | root: './__tests__/integration/', 8 | plugins: [react()], 9 | server: { 10 | port: 8080, 11 | open: '/', 12 | }, 13 | }); 14 | --------------------------------------------------------------------------------