UNPKG

3 kBTypeScriptView Raw
1import { jsx } from '../../jsx';
2import Component from '../../base/component';
3import { partition, hierarchy } from '../../deps/d3-hierarchy/src';
4import { Category } from '../../attr';
5import { isInBBox } from '../../util';
6import CoordController from '../../controller/coord';
7import { mix, isFunction } from '@antv/util';
8import Coord from '../../coord';
9import { Ref } from '../../types';
10
11function rootParent(data) {
12 let d = data;
13 while (d.depth > 1) {
14 d = d.parent;
15 }
16 return d;
17}
18
19export default (View) => {
20 return class Sunburst extends Component {
21 coordController: CoordController;
22 coord: Coord;
23 color: Category;
24 triggerRef: Ref[];
25
26 constructor(props, context) {
27 super(props, context);
28 const { coord, color, data } = props;
29 const { width, height, theme } = context;
30
31 this.coordController = new CoordController();
32
33 const { coordController } = this;
34 this.coord = coordController.create(coord, { width, height });
35 this.color = new Category({
36 range: theme.colors,
37 ...color,
38 data,
39 });
40 }
41
42 didMount() {
43 const { props, container } = this;
44 const { onClick } = props;
45 const canvas = container.get('canvas');
46
47 this.triggerRef = [];
48
49 canvas.on('click', (ev) => {
50 const { points } = ev;
51 const shape = this.triggerRef.find((ref) => {
52 return isInBBox(ref.current.getBBox(), points[0]);
53 });
54 if (shape) {
55 ev.shape = shape;
56 // @ts-ignore
57 ev.payload = shape.payload;
58 onClick && onClick(ev);
59 }
60 });
61 }
62
63 _mapping(children) {
64 const { color: colorAttr, coord } = this;
65 for (let i = 0, len = children.length; i < len; i++) {
66 const node = children[i];
67 const root = rootParent(node);
68 const color = colorAttr.mapping(root.data[colorAttr.field]);
69 node.color = color;
70 const { x0, x1, y0, y1 } = node;
71 const rect = coord.convertRect({
72 x: [x0, x1],
73 y: [y0, y1],
74 });
75 mix(node, rect);
76 // 递归处理
77 if (node.children && node.children.length) {
78 this._mapping(node.children);
79 }
80 }
81 }
82
83 sunburst() {
84 const { props } = this;
85 const { data, value, sort = true } = props;
86
87 const root = hierarchy({ children: data }).sum(function(d) {
88 return d[value];
89 });
90
91 // 内置按value大小顺序排序,支持传入sort函数
92 if (sort === true || isFunction(sort)) {
93 const sortFn = isFunction(sort) ? sort : (a, b) => b[value] - a[value];
94 root.sort(sortFn);
95 }
96
97 const nodes = partition()(root);
98 const { children } = nodes;
99 this._mapping(children);
100 return nodes;
101 }
102
103 render() {
104 const node = this.sunburst();
105 const { coord, props } = this;
106 return <View {...props} coord={coord} node={node} triggerRef={this.triggerRef} />;
107 }
108 };
109};