@antv/f2
Version:
Charts for mobile visualization.
326 lines (325 loc) • 10.3 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _tslib = require("tslib");
var _fEngine = require("@antv/f-engine");
var _util = require("@antv/util");
var _coord = _interopRequireDefault(require("../controller/coord"));
var _scale = _interopRequireDefault(require("../controller/scale"));
var _theme = _interopRequireDefault(require("../theme"));
// 统计图表
var Chart = /** @class */function (_super) {
(0, _tslib.__extends)(Chart, _super);
function Chart(props, context) {
var _this = _super.call(this, props) || this;
// 坐标系
_this.componentsPosition = [];
var theme = context.theme,
px2hd = context.px2hd;
// hack 处理,设置默认的主题样式
// 目前没想到其他更合适的方式,只能先这样处理
context.theme = (0, _util.deepMix)(px2hd(_theme.default), theme);
var data = props.data;
_this.scale = new _scale.default(data);
_this.coord = new _coord.default();
_this.coordRef = (0, _fEngine.createRef)();
// state
_this.state = {
filters: {}
};
return _this;
}
Chart.prototype.getStyle = function (props) {
var _a = this,
context = _a.context,
layout = _a.layout;
var theme = context.theme,
px2hd = context.px2hd;
var left = layout.left,
top = layout.top,
width = layout.width,
height = layout.height;
var customStyle = props.style;
return px2hd((0, _tslib.__assign)((0, _tslib.__assign)({
left: left,
top: top,
width: width,
height: height
}, theme.chart), customStyle));
};
Chart.prototype.willMount = function () {
var _a = this,
props = _a.props,
coord = _a.coord,
scale = _a.scale;
var scaleOptions = props.scale,
coordOption = props.coord;
this.resetCoordLayout();
// 初始化 scale
scale.create(scaleOptions);
// 初始化 coord
coord.create(coordOption);
};
// props 更新
Chart.prototype.willReceiveProps = function (nextProps, context) {
var _a = this,
scale = _a.scale,
coord = _a.coord,
lastProps = _a.props;
var nextStyle = nextProps.style,
nextData = nextProps.data,
nextScale = nextProps.scale;
var lastStyle = lastProps.style,
lastData = lastProps.data,
lastScale = lastProps.scale;
// style 更新
if (!(0, _fEngine.isEqual)(nextStyle, lastStyle) || context !== this.context) {
var style = this.getStyle(nextProps);
coord.updateLayout(style);
}
if (nextData !== lastData) {
scale.changeData(nextData);
}
// scale
if (!(0, _fEngine.isEqual)(nextScale, lastScale)) {
scale.update(nextScale);
}
};
Chart.prototype.willUpdate = function () {
this.coord.create(this.props.coord);
};
Chart.prototype.on = function (eventName, listener) {
var roolEl = this.coordRef.current;
if (!roolEl || !roolEl.gesture) return;
var gesture = roolEl.gesture;
gesture.on(eventName, listener);
};
Chart.prototype.off = function (eventName, listener) {
var roolEl = this.coordRef.current;
if (!roolEl || !roolEl.gesture) return;
var gesture = roolEl.gesture;
gesture.off(eventName, listener);
};
// 给需要显示的组件留空
Chart.prototype.layoutCoord = function (layout) {
this.coord.useLayout(layout);
};
Chart.prototype.resetCoordLayout = function () {
var _a = this,
coord = _a.coord,
props = _a.props;
var style = this.getStyle(props);
coord.updateLayout(style);
};
Chart.prototype.updateAdjust = function (adjust) {
this.adjust = adjust;
};
Chart.prototype.updateCoordLayout = function (layout) {
var _this = this;
if ((0, _util.isArray)(layout)) {
layout.forEach(function (item) {
_this.layoutCoord(item);
});
return;
}
this.layoutCoord(layout);
};
Chart.prototype.updateCoordFor = function (component, layout) {
var _this = this;
if (!layout) return;
var componentsPosition = this.componentsPosition;
var componentPosition = {
component: component,
layout: layout
};
var existIndex = (0, _util.findIndex)(componentsPosition, function (item) {
return item.component === component;
});
// 说明是已经存在的组件
if (existIndex > -1) {
componentsPosition.splice(existIndex, 1, componentPosition);
// 先重置,然后整体重新算一次
this.resetCoordLayout();
// 再整体计算前,需要去掉已经销毁的组件
this.removeComponentsPositionCache();
componentsPosition.forEach(function (componentPosition) {
var layout = componentPosition.layout;
_this.updateCoordLayout(layout);
});
return;
}
// 是新组件,直接添加
componentsPosition.push(componentPosition);
this.updateCoordLayout(layout);
};
Chart.prototype.removeComponentsPositionCache = function () {
var _a;
if (!((_a = this.componentsPosition) === null || _a === void 0 ? void 0 : _a.length)) return;
for (var i = this.componentsPosition.length; i > -1; i--) {
var item = this.componentsPosition[i];
if (item && item.component && item.component.destroyed) {
this.componentsPosition.splice(i, 1);
}
}
};
Chart.prototype.getGeometrys = function () {
// @ts-ignore
var children = this.children.children;
var geometrys = [];
_fEngine.Children.toArray(children).forEach(function (element) {
if (!element) return false;
var component = element.component;
// @ts-ignore
if (component && component.isGeometry) {
geometrys.push(component);
}
});
return geometrys;
};
/**
* calculate dataset's position on canvas
* @param {Object} record the dataset
* @return {Object} return the position
*/
Chart.prototype.getPosition = function (record) {
var coord = this.getCoord();
var xScale = this.getXScales()[0];
var xField = xScale.field;
var yScales = this.getYScales();
// default first
var yScale = yScales[0];
var yField = yScale.field;
for (var i = 0, len = yScales.length; i < len; i++) {
var scale = yScales[i];
var field = scale.field;
if (record[field]) {
yScale = scale;
yField = field;
break;
}
}
var x = xScale.scale(record[xField]);
var y = yScale.scale(record[yField]);
return coord.convertPoint({
x: x,
y: y
});
};
Chart.prototype.getSnapRecords = function (point, inCoordRange) {
var geometrys = this.getGeometrys();
if (!geometrys.length) return;
// @ts-ignore
return geometrys[0].getSnapRecords(point, inCoordRange);
};
Chart.prototype.getRecords = function (data, field) {
var geometrys = this.getGeometrys();
if (!geometrys.length) return;
// @ts-ignore
return geometrys[0].getRecords(data, field);
};
Chart.prototype.getLegendItems = function (point) {
var geometrys = this.getGeometrys();
if (!geometrys.length) return;
// @ts-ignore
return geometrys[0].getLegendItems(point);
};
Chart.prototype.setScale = function (field, option) {
this.scale.setScale(field, option);
};
Chart.prototype.getScale = function (field) {
return this.scale.getScale(field);
};
Chart.prototype.getScales = function () {
return this.scale.getScales();
};
Chart.prototype.getXScales = function () {
var geometrys = this.getGeometrys();
return geometrys.map(function (component) {
// @ts-ignore
return component.getXScale();
});
};
Chart.prototype.getYScales = function () {
var geometrys = this.getGeometrys();
return geometrys.map(function (component) {
// @ts-ignore
return component.getYScale();
});
};
Chart.prototype.getColorScales = function () {
var geometrys = this.getGeometrys();
return geometrys.map(function (component) {
// @ts-ignore
return component.getColorScale();
});
};
Chart.prototype.getLayout = function () {
return this.coord.layout;
};
Chart.prototype.getCoord = function () {
return this.coord.coord;
};
Chart.prototype.filter = function (field, condition) {
var _a;
var filters = this.state.filters;
this.setState({
filters: (0, _tslib.__assign)((0, _tslib.__assign)({}, filters), (_a = {}, _a[field] = condition, _a))
});
};
Chart.prototype._getRenderData = function () {
var _a = this,
props = _a.props,
state = _a.state;
var data = props.data;
var filters = state.filters;
if (!filters || !Object.keys(filters).length) {
return data;
}
var filteredData = data;
(0, _util.each)(filters, function (condition, field) {
if (!condition) return;
filteredData = filteredData.filter(function (record) {
return condition(record[field], record);
});
});
return filteredData;
};
Chart.prototype.render = function () {
var _this = this;
var _a = this,
props = _a.props,
scale = _a.scale,
chartLayout = _a.layout;
var children = props.children,
originData = props.data;
if (!originData) return null;
var data = this._getRenderData();
var layout = this.getLayout();
var coord = this.getCoord();
var scaleOptions = scale.getOptions();
var width = chartLayout.width,
height = chartLayout.height;
return (0, _fEngine.jsx)("group", {
ref: this.coordRef,
style: {
width: width,
height: height,
fill: 'transparent'
}
}, _fEngine.Children.map(children, function (child) {
return _fEngine.Children.cloneElement(child, {
data: data,
chart: _this,
layout: layout,
coord: coord,
// 传 scaleOptions 是为了让 child 感知到 props 的的变化,合理的做法的应该是传递 scale,但是现在无法感知到 scale 的变化, 所以暂时只能先这么处理,scaleOptions 子组件目前是使用不到的。
scaleOptions: scaleOptions
});
}));
};
return Chart;
}(_fEngine.Component);
var _default = exports.default = Chart;