상세 컨텐츠

본문 제목

[Javascript/React] JSON으로 만든 XML을 그려보자(드디어) feat. D3

프론트 연구 노트

by bydawn25 2022. 6. 30. 09:30

본문

넉넉한 개발자 블로그의 효자 아이템! 

https://bydawn25.tistory.com/31

 

[Javascript/React] Parse XML to JSON / XML을 JSON으로 만들기

지금하고 있는 프로젝트에서 XML을 읽어서 해석해야하는 부분이 존재했다. 개발자 인생 XML은 정말 마주하고 싶지 않은 데이터 형식인데 애석하게도 예전 표준을 따르는 많은 디바이스들이 XML을

bydawn25.tistory.com

물론 ㅋㅋㅋㅋㅋㅋㅋ 그래봐야 전체 조회수가 500회 밖에 되지 않지만 덕분에 평균조회수가 15회를 웃돌고 있다.

 

다음 목표는 평균 조회수 30회!(소박)

 

확실히 글을 꾸준히 쓰니까 방문해 주시는 분들이 계속 계신다. 앞으로도 웹과 클라우드, 나아가 내가 관심있는 여러분야의 도전기를 꾸준히 올려야 겠다는 생각이 든다. ( •̀ ω •́ )✧

 

 

 

 

각설하고 저번 포스팅에 이어 Parsing된 결과를 가지고 D3라는 라이브러리를 이용하여 웹상에 그림을 그려보도록 하겠다.

 

D3란?

https://d3js.org/

 

D3.js - Data-Driven Documents

D3 is a JavaScript library for visualizing data with HTML, SVG, and CSS.

d3js.org

D3는 Javascript 라이브러리로써 웹 표준화 환경에 맞춰 "강력한 시각화"기능을 제공하는 툴이다.

 

여기서 강력한 시각화랑 웹 상에서 색깔을 지정하거나, 점을 찍거나, 선을 그리거나 나아가 시간에 따라 움직이는 동적인 역활까지 포함할 수 있겠다.

 

 

 

 

 

나의 목표는 아래와 같이 저번 포스팅에서 Parsing된 Json의 정보를 바탕으로 웹상에 고대로 그려주는 것이다.

 

내가 시작점을 정해주면 알아서 x,y좌표를 총총찾아가 xml상에서 요구하는 선을 그리거나, 점을 찍거나 해야한다. 이는 다행이 D3를 통해 구현 가능하다!

 

 

 

 

 

square : {
     coordination : "0,0",
     lineThickness: 1,
     bgColor : "255,255,255",
     width : 20,
     height : 20
}

아래의 json형태로 parsing된 데이터를 그려준다고 가정해보자.

우리는 사격형을 그려볼 것이다.

 

 

 

 

 

최종코드

---------------------------------------------------(1) 초기 데이터 설정하는 부분 -------------------------------------------
var height = 550;
let svg = d3.select(targetSvg);

svg
    .attr('width', '100%')
    .attr('height', height);

let dic = {};

//coordination
const coordination = targetObj.coordination.split(',').map(val => parseInt(val));
//width
const rectWidth = parseInt(targetObj.width);
//height
const rectHeight = parseInt(targetObj.height);
//stroke-width
const strokeWidth = parseInt(targetObj.lineThickness);
//color
const colorAry = targetObj.bgColor.split(",").map(item => parseInt(item));

dic['x'] = coordination[0];
dic['y'] = coordination[1];
dic['width'] = rectWidth;
dic['height'] = rectHeight;
dic['strokeWidth'] = strokeWidth;
dic['color'] = colorAry;

---------------------------------------------------(2) D3를 이용해서 그리는 부분 -------------------------------------------
//draw rectangle
svg.selectAll("rect")
        .data(dic)
        .enter()
        .append("rect")
        .attr("x", function(d) { return d.x;})
        .attr("y", function(d,i) { return d.y+5; })
        .attr("width", function(d,i) { return d.width; })
        .attr("height", function(d,i) { return d.height + 1; })
        .attr('stroke', 'black')
        .attr('stroke-width', function(d) { return d.strokeWidth;})
        .attr('fill',function(d) {
          return `rgb(${d.color[0]},${d.color[1]},${d.color[2]})`
        });

어렵지 않고 단순하다.

 

Json으로 이미 정리된 데이터를 d3로 사용하기 쉽게 dictionary화 하는 부분이 첫 단락이고 본격적으로 ㅇ3를 이용해 그리는 부분이 두번째 단락이다.

 

 

 

 

 

 

