Reputation: 49
i want rendering dcCharts on the server with node.js. I have an example with d3.js and node.js. But my code doesnt work. Im a beginner with node.js, hopefully yoe have an idea ?
The code for d3.js with node.js:example
and here what i try with dc.js and node.js:
var d3 = require('d3')
, dc = require('dc')
, jsdom = require('jsdom')
, fs = require('fs')
, htmlStub = '<html><head></head><body><div id="dataviz-container"></div><script src="js/d3.v3.min.js"></script></body></html>'
jsdom.env({
features : { QuerySelector : true }
, html : htmlStub
, done : function(errors, window) {
// this callback function pre-renders the dataviz inside the html document, then export result into a static file
var el = window.document.querySelector('#dataviz-container')
, body = window.document.querySelector('body')
var data = [
{date: "12/27/2012", http_404: 2, http_200: 190, http_302: 100},
{date: "12/28/2012", http_404: 2, http_200: 10, http_302: 100},
{date: "12/29/2012", http_404: 1, http_200: 300, http_302: 200},
{date: "12/30/2012", http_404: 2, http_200: 90, http_302: 0},
{date: "12/31/2012", http_404: 2, http_200: 90, http_302: 0},
{date: "01/01/2013", http_404: 2, http_200: 90, http_302: 0},
{date: "01/02/2013", http_404: 1, http_200: 10, http_302: 1},
{date: "01/03/2013", http_404: 2, http_200: 90, http_302: 0},
{date: "01/04/2013", http_404: 2, http_200: 90, http_302: 0},
{date: "01/05/2013", http_404: 2, http_200: 90, http_302: 0},
{date: "01/06/2013", http_404: 2, http_200: 200, http_302: 1},
{date: "01/07/2013", http_404: 1, http_200: 200, http_302: 100}
];
var ndx = crossfilter(data);
var parseDate = d3.time.format("%m/%d/%Y").parse;
data.forEach(function(d) {
d.date = parseDate(d.date);
d.total= d.http_404+d.http_200+d.http_302;
});
var dateDim = ndx.dimension(function(d) {return d.date;});
var hits = dateDim.group().reduceSum(function(d) {return d.total;});
var hitslineChart = dc.pieChart('dataviz-container');
hitslineChart
.width(500).height(200)
.transitionDuration(500)
.colors(d3.scale.category10())
.radius(90)
.dimension(dateDim)
.group(hits);
dc.renderAll();
// save result in an html file, we could also keep it in memory, or export the interesting fragment into a database for later use
var svgsrc = window.document.innerHTML
fs.writeFile('index.html', svgsrc, function(err) {
if(err) {
console.log('fehler beim speichern', err)
} else {
console.log('Datei wurde gespeichert!')
}
})
} // end jsDom done callback
})
I think var hitslineChart = dc.pieChart('dataviz-container');
is wrong.
I change know my htmlStub and dc.pieChart:
var hitslineChart = dc.pieChart('el');
htmlStub = '<html><head></head><body><div id="dataviz-container"></div></script><script type="text/javascript" src="js/d3.js"></script><script type="text/javascript" src="js/crossfilter.js"></script><script type="text/javascript" src="js/dc.js"></script></body></html>'
Unfortunately, I still get this error:
C:\Users\kasse\Code\node-modules\dc\dc.js:2366
var _colors = d3.scale.category20c();
ReferenceError: d3 is not defined
at Object.dc.colorChart (C:\Users\kasse\Code\node_modules\dc\dc.js:2366:19)
at Object.dc.pieChart (C:\Users\kasse\Code\node_modules\dc\dc.js:2971:31)
at jsdom.env.done (C:\Users\kasse\Code\pre_render.js:44:25)
at C:\Users\kasse\Code\node_modules\jsdom\lib\jsdom.js:255:9
at process._tickCallback (node.js:415:13)
at Function.Module.runMain (module.js:499:11)
at startup (node.js:119:16)
at node.js:902:3
Thanks for any help.
Upvotes: 1
Views: 2341
Reputation: 26
You need to make d3 a global variable inside your module:
global.d3 = d3;
... chart rendered here
dc.renderAll();
var svgsrc = window.document.querySelector('#bubbleChart');
fs.writeFile('chart.svg', svgsrc.innerHTML, function(err) {
if (err) {
console.log('error saving document', err);
} else {
console.log('The file was saved!');
}
});
Then convert the svg to a png using command line tools like ImageMagick. See this post for an example: http://eng.wealthfront.com/2011/12/converting-dynamic-svg-to-png-with.html
Upvotes: 1
Reputation: 3622
Your htmlStub is wrong, it has an extra </script>
in; that is almost certainly causing node.js to fail to run it.
It should (probably) be:
htmlStub = '<html><head></head><body><div id="dataviz-container"></div><script type="text/javascript" src="js/d3.js"></script><script type="text/javascript" src="js/crossfilter.js"></script><script type="text/javascript" src="js/dc.js"></script></body></html>';
Errors like this are more obvious if you break up the strings:
htmlStub = '<html><head></head><body>';
htmlStub += '<div id="dataviz-container"></div>';
htmlStub += '<script type="text/javascript" src="js/d3.js"></script>';
htmlStub += '<script type="text/javascript" src="js/crossfilter.js"></script>';
htmlStub += '<script type="text/javascript" src="js/dc.js"></script>';
htmlStub += '</body></html>';
Upvotes: 1