org-chart
org-chart copied to clipboard
chart.exportImg() is throwing blurry image
i am trying to export the full org chart in expanded mode,
i have tried with 50 records its working fine, now as things are getting complexed and with 250 records its printing blurry images
is there any way to achieve the clear pdf for the records
Image quality varies on the screen PPI , it looks good on retina macbook screens for example, but not so good on non-retina macbook screens.
That's because converting happens directly on the frontend.
There is a way to increase scale (default is 3), but be aware that it's performance heavy operation and it might work for poor screens, but fail on retina screens , because retina needs to do at least 4X times more operations
So, I'd suggest having some kind of conditional scaling set depending on the screen, remember default is 3
is am using the pdf option sent by dufault just need the highest image quality can you guide me
Adding scale:5
in place of green line should do the trick
Hi, i have the same problem with my export. I have changed the scale to 6 but I still have blur and a big file (150MB)!
Do you have any tip how can I export smaller file?
@grzegorzCieslik95 scale controls how bit the file is. scale:1 exports exactly the same size as on the screen, scale 6 - makes it 36x bigger image.
Can you post a 3x scale photo of the exported org chart?
Sure, i post scale 3 and 6
I can see the quality difference.
The issue with blurriness is that you are trying to export a horizontally spread chart on a vertical screen :/
Not sure how to approach this - I think I have to apply some kind of cropping to make it look better. I will keep this issue open, not sure when it will be fixed
Hi, I have sth like this https://stackblitz.com/edit/js-7qzbix?file=index.html . I'm still having problem with rendering images but it works very well in big organisation.
Of course this is the pdf export, but on pdf zoom works different than on HTML -> this is why I changed some part of export
Hello, i paste here my code for export pdf without blur for ~300 nodes
const { svg } = chart.current.getChartState();
const graphNode = svg.node();
if (!graphNode) {
return null;
}
const nodeWithInlineStyles = computeToInlineStyles(graphNode); // replace style to inline style
await transformImagesToBase64(nodeWithInlineStyles); // replace image URL to base64
const { y: oY, x: oX } = graphNode.getBoundingClientRect();
const { height, width, x, y } =
graphNode.children[0].getBoundingClientRect();
const opt = {
margin: [4, 8],
filename: fileName,
image: { type: 'jpeg', quality: 0.98 },
html2canvas: {
useCORS: true,
allowTaint: true,
letterRendering: true,
scale: getCorrectScale(
graphNode.getElementsByClassName(nodeClassName).length, // get correct scale for nodes count
),
height,
width,
x: x - oX,
y: y - oY,
},
jsPDF: {
unit: 'px',
format: [height + 12, width + 16],
orientation: height > width ? 'p' : 'l',
},
};
return html2pdf()
.set(opt)
.from(nodeWithInlineStyles)
.save()
computeToInlineStyles
-> return new copied node
if you want, I can create pr for this but this is only pdf export
Hi,
I tried several variations, for A0 format the scale factor 4.6 is the highest I can choose (or nothing actually happens) now the file is quit large (130MB) but still blurry...Any idea why? Thank you!
function downloadPdf(chart) {
chart.exportImg({
save: false,
full: true,
scale: 4.6,
onLoad: (base64) => {
var pdf = new jspdf.jsPDF('landscape','mm','a0');
var img = new Image();
img.src = base64;
img.onload = function () {
var widthInInches = img.width;
var heightInInches = img.height;
var aspectRatio = img.height / img.width;
var pdfWidth = '1189';
var pdfHeight = pdfWidth * aspectRatio;
pdf.addImage(
img,
'JPEG',
0,
0,
pdfWidth,
pdfHeight
);
pdf.save('chart.pdf');
};
},
});
}
</script>
dbdaniellozynski Did you tried my method to generate pdf? I dont use native export from library.
@grzegorzCieslik95 Hi, I am not really a JS guy, I simply don't unterstand what to do with your code :-(
Oki, so i dont know how to help you with this. I had the same problem with this library native export
Ok, I tried to understand your code and came up with this (absolutely no idea if that should work that way, but at least it creates an very blurry PDF ;-)
Is that sort of the way you intended to use the code? Do you know why it's blurry?
`
d3.csv(
'd3__team_org_chart_d3.csv'
).then((data) => {
chart = new d3.OrgChart()
.nodeHeight((d) => 85 + 25)
.nodeWidth((d) => 290 + 2)
.childrenMargin((d) => 150)
.compactMarginBetween((d) => 350)
.compactMarginPair((d) => 90)
.neighbourMargin((a, b) => 100)
.nodeContent(function (d, i, arr, state) {
const color = '#FFFFFF';
const imageDiffVert = 25 + 2;
return `
<div style='width:${d.width} px;height:${d.data.height} px;padding-top:${imageDiffVert - 2}px;padding-left:1px;padding-right:1px'>
<div style="font-family: 'Inter', sans-serif;background-color:${color}; margin-left:-1px;width:${d.width - 2}px;height:${d.data.height - imageDiffVert}px;border-radius:10px;border: 1px solid #E4E2E9">
<div style="display:flex;justify-content:flex-end;margin-top:5px;margin-right:8px">${d.data.teamMembers}
</div>
<div style="background-color:${color};margin-top:${-imageDiffVert - 20}px;margin-left:${15}px;border-radius:100px;width:50px;height:50px;" ></div>
<div style="margin-top:${-imageDiffVert - 20
}px;"> <img src=" ${d.data.image}" style="margin-left:${20}px;border-radius:100px;width:40px;height:40px;" /></div>
<div style="font-size:15px;color:#08011E;margin-left:20px;margin-top:10px"> ${d.data.name
} </div>
<div style="color:#716E7B;margin-left:20px;margin-top:3px;font-size:12px;"> ${d.data.position
} </div>
</div>
</div>
`;
})
.container('.chart-container')
.data(data)
.render();
});
function computeToInlineStyles(node) {
const computedStyle = window.getComputedStyle(node);
const inlineStyle = Array.from(computedStyle).reduce((acc, styleName) => {
acc += `${styleName}: ${computedStyle.getPropertyValue(styleName)};`;
return acc;
}, '');
node.setAttribute('style', inlineStyle);
}
function getCorrectScale(nodesCount) {
// Logic to determine the scale based on the number of nodes
// Adjust scale based on the number of nodes
if (nodesCount > 50) {
return 0.5; // Example: Reduce scale if there are many nodes
} else {
return 1; // Default scale
}
}
async function exportChartToPDF(fileName, nodeClassName) {
if (!chart) {
console.error("chart not initialized");
return;
}
const { svg } = chart.getChartState();
if (!svg) {
console.error("SVG element not found in chart state.");
return;
}
const graphNode = svg.node();
if (!graphNode) {
console.error("Graph node not found.");
return;
}
computeToInlineStyles(graphNode); // Replace style to inline style
const { y: oY, x: oX } = graphNode.getBoundingClientRect();
const { height, width, x, y } = graphNode.children[0].getBoundingClientRect();
const opt = {
margin: [4, 8],
filename: fileName,
image: { type: 'jpeg', quality: 1 },
html2canvas: {
useCORS: true,
allowTaint: true,
letterRendering: true,
scale: getCorrectScale(document.getElementsByClassName("chart-container").length), // Get correct scale for nodes count
height,
width,
x: x - oX,
y: y - oY,
},
jsPDF: {
unit: 'px',
format: [height + 12, width + 16],
orientation: height > width ? 'p' : 'l',
},
};
return html2pdf()
.set(opt)
.from(graphNode)
.save();
}
</script>`
imho you need to add more scale -> I use values between 5 and 50 in my case
hi, @bumbeishvili is there any update on this thread, i have a tree with height 7; total of ~400 nodes the output for my pdf is same as @grzegorzCieslik95 posted in this thread [images and text are blurry ]
i tried generating an svg and using that svg inside the pdf also played with svg2pdf lib -> that didnot worked is there any idea to tackle this issue
@sachin717 how did you resolve this issue
@vatraiadarsh no update on my end