이번 예시에서는 사각형을 사용하여 rect 태그를 사용하였지만 사용자분들은 입맛에 맞게 도형을 그려낼 수 있으니 삼각형이나 동그라미 등 여러 도형을 그려낼 수 있다.

 

공식라이브러리 주소는 맨 위에 첨부하였으니 참고하시길 바란다. 그럼 본격적으로 코드를 설명에 들어가겠다.

 

 

 

 

 

(1) Dictionary화 및 초기설정하기

let svg = d3.select(targetSvg); //그리고자 하는 target svg 지정

D3는 Svg태그를 이용해 그림을 그린다. 필자는 render함수에 그리고자 하는 타겟 svg태그를 미리 설정해 주었다.

 

targetSvg라는 parameter로 그리고 싶은 부분의 svg를 함수로 전달받는 방법으로 구현했다.

 

 

 

 

var height = 550;

svg //svg 크기 설정
    .attr('width', '100%')
    .attr('height', height);

svg의 크기는 d3의 함수인 attr를 이용하여 가로는 꽉 차도록 설정하고 높이는 수동으로 설정해 주었다.

 

 

 

 

 

//coordination
const coordination = targetObj.coordination.split(',').map(val => parseInt(val));

dic['x'] = coordination[0];
dic['y'] = coordination[1];

json형태로 들어온 데이터는 d3가 읽고 적용하기에 적합하지 않다. 

 

x,y로 시작점을 잡아야 하는 coordination값들은 이대로 string으로 들어가버리면 d3가 읽을 수 없으므로 쉼표(,)를 인자로 잘라 각각 x와 y값으로 정리해 줬다.

 

 

 

 

 

//color
const colorAry = targetObj.bgColor.split(",").map(item => parseInt(item));

dic['color'] = colorAry;

color값도 rgb를 사용해야 하므로 사용하기 쉽도록 ary형태로 바꿔주었다.

 

 

 

 

//width
const rectWidth = parseInt(targetObj.width);
//height
const rectHeight = parseInt(targetObj.height);
//stroke-width
const strokeWidth = parseInt(targetObj.lineThickness);

dic['width'] = rectWidth;
dic['height'] = rectHeight;
dic['strokeWidth'] = strokeWidth;

나머지 값들은 따로 잘라서 처리를 해주지 않아도 되어 그냥 넣어주었다.

 

이렇게 하면 필요한 값들이 필요한 형태로 들어간 dictionary정리가 완료되었다.

 

 

 

 

(2) D3로 그려보기

사용하기 위한 데이터를 정제하는 과정은 길고 복잡했지만 막상 D3를 이용하는 부분은 그리 어렵지 않다 ㅋㅋㅋ

svg.selectAll("rect")
        .data(dic)
        .enter()
        .append("rect")
        .attr("x", function(d) { return d.x;}) //X좌표설정
        .attr("y", function(d,i) { return d.y+5; }) //Y좌표설정
        .attr("width", function(d,i) { return d.width; }) //width설정
        .attr("height", function(d,i) { return d.height + 1; }) //높이설정
        .attr('stroke', 'black')
        .attr('stroke-width', function(d) { return d.strokeWidth;}) //굵기설정
        .attr('fill',function(d) { //색깔설정
          return `rgb(${d.color[0]},${d.color[1]},${d.color[2]})`
        });

위의 구현은 d3의 공식라이브러를 참고하였다.

 

선택한 svg를 append하여 X축 설정, Y축 설정, 너비, 높이, 굵기, 색깔 순서로 찬찬히 설정해서 확장해 나가면 된다.

 

 

 

 

svg.selectAll("rect")
        .data(dic)
        .enter()
        .append("rect")

여기까지는 주어진 문법이다.

 

 

 

 

 

 .attr("x", function(d) { return d.x;})

attr function이 각 속성들을 설정할 수 있게 해준다. 여기 밑줄친곳에 x를 조절하고 싶으면 x를 y를 조절하고 싶으면 y를 삽입하면된다.

 

 

 

 

 

<d3완성본>

 

 

 

 

이렇게 하면 d3로 예쁜 사각형을 그려낼 수 있다! D3는 여기저기서 자주 사용하는 라이브러리니 한번쯤 연습삼아 사용해봐도 좋을 듯 하다.

 

다음편은 요 SVG를 프린터로 출력하는 방법을 알아보겠다.

 

 

 

 

 

 

관련글 더보기