@alicloud/cloud-charts
Version:

253 lines (241 loc) • 8.58 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports["default"] = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _core = require("@antv/g2/esm/core");
var G2Connect = /*#__PURE__*/function () {
function G2Connect(charts, config) {
var _this = this;
if (charts === void 0) {
charts = [];
}
if (config === void 0) {
config = {};
}
this.charts = void 0;
this.config = void 0;
// 事件相关函数
// 需要注意的是,这里用闭包创建特殊的行为函数。
// 事件函数被调用时,this(chartInstance)会指向触发事件的图表实例,而self指向connect类的实例
this.handlePlotmove = function () {
var self = _this;
return function (e) {
var _self$config = self.config,
type = _self$config.type,
coordinate = _self$config.coordinate,
custom = _self$config.custom;
// @ts-ignore 显式声明this,指向触发事件的图表实例
var chartInstance = this;
var record = type === 'data' ? getRecord(chartInstance, e) : null;
self.charts.forEach(function (chart, index) {
// 过滤自身和已销毁的实例
if (chart === chartInstance || chart.destroyed) {
return;
}
if (custom) {
custom(e, chart, chartInstance);
return;
}
if (type === 'data' && record) {
// record为当前鼠标位置的数据,而非其余联动图表的数据,所以需要根据X轴判断
// 根据数据找到对应点,如果传入的数据不在画布空间内,point 为 null
var targetRecord = getRecordByX(chart, record);
var point = chart.getXY(targetRecord !== null && targetRecord !== void 0 ? targetRecord : record);
// 额外判断
// 1、如果数据中包含null, point中的坐标会变为 NaN
// 2、类型不一致坐标会出现负数
if (point && !isNaN(point.x) && !isNaN(point.y) && point.x > 0 && point.y > 0) {
// 找到对应的点,显示并return
chart.showTooltip(getPoint(point, e, coordinate));
}
// 只有所选数据存在才会显示tooltip不然不显示
return;
}
// 根据e直接显示tooltip,x、y属性是 getter,会在tooltip内部处理时被忽略,这里另外读取出来传入
// 当图表宽度不一致的时候根据位置显示就会有问题
chart.showTooltip({
x: e.x,
y: e.y
});
});
};
}();
this.handlePlotleave = function () {
var self = _this;
return function () {
// @ts-ignore 显式声明this,指向触发事件的图表实例
var chartInstance = this;
self.charts.forEach(function (chart) {
// 过滤自身和已销毁的实例
if (chart !== chartInstance && !chart.destroyed) {
// 隐藏tooltip
chart.hideTooltip();
}
});
};
}();
// 支持图例统一交互
this.handleLegendItementer = function () {
var self = _this;
return function (e) {
var custom = self.config.custom;
// @ts-ignore 显式声明this,指向触发事件的图表实例
var chartInstance = this;
self.charts.forEach(function (chart) {
// 过滤自身和已销毁的实例
if (chart === chartInstance || chart.destroyed) {
return;
}
if (custom) {
custom(e, chart, chartInstance);
return;
}
});
};
}();
this.handleLegendItemleave = function () {
var self = _this;
return function () {
// @ts-ignore 显式声明this,指向触发事件的图表实例
var chartInstance = this;
self.charts.forEach(function (chart) {
// 过滤自身和已销毁的实例
if (chart !== chartInstance && !chart.destroyed) {}
});
};
}();
this.charts = [];
// 配置项,后续添加数据联动等配置项
this.config = Object.assign({
type: 'position',
coordinate: 'xy',
custom: null
}, config);
// 添加绑定
this.add.apply(this, charts);
}
var _proto = G2Connect.prototype;
_proto.add = function add() {
var _this2 = this;
for (var _len = arguments.length, charts = new Array(_len), _key = 0; _key < _len; _key++) {
charts[_key] = arguments[_key];
}
charts.forEach(function (chart) {
if (!isValidChart(chart)) {
return;
}
if (_this2.charts.indexOf(chart) === -1) {
// 存储实例的引用
_this2.charts.push(chart);
// 绑定事件 新版G2底层事件系统没有去重,需要手动去重
chart.on('plot:mousemove', _this2.handlePlotmove);
chart.on('plot:mouseleave', _this2.handlePlotleave);
chart.on('legend-item:mouseenter', _this2.handleLegendItementer);
chart.on('legend-item:mouseleave', _this2.handleLegendItemleave);
}
});
};
_proto.remove = function remove() {
var _this3 = this;
for (var _len2 = arguments.length, charts = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
charts[_key2] = arguments[_key2];
}
if (charts.length === 0) {
// 清空所有绑定
this.charts.forEach(function (chart) {
if (!isValidChart(chart)) {
return;
}
chart.off('plot:mousemove', _this3.handlePlotmove);
chart.off('plot:mouseleave', _this3.handlePlotleave);
});
this.charts = [];
} else {
charts.forEach(function (chart) {
if (!isValidChart(chart)) {
return;
}
var index = _this3.charts.indexOf(chart);
if (index !== -1) {
// 去除实例的存储
_this3.charts.splice(index, 1);
// 绑定事件
chart.off('plot:mousemove', _this3.handlePlotmove);
chart.off('plot:mouseleave', _this3.handlePlotleave);
chart.off('legend-item:mouseenter', _this3.handleLegendItementer);
chart.off('legend-item:mouseleave', _this3.handleLegendItemleave);
}
});
}
};
_proto.destroy = function destroy() {
this.remove();
};
return G2Connect;
}();
/**
* 判断图表是否有效
*
* @param {object} chart G2图表实例
*
* @return {boolean} 是否有效图例
* */
function isValidChart(chart) {
return chart && !chart.destroyed && chart.constructor === _core.Chart;
}
/**
* 获取原始数据
*
* @param {object} chart G2图表实例
* @param {object} e G2 plot:mousemove 事件传入的参数
*
* @return {object|null} 获取的原始数据,没有找到时为 null
* */
function getRecord(chart, e) {
var record = e.data;
// 在折线图中选中的record.data为数组,改为用最贴近数据读取
if (!record || Array.isArray(record.data)) {
record = chart.getSnapRecords(e);
if (Array.isArray(record) && record[0]) {
record = record[0]._origin;
} else {
record = null;
}
} else if (record.data) {
record = record.data;
}
return record;
}
/**
* 根据原始数据的X轴坐标获取相应的点的数据
*
* @param {object} chart G2图表实例
* @param {object} record 原始数据
*
* @return {object|undefined} 获取的新数据,没有找到时为 null
* */
function getRecordByX(chart, record) {
var _chart$options$data, _chart$options;
var filterData = (_chart$options$data = chart === null || chart === void 0 ? void 0 : (_chart$options = chart.options) === null || _chart$options === void 0 ? void 0 : _chart$options.data) !== null && _chart$options$data !== void 0 ? _chart$options$data : [];
// 返回第一个能匹配上的数据即可
return filterData.find(function (ele) {
return ele.x === record.x;
});
}
/**
* 按照coordinate设置获取正确的坐标
*
* @param {object} point 原始获得的坐标
* @param {object} e G2 plot:mousemove 事件传入的参数
* @param {string} coordinate 坐标设置
*
* @return {object} 正确的坐标
* */
function getPoint(point, e, coordinate) {
return (0, _extends2["default"])({}, point, {
x: coordinate === 'y' ? e.x : point.x,
y: coordinate === 'x' ? e.y : point.y
});
}
var _default = exports["default"] = G2Connect;