- 주의 -
1. 하위 컴포넌트에서 <template></template> 태그 없애기
2. axios로 전달받은 데이터가 화면에 부착 안될때는 v-if='true' 사용하기
3. <script>안에 해당 차트import 꼭 넣기

- 참고 사이트 -
1. vue-chart.js 사용예제(블로그) : https://chuckolet.tistory.com/8
2. vue-chart.js 공식사이트 : https://vue-chartjs.org/guide/#introduction
3. chart.js 공식사이트 : https://www.chartjs.org/docs/latest/general/responsive.html
4. chart.js 사용예제(블로그) : https://ming9mon.tistory.com/122?category=841705

상위 컴포넌트

// weather.vue

<template>
  <div class="all">

    <div class="canvas">
      <weather-chart v-bind:class="size" v-bind:weather="weather" v-bind:time="time" v-bind:temperature="temperature" v-if="loaded"/>
    </div>

  </div>
</template>

<script>
import {Line} from 'vue-chartjs'
import weatherChart from './weatherChart'

var axios = require('axios')
var cheerio = require('cheerio');

export default {
  extends: Line,
  components:{
    weatherChart
  },
  data() {
    return {
      number : '',
      temperature : [],
      weather: [],
      time : [],
      loaded: false,
      size: 'firstClass'
    }
  },

  methods: {
    getData: function(){
      axios.get('https://search.naver.com/search.naver?sm=top_hty&fbm=1&ie=utf8&query=%EB%82%A0%EC%94%A8')
      .then(res => {
        var $ = cheerio.load(res.data)
        this.loaded = true
        var number = $("#main_pack > div.sc.cs_weather._weather > div:nth-child(2) > div.weather_box > div.weather_area._mainArea > div.today_area._mainTabContent > div.table_info.bytime._todayWeatherByTime > div.info_list.weather_condition._tabContent > ul > li").length
        this.number = number
        for(var i=1; i<=number; i++){
          this.temperature.push($("#main_pack > div.sc.cs_weather._weather > div:nth-child(2) > div.weather_box > div.weather_area._mainArea > div.today_area._mainTabContent > div.table_info.bytime._todayWeatherByTime > div.info_list.weather_condition._tabContent > ul > li:nth-child("+i+") > dl > dd.weather_item._dotWrapper > span:nth-child(1)").text())
        }
        for(var i=1; i<=number; i++){
          this.weather.push($("#main_pack > div.sc.cs_weather._weather > div:nth-child(2) > div.weather_box > div.weather_area._mainArea > div.today_area._mainTabContent > div.table_info.bytime._todayWeatherByTime > div.info_list.weather_condition._tabContent > ul > li:nth-child("+i+") > dl > dd.item_condition > span").text())
        }
        for(var i=1; i<=number; i++){
          this.time.push($("#main_pack > div.sc.cs_weather._weather > div:nth-child(2) > div.weather_box > div.weather_area._mainArea > div.today_area._mainTabContent > div.table_info.bytime._todayWeatherByTime > div.info_list.weather_condition._tabContent > ul > li:nth-child("+i+") > dl > dd.item_time > span").text())
        }
      }) // axios 끝
    }, // getData함수 끝
  },
  mounted(){
    this.getData()
  }
}
</script>

<style scoped>
  .detail{
    display: flex;
    flex-direction: row;
    width: 600px;
  }
  .weather {
    padding-left: 27px;
  }
  .firstClass{
    padding-top: 30px;
    height: 150px;
    width: 700px;
  }

</style>

하위 컴포넌트

// weatherChart.vue

<script>
import {Line} from 'vue-chartjs'
export default {
  extends: Line,
  props:{
    time: {
      type: Array,
    },
    temperature: {
      type: Array
    }
  },
  data() {
    return {
      datacollection: {
        labels: this.time, // 가로축 데이터
        datasets: [
          {
            label: '온도', // 차트 상단에 차트 이름
            data: this.temperature, // 세로축 데이터
            backgroundColor: 'azure',
            borderColor: 'aqua',
          }
        ]
      }, // chart데이터 끝

      options: {
        responsive: true,
        maintainAspectRatio: false, // 차트 width, height 크기조절

        legend:{
          display:false, // 차트 위에 label 표시 여부
        },

        tooltips: {
				enabled: false // 차트에 마우스 올렷을때 데이터 표시 여부
			  },

  			hover: {
  				animationDuration: 0
  			},

  			animation: { // 데이터 항상 표시
  				duration: 1,
  				onComplete: function () {
  					var chartInstance = this.chart,
  					ctx = chartInstance.ctx;
  					ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
  					ctx.fillStyle = 'black';
  					ctx.textAlign = 'right';
  					ctx.textBaseline = 'bottom';

  					this.data.datasets.forEach(function (dataset, i) {
  						var meta = chartInstance.controller.getDatasetMeta(i);
  						meta.data.forEach(function (bar, index) {
  							var data = dataset.data[index];
  							ctx.fillText(data, bar._model.x, bar._model.y - 5);
  						});
  					});
  				}
  			},

        scales: {

          yAxes: [{
            // display: false, // y축 기준 표시 여부
            ticks: { // y축 기준 데이터 변경
              // beginAtZero:true,
              min: 0, // y축 최소값
						  // max: 13, // y축 최대값
              stepSize: 10, // y축 간격
						  fontSize : 12, // 글자크기
            },
            gridLines: {
              display: false, // 차트 안에 가로선 표시 여부
              drawBorder: false
            }
          }],

          xAxes: [{
            display: false,
            gridLines:{
              display: false,
              brawBorder:false
            }
          }]

        }, // scales 끝

      }, //옵션 끝

    } // 모든 data 끝
  },
  mounted(){
    this.renderChart(this.datacollection, this.options)
  }
}
</script>

<style scoped>

</style>

 

결과물

'라이브러리' 카테고리의 다른 글

Vuex(개념)  (0) 2020.12.15
Vuex(응용예제)  (0) 2020.04.27
Vuex(기본예제)  (0) 2020.04.27

+ Recent posts