Skip to content

Commit 89683f8

Browse files
authored
fix: add :root to charts CSS selector to fix exporting (#9907)
1 parent 1d83057 commit 89683f8

File tree

8 files changed

+191
-49
lines changed

8 files changed

+191
-49
lines changed

packages/charts/src/helpers.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,49 @@ export function deepMerge(target, source) {
5757

5858
return target;
5959
}
60+
61+
export function prepareExport(chart) {
62+
// Guard against another print 'before print' event coming before
63+
// the 'after print' event.
64+
if (!chart.tempBodyStyle) {
65+
let effectiveCss = '';
66+
67+
// LitElement uses `adoptedStyleSheets` for adding styles
68+
if (chart.shadowRoot.adoptedStyleSheets) {
69+
chart.shadowRoot.adoptedStyleSheets.forEach((sheet) => {
70+
effectiveCss += `${[...sheet.cssRules].map((rule) => rule.cssText).join('\n')}\n`;
71+
});
72+
}
73+
74+
// Strip off host selectors that target individual instances
75+
effectiveCss = effectiveCss.replace(/:host\(.+?\)/gu, (match) => {
76+
const selector = match.substr(6, match.length - 7);
77+
return chart.matches(selector) ? '' : match;
78+
});
79+
80+
// Zoom out a bit to avoid clipping the chart's edge on paper
81+
effectiveCss =
82+
`${effectiveCss}body {` +
83+
` -moz-transform: scale(0.9, 0.9);` + // Mozilla
84+
` zoom: 0.9;` + // Others
85+
` zoom: 90%;` + // Webkit
86+
`}`;
87+
88+
chart.tempBodyStyle = document.createElement('style');
89+
chart.tempBodyStyle.textContent = effectiveCss;
90+
document.body.appendChild(chart.tempBodyStyle);
91+
if (chart.options.chart.styledMode) {
92+
document.body.setAttribute('styled-mode', '');
93+
}
94+
}
95+
}
96+
97+
export function cleanupExport(chart) {
98+
if (chart.tempBodyStyle) {
99+
document.body.removeChild(chart.tempBodyStyle);
100+
delete chart.tempBodyStyle;
101+
if (chart.options.chart.styledMode) {
102+
document.body.removeAttribute('styled-mode');
103+
}
104+
}
105+
}

packages/charts/src/styles/vaadin-chart-base-styles.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ export const chartStyles = css`
8181
display: block;
8282
width: 100%;
8383
overflow: hidden;
84+
}
85+
86+
:host,
87+
:root {
8488
font-size: var(--vaadin-charts-font-size, 0.75rem);
8589
line-height: normal;
8690

packages/charts/src/vaadin-chart-mixin.js

Lines changed: 3 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import Highcharts from 'highcharts/es-modules/masters/highstock.src.js';
3333
import { get } from '@vaadin/component-base/src/path-utils.js';
3434
import { ResizeMixin } from '@vaadin/component-base/src/resize-mixin.js';
3535
import { SlotObserver } from '@vaadin/component-base/src/slot-observer.js';
36-
import { deepMerge, inflateFunctions } from './helpers.js';
36+
import { cleanupExport, deepMerge, inflateFunctions, prepareExport } from './helpers.js';
3737

3838
['exportChart', 'exportChartLocal', 'getSVG'].forEach((methodName) => {
3939
/* eslint-disable @typescript-eslint/no-invalid-this, prefer-arrow-callback */
@@ -1202,55 +1202,12 @@ export const ChartMixin = (superClass) =>
12021202
// Workaround for https://github.com/vaadin/vaadin-charts/issues/389
12031203
// Hook into beforePrint and beforeExport to ensure correct styling
12041204
if (['beforePrint', 'beforeExport'].indexOf(event.type) >= 0) {
1205-
// Guard against another print 'before print' event coming before
1206-
// the 'after print' event.
1207-
if (!self.tempBodyStyle) {
1208-
let effectiveCss = '';
1209-
1210-
// PolymerElement uses `<style>` tags for adding styles
1211-
[...self.shadowRoot.querySelectorAll('style')].forEach((style) => {
1212-
effectiveCss += style.textContent;
1213-
});
1214-
1215-
// LitElement uses `adoptedStyleSheets` for adding styles
1216-
if (self.shadowRoot.adoptedStyleSheets) {
1217-
self.shadowRoot.adoptedStyleSheets.forEach((sheet) => {
1218-
effectiveCss += [...sheet.cssRules].map((rule) => rule.cssText).join('\n');
1219-
});
1220-
}
1221-
1222-
// Strip off host selectors that target individual instances
1223-
effectiveCss = effectiveCss.replace(/:host\(.+?\)/gu, (match) => {
1224-
const selector = match.substr(6, match.length - 7);
1225-
return self.matches(selector) ? '' : match;
1226-
});
1227-
1228-
// Zoom out a bit to avoid clipping the chart's edge on paper
1229-
effectiveCss =
1230-
`${effectiveCss}body {` +
1231-
` -moz-transform: scale(0.9, 0.9);` + // Mozilla
1232-
` zoom: 0.9;` + // Others
1233-
` zoom: 90%;` + // Webkit
1234-
`}`;
1235-
1236-
self.tempBodyStyle = document.createElement('style');
1237-
self.tempBodyStyle.textContent = effectiveCss;
1238-
document.body.appendChild(self.tempBodyStyle);
1239-
if (self.options.chart.styledMode) {
1240-
document.body.setAttribute('styled-mode', '');
1241-
}
1242-
}
1205+
prepareExport(self);
12431206
}
12441207

12451208
// Hook into afterPrint and afterExport to revert changes made before
12461209
if (['afterPrint', 'afterExport'].indexOf(event.type) >= 0) {
1247-
if (self.tempBodyStyle) {
1248-
document.body.removeChild(self.tempBodyStyle);
1249-
delete self.tempBodyStyle;
1250-
if (self.options.chart.styledMode) {
1251-
document.body.removeAttribute('styled-mode');
1252-
}
1253-
}
1210+
cleanupExport(self);
12541211
}
12551212

12561213
self.dispatchEvent(new CustomEvent(eventList[key], customEvent));

packages/charts/test/visual/base/chart.test.js

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
import { fixtureSync } from '@vaadin/testing-helpers/dist/fixture.js';
1+
import { aTimeout, fixtureSync, nextFrame } from '@vaadin/testing-helpers';
22
import { visualDiff } from '@web/test-runner-visual-regression';
3+
import '../../chart-not-animated-styles.js';
34
import '../../../src/vaadin-chart.js';
5+
import Highcharts from 'highcharts/es-modules/masters/highstock.src.js';
6+
import { cleanupExport, prepareExport } from '../../../src/helpers.js';
47

58
describe('chart', () => {
69
let element;
@@ -73,6 +76,10 @@ describe('chart', () => {
7376
`);
7477
});
7578

