토폴로지 라이브러리 Cytoscape.js 라벨에 이미지 표시

,

토폴로지 라이브러리인 Cytoscape.js에서 라벨에 이미지를 표시해야 하는 상황이 생겼다.

빙챗, 챗GPT4, 바드에게 모두 물었고 빙챗이 가장 좋은 답변을 했다.

두 가지 방법이 있다(빙챗은 세 가지를 알려 줬으나 라이브러리 코드를 수정하는 것은 방법이라고 할 수 없으므로 실질적으로 방법은 두 가지다).

HTML 라벨 확장 설치

cytoscape-node-html-label 확장을 사용하면 매우 간편하다. 라벨을 아래와 같이 지정하면 된다고 한다.

cyInstance.nodeHtmlLabel( [{ tpl: d => '<div>' + d + '</div>' }] );

이 방법은 직접 사용해 본 건 아니라서 여기서 줄인다.

그런데 노드 라벨이 아니라 엣지 라벨에 적용하려면 아래 방법을 사용해야 한다.

아이콘 폰트

아이콘 폰트를 사용하면 된다. 그러나 일반 이미지는 사용할 수 없고, 이미지가 svg여야 한다.

svg를 가지고 Fontello 같은 아이콘 폰트 생성 사이트에 가서 svg를 이용해 아이콘 폰트를 만든 다음 활용한다. 스택 오버플로의 이 답변을 참고하는 것이 좋다.

요지는 웹폰트를 넣은 다음 Cytoscape의 스타일 지정시 font-family를 아이콘 폰트 글꼴로 지정하라는 것이다(ex: 'font-family': 'fontello, D2Coding, sans-serif').

이 때 주의할 점이 있다. 토폴로지 실행 전에 아이콘 폰트가 한 번이라도 사용돼야 한다는 점이다. 그렇지 않으면 무의미한 네모가 나온다.

유니코드 코드 포인트

Fontello의 글자와 HTML String, CSS content 속성에서 사용하는 글자가 다르니 주의해야 한다. 아이콘 폰트를 만들어서 다운받고 압축을 풀어 demo.html을 브라우저에서 열고 소스를 보면 0xe801 같은 형식의 문자가 있다. 이런 형식의 문자를 유니코드 코드 포인트라고 하는데 정확히는 맨 뒤의 4글자가 코드 포인트다. 코드 포인트는 글자 번호라고 생각하면 된다.

e801번에는 할당된 문자가 없을 것이다. 이 번호가 속하는 번호대는 Private Use Area라고 하는데, 사적으로 쓸 수 있도록 비워 둔 번호대이다. 그래서 충돌 우려 없이 사용할 수 있다.

할당된 글자가 없으므로 e801번 글자를 표시하면 그냥 무의미한 네모가 나온다. 그런데 이 코드에 아이콘을 할당한 웹폰트를 만들어 아이콘을 표시하는 방법이 바로 아이콘 폰트다.

이제 코드 포인트로 글자를 표시하는 다양한 방법을 소개한다.

자바스크립트의 경우. Cytoscape.js를 사용하고 있다면 라벨 속성의 값으로 문자열을 리턴해 줘야 한다. 그럴 때는 '\ue801'처럼 맨 앞에 \u를 써 준다.

JS에서는 0xe801처럼 0x를 맨 앞에 붙이면 따옴표 없이도 사용할 수 있다. 16진수 숫자기 때문이다.

let codePoint = 0xe801;
console.log(codePoint); // 10진수 59393이 표시된다.
let unicodeChar = String.fromCodePoint(codePoint);
console.log(unicodeChar); // 이상한 네모 문자가 표시된다.

HTML에선 또 다르다. &#xe801;라고 써야 문자가 제대로 표시된다. HTML에선 &#x로 시작해서 ;로 끝나는 문자를 16진수로 표시하는 HTML 엔티티(쉽게 말해 특수문자를 표시하는 특수한 문자)로 해석하기 때문이다.

CSS 가상 선택자에서 content 속성에 넣을 때는 아래처럼 \e801처럼 맨 앞에 \를 써 줘야 한다.

.c-fontello--stop:before {
  content: '\e801';
}

👇 카테고리 글 목록

,

대표글

댓글 남기기