Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: getSnapshot支持饼图 #1380

Merged
merged 1 commit into from
Mar 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/f2/src/chart/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ class Chart extends Component implements IChart, InteractionMixin {
getGeometrys() {
const { children } = this;
const geometrys: Component[] = [];
// @ts-ignore
Children.toArray(children).forEach((element) => {
if (!element) return false;
const { component } = element;
Expand Down
46 changes: 38 additions & 8 deletions packages/f2/src/components/geometry/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -433,14 +433,15 @@ class Geometry<T extends GeometryProps = GeometryProps> extends Component<T> {
return this.getAttr('y').scale;
}

_getSnap(scale, invertPointX) {
if (scale.isCategory) {
return scale.invert(invertPointX);
_getXSnap(invertPointX) {
const xScale = this.getXScale();
if (xScale.isCategory) {
return xScale.invert(invertPointX);
}

// linear 类型
const invertValue = scale.invert(invertPointX);
const values = scale.values;
const invertValue = xScale.invert(invertPointX);
const values = xScale.values;
const len = values.length;
// 如果只有1个点直接返回第1个点
if (len === 1) {
Expand All @@ -466,6 +467,24 @@ class Geometry<T extends GeometryProps = GeometryProps> extends Component<T> {
return null;
}

_getYSnapRecords(invertPointY, records) {
const yScale = this.getYScale();
const { field: yField } = yScale;
const yValue = yScale.invert(invertPointY);
// category
if (yScale.isCategory) {
return records.filter((record) => record[FIELD_ORIGIN][yField] === yValue);
}
// linear
return records.filter((record) => {
const rangeY = record[yField];
if (rangeY[0] <= yValue && rangeY[1] >= yValue) {
return true;
}
return false;
});
}

// 把 records 拍平
flatRecords() {
const { records } = this;
Expand All @@ -476,7 +495,7 @@ class Geometry<T extends GeometryProps = GeometryProps> extends Component<T> {

getSnapRecords(point) {
const { props } = this;
const { coord } = props;
const { coord, adjust } = props;
const invertPoint = coord.invertPoint(point);
const xScale = this.getXScale();
const yScale = this.getYScale();
Expand All @@ -486,14 +505,24 @@ class Geometry<T extends GeometryProps = GeometryProps> extends Component<T> {
return [];
}

const records = this.flatRecords();

// 处理饼图
if (adjust === 'stack' && coord.isPolar && coord.transposed) {
// 弧度在半径范围内
if (invertPoint.x >= 0 && invertPoint.x <= 1) {
const snapRecords = this._getYSnapRecords(invertPoint.y, records);
return snapRecords;
}
}

const rst = [];
const value = this._getSnap(xScale, invertPoint.x);
const value = this._getXSnap(invertPoint.x);
if (!value) {
return rst;
}
const { field: xField } = xScale;
const { field: yField } = yScale;
const records = this.flatRecords();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个为啥要去掉?去掉后 line 的查找好像是有问题的

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好吧,挪到上面了,看错了

for (let i = 0, len = records.length; i < len; i++) {
const record = {
...records[i],
Expand All @@ -507,6 +536,7 @@ class Geometry<T extends GeometryProps = GeometryProps> extends Component<T> {
rst.push(record);
}
}

return rst;
}

Expand Down
38 changes: 38 additions & 0 deletions packages/f2/src/coord/polar.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Base from './base';
import { Range, Option } from './types';
import { Vector2, Matrix } from '@antv/f2-graphic';

interface PolarOption extends Option {
radius: number; // 内半径比例
Expand Down Expand Up @@ -64,6 +65,43 @@ class Polar extends Base {
y: center.y + Math.sin(angle) * radius,
};
}

invertPoint(point) {
const { center, transposed, x: rangeX, y: rangeY } = this;
const x = { start: rangeX[0], end: rangeX[1] }
const y = { start: rangeY[0], end: rangeY[1] }
const xDim = transposed ? 'y' : 'x';
const yDim = transposed ? 'x' : 'y';

const m = [1, 0, 0, 1, 0, 0];
Matrix.rotate(m, m, x.start);

let startV = [1, 0];
Vector2.transformMat2d(startV, startV, m);
startV = [startV[0], startV[1]];

const pointV = [point.x - center.x, point.y - center.y];
if (Vector2.zero(pointV)) {
return {
x: 0,
y: 0
};
}

let theta = Vector2.angleTo(startV, pointV, x.end < x.start);
if (Math.abs(theta - Math.PI * 2) < 0.001) {
theta = 0;
}
const l = Vector2.length(pointV);
let percentX = theta / (x.end - x.start);
percentX = x.end - x.start > 0 ? percentX : -percentX;
const percentY = (l - y.start) / (y.end - y.start);
const rst = {};
rst[xDim] = percentX;
rst[yDim] = percentY;
return rst;
}

}

export default Polar;
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
94 changes: 91 additions & 3 deletions packages/f2/test/components/interval/example/pie.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,61 @@
import { jsx } from '../../../../src';
import { Polar, Rect } from '../../../../src/coord';
import { Canvas, Chart } from '../../../../src';
import { Interval, Legend } from '../../../../src/components';
import { createContext, delay } from '../../../util';
import { isArray } from '@antv/util';
import { Canvas, Chart, Component } from '../../../../src';
import { Interval } from '../../../../src/components';
import { createContext, delay, gestureSimulator } from '../../../util';

// @ts-ignore
class Test extends Component {
constructor(props) {
super(props);
this.state = {
record: null,
};
}
didMount() {
super.didMount();
this._initEvent();
}

_handleEvent = (ev) => {
const { chart } = this.props;
const point = ev.points[0];
const pieData = chart.getSnapRecords(point);
if (isArray(pieData) && pieData.length > 0) {
this.setState({ record: pieData[0] });
}
};

_initEvent() {
const { context } = this;
const { canvas } = context;
canvas.on('click', this._handleEvent);
}

render() {
if (!this.state.record) {
return null;
}
const { record } = this.state;
const { coord } = this.props;
const { x, y } = coord?.center;
const { radius } = coord;

const { xMax, xMin } = record;
return (
<text
attrs={{
text: record.origin.name,
x: x + radius * Math.cos(xMin + (xMax - xMin) / 2),
y: y + radius * Math.sin(xMin + (xMax - xMin) / 2),
fill: '#000',
fontSize: '22px',
}}
/>
);
}
}

const data = [
{
Expand Down Expand Up @@ -70,4 +123,39 @@ describe('饼图', () => {
await delay(1000);
expect(context).toMatchImageSnapshot();
});

it('饼图-交互式label', async () => {
const context = createContext('饼图-交互式label');
const chartRef = { current: null };
const { type, props } = (
<Canvas context={context} pixelRatio={1}>
<Chart
ref={chartRef}
data={data}
coord={{
type: Polar,
transposed: true,
}}
>
<Interval
x="a"
y="percent"
adjust="stack"
color={{
field: 'name',
range: ['#1890FF', '#13C2C2', '#2FC25B', '#FACC14', '#F04864', '#8543E0'],
}}
/>
<Test />
</Chart>
</Canvas>
);

const canvas = new Canvas(props);
canvas.render();

await gestureSimulator(context.canvas, 'click', { x: 205, y: 76 });
await delay(1000);
expect(context).toMatchImageSnapshot();
});
});