UNPKG

@antv/g2plot

Version:

An interactive and responsive charting library

291 lines 10.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Plot = exports.PLOT_CONTAINER_OPTIONS = void 0; var tslib_1 = require("tslib"); var g2_1 = require("@antv/g2"); var util_1 = require("@antv/util"); var event_emitter_1 = tslib_1.__importDefault(require("@antv/event-emitter")); var size_sensor_1 = require("size-sensor"); var utils_1 = require("../utils"); var SOURCE_ATTRIBUTE_NAME = 'data-chart-source-type'; /** plot 图表容器的配置 */ exports.PLOT_CONTAINER_OPTIONS = [ 'padding', 'appendPadding', 'renderer', 'pixelRatio', 'syncViewPadding', 'supportCSSTransform', 'limitInPlot', ]; /** * 所有 plot 的基类 */ var Plot = /** @class */ (function (_super) { tslib_1.__extends(Plot, _super); function Plot(container, options) { var _this = _super.call(this) || this; _this.container = typeof container === 'string' ? document.getElementById(container) : container; _this.options = utils_1.deepAssign({}, _this.getDefaultOptions(), options); _this.createG2(); _this.bindEvents(); return _this; } /** * 获取默认的 options 配置项 * 每个组件都可以复写 */ Plot.getDefaultOptions = function () { return { renderer: 'canvas', xAxis: { nice: true, label: { autoRotate: false, autoHide: { type: 'equidistance', cfg: { minGap: 6 } }, }, }, yAxis: { nice: true, label: { autoHide: true, autoRotate: false, }, }, animation: true, }; }; /** * 创建 G2 实例 */ Plot.prototype.createG2 = function () { var _a = this.options, width = _a.width, height = _a.height, defaultInteractions = _a.defaultInteractions; this.chart = new g2_1.Chart(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({ container: this.container, autoFit: false }, this.getChartSize(width, height)), { localRefresh: false }), utils_1.pick(this.options, exports.PLOT_CONTAINER_OPTIONS)), { defaultInteractions: defaultInteractions })); // 给容器增加标识,知道图表的来源区别于 G2 this.container.setAttribute(SOURCE_ATTRIBUTE_NAME, 'G2Plot'); }; /** * 计算默认的 chart 大小。逻辑简化:如果存在 width 或 height,则直接使用,否则使用容器大小 * @param width * @param height */ Plot.prototype.getChartSize = function (width, height) { var chartSize = utils_1.getContainerSize(this.container); return { width: width || chartSize.width || 400, height: height || chartSize.height || 400 }; }; /** * 绑定代理所有 G2 的事件 */ Plot.prototype.bindEvents = function () { var _this = this; if (this.chart) { this.chart.on('*', function (e) { if (e === null || e === void 0 ? void 0 : e.type) { _this.emit(e.type, e); } }); } }; /** * 获取默认的 options 配置项 * 每个组件都可以复写 */ Plot.prototype.getDefaultOptions = function () { return Plot.getDefaultOptions(); }; /** * 绘制 */ Plot.prototype.render = function () { // 暴力处理,先清空再渲染,需要 G2 层自行做好更新渲染 this.chart.clear(); // 因为子 view 会继承父 view 的 options 配置(包括 legend,所以会导致 legend 重复创建) // 所以这里给 chart 实例的 options 配置清空 // 最好的解法是在 G2 view.clear 方法的时候,重置 options 配置。或者提供方法去 resetOptions // #1684 理论上在多 view 图形上,只要存在 custom legend,都存在类似问题(子弹图、双轴图) // @ts-ignore this.chart.options = { data: [], animate: true, }; this.chart.views = []; // 删除已有的 views // 执行 adaptor this.execAdaptor(); // 渲染 this.chart.render(); // 绑定 this.bindSizeSensor(); }; /** * 更新: 更新配置且重新渲染 * @param options */ Plot.prototype.update = function (options) { this.updateOption(options); this.render(); }; /** * 更新配置 * @param options */ Plot.prototype.updateOption = function (options) { this.options = utils_1.deepAssign({}, this.options, options); }; /** * 设置状态 * @param type 状态类型,支持 'active' | 'inactive' | 'selected' 三种 * @param conditions 条件,支持数组 * @param status 是否激活,默认 true */ Plot.prototype.setState = function (type, condition, status) { if (status === void 0) { status = true; } var elements = utils_1.getAllElementsRecursively(this.chart); util_1.each(elements, function (ele) { if (condition(ele.getData())) { ele.setState(type, status); } }); }; /** * 获取状态 */ Plot.prototype.getStates = function () { var elements = utils_1.getAllElementsRecursively(this.chart); var stateObjects = []; util_1.each(elements, function (element) { var data = element.getData(); var states = element.getStates(); util_1.each(states, function (state) { stateObjects.push({ data: data, state: state, geometry: element.geometry, element: element }); }); }); return stateObjects; }; /** * 更新数据 * @override * @param options */ Plot.prototype.changeData = function (data) { // @ts-ignore this.update({ data: data }); // TODO: 临时方案,最好使用下面的方式去更新数据 // this.chart.changeData(data); }; /** * 修改画布大小 * @param width * @param height */ Plot.prototype.changeSize = function (width, height) { this.chart.changeSize(width, height); }; /** * 增加图表标注。通过 id 标识,如果匹配到,就做更新 */ Plot.prototype.addAnnotations = function (annotations, view) { view = view ? view : this.chart; var incoming = tslib_1.__spreadArrays(annotations); var controller = view.getController('annotation'); var current = controller.getComponents().map(function (co) { return co.extra; }); controller.clear(true); var _loop_1 = function (i) { var annotation = current[i]; var findIndex = incoming.findIndex(function (item) { return item.id && item.id === annotation.id; }); if (findIndex !== -1) { annotation = utils_1.deepAssign({}, annotation, incoming[findIndex]); incoming.splice(findIndex, 1); } controller.annotation(annotation); }; for (var i = 0; i < current.length; i++) { _loop_1(i); } incoming.forEach(function (annotation) { return controller.annotation(annotation); }); view.render(true); }; /** * 删除图表标注。通过 id 标识,如果匹配到,就做删除 */ Plot.prototype.removeAnnotations = function (annotations) { var controller = this.chart.getController('annotation'); var current = controller.getComponents().map(function (co) { return co.extra; }); controller.clear(true); var _loop_2 = function (i) { var annotation = current[i]; if (!annotations.find(function (item) { return item.id && item.id === annotation.id; })) { controller.annotation(annotation); } }; for (var i = 0; i < current.length; i++) { _loop_2(i); } this.chart.render(true); }; /** * 销毁 */ Plot.prototype.destroy = function () { // 取消 size-sensor 的绑定 this.unbindSizeSensor(); // G2 的销毁 this.chart.destroy(); // 清空已经绑定的事件 this.off(); this.container.removeAttribute(SOURCE_ATTRIBUTE_NAME); }; /** * 执行 adaptor 操作 */ Plot.prototype.execAdaptor = function () { var adaptor = this.getSchemaAdaptor(); var _a = this.options, padding = _a.padding, appendPadding = _a.appendPadding; // 更新 padding this.chart.padding = padding; // 更新 appendPadding this.chart.appendPadding = appendPadding; // 转化成 G2 API adaptor({ chart: this.chart, options: this.options, }); }; /** * 当图表容器大小变化的时候,执行的函数 */ Plot.prototype.triggerResize = function () { this.chart.forceFit(); }; /** * 绑定 dom 容器大小变化的事件 */ Plot.prototype.bindSizeSensor = function () { var _this = this; if (this.unbind) { return; } var _a = this.options.autoFit, autoFit = _a === void 0 ? true : _a; if (autoFit) { this.unbind = size_sensor_1.bind(this.container, function () { // 获取最新的宽高信息 var _a = utils_1.getContainerSize(_this.container), width = _a.width, height = _a.height; // 主要是防止绑定的时候触发 resize 回调 if (width !== _this.chart.width || height !== _this.chart.height) { _this.triggerResize(); } }); } }; /** * 取消绑定 */ Plot.prototype.unbindSizeSensor = function () { if (this.unbind) { this.unbind(); this.unbind = undefined; } }; return Plot; }(event_emitter_1.default)); exports.Plot = Plot; //# sourceMappingURL=plot.js.map