@alicloud/cloud-charts
Version:

334 lines (308 loc) • 10.5 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.PADDING_TOP = exports.HIERARCHY_DATA_TRANSFORM_PARAMS = exports.DrillDownAction = exports.DEFAULT_BREAD_CRUMB_CONFIG = exports.BREAD_CRUMB_NAME = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
var _g = require("@antv/g2");
var _util = require("@antv/util");
var _lodash = require("lodash");
var _themes = _interopRequireDefault(require("../../../themes"));
var _common = require("../../common");
var _transformTreeNodeData = require("../../utils/transformTreeNodeData");
// 面包屑文字和分割符'/'之间的距离
var PADDING = 4;
// 面包屑位置距离树图的距离
var PADDING_LEFT = 0;
// 面包屑位置距离树图的顶部距离
var PADDING_TOP = exports.PADDING_TOP = 5;
/** Group name of breadCrumb: 面包屑 */
var BREAD_CRUMB_NAME = exports.BREAD_CRUMB_NAME = 'drilldown-bread-crumb';
// 面包屑默认配置
var DEFAULT_BREAD_CRUMB_CONFIG = exports.DEFAULT_BREAD_CRUMB_CONFIG = {
/** 位置,默认:左上角 */
position: 'top-left',
dividerText: '/',
textStyle: {
fontSize: 12,
fill: _themes["default"]['widgets-legend-text-normal'],
cursor: 'pointer'
},
activeTextStyle: {
fill: _themes["default"]['widgets-legend-text-highlight']
}
};
/**
* hierarchy 数据转换的参数
*/
var HIERARCHY_DATA_TRANSFORM_PARAMS = exports.HIERARCHY_DATA_TRANSFORM_PARAMS = 'hierarchy-data-transform-params';
/**
* Hierarchy plot 节点的数据
*/
/**
* @description 下钻交互的 action
*
* 适用于:hierarchy
*/
var DrillDownAction = exports.DrillDownAction = /*#__PURE__*/function (_Action) {
(0, _inheritsLoose2["default"])(DrillDownAction, _Action);
function DrillDownAction() {
var _this;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _Action.call.apply(_Action, [this].concat(args)) || this;
/** Action name */
_this.name = 'drill-down';
// 存储历史下钻数据
_this.historyCache = [];
// 存储初始数据
_this.rootData = [];
// 面包屑 group
_this.breadCrumbGroup = null;
// 面包屑基础配置
_this.breadCrumbCfg = DEFAULT_BREAD_CRUMB_CONFIG;
return _this;
}
var _proto = DrillDownAction.prototype;
/**
* 点击事件, 下钻数据,并绘制面包屑
*/
_proto.click = function click() {
var data = (0, _util.get)(this.context, ['event', 'data', 'data']);
if (!data) return false;
// console.log('click', data)
this.drill(data);
this.drawBreadCrumb();
}
/**
* 重置位置,初始化及触发 chart afterchangesize 回调时使用
*/;
_proto.resetPosition = function resetPosition() {
// 当在第一层级未绘制面包屑,此时 changedata 触发 resetPosition 函数,需判断 this.breadCrumbGroup 是否存在
if (!this.breadCrumbGroup) return;
var coordinate = this.context.view.getCoordinate();
var breadCrumbGroup = this.breadCrumbGroup;
var bbox = breadCrumbGroup.getBBox();
var _this$getButtonCfg = this.getButtonCfg(),
position = _this$getButtonCfg.position;
// @todo 后续抽取一个函数来处理,以及增加 margin 或者 padding 的设置
// 非 polar 的,需要使用 coordinate,除却图表组件
var point = {
x: coordinate.start.x,
y: coordinate.end.y - (bbox.height + PADDING_TOP * 2)
};
if (coordinate.isPolar) {
// 默认,左上角直接出发
point = {
x: 0,
y: 0
};
}
if (position === 'bottom-left') {
// 涉及到坐标反转的问题
point = {
x: coordinate.start.x,
y: coordinate.start.y
};
}
/** PADDING_LEFT, PADDING_TOP 与画布边缘的距离 */
var matrix = _g.Util.transform(null, [['t', point.x + PADDING_LEFT, point.y + bbox.height + PADDING_TOP]]);
breadCrumbGroup.setMatrix(matrix);
}
/**
* 返回上一层
*/;
_proto.back = function back() {
if ((0, _util.size)(this.historyCache)) {
this.backTo(this.historyCache.slice(0, -1));
}
}
/**
* 重置
*/;
_proto.reset = function reset() {
if (this.historyCache[0]) {
this.backTo(this.historyCache.slice(0, 1));
}
// 清空
this.historyCache = [];
this.hideCrumbGroup();
}
/**
* 下钻数据并更新 view 显示层
* @param nodeInfo 下钻数据
*/;
_proto.drill = function drill(nodeInfo) {
var _this$rootData;
var view = this.context.view;
// 重新 update 数据
// 1. 用nodeInfo数据转为dataset
// 2. dv转换为nodes列表
// 3. 列表传入图表的view里面,更新数据
nodeInfo.value = undefined;
// console.log('update nodeInfo', nodeInfo);
var _computeData = (0, _transformTreeNodeData.computeData)(nodeInfo),
drillData = _computeData.source;
// console.log('update drillData', drillData)
view.changeData(drillData);
// 存储历史记录
// 目前只考虑两层,history永远是root + 当前选中节点
var historyCache = [];
// 当前选中值
var node = nodeInfo;
while (node) {
var _node;
var nodeData = (0, _lodash.cloneDeep)(node.data || node);
nodeData.value = undefined;
var _computeData2 = (0, _transformTreeNodeData.computeData)(nodeData),
childrenData = _computeData2.source;
// console.log('遍历', nodeData, childrenData)
historyCache.unshift({
id: nodeData.name + "_" + node.height + "_" + node.depth,
name: nodeData.name,
children: childrenData
});
node = (_node = node) === null || _node === void 0 ? void 0 : _node.parent;
}
this.historyCache = (this.historyCache || []).slice(0, -1).concat(historyCache);
if (((_this$rootData = this.rootData) === null || _this$rootData === void 0 ? void 0 : _this$rootData.length) === 0) {
this.rootData = [historyCache[0]];
} else {
this.rootData = [this.historyCache[0]];
}
}
/**
* 回退事件,点击面包屑时触发
* @param historyCache 当前要回退到的历史
*/;
_proto.backTo = function backTo(historyCache) {
if (!historyCache || historyCache.length <= 0) {
return;
}
var view = this.context.view;
// const data = last(historyCache).children; // 处理后的数组
// 目前只考虑两层的计算
// console.log('backTo', this.rootData[0].children)
view.changeData(this.rootData[0].children);
if (historyCache.length > 1) {
this.historyCache = historyCache;
this.drawBreadCrumb();
} else {
// 清空
this.historyCache = [];
this.hideCrumbGroup();
}
}
/**
* 获取 mix 默认的配置和用户配置
*/;
_proto.getButtonCfg = function getButtonCfg() {
var view = this.context.view;
var drillDownConfig = (0, _util.get)(view, ['interactions', 'drill-down', 'cfg', 'drillDownConfig']);
return (0, _common.deepAssign)(this.breadCrumbCfg, drillDownConfig === null || drillDownConfig === void 0 ? void 0 : drillDownConfig.breadCrumb, this.cfg);
}
/**
* 显示面包屑
*/;
_proto.drawBreadCrumb = function drawBreadCrumb() {
this.drawBreadCrumbGroup();
this.resetPosition();
this.breadCrumbGroup.show();
}
/**
* 绘制 Button 和 文本
*/;
_proto.drawBreadCrumbGroup = function drawBreadCrumbGroup() {
var _this2 = this;
var config = this.getButtonCfg();
var cache = this.historyCache;
// 初始化面包屑 group
if (!this.breadCrumbGroup) {
this.breadCrumbGroup = this.context.view.foregroundGroup.addGroup({
name: BREAD_CRUMB_NAME
});
} else {
this.breadCrumbGroup.clear();
}
// 绘制面包屑
var left = 0;
cache.forEach(function (record, index) {
// 添加文本
var textShape = _this2.breadCrumbGroup.addShape({
type: 'text',
id: record.id,
name: BREAD_CRUMB_NAME + "_" + record.name + "_text",
attrs: (0, _extends2["default"])({
text: index === 0 && !(0, _util.isNil)(config.rootText) ? config.rootText : record.name
}, config.textStyle, {
x: left,
y: 0
})
});
var textShapeBox = textShape.getBBox();
left += textShapeBox.width + PADDING;
// 增加文本事件
textShape.on('click', function (event) {
var _last;
var targetId = event.target.get('id');
if (targetId !== ((_last = (0, _util.last)(cache)) === null || _last === void 0 ? void 0 : _last.id)) {
var newHistoryCache = cache.slice(0, cache.findIndex(function (d) {
return d.id === targetId;
}) + 1);
_this2.backTo(newHistoryCache);
// this.reset();
}
});
// active 效果内置
textShape.on('mouseenter', function (event) {
var _last2;
var targetId = event.target.get('id');
if (targetId !== ((_last2 = (0, _util.last)(cache)) === null || _last2 === void 0 ? void 0 : _last2.id)) {
textShape.attr(config.activeTextStyle);
} else {
textShape.attr({
cursor: 'default'
});
}
});
textShape.on('mouseleave', function () {
textShape.attr(config.textStyle);
});
if (index < cache.length - 1) {
// 添加反斜杠
var dividerShape = _this2.breadCrumbGroup.addShape({
type: 'text',
name: config.name + "_" + record.name + "_divider",
attrs: (0, _extends2["default"])({
text: config.dividerText
}, config.textStyle, {
x: left,
y: 0
})
});
var dividerBox = dividerShape.getBBox();
left += dividerBox.width + PADDING;
}
});
}
/**
* 隐藏面包屑
*/;
_proto.hideCrumbGroup = function hideCrumbGroup() {
if (this.breadCrumbGroup) {
this.breadCrumbGroup.hide();
}
}
/**
* @override
* destroy: 销毁资源
*/;
_proto.destroy = function destroy() {
if (this.breadCrumbGroup) {
this.breadCrumbGroup.remove();
}
_Action.prototype.destroy.call(this);
};
return DrillDownAction;
}(_g.Action);