apertureless / vue-chartjs

📊 Vue.js wrapper for Chart.js
https://vue-chartjs.org
MIT License
5.55k stars 837 forks source link

Charts initially rendering fine but not after calling page again (only be resizing) #482

Closed MarcWeller closed 5 years ago

MarcWeller commented 5 years ago

Hi *,

I am currently developing a CoreUI based single page application and I am working on a dashboard containing some charts receiving there date via axios call.

Expected Behavior

I would like the charts to be rendered when I call the dashboard component. This is currently working. I need this to work after leaving the dashboard component and coming back to it again.

Actual Behavior

When first opening the dashboard the chart isrendered fine. Then I use vue router to go to another compontent and go back to the dashboard the chart are not rendered. Something I noticed: Canvas height is not set due to developer tools.

As far as I see data and options are there.

As soon as I change the browsers width the chart is rendered, but depending on the width the charts are not rendered within the canvas.

Here ist what my code looks like: ($navapi being axios...)

OrderCountLine.vue

<div class="animated fadeIn">
        <b-row>
        <b-col sm="6" lg="3">
            <b-card no-body class="bg-info">
            <b-card-body class="pb-0">
                <h4 class="mb-0">{{orderCount}}</h4>
                <p v-if="orderCount == 1">Order</p>
                <p v-else>Orders</p>
            </b-card-body>
            <order-count-line v-if="loaded" chartId="card-chart-02" class="chart-wrapper px-3" :chartdata="chartdataLine" style="height:70px;" :height="70" />
            </b-card>
        </b-col>
</template>

<script>
export default {
  name: 'dashboard',
  components: {
    OrderCountLine
  },
  data: function () {
    return {
      loaded: false,
      chartdataLine: null,
      orderCount: this.orderCount
    }}
  ,
  async mounted () {
      this.loaded = false

      try {
            var orderCountdata = []
            Date.prototype.addDays = function(days) {
              var date = new Date(this.valueOf());
              date.setDate(date.getDate() + days);
              return date;
            }

            var today = new Date();
            var lastSevenDays = [];
            var i;
            for(i = -8; i < -1; i++){
              lastSevenDays.push(this.$t('general.Dates.WeekdayNames.'+today.addDays(i).getDay().toString() ))
            }  

            this.$navapi.get("myURL")
            .then(response => {
               var data = response.data["value"][0]
               orderCountdata.push(data.CountSalesShipmentPerDay7)
               orderCountdata.push(data.CountSalesShipmentPerDay6)
               orderCountdata.push(data.CountSalesShipmentPerDay5)
               orderCountdata.push(data.CountSalesShipmentPerDay4)
               orderCountdata.push(data.CountSalesShipmentPerDay3)
               orderCountdata.push(data.CountSalesShipmentPerDay2)
               orderCountdata.push(data.CountSalesShipmentPerDay1)
               this.orderCount = data.CountSalesShipmentPerDay7 + data.CountSalesShipmentPerDay6 + data.CountSalesShipmentPerDay5 + data.CountSalesShipmentPerDay4 + data.CountSalesShipmentPerDay3 + data.CountSalesShipmentPerDay2 + data.CountSalesShipmentPerDay1
               this.loaded = true
            });
            var orderCountDataLine = 
            {
              labels: lastSevenDays,
              datasets:[
                {
                  label: this.$t('widget.orders'),
                  backgroundColor: getStyle('--light-blue') || '#63c2de',
                  borderColor: 'rgba(255,255,255,.55)',
                  data: orderCountdata
                }
              ]
            }

            this.chartdataLine = orderCountDataLine
            this.loaded = true
            this.orderCount = this.warnings
      } catch (e) {
        console.error(e)
        this.loaded = false
      }
  }
}

</script>

OrderCountLine.vue

<script>
import { Line } from 'vue-chartjs'
import { CustomTooltips } from '@coreui/coreui-plugin-chartjs-custom-tooltips'

export default {

  extends: Line,
  props: {
      height: {
        type: Number,
        required: false
      },
      width: {
        type: Number,
        required: false
      },
      chartdata: {
        type: Object,
        default: null
      },
  },
  mounted () {

    this.renderChart(this.chartdata,
      {
        tooltips: {
          enabled: false,
          custom: CustomTooltips
        },
        responsive: true,
        maintainAspectRatio: true,
        legend: {
          display: false
        },
        scales: {
          xAxes: [
            {
              gridLines: {
                color: 'transparent',
                zeroLineColor: 'transparent'
              },
              ticks: {
                fontSize: 2,
                fontColor: 'transparent'
              }
            }
          ],
          yAxes: [
            {
              display: false,
              ticks: {
                min: 0,
                beginAtZero: true,
                display: false,
                //min: Math.min.apply(Math, this.chartdata.datasets[0].data) - 5,
                //max: Math.max.apply(Math, this.chartdata.datasets[0].data) + 5
              }
            }
          ]
        },
        elements: {
          line: {
            tension: 0.00001,
            borderWidth: 1
          },
          point: {
            radius: 4,
            hitRadius: 10,
            hoverRadius: 4
          }
        }
      }
    )
  }
}
</script>

Environment

MarcWeller commented 5 years ago

Sorry, should have set this.loaded only once. Within .then...

Although it is rendered each time it does not render correctly after resizing the page. Canvas ist outside the b-card element.

MarcWeller commented 5 years ago

MaintainAspectRatio needs to be set to false.