treemap.js 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import { assign, isArray } from '@antv/util';
  2. import * as d3Hierarchy from 'd3-hierarchy';
  3. import { getAllNodes, getField } from './util';
  4. var DEFAULT_OPTIONS = {
  5. field: 'value',
  6. tile: 'treemapSquarify',
  7. size: [1, 1],
  8. round: false,
  9. ignoreParentValue: true,
  10. padding: 0,
  11. paddingInner: 0,
  12. paddingOuter: 0,
  13. paddingTop: 0,
  14. paddingRight: 0,
  15. paddingBottom: 0,
  16. paddingLeft: 0,
  17. as: ['x', 'y'],
  18. // 默认降序
  19. sort: function (a, b) { return b.value - a.value; },
  20. // 纵横比, treemapSquarify 布局时可用,默认黄金分割比例
  21. ratio: 0.5 * (1 + Math.sqrt(5)),
  22. };
  23. export function getTileMethod(tile, ratio) {
  24. return tile === 'treemapSquarify' ? d3Hierarchy[tile].ratio(ratio) : d3Hierarchy[tile];
  25. }
  26. export function treemap(data, options) {
  27. options = assign({}, DEFAULT_OPTIONS, options);
  28. var as = options.as;
  29. if (!isArray(as) || as.length !== 2) {
  30. throw new TypeError('Invalid as: it must be an array with 2 strings (e.g. [ "x", "y" ])!');
  31. }
  32. var field;
  33. try {
  34. field = getField(options);
  35. }
  36. catch (e) {
  37. console.warn(e);
  38. }
  39. var tileMethod = getTileMethod(options.tile, options.ratio);
  40. var partition = function (data) {
  41. return d3Hierarchy
  42. .treemap()
  43. .tile(tileMethod)
  44. .size(options.size)
  45. .round(options.round)
  46. .padding(options.padding)
  47. .paddingInner(options.paddingInner)
  48. .paddingOuter(options.paddingOuter)
  49. .paddingTop(options.paddingTop)
  50. .paddingRight(options.paddingRight)
  51. .paddingBottom(options.paddingBottom)
  52. .paddingLeft(options.paddingLeft)(
  53. /**
  54. * d3Hierarchy 布局中需指定 sum 函数计算 node 值,规则是:从当前 node 开始以 post-order traversal 的次序为当前节点以及每个后代节点调用指定的 value 函数,并返回当前 node。
  55. * for example:
  56. * { node: 'parent', value: 10, children: [{node: 'child1', value: 5}, {node: 'child2', value: 5}, ]}
  57. * parent 所得的计算值是 sum(node(parent)) + sum(node(child1)) + sum(node(child2))
  58. * ignoreParentValue 为 true(默认) 时,父元素的值由子元素累加而来,该值为 0 + 5 + 5 = 10
  59. * ignoreParentValue 为 false 时,父元素的值由当前节点 及子元素累加而来,该值为 10 + 5 + 5 = 20
  60. * sum 函数中,d 为用户传入的 data, children 为保留字段
  61. */
  62. d3Hierarchy
  63. .hierarchy(data)
  64. .sum(function (d) { return (options.ignoreParentValue && d.children ? 0 : d[field]); })
  65. .sort(options.sort));
  66. };
  67. var root = partition(data);
  68. /*
  69. * points:
  70. * 3 2
  71. * 0 1
  72. */
  73. var x = as[0];
  74. var y = as[1];
  75. root.each(function (node) {
  76. node[x] = [node.x0, node.x1, node.x1, node.x0];
  77. node[y] = [node.y1, node.y1, node.y0, node.y0];
  78. ['x0', 'x1', 'y0', 'y1'].forEach(function (prop) {
  79. if (as.indexOf(prop) === -1) {
  80. delete node[prop];
  81. }
  82. });
  83. });
  84. return getAllNodes(root);
  85. }
  86. //# sourceMappingURL=treemap.js.map