svg의 text 사용법, textspan을 이용해서 줄바꿈 해보기.

2 분 소요

svg에서 text를 사용하기.

  • 저는 입력받은 데이터를 이용해서 비교적 간단한 그래프를 그려주고, 특정 부분에 마우스를 올렸을 때 필요한 데이터가 뜨도록 하는 작업을 수행하고 있습니다.
  • 즉, 해당 요소 위에 마우스가 올라오면, 그 위치에 새로운 text 요소를 만들어주고, 마우스가 벗어나면 그 텍스트 요소의 id를 선택해서 지워주는 작업을 진행하고 있죠.
  • 일단 이 말만 보면 그렇게 어려운 일처럼 느껴지지는 않습니다.
  • 그러나, 해당 텍스트가 지나치게 길어질 경우에 문제점들이 발생하죠.
    • 예를 들어서, 줄바꿈이나, html의 기본 태그들(<br>)들이 먹히지 않는다는 단점이 있습니다. 마찬가지로 \n도 사용되지 않습니다.
  • 우선 더 진행하기 전에 text라는 요소부터 정확하게 알아보도록 합시다.

text tag in svg

  • 텍스트 태그는 그냥 svg 내에서 텍스트를 표시하기 위한 방법 중 하나입니다.
  • 기존의 html 에서는 p등으로 표시를 했는데, 이것과의 차이는 text의 경우 위치할 수 있는 좌표를 잡을 수 있다는 것이 차이죠.

  • 아래에서 몇 가지는 테스트 해봤습니다.
<html>
    <head>
        <script src="https://d3js.org/d3.v5.min.js"></script>
        <script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
    </head>
    <style>
        /* 
        - 가능하면 모든 svg도 div에 넣어서 처리해주는 것이 효과적임. 
        - 아래처럼 div에 넣어서 전체 크기를 세팅하고, 그 다음에 svg를 세팅하는 것이 가장 바람직함.
        */
        div{
            border:1px solid;
            height:100px;
        }
        svg{
            /*이미 상위 요소인 div에서 크기가 맞춰져 있기 때문에 모두 100%로 해두는 것이 좋음*/
            width:100%;
            height:100%;
        }
    </style>
    <body>
        <!--
            - 같은 태그지만, svg내에 있을 때와 svg 밖에 있을때 서로 다름. 
            - 즉, 기본적으로 text 태그는 svg 내에서만 유효하다고 생각하면 좋음. 
            - 해당 텍스트의 좌표, 색깔등을 지정할 수 있음.
        -->
        <div>
            <text x="100" y="15" fill="red">
                This is not text tag in svg
            </text>
        </div>
        <div>
            <svg>
                <text x="100" y="15" fill="red">
                    This is text in svg
                </text>
            </svg>
        </div>
        <div>
            <svg>
                <text x="100" y="15" fill="red">
                <!--
                - 아래처럼 텍스트가 길어질 경우에 그냥 전체 svg를 벗어나게 됩니다.
                - 당연하지만, Html 에서 줄바꿈이 있다고 해도 적용되지는 않죠.
                --> 
                    This is longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong text in svg
                </text>
            </svg>
        </div>
        <div>
            <svg>
                <text id="abcd" x="100" y="15" fill="red">
                    <!--
                    - javascript에서 스트링을 넣어준다고 해도,안 되는 것은 마찬가지입니다. 
                    - console.log를 통해서 출력할 때는 '\n'으로도 되는데, 그렇지 않을때는 안됩니다. 
                    - 특히, text 태그 내에서는 안됩니다. 
                    - 즉, 이를 해결하기 위해서는 tspan을 이용해서 구분해서 보여주는 것이 제일 좋은 것 같습니다. 
                    -->
                </text>
            </svg>
        </div>
        <div>
            <svg>
                <!--그 외에 tspan을 넣을 수도 있습니다.-->
                <text x="100" y="15" fill="red">
                    This is text in svg and more textspan
                    <!-- 좌표를 똑같이 지정했기 때문에 겹쳐서 나오게 됩니다.-->
                    <tspan x="200", y="100">First tspan</tspan>
                    <tspan x="200" , y="100">second tspan</tspan>
                </text>
            </svg>
        </div>
        <div>
            <svg>
                <!-- tspan은 text 태그 안에서만 유효합니다. 아래 코드는 보이지 안습니다.-->
                <tspan x="200" , y="100">This will be not shown</tspan>
            </svg>
        </div>
        <div>
            <svg>
                <!--이렇게 하면 보이죠. --> 
                <text>
                    <tspan x="200" , y="100">This will be shown</tspan>
                </text> 
            </svg>
        </div>
        <div>
            <svg id="with_script">
                <text id="target_text" x="100" y="15" fill="red">
                </text>
            </svg>
        </div>
        
        <script>
            d3.select("#abcd").text("longlong".repeat(20)+"\n"+"<br/>"+"bbb"+ "longlong".repeat(20));

            var str_lst = ["aaa", "bbb", "ccc"];
            var d_lst = [];
            for(var i=0;i< str_lst.length ;i=i+1){
                // 아래처럼 정확한 포지션을 넘기는 것이 아니라, %로 넘길 수도 있음.
                // 이렇게 해도 되는 건줄 알았으면 굳이 정확한 포지션을 잡지 않아도...후....
                // 배움에는 끝이 없다 하하하하하하하하
                d_lst.push({
                    "x":30*(i+1)+"%", "y":30*(i+1)+"%", "s":str_lst[i]
                })
            }
            d3.select("#with_script").select("text").selectAll("tspan").data(d_lst)
            .enter().append("tspan")
            .attr("x", function (d) { return d["x"] })
            .attr("y", function (d) { return d["y"] })
            // dx, dy는 각각 정해진 좌표에서 각 축으로 움직일 것인지를 의미하는듯.
            .attr("dx", function (d) { return "-30%" }) 
            .text(function(d){return d["s"]})


        </script>
    </body>
</html>

wrap-up

  • 정리하면 다음과 같습니다.
    • text는 svg 내에 포함되어 있어야 합니다.ㅏ
    • tspan은 text 내에만 들어갈 수 있습니다. 따로 있으면 안 보여집니다.
    • 좌표는 반드시 픽셀로 넣어야 하는 것이 아니고, x, y 모두 퍼센트를 가지고 넣을 수 있습니다.
    • text, tspan 모두 어떻게 해도 줄바꿈을 넣을 수 없습니다. 넣고 싶다면, 반드시 tspan을 사용해서 보여줘야만 합니다.

태그: ,

카테고리:

업데이트:

댓글남기기