amcharts5
amcharts5 copied to clipboard
Charts get cropped when printed (whole page not export)
Bug description
Charts don't resize in a right way when printed and the version 4 workaround is not working as expected:
Default:
With resize on print:
Code used for resize:
if (window.matchMedia) {
window.matchMedia('print').addEventListener('change', (query) => {
if (query.matches) {
this.chart.set('maxWidth', 70);
this.chart.set('maxHeight', 100);
} else {
setTimeout(() => {
this.chart.set('maxWidth', null);
this.chart.set('maxHeight', null);
}, 0);
}
});
}
Expected output:
Environment
- amCharts version: 5.2.9
- Browser and its version: Google chrome @103.0.5060.114
- Related frameworks and their versions:
- Angular: 13.3.0
- Typescript: 4.6.2
Try calling this after setting the width/height on the chart:
root._runTickerNow();
Try calling this after setting the width/height on the chart:
root._runTickerNow();
Didn't make any difference.
How about setting width
/height
instead of maxWidth
/maxHeight
?
How about setting
width
/height
instead ofmaxWidth
/maxHeight
?
Comes out same looking like Default (so basically no resizing)
Alright. Hold on, we're experimenting with something. Will keep you posted.
This issue is stale because it has been open 30 days with no activity. It will be closed in 5 days unless a new comment is added.
Here is my current workaround that I think can be really helpful when some minor kinks are ironed out.:
- Listen to
frameended
event. - On frame ended export the chart to an image.
- Then place the image on top of the chart using css.
It won't always be perfect but it will work more often than just trying to print the chart alone.
here is my code -using angular.
frameEnded$ = new Subject<void>();
this.chartRoot.events.on('frameended', () => this.frameEnded$.next());
this.frameEnded$.pipe(debounceTime(100)).subscribe(() => {
if (this.printable) {
const exporting = Exporting.new(this.chartRoot, {
pngOptions: {
quality: 0.9
}
});
exporting.export('png').then((imageURI) => {
this.printableImageURI = imageURI;
});
}
});
Edit: don't use frameended
use width
like this:
this.chart.onPrivate('width', () => this.widthChanged.next());
this.widthChanged.pipe(debounceTime(100)).subscribe(() => {
if (this.printable) {
const exporting = Exporting.new(this.chartRoot, {
pngOptions: {
quality: 0.9
}
});
exporting.export('png').then((imageURI) => {
this.printableImageURI = imageURI;
});
}
});
Ummmm, wouldn't that be a huge resource drain if you export image on every frame?
P.S. we're still working on a way to force the chart to fully render in a 100% non-async way.
Ummmm, wouldn't that be a huge resource drain if you export image on every frame?
So far with just 4 charts it's not noticeable. Though it would be much better if we can listen to a resize
event instead of framended
but as far as I know there is none.
There is:
chart.onPrivate("width", function(ev) {
// Width of the chart changed
});
chart.onPrivate("width", function(ev) { // Width of the chart changed });
That works much better ! Thanks.
P.S. we're still working on a way to force the chart to fully render in a 100% non-async way.
All the luck. Please tell me if there is anyway to help.
As I mentioned, it would be better if we could come up to disable async rendering of the chart so changes can be applied before print. We will let you know when/if we make that happen.