index.html 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. <head>
  2. <style> body { margin: 0; } </style>
  3. <script src="//unpkg.com/3d-force-graph"></script>
  4. <!-- <script src="../../dist/3d-force-graph.js"></script>-->
  5. </head>
  6. <body>
  7. <div id="3d-graph"></div>
  8. <script>
  9. // Random tree
  10. const N = 40;
  11. const gData = {
  12. nodes: [...Array(N).keys()].map(i => ({ id: i })),
  13. links: [...Array(N).keys()]
  14. .filter(id => id)
  15. .map(id => ({
  16. source: id,
  17. target: Math.round(Math.random() * (id-1))
  18. }))
  19. };
  20. let selectedNodes = new Set();
  21. const Graph = ForceGraph3D()
  22. (document.getElementById('3d-graph'))
  23. .graphData(gData)
  24. .nodeRelSize(9)
  25. .nodeColor(node => selectedNodes.has(node) ? 'yellow' : 'grey')
  26. .onNodeClick((node, event) => {
  27. if (event.ctrlKey || event.shiftKey || event.altKey) { // multi-selection
  28. selectedNodes.has(node) ? selectedNodes.delete(node) : selectedNodes.add(node);
  29. } else { // single-selection
  30. const untoggle = selectedNodes.has(node) && selectedNodes.size === 1;
  31. selectedNodes.clear();
  32. !untoggle && selectedNodes.add(node);
  33. }
  34. Graph.nodeColor(Graph.nodeColor()); // update color of selected nodes
  35. })
  36. .onNodeDrag((node, translate) => {
  37. if (selectedNodes.has(node)) { // moving a selected node
  38. [...selectedNodes]
  39. .filter(selNode => selNode !== node) // don't touch node being dragged
  40. .forEach(node => ['x', 'y', 'z'].forEach(coord => node[`f${coord}`] = node[coord] + translate[coord])); // translate other nodes by same amount
  41. }
  42. })
  43. .onNodeDragEnd(node => {
  44. if (selectedNodes.has(node)) { // finished moving a selected node
  45. [...selectedNodes]
  46. .filter(selNode => selNode !== node) // don't touch node being dragged
  47. .forEach(node => ['x', 'y', 'z'].forEach(coord => node[`f${coord}`] = undefined)); // unfix controlled nodes
  48. }
  49. });
  50. </script>
  51. </body>