79+
afterEach(() => {
80+
document.documentElement.style.removeProperty('color-scheme');
81+
});
82+
7683
it('pie', async () => {
7784
await visualDiff(element, 'pie');
7885
});
@@ -82,4 +89,66 @@ describe('chart', () => {
8289
await visualDiff(element, 'pie-dark');
8390
});
8491
});
92+
93+
describe('exporting', () => {
94+
let exporting;
95+
beforeEach(async () => {
96+
const fixture = fixtureSync(`
97+
<div>
98+
<vaadin-chart
99+
hidden
100+
title="Solar Employment Growth by Sector, 2010-2016"
101+
categories="[2010, 2011, 2012, 2013, 2014, 2015, 206, 2017]"
102+
additional-options='{
103+
"plotOptions": {
104+
"series": {
105+
"animation": false
106+
}
107+
}
108+
}'
109+
>
110+
<vaadin-chart-series
111+
title="Installation"
112+
values="[43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]"
113+
></vaadin-chart-series>
114+
<vaadin-chart-series
115+
title="Manufacturing"
116+
values="[24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434]"
117+
></vaadin-chart-series>
118+
<vaadin-chart-series
119+
title="Sales &amp; Distribution"
120+
values="[11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387]"
121+
></vaadin-chart-series>
122+
<vaadin-chart-series
123+
title="Project Development"
124+
values="[null, null, 7988, 12169, 15112, 22452, 34400, 34227]"
125+
></vaadin-chart-series>
126+
<vaadin-chart-series
127+
title="Other"
128+
values="[12908, 5948, 8105, 11248, 8989, 11816, 18274, 18111]"
129+
></vaadin-chart-series>
130+
</vaadin-chart>
131+
<div id="exporting" style="margin: 2em;"></div>
132+
</div>
133+
`);
134+
element = fixture.querySelector('vaadin-chart');
135+
exporting = fixture.querySelector('#exporting');
136+
137+
await nextFrame();
138+
139+
const chart = Highcharts.chart(exporting, element.configuration.userOptions);
140+
element.configuration.series.forEach((series) => chart.addSeries(series.userOptions));
141+
prepareExport(element);
142+
143+
await aTimeout(500);
144+
});
145+
146+
afterEach(() => {
147+
cleanupExport(element);
148+
});
149+
150+
it('styled mode', async () => {
151+
await visualDiff(exporting, 'styled-mode');
152+
});
153+
});
85154
});
25.9 KB
Loading

