org-chart
org-chart copied to clipboard
Image export incomplete (missing styles)
Describe the bug Loving this lib :) But when I export the image, the image seems not complete (not all CSS styles seems to be taken into account)
To Reproduce Steps to reproduce the behavior:
- Create chart
- Apply some styling like this:
h1 {background-color: gray;}
(same for DIV borders etc.) - Export as PNG
Expected behavior Exported image should look like in the browser
Screenshots
Browser:
Export:
Full scss markup
div.node {
background-color: white;
border-radius:10px;
border: 1px solid lightgray;
padding: 0 $s $s $s;
max-height: 455px;
overflow: auto;
h1 {
font-size: $md;
margin: 0 (-$s) $s (-$s);
align-content: center;
text-align: center;
background-color: whitesmoke;
border-top-left-radius: $s;
border-top-right-radius: $s;
padding: $xs;
}
table {
border-collapse: collapse;
tr {
&:not(:first-child).category {
border-top: 1px solid lightgray;
}
&.odd {
background-color: white;
}
&.even {
background-color: whitesmoke;
}
&.category {
td {
padding-top: $s;
padding-bottom: $xs;
}
td:first-child {
font-weight: bold;
}
}
}
ul {
padding: 0 0 $xs;
margin: 0 0 0 $md;
}
}
}
Desktop (please complete the following information):
- OS: Win10x64
- Browser: Chrome 98.0.4758.102
- Org-Chart: 2.6.0
- d3: 7.3
You have two choices:
Choice 1. Apply those styles as inner CSS - it's tested and working well
Choice 2. Write a js function that will loop over Org Chart dom elements and will apply currently applied styles as inner style. This is theoretical and not sure if it's gonna work. If you do this approach, please also share the code, it may help other people with similar issues
Hello @bumbeishvili,
thanks for your quick response. I found this library here: https://github.com/lukehorvat/computed-style-to-inline-style They even mention inline SVGs for this. So maybe I am able to solve this. If I got time (and was successful), then I will post the solution here.
Looking forward to seeing the result
Hi there, did some tests today.
The library copied each css property over to the SVG in the DOM as it should:
(Styles now inlined)
But when calling 'exportImg()', the styles seem still ignored:
So it seems inline styles are the only variant
Helllo @bumbeishvili,
unfortunately that's not an option for me as there are quite complex (S)CSS selectors in place, regarding table structures in the nodes and so in.
It seems like this library didn't generate inline-styles for the HTML (data) struture inside the nodes but only the SVG nodes itself :(
In that case, maybe try to find some script that will generate inline styles for foreignObject elements? In theory, it should not be hard, it's just a traversing a dom tree and applying calculated styles as inner styles
Hello @bumbeishvili,
many thinks for your response. The strange thing is, even when I directly add styles by hand in the dom directly to an element via devtools, they get removed by the image export process:
Before:
After export attempt via
this.chart.exportImg({
full: true, // export the full chart, regardless of screen selection (does not work reliable)
scale: 5, // font gets smaller for many nodes, so we go BIG here,
})
@spyro2000 so, the process for exporting as an image is following
• Take SVG element • Convert it to String • Draw it on Canvas • Export image from Canvas element
If your styles are not part of the converted string in step 2, then it will not work. Maybe Dom element reference is different when you are applying the style using chrome and that's why it is not working, I am not exactly sure
@spyro2000 easiest way it to just inline your styles directly on your svg's elements. And don't use CSS variables. Use js template string variables instead.
Browsers ignore external stylesheets for svgs in canvas because they think they could be a source or arbitrary code that could get run as an attack.
You could write a function that grabs all the style rules from all the stylesheets, crawls your svg's element tree, and checks if any of the rules's selectors match, and append the rules to the element's style attribute, but it becomes incredibly slow with just a handful of chart nodes, and unusable pretty quickly.
Until browsers provide a way to export svgs directly, this isn't going to change.