score:1
Taking these suggestions, I wanted to offer a 3rd approach that should solve some of the shortcomings of the previous answers in conjunction with other solutions I have seen elsewhere, resulting in what worked for me (that the above did not).
Setting window.onbeforeprint
is fine, unless you have other onbeforeprint
handlers and don't want to blow them away. window.addEventListener('onbeforeprint', function)
allows you to both set numerous separate event listeners, AND remove them when you're done. Additionally, Safari does not support these specific event listeners anyways, so it is recommended to use window.matchMedia
instead, which is supported on all evergreen browsers.
function _setupPrintHandler() {
let chart; // save a local copy so you don't have to find the element again.
var beforePrint = function() {
chart = $('#container').highcharts();
if (chart) {
// Set your arbitrary width/height needed for printing
// Save the existing chart info if explicitly set
// beforeChartWidth = chart.chartWidth;
// beforeChartHeight = chart.chartHeight;
const printWidth = 710, printHeight = 450;
chart.setSize(printWidth, printHeight, false);
chart.reflow()
}
};
var afterPrint = function() {
if (chart) {
// if the previous values were saved, use them, otherwise `null` will return to auto-fit the container size
const prevWidth = beforeChartWidth || null;
const prevHeight = beforeChartHeight || null;
chart.setSize(prevWidth, prevHeight, false);
chart.reflow();
}
};
// use the new window.matchMedia query with better support
if (window.matchMedia) {
var mediaQueryList = window.matchMedia('print');
mediaQueryList.addListener(function(mql) {
if (mql.matches) {
beforePrint();
} else {
afterPrint();
}
});
}
// Fallback if matchMedia isn't available
else {
window.addEventListener('onbeforeprint', beforePrint);
window.addEventListener('onafterprint', afterPrint);
// Use elsewhere if needed:
// window.removeEventListener('onbeforeprint', beforePrint)
// window.removeEventListener('onafterprint', afterPrint)
}
};
Update:
Runnable example sans jQuery because it's 2020. Use the "expand snippet" link to test the print scenario.
Highcharts.setOptions({ // Apply to all charts
chart: {
events: {
beforePrint: function() {
// Not called from global print event
this.oldhasUserSize = this.hasUserSize;
this.resetParams = [this.chartWidth, this.chartHeight, false];
this.setSize(600, 400, false);
},
afterPrint: function() {
//not called from global print event
this.setSize.apply(this, this.resetParams);
this.hasUserSize = this.oldhasUserSize;
}
}
}
});
Highcharts.chart('container', {
title: {
text: 'Rescale to print'
},
subtitle: {
text: 'The chart size is set to 600x400 and restored after User-prompted print.'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
]
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
function _setupPrintHandler() {
let beforeChartWidth, beforeChartHeight;
var beforePrint = function() {
// Access cached charts without jQuery
Highcharts.charts.forEach(chart => {
if (chart) {
// Set your arbitrary width/height needed for printing
// Save the existing chart info if explicitly set
// beforeChartWidth = chart.chartWidth;
// beforeChartHeight = chart.chartHeight;
const printWidth = 600,
printHeight = 200;
chart.setSize(printWidth, printHeight, false);
chart.reflow()
}
});
};
var afterPrint = function() {
Highcharts.charts.forEach(chart => {
if (chart) {
// if the previous values were saved, use them, otherwise `null` will return to auto-fit the container size
const prevWidth = beforeChartWidth || null;
const prevHeight = beforeChartHeight || null;
chart.setSize(prevWidth, prevHeight, false);
chart.reflow();
}
});
};
// use the new window.matchMedia query with better support
if (window.matchMedia) {
var mediaQueryList = window.matchMedia('print');
mediaQueryList.addListener(function(mql) {
if (mql.matches) {
beforePrint();
} else {
afterPrint();
}
});
}
// Fallback if matchMedia isn't available
else {
window.addEventListener('onbeforeprint', beforePrint);
window.addEventListener('onafterprint', afterPrint);
// Use elsewhere if needed:
// window.removeEventListener('onbeforeprint', beforePrint)
// window.removeEventListener('onafterprint', afterPrint)
}
};
// Run the setup function
_setupPrintHandler()
<script src="https://code.highcharts.com/highcharts.js"></script>
<!-- Don't need exporting anymore -->
<!-- <script src="https://code.highcharts.com/modules/exporting.js"></script> -->
<div id="container" style="height: 400px"></div>
score:2
Here is a mix of different solutions, with no need of exporting.js (which adds exporting button to all graphs on page...)
The size is automatically rescaled, then reset after print.
Tested mostly on IE
window.onbeforeprint = function() {
$(Highcharts.charts).each(function(i,chart){
chart.oldhasUserSize = chart.hasUserSize;
chart.resetParams = [chart.chartWidth, chart.chartHeight, false];
var height = chart.renderTo.clientHeight;
var width = chart.renderTo.clientWidth;
chart.setSize(width, height);
});
}
window.onafterprint = function() {
$(Highcharts.charts).each(function(i,chart){
chart.setSize.apply(chart, chart.resetParams);
chart.hasUserSize = chart.oldhasUserSize;
});
}
UPDATE: I now use a different version, fixing the size of each chart instead of using clientWidth. It works on the 3 browsers I tested (IE 11, FF & Chrome)
function redimChartBeforePrint(chart, width, height) {
if (typeof(width) == 'undefined')
width = 950;
if (typeof(height) == 'undefined')
height = 400;
chart.oldhasUserSize = chart.hasUserSize;
chart.resetParams = [chart.chartWidth, chart.chartHeight, false];
chart.setSize(width, height, false);
}
function redimChartAfterPrint(chart) {
chart.setSize.apply(chart, chart.resetParams);
chart.hasUserSize = chart.oldhasUserSize;
}
window.onbeforeprint = function() {
redimChartBeforePrint($('#chart1').highcharts());
redimChartBeforePrint($('#chart2').highcharts(), 800, 600);
...
};
window.onafterprint = function() {
redimChartAfterPrint($('#chart1').highcharts());
redimChartAfterPrint($('#chart2').highcharts());
...
};
score:10
Using listener that will trigger reflow for a chart and media queries in CSS chart should be printed in set size when printing a website.
JS:
$(function () {
Highcharts.setOptions({ // Apply to all charts
chart: {
events: {
beforePrint: function () {
this.oldhasUserSize = this.hasUserSize;
this.resetParams = [this.chartWidth, this.chartHeight, false];
this.setSize(600, 400, false);
},
afterPrint: function () {
this.setSize.apply(this, this.resetParams);
this.hasUserSize = this.oldhasUserSize;
}
}
}
});
$('#container').highcharts({
title: {
text: 'Rescale to print'
},
subtitle: {
text: 'Click the context menu and choose "Print chart".<br>The chart size is set to 600x400 and restored after print.'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
var printUpdate = function () {
$('#container').highcharts().reflow();
};
if (window.matchMedia) {
var mediaQueryList = window.matchMedia('print');
mediaQueryList.addListener(function (mql) {
printUpdate();
});
}
});
CSS:
@page {
size: A4;
margin: 0;
}
@media print {
html, body {
padding:0px;
margin:0px;
width: 210mm;
height: 297mm;
}
#container {
float:left;
padding: 0px;
margin: 0px;
width: 80%;
}
}
HTML:
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="height: 400px;"></div>
JSFiddle: http://jsfiddle.net/w4ro5xb7/13/
Test in full screen result for better effect: http://jsfiddle.net/w4ro5xb7/13/show/
Source: stackoverflow.com
Related Query
- Redraw/Resize highcharts when printing website
- Resize a chart before printing with Highcharts
- when printing page with highcharts using javascript this.print() width values in css in @media print seem to be ignored
- force Highcharts redraw animation when changing graph type
- Highcharts + Angularjs : Graph doesn't redraw when adding series from an external event
- Resize DIV to fit page width when printing
- dynamically set height of chart when printing Highcharts
- Highcharts checkboxes multiply when window resize event fires
- Highcharts not printing the line when there is empty data in the beginning
- Highcharts cloud issue with data source when duplicating chart
- Highcharts When printing the chart does not fit the page
- Highcharts - how to prevent xAxis redraw when using addSeries?
- HighCharts - When I download csv, can I switch data source to new one?
- Highcharts export : button is missing when website on IIS server
- Responsive Highcharts not sizing correctly until window resize
- Resize height with Highcharts
- Highcharts charts don't resize properly on window resize
- Highcharts => Getting the id of a point when clicking on a line chart
- Resize data points with highcharts
- Highcharts area fillOpacity do not work when changing the color
- How to make highcharts scrollable horizontally when having big range in x-axis
- Highcharts does not resize charts inside tabs
- Change title when drilldown in Highcharts
- Highcharts saying undefined is not a function when trying to add a new chart
- Add tooltip to legend in highcharts when hovering
- Javascript Highcharts v3.0.5 - How to hide Y Axis Title when using multiple Y Axis
- JavaScript error when using Highcharts
- Highcharts - only show tooltip when hovering directly on point
- Resize highcharts using react-grid-layout not working
- php: laravel slow view render time when rendering javascript for highcharts
More Query from same tag
- Define colors in pie chart dynamically data
- How to add secondary y-axis to highcharts
- Highcharts xrange styling
- Highcharts chartWidth no longer works with chart.getSVG()
- Is it possible to plot more than 35000 points in Highcharts
- Highcharts GANTT chart - need to allow category with no data
- highcharts - removing decimal places on Y axis with only one point
- Can highcharts crosshairs show on top of area chart fill?
- How to show the json data in Pie chart HighChart?
- Highcharts: how to get the data points in the zoomed window?
- Push array data into HighCharts?
- Highcharts draw grid lines into yAxis area
- Calling Typescript function from Highcharts load event
- Hightchart map pie : clic and hide specific pie
- How to set dataLabel Format and axis label angle in R highcharter package
- Drilldown multiple levels and multiple type Highchart
- How do I add a tooltip to the x-axis labels in highcharts?
- get data from hashmap into highcharts
- Highcharts dim unselected bars color on hover
- Column based Highchart drilldown series assign color code to each column
- Highcharts Line Chart Drill down not working properly
- Highchart issue when added into bootstrap carousel
- Highchart plot points are being displayed incorrectly
- Add static content into highchart exported pdf header
- Highcharts chart title and subtitle overlapping on Iphone 5
- highcharts draw datetime a week earlier
- How to set tick interval in highstocks
- Draw line before marker appear Highchart
- Kendo Linear Guage with logarithmic scale
- How to retain the conditional color of bar in highcharts