UNPKG

9.65 kBJavaScriptView Raw
1import { __assign, __extends } from "tslib";
2import { isEqual, Component, Children, jsx, createRef } from '@antv/f-engine';
3import { each, findIndex, isArray, deepMix } from '@antv/util';
4import CoordController from '../controller/coord';
5import ScaleController from '../controller/scale';
6import Theme from '../theme';
7// 统计图表
8var Chart = /** @class */function (_super) {
9 __extends(Chart, _super);
10 function Chart(props, context) {
11 var _this = _super.call(this, props) || this;
12 // 坐标系
13 _this.componentsPosition = [];
14 var theme = context.theme,
15 px2hd = context.px2hd;
16 // hack 处理,设置默认的主题样式
17 // 目前没想到其他更合适的方式,只能先这样处理
18 context.theme = deepMix(px2hd(Theme), theme);
19 var data = props.data;
20 _this.scale = new ScaleController(data);
21 _this.coord = new CoordController();
22 _this.coordRef = createRef();
23 // state
24 _this.state = {
25 filters: {}
26 };
27 return _this;
28 }
29 Chart.prototype.getStyle = function (props) {
30 var _a = this,
31 context = _a.context,
32 layout = _a.layout;
33 var theme = context.theme,
34 px2hd = context.px2hd;
35 var left = layout.left,
36 top = layout.top,
37 width = layout.width,
38 height = layout.height;
39 var customStyle = props.style;
40 return px2hd(__assign(__assign({
41 left: left,
42 top: top,
43 width: width,
44 height: height
45 }, theme.chart), customStyle));
46 };
47 Chart.prototype.willMount = function () {
48 var _a = this,
49 props = _a.props,
50 coord = _a.coord,
51 scale = _a.scale;
52 var scaleOptions = props.scale,
53 coordOption = props.coord;
54 this.resetCoordLayout();
55 // 初始化 scale
56 scale.create(scaleOptions);
57 // 初始化 coord
58 coord.create(coordOption);
59 };
60 // props 更新
61 Chart.prototype.willReceiveProps = function (nextProps, context) {
62 var _a = this,
63 scale = _a.scale,
64 coord = _a.coord,
65 lastProps = _a.props;
66 var nextStyle = nextProps.style,
67 nextData = nextProps.data,
68 nextScale = nextProps.scale;
69 var lastStyle = lastProps.style,
70 lastData = lastProps.data,
71 lastScale = lastProps.scale;
72 // style 更新
73 if (!isEqual(nextStyle, lastStyle) || context !== this.context) {
74 var style = this.getStyle(nextProps);
75 coord.updateLayout(style);
76 }
77 if (nextData !== lastData) {
78 scale.changeData(nextData);
79 }
80 // scale
81 if (!isEqual(nextScale, lastScale)) {
82 scale.update(nextScale);
83 }
84 };
85 Chart.prototype.willUpdate = function () {
86 this.coord.create(this.props.coord);
87 };
88 Chart.prototype.on = function (eventName, listener) {
89 var roolEl = this.coordRef.current;
90 if (!roolEl || !roolEl.gesture) return;
91 var gesture = roolEl.gesture;
92 gesture.on(eventName, listener);
93 };
94 Chart.prototype.off = function (eventName, listener) {
95 var roolEl = this.coordRef.current;
96 if (!roolEl || !roolEl.gesture) return;
97 var gesture = roolEl.gesture;
98 gesture.off(eventName, listener);
99 };
100 // 给需要显示的组件留空
101 Chart.prototype.layoutCoord = function (layout) {
102 this.coord.useLayout(layout);
103 };
104 Chart.prototype.resetCoordLayout = function () {
105 var _a = this,
106 coord = _a.coord,
107 props = _a.props;
108 var style = this.getStyle(props);
109 coord.updateLayout(style);
110 };
111 Chart.prototype.updateCoordLayout = function (layout) {
112 var _this = this;
113 if (isArray(layout)) {
114 layout.forEach(function (item) {
115 _this.layoutCoord(item);
116 });
117 return;
118 }
119 this.layoutCoord(layout);
120 };
121 Chart.prototype.updateCoordFor = function (component, layout) {
122 var _this = this;
123 if (!layout) return;
124 var componentsPosition = this.componentsPosition;
125 var componentPosition = {
126 component: component,
127 layout: layout
128 };
129 var existIndex = findIndex(componentsPosition, function (item) {
130 return item.component === component;
131 });
132 // 说明是已经存在的组件
133 if (existIndex > -1) {
134 componentsPosition.splice(existIndex, 1, componentPosition);
135 // 先重置,然后整体重新算一次
136 this.resetCoordLayout();
137 // 再整体计算前,需要去掉已经销毁的组件
138 this.removeComponentsPositionCache();
139 componentsPosition.forEach(function (componentPosition) {
140 var layout = componentPosition.layout;
141 _this.updateCoordLayout(layout);
142 });
143 return;
144 }
145 // 是新组件,直接添加
146 componentsPosition.push(componentPosition);
147 this.updateCoordLayout(layout);
148 };
149 Chart.prototype.removeComponentsPositionCache = function () {
150 var _a;
151 if (!((_a = this.componentsPosition) === null || _a === void 0 ? void 0 : _a.length)) return;
152 for (var i = this.componentsPosition.length; i > -1; i--) {
153 var item = this.componentsPosition[i];
154 if (item && item.component && item.component.destroyed) {
155 this.componentsPosition.splice(i, 1);
156 }
157 }
158 };
159 Chart.prototype.getGeometrys = function () {
160 // @ts-ignore
161 var children = this.children.children;
162 var geometrys = [];
163 Children.toArray(children).forEach(function (element) {
164 if (!element) return false;
165 var component = element.component;
166 // @ts-ignore
167 if (component && component.isGeometry) {
168 geometrys.push(component);
169 }
170 });
171 return geometrys;
172 };
173 /**
174 * calculate dataset's position on canvas
175 * @param {Object} record the dataset
176 * @return {Object} return the position
177 */
178 Chart.prototype.getPosition = function (record) {
179 var coord = this.getCoord();
180 var xScale = this.getXScales()[0];
181 var xField = xScale.field;
182 var yScales = this.getYScales();
183 // default first
184 var yScale = yScales[0];
185 var yField = yScale.field;
186 for (var i = 0, len = yScales.length; i < len; i++) {
187 var scale = yScales[i];
188 var field = scale.field;
189 if (record[field]) {
190 yScale = scale;
191 yField = field;
192 break;
193 }
194 }
195 var x = xScale.scale(record[xField]);
196 var y = yScale.scale(record[yField]);
197 return coord.convertPoint({
198 x: x,
199 y: y
200 });
201 };
202 Chart.prototype.getSnapRecords = function (point, inCoordRange) {
203 var geometrys = this.getGeometrys();
204 if (!geometrys.length) return;
205 // @ts-ignore
206 return geometrys[0].getSnapRecords(point, inCoordRange);
207 };
208 Chart.prototype.getRecords = function (data, field) {
209 var geometrys = this.getGeometrys();
210 if (!geometrys.length) return;
211 // @ts-ignore
212 return geometrys[0].getRecords(data, field);
213 };
214 Chart.prototype.getLegendItems = function (point) {
215 var geometrys = this.getGeometrys();
216 if (!geometrys.length) return;
217 // @ts-ignore
218 return geometrys[0].getLegendItems(point);
219 };
220 Chart.prototype.setScale = function (field, option) {
221 this.scale.setScale(field, option);
222 };
223 Chart.prototype.getScale = function (field) {
224 return this.scale.getScale(field);
225 };
226 Chart.prototype.getScales = function () {
227 return this.scale.getScales();
228 };
229 Chart.prototype.getXScales = function () {
230 var geometrys = this.getGeometrys();
231 return geometrys.map(function (component) {
232 // @ts-ignore
233 return component.getXScale();
234 });
235 };
236 Chart.prototype.getYScales = function () {
237 var geometrys = this.getGeometrys();
238 return geometrys.map(function (component) {
239 // @ts-ignore
240 return component.getYScale();
241 });
242 };
243 Chart.prototype.getLayout = function () {
244 return this.coord.layout;
245 };
246 Chart.prototype.getCoord = function () {
247 return this.coord.coord;
248 };
249 Chart.prototype.filter = function (field, condition) {
250 var _a;
251 var filters = this.state.filters;
252 this.setState({
253 filters: __assign(__assign({}, filters), (_a = {}, _a[field] = condition, _a))
254 });
255 };
256 Chart.prototype._getRenderData = function () {
257 var _a = this,
258 props = _a.props,
259 state = _a.state;
260 var data = props.data;
261 var filters = state.filters;
262 if (!filters || !Object.keys(filters).length) {
263 return data;
264 }
265 var filteredData = data;
266 each(filters, function (condition, field) {
267 if (!condition) return;
268 filteredData = filteredData.filter(function (record) {
269 return condition(record[field], record);
270 });
271 });
272 return filteredData;
273 };
274 Chart.prototype.render = function () {
275 var _this = this;
276 var _a = this,
277 props = _a.props,
278 scale = _a.scale,
279 chartLayout = _a.layout;
280 var children = props.children,
281 originData = props.data;
282 if (!originData) return null;
283 var data = this._getRenderData();
284 var layout = this.getLayout();
285 var coord = this.getCoord();
286 var scaleOptions = scale.getOptions();
287 var width = chartLayout.width,
288 height = chartLayout.height;
289 return jsx("group", {
290 ref: this.coordRef,
291 style: {
292 width: width,
293 height: height,
294 fill: 'transparent'
295 }
296 }, Children.map(children, function (child) {
297 return Children.cloneElement(child, {
298 data: data,
299 chart: _this,
300 layout: layout,
301 coord: coord,
302 // 传 scaleOptions 是为了让 child 感知到 props 的的变化,合理的做法的应该是传递 scale,但是现在无法感知到 scale 的变化, 所以暂时只能先这么处理,scaleOptions 子组件目前是使用不到的。
303 scaleOptions: scaleOptions
304 });
305 }));
306 };
307 return Chart;
308}(Component);
309export default Chart;
\No newline at end of file