Redraw/Resize highcharts when printing website

前端 未结 3 2044
悲哀的现实
悲哀的现实 2021-02-06 05:57

When I\'m printing the bottom right frame the text some text is partly covered by the highcharts because they don\'t resize before printing. Is there a solution to

3条回答
  •  我寻月下人不归
    2021-02-06 06:36

    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()
    
    
    
    
    

提交回复
热议问题