1 | import { deepMix, isFunction, isNil, mix } from '@antv/util';
|
2 | import { jsx } from '../../jsx';
|
3 | import Geometry from '../geometry';
|
4 | import * as LabelViews from './label';
|
5 |
|
6 | export default (Views) => {
|
7 | return class Interval extends Geometry {
|
8 | getDefaultCfg() {
|
9 | return {
|
10 | geomType: 'interval',
|
11 | justifyContent: true,
|
12 | startOnZero: true,
|
13 | };
|
14 | }
|
15 |
|
16 | getDefaultSize() {
|
17 | const { attrs, props, adjust, records } = this;
|
18 | const { coord, sizeRatio } = props;
|
19 | const { x } = attrs;
|
20 | const { scale } = x;
|
21 | const { values } = scale;
|
22 |
|
23 | if (sizeRatio) {
|
24 | return (1 / values.length) * sizeRatio;
|
25 | }
|
26 |
|
27 | const defaultWithRatio = {
|
28 | column: 1 / 2,
|
29 | rose: 0.999999,
|
30 | multiplePie: 3 / 4,
|
31 | };
|
32 |
|
33 | const count = values.length;
|
34 |
|
35 | let ratio;
|
36 | if (coord.isPolar) {
|
37 | if (coord.transposed && count > 1) {
|
38 | ratio = defaultWithRatio.multiplePie;
|
39 | } else {
|
40 | ratio = defaultWithRatio.rose;
|
41 | }
|
42 | } else {
|
43 | ratio = defaultWithRatio.column;
|
44 | }
|
45 |
|
46 | const size = (1 / values.length) * ratio;
|
47 |
|
48 |
|
49 | if (adjust && adjust.type === 'dodge') {
|
50 | return size / records.length;
|
51 | }
|
52 |
|
53 | return size;
|
54 | }
|
55 |
|
56 | mapping() {
|
57 | const records = super.mapping();
|
58 |
|
59 | const { props } = this;
|
60 | const { coord } = props;
|
61 | const y0 = this.getY0Value();
|
62 | const defaultSize = this.getDefaultSize();
|
63 |
|
64 | for (let i = 0, len = records.length; i < len; i++) {
|
65 | const record = records[i];
|
66 | const { children } = record;
|
67 | for (let j = 0, len = children.length; j < len; j++) {
|
68 | const child = children[j];
|
69 | const { normalized, size: mappedSize } = child;
|
70 |
|
71 |
|
72 | if (isNil(mappedSize)) {
|
73 | const { x, y, size = defaultSize } = normalized;
|
74 | mix(child, coord.convertRect({ x, y, y0, size }));
|
75 | } else {
|
76 | const { x, y } = child;
|
77 | const rect = { size: mappedSize, x, y, y0 };
|
78 | mix(child, coord.transformToRect(rect));
|
79 | }
|
80 |
|
81 | mix(child.shape, this.getSelectionStyle(child));
|
82 | }
|
83 | }
|
84 | return records;
|
85 | }
|
86 |
|
87 |
|
88 | getPointY0() {
|
89 | const { props } = this;
|
90 | const { coord } = props;
|
91 | const y0 = this.getY0Value();
|
92 | const y0Point = coord.convertPoint({ y: y0, x: 0 });
|
93 | return y0Point?.y;
|
94 | }
|
95 |
|
96 | render() {
|
97 | const { props, state, container } = this;
|
98 | const { coord, shape = 'rect', animation, showLabel, labelCfg: customLabelCfg } = props;
|
99 | const View = isFunction(Views) ? Views : Views[shape];
|
100 | const LabelView = LabelViews[shape];
|
101 | const labelCfg = deepMix(
|
102 | {
|
103 | label: null,
|
104 | offsetX: 0,
|
105 | offsetY: 0,
|
106 | },
|
107 | customLabelCfg
|
108 | );
|
109 |
|
110 | if (!View) return null;
|
111 | const { selected } = state;
|
112 |
|
113 | const records = this.mapping();
|
114 | const pointY0 = this.getPointY0();
|
115 | const clip = this.getClip();
|
116 | return (
|
117 | <View
|
118 | coord={coord}
|
119 | records={records}
|
120 | selected={selected}
|
121 | shape={shape}
|
122 | animation={animation}
|
123 | showLabel={showLabel}
|
124 | labelCfg={labelCfg}
|
125 | LabelView={LabelView}
|
126 | y0={pointY0}
|
127 | clip={clip}
|
128 | />
|
129 | );
|
130 | }
|
131 | };
|
132 | };
|