drill-down.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.DrillDownAction = exports.HIERARCHY_DATA_TRANSFORM_PARAMS = exports.DEFAULT_BREAD_CRUMB_CONFIG = exports.BREAD_CRUMB_NAME = exports.PADDING_TOP = void 0;
  4. var tslib_1 = require("tslib");
  5. var g2_1 = require("@antv/g2");
  6. var util_1 = require("@antv/util");
  7. var deep_assign_1 = require("../../utils/deep-assign");
  8. // 面包屑文字和分割符'/'之间的距离
  9. var PADDING = 4;
  10. // 面包屑位置距离树图的距离
  11. var PADDING_LEFT = 0;
  12. // 面包屑位置距离树图的顶部距离
  13. exports.PADDING_TOP = 5;
  14. /** Group name of breadCrumb: 面包屑 */
  15. exports.BREAD_CRUMB_NAME = 'drilldown-bread-crumb';
  16. // 面包屑默认配置
  17. exports.DEFAULT_BREAD_CRUMB_CONFIG = {
  18. /** 位置,默认:左上角 */
  19. position: 'top-left',
  20. dividerText: '/',
  21. textStyle: {
  22. fontSize: 12,
  23. fill: 'rgba(0, 0, 0, 0.65)',
  24. cursor: 'pointer',
  25. },
  26. activeTextStyle: {
  27. fill: '#87B5FF',
  28. },
  29. };
  30. /**
  31. * hierarchy 数据转换的参数
  32. */
  33. exports.HIERARCHY_DATA_TRANSFORM_PARAMS = 'hierarchy-data-transform-params';
  34. /**
  35. * @description 下钻交互的 action
  36. * @author liuzhenying
  37. *
  38. * 适用于:hierarchy plot
  39. */
  40. var DrillDownAction = /** @class */ (function (_super) {
  41. tslib_1.__extends(DrillDownAction, _super);
  42. function DrillDownAction() {
  43. var _this = _super !== null && _super.apply(this, arguments) || this;
  44. /** Action name */
  45. _this.name = 'drill-down';
  46. // 存储历史下钻数据
  47. _this.historyCache = [];
  48. // 面包屑 group
  49. _this.breadCrumbGroup = null;
  50. // 面包屑基础配置
  51. _this.breadCrumbCfg = exports.DEFAULT_BREAD_CRUMB_CONFIG;
  52. return _this;
  53. }
  54. /**
  55. * 点击事件, 下钻数据,并绘制面包屑
  56. */
  57. DrillDownAction.prototype.click = function () {
  58. var data = (0, util_1.get)(this.context, ['event', 'data', 'data']);
  59. if (!data)
  60. return false;
  61. this.drill(data);
  62. this.drawBreadCrumb();
  63. };
  64. /**
  65. * 重置位置,初始化及触发 chart afterchangesize 回调时使用
  66. */
  67. DrillDownAction.prototype.resetPosition = function () {
  68. // 当在第一层级未绘制面包屑,此时 changedata 触发 resetPosition 函数,需判断 this.breadCrumbGroup 是否存在
  69. if (!this.breadCrumbGroup)
  70. return;
  71. var coordinate = this.context.view.getCoordinate();
  72. var breadCrumbGroup = this.breadCrumbGroup;
  73. var bbox = breadCrumbGroup.getBBox();
  74. var position = this.getButtonCfg().position;
  75. // @todo 后续抽取一个函数来处理,以及增加 margin 或者 padding 的设置
  76. // 非 polar 的,需要使用 coordinate,除却图表组件
  77. var point = { x: coordinate.start.x, y: coordinate.end.y - (bbox.height + exports.PADDING_TOP * 2) };
  78. if (coordinate.isPolar) {
  79. // 默认,左上角直接出发
  80. point = { x: 0, y: 0 };
  81. }
  82. if (position === 'bottom-left') {
  83. // 涉及到坐标反转的问题
  84. point = { x: coordinate.start.x, y: coordinate.start.y };
  85. }
  86. /** PADDING_LEFT, PADDING_TOP 与画布边缘的距离 */
  87. var matrix = g2_1.Util.transform(null, [['t', point.x + PADDING_LEFT, point.y + bbox.height + exports.PADDING_TOP]]);
  88. breadCrumbGroup.setMatrix(matrix);
  89. };
  90. /**
  91. * 返回上一层
  92. */
  93. DrillDownAction.prototype.back = function () {
  94. if ((0, util_1.size)(this.historyCache)) {
  95. this.backTo(this.historyCache.slice(0, -1));
  96. }
  97. };
  98. /**
  99. * 重置
  100. */
  101. DrillDownAction.prototype.reset = function () {
  102. if (this.historyCache[0]) {
  103. this.backTo(this.historyCache.slice(0, 1));
  104. }
  105. // 清空
  106. this.historyCache = [];
  107. this.hideCrumbGroup();
  108. };
  109. /**
  110. * 下钻数据并更新 view 显示层
  111. * @param nodeInfo 下钻数据
  112. */
  113. DrillDownAction.prototype.drill = function (nodeInfo) {
  114. var view = this.context.view;
  115. var transformData = (0, util_1.get)(view, ['interactions', 'drill-down', 'cfg', 'transformData'], function (v) { return v; });
  116. // 重新 update 数据
  117. var drillData = transformData(tslib_1.__assign({ data: nodeInfo.data }, nodeInfo[exports.HIERARCHY_DATA_TRANSFORM_PARAMS]));
  118. view.changeData(drillData);
  119. // 存储历史记录
  120. var historyCache = [];
  121. var node = nodeInfo;
  122. while (node) {
  123. var nodeData = node.data;
  124. historyCache.unshift({
  125. id: "".concat(nodeData.name, "_").concat(node.height, "_").concat(node.depth),
  126. name: nodeData.name,
  127. // children 是实际数据
  128. children: transformData(tslib_1.__assign({ data: nodeData }, nodeInfo[exports.HIERARCHY_DATA_TRANSFORM_PARAMS])),
  129. });
  130. node = node.parent;
  131. }
  132. this.historyCache = (this.historyCache || []).slice(0, -1).concat(historyCache);
  133. };
  134. /**
  135. * 回退事件,点击面包屑时触发
  136. * @param historyCache 当前要回退到的历史
  137. */
  138. DrillDownAction.prototype.backTo = function (historyCache) {
  139. if (!historyCache || historyCache.length <= 0) {
  140. return;
  141. }
  142. var view = this.context.view;
  143. var data = (0, util_1.last)(historyCache).children; // 处理后的数组
  144. view.changeData(data);
  145. if (historyCache.length > 1) {
  146. this.historyCache = historyCache;
  147. this.drawBreadCrumb();
  148. }
  149. else {
  150. // 清空
  151. this.historyCache = [];
  152. this.hideCrumbGroup();
  153. }
  154. };
  155. /**
  156. * 获取 mix 默认的配置和用户配置
  157. */
  158. DrillDownAction.prototype.getButtonCfg = function () {
  159. var view = this.context.view;
  160. var drillDownConfig = (0, util_1.get)(view, ['interactions', 'drill-down', 'cfg', 'drillDownConfig']);
  161. return (0, deep_assign_1.deepAssign)(this.breadCrumbCfg, drillDownConfig === null || drillDownConfig === void 0 ? void 0 : drillDownConfig.breadCrumb, this.cfg);
  162. };
  163. /**
  164. * 显示面包屑
  165. */
  166. DrillDownAction.prototype.drawBreadCrumb = function () {
  167. this.drawBreadCrumbGroup();
  168. this.resetPosition();
  169. this.breadCrumbGroup.show();
  170. };
  171. /**
  172. * 绘制 Button 和 文本
  173. */
  174. DrillDownAction.prototype.drawBreadCrumbGroup = function () {
  175. var _this = this;
  176. var config = this.getButtonCfg();
  177. var cache = this.historyCache;
  178. // 初始化面包屑 group
  179. if (!this.breadCrumbGroup) {
  180. this.breadCrumbGroup = this.context.view.foregroundGroup.addGroup({
  181. name: exports.BREAD_CRUMB_NAME,
  182. });
  183. }
  184. else {
  185. this.breadCrumbGroup.clear();
  186. }
  187. // 绘制面包屑
  188. var left = 0;
  189. cache.forEach(function (record, index) {
  190. // 添加文本
  191. var textShape = _this.breadCrumbGroup.addShape({
  192. type: 'text',
  193. id: record.id,
  194. name: "".concat(exports.BREAD_CRUMB_NAME, "_").concat(record.name, "_text"),
  195. attrs: tslib_1.__assign(tslib_1.__assign({ text: index === 0 && !(0, util_1.isNil)(config.rootText) ? config.rootText : record.name }, config.textStyle), { x: left, y: 0 }),
  196. });
  197. var textShapeBox = textShape.getBBox();
  198. left += textShapeBox.width + PADDING;
  199. // 增加文本事件
  200. textShape.on('click', function (event) {
  201. var _a;
  202. var targetId = event.target.get('id');
  203. if (targetId !== ((_a = (0, util_1.last)(cache)) === null || _a === void 0 ? void 0 : _a.id)) {
  204. var newHistoryCache = cache.slice(0, cache.findIndex(function (d) { return d.id === targetId; }) + 1);
  205. _this.backTo(newHistoryCache);
  206. }
  207. });
  208. // active 效果内置
  209. textShape.on('mouseenter', function (event) {
  210. var _a;
  211. var targetId = event.target.get('id');
  212. if (targetId !== ((_a = (0, util_1.last)(cache)) === null || _a === void 0 ? void 0 : _a.id)) {
  213. textShape.attr(config.activeTextStyle);
  214. }
  215. else {
  216. textShape.attr({ cursor: 'default' });
  217. }
  218. });
  219. textShape.on('mouseleave', function () {
  220. textShape.attr(config.textStyle);
  221. });
  222. if (index < cache.length - 1) {
  223. // 添加反斜杠
  224. var dividerShape = _this.breadCrumbGroup.addShape({
  225. type: 'text',
  226. name: "".concat(config.name, "_").concat(record.name, "_divider"),
  227. attrs: tslib_1.__assign(tslib_1.__assign({ text: config.dividerText }, config.textStyle), { x: left, y: 0 }),
  228. });
  229. var dividerBox = dividerShape.getBBox();
  230. left += dividerBox.width + PADDING;
  231. }
  232. });
  233. };
  234. /**
  235. * 隐藏面包屑
  236. */
  237. DrillDownAction.prototype.hideCrumbGroup = function () {
  238. if (this.breadCrumbGroup) {
  239. this.breadCrumbGroup.hide();
  240. }
  241. };
  242. /**
  243. * @override
  244. * destroy: 销毁资源
  245. */
  246. DrillDownAction.prototype.destroy = function () {
  247. if (this.breadCrumbGroup) {
  248. this.breadCrumbGroup.remove();
  249. }
  250. _super.prototype.destroy.call(this);
  251. };
  252. return DrillDownAction;
  253. }(g2_1.Action));
  254. exports.DrillDownAction = DrillDownAction;
  255. //# sourceMappingURL=drill-down.js.map