Node.js + HighCharts

2214 VIEWS

·

Generating charts on the server side is a very useful technique. It is often preferred to generating on the front-end because it takes off processing load, thus creating shorter loading times and fewer lags. It is also useful for “background” tasks such as sending weekly e-mail reports and so on (which cannot be done on the front-end).

In this tutorial, you will learn to use Node.js with the Highcharts library to generate charts on the fly. With this, you can easily automate the generation of reports and data visuals that can be sent via e-mail, or whichever communication means you prefer.

Note: This tutorial assumes you have prior experience with Node.js.

Setup

– Install the highcharts package:

npm install highcharts-export-server

Creating a sample chart

To generate a chart with the highcharts package, you:

  1. Initialize the highcharts exporter.
  2. Create an object that describes the look of your chart and what data should be in it (refer to the Highcharts demo site for more samples).
  3. Run the export function, passing the object you created above.
const fs = require("fs");
const chartExporter = require("highcharts-export-server");
// Initialize the exporter
chartExporter.initPool();
// Chart details object specifies chart type and data to plot
const chartDetails = {
   type: "png",
   options: {
       chart: {
           type: "pie"
       },
       title: {
           text: "Heading of Chart"
       },
       plotOptions: {
           pie: {
               dataLabels: {
                   enabled: true,
                   format: "{point.name}: {point.y}"
               }
           }
       },
       series: [
           {
               data: [
                   {
                       name: "a",
                       y: 100
                   },
                   {
                       name: "b",
                       y: 20
                   },
                   {
                       name: "c",
                       y: 50
                   }
               ]
           }
       ]
   }
};

chartExporter.export(chartDetails, (err, res) => {
   // Get the image data (base64)
   let imageb64 = res.data;

   // Filename of the output
   let outputFile = "bar.png";

   // Save the image to file
   fs.writeFileSync(outputFile, imageb64, "base64", function(err) {
       if (err) console.log(err);
   });

   console.log("Saved image!");
   chartExporter.killPool();
});

Sample code for generating a pie chart

Run the code above and you should see bar.png in your working directory:

Scenario: Generating graphs for a restaurant

Now, we will be creating charts from a dataset of transactions for a fictional restaurant. Each transaction data point contains the name of the item bought, its price, and the time of the transaction.

You can download the dataset (JSON) here.

Preview of transaction dataset

Our Goal: To generate a pie chart that shows us which products are bought most frequently.

Step 0: Preparing the data

We want to create a summary table of items bought, with their frequency and revenue (price).
The code below does that with Javascript’s array ‘reduce’ function (read more on that here).

// import the dataset 
const purchase_data = require("./purchase_data.json");

// create summary table with reduce function
let prepped_data = purchase_data.reduce(function(all_transactions, transaction) {
   item = transaction["Item"];
   price = parseFloat(transaction["Amount"]);
   if (item in all_transactions) {
       all_transactions[item] = {
           freq:(all_transactions[item]["freq"] += 1),
           amnt:(parseFloat(all_transactions[item]["amnt"]) + price).toFixed(2)
       };
   } else {
       all_transactions[item] = {
           freq: 1,
           amnt: price
       };
   }
   return all_transactions;
}, {});

console.log(prepped_data);

Data-Prepping Function

On running this code, you should see this output:

Now we have a summary table that contains basic info for each product type: total revenue and frequency, so we can move ahead to plotting a graph.

Step 1: Creating charts for our data

You likely noticed that the data points (in the data attribute of the chart details) for the sample chart from earlier were in the form (name, y). So, we need to transform our summary table into the right format for the chart exporter:

let pie_data = [];
for (item in prepped_data) {
   let name = item;
   let freq = prepped_data[item]["freq"];
   pie_data.push({ name: name, y: freq });
}

We obtain a list of objects containing product names and their frequencies

Now that we have the plot data in the right format, we can create the chart details:

const chartDetails = {
   type: "png",
   options: {
       chart: {
           type: "pie"
       },
       title: {
           text: "Pie Chart showing frequency of items purchased"
       },
       plotOptions: {
           pie: {
               dataLabels: {
                   enabled: true,
                   format: "{point.name}: {point.y}"
               }
           }
       },
       series: [
           {
               Data: pie_data
           }
       ]
   }
};

Plug this into the sample code from Step 1 and run:

chartExporter.export(chartDetails, (err, res) => {
   // Get the image data (base64)
   let imageb64 = res.data;

   // Filename of the output
   let outputFile = "bar.png";

   // Save the image to file
   fs.writeFileSync(outputFile, imageb64, "base64", function(err) {
       if (err) console.log(err);
   });

   console.log("Saved image!");
   chartExporter.killPool();
});

Run the code and you will see a new PNG that looks like this:

There you go! You’ve created a chart on the server-side with Node.js. Your options are many. For example, instead of writing the chart image to a file, you could make your script send it via e-mail on a weekly basis.

Resources

  1. The Highcharts demo site has dozens of chart samples to choose from.
  2. Restaurant dataset: https://gist.github.com/kevindeyoungster/303b8557cd2824e8aa2fd7fa714e10b9

Kevin de Youngster is a CS major at Ashesi University with 2 years experience in coding. He has experience with python, web development (CSS, HTML, JS) and NodeJS. Having a keen interest in how software is used to enhance other industries, he has interned with a number of companies and is currently working at Chalkboard Education. When he isn't immersed in building projects, he spends his time watching nature videos and making illustrations.


Discussion

Click on a tab to select how you'd like to leave your comment

Leave a Comment

Your email address will not be published. Required fields are marked *

Menu