N:::만지작 거리기

N_23. 3D 시각화 사용

joyHong 2022. 3. 4. 00:56

지난 글에서는 3D 그래프 탐험 영상을 소개하였다.

https://joyhong.tistory.com/149

 

N_22. 3D 그래프 탐험

이전에 작성한  블로그의 내용으로 만들어진 결과물을 3D 그래프로 표현.

joyhong.tistory.com

이번 글에서는 위와 같은 3D 그래프를 직접 만들어 보려고 한다.

시각화 라이브러리는 3d-force-graph 라는 것으로

https://github.com/vasturiano/3d-force-graph

위 주소가 공식 깃 주소이다.

 

 

간단한 데모를 위해 도커 우분투 컨테이너 상에서

nodejs, npm, express, 3d-force-graph를 설치하고 진행하겠다.

노드와 npm이 설치되어 있거나

윈도우 환경 또는 맥사용자는 각자의 환경에 맞게 nodejs와 npm을 설치하면 된다.

 

nodejs 설치

root@b1eb5294b23d:/home# apt install nodejs

 

npm 설치

root@b1eb5294b23d:/home# apt install npm

 

노드 버전 확인

root@b1eb5294b23d:/home# node -v

v10.19.0

 

express와 3d-force-graph 설치

root@b1eb5294b23d:/home# npm i 3d-force-graph
root@b1eb5294b23d:/home# npm i express

 

이렇게 4개를 설치하면 기본 준비가 끝나게 된다.

 

다음으로는 app.js 파일을 생성하고 다음과 같이 코드를 넣어보겠다.

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/sample.html');
});

app.get('/data', (req, res) => {
  res.sendFile(__dirname + '/miserables.json');
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

 

포트는 3000번으로 하고 http://localhost:3000/ 으로 요청이 들어오면 sample.html 파일을 전송하고, http://localhost:3000/data 로 요청이 들어오면 miserables.json 파일을 전송하도록 하였다.

miserables.json은 레미제라블 에서 등장하는 인물들의 관계를 네트워크로 표현한 데이터이다.

https://github.com/joyhong85/3d_graph/blob/5e3f5c10975c8730aec922a78eff7ee3bbfd8039/miserables.json

또는 3d-force-graph 깃에서 다운로드를 받을 수 있으며, 

예제를 만들기 위해서 json 파일을 다운받아 app.js와 동일한 경로에 저장하도록 한다. 

마지막으로 sample.html 파일을 app.js 파일과 동일한 경로에 생성하고 아래와 같이 코드를 넣어보겠다.

<head>
  <style> body { margin: 0; } </style>
  <script src="//unpkg.com/three"></script>
  <script src="//unpkg.com/three-spritetext"></script>
  <script src="//unpkg.com/3d-force-graph"></script>
  <script src="https://requirejs.org/docs/release/2.3.6/minified/require.js"></script>
  <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>

<body>
  <div id="3d-graph"></div>

  <script>

    const elem = document.getElementById('3d-graph');

    var gData;
    $.ajax({
        url: "/data",
        async:false,
        dataType: "json",
        success: function (data) {
            gData = data;
        }
    });

    const Graph = ForceGraph3D()(elem)
      .graphData(gData)
      .nodeLabel('id')
      .nodeAutoColorBy('group')
      .linkThreeObjectExtend(true)
      .linkThreeObject(link => {
        const sprite = new SpriteText(`${link.source} > ${link.target}`);
        sprite.color = 'lightgrey';
        sprite.textHeight = 1.5;
        return sprite;
      })
      .linkPositionUpdate((sprite, { start, end }) => {
        const middlePos = Object.assign(...['x', 'y', 'z'].map(c => ({
          [c]: start[c] + (end[c] - start[c]) / 2 // calc middle point
        })));

        Object.assign(sprite.position, middlePos);
      });

    Graph.d3Force('charge').strength(-120);

  </script>
</body>

sample.html 에서 ajax로 json 데이터를 받아오고, 그 데이터를 3d-force-graph 로 시각화를 하는 구조이다.

3d-force-graph 깃에서는 다양한 예제와 샘플코드를 제공하기 때문에

필요와 목적에 맞는 내용을 구성하면 된다.

위 예시는 ajax로 데이터를 받아와 사용하는 부분만 변경하였다.

작성이 완료되었으면 실행을 시키도록 한다.

root@b1eb5294b23d:/home# node app.js

그럼 웹브라우저에서 http://localhost:3000 으로 접근을 하면 아래와 같이 화면이 나오게 된다.

 

이 예제에서 사용한 코드는 아래의 깃에서 제공한다.

https://github.com/joyhong85/3d_graph

 

그럼 보다 더 다양한 멋진 시각화를 각자가 할 수 있을 것이다.