forceGraph.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. var __rest = (this && this.__rest) || function (s, e) {
  2. var t = {};
  3. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
  4. t[p] = s[p];
  5. if (s != null && typeof Object.getOwnPropertySymbols === "function")
  6. for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  7. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
  8. t[p[i]] = s[p[i]];
  9. }
  10. return t;
  11. };
  12. import { forceSimulation, forceManyBody, forceLink, forceX, forceY, forceCenter, } from 'd3-force';
  13. import { deepMix } from '@antv/util';
  14. import { subObject } from '../utils/helper';
  15. import { maybeAnimation, subTooltip } from '../utils/mark';
  16. import { field, initializeData } from './utils';
  17. function dataTransform(data, layout, encode) {
  18. const { nodes, links } = data;
  19. const { joint, nodeStrength, linkStrength } = layout;
  20. const { nodeKey = (d) => d.id, linkKey = (d) => d.id } = encode;
  21. const nodeForce = forceManyBody();
  22. const linkForce = forceLink(links).id(field(linkKey));
  23. typeof nodeStrength === 'function' && nodeForce.strength(nodeStrength);
  24. typeof linkStrength === 'function' && linkForce.strength(linkStrength);
  25. const simulation = forceSimulation(nodes)
  26. .force('link', linkForce)
  27. .force('charge', nodeForce);
  28. joint
  29. ? simulation.force('center', forceCenter())
  30. : simulation.force('x', forceX()).force('y', forceY());
  31. simulation.stop();
  32. const n = Math.ceil(Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay()));
  33. for (let i = 0; i < n; i++)
  34. simulation.tick();
  35. return {
  36. nodesData: nodes,
  37. linksData: links,
  38. };
  39. }
  40. export const ForceGraph = (options) => {
  41. return () => {
  42. const DEFAULT_LAYOUT_OPTIONS = {
  43. joint: true,
  44. };
  45. const DEFAULT_LINK_OPTIONS = {
  46. type: 'link',
  47. axis: false,
  48. legend: false,
  49. encode: {
  50. x: [(d) => d.source.x, (d) => d.target.x],
  51. y: [(d) => d.source.y, (d) => d.target.y],
  52. },
  53. style: {
  54. stroke: '#999',
  55. strokeOpacity: 0.6,
  56. },
  57. };
  58. const DEFAULT_NODE_OPTIONS = {
  59. type: 'point',
  60. axis: false,
  61. legend: false,
  62. encode: {
  63. x: 'x',
  64. y: 'y',
  65. size: 5,
  66. color: 'group',
  67. shape: 'point',
  68. },
  69. scale: {
  70. color: { type: 'ordinal' },
  71. },
  72. style: {
  73. stroke: '#fff',
  74. },
  75. };
  76. const DEFAULT_LABEL_OPTIONS = {
  77. text: '',
  78. };
  79. const { data, encode: e = {}, scale, style = {}, layout = {}, nodeLabels = [], linkLabels = [], animate = {}, tooltip = {}, } = options;
  80. const { nodeKey = (d) => d.id, linkKey = (d) => d.id } = e, restEncode = __rest(e, ["nodeKey", "linkKey"]);
  81. const encode = Object.assign({ nodeKey, linkKey }, restEncode);
  82. const nodeEncode = subObject(encode, 'node');
  83. const linkEncode = subObject(encode, 'link');
  84. const { links, nodes } = initializeData(data, encode);
  85. const { nodesData, linksData } = dataTransform({ links, nodes }, deepMix({}, DEFAULT_LAYOUT_OPTIONS, layout), encode);
  86. const linkTooltip = subTooltip(tooltip, 'link', {
  87. items: [
  88. (d) => ({ name: 'source', value: field(linkKey)(d.source) }),
  89. (d) => ({ name: 'target', value: field(linkKey)(d.target) }),
  90. ],
  91. });
  92. const nodeTooltip = subTooltip(tooltip, 'node', {
  93. items: [(d) => ({ name: 'key', value: field(nodeKey)(d) })],
  94. }, true);
  95. return [
  96. deepMix({}, DEFAULT_LINK_OPTIONS, {
  97. data: linksData,
  98. encode: linkEncode,
  99. labels: linkLabels,
  100. style: subObject(style, 'link'),
  101. tooltip: linkTooltip,
  102. animate: maybeAnimation(animate, 'link'),
  103. }),
  104. deepMix({}, DEFAULT_NODE_OPTIONS, {
  105. data: nodesData,
  106. encode: Object.assign({}, nodeEncode),
  107. scale,
  108. style: subObject(style, 'node'),
  109. tooltip: nodeTooltip,
  110. labels: [
  111. Object.assign(Object.assign({}, DEFAULT_LABEL_OPTIONS), subObject(style, 'label')),
  112. ...nodeLabels,
  113. ],
  114. animate: maybeAnimation(animate, 'link'),
  115. }),
  116. ];
  117. };
  118. };
  119. ForceGraph.props = {};
  120. //# sourceMappingURL=forceGraph.js.map