Using NodeJs to render JavaScript charts on the server


Ideally, you want both rich interactive charts in your front-end (“just like Google Finance” is a common request) and the ability to render the same charts on the server for exporting, emailing, or supporting less capable clients (Blackberry, I’m looking at you). The perfect scenario would be to do this using the same library so that they look identical, and so you don’t have to maintain two separate code bases. Unfortunately due to limitations in libraries, platforms and environments – it’s difficult to make this a reality.

Recently, I’ve been developing a HTML5 application in which we used the Highcharts charting library to provide basic line and bar charts. Highcharts is a JavaScript library that will render either SVG or VML dependent on the hosting browser (if you’re interested, take a look at some of their demos). To support exports, the library will create an SVG in the browser and post it up to the web server. In the box (figuratively), they supply a php script which will render this content into an image or a PDF then return it over HTTP. This works great for situations where we have a full web browser, but sadly, we have to resort to another charting library that can produce static images to produce images on the server. It’s challenging to get the charts looking identical, and maintaining two code bases is a pain.

Unless you’ve had something better to do than constantly follow blogs and twitter (oh, just me then…), you’ve probably heard about Nodejs. It’s a server-side JavaScript implementation running on top of Google’s excellent V8 engine (the one under Chrome). Using the jsdom library, we can provide an environment similar to a browser into which we can load client-side scripts. With very little work, I was able to load up the Highcharts library in node, then using identical code which I would write for a browser, render the chart and grab the SVG content. Compare a chart rendering in a browser to the following from my node sample:

var $ = window.jQuery,
 Highcharts = window.Highcharts,
 document = window.document,
 $container = $('<div id="container" />'),
 chart;

$container.appendTo(document.body);

chart = new Highcharts.Chart({
 chart: {
  defaultSeriesType: chartType,
  renderTo: $container[0],
  renderer: 'SVG',
  width: width,
  height: height
 },
 series: [{
  animation: false,
  data: data
 }]
});

svg = $container.children().html();

Once we’ve grabbed this SVG content, we can render it to an image using the command line tool convert. As it’s super easy in Node to create a basic web server (literally just a single function), I created a basic server which accepts requests like /bar?data=1,2,3,4 and will return the chart rendered as an image using Highcharts.

this.server = http.createServer(function(request, response) {
	var url = parse(request.url, true),
		chartTypeMatch = /^\/(\w+)$/.exec(url.pathname),
		chartType	= chartTypeMatch ? chartTypeMatch[1] : null,

	/* Some code omitted */
	createHighchartsWindow(function(window) {
		/* chart generation from above */

		svg = $container.children().html();

		// Start convert reading in an svg and outputting a png
		convert	= spawn('convert', ['svg:-', 'png:-']);

		// We're writing an image, hopefully...
		response.writeHeader(200, {'Content-Type': 'image/png'});

		// Pump in the svg content
		convert.stdin.write(svg);
		convert.stdin.end();

		// Write the output of convert straight to the response
		convert.stdout.on('data', function(data) {
			response.write(data);
		});

		// When we're done rendering, we're done
		convert.on('exit', function(code) {
			response.end();
		});
	});
}).listen(2308); // Start HTTP server listening on port 2308

So far I’ve only prototyped these ideas, but it’s working pretty well (see image below). Although I’ve used Highcharts for this example, it should be possible to use any SVG based JavaScript charting package. I feel this technique has the potential to be able to support both rich client side charts and static server generated images using the same libraries, and most importantly, sharing the same code. My prototype is available at up at GitHub. What do you think?

Highcharts chart rendered on Node
About these ads

