score:9
The problem is the chart does not fit the new print width dimension. Fortunately we can perform a redraw when print is initiated.
The solution is to render your chart to an image using the canvas.toDataURL()
method when printing is invoked, then switch it back to the canvas chart after printing. More on toDataURL().
To detect when to invoke your functions webkit provide the method window.matchMedia('print')
(which will be true
during print or false
again afterwards) while other browsers use window.onbeforeprint
and window.onafterprint
. More on print methods.
All that is then left to do is ensure the image is responsive using CSS, i.e. scales to 100% width.
score:0
I used a custom print style for the canvas with a custom right padding:
@media print {
.chartCanvas {
padding-right: 1cm;
}
}
score:0
Following the links and Reggie Pinkham's example I was able to make this work in Angular 2. The example is in typescript but reader's should be able to adapt this to regular JavaScript fairly easily to work in other projects. Note I have only tested this in the latest version of Chrome on a Linux box as that is just fine for my internal company project.
// imports left out here
export class ScaleChartComponent implements OnInit {
private chart:Chart;
private chartNode:HTMLCanvasElement;
private chartImage:HTMLImageElement;
private mediaQueryListener:MediaQueryListListener;
// el is a reference to the root node of my angular html component think of it as just a div container.
constructor(private el:ElementRef) { }
ngOnDestroy() {
this.chart.clear();
this.chart.destroy();
this.chart = null;
this.cleanupPrint();
}
ngAfterViewInit() {
this.drawChart();
this.setupPrint();
}
// need to setup the event listeners here and hold a reference to cleanup afterwards.
public setupPrint() {
if (!window.matchMedia) {
return;
}
var mediaQueryList = window.matchMedia('print');
this.mediaQueryListener = this.handlePrintMediaChange.bind(this);
mediaQueryList.addListener(this.mediaQueryListener);
}
// make sure to cleanup the reference after the fact.
public cleanupPrint() {
if (!window.matchMedia) {
return;
}
var mediaQueryList = window.matchMedia('print');
mediaQueryList.removeListener(this.mediaQueryListener);
this.mediaQueryListener = null;
}
// here's where the magic happens. I first grab the image
// then
public handlePrintMediaChange(mql) {
if (mql.matches) {
let dataUrl = this.chartNode.toDataURL('image/png');
if (this.chartNode && this.chartNode.parentNode) {
this.chartImage = new Image();
this.chartImage.src = dataUrl;
this.chartNode.parentNode.appendChild(this.chartImage);
this.chartService.destroyChart(this.chart);
this.chartNode.parentNode.removeChild(this.chartNode);
}
} else {
// here is where we switch back to non print mode.
if (this.chartImage) {
if (this.chartImage.parentNode) {
this.chartImage.parentNode.removeChild(this.chartImage);
}
this.chartImage = null;
}
// go through and recreate the entire chart again.
this.drawChart();
}
}
public drawChart() {
var chartData = {}; // setup your chart data here.
this.chartNode = this.createChartNode();
if (this.chartNode) {
this.chart = ; // execute your chart.js draw commands here.
}
}
private createChartNode() {
let componentElement = this.el.nativeElement as Element;
let element = componentElement.querySelector(".scale-chart-container");
if (!element) {
console.error("could not find element with class .scale-chart-container");
return null;
}
let chartNode = document.createElement("canvas") as HTMLCanvasElement;
element.appendChild(chartNode);
chartNode = chartNode;
return chartNode;
}
}
Note that I've left out the Chart.js commands and data as that will vary based upon the person. I have an external service that deals with that which I've left out.
I hope this helps anyone who's scratching their head on how to go off of Reggie's answer.
score:0
Here's an easy fix based on Reggie's answer which is a little easier to implement than Stephen's answer:
//Fix chartjs printing:
window.onbeforeprint = (ev) => {
for (var id in Chart.instances) {
let instance = Chart.instances[id];
let b64 = instance.toBase64Image();
let i = new Image();
//Instead of the below, you could save something on the
//chart that decides what to change this to. This worked for me
//however:
i.style.maxWidth = "100vw";
i.src = b64;
let parent = instance.canvas.parentNode;
instance.tempImage = i;
instance.oldDisplay = instance.canvas.style.display;
instance.canvas.style.display = "none";
parent.appendChild(i);
}
};
window.onafterprint = (ev) => {
for (var id in Chart.instances) {
let instance = Chart.instances[id];
if (instance.tempImage) {
let parent = instance.canvas.parentNode;
parent.removeChild(instance.tempImage);
instance.canvas.style.display = instance.oldDisplay;
delete instance.oldDisplay;
delete instance.tempImage;
}
}
};
score:28
If your charts are simple, try using just using css
@media print {
canvas.chart-canvas {
min-height: 100%;
max-width: 100%;
max-height: 100%;
height: auto!important;
width: auto!important;
}
}
Source: stackoverflow.com
Related Query
- Resize chart.js canvas for printing
- Resize Chart Independently From Legend in ChartJS for Canvas Download
- (Vue, ChartJS) Create gradient background for chart from child component canvas context
- HorizontalBar chart is displayed below canvas when I set height with style attribute for chart div (Chart.js 2.9.4)
- Chart.js canvas resize of pie / doughnut chart
- attempting to change height and width of canvas for chart
- getting additional value fields from data source for dx.chartjs doughnut chart
- Height for chart area (not the canvas size)?
- Canvas is not defined for simple chart
- How to clear a chart from a canvas so that hover events cannot be triggered?
- Chart.js canvas resize
- How can labels/legends be added for all chart types in chart.js (chartjs.org)?
- Chart Js Change Label orientation on x-Axis for Line Charts
- Converting Chart.js canvas chart to image using .toDataUrl() results in blank image
- Chartjs random colors for each part of pie chart with data dynamically from database
- Chart.js how to show cursor pointer for labels & legends in line chart
- Chart JS - Use time for xAxes
- show label in tooltip but not in x axis for chartjs line chart
- How to add second Y-axis for Bar and Line chart in Chart.js?
- chart.js Line chart with different background colors for each section
- Chart JS - set start of week for x axis time series
- Problem for display a chart with Chart.js and Angular
- Can't resize react-chartjs-2 doughnut chart
- set background color to save canvas chart
- Chart js. How to change font styles for "labels" array?
- Different color for each column in angular-chartjs bar chart
- Border radius for the bar chart in ChartJS
- Chart JS show multiple data points for the same label
- Chart.js tooltip hover customization for mixed chart
- Can I specify a different font size for each row of text in Chart Title?
More Query from same tag
- I cant get Legend to work for my chartjs donut chart
- How do i make a new chart by pressing a button (chart.js)?
- Prevent chart.js "jumping"
- Chart.js label and point getting cutoff on the right
- How to add unused data background to bar in chart js
- How to provide empty values for Chart.js data?
- Chartjs with Node.js : Unexpected token <
- Chart.js the value on the graph does not disappear when deselected
- How to connect a charts.js chart to data
- Displaying line chart for multiple datasets using chart.js
- chart.js - user add the final point of the line
- Change chartType onclick ChartJS
- Display API data in line charts dynamically
- Attach data to label (Chart.js & Django 3)
- chartjs: How to create single outer border for stacked barchart
- break y axis in line chart chart.js
- Tiny error in the ChartJs book
- Hide x-axis when it has no value on chart.js
- how to add extra label at zero levels in x-axis in chartjs
- How to decrease the interval for Horizontal Stacked bar in ChartNew.js?
- npm chart.js is big after minimization
- Chart.js how to display % on tooltip
- Chart.js tooltip yAlign
- Chart JS Line insert Picture
- Plotting Real Time data using Flask Chart.js
- Duplicate of legends are Produced in ng2 chart
- ERROR TypeError: Cannot read property 'nativeElement' of undefined in Ionic 5 and chart.js
- Strange issue with Chart.js bar chart, image scattering
- React-chartjs-2: How to display timeline of released dates over 5 past years in Bar Chart?
- chart.js? Specifically Radar Charta and Negative Numbers