I'm using Node on a server side application, to dynamically produce graphs. I'm using d3.js and rickshaw.js to create SVG versions of the graph, and imagemagick to convert that SVG into a png. I am using JSDOM as my DOM.
I am getting this error: https://github.com/shutterstock/rickshaw/issues/186
The solution given here is to pull in the css, I found an answer on stack overflow on how to do this with JSDOM:
How do you ad stylesheets to JSDOM
So I've followed these instructions, and pulled in a rickshaw.css. When I print the DOM to console, I can see it in the head, in a style element.
var mainCss = fs.readFileSync(path.normalize("rickshaw.css"), 'utf8');
console.log("mainCss",mainCss);
var document = jsdom.jsdom("<!DOCTYPE html><html><meta http-equiv=\"content-type\"content=\"text/html; charset=utf-8\"><head></head><body id=\"abody\"><div id=\"chart_container\"><div id=\"y_axis\"></div><div id=\"chart\"></div></div></body></html>", jsdom.level(3, 'index'), {
features : {
FetchExternalResources : ['script', 'css'],
QuerySelector : true
}
});
GLOBAL.window = document.parentWindow;
var head = document.getElementsByTagName('head')[0];
style = document.createElement("style");
style.type = 'text/css';
style.innerHTML = mainCss;
head.appendChild(style);
I'm setting up my graph as so:
var graph = new Rickshaw.Graph( {
element: document.querySelector('#chart'),
width: 600,
height: 600,
series: seriesArr
});
var yAxis = new Rickshaw.Graph.Axis.Y({
graph: graph
});
var xAxis = new Rickshaw.Graph.Axis.Time({
graph: graph,
timeUnit: "hour"
});
yAxis.render();
xAxis.render();
graph.render();
utils.convertSVGtoPNG(document.querySelector('#chart').innerHTML);
Still I am getting a black square, as my output SVG.
Am I missing something? Am I thinking about something wrong? Any help would be greatly appreciated.
Unfortunately, it looks like imagemagick doesn't support external CSS and other people asking for solutions for similar problems haven't received any alternative suggestions for tools that do. So you're going to have to make sure that the relevant styles are applied inline in order for your SVG to PNG converter to recognize them.
The universal way to do this would be to write a script that traverses the CSS-DOM, grabs each rule, selects all elements that match the rule, and applies the corresponding styles to them as inline styles.
However, that would probably be overkill for your needs. Your specific problem is caused by the default style for
<path>
elements, which is solid black fill and no stroke. When using grid lines, this means that the axis domain path gets drawn as a solid black rectangle covering the entire plotting area.The simple solution is therefore to select these paths after drawing the axes, and apply custom styles directly:
If anyone is interested in the d3 selectors to replicate all css, as recommended by Amelia here they are:
It isn't formatted well, and I've had to remove any class that had pseudo-selectors.