163 thoughts on “Using NodeJs to render JavaScript charts on the server

  1. JsDom is designed to be as lightweight as possible so it’s super quick. Take a look at the bulk of the code on GitHub. It did feel a little weird at first to pretend that there’s a browser inside node, however once I’d read about how JsDom works and how the scripts are executed, it was pretty straight forward.

    The code could also very likely be improved from my prototype. I’m currently creating a ‘window’ object on every request. Assuming the chart can be destroyed cleanly (I think it can). We could only create it once and just remove the chart node when completed. Of course it’s debatable whether responding to an HTTP request is the best way to generate these charts, it could also be done as an offline process.

  2. hey Dave,

    I’m totally new to node, but can you give me a really simple example on how you actually run your code on the server and save the chart to file.

    I have node installed and your code. I then type node index.js and i get listening on 2308.

    thanks,
    tj.

  3. Hi Dave,

    I’m trying to get this to work myself. I have this error now after calling like this?

    lynx 127.0.0.1:2308/chartType?data=0,1,2,3

    /usr/local/lib/node/.npm/jsdom/0.1.16/package/lib/jsdom/browser/index.js:325
            process.binding('evals').Script.runInNewContext(
                                            ^
    TypeError: undefined is not a function
        at CALL_NON_FUNCTION_AS_CONSTRUCTOR (native)
        at Object.xhr (http://code.jquery.com/jquery-latest.js:5482:11)
        at http://code.jquery.com/jquery-latest.js:6012:45
        at http://code.jquery.com/jquery-latest.js:6883:2
        at /usr/local/lib/node/.npm/jsdom/0.1.16/package/lib/jsdom/browser/index.js:325:41
        at IncomingMessage. (/usr/local/lib/node/.npm/jsdom/0.1.16/package/lib/jsdom/browser/index.js:367:13)
        at IncomingMessage.emit (events:41:20)
        at HTTPParser.onMessageComplete (http:107:23)
        at Client.onData [as ondata] (http:848:27)
        at IOWatcher.callback (net:494:29)
    
    • Looks like this is an issue with jquery 1.4.3

      Change line 39 in index.js to include the path to jquery 1.4.2, works for me.


      jsdom.jQueryify(window, "http://code.jquery.com/jquery-1.4.2.min.js", function() {
      script.src = 'file://' + __dirname + '/highcharts/highcharts.src.js';
      script.onload = function() {
      if (this.readyState === 'complete') {
      fn(window);
      }
      }
      });

      Thanks for sharing

      Cheers
      Roger.

  4. thanks guys, i am progressing, BUT im now getting this error.

    listening on 2308
    writeHeader() has been renamed to writeHead()
    Generating chartType chart
    
    node.js:63
        throw e;
        ^
    Error: EPIPE, Broken pipe
        at Stream._writeImpl (net:300:14)
        at Stream._writeOut (net:732:25)
        at Stream.write (net:665:17)
        at /home/touchpoint/node/node-v0.2.3/test/hc/index.js:106:17
        at Object.onload (/home/touchpoint/node/node-v0.2.3/test/hc/index.js:44:5)
        at /usr/local/lib/node/.npm/jsdom/0.1.16/package/lib/jsdom/browser/index.js:332:19
        at /usr/local/lib/node/.npm/jsdom/0.1.16/package/lib/jsdom/browser/index.js:349:11
        at fs:84:13
        at node.js:768:9

    I hate not solving things for myself but i am really stuck with how to debug these errors.

    -tj

  5. Hi Dave,

    I am still getting the same error message, I did have the url wrong (thanks for that).

    here is the error:

    
    listening on 2308
    writeHeader() has been renamed to writeHead()
    Generating bar chart
    
    node.js:63
        throw e;
        ^
    Error: EPIPE, Broken pipe
        at Stream._writeImpl (net:300:14)
        at Stream._writeOut (net:732:25)
        at Stream.write (net:665:17)
        at /home/touchpoint/node/node-v0.2.3/test/hc/index.js:106:17
        at Object.onload (/home/touchpoint/node/node-v0.2.3/test/hc/index.js:44:1)
        at /usr/local/lib/node/.npm/jsdom/0.1.16/package/lib/jsdom/browser/index.js:332:19
        at /usr/local/lib/node/.npm/jsdom/0.1.16/package/lib/jsdom/browser/index.js:349:11
        at fs:84:13
        at node.js:768:9
    
    
    
    • It looks like there may have been some changes to node since I wrote this, note the writeHeader/writeHead messahe. Change writeHeader to writeHead.

      I’ll make sure it’s updated to the latest version of node when I get a chance. Sorry for all this inconvenience.

  6. Hi David,

    that was magic. how did you manage to get it working?
    got the same error as TJ. Do I need to place batik-rasterizer.jar, related lib and index.php for an export side by side to the index.js?

    • Hey Artyom,

      You don’t need any of the highcharts components to export server side, just the convert command line SVG renderer – http://www.imagemagick.org/script/convert.php. The above is just a proof of concept and not a ready to go solution. I’m considering trying to make it a normal node “highcharts” library which will just take the highcharts options obj and return an image of some description. It’s good to know there’s interest.

      David.

  7. Hi Dave,
    I have a couple of questions – I’m struggling a bit to get this thing running. Not sure if there have been changes in the latest jsdom but your code that loads the scripts isn’t actually loading highcharts for me. I put console logs in all the included files and jsdom is getting loaded so is jquery but high charts is not unless I do something like

    // Load scripts
    jsdom.jQueryify(window, “highcharts/jquery.min.js”, function(window, jsdom) {
    script.type= ‘text/javascript';
    script.src = ‘file://highcharts/highcharts.src.js';
    script.onload = function() {
    fn(window);
    }
    var head= window.document.getElementsByTagName(‘head’)[0];
    head.appendChild(script);
    });

    Also, when onload gets called the readystate is undefined in my onload function.

    Any ideas what might be going on?

    Thanks!

    • Hey Dale,

      I think both Node and JsDom have changed quite a bit since this post. As you’re not the first person I’m going to put some effort in to clean this up and maybe find a way to release the server integration as a proper library. I’ll try to have a bash at starting it later this evening or maybe tomorrow. I’ll let you know.

      David.

      • Thanks David! If possible maybe you could post the versions of jsdom, nodeJS, and jquery that you worked with. I noticed you checked in HighCharts. Did you make mods to that?

  8. Hey David,
    I was able to get your prototype running using older versions of node and JsDom. The svg that gets generated by High Charts will render fine in Chrome and Image Viewer. (I saved it to a .svg file) However, I’ve not been able to get convert or batik to convert the file. My question to you is did you have to clean up the svg to get it to convert? Did you have to make any changes to the High Charts code?

    Thanks
    -Dale

    • Hey Dale,
      Thanks for your perseverance. I’ve just tried it myself and managed to get it running roughly against the current version of node and the most recent JsDom in npm. I hit some difficultly with a newer version of jQuery but haven’t had a chance to take a good look at it.
      I think I had to make one or two changes to the highcharts code to get it working, nothing significant – just global scope issues I think. I’ll try it against a recently version and see what I find.
      I’ve started (20 mins) trying to pull it together into a actual node library which you’ll be able to hand a Highchart’s options object and be handed back a png encoded Buffer. Check it out at https://github.com/davidpadbury/node-highcharts. Feel free to fork ;)

      David.

      • Very cool. I can’t wait to give it a try. Today I finally got the system spitting out jpegs. Maybe its because I’m using a real life line graph with lots of options, but I had to write a ton of code to sanitize the svg before batik would convert it. I got this running completely inside of Tomcat without shelling out or spawning any child processes using the Rhino and Batik jars

      • No, I went down the JsDom/nodeJS/convert path but I really wanted a pure Java solution and one where I didn’t have to shell out of tomcat. So, I switched over to using Rhino, envjs and Batik. Batik complained a lot about the generated svg and their parser isn’t very helpful in pointing out the errors. I had to write a fair bit of scrubbing code and its mostly by trial and error. I want to thank you again for getting me going in the right direction.

        cheers!
        -Dale

      • Hi David,

        Glad I found this because I was just about to start something similar.

        I’m having a lot of trouble getting the resulting svg to convert properly. At this point, I’ve tried both the convert that came with Ubuntu 10.04 as well as the latest ImageMagick convert compiled from source. Neither work. I also tried batik, but after spending 20 minutes fixing errors there was no end in sight.

        What program and version are you using for svg conversions?

  9. Hi David. Glad you had a progress. Unlike you I still get an exception with the latest files from github(trying to run test/index.js) I’m such a noob so I don’t even understand where the error is:

    debian:~/node1/test# node ./index.js

    node.js:63
    throw e;
    ^
    Error: EPIPE, Broken pipe
    at Stream._writeImpl (net:300:14)
    at Stream._writeOut (net:740:25)
    at Stream.write (net:673:17)
    at /root/node1/lib/node-highcharts.js:54:17
    at Object.onload (/root/node1/lib/node-highcharts.js:30:5)
    at Object.javascript (/usr/local/lib/node/.npm/jsdom/0.1.20/package/lib/jsdom/level2/languages/javascript.js:15:13)
    at /usr/local/lib/node/.npm/jsdom/0.1.20/package/lib/jsdom/level2/html.js:970:35
    at fs:84:13
    at node.js:773:9
    Is it at line 30 of /root/node1/lib/node-highcharts.js where “callback(window);” is called? or at line 54 on “convert.stdin.write(svg);”?
    could you plz help me a bit? may be my server lacks some libs or have different versions of node/jsdom/jquery/whatever?

    thx in advance!

  10. Avery, I am using the latest batik. I too spent a lot of time chasing down mysterious errors. I finally got the svg code scrubbed enough to work. If you are using High Charts 2.1 you can call chart.getSvg() and it will do a lot of the scrubbing for you. If not try looking at their exporting.src.js module and you will see the scrubbing that High charts had to do to get their examples to export. I had to do even a bit more.

  11. Thanks for the suggestions. I ended up using rsvg-convert from librsvg, which works well without modifications to the SVG output.

    The only other issue I’m having is that if I call render, then node.js will no longer exit when there’s nothing left to do, sort of like there’s a lingering event listener that hasn’t been called. Any ideas?

  12. Tried this with some latest and greatest of various libraries and i’m having issues with the conversion (I think). I can view the .svg in my viewer and it looks to be what I’m attempting to create, but when it converts it turns it to an empty, but correctly sized, .png having just a left and top border. Just empty white space. Seen this before?

    I can print the svg to the console, copy paste it into a file, and run the conversion tool on it. Doing so results in this error: convert: non-conforming drawing primitive definition `,’ @ error/draw.c/DrawImage/3147.

    With so many moving parts its hard to know what might be causing this issue. One library I haven’t updated to the current is Highcharts. That’s pretty much a no go. But all the node stuff is freshly installed from npm and ImageMagik is freshly installed as well.

    Any thoughts?

      • Done!

        Worth mentioning that it is behaving this way with the little test example you have in your distro. I had to make a few changes to get it to run, not nothing (I don’t think) that would cause any issues. Just had to be done to make anything happen.

      • Great – I’ll take a look at it as soon as I can. It’s probably just an issue with cleaning up the outputted SVG from highcharts to be suitable for ImageMagik. I’ll try to clear it up a little to make this project a little more usable.

  13. Because it is a bit more forthcoming with error messages, I was able to get batik to turn the svg outputted by highcharts into what appears to be the right png. Had to do things like change clippath to clipPath and fill empty (“”) x/y/width/height params with zeros.

    ImageMagick still complained. Spent some time with it, and it seems to dislike font-family when it looks like this…

    font-family:'lucida grande', 'lucida sans unicode', verdana, arial, helvetica, sans-serif

    Throughout the .svg I removed the first two entries, leaving just…

    verdana, arial, helvetica, sans-serif

    …and it generates the image just fine, but the image itself is fairly warped looking.

    I’m well outside my comfort zone with this stuff, just sort of taking shots in the dark. Could well be I’m arsing things up a bit somewhere.

  14. Hi David,

    that’s exactly what I need but I don’t get it quite right, I think the code is not complete. In the first line you’re using window which is not defined. What must be included to getit running?

    • Hey Stefan, yeah – it’s a bit of a mess and is difficult (perhaps impossible) to reuse in it’s current state. I’m working on it again for a talk I’ve got coming up so I’m hoping to get it in a suitable state to push to npm.

  15. For a current version of highcharts there must be found a replacement or an implementation for getBBox() calls. Other necessary changes are the same as already done by David.

    • Hey Stefan. I’ve been working on replacing the dependency on having image magick installed with node-canvas and CanVG. The BBox call is actually a bit problematic – there’s a few places in the highcharts codebase that depend on being able to measure elements, which is clearly quite difficult for us. I’m trying to come up with alternatives. Expect a release soon. Honest.

  16. David –

    I’ve tried to get your example running on my Windows XP box with the node binaries from http://node-js.prcn.co.cc. I did encounter a missing jsdom for the require() which I think I resolved by adding them to the /lib folder. Now I’m getting an error about missing module ‘request’ from within the jsdom.js.

    Since I’m on a deadline to get this little project (convert Highcharts to PDF) done, I finally decided to write my own jQuery.post coldfusion page to convert the SVG to PNG for inclusion via an img tag. I did discover that the ImageMagick convert couldn’t handle the SVG – something about the font-family: containing font names with embedded spaces. Ended up using Inkscape – incredible package!

    • I haven’t updated this for a couple of months so it probably needs another update for node 4 and the newer versions of the libraries.

      You should probably being using npm for installing jsdom if you’re not already.

  17. David,

    I’m sure you’re pretty tired of this thread being dragged back up, but I’m having a peculiar problem with your code: the script.onload event will not fire, regardless of the value of the script.src to load Highcharts. I tried replacing this with a node.js require(), only to find the window/document variables were out of scope in the file.

    This code is the exact solution to my problem, so if I can get this working, it would be ideal.

    Any advice?

    Thanks,
    Travis

    • To follow up, I’ve done a bit more testing. Rewriting your example to use jsdom.env, and trying out Zombie, both return the same error:
      ‘Invalid character in tag name: <'

      This originates from the highcharts.js file. At a loss here.

      • Hi Travis,

        Sorry you’re having difficulties with it. I’m afraid it’s so long since I originally threw it together that just about all the libraries have had significant changes. I’ll give it a quick bash now and let you know how far I get.

      • David,

        Thank you very much for updating this code! I’m going to run with this and see what I can do to get it fully working. With your example, I’m getting the same “empty PNG with top and left borders” that db mentioned above, and the hanging that Avery Fay mentioned.

        I can alter it to push out the SVG just fine (although it’s still hanging).

        Thanks so much!

      • Someone emailed me a while back to let me know that they’d fixed the hanging problem but wasn’t good enough to share how… I assume it’s high charts registering some kind of callback which keeps node waiting. Do feel free to let me know what progress you make, or better yet get me to pull something ;)

      • Using the librsvg instead of ImageMagick fixed the clipping issue — although for anyone seeing this in the future, I had to install xorg-x11-fonts on my server since I didn’t have an x11 server running–I was just getting boxes for the letters before I did that.

      • I’m keen on investigating converting the svg to canvas via CanVG and then using node-canvas to render the thing. That way the entire lib would be npm’able.

        Could maybe investigate node bindings to librsvg as well if no one has yet…

      • Well, David, after pouring over the highcharts code, disabling every event listener I could find… I’ve gotten nowhere on that front. I don’t really know node.js well (I’m actually only using it for this specific task =X), so I’ve really exhausted my resources.

        I’m taking the easy (albeit naughty) route and doing a process.exit(0) after my successful file generation.

        Thanks for your help!

      • No waste of time at all! I have a fully functioning (although somewhat hacky) server-side solution to generate my thumbnails! I’m very pleased!

        You’re definitely right in that it’s the highcharts.js though… disabling that call prevents the process from hanging–which is why I dug through attempting to find the issue.

        Throughout this whole process I just kept thinking there’s got to be a way to get a list of all listeners and timers in node.js, but I couldn’t find anything to that tune.

      • I did not. I’m not exposing any ports for node to use at the moment, and would need to get a lot of approval before opening something up (it’s a production server).

        If I get some time this weekend, I may crack open a local copy and give this a whirl.

  18. Hi Dave,

    amazing!and This way I can configure interactively charts in the browser and then generate PDF reports on the server using this JSON configuration. Thank you!

    Best Andreas

  19. I have spent quite a bit of time looking at getting the newer versions of highcharts and jquery to work with nodejs using your framework. It looks like there are many things that highcharts (as does most client-side javascript) expects the browsers to do that nodejs does not. Even if you hardcode the browser detection isIE,isWebkit,etc., the SVG generated by highcharts in node is very different from the SVG generated using the exporting module button in a browser. In fact, it’s not even valid XML, as the text nodes have style attributes redefined. Bummer.

    • The highcharts object has a “GetSVG” method, try that.

      Also, I’ve actually sadly abandoned this method in my production environment. It was simply too much of a hassle, too slow, and broke too frequently. I’m actually performing an AJAX call when the chart is loaded, and sending the results of GetSVG back to the server, then converting that to PNG via librsvg. I’ve found this to be incredibly reliable with very minimal impact on the client.

      The worst part is you can’t systematically generate your thumbnails using only the server. You can run a scheduled task (or cron job equivalent) on your local machine (or any machine with a “head”) to poll your site at any time to perform the rendering and updating AJAX call.

      YMMV, good luck and godspeed all.

      • Hi

        I’ve a ‘almost’ working environment, and I think I have the same issue as Alex, regarding svg generated by getSVG, has issues with legends, Y labels, and is putting one on top of the others.

        But SVG generated by highcharts (in the classic way, though web browser) does _not_ has this problems..

        In my case, I could not use the AJAX call on each onload() event, because my app is working completely in background.

        any ideas?
        Thanks in advance

      • Hi Efrain,

        The difficultly is that Highcharts wants to measure it’s contents to layout things like the legend (this happens in the getBBox function). As they’re actually getting laid out in jsdom we don’t have any dimensions available.

        We got through most of this by just manually positioning everything in Highcharts. You could take a bash at filling in the getBBox function to look at the element and attempt to estimate it’s size – many elements will have height and width properties set. Although I’m afraid it’s nothing I’ve attempted and it’s been a while since I touched all of this.

        David.

      • @Efrain,

        I don’t know how to fix the jsdom side of things, but there is one thing you can do to render on the client side without them seeing: create an iFrame and, using absolute positioning, move it to where they can’t see it. The iFrame will contain all the highcharts items as well as the async call to report the SVG back to the server.

        I know this method seems naughty, but if you absolutely have to get a production unit up and running like I did, this might be your best bet.

      • I wouldn’t say it’s naughty. If you have access to a browser then just use the standard exporting functionality in Highcharts. You can then take the SVG and render it anywhere you like (Highcharts comes with a php exaple and I’ve done it ASP.NET and Java using the same technique).

        This node stuff is only for when you can’t use a browser.

      • Thanks guys,

        I’ll try your suggestions, I’ve already have the standard exporting options working, so It should be no problem about it.

        Regards

    • Hi, I’m using the (almost) latest highcharts version. My present diff is
      1511c1511
      nodeName = element.nodeName.toLowerCase(),

      Not much, right? :-)

      Along with this snippet of code:
      Chart.prototype.createHighchartsWindow = function(fn) {
      var window = jsdom.jsdom().createWindow();
      var script = window.document.createElement(‘script’);

      // jsdom doesn’t yet support createElementNS, so just fake it up
      window.document.createElementNS = function(ns, tagName) {
      var elem = window.document.createElement(tagName);
      elem.getBBox = function() {
      if (this.textContent) {
      return {
      width: this.textContent.length * 6.5,
      height: 14
      }
      }
      return {
      x: elem.offsetLeft,
      y: elem.offsetTop,
      width: elem.offsetWidth,
      height: elem.offsetHeight
      };
      };
      elem.createSVGRect = function() {}
      return elem;
      };

      // Load scripts
      jsdom.jQueryify(window, __dirname + ‘/lib/jquery-1.4.4.js’, function() {
      script.src = ‘file://’ + __dirname + ‘/lib/highcharts/highcharts.src_110803_charts.js';
      script.type = ‘text/javascript';
      script.onload = function() {
      fn(window);
      }
      var head = window.document.getElementsByTagName(‘head’)[0];
      head.appendChild(script);
      });
      };

      Surely, it doesn’t support different font sizes.

  20. Kind of pulling my hair out here. Has to be something simple.

    Regardless of the way I grab SVG (existing container html approach, or latest getSVG), when I generate the SVG into an image or PDF, using any tool (convert, xhtml2pdf, whatever) – I get a blank image. The dimensions are there, but it’s totally white.

    Anyone ever experienced this?

    • In response to my own message, it seems the issue is:

      .getSVG while running under node does not generate valid XML markup and it’s inconsistent with what is generated when getSVG is fired from the browser.

      If the client is made to post the SVG content from the browser to the server, it’s valid.

      If nodejs is used to generate the SVG from either grabbing it from the container, or using the getSVG function call, it does not create valid SVG.

      This goes back to the earlier comment that jsdom is not handling the style attribute correctly, and it is duplicated and therefore a malformed xml block causing the converters to fail.

  21. Highcharts 2.1.x is not compatible with node-highcharts.
    2.0.5 is the last compatible version, distributed with node-highcharts.

    Would be great to use the same version of Highcharts on both client and server sides.

  22. Hi,
    I tried your example. i created a var svg and loaded it with the svg of a chart.
    i did content.stdin.write(svg) but when i do content.stdout.on(‘data’) it always returns false.
    Please help me i am stuck.

  23. Hey guys,

    I just upgraded to Highcharts 2.1.9. Here’s my diff to make it work:

    using jquery 1.6.4.min
    jquery >1.7 doesn’t work

    • Stefan,

      I have tried to patch Highcharts 2.1.9 using your diffs below in conjunction with jquery-1.6.4.min.js. Could you provide a zip to a working node.js solution or even just the entire patched 2.1.9 Highcharts library?

      Just out of curiosity, does this fix display problems such as jumbled legends as mentioned above?

      • Have you tried the unified diff in the post below? It also tells you the exact version of highcharts that I use. If you can’t apply the patch using the appropriate tools, you can do it manually, it’s only a small diff. There’s no place where I can put the patched lib.

        My patch doesn’t fix anything, but if problems are related to element dimensions, my createElementNS function I posted on February 20 might be helpful. Play with the numeric constants to get a good result.

      • Thank you very much, stefan4! Your patch did work for me this time and your version of createElementNS (from September 13, 2011 it looks like) did the trick for my legends.

        The last important feature that I’m struggling with is null points. It is very important for my server-side charts to NOT show lines connecting when null points are present. I am able to send Highcharts the data [1, 2, null, 4, 5] and see the gap, but when I provide 1000 points with two nulls, the lines get connected. The second case works just fine with 2.2.0 in a browser. This seems very weird to me, any idea?

        I’m going to email Highcharts too and see if they can help me. The changelog for 2.2.0 says the numerous bugs and have better performance with thousands of points. Unfortunately, it doesn’t look that they have a place where I can go see exactly what bugs were fixed, so hopefully they will respond to my email.

      • I’m glad to hear that it works for you. As for the nulls, I haven’t had that case so far, but I know about a plotOption “connectNulls”.

      • Yeah, the connectNulls option default to false, though. Since you mentioned it, I went ahead and explicetly set it just to make sure the default wasn’t different in 2.1.9 – but that did not help.

        Upon further inspection, this definitely seems to be a Highcharts bug when dealing with a large number of points that they have already fixed in 2.2.0. I started messing around with the data by zooming in moving around (technically not zooming – I’m viewing decimated data through ajax) and noticed that null point does but at a random spot in the data until you get to about 40 points or less.

        Hopefully they will respond to my email, otherwise its time to sift through 2.2.0 and see what they might have changed. :o

        Thanks again for your help!!

  24. Pingback: Using NodeJs to render JavaScript charts on the server | x443

  25. I’ve been trying your solution Stefan, but I am getting the following problem. On creating the chart (chart = Highcharts.Chart(options) ), I get the following error:
    Error: Invalid character: Invalid character in tag name: <
    Any ideas?

  26. I have had invalid character in tag name several times and had to analyze the SVG to find out.
    For me, it was the added copyright character (i use \uA9)
    and the solution is to use the export module (it sanitizes the SVG) and add

    options.credits.text = options.credits.text.replace(/\xA9/,'(c)’);

    in the getSVG function.

  27. A great idea, one would have hoped that HighChart would take this on, as a serverside component would be a great addition to their offerings.

  28. Pingback: The Node.js Revolution, or: How I Learned to Stop Worrying and Love the Node « James on JavaScript

  29. We’ve just released our html5 canvas charting javascript library for node.js.
    (It does not need jsdom, the only dependency is the node “canvas” package).

    It can be installed from npm (“npm install TeeChart”) and includes a small main.js sample script that returns png images created server-side.

    http://search.npmjs.org/#/TeeChart

  30. Hi David

    I am completely new to the node.js, I got a requirement to export HighCharts into pdf and come across with this article. I installed Node.js (http://nodejs.org) and downloaded your sample – I am not able to run your sample. I am getting below errorr message

    node.js:201
    throw e; // process.nextTick error, or ‘error’ event on first tick
    ^
    Error: Cannot find module ‘node-highcharts’
    at Function._resolveFilename (module.js:332:11)
    at Function._load (module.js:279:25)
    at Module.require (module.js:354:17)
    at require (module.js:370:17)
    at Object. (C:\Program Files\nodejs\example.js:2:18)
    at Module._compile (module.js:441:26)
    at Object..js (module.js:459:10)
    at Module.load (module.js:348:31)
    at Function._load (module.js:308:12)
    at Array.0 (module.js:479:10)

    Your help will be much apprecitated

    Thanks
    Jiju Antony

  31. I am getting an empty image. using jquery 1.7.1 and highchart 2.2.3. any idiea…I can see the svg content when console.log(svg).

  32. Pingback: jQuery plugins with node.js | Easy jQuery | Free Popular Tips Tricks Plugins API Javascript and Themes

  33. Why am I seeing an empty image even though the svg is generated fine. The svg generated renders fine on the browser but conversion fails by imageMagick convert.

    Can anyone please reply to this thread?

    • If your svg looks fine, you start getting a little off-topic, but I can give you my convert version and my command line parameters (converts from stdin to stdout):
      convert -density 150 -quality 100 svg:- png:-
      The version number is “Version: ImageMagick 6.2.8″
      Good luck.

  34. IMHO, if your server side is a Unix machine, your best bet is to run Xvfb and launch firefox on the server side, then Ajax the SVG data back to the web server, web server stores it and terminates firefox process. It’s the most foolproof because

    1. As long as you have a working html file with Highcharts, it will work on the server side. Just using the same script.
    2. You don’t need to stick any particular version of Highcharts.

  35. Pingback: Script installation service

  36. Pingback: Highcharts und PrinceXML | freakcommander

  37. Pingback: Server-Side HighStock charts generation with NodeJS | BlogoSfera

  38. In node-highcharts,js –> window.jQuery,
    Highcharts = window.Highcharts, was throwing errors both are undefined, so i was unable to generate svg using render method..

    Please provide your input how to proceed on this,
    Thanks

  39. Bars of 12 to 14 inches are adequate for most small chores, while an 18- or 20-inch bar is necessary
    to remove large trees. Numerous folks would
    say that the electric chainsaw is usually greater than those that are powered
    by gas alone. The files are fairly reasonably priced, only a few pounds each, so it may be worth purchasing them in
    bulk if you undertake lots of timber cutting.

  40. Is is possible for node to do all the javascript parsing of data and highcharts generation of charts – but then return the whole DOM for the chart not just SVG. This way the chart would still be interactive? Not just an image?

    We are looking at this since Highcharts with lots of data is SLOW on IE8.

  41. We are the only dry cleaners who do not [url=http://www.mybootsclearanceshop.com/]UGGS Sale Clearance[/url] clean with the toxic chemical known as perchlorethylene.Haix boots are also manufactured for [url=http://www.mybootsclearanceshop.com/UGGS-CLEARANCE-ITEM/UGG-BAILEY-BUTTON-BOOTS-5803/]UGG Bailey Button Boots[/url] fire fighters. They are available in several stores today. To decrease these kinds of risks, suitable gadgets and equipment need to be utilized when performing yoga methods.”Assertiveness may possibly not make you really feel less stressed however it can, if practiced, boost the chances of the being heard and understood. Many home owners are not aware of the unconventional way of selling property without the services of estate agents or house brokers. This will give any dinner party, even if it is just a family gathering, a whole new ambience and believe it or not, it will make the food taste better too! Presentation is a big part of dining but many of us do not take the trouble to work on presentation when it comes to family meals. This procedure saves both the client and service provider precious time and money. Let’s just take the delivery from China to Australia for example. However, it doesnt have to. However ,, you can create that good by means of selecting the right automotive and additionally receiving the very best cope into it.The “log book” can surely federal and state must every driver must hold on to showing what they’re creating every minute of day time. Once the party is over, the hangover has quietened down to a dull throb and you聮re ready to face the [url=http://www.mybootsclearanceshop.com/NEW-UGG-BOOTS-2013/UGG-KENSINGTON-BOOTS-TOAST-5678/]UGG Boots Kensington[/url] world again, the carpet protection film can be easily removed without leaving any adhesive residue or tearing out half your pile along with it.

  42. Others thionk the habit is more likely connected to their checking the ground
    for the scent of its enemies, since the ddog has its nose to the grounhd during the turning around.
    There is a department on Free and Low coost
    Heelp which can’t allow specific referrals, but which pointfs you in thhe right direction.

    Well, everyone witth dogs wants to be like Amtrak.

  43. hey Dave,

    I’m totally new to node, but can you give me a really simple example on how you actually run your code on the server and save the chart to file.

    thanks,
    tj.

  44. If you have been trying to promote your own web site and you
    have received traffic every hour, my hands are down for you.
    This doesn’t mean getting your family and associates
    to vote for your substance out of the goodness of their hearts (admitting
    that does not damage either. Traders pushed the Board
    of Trade to shorten its schedule when in actual fact surgical.

  45. The company also targets food processing, wastes, and fertilizers.
    There, they actually water and wall arlington can polish the water or it
    can be like this that means volume. Usually we have to
    seee the slide so it is the little things that we are treating the waste
    disposal? Estuaries is the zone where the root of the
    problem of wazter pollution to explain what you have to get fom the hinder settling velocity.
    The hormones from birth control water and wall arlington pills are showing upp in the northern areas.

  46. Its like you learn my thoughts! You appear to understand so much
    about this, like you wrote the guide in it or something.
    I believe that you simply can do with some p.c. to power the
    message home a little bit, however instead of
    that, that is fantastic blog. A fantastic read.

    I will definitely be back.

  47. Great goods from you, man. I’ve understand your stuff previous to and you are just extremely excellent.
    I really like what you’ve acquired here, really like what you
    are stating and the way in which you say it. You make it enjoyable and
    you still care for to keep it sensible. I cant wait
    to read much more from you. This is really a great website.

  48. I really like what you guys tend to be up too.

    This sort of clever work and exposure! Keep up the great works guys I’ve incorporated you guys to my personal
    blogroll.
    Hello, i think that i saw you visited my site so i came to “return the favor”.I am trying to
    find things to improve my site!I suppose its
    ok to use a few of your ideas!\

  49. Might I ask if your are ok with paid blog entries? All I would want is for you to post content for me and also a hyperlink or reference to my web site.
    I am going to compensate you.

  50. Have you ever considered about including a
    little bit more than just your articles? I mean, what you say is valuable and all.
    But think of if you added some great photos or video clips to give your posts more,
    “pop”! Your content is excellent but with images and clips, this website could
    certainly be one of the very best in its niche. Superb blog!

  51. Hello everybody, here every one is sharing such know-how, so it’s good to read this webpage, and I
    used to pay a quick visit this blog every day.

  52. Do you find fitness easy or hard? Want to learn the way to improve
    on your physical appearance or health? Should you be ready,
    then you definitely came to the correct location.

  53. Determining to keep to the ideas layed out earlier mentioned can be a wonderful beginning
    point. Come up with a unique physical fitness playlist, featuring tracks you are
    aware can keep yourself on path.

  54. Walk on the road, Air Jordan Basketball Shoes is season and mood, even if the clothes on regulators haven’t altered and a jacket unlined higher garment, but the shoes will have significant seasonal eset, a pair of shoes, the first change garments based on the season like a new fashion taking, imagine detecting steps possess seer did not see it’s person the effect of the shoes.

    Nike Air Jordans Footwear , this seemingly bizarre shoe money is actually the earliest high-heeled shoes. It was born in the 15th century French courtroom, hundreds of years it is unique. But really let it well-known Vivienne Westwood set million is in her, 1993 conference “Naomi Campbell black pearls” supermodel with stepping on a footwear 8 inches higher, and play this particular fall on the stage, it has become popular through the 1990s. Now Vivienne Westwood this pair of shoes is being collected V&A museum in London for people to view and admire.

    Candy color chiffon unlined upper garment, delicate and stereo feeling cross-over collar, very sexy, natural drape line, relaxed and style, make easily a delicate lumbar curve, the drape of dress type design, Air Jordan Shoes For Sale, really sweet romance.

    Leisure time vacation how less got broken flower skirt skirt oh yea. Many fashionable NBA Basketball Jerseys, growth blasting design individuals must have. Contracted take waist style, sq . deep cut brought clipping, reveal the fashionable glamour of incomparable.

    Classic fashionable black Football Team Jerseys and white stripe unlined upper garment, very exaggerated sense flabby modelling, suitable for all kinds of figure of the United States brow, beardless figure restriction, radian feeling round brought to expose a sexy breath. And preview 2011 chun xia’s footwear fashion, like put on these shoes made a journey, can feel from the foot sudden power.

    Whatever rippers models of vamp, chalaza Oxford shoes or clasp shallow mouth area shoes, without exclusion, the sole below additional a layer associated with chromatic stripe bubble associated with hot thick soles, orange, Women Prada Sunglasses, dazzling huang home uniform blue… A high purity colourful colour NHL Hockey Jerseys strike the line of view of people. Waterproof sets foot have eight centimeters, whether in the color or style innovation are educated me.

    In colour super stripe froth sole and various vamp have a circle between braided hemp qualitative material transition, look from flank, such Oakleys Sunglass seems all over, but it’s also require a MiucciaPrada today period to express is the theme of the baroque style – hot, weird and striking, disjointed and conflict.

  55. We are a group of volunteers and opening a new scheme in our community.
    Your web site provided us with valuable info to work on. You’ve done an impressive job and our entire community will be thankful to you.

  56. It’s hard to find your website in google. I found it on 13
    spot, you should build quality backlinks , it will help you to increase
    traffic. I know how to help you, just search in google – k2 seo tricks

  57. Excellent items from you, man. I have be aware your stuff previous to and you
    are simply too excellent. I actually like what you’ve obtained right here, really like
    what you are saying and the best way in which you assert it.
    You make it enjoyable and you continue to care for to keep it wise.
    I can not wait to read far more from you. This is actually a terrific website.

    My website http://csiaspb.org

  58. These kinds of electrical contractor provide can vary by tax year are required to Umbrella
    Company, Roofing Contractors Denton TX area? A professional bathroom
    remodeling is carved to have all appropriate permits for the ‘client, ‘ and each one to manage.
    Upon removal of existing houses.

  59. Hello I am so happy I found youir weblog, I really found youu by accident,
    while I was browsing oon Goole for something
    else, Anyhow I aam here now and would just like too say cheers
    for a fantastic post and a all round exciting blog (I also love the theme/design), I don’t have time tto look over it all at tthe moment but I have saved it and also included your RSS
    feeds, so when I haqve time I will be back to read a lot more, Please do keep up the awesome job.

  60. I see a lot of interesting articles on your page.
    You have to spend a lot of time writing, i know how to save
    you a lot of time, there is a tool that creates unique, SEO friendly articles in couple of
    minutes, just type in google – k2 unlimited content

  61. You can base your provide selection, step back and fix the
    problem, saving money are usually so busy they can answer all your equipments and
    labor issues helps people work for ADCS Inc. If the damage caused to the environment
    and for which the finishing procedure.

  62. Pingback: Rendering JQPlot as images server side for email without node.js - ZeScience Portal

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s