packages/charts/test/visual/lumo/chart.test.js

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
import { fixtureSync } from '@vaadin/testing-helpers/dist/fixture.js';
1+
import { aTimeout, fixtureSync, nextFrame } from '@vaadin/testing-helpers';
22
import { visualDiff } from '@web/test-runner-visual-regression';
33
import '@vaadin/vaadin-lumo-styles/props.css';
44
import '@vaadin/vaadin-lumo-styles/components/charts.css';
5+
import '../../chart-not-animated-styles.js';
56
import '../../../vaadin-chart.js';
7+
import Highcharts from 'highcharts/es-modules/masters/highstock.src.js';
8+
import { cleanupExport, prepareExport } from '../../../src/helpers.js';
69

710
describe('chart', () => {
811
let element;
@@ -94,4 +97,66 @@ describe('chart', () => {
9497
await visualDiff(element, 'pie-classic');
9598
});
9699
});
100+
101+
describe('exporting', () => {
102+
let exporting;
103+
beforeEach(async () => {
104+
const fixture = fixtureSync(`
105+
<div>
106+
<vaadin-chart
107+
hidden
108+
title="Solar Employment Growth by Sector, 2010-2016"
109+
categories="[2010, 2011, 2012, 2013, 2014, 2015, 206, 2017]"
110+
additional-options='{
111+
"plotOptions": {
112+
"series": {
113+
"animation": false
114+
}
115+
}
116+
}'
117+
>
118+
<vaadin-chart-series
119+
title="Installation"
120+
values="[43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]"
121+
></vaadin-chart-series>
122+
<vaadin-chart-series
123+
title="Manufacturing"
124+
values="[24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434]"
125+
></vaadin-chart-series>
126+
<vaadin-chart-series
127+
title="Sales &amp; Distribution"
128+
values="[11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387]"
129+
></vaadin-chart-series>
130+
<vaadin-chart-series
131+
title="Project Development"
132+
values="[null, null, 7988, 12169, 15112, 22452, 34400, 34227]"
133+
></vaadin-chart-series>
134+
<vaadin-chart-series
135+
title="Other"
136+
values="[12908, 5948, 8105, 11248, 8989, 11816, 18274, 18111]"
137+
></vaadin-chart-series>
138+
</vaadin-chart>
139+
<div id="exporting" style="margin: 2em;"></div>
140+
</div>
141+
`);
142+
element = fixture.querySelector('vaadin-chart');
143+
exporting = fixture.querySelector('#exporting');
144+
145+
await nextFrame();
146+
147+
const chart = Highcharts.chart(exporting, element.configuration.userOptions);
148+
element.configuration.series.forEach((series) => chart.addSeries(series.userOptions));
149+
prepareExport(element);
150+
151+
await aTimeout(500);
152+
});
153+
154+
afterEach(() => {
155+
cleanupExport(element);
156+
});
157+
158+
it('styled mode', async () => {
159+
await visualDiff(exporting, 'styled-mode');
160+
});
161+
});
97162
});
28.5 KB
Loading

packages/vaadin-lumo-styles/src/components/chart.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
55
*/
66
@media lumo_components_chart {
7-
:host {
7+
:host,
8+
:root {
89
--vaadin-charts-background: var(--lumo-base-color);
910
--vaadin-charts-title-label: var(--lumo-header-text-color);
1011
--vaadin-charts-axis-title: var(--lumo-secondary-text-color);

0 commit comments

Comments
 (0)