Fix trend viz in FE PDFs (#77612)

This commit is contained in:
Nick Fitzpatrick
2026-07-17 19:38:38 +05:30
committed by GitHub
parent 95267311e5
commit cd9d166077
4 changed files with 69 additions and 5 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -308,6 +308,56 @@ export const SmartScalarUnicodeSubscript = {
},
};
// metabase#77001 guard: html2canvas drops the arrow's currentColor on export — must be red, not black.
export const SmartScalarDownload = {
render: Template,
args: {
...defaultArgs,
card: createMockCard({
id: getNextId(),
display: "smartscalar",
visualization_settings: {
"graph.dimensions": ["timestamp"],
"graph.metrics": ["count"],
},
}),
result: createMockDataset({
data: createMockDatasetData({
cols: [
createMockColumn(DateTimeColumn({ name: "Timestamp" })),
createMockColumn(NumberColumn({ name: "Count" })),
],
insights: [
{
"previous-value": 220,
unit: "week",
offset: -199100,
"last-change": -0.3181818181818182,
col: "count",
slope: 10,
"last-value": 150,
"best-fit": ["+", -199100, ["*", 10, "x"]],
},
],
rows: [
["2024-07-21T00:00:00Z", 220],
["2024-07-28T00:00:00Z", 150],
],
}),
}),
},
play: async ({ canvasElement }: { canvasElement: HTMLCanvasElement }) => {
const asyncCallback = createAsyncCallback();
try {
await downloadQuestionAsPng(canvasElement);
} finally {
asyncCallback();
}
},
};
export const SmartScalarLightThemeTooltip = {
parameters: {
loki: { skip: true },

View File

@@ -4,6 +4,7 @@ import DashboardS from "metabase/css/dashboard.module.css";
import { Badge, Flex, Group, Icon, Stack, Tooltip } from "metabase/ui";
import { measureTextWidth } from "metabase/utils/measure-text";
import { formatValue } from "metabase/visualizations/lib/formatting/value";
import { SAVING_DOM_IMAGE_DISPLAY_NONE_CLASS } from "metabase/visualizations/lib/image-exports";
import type { ColumnSettings } from "metabase-types/api";
import { CHANGE_TYPE_OPTIONS, type ComparisonResult } from "../compute";
@@ -133,7 +134,13 @@ export function PreviousValueComparison({
</VariationDetails>
{showsOtherValuesInTooltip && (
<Badge size="xs" variant="light" w={ELLIPSIS_BADGE_WIDTH}>
<Badge
px="xs"
size="xs"
variant="light"
w={ELLIPSIS_BADGE_WIDTH}
className={SAVING_DOM_IMAGE_DISPLAY_NONE_CLASS}
>
<Group align="center" h="100%">
<Icon name="ellipsis" size={12} />
</Group>

View File

@@ -1,5 +1,5 @@
diff --git a/node_modules/html2canvas-pro/dist/html2canvas-pro.esm.js b/node_modules/html2canvas-pro/dist/html2canvas-pro.esm.js
index d49f1bd..2f21002 100644
index d49f1bd..cb90b52 100644
--- a/node_modules/html2canvas-pro/dist/html2canvas-pro.esm.js
+++ b/node_modules/html2canvas-pro/dist/html2canvas-pro.esm.js
@@ -5875,6 +5875,8 @@ class SVGElementContainer extends ElementContainer {
@@ -11,7 +11,7 @@ index d49f1bd..2f21002 100644
const bounds = parseBounds(context, img);
img.setAttribute('width', `${bounds.width}px`);
img.setAttribute('height', `${bounds.height}px`);
@@ -7144,14 +7146,48 @@ const ignoredStyleProperties = [
@@ -7144,14 +7146,55 @@ const ignoredStyleProperties = [
'd', // #2483
'content' // Safari shows pseudoelements if content is set
];
@@ -64,10 +64,17 @@ index d49f1bd..2f21002 100644
+ target.style.setProperty('transform', transform);
+ target.style.setProperty('transform-origin', style.getPropertyValue('transform-origin'));
+ target.style.setProperty('transform-box', style.getPropertyValue('transform-box'));
+ }
+ // Same empty-cssText Chrome quirk drops the resolved `color`, so SVGs painting
+ // with fill="currentColor" lose their inherited color when serialized standalone
+ // (rendered black). Re-apply it so currentColor resolves. (metabase#77001)
+ const color = style.getPropertyValue('color');
+ if (color) {
+ target.style.setProperty('color', color);
}
return target;
};
@@ -7534,7 +7570,8 @@ class ElementPaint {
@@ -7534,7 +7577,8 @@ class ElementPaint {
const rotateMatrix = [cos, sin, -sin, cos, 0, 0];
this.effects.push(new TransformEffect(offsetX, offsetY, rotateMatrix));
}
@@ -77,7 +84,7 @@ index d49f1bd..2f21002 100644
const origin = this.container.styles.transformOrigin;
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
const offsetY = this.container.bounds.top + getAbsoluteValue(origin[1], this.container.bounds.height);
@@ -10373,12 +10410,12 @@ class Validator {
@@ -10373,12 +10417,12 @@ class Validator {
}
// Basic format validation - nonce should be base64-like
// Typical format: base64 string, often 32+ characters