Skip to content

Commit

Permalink
Merge pull request #1365 from VisActor/feat/circle-axis-polygon
Browse files Browse the repository at this point in the history
Feat/circle axis polygon
  • Loading branch information
xile611 authored Aug 13, 2024
2 parents 9541ac8 + 34eb182 commit 4bcb042
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 80 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "feat: support polygon of circle-axis\n\n",
"type": "none",
"packageName": "@visactor/vrender-components"
}
],
"packageName": "@visactor/vrender-components",
"email": "[email protected]"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "feat: support polygon of circle-axis\n\n",
"type": "none",
"packageName": "@visactor/vrender-core"
}
],
"packageName": "@visactor/vrender-core",
"email": "[email protected]"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "feat: support polygon of circle-axis\n\n",
"type": "none",
"packageName": "@visactor/vrender"
}
],
"packageName": "@visactor/vrender",
"email": "[email protected]"
}
55 changes: 28 additions & 27 deletions packages/vrender-components/src/axis/animate/group-transition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,34 +70,35 @@ export class GroupTransition extends ACustomAnimate<any> {
let easing = this.easing;

// 新的场景树
Object.keys(this._newElementAttrMap).forEach(id => {
const { node, attrs, state } = this._newElementAttrMap[id];
if (state === 'enter') {
const { enter = {} } = this.params ?? {};
duration = isValidNumber(enter.duration) ? enter.duration : duration;
easing = enter.easing ? enter.easing : easing;
}
if ((node as IGraphic).type === 'path') {
(node as IGraphic)
.animate({
interpolate(key: string, ratio: number, from: any, to: any, nextAttributes: any) {
if (key === 'path') {
nextAttributes.path = interpolateString(from, to)(ratio);
return true;
}
this._newElementAttrMap &&
Object.keys(this._newElementAttrMap).forEach(id => {
const { node, attrs, state } = this._newElementAttrMap[id];
if (state === 'enter') {
const { enter = {} } = this.params ?? {};
duration = isValidNumber(enter.duration) ? enter.duration : duration;
easing = enter.easing ? enter.easing : easing;
}
if ((node as IGraphic).type === 'path') {
(node as IGraphic)
.animate({
interpolate(key: string, ratio: number, from: any, to: any, nextAttributes: any) {
if (key === 'path') {
nextAttributes.path = interpolateString(from, to)(ratio);
return true;
}

return false;
}
})
// .wait(delay)
.to(attrs, duration, easing as EasingType);
} else {
(node as IGraphic)
.animate()
// .wait(delay)
.to(attrs, duration, easing as EasingType);
}
});
return false;
}
})
// .wait(delay)
.to(attrs, duration, easing as EasingType);
} else {
(node as IGraphic)
.animate()
// .wait(delay)
.to(attrs, duration, easing as EasingType);
}
});
}

