계기
개인 프로젝트로 connection 이라는 이름의 프로젝트를 진행중이다.
해당 프로젝트에서는 특정 아이템들을 그래프화시켜서 보여주어야 하는데, 무슨 라이브러리를 쓸지 고민하다가 cytoscape 를 쓰기로 했다.
cytoscape를 쓰기로 결심을 하게 된 가장 큰 이유는 아래 demo였다.
문제는 connection 프로젝트에서 Vue.js를 쓰기로 마음먹었는데, 여기서 어떻게 이걸 쓰냐였다.
vue component로 wrapping 해놓은 vue-cytoscape가 있는 것 같긴 했지만..
star 수나, issue 수를 보고 사용하고 싶은 마음이 별로 없어졌다.
그냥 직접 가져와서 뻘짓 해보기로 결정했다.
그럼 어떻게 하지?
일단 설치
1
> yarn add cytoscape
그리고 직접 import 해서 여러 뻘짓을 했는데, 계속 element가 잘 안보였다. 원인을 찾다가 관련 스택오버플로우 답변을 찾았다.
일단 그대로 적용했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<template>
<div id="cy-wrapper">
<div id="cy" ref="cyElement"></div>
</div>
</template>
<script lang="ts">
import { defineComponent, nextTick, onMounted, ref } from 'vue'
import cytoscape from 'cytoscape';
export default defineComponent({
name: 'CytoscapeTest',
setup() {
const cyElement = ref(null);
const cyInstance = ref(null);
const resizeGraph = () => {
if (cyInstance.value) {
cyInstance.value.resize();
}
}
const test = async () => {
await nextTick()
resizeGraph();
}
onMounted(() => {
import('cytoscape')
.then((cy) => {
const cytoscape = cy.default;
})
.then(() => {
const element = document.createElement('div');
element.setAttribute('id', 'cy-mounting-point');
cyElement.value.appendChild(element);
cyInstance.value = Object.freeze(
cytoscape({
container: element,
elements: [ // list of graph elements to start with
{ // node a
data: { id: 'a' }
},
{ // node b
data: { id: 'b' }
},
{ // edge ab
data: { id: 'ab', source: 'a', target: 'b' }
}
],
style: [ // the stylesheet for the graph
{
selector: 'node',
style: {
'background-color': '#666',
'label': 'data(id)'
}
},
{
selector: 'edge',
style: {
'width': 3,
'line-color': '#ccc',
'target-arrow-color': '#ccc',
'target-arrow-shape': 'triangle',
'curve-style': 'bezier'
}
}
],
layout: {
name: 'grid',
rows: 1
}
})
);
test();
})
});
return {
cyElement,
}
},
})
</script>
하지만 여전히 보이지 않았다.
근데, 아래 이미지와 같이 canvas element는 있는데 보이지 않았고, 어? width, height 문제인가?
라는 생각이 들었다.
그래서 아래 코드와 같이 임시로 스타일을 추가해주었더니, 아주 잘 보였다.. (왠지 나의 뻘짓 코드도 동일한 문제였던 것 같고, stackoverflow의 코드처럼 복잡한 코드가 되지 않아도 되지 않았을까 라는 생각이 들었다.. 일단 다음에 고치기로 했다..)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style lang="scss">
#cy {
width: 100%;
min-height: 1000px;
div {
width: 100%;
min-height: 1000px;
}
div#cy-mounting-point {
canvas {
padding-left: 0;
padding-right: 0;
margin-left: auto;
margin-right: auto;
display: block;
}
}
}
</style>
일단 그래프 형태로 찍어냈다는 것에 만족하고… 원하는 형태의 그래프로 조금씩 바꾸어 나가면 될 것 같다.
끝