Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue-chartjs is rendering my responsive chart too tall for my window

Tags:

vue-chartjs

I created a simple responsive HTML + JS chart with chart.js which worked well. I decided to do it within Vue CLI and so have tried to switch it to vue-chartjs but the same chart always renders about 33% taller than my window and so presents vertical scrollbars (the width is fine). I recreated the problem with a sample trivial graph which I render with:

import {Line} from 'vue-chartjs'
export default {
  extends: Line,
  mounted () {
    this.renderChart(data, options)
  } 
} 

Note the data is trivial and the options are {}.

If I use chart.js in my Vue component, instead of vue-chartjs then it works fine. I.e. I do nothing more than delete the above code from my component and change it to the following then it renders fine, just like my sample HTML + chart.js version.

import Chart from 'chart.js'
function mount(el) {
    return new Chart(
        document.getElementById(el).getContext('2d'), {
        type: 'line',
        data: data,
        options: options,
    })
}

export default {
    template: '<canvas id="chart"></canvas>',
    mounted () {
        self.chart = mount('chart')
    }
}

I am using the default responsive: true and maintainAspectRatio: false of course, and have no explicit CSS or size settings anywhere.

Why can I not get the chart to render the height correctly when I use vue-chartjs? I am using vue-chartjs version 3.4.2 but have also tried a few versions back. I have looked all over the github bug tracker but seen nothing related.

like image 548
bulletmark Avatar asked Apr 06 '19 01:04

bulletmark


People also ask

How do you change the size of a chart in Chartjs?

To set the chart size in ChartJS, we recommend using the responsive option, which makes the Chart fill its container. You must wrap the chart canvas tag in a div in order for responsive to take effect. You cannot set the canvas element size directly with responsive .


2 Answers

UPDATE:

You should pass the options as prop or locally. But it's needed to add:

  • responsive: true
  • maintainAspectRatio: false

the desired height as well as the options as you said. Here's how it worked for me:

options:

options: {
                    scales: {
                        yAxes: [
                            {
                                ticks: {
                                    beginAtZero: true
                                }
                            }]
                    },
                    responsive: true,
                    maintainAspectRatio: false
                }

In template:

<bin-graph-weight :chart-data="datacollection" :styles="myStyles" :options="datacollection.options"/>

graph-component.js:

import { Line, mixins } from 'vue-chartjs'

const { reactiveProp } = mixins

export default {
    extends: Line,
    mixins: [reactiveProp],
    props: ['options'],
    mounted () {
    // this.chartData is created in the mixin.
        this.renderChart(this.chartData, this.options)
    },
    // If you want to pass options please create a local options object
    watch: {
        chartData () {
            this.$data._chart.update()
        }
    }
}

like image 115
Despertaweb Avatar answered Dec 09 '22 16:12

Despertaweb


Also had problem with height overflow and responsiveness, fixed by introducing flex parent container that takes up 100% of the space. After setting responsive and ratio options (check out related chartjs doc):

options: {
  // ..
  responsive: true,
  maintainAspectRatio: true
}

I used following css to fill 100% of the parent (where TheChart is vue-chartjs component. Basically need to make sure the chart's parent is always filling 100% of it's own parent):

vue template

<v-container class="chart-container">
  <TheChart :chartdata="chartData" :options="chartOptions" />
</v-container>

scss:

.chart-container {
  flex-grow: 1;
  min-height: 0;

  > div {
    position: relative;
    height: 100%;
  }
}
like image 42
ego Avatar answered Dec 09 '22 17:12

ego