Resize or resize charts when printing a website

When I print the bottom right frame, some text partially covered by high-frequency diagrams because they do not change before printing. Is there a solution to customize the print layout with @media print for the website and force changing the charts / sizes to the container size when printing the website?

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> <div id="container" style="height: 400px"></div> 

Javascript

 $(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] }] }); }); 

Jsfiddle

+6
source share
3 answers

Using a listener that will cause a recount for the chart, and media queries in the CSS table should be printed at the specified size when printing the 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/

Full screen test for better effect: http://jsfiddle.net/w4ro5xb7/13/show/

+9
source

Here are a few different solutions, without the need for export.js (which adds an export button to all the charts on the page ...)

The size is automatically scaled, then reset after printing. A.

Tested mainly 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: Now I am using a different version, fixing the size of each chart instead of using clientWidth. It works in three browsers that I tested (IE 11, FF and 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()); ... }; 
0
source

Accepting these suggestions, I wanted to propose a third approach, which should eliminate some of the shortcomings of the previous answers in combination with other solutions that I saw in other places, which led to what worked for me (that the above did not work).

Setting window.onbeforeprint onbeforeprint if you do not have other onbeforeprint handlers and do not want them onbeforeprint . window.addEventListener('onbeforeprint', function) allows you to set many separate event listeners and delete them when you are done. In addition, Safari does not support these special event listeners anyway, so it is recommended that you use window.matchMedia instead, which is supported in 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) } }; 
0
source

Source: https://habr.com/ru/post/1232441/


All Articles