본문 바로가기
JavaScript/D3.js

D3.js d3-force 라이브러리로 힘 기반 그래프 레이아웃 구현하기

by GangDev 2024. 4. 22.

D3.js의 d3-force 라이브러리는 데이터 시각화에서 힘 기반 그래프 레이아웃을 구현하는 데 사용된다.

이 라이브러리는 노드와 링크를 사용하여 복잡한 네트워크 구조를 시각화하는 데 특히 유용하다.

d3-force는 노드 간의 상호작용을 시뮬레이션하여 그래프의 레이아웃을 자동으로 조정한다.

이를 통해 데이터의 관계를 시각적으로 표현할 수 있다.

 

주요 기능 >>

* forceSimulation: 노드의 집합에 대한 시뮬레이션을 생성한다. 이 시뮬레이션은 노드의 위치를 계산하고 업데이트한다.

 

* forceX 및 forceY: 노드를 특정 X 또는 Y 위치로 끌어당긴다. 이는 노드를 화면의 특정 영역으로 유지하는 데 유용하다.

 

* forceLink: 링크를 사용하여 노드 간의 거리를 유지한다. 이는 노드 간의 관계를 강조하는 데 사용된다.

 

* forceCollide: 노드 간의 충돌을 방지하여 노드가 서로 겹치지 않도록 한다.

 

* forceManyBody: 노드 간의 전류를 시뮬레이션하여 노드를 밀어낼 수 있다. 이는 노드 간의 거리를 조정하는 데 사용된다.

// 노드 데이터 생성
var nodes = [
 {id: "Node1"},
 {id: "Node2"},
 {id: "Node3"}
];

// 링크 데이터 생성
var links = [
 {source: "Node1", target: "Node2"},
 {source: "Node2", target: "Node3"}
];

// 시뮬레이션 생성
var simulation = d3.forceSimulation(nodes)
 .force("link", d3.forceLink(links).id(function(d) { return d.id; }))
 .force("charge", d3.forceManyBody())
 .force("center", d3.forceCenter(width / 2, height / 2));

// 시뮬레이션 업데이트
simulation.on("tick", function() {
 // 여기서 노드의 위치를 업데이트하고, 렌더링을 처리
});

 

위 예제에서는 노드와 링크를 정의하고, 시뮬레이션을 생성하여 노드 간의 관계를 시뮬레이션한다.

forceLink는 링크를 사용하여 노드 간의 거리를 유지하고, forceManyBody는 노드 간의 전류를 시뮬레이션하여 노드를 밀어낸다.

forceCenter는 노드를 화면의 중앙으로 끌어당긴다.

 

d3-force를 사용하면 복잡한 네트워크 구조를 시각화하는 데 필요한 다양한 힘을 쉽게 조정할 수 있다.

 

forceX, forceY

d3-force 라이브러리에서 forceX와 forceY 함수는 노드의 X축과 Y축 위치를 조정하는 데 사용된다.

이 함수들은 노드를 특정 위치로 끌어당기거나 특정 방향으로 이동시키는 데 유용하다.

이들 함수는 시뮬레이션에 추가되어 노드의 위치를 계싼하고 업데이트하는 데 사용된다.

 

forceX 사용 방법 >>

forceX 함수는 노드를 특정 X축 위치로 끌어당기는 데 사용된다.

이 함수는 노드의 X축 위치를 계산하는 데 사용되는 함수를 인자로 받는다.

예를 들어, 노드의 값에 따라 X축 위치를 계산하려면 다음과 같이 사용할 수 있다.

var simulation = d3.forceSimulation(nodes)
 .force('x', d3.forceX().x(function(d) { return xScale(d.value); }));

 

위 코드에서 xScale 함수는 노드의 값을 기반으로 X축 위치를 계산한다.

이렇게 하면 노드는 해당 값에 따라 화면의 특정 위치로 끌어당겨진다.

 

forceY 사용 방법 >>

forceY 함수는 노드를 특정 Y축 위치로 끌어당기는 데 사용된다.

이 함수는 노드의 Y축 위치를 계산하는 데 사용되는 함수를 인자로 받는다.

예를 들어, 모든 노드를 Y축의 0 위치로 끌어당기려면 다음과 같이 사용할 수 있다.

var simulation = d3.forceSimulation(nodes)
 .force('y', d3.forceY().y(function(d) { return 0; }));

 

위 코드에서는 모든 노드의 Y축 위치를 0으로 설정하여 노드를 화면의 중앙으로 끌어당겨진다.

 

유의사항 >>

forceX 와 forceY 함수를 사용할 때는 노드의 위치가 정확히 지정된 위치에 도달하지 않을 수 있다는 점을 유의해야 한다.

이는 시뮬레이션의 다른 힘들과의 상호작용 때문에 발생할 수 있다.

따라서, 이 함수들을 사용할 때는 노드의 위치가 예상대로 조정되지 않을 수 있음을ㅇ 염두해야 한다.

 

다음은 forceX 와 forceY를 사용하여 노드를 화면의 중앙으로 끌어당기는 예제이다.

const gravityXForce = d3.forceX().strength(0.03);
const gravityYForce = d3.forceY().strength(0.03);

this.simulation = d3.forceSimulation(nodes)
 .force('gravityX', gravityXForce)
 .force('gravityY', gravityYForce);

 

위 코드에서 gravityXForce 와 gravityForce 는 각각 X 축과 Y축으로 노드를 끌어당기는 힘을 생성한다.

이 힘들은 시뮬레이션에 추가되어 노드의 위치를 계산하고 업데이트한다.