-
-
Save kidroca/19e5fe2de8e24aa92a41e94f2d41eda4 to your computer and use it in GitHub Desktop.
import React from 'react'; | |
import { Global } from 'recharts'; | |
import { htmlSvgToPdfSvg } from '../imageFromSvg'; | |
export const ChartSvg = ({ debug, style, children, width, height }) => { | |
return chartToPdfSvg(children, width, height, debug, style); | |
}; | |
const chartToPdfSvg = (children, width, height, debug, style) => { | |
Global.set('isSsr', true); | |
const component = htmlSvgToPdfSvg(children); | |
Global.set('isSsr', false); | |
const result = React.cloneElement(component, { width, height, debug, style }); | |
return result; | |
}; | |
export default ChartSvg; |
import { View } from '@react-pdf/renderer'; | |
import { CartesianGrid, Label, Scatter, ScatterChart, XAxis, YAxis } from 'recharts'; | |
import Chart from './Chart'; | |
export const ExampleUsage = ({ data = getSampleData() }) => ( | |
<View> | |
<Chart width={600} height={300}> | |
<MyRechartsChart data={data} /> | |
</Chart> | |
</View> | |
); | |
const MyRechartsChart = ({ width, height, data }) => ( | |
<ScatterChart width={width} height={height}> | |
<CartesianGrid /> | |
<XAxis name="x" dataKey="x" /> | |
<YAxis name="y" dataKey="y" /> | |
<Scatter name="My Scatter" data={data} isAnimationActive={false} /> | |
</ScatterChart> | |
) | |
function getSampleData() { | |
return [ | |
{ x: 100, y: 100 }, | |
{ x: 200, y: 100 }, | |
{ x: 200, y: 150 }, | |
{ x: 150, y: 200 }, | |
{ x: 125, y: 150 } | |
] | |
} | |
export default ExampleUsage; |
import React, { createElement } from 'react'; | |
import ReactDom from 'react-dom/server'; | |
import reactHtmlParser from 'react-html-parser'; | |
export const htmlSvgToPdfSvg = (children) => { | |
const svgString = ReactDom | |
.renderToStaticMarkup(children) | |
.replaceAll('px', 'pt'); | |
const [component] = reactHtmlParser(svgString, { transform: convertToPdfSvg }); | |
return component; | |
}; | |
function convertToPdfSvg(node, index) { | |
if (node.type == 'text') { | |
return node.data; | |
} | |
node.props = { key: index }; | |
Object.entries(node.attribs).forEach(([key, value]) => { | |
const [first, ...rest] = key.split('-'); | |
const newKey = [first, ...rest.map(word => `${word[0].toUpperCase()}${word.slice(1)}`)].join(''); | |
node.props[newKey] = value; | |
}); | |
node.name = node.name?.toUpperCase(); | |
if (node.name == 'CLIPPATH') node.name = 'CLIP_PATH'; | |
// we're removing nested <defs> because they don't work | |
if (node.name == 'DEFS' && node.parent.name != 'SVG') return null; | |
if (node.children) node.children = node.children.map(convertToPdfSvg); | |
return createElement(node.name, node.props, node.children); | |
} | |
export default htmlSvgToPdfSvg; |
{ | |
"dependencies": { | |
"@react-pdf/renderer": "^2.0.16", | |
"react": "^17.0.2", | |
"react-dom": "^17.0.2", | |
"react-html-parser": "^2.0.2", | |
"recharts": "^2.0.9" | |
} | |
} |
I just created https://github.com/EvHaus/react-pdf-charts which allows for recharts to be rendered into react-pdf
. It had only very basic support at the moment, but I'm hoping with some help from the community -- we can get to full support.
@EvHaus it does not work properly. I can see that Path is being converted to Line and it's not even found in parsed HTML string.
probably Html parser is bringing this issue
@leq382121 Hmm. Could you open an issue in https://github.com/EvHaus/react-pdf-charts/issues with the code you're using and I'll take a look.
@EvHaus @leq382121 I am facing an issue while displaying the BarChart inside my pdf.... So when I am using " import ReactPDFChart from "react-pdf-charts" " this and trying to get my BarChart then Barchart is only showing the CartesianGrid, XAxis and YAxis but no values.
Below is the code with "ReactPDFChart" -
import React from "react";
import ReactPDFChart from "react-pdf-charts";
import { BarChart, Bar, XAxis, YAxis, CartesianGrid } from "recharts";
const data = [
{ name: 'A', uv: 4000, pv: 2400, amt: 2400 },
{ name: 'B', uv: 3000, pv: 1398, amt: 2210 },
{ name: 'C', uv: 2000, pv: 9800, amt: 2290 },
{ name: 'D', uv: 2780, pv: 3908, amt: 2000 },
{ name: 'E', uv: 1890, pv: 4800, amt: 2181 },
{ name: 'F', uv: 2390, pv: 3800, amt: 2500 },
{ name: 'G', uv: 3490, pv: 4300, amt: 2100 },
];
// Silence useLayoutEffect does nothing on the server
warnings. These come
// from recharts
but they're harmless and just clutter the console output.
const consoleError = console.error;
console.error = function (message) {
if (message?.startsWith('Warning: useLayoutEffect does nothing on the server')) return;
consoleError.apply(console, arguments);
};
const PdfBarChart = () => (
<ReactPDFChart> <BarChart data={data} width={500} height={300}> <XAxis dataKey="name" /> <YAxis /> <CartesianGrid stroke="#ccc" strokeDasharray="3 3" /> <Bar dataKey="uv" fill="#8884d8" /> <Bar dataKey="pv" fill="#82ca9d" /> </BarChart> </ReactPDFChart>
);
export default PdfBarChart;
And when I try the same above code without "ReactPDFChart" it is giving me error like below -
htmlLayer.getElementsByClassName is not a function
TypeError: htmlLayer.getElementsByClassName is not a function
at CartesianAxis.componentDidMount (http://localhost:3000/static/js/bundle.js:144491:28)
So can anyone please guide or help me to figure this out and render the Bar and another Charts in the pdf.
@Kartik0899 Could you please open a new issue at https://github.com/EvHaus/react-pdf-charts/issues and we can take it from there.
BarChart doesn't work properly, ni the PieChart
BarChart doesn't work properly, ni the PieChart
@omarhsounalogient
You need to add isAnimationActive={false} when rendering BarChart and PieChart component in the browser.
For example -
<Bar isAnimationActive={false} dataKey="uv" fill="#8884d8" />
<Pie isAnimationActive={false} dataKey="value" nameKey="name" cx="25%" cy="50%" outerRadius={50} fill="#000" label />
Hope it helps!
I'm having the same issue with renderFn. Anyone figure this out?
I degraded the version react-pdf ,and it worked
BarChart doesn't work properly, ni the PieChart
@omarhsounalogient
You need to add isAnimationActive={false} when rendering BarChart and PieChart component in the browser. For example -
<Bar isAnimationActive={false} dataKey="uv" fill="#8884d8" />
<Pie isAnimationActive={false} dataKey="value" nameKey="name" cx="25%" cy="50%" outerRadius={50} fill="#000" label />
Hope it helps!
You save my life, after like 4 hours with this issue your advice work
I have digged into the node modules and found out that recharts inner tags "TITLE" and "DEFS" are breaking render function. I've included this line of code to ditch those two values and it's sucessfuly rendered.
if (node.name == "TITLE" || node.name == "DESC") return null;
Result:
Hope it helps!