본문 바로가기
개발/스프링 프레임웍

spring boot, thymeleaf, neo4j 그래픽 시각화 하기 sigma.js 샘플

by 꿈트리꿈트리 2024. 11. 10.

스프링 부트, 타임리프?타입리프? 에 neo4j를 붙여 봤다 기존 RDB와는 많이 다른 객체간의 연결관계에 기반한 graphdb를 붙여 보았다. 

 일단은 생각 보다는 내 맘에 쏙 드는 샘플이나 글들이 별로 없었고 RDB나 NOSQL을 많이 쓰는 거 같다.

 언제나 그렇듯이 별거 아닌걸로 날린 시간이 많은거 같다. 

 

1. 프로젝트 설정

1.1 Spring Boot 프로젝트 생성

  • Spring Initializr를 사용하여 새로운 프로젝트를 생성합니다.
  • 필요한 의존성을 추가합니다:
    • Spring Web
    • Spring Data Neo4j

1.2 Maven 의존성 설정

pom.xml 파일에 다음과 같이 의존성을 추가합니다:

<dependencies>
    <!-- Spring Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring Data Neo4j -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-neo4j</artifactId>
    </dependency>
</dependencies>

 

2. Neo4j 설정

2.1 Neo4j 설치 및 실행

  • Neo4j를 다운로드하여 설치합니다.
  • 기본적으로 bolt://localhost:7687에서 실행됩니다.

2.2 애플리케이션 설정

application.properties 또는 application.yml 파일에 Neo4j 연결 정보를 추가합니다.

application.properties:

 

spring.neo4j.uri=bolt://localhost:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=비밀번호

 

3. 도메인 모델 생성

그래프 데이터를 표현하기 위한 엔티티를 생성합니다.

 

import org.springframework.data.neo4j.core.schema.*;

@Node
public class Person {
    @Id @GeneratedValue private Long id;
    private String name;

    @Relationship(type = "KNOWS")
    private List<Person> friends;

    // getters and setters
}

 

4. 리포지토리 생성

데이터베이스와 상호 작용하기 위한 리포지토리를 생성합니다.

import org.springframework.data.neo4j.repository.Neo4jRepository;

public interface PersonRepository extends Neo4jRepository<Person, Long> {
}

 

5. 컨트롤러 생성

REST API를 통해 데이터를 제공하기 위한 컨트롤러를 생성합니다.

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class PersonController {

    private final PersonRepository repository;

    public PersonController(PersonRepository repository) {
        this.repository = repository;
    }

    @GetMapping("/persons")
    public List<Person> getAllPersons() {
        return repository.findAll();
    }
}

 

6. 프론트엔드 설정

6.1 정적 리소스 폴더 생성

  • src/main/resources/static 폴더를 생성합니다.

6.2 HTML 파일 작성

index.html 파일을 생성하고 다음 내용을 추가합니다:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Graph Visualization</title>
    <script src="https://cdn.jsdelivr.net/npm/sigma@2/build/sigma.min.js"></script>
    <style>
        #container {
            width: 800px;
            height: 600px;
            margin: auto;
        }
    </style>
</head>
<body>
    <h1>Neo4j Graph Visualization with Sigma.js</h1>
    <div id="container"></div>

    <script>
        fetch('/api/persons')
            .then(response => response.json())
            .then(data => {
                const nodes = [];
                const edges = [];

                data.forEach(person => {
                    nodes.push({
                        id: person.id.toString(),
                        label: person.name,
                        x: Math.random(),
                        y: Math.random(),
                        size: 10,
                        color: '#008cc2'
                    });

                    if (person.friends) {
                        person.friends.forEach(friend => {
                            edges.push({
                                id: 'edge' + person.id + '-' + friend.id,
                                source: person.id.toString(),
                                target: friend.id.toString(),
                                color: '#ccc'
                            });
                        });
                    }
                });

                const graph = { nodes, edges };
                const container = document.getElementById('container');
                const renderer = new sigma({
                    graph: graph,
                    container: container
                });
            });
    </script>
</body>
</html>

 

 

여기 까지 하면 기본적으로 neo4에서 가져온 데이터를 가지고 그래프를 그려주지만

프런트 쪽에 x,y 좌표를 직접 찍어 줘야 하는데 이게 난감했다 적당한 거리를 벌려 주고 위아래 어디에 찍을지 내가 전부 지정해 주는건 아닌거 같고 그렇다고 랜덤 하게 할 수도 없고 알고리즘을 만들기도

그래서 일단 기본 샘플은 이렇게 하면 되고 다음 시간에는 

 

forceatlas2 를 사용하여 적당하게 그래플 좌표를 찍어 주는 샘플을 소개 해 보게습니다.