index.html 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset='utf-8'>
  5. <title>Force Layout</title>
  6. <style type="text/css">
  7. .links line {
  8. stroke: #999;
  9. stroke-opacity: 0.6;
  10. }
  11. .nodes circle {
  12. fill: #fff;
  13. pointer-events: all;
  14. stroke: #000;
  15. stroke-width: 1.5;
  16. }
  17. .nodes .child {
  18. fill: #000;
  19. stroke: #fff;
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <script src="d3.v7.min.js"></script>
  25. <div id="svgContainer"></div>
  26. <script type="text/javascript">
  27. const width = 1024;
  28. const height = 768;
  29. const svg = d3.select("#svgContainer").append("svg")
  30. .attr("width", width)
  31. .attr("height", height);
  32. drag = simulation => {
  33. function dragstarted(event, d) {
  34. if (!event.active) simulation.alphaTarget(0.3).restart();
  35. d.fx = d.x;
  36. d.fy = d.y;
  37. }
  38. function dragged(event, d) {
  39. d.fx = event.x;
  40. d.fy = event.y;
  41. }
  42. function dragended(event, d) {
  43. if (!event.active) simulation.alphaTarget(0);
  44. d.fx = null;
  45. d.fy = null;
  46. }
  47. return d3.drag()
  48. .on("start", dragstarted)
  49. .on("drag", dragged)
  50. .on("end", dragended);
  51. }
  52. d3.json("data.json").then(function(data) {
  53. const root = d3.stratify().path(d => d)(data);
  54. const links = root.links();
  55. const nodes = root.descendants();
  56. //console.log(root);
  57. //console.log(links);
  58. //console.log(nodes);
  59. const simulation = d3.forceSimulation(nodes)
  60. .force("link", d3.forceLink(links).id(d => d.id).distance(10).strength(1))
  61. .force("charge", d3.forceManyBody().strength(-50))
  62. .force("x", d3.forceX())
  63. .force("y", d3.forceY())
  64. .force("center", d3.forceCenter(width / 2, height / 2));
  65. const link = svg.append("g")
  66. .attr("class", "links")
  67. .selectAll("line")
  68. .data(links)
  69. .join("line");
  70. const node = svg.append("g")
  71. .attr("class", "nodes")
  72. .selectAll("circle")
  73. .data(nodes)
  74. .join("circle")
  75. .attr("class", d => d.children ? null : "child")
  76. .attr("r", 3.5)
  77. .call(drag(simulation));
  78. node.append("title").text(d => d.data);
  79. const zoom = d3.zoom()
  80. .scaleExtent([1, 8])
  81. .on('zoom', function(e) {
  82. console.log("zoom");
  83. link.attr('transform', e.transform);
  84. node.attr('transform', e.transform);
  85. });
  86. svg.call(zoom);
  87. simulation.on("tick", () => {
  88. link
  89. .attr("x1", d => d.source.x)
  90. .attr("y1", d => d.source.y)
  91. .attr("x2", d => d.target.x)
  92. .attr("y2", d => d.target.y);
  93. node
  94. .attr("cx", d => d.x)
  95. .attr("cy", d => d.y);
  96. });
  97. });
  98. </script>
  99. </body>
  100. </html>