D3.js forceSimulation 레이디얼(radial) 포스

D3.js forceSimulation의 레이디얼(radial) 포스를 설명한다.

예제 프로그램

D3.js forceSimulation의 forceRadial 데모이다. 요소를 원형으로 배치할 수 있다.

코드 확인

예제 코드

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>D3 v7 force simulation force radial</title>
</head>

<body>
  <svg width="800" height="600"></svg>
  <script src="https://d3js.org/d3.v7.min.js"></script>
  <script>
    // 1. 그리려는 데이터 준비
    var width = document.querySelector("svg").clientWidth;
    var height = document.querySelector("svg").clientHeight;
    var nodesData = [];
    for (var i = 0; i < 50; i++) {
      nodesData.push({
        "x": width * Math.random(),
        "y": height * Math.random(),
        "r": parseInt(20 * Math.random() + 2)
      });
    }

    // 2. svg 요소 추가
    var node = d3.select("svg")
      .selectAll("circle")
      .data(nodesData)
      .enter()
      .append("circle")
      .attr("r", function (d) { return d.r })
      .attr("fill", "Gold")
      .attr("stroke", "black")
      .attr("opacity", 0.7)
      .call(d3.drag()
        .on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended));

    // 3. forceSimulation 설정
    var simulation = d3.forceSimulation()
      .force("collide",
        d3.forceCollide()
          .radius(function (d) { return d.r + 1 })
          .iterations(16))
      .force("charge", d3.forceManyBody().strength(-30))
      .force("r",
        d3.forceRadial()
          .radius(height * 0.35)
          .x(width / 2)
          .y(height / 2)
          .strength(0.5)
      );

    simulation.velocityDecay(0.2);

    simulation
      .nodes(nodesData)
      .on("tick", ticked);

    // 4. forceSimulation 그림 업데이트 함수
    function ticked() {
      node
        .attr("cx", function (d) { return d.x; })
        .attr("cy", function (d) { return d.y; });
    }

    // 5. 드래그 이벤트 함수
    function dragstarted(d) {
      if (!event.active) simulation.alphaTarget(0.3).restart();
      d.fx = d.x;
      d.fy = d.y;
    }

    function dragged(event, d) {
      d.fx = event.x;
      d.fy = event.y;
    }

    function dragended(event, d) {
      if (!event.active) simulation.alphaTarget(0);
      d.fx = null;
      d.fy = null;
    }
  </script>
</body>

</html>

설명

기본은 노드 상호작용의 샘플과 동일하다. “3. forceSimulation 설정"만 설명한다.

3. forceSimulation 설정

// 3. forceSimulation 설정
var simulation = d3.forceSimulation()
  .force("collide",
    d3.forceCollide()
    .radius(function(d) { return d.r + 1 })
    .iterations(16))
  .force("charge", d3.forceManyBody().strength(-30))
  // 여기서부터 설명 ---------------
  .force("r",
    d3.forceRadial()
    .radius(height / 2 * 0.7)
    .x(width / 2)
    .y(height / 2)
    .strength(0.5)
  );
  // 여기까지 설명 -----------------

simulation.velocityDecay(0.2);

simulation
  .nodes(nodesData)
  .on("tick", ticked);

forceSimulation.force()로 설정할 수 있는 파라미터를 정리는아래와 같다.

“r” : 레이디얼 포스

함수 설명
radius Circle 반경.
값이 지정되어 있지 않은 경우는 현재의 설정 값를 반환한다.
x Circle의 중심 x 좌표.
기본값은 0이다.
y Circle의 중심 y 좌표.
기본값은 0이다.
strength Circle의 위치로 노드가 이동하는 속도.
1스텝으로 거리 * strength의 값분 변화한다.
1.0 이상의 숫자는 더 이상 사용되지 않는다.
0.0 ~ 1.0의 소수점으로 설정한다.
기본값은 0.1이다.



최종 수정 : 2024-01-18