我正在使用@media print {
来自定义我的打印视图。我的图表存在的问题是它们的打印大小取决于浏览器窗口的大小。所以当我的浏览器很大时,画布对于页面来说太大了(我使用响应式图表)调整用于打印的chart.js画布
我试图重新定义@media print {
内的画布大小,但没有成功。
当我打印时(不影响我的浏览器视图),获得一致统计图大小的解决方案是什么?
我正在使用@media print {
来自定义我的打印视图。我的图表存在的问题是它们的打印大小取决于浏览器窗口的大小。所以当我的浏览器很大时,画布对于页面来说太大了(我使用响应式图表)调整用于打印的chart.js画布
我试图重新定义@media print {
内的画布大小,但没有成功。
当我打印时(不影响我的浏览器视图),获得一致统计图大小的解决方案是什么?
问题是图表不适合新的打印宽度尺寸。幸运的是,我们可以在启动打印时执行重绘。
解决方法是在调用打印时使用canvas.toDataURL()
方法将图表呈现为图像,然后在打印后将其切换回画布图表。 More on toDataURL()。
要检测时要调用的函数的WebKit提供的方法window.matchMedia('print')
(这将是印刷过程中true
或false
之后再次),而其他浏览器使用window.onbeforeprint
和window.onafterprint
。 More on print methods。
接下来要做的就是确保图像响应使用CSS,即缩放至100%宽度。
继我是能够使在角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之命令和数据,这将因于人。我有一个外部服务来处理我遗漏的内容。
我希望这可以帮助那些正在摸索如何脱离雷吉的答案的人。
如果您的图表很简单,请尝试使用只用css
@media print {
canvas.chart-canvas {
min-height: 100%;
max-width: 100%;
max-height: 100%;
height: auto!important;
width: auto!important;
}
}
任何人都知道有这样一个工作的例子吗? – Rodney