Skip to content

Commit f5c2a1d

Browse files
author
xuying.xu
committed
feat: 增加elementLink
1 parent ce0c8d7 commit f5c2a1d

File tree

13 files changed

+367
-21
lines changed

13 files changed

+367
-21
lines changed

packages/f2/src/chart/index.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
Ref,
1010
createRef,
1111
} from '@antv/f-engine';
12+
import Selection, { SelectionProps, SelectionState } from '../components/geometry/selection';
1213
import { ScaleConfig } from '../deps/f2-scale/src';
1314
import { each, findIndex, isArray, deepMix } from '@antv/util';
1415
import CoordController, { Coord } from '../controller/coord';
@@ -19,7 +20,7 @@ import { CoordType, CoordProps } from './Coord';
1920

2021
export { Point } from './types';
2122

22-
export interface ChartProps<TRecord extends DataRecord = DataRecord> {
23+
export interface ChartProps<TRecord extends DataRecord = DataRecord> extends SelectionProps {
2324
data: Data<TRecord>;
2425
scale?: DataRecordScale<TRecord>;
2526
coord?: CoordType | CoordProps;
@@ -54,7 +55,7 @@ export interface ComponentPosition {
5455
class Chart<
5556
TRecord extends DataRecord = DataRecord,
5657
IProps extends ChartProps<TRecord> = ChartProps<TRecord>
57-
> extends Component<IProps, ChartState> {
58+
> extends Selection<IProps, SelectionState & ChartState> {
5859
// 坐标系
5960
private componentsPosition: ComponentPosition[] = [];
6061

@@ -65,7 +66,7 @@ class Chart<
6566
public adjust: any;
6667
public coordRef: Ref;
6768
constructor(props: IProps, context?: IContext) {
68-
super(props);
69+
super(props, context);
6970

7071
const { theme, px2hd } = context;
7172

@@ -81,6 +82,7 @@ class Chart<
8182
// state
8283
this.state = {
8384
filters: {},
85+
selected: [],
8486
};
8587
}
8688

@@ -112,8 +114,12 @@ class Chart<
112114
coord.create(coordOption);
113115
}
114116

117+
didMount(): void {
118+
super.didMount();
119+
}
120+
115121
// props 更新
116-
willReceiveProps(nextProps: IProps, context) {
122+
willReceiveProps(nextProps: IProps, context?: IContext) {
117123
const { scale, coord, props: lastProps } = this;
118124
const { style: nextStyle, data: nextData, scale: nextScale } = nextProps;
119125
const { style: lastStyle, data: lastData, scale: lastScale } = lastProps;
@@ -331,6 +337,7 @@ class Chart<
331337
...filters,
332338
[field]: condition,
333339
},
340+
selected: this.state.selected || [],
334341
});
335342
}
336343

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { jsx } from '@antv/f-engine';
2+
3+
export default (props) => {
4+
const { elements, color } = props;
5+
const topPoints = [];
6+
const bottomPoints = [];
7+
8+
elements.map((d) => {
9+
const { min, max } = d.shape.getBounds();
10+
topPoints.push([min[0], min[1]]);
11+
topPoints.push([max[0], min[1]]);
12+
bottomPoints.push([min[0], max[1]]);
13+
bottomPoints.push([max[0], max[1]]);
14+
});
15+
16+
// 将上边的点和下边的点连接起来,形成一个多边形
17+
const points = [...topPoints, ...bottomPoints.reverse()];
18+
19+
return (
20+
<group>
21+
<polygon
22+
style={{
23+
points,
24+
fill: color,
25+
stroke: 'none',
26+
opacity: 0.4,
27+
}}
28+
/>
29+
</group>
30+
);
31+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import withElementLink, { ElementLinkProps } from './withElementLink';
2+
import elementLinkView from './elementLinkView';
3+
4+
export { ElementLinkProps, withElementLink, elementLinkView };
5+
export default withElementLink(elementLinkView);
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { jsx, Component, Children } from '@antv/f-engine';
2+
import { ChartChildProps } from '../../chart';
3+
export interface DataRecord {
4+
origin: any;
5+
[k: string]: any;
6+
}
7+
8+
export interface ElementLinkProps {
9+
[k: string]: any;
10+
}
11+
export interface ElementLinkState {
12+
selected: any[];
13+
}
14+
15+
export default (View) => {
16+
return class ElementLink<IProps extends ElementLinkProps & ElementLinkProps> extends Component<
17+
IProps & ChartChildProps,
18+
ElementLinkState
19+
> {
20+
constructor(props: IProps & ChartChildProps) {
21+
super(props);
22+
this.state = {
23+
selected: [],
24+
};
25+
}
26+
27+
findAllShapeNode(vNode, value) {
28+
if (!value) return [];
29+
30+
const shapeNodes = [];
31+
Children.map(vNode, (node) => {
32+
if (!node) return;
33+
const { key, children } = node;
34+
if (key === value) {
35+
shapeNodes.push(...children);
36+
}
37+
if (children) {
38+
shapeNodes.push(...this.findAllShapeNode(children, value));
39+
}
40+
});
41+
return shapeNodes;
42+
}
43+
44+
render() {
45+
const { props } = this;
46+
const { chart, field } = props;
47+
const { selected } = chart.state;
48+
const geometry = props.chart.getGeometrys()[0];
49+
50+
if (!selected || !selected.length) return null;
51+
const value = selected[0][field];
52+
53+
const elements = this.findAllShapeNode(geometry, value);
54+
55+
const colorController = geometry.getAttr('color');
56+
const color = colorController.mapping(value);
57+
return <View color={color} elements={elements} {...props} />;
58+
}
59+
};
60+
};

packages/f2/src/components/geometry/index.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -778,9 +778,12 @@ class Geometry<
778778
const records = this.flatRecords();
779779
const xScale = this.getXScale();
780780
const yScale = this.getYScale();
781+
const colorScale = this.getColorScale();
781782
const { field: xField } = xScale;
782783
const { field: yField } = yScale;
783-
const value = data[xField];
784+
const { field: colorField } = colorScale;
785+
const fieldValue = field === 'xfield' ? xField : field === 'colorField' ? colorField : yField;
786+
const value = data[fieldValue];
784787
const rst = [];
785788

786789
for (let i = 0, len = records.length; i < len; i++) {
@@ -789,7 +792,7 @@ class Geometry<
789792
xField,
790793
yField,
791794
};
792-
const originValue = record[FIELD_ORIGIN][field === 'xfield' ? xField : yField];
795+
const originValue = record[FIELD_ORIGIN][fieldValue];
793796
if (originValue === value) {
794797
rst.push(record);
795798
}

packages/f2/src/components/geometry/selection.ts

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { isFunction } from '@antv/util';
22
import { Component, isEqual as equal, ShapeStyleProps } from '@antv/f-engine';
3-
import { ChartChildProps } from '../../chart';
3+
import Chart, { ChartChildProps, ChartProps } from '../../chart';
44

55
function isEqual(origin1, origin2, fields: string[]) {
66
if (origin1 === origin2) {
@@ -26,6 +26,7 @@ export interface SelectionProps {
2626
unSelectedStyle?: ShapeStyleProps | StyleType;
2727
cancelable?: boolean;
2828
onChange?: Function;
29+
mode: 'element-link' | 'element' | 'point';
2930
};
3031
}
3132

@@ -36,7 +37,7 @@ export interface SelectionState {
3637
class Selection<
3738
P extends SelectionProps = SelectionProps,
3839
S extends SelectionState = SelectionState
39-
> extends Component<P & ChartChildProps, S> {
40+
> extends Component<P & (ChartChildProps | ChartProps), S> {
4041
constructor(props: P, context) {
4142
super(props, context);
4243

@@ -46,21 +47,47 @@ class Selection<
4647
this.state.selected = defaultSelected;
4748
}
4849

50+
getElementRecord(shape) {
51+
const origin = shape.get('data') || {};
52+
return [
53+
{
54+
origin,
55+
},
56+
];
57+
}
58+
59+
getLinkRecord(shape, chart) {
60+
const origin = shape.get('data') || {};
61+
62+
const records = chart.getRecords(origin, 'colorField');
63+
64+
return records;
65+
}
66+
67+
getSelectRecords(ev, triggerOn, mode: string, chart) {
68+
const { points, canvasX: x, canvasY: y } = ev;
69+
const point = triggerOn === 'click' ? { x, y } : points[0];
70+
if (mode === 'element') return this.getElementRecord(ev.target);
71+
if (mode === 'element-link') return this.getLinkRecord(ev.target, chart);
72+
return this.getSnapRecords(point);
73+
}
74+
4975
didMount() {
5076
const { props, state } = this;
51-
const { selection, chart } = props;
77+
const { selection } = props;
5278
if (!selection) return;
5379
// 默认为 click
54-
const { triggerOn = 'click', onChange } = selection;
80+
const { triggerOn = 'click', onChange, mode } = selection;
81+
// 监听在整个画布上,适用于折线图。
82+
const chart = (props.chart || this) as Chart; // 添加类型断言
5583
chart.on(triggerOn, (ev) => {
56-
const { points, canvasX: x, canvasY: y } = ev;
57-
const point = triggerOn === 'click' ? { x, y } : points[0];
58-
const records = this.getSnapRecords(point);
84+
const records = this.getSelectRecords(ev, triggerOn, mode, chart);
85+
5986
const { type = 'single', cancelable = true } = selection;
6087

6188
if (!records || !records.length) {
6289
if (cancelable) {
63-
onChange && onChange({ selected: null })
90+
onChange && onChange({ selected: null });
6491
this.setState({
6592
selected: null,
6693
} as S);
@@ -71,15 +98,15 @@ class Selection<
7198
const { selected } = state;
7299
const origins = records.map((record) => record.origin);
73100
if (!selected || !selected.length) {
74-
onChange && onChange({ selected: origins })
101+
onChange && onChange({ selected: origins });
75102
this.setState({
76103
selected: origins,
77104
} as S);
78105
}
79106

80107
if (type === 'single') {
81108
if (!cancelable) {
82-
onChange && onChange({ selected: origins })
109+
onChange && onChange({ selected: origins });
83110
this.setState({
84111
selected: origins,
85112
} as S);
@@ -91,7 +118,7 @@ class Selection<
91118
newSelected.push(record.origin);
92119
}
93120
});
94-
onChange && onChange({ selected: newSelected })
121+
onChange && onChange({ selected: newSelected });
95122
this.setState({
96123
selected: newSelected,
97124
} as S);
@@ -116,7 +143,7 @@ class Selection<
116143
.map((key) => selectedMap[key])
117144
.filter(Boolean);
118145

119-
onChange && onChange({ selected: newSelected })
146+
onChange && onChange({ selected: newSelected });
120147
this.setState({
121148
selected: newSelected,
122149
} as S);
@@ -146,7 +173,7 @@ class Selection<
146173
if (!selected || !selected.length) {
147174
return false;
148175
}
149-
const { chart } = props;
176+
const chart = (props.chart || this) as Chart;
150177
const scales = chart.getScales();
151178
const fields = Object.keys(scales);
152179
for (let i = 0, len = selected.length; i < len; i++) {

packages/f2/src/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ export {
3333
CandlestickView,
3434
} from './candlestick';
3535
export { default as Pictorial, PictorialProps } from './pictorial';
36+
export { default as ElementLink } from './elementLink';

packages/f2/src/components/interval/view/rect.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ export default (props) => {
1414
return (
1515
<group key={key}>
1616
{children.map((item) => {
17-
const { key, xMin, xMax, yMin, yMax, color, shape } = item;
17+
const { key, xMin, xMax, yMin, yMax, color, shape, origin } = item;
1818
if (isNaN(xMin) || isNaN(xMax) || isNaN(yMin) || isNaN(yMax)) {
1919
return null;
2020
}
2121
return (
2222
<rect
2323
key={key}
24+
data={origin}
2425
attrs={{
2526
x: xMin,
2627
y: yMin,

packages/f2/src/components/interval/withInterval.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ export default (Views) => {
9898
mix(child, coord.transformToRect(rect));
9999
}
100100

101-
mix(child.shape, this.getSelectionStyle(child));
101+
mix(child.shape, this.props.chart.getSelectionStyle(child));
102102
}
103103
}
104104
return records;
14 KB
Loading

0 commit comments

Comments
 (0)