victorgarciaesgi / vue-chart-3

📊 A simple wrapper around Chart.js 3 for Vue 2 & 3
https://vue-chart-3.netlify.app/
MIT License
310 stars 112 forks source link

LineChart background gradient fail #136

Open h3clikejava opened 2 years ago

h3clikejava commented 2 years ago

When loading the chart for the first time, it is normal, but after clicking the shuffle button, it will be abnormal.

<template>
  <div id="app" style="width: 400px">
    <button @click="shuffleData">Shuffle</button>
    <LineChart v-bind="lineChartProps" />
  </div>
</template>

<script>
import { Chart, registerables } from 'chart.js';
import { LineChart, useLineChart } from 'vue-chart-3';
import { ref, computed, defineComponent } from 'vue';
import { shuffle } from 'lodash';

Chart.register(...registerables);

export default defineComponent({
  name: 'App',
  components: {
    LineChart,
  },
  setup() {
    const data = ref([30, 40, 60, 70, 5]);

    const chartData = computed(() => ({
      labels: ['Paris', 'Nîmes', 'Toulon', 'Perpignan', 'Autre'],
      datasets: [
        {
          data: data.value,
          backgroundColor: function(context) {
            const chart = context.chart;
            const {ctx, chartArea} = chart;

            if (!chartArea) {
              // This case happens on initial chart load
              return;
            }
            var gradient = ctx.createLinearGradient(0, 0, 0, 400);
              gradient.addColorStop(0, 'red');
              gradient.addColorStop(1, 'transparent');

            return gradient;
          },
          fill: true,
        },
      ],
    }));

    const { lineChartProps, lineChartRef } = useLineChart({
      chartData,
    });

    function shuffleData() {
      data.value = shuffle(data.value);
    }

    return { shuffleData, lineChartProps, lineChartRef };
  },
});
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>