d3js로 marker 정의해서 사용하기. 혹은 선에 arrow 추가하기.

d3js를 이용해서 화살표를 그려보려고 합니다.

  • 우리가 아는 대부분의 라이브러리들에서는 이 부분이 무척 쉽게 해결되었던 것 같은데, d3에서는 이 부분이 손쉽게 해결되지 않습니다.
  • 우선, 화살표라는 요소가 따로 존재하지 않습니다. 즉, 화살표를 그리기 위해서는 새로운 요소, 화살표의 머리 부분을 직접 정의해주어야 한다는말이 됩니다.
  • 즉, 새로운 svg를 만들어서 일종의 marker로서 만든다는 것을 의미하죠.
  • 이를 이용하면, 굳이 직접 만든 svg일 필요가 없고, 어떤 파일이든 svg라면, 선에 올려서 사용할 수 있다는 말이 됩니다.
  • 아무튼, 해보도록 하지요.

do it.

  • 의미적으로 설명하면 다음과 같습니다.
    • 대상 svg를 select
    • 추가하려는 marker의 아이디를 추가하고, 가로 세로 폭, viewbox 등을 정의함.
    • 해당 marker가 그려질 때, 그려지는 중심점이 어디인지를 정함(refX, refY)
    • 그 다음, 해당 marker를 그려줌.
      • polygon, path등 다양한 소스를 이용해서 그릴 수 있음.
<div>
    <!-- d3js -->
    <svg>
        
    </svg>
</div>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
    var svg = d3.select("svg");
    // 그림이 직접 그려지는 것이 아니고, 정의만 해주는 것입니다. 
    // 이후에 필요할 때 직접 가져와서 쓸수 있죠.
    svg.append("defs").append("marker")
        .attr("id", "arrow1") // 해당 요소의 id을 추가하고요. 
        .attr("markerUnits", "strokeWidth") 
        .attr("markerWidth", "12").attr("markerHeight", "12")// 너비와 높이를 정해주고, 
        .attr("viewBox", "0 0 12 12")//해당 개체가 어떻게 보여줄지 정하고, 
        .attr("refX", "6").attr("refY", "6") 
        // marker가 선에 그려질 경우 어떤 포인트에서 그려질지를 정합니다. 
        // 예를 들어, viewbox가 "0 0 12 12"인 상태에서 각각 6으로 잡을 경우에는 중점이 딱 떨어지게 되겠죠.
        .attr("orient", "auto")// 이걸 없애면 선의 방향에 맞춰서 그려지지 않습니다. 
    
    // 이제 해당 부분에 그려질 그림을 그려줍니다.
    // 아래처럼 반드시 하나의 그림만 추가될 필요는 없고, 여러 그림이 추가될 수 있습니다.
    var marker1 = d3.select("#arrow1");
        marker1.append("polygon")
            .attr("points", "0 0, 0 12, 12 12, 12 0")
            .attr("fill", "black");
        marker1.append("polygon")
            .attr("points", "0 0, 0 6, 6 6, 12 0, 0 0")
            .attr("fill", "blue");

    var line = svg.append("line")
        .attr("x1", 150).attr("y1", 10)
        .attr("x2", 200).attr("y2", 50)
        .attr("stroke", "red")
        .attr("stroke-width", 2)
        //이렇게 정의해서 사용할 수 있습니다.
        .attr("marker-end", "url(#arrow1)");

</script>

wrap-up

  • svg의 defs 내에 필요한 그림을 따로 넘겨서, 필요할때마다 가져와서 사용할 수 있다는 것을 배웠습니다.
  • d3js에서는 line의 특성에 arrow를 설정하는 것이 없고, 필요하다면 직접 새로운 마커를 정의하고 가져와서 사용해야 합니다.
  • 전반적으로 d3js는 필요한 모든 것을 하나하나 직접 정의해야 한다는 단점이 있다고 생각될 수 있지만, 그만큼 조금만 더 사용하면 활용도가 확 넓어진다는 강점 또한 있는 것 같습니다.

reference

댓글남기기