onUpdate(end: boolean, ratio: number, out: Record<string, any>): void {
Expand Down
53 changes: 36 additions & 17 deletions packages/vrender-components/src/axis/circle.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
/**
* @description 圆弧型坐标轴
*/
import type { IGroup, IText, ITextGraphicAttribute, TextAlignType, TextBaselineType } from '@visactor/vrender-core';
import type {
IGraphic,
IGroup,
IText,
ITextGraphicAttribute,
TextAlignType,
TextBaselineType
} from '@visactor/vrender-core';
// eslint-disable-next-line no-duplicate-imports
import { graphicCreator } from '@visactor/vrender-core';
// eslint-disable-next-line no-duplicate-imports
import type { Point } from '@visactor/vutils';
import { isNil, get, merge, isNumberClose, isEmpty, mixin } from '@visactor/vutils';
import { isNil, get, merge, isNumberClose, isEmpty, mixin, isValidNumber } from '@visactor/vutils';
import { POLAR_END_ANGLE, POLAR_START_ANGLE } from '../constant';
import type { CircleAxisAttributes, TitleAttributes, SubTickAttributes, TickLineItem, AxisItem } from './type';
import { AxisBase } from './base';
import { DEFAULT_AXIS_THEME } from './config';
import { AXIS_ELEMENT_NAME, DEFAULT_STATES } from './constant';
import { CircleAxisMixin } from './mixin/circle';
import { getCircleLabelPosition } from './util';
import { getCircleLabelPosition, getCirclePoints, getPolygonPath } from './util';
import type { ComponentOptions } from '../interface';
import { loadCircleAxisComponent } from './register';

Expand All @@ -37,7 +44,8 @@ export class CircleAxis extends AxisBase<CircleAxisAttributes> {
center,
innerRadius = 0,
line = {},
inside = false
inside = false,
sides
} = this.attribute as CircleAxisAttributes;

let arcRadius = radius;
Expand All @@ -47,22 +55,33 @@ export class CircleAxis extends AxisBase<CircleAxisAttributes> {
arcInnerRadius = 0;
}

const arcAttrs = {
...center,
startAngle,
endAngle,
radius: arcRadius,
innerRadius: arcInnerRadius,
...line.style
};
const axisLine = graphicCreator.circle(arcAttrs);
axisLine.name = AXIS_ELEMENT_NAME.line;
axisLine.id = this._getNodeId('line');
let lineGraphic: IGraphic;
if (isValidNumber(sides) && sides >= 3) {
const gridPoints = getCirclePoints(center as Point, sides as number, arcRadius, startAngle, endAngle);

lineGraphic = graphicCreator.path({
...line.style,
path: getPolygonPath(gridPoints, true)
});
} else {
const arcAttrs = {
...center,
startAngle,
endAngle,
radius: arcRadius,
innerRadius: arcInnerRadius,
...line.style
};
lineGraphic = graphicCreator.circle(arcAttrs);
}

lineGraphic.name = AXIS_ELEMENT_NAME.line;
lineGraphic.id = this._getNodeId('line');

if (!isEmpty(line.state)) {
axisLine.states = merge({}, DEFAULT_STATES, line.state);
lineGraphic.states = merge({}, DEFAULT_STATES, line.state);
}
container.add(axisLine);
container.add(lineGraphic);
}

