title: Server-Side HighStock charts generation with NodeJS
body: <p>I'm using <a href="http://www.highcharts.com/products/highstock">HighStock</a> to generate some charts in browser. But now I want to store some of them at the server. So I know that HighCharts can be exported to the server but I'd rather use some other way if possible. The thing is to run HighStock at the server and convert the svg to some image format and then store it there.</p>
  
  <p>Quick googling gives me <a href="http://blog.davidpadbury.com/2010/10/03/using-nodejs-to-render-js-charts-on-server/">this page</a>. Combining HighCharts and NodeJS seems to be the right way but this solution does not work for newer versions of HighCharts. More precisely, using <a href="https://github.com/tmpvar/jsdom">jsdom</a> module (v0.2.10 - the latest) in NodeJS with HighStock v1.0.2 (look at the following code):</p>
  
  <pre><code>var jsdom = require('jsdom');
  var fs = require('fs');
  var jQuery = fs.readFileSync('./js/jquery-1.7.min.js').toString();
  var Highstock = fs.readFileSync('./js/highstock.js').toString();
  jsdom.env({
      html: '&lt;div id="container"&gt;&lt;/div&gt;',
      src: [ jQuery, Highstock ],
      done: function(errors, window) {
          if (errors) return console.log(errors);
          var Highcharts = window.Highcharts;
          var chart = new Highcharts.Chart(options);
      }
  });
  </code></pre>
  
  <p>throws an exception:</p>
  
  <pre><code>Error: Invalid character: Invalid character in tag name: &lt;
  </code></pre>
  
  <p>Somehow these two libraries does not seem to work together. So this may work with older versions of HighStock but actually I need HighStock v1.0.2.</p>
  
  <p>Is there any solution for this problem? Some better library that <code>jsdom</code>? Or some strange yet working tricks? Any idea appreciated. :)</p>
  
  <p><strong>// EDIT</strong> </p>
  
  <p>Thanks to ReCoder I've managed to get it working. Main thing was to add <code>forExport</code> flag to the options (preventing exceptions). Unfortunetly this generated the chart but did not update the holder. I've managed to get it working after adding <code>exporting</code> module (part of HighStock package). The full working code looks like this:</p>
  
  <pre><code>var jsdom = require('jsdom');
  var fs = require('fs');
  var jQuery = fs.readFileSync('./js/jquery-1.7.min.js').toString();
  var Highstock = fs.readFileSync('./js/highstock.src.js').toString();
  var Exporting = fs.readFileSync('./js/exporting.src.js').toString();
  
  jsdom.env({
      html: '&lt;div id="container"&gt;&lt;/div&gt;',
      src: [ jQuery, Highstock, Exporting ],
      done: function(errors, window) {
          if (errors) return console.log(errors);
          var Highcharts = window.Highcharts;
          var chart = new Highcharts.Chart({
                chart: {
                   renderTo: 'container',
                   animation: false,
                   forExport: true       
                },
                exporting: { enabled: false },
                xAxis: {
                   categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
                      'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
                },
                series: [{
                   animation: false,
                   name: 'Tokyo',
                   data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
                }, {
                   animation: false,      
                   name: 'New York',
                   data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
                }, {
                   animation: false,      
                   name: 'Berlin',
                   data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0]
                }, {
                   animation: false,      
                   name: 'London',
                   data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8]
                }]
          });
  
          var svg = chart.getSVG();
  
          fs.writeFile("./test.svg", svg, function(err) {
              if(err) {
                  console.log(err);
              } else {
                  console.log("The file was saved!");
              }            
          }); 
      }
  });
  </code></pre>
  
  <p>The chart is not as good as it should be (for example labels badly placed), but maybe it's a matter of tuning options. At least it works!</p>