Vue.js + SVG로 꺾은선형 차트 그리기

자신이 개발하고 있는 서비스(Vue를 주로 사용)로 분석계의 기능을 만들 때
"역시 이것, 세로 꺾은 선 그래프가 가장 알기 쉽다"
그럼, 구구 ...
그러나, 그대로 사용할 수 있는 것 같은 패키지는 발견되지 않고, 자전으로 만드는 것을 결의.

Vue의 공식 페이지에 SVG로 그려진 그래프 가 있었으므로 해 보았습니다.

샘플




htps : // js 푹 dぇ. 네 t/와ょㅇ 7K/5th9k53/

SVG란?



SVG는 이미지 포맷 중 하나이기도 하며, XML을 사용한 마크업 언어이기도 하며, 그 중에는 HTML이나 CSS와 같은 감각으로 쓸 수 있는 것도 있습니다. 예를 들어, 이렇게 :hover 도 사용할 수 있습니다. ※샘플의 점 부분에 마우스를 올려 보세요.

또한 HTML과 마찬가지로 JavaScript로 제어할 수 있기 때문에 이번에는 Vue.js를 사용하여 꺾은선형 차트를 그려갑니다.

샘플 데이터 준비



0~100의 수치를 5개씩 적당히 준비했습니다. (꼭 랜덤 함수 사용해 주세요.)

JavaScript | 3 행 ~
data: {
  all_data: [
    {
      type: 'a',
      scores: [34, 46, 28, 39, 60]    
    },
    {
      type: 'b',
      scores: [47, 32, 52, 33, 52]
    },
    {
      type: 'c',
      scores: [38, 29, 42, 53, 41]
    },
    {
      type: 'd',
      scores: [52, 57, 69, 48, 46]
    }
  ],
  ratio: 3, //横幅を3倍に拡大するために使う
  row_height: 30,
},

SVG 토대 준비



HTML | 두 번째 줄 ~
<svg :width="100 * ratio"
  :height="svgHeight"
  :viewBox="'0 0 ' + 100 * ratio + ' ' + svgHeight"
  class="line-graph">
  <!-- ... -->
</svg>
widthheight는 화면에 표시되는 크기를 나타냅니다.
viewBox 는 어디에서 어디까지를 잘라 채우는지를 나타내, viewBox="x y width height" 와 같이 4 개의 값을 지정합니다.
x: viewBox 왼쪽 상단의 x 좌표
y: viewBox 왼쪽 위의 y 좌표
width: viewBox 너비
height: viewBox 높이

이번은 0~100의 데이터를 취급하고 있습니다만, 그대로는 너무 작기 때문에 3배( ratio: 3 )로 해 표시시킵니다. 높이는 그래프의 점의 수에 맞추어 계산해 내고 싶습니다.


JavaScript | 25 행 ~
svgHeight(){
  return (this.all_data[0].scores.length - 1) * this.row_height
}
all_data 첫번째 scores 의 데이터의 수를 참조해 계산해, 이 :height="svgHeight" :viewBox="'0 0 ' + 100 * ratio + ' ' + svgHeight" 2 개의 값을 넣었습니다.

하나의 꺾은선형 차트를 그룹화하고 반복





HTML | 6 행 ~
<g v-for="data in all_data" :class="'type-' + data.type">
  <!-- ... -->
</g>

SVG의 g 요소는 자식 요소를 묶는 것으로, 소위 "그룹화"입니다. 이미지와 같은 1개의 꺾은선형 차트를 1개의 그룹으로서 v-for 를 활용해, 4개분 반복해 줍니다.:class="'type-' + data.type" 로 하는 것으로, 1개씩에 .type-a , .type-b 라고 하는 각각 다른 class를 부여해, 색을 바꾸고 있습니다.

사이의 선과 점을 그룹화하고 반복





HTML | 7 행 ~
<g v-for="(score, index) in data.scores" :key="index">
  <line v-if="index != 0"
    :x1="data.scores[index - 1] * ratio"
    :y1="(index - 1) * row_height"
    :x2="score * ratio"
    :y2="index * row_height"/>
  <circle
    :cx="score * ratio"
    :cy="index * row_height"/>
</g>

하나의 그래프에서 사이를 연결하는 선(line)과 점(circle)을 그룹화하고 데이터 수만큼 반복합니다.

line 요소는 시작점과 끝점의 좌표를 지정하여 그릴 수 있습니다. 이 경우, 시작점은 1개 전의 점의 위치이므로, index - 1 로 x 좌표·y 좌표 각각의 값을 구하고 있습니다. v-forindex 를 전달하면 자신이 몇 번째 데이터인지 알 수 있습니다.
또, 1 번째의 line 는 불필요하므로 v-if="index != 0" 그리고 그리지 않게 합니다.

circle 요소는 원의 중심 좌표와 반지름을 지정하여 그릴 수 있습니다. 반경 r은 CSS로 지정했습니다.

이 경우 "x2 = cx", "y2 = cy"입니다.

요약



「각 속성에 적절한 좌표를 넣으면 그릴 수 있다」라는 당연한 것을 깨달았으므로, 큰 수확입니다. 시간이 많이 걸리지 않고 그래프를 만들 수 있었습니다.

좋은 웹페이지 즐겨찾기