VueJS + Chart js - Диаграмма отображается только после изменения кода - PullRequest
0 голосов
/ 12 марта 2020

Я использую следующее руководство (статистика загрузки по запросу для пакетов NPM), чтобы создать основу для моего веб-приложения, указанного в таблице:

Я извлек приведенный ниже код из учебника и изменил его так, чтобы он делал чистые основы. Получить данные и представить данные. В частности, из этих:

Пожалуйста, примечание: Код выполняет вызов API и извлекает данные без проблем. Однако эти данные будут отображены в диаграмме только в том случае, если я внесу изменение в код. Например, изменив цвет линии на что-то другое. Кажется, он работает только в следующем «цикле», если это имеет смысл. Как только данные рендерится, если я обновлю sh, эта страница снова станет пустой. Я подозреваю, что это как-то связано с синхронизацией страниц. Однако не уверен, с чего начать или что я ищу.

Приложение. Vue

<template>
  <v-app style="background-color: rgb(228, 228, 228);">
    <section class="One">    
      <v-card class="One" color="rgb(255, 255, 255)" >

            <LineChart :chart-data="downloads" :chart-labels="labels"/>

      </v-card>
    </section>    
   </v-app>
</template>



<script>
import axios from 'axios';
import LineChart from  './components/test3.vue';


export default {
  name: 'App',

  components: { 
    LineChart,

  },
    data () {
      return {
        package: '',
        packageName: '',
        loaded: false,
        loading: false,
        downloads: [],
        downloadsYear: [],
        downloadsMonth: [],
        downloadsWeek: [],
        labels: [],
        labelsYear: [],
        labelsMonth: [],
        labelsWeek: [],
        showError: false,
        showSettings: false,
        errorMessage: 'Please enter a package name',
        periodStart: '',
        periodEnd: new Date(),
        rawData: '',
        totalDownloads: '',
        dailyPng: null,
        weeklyPng: null,
        monthlyPng: null,
        yearlyPng: null
      }
    },

mounted(){

        this.loaded = false
        axios.get(`https://api.npmjs.org/downloads/range/2017-01-01:2017-04-19/vue`)
          .then(response => {
            this.rawData = response.data.downloads
            this.downloads = response.data.downloads.map(entry => entry.downloads)
            this.labels = response.data.downloads.map(entry => entry.day)
            this.packageName = response.data.package
            this.totalDownloads = this.downloads.reduce((total, download) => total + download)
            this.setURL()
            this.groupDataByDate()
            this.loaded = true
            this.loading = false
          })
          .catch(err => {
            this.errorMessage = err.response.data.error
            this.loading = false
          })
      },
};

</script>

Компонент диаграммы:

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

  export default {
    extends: Line,

    props: {
      chartData: {
        type: Array,
        required: false
      },
      chartLabels: {
        type: Array,
        required: true
      }
    },
    data () {
      return {
        gradient: null,
        options: {
          showScale: true,
          scales: {
            yAxes: [{
              ticks: {
                beginAtZero: false,

              },
              gridLines: {
                display: true,
                color: '#EEF0F4',
                borderDash: [5, 15]
              }
            }],
            xAxes: [ {
              gridLines: {
                display: true,
                color: '#EEF0F4',
                borderDash: [5, 15]
              }
            }]
          },
          tooltips: {
            backgroundColor: '#4F5565',
            titleFontStyle: 'normal',
            titleFontSize: 18,
            bodyFontFamily: "'Proxima Nova', sans-serif",
            cornerRadius: 3,
            bodyFontColor: '#20C4C8',
            bodyFontSize: 14,
            xPadding: 14,
            yPadding: 14,
            displayColors: false,
            mode: 'index',
            intersect: false,
            callbacks: {
              title: tooltipItem => {
                return `? ${tooltipItem[0].xLabel}`
              },
              label: (tooltipItem, data) => {
                let dataset = data.datasets[tooltipItem.datasetIndex]
                let currentValue = dataset.data[tooltipItem.index]
                return `? ${currentValue.toLocaleString()}`
              }
            }
          },
          legend: {
            display: false
          },
          responsive: true,
          maintainAspectRatio: false
        }
      }
    },
    mounted () {
      this.gradient = this.$refs.canvas
        .getContext('2d')
        .createLinearGradient(0, 0, 0, 450)
      this.gradient.addColorStop(0, 'rgba(52, 217, 221, 0.6)')
      this.gradient.addColorStop(0.5, 'rgba(52, 217, 221, 0.25)')
      this.gradient.addColorStop(1, 'rgba(52, 217, 221, 0)')
      this.renderChart({
        labels: this.chartLabels,
        datasets: [
          {
            label: 'downloads',
            borderColor: '#249EBF',
            pointBackgroundColor: 'rgba(0,0,0,0)',
            pointBorderColor: 'rgba(0,0,0,0)',
            pointHoverBorderColor: '#249EBF',
            pointHoverBackgroundColor: '#fff',
            pointHoverRadius: 4,
            pointHitRadius: 10,
            pointHoverBorderWidth: 1,
            borderWidth: 1,
            backgroundColor: this.gradient,
            data: this.chartData
          }
        ]
      }, this.options)
      setTimeout(() => {
        this.download()
      }, 500)
    },
    methods: {
      formatNumber (num) {
        let numString = Math.round(num).toString()
        let numberFormatMapping = [[6, 'm'], [3, 'k']]
        for (let [numberOfDigits, replacement] of numberFormatMapping) {
          if (numString.length > numberOfDigits) {
            let decimal = ''
            if (numString[numString.length - numberOfDigits] !== '0') {
              decimal = '.' + numString[numString.length - numberOfDigits]
            }
            numString = numString.substr(0, numString.length - numberOfDigits) + decimal + replacement
            break
          }
        }
        return numString
      }
    }
  }
</script>

1 Ответ

1 голос
/ 12 марта 2020

Вам необходимо уведомить дочерний компонент о повторной визуализации. добавить watcher можно только одним способом, следить за изменением данных и обновлять их.

Еще один более простой способ - добавить к нему key реквизит.

в вашем App.vue, сделайте так:

 <LineChart :chart-data="downloads" :chart-labels="labels" :key="downloads.length"/>

здесь я использую длину downloads в качестве ключевого значения. это простое и временное разрешение, чтобы показать вам, как использовать key. В вашем приложении вы должны использовать какое-то другое значение в качестве ключа, в случае если различные вызовы API возвращают данные одинаковой длины.

Вы также можете установить ключ на другое значение и изменять это значение каждый раз, когда вы вызываете API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...