protected getTitleAttribute() {
Expand Down
33 changes: 7 additions & 26 deletions packages/vrender-components/src/axis/grid/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,7 @@ import type { Point } from '../../core/type';
import type { GridItem, CircleGridAttributes, GridBaseAttributes, GridAttributes, LineGridAttributes } from './type';
import type { AxisItem, TransformedAxisItem } from '../type';
import { AXIS_ELEMENT_NAME } from '../constant';
import { getElMap, getVerticalCoord } from '../util';

function getLinePath(points: Point[], closed: boolean) {
let path = '';
if (points.length === 0) {
return path;
}
points.forEach((point, index) => {
if (index === 0) {
path = `M${point.x},${point.y}`;
} else {
path += `L${point.x},${point.y}`;
}
});
if (closed) {
path += 'Z';
}

return path;
}
import { getElMap, getPolygonPath, getVerticalCoord } from '../util';

function getArcPath(center: Point, points: Point[], reverse: boolean, closed: boolean) {
let path = '';
Expand Down Expand Up @@ -68,8 +49,8 @@ function getRegionPath(from: Point[], to: Point[], attribute: GridAttributes) {
const toEnd = reversePoints[0];
const center = (attribute as LineGridAttributes).center as Point;

regionPath = getLinePath(from, !!closed);
nextPath = getLinePath(reversePoints, !!closed);
regionPath = getPolygonPath(from, !!closed);
nextPath = getPolygonPath(reversePoints, !!closed);
const toEndRadius = PointService.distancePP(toEnd, center);
const fromStartRadius = PointService.distancePP(fromStart, center);
regionPath += `A${toEndRadius},${toEndRadius},0,0,1,${toEnd.x},${toEnd.y}L${toEnd.x},${toEnd.y}`;
Expand All @@ -79,8 +60,8 @@ function getRegionPath(from: Point[], to: Point[], attribute: GridAttributes) {
regionPath = getArcPath(center, from, false, !!closed);
nextPath = getArcPath(center, reversePoints, true, !!closed);
} else if (type === 'line' || type === 'polygon') {
regionPath = getLinePath(from, !!closed);
nextPath = getLinePath(reversePoints, !!closed);
regionPath = getPolygonPath(from, !!closed);
nextPath = getPolygonPath(reversePoints, !!closed);
}

if (closed) {
Expand Down Expand Up @@ -186,7 +167,7 @@ export abstract class BaseGrid<T extends GridBaseAttributes> extends AbstractCom
const { id, points } = item;
let path = '';
if (type === 'line' || type === 'polygon') {
path = getLinePath(points, !!closed);
path = getPolygonPath(points, !!closed);
} else if (type === 'circle') {
const { center } = this.attribute as unknown as CircleGridAttributes;
path = getArcPath(center, points, false, !!closed);
Expand Down Expand Up @@ -214,7 +195,7 @@ export abstract class BaseGrid<T extends GridBaseAttributes> extends AbstractCom
const dirLen = Math.sqrt(dir.x * dir.x + dir.y * dir.y);
const ratio = depth / dirLen;
nextPoints.push({ x: points[0].x + dir.x * ratio, y: points[0].y + dir.y * ratio });
const path = getLinePath(nextPoints, !!closed);
const path = getPolygonPath(nextPoints, !!closed);
const deltaX = abs(nextPoints[0].x - nextPoints[1].x);
const deltaY = abs(nextPoints[0].y - nextPoints[1].y);
const shape = graphicCreator.path({
Expand Down
11 changes: 1 addition & 10 deletions packages/vrender-components/src/axis/grid/line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,7 @@ import type { TransformedAxisItem } from '../type';
import { LineAxisMixin } from '../mixin/line';
import type { ComponentOptions } from '../../interface';
import { loadLineAxisGridComponent } from '../register';

function getCirclePoints(center: Point, count: number, radius: number, startAngle: number, endAngle: number) {
const points: Point[] = [];
const range = endAngle - startAngle;
for (let i = 0; i < count; i++) {
const angle = startAngle + (i * range) / count;
points.push(polarToCartesian(center, radius, angle));
}
return points;
}
import { getCirclePoints } from '../util';

export interface LineAxisGrid
extends Pick<LineAxisMixin, 'isInValidValue' | 'getTickCoord' | 'getVerticalVector'>,
Expand Down
5 changes: 5 additions & 0 deletions packages/vrender-components/src/axis/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ export interface CircleAxisAttributes extends AxisBaseAttributes {
radius: number;
/** 内半径 */
innerRadius?: number;
/**
* 边数
* @since 0.19.24
*/
sides?: number;
}

// 坐标轴标题配置
Expand Down
29 changes: 29 additions & 0 deletions packages/vrender-components/src/axis/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,32 @@ export function getPolarAngleLabelPosition(
const vector = getCircleVerticalVector(labelOffset || 1, labelPoint, center, inside);
return getCircleLabelPosition(labelPoint, vector, text, style);
}

export function getCirclePoints(center: Point, count: number, radius: number, startAngle: number, endAngle: number) {
const points: Point[] = [];
const range = endAngle - startAngle;
for (let i = 0; i < count; i++) {
const angle = startAngle + (i * range) / count;
points.push(polarToCartesian(center, radius, angle));
}
return points;
}

export function getPolygonPath(points: Point[], closed: boolean) {
let path = '';
if (points.length === 0) {
return path;
}
points.forEach((point, index) => {
if (index === 0) {
path = `M${point.x},${point.y}`;
} else {
path += `L${point.x},${point.y}`;
}
});
if (closed) {
path += 'Z';
}

return path;
}

0 comments on commit 4bcb042

Please sign in to comment.