2017-01-16 39 views
0

我正在使用@media print {来自定义我的打印视图。我的图表存在的问题是它们的打印大小取决于浏览器窗口的大小。所以当我的浏览器很大时,画布对于页面来说太大了(我使用响应式图表)调整用于打印的chart.js画布

我试图重新定义@media print {内的画布大小,但没有成功。

当我打印时(不影响我的浏览器视图),获得一致统计图大小的解决方案是什么?

enter image description here

回答

5

问题是图表不适合新的打印宽度尺寸。幸运的是,我们可以在启动打印时执行重绘。

解决方法是在调用打印时使用canvas.toDataURL()方法将图表呈现为图像,然后在打印后将其切换回画布图表。 More on toDataURL()

要检测时要调用的函数的WebKit提供的方法window.matchMedia('print')(这将是印刷过程中truefalse之后再次),而其他浏览器使用window.onbeforeprintwindow.onafterprintMore on print methods

接下来要做的就是确保图像响应使用CSS,即缩放至100%宽度。

+3

任何人都知道有这样一个工作的例子吗? – Rodney

0

我使用自定义打印样式的画布自定义右填充:

@media print { 
    .chartCanvas { 
    padding-right: 1cm; 
    } 
} 
+1

不知道如何解决这个问题。画布仍然没有调整大小,因为您添加了填充。 – perry

+0

这实际上确实解决了我的问题,谢谢! – mfink

0

继我是能够使在角2.这项工作的例子是打字稿的联系和雷吉平卡姆的例子,但读者应该能够很容易地适应这个常规的JavaScript来在其他项目中工作。注意我只在linux系统的最新版本的chrome上测试过,因为这对我公司的内部项目来说很好。

// 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; 

} 

}

请注意,我已经离开了chart.js之命令和数据,这将因于人。我有一个外部服务来处理我遗漏的内容。

我希望这可以帮助那些正在摸索如何脱离雷吉的答案的人。

1

如果您的图表很简单,请尝试使用只用css

@media print { 
    canvas.chart-canvas { 
     min-height: 100%; 
     max-width: 100%; 
     max-height: 100%; 
     height: auto!important; 
     width: auto!important; 
    } 
}