dev

2. ChatGPT Vue 3 + D3 라인 차트에 애니메이션 효과 넣기

뫼B우스 2023. 2. 5. 13:38
반응형

ChatGPT에서 제시한 예제 코드로 Vue 3에서 D3 라인 차트를 만들어 보았다.

2023.02.03 - [D3] - 1. ChatGPT 를 이용한 Vue3 + D3.js Line Chart 예제 코드 만들기

1. ChatGPT 를 이용한 Vue3 + D3.js  Line Chart 예제 코드 만들기

차트 라이브러리를 활용하여 데이터 시각화 (Chart)를 해보려고 한다. 필자의 레벨은 HTML+CSS+JavaScript 등 전부 초급이다. 초급 중에 왕 초급... 데이터 시각화 사이트를 만들기 위해 여러 개발 도구

datapuzzler.tistory.com

개인적으로 생각하는 D3의 강점은 애니메이션 효과를 넣어 동적으로 시각화 할 수 있다는 것이다.

ChatGPT 제시한 예제 코드를 바탕으로 라인 차트에 애니메이션 기능을 추가하고자 한다.


1. 라인 차트 예제 코드에서 데이터값이 적은 관계로 1년치 데이터를 생성한다.

      data: [
        { date: new Date('2020-01-01'), value: 50 },
        { date: new Date('2020-02-01'), value: 60 },
        { date: new Date('2020-03-01'), value: 55 },
        { date: new Date('2020-04-01'), value: 75 },
        { date: new Date('2020-05-01'), value: 68 },
        { date: new Date('2020-06-01'), value: 65 },
        { date: new Date('2020-07-01'), value: 60 },
        { date: new Date('2020-08-01'), value: 65 },
        { date: new Date('2020-09-01'), value: 60 },
        { date: new Date('2020-10-01'), value: 40 },
        { date: new Date('2020-11-01'), value: 50 },
        { date: new Date('2020-12-01'), value: 60 },
      ],


2. ChatGPT 예제 코드가 동작 안한 이유는 width, height 값이 0,0 이기 때문이었다. 적당한 값을 정의해주면 라인차트가 그려진다.

//    const svgWidth = +svgContainer.attr('width');
//    const svgHeight = +svgContainer.attr('height');
    const svgWidth = 1000
    const svgHeight = 400

테스트 용이기 때문에 적당한 값을 바로 입력했다.

3. 애니메이션 효과를 넣기 위해 ChatGPT에 물어봤다.

ㅠㅠ 제시한 코드는 다음과 같다.

<template>
  <div>
    <svg ref="svgContainer"></svg>
  </div>
</template>

<script>
import * as d3 from 'd3';

export default {
  name: 'LineChart',
  data() {
    return {
      data: [
        { date: new Date('2020-01-01'), value: 50 },
        { date: new Date('2020-02-01'), value: 60 },
        { date: new Date('2020-03-01'), value: 55 },
        { date: new Date('2020-04-01'), value: 75 },
        { date: new Date('2020-05-01'), value: 68 },
      ],
    };
  },
  mounted() {
    const svgContainer = d3.select(this.$refs.svgContainer);

    const svgWidth = +svgContainer.attr('width');
    const svgHeight = +svgContainer.attr('height');

    const margin = { top: 20, right: 20, bottom: 30, left: 50 };
    const width = svgWidth - margin.left - margin.right;
    const height = svgHeight - margin.top - margin.bottom;

    const g = svgContainer
      .append('g')
      .attr('transform', `translate(${margin.left},${margin.top})`);

    const x = d3.scaleTime().rangeRound([0, width]);
    const y = d3.scaleLinear().rangeRound([height, 0]);

    const line = d3
      .line()
      .x(d => x(d.date))
      .y(d => y(d.value));

    x.domain(d3.extent(this.data, d => d.date));
    y.domain(d3.extent(this.data, d => d.value));

    g.append('g')
      .attr('transform', `translate(0,${height})`)
      .call(d3.axisBottom(x))
      .select('.domain')
      .remove();

    g.append('g')
      .call(d3.axisLeft(y))
      .append('text')
      .attr('fill', '#000')
      .attr('transform', 'rotate(-90)')
      .attr('y', 6)
      .attr('dy', '0.71em')
      .attr('text-anchor', 'end')
      .text('Value');

    const path = g
      .append('path')
      .datum(this.data)
      .attr('fill', 'none')
      .attr('stroke', 'steelblue')
      .attr('stroke-linejoin', 'round')
      .attr('stroke-linecap', 'round')
      .attr('stroke-width', 1.5)
      .attr('d', line)

</script> 를 먹어버린 오류는 또 다시 나타났고, 반복적으로 물어보아도 비슷한 답을 제시하였다.

마지막 코드에서
const path = g ~~~~ 하고 뭔가를 시도하려 하지만, 아직 학습이 완료되진 않은 듯 했다.
아님 질문을 잘못했을 수도 있다.

그럼 초짜인 나는 어떻게 해야 하나? ㅠㅠ

4. 수정된 애니메이션 라인 차트
- 라인에 커브를 주고 (보기 좋으라고)

    const line = d3
      .line()
      .curve(d3.curveCatmullRom.alpha(0.5)) //추가 
      .x(d => x(d.date))
      .y(d => y(d.value));

- ChatGPT 제시한 코드에 애니메이션 효과 추가

    const path = g.append('path')
      .datum(this.data)
      .attr('fill', 'none')
      .attr('stroke', 'black')
      .attr('stroke-linejoin', 'round')
      .attr('stroke-linecap', 'round')
      .attr('stroke-width', 1.5)
      .attr('d', line);

// 이하 추가
    const pathLength = path.node().getTotalLength();

    const transitionPath = d3
        .transition()
        .duration(2500)
        .ease(d3.easeLinear);

    path
        .attr("stroke-dashoffset", pathLength)
        .attr("stroke-dasharray", pathLength)
        .transition(transitionPath)
        .transition()
        .attr("stroke-dashoffset", 0)
        .attr("d", line);


이렇게 수정하니 다음과 같은 애니메이션 라인 차트 완성 !


어찌됐든 애니메이션 라인 차트 예제 코드는 완성하였다. ㅠㅠ

반응형