I’m facing an issue with exporting charts to PDF using the html-to-image and jspdf libraries. The charts are created using the Recharts library. When I change the page zoom in Safari, the elements in the charts (such as dots) that have cx and cy attributes do not appear in the correct positions in the exported PDF. This misalignment issue seems to be specific to Safari.
Here is the code snippet I’m using for exporting the report as a PDF:
export const exportAsPDFSingleReport = async (content, fileName, fileType, setExporting, reportId) => {
const style = document.createElement("style");
style.innerHTML = `
#my-report .report {
width: fit-content;
height: fit-content;
display: flex;
gap: 20px;
flex-direction: column;
}
`;
content.appendChild(style);
style.onload = async function () {
try {
const imgData = await htmlToImage.toPng(content).then(() => {
return htmlToImage.toPng(content);
});
const img = new Image();
img.src = imgData;
img.onload = function () {
const imageWidth = img.width;
const imageHeight = img.height;
const pdf = new jsPDF({
orientation: "l",
unit: "px",
format: [imageWidth, imageHeight]
});
pdf.addImage(imgData, "PNG", 0, 0, imageWidth, imageHeight, true);
pdf.save(`${fileName}.${fileType}`);
};
} catch (error) {
console.error("Error exporting as PDF:", error);
} finally {
setExporting((prevExporting) => ({
...prevExporting,
[reportId]: false
}));
}
};
};
The chart component is defined as follows:
<Line
type="monotone"
dataKey="created"
strokeWidth={3}
dot={{
display: showLabel ? "true" : "none",
r: 3,
stroke: CREATED_VS_RESOLVED_COLORS.red,
strokeWidth: 2,
cursor: "pointer",
onMouseEnter: (e) => setIsHover(e),
fill: MODES[colorMode].background
}}
activeDot={{
r: 3,
cursor: "pointer",
onMouseLeave: () => setIsHover(null),
dataKey: isHover?.dataKey,
payload: isHover?.payload,
stroke: CREATED_VS_RESOLVED_COLORS.red
}}
/>
exported result on Safari
exported expected result on Chrome
Kristina Garanchuk is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.