Search code examples
vue.jsprintingchart.jsvue-chartjs

Is it possible to print a chart with vue-chartjs?


I am using vue-chartjs to render graphs on a webapp. I know you can print charts if you are using the original library. However I have no idea on how to do it with the vue version of the library.

I have my charts variable on an external charts.js file

import {Bar, mixins } from 'vue-chartjs'
Chart.defaults.global
let chartOptions = Chart.defaults.global;   
const { reactiveProp } = mixins
export default {
   extends: Bar,
   mixins: [reactiveProp],
   props: ['options'],

   mounted () {
    let that = this;
    that.chartOptions = {
      scales: {
        yAxes: [{
            ticks: {
                suggestedMin: 0,  
                fontFamily: "'Overpass_Mono', 'Monaco', monospace",
                fontColor: "rgba(254, 255, 248, 0.5)"
            },
            gridLines: {
                color: 'rgba(255, 80, 248, 0.08)',
                zeroLineColor: 'rgb(168, 119, 181)',
                 zeroLineWidth: 2
            },
        }],
        xAxes: [{
            ticks: {
                suggestedMin: 0,    
                 fontColor: "rgb(168, 119, 181)"

            },
            gridLines: {
                color: 'rgba(255, 80, 248, 0.08)',
                zeroLineColor: 'transparent',
            }
        }],
    },
    legend: {
        labels: {
            fontColor: 'rgb(168, 119, 181)',
        }
    }
  },
    this.renderChart(this.chartData, that.chartOptions)
  }
}

Then on my component template I have:

<template>
    <div class="report">
        <charts v-if="todaySelected"
                :chart-id="'total_visits_chart_bar'" 
                :height="chartsHeight" 
                :options="chartOptions"
                :chart-data="datacollection" 
        ></charts>
        <div v-if="todaySelected">
        <button @click="printChart(charts)">Print chart</button>
    </div>
</template>
<script>
import charts from './chart_0.js'
    components: {
       charts,
    },
    data() {
        return{
             datacollection: {"datasets":[{"label":"Entries Today","data":[15,15,15,0]},{"label":"Currently Inside","data":[2,2,2,0]}],"labels":[]}
        }
     }.
 methods: {
     printChart(charts) {
        charts.print();
     },
  }
</script>

Any help would be appreciated.


Solution

  • The answer is: Yes, it is. Your print method in the components' script could be:

    methods:{
      printChart() {
        var canvasEle = document.getElementById('total_visits_chart_bar');
        var win = window.open('', 'Print', 'height=600,width=800');
        win.document.write("<br><img src='" + canvasEle.toDataURL() + "' />");
        setTimeout(function(){ //giving it 200 milliseconds time to load
                win.document.close();
                win.focus()
                win.print();
                win.location.reload()
        }, 200);  
      },
    }
    

    You can also add this to your component's style:

    @media print{
        @page {
            size: landscape
            }
    }