Categories: Tutorials

Creating Charts Using FusionCharts Suite XT with the MEAN Stack

FusionCharts Suite XT comes with a plethora of charts, gauges, and maps that can be used to plot both static and real-time data. Not only that but the suite can be extended to work with various JavaScript libraries to create web and mobile applications. In this article, we’ll discuss how FusionCharts can be used in conjunction with the MEAN stack—a collection of JavaScript-based technologies—to render various charts from the FusionCharts library. Let’s look at how you can create Data Charts without using chart data directly instead of using data from a database.

Creating Charts Using FusionCharts Suite XT with the MEAN Stack

The MEAN Stack

MEAN is an acronym for MongoDB, ExpressJS, AngularJS, and Node.js. The MEAN stack, like said earlier, is a full-stack of JavaScript-based technologies that are used to develop web applications. Also, it is a complete development toolkit that can be used for the client-side as well as the server-side execution environments. Now we will consider how you can start with installing and setting up the MEAN stack and using it with FusionCharts to create charts.

Installing the MEAN Stack and Setting Up Your Project

In order to build an application, the four components of the MEAN stack have to be first installed individually.

Installing Node.js

Download the relevant Node.js installer for your operating system from here and follow the instructions to install it on your system. For Windows, the installer will update the path variable to include the location for the node executable. To verify installation, open a terminal and execute the command shown below:
$ node -v
Executing this command will tell you the node.js version installed. Next, run the node command, after which the prompt will change. When the prompt changes, execute the following command on the command line:
(function() {
    console.log('Node is working');
})()
If the output after executing this command is ‘Node is working’, your installation has been successful.

Installing MongoDB

MongoDB is an open-source document-based database that provides high performance, high availability, and can be scaled automatically. MongoDB distributions can be downloaded from here and installed in your system.

Installing Express.js

Express.js is a web application framework for Node.js that comes with a robust set of features for developing mobile and web applications. After you’ve installed Node.js, create a working directory to save your application. The steps are outlined below:
  1. Create a new directory, named fusioncharts-demo.
     $ mkdir fusioncharts-demo
  2. Change the working directory to fusioncharts-demo.
     $ cd fusioncharts-demo
  3. Create the package.json file for your application.
     $ npm init
  4. Install Express.js for your application. Install it in the fusioncharts-demo directory and save it in the dependencies list.
     $ npm install express --save

Installing AngularJS

You can install AngularJS via Bower (a package management software). If you don’t have Bower installed in your system, execute the following command to install it:
 $ npm install --g bower
Now, to install AngularJS via Bower, execute the following command:
 $ bower install angular

How to Install FusionCharts

To integrate FusionCharts for your project, after the MEAN stack has been installed, you need to install the FusionCharts Suite XT and the Angular-FusionCharts plugin. We’ll be installing these using the Bower package management software.

Installing the FusionCharts Package

To install the FusionCharts package using Bower, execute the following command:
 $ bower install fusioncharts
Click here to read more on installation via Bower.

Installing the Angular-FusionCharts Plugin

To install the Angular-FusionCharts plugin using Bower, execute the following command:
 $ bower install fusioncharts-angular
Click here to read more about the Angular-FusionCharts plugin. Also, click here to read more on installation via Bower.

Creating a Simple Chart Using FusionCharts with the MEAN Stack

Now that the MEAN stack and FusionCharts package have been installed, it’s time we tried out rendering a simple chart using the combination. Rendering a chart using FusionCharts and the MEAN stack is a 4 step process, as outlined below:

Step 1

Create a JS file, server.js, and save it in the fusioncharts-demo directory. Then copy the code given below and paste it into the server.js file:
var express,
    app;

express = require('express');
app = express();

app.listen(3000, function() {
    console.log('Server up: localhost:3000');
});

app.use(express.static(__dirname + '/public'));
app.use('/bower_components', express.static(__dirname + '/bower_components'));
app.use('/webapp', express.static(__dirname + '/webapp'));

app.get('/', function(req, res) {
    res.render('index');
});
The server file is ready.

Step 2

Create a folder, public, under the fusioncharts-demo directory. Also, create an HTML file, index.html, and save it in the fusioncharts-demo/public directory. Add the code given below in the index.html file:
<!DOCTYPE html>
<html>

<head>
    <title>Angular FusionCharts Demos</title>
    <!-- angularjs plugin install -->
    <script type="text/javascript" src="bower_components/angular/angular.js"></script>
    <!-- fusioncharts js lib install -->
    <script type="text/javascript" src="bower_components/fusioncharts/fusioncharts.js"></script>
    <script type="text/javascript" src="bower_components/fusioncharts/themes/fusioncharts.theme.zune.js"></script>
    <!-- fusioncharts-angular plugin install -->
    <script type="text/javascript" src="bower_components/fusioncharts-angular/angular-fusioncharts.js"></script>
    <!-- a js file for angular operation -->
    <script type="text/javascript" src="webapp/app.js"></script>
</head>

<body>
    <!-- Define AngularJS Application using ng-app directive -->
    <div ng-app="myapp" ng-controller="myctrl">
        <!-- In your HTML, find the section where you want to add the chart -->
        <fusioncharts width="450" 
             height="230" 
                      type="bar2d" 
                      dataformat="json" 
                      datasource={ {data}}>
        </fusioncharts>
    </div>
</body>

</html>

Step 3

Define the myctrl controller created in Step 2 using the ng-controller directive. Create a folder, webapp, under the fusioncharts-demo directory. Create a JS file, app.js, and save it in the fusioncharts-demo/webapp directory. Copy the code given below and paste it into the app.js file:
var app = angular.module("myapp", ['ng-fusioncharts']);

app.controller('myctrl', function($scope) {
    $scope.data = {
        chart: {
            caption: "Harry's SuperMart",
            subCaption: "Top 5 stores in last month by revenue",
            numberPrefix: "$",
            theme: "zune"
        },
        data: [{
                label: "Bakersfield Central",
                value: "880000"
            },
            {
                label: "Garden Groove harbour",
                value: "730000"
            },
            {
                label: "Los Angeles Topanga",
                value: "590000"
            },
            {
                label: "Compton-Rancho Dom",
                value: "520000"
            },
            {
                label: "Daly City Serramonte",
                value: "330000"
            }
        ]
    };
});

Before we execute the final steps, let’s take a quick look at the directory structure created:

Step 4

Run the server.js file from the terminal, as shown below:
 $ node server.js
This will start the server.

Step 5

To test the app created, open your browser, and type https://localhost:3000 in the address bar. Your chart should now render, as shown in the image below:

Creating Charts Using FusionCharts and MEAN Stack Using a Database

We will now see how we can create charts using Express.js and MongoDB. The steps for creating charts using FusionCharts and the MEAN stack and by fetching data from a database are outlined below:
  1. Install the Mongoose client and establish the connection to the MongoDB database
  2. Create a data model
  3. Populate data in the MongoDB database
  4. Create REST API for data retrieval
  5. Next, create a method to fetch data using the Angular Controller
  6. Create a view for rendering the chart
As an example, we’ll be writing the code to render a chart that shows the 10 most populous countries of the world. The chart can be drilled down further to show the 10 most populous cities in each country. We will now cover each of the steps listed above in detail, with respect to the example.

Step 1: Installing the Mongoose Client and Establishing a Connection to the MongoDB Database

Step 1.1

Install the Mongoose client. Mongoose translates the data in your database to JavaScript objects that can be used in your application. Everything in Mongoose starts with a schema. Each schema maps to a MongoDB collection and defines the shape of the documents within that collection. To install Mongoose, execute the following command at the terminal:
 $ npm install mongoose --save

Step 1.2

Create a JS file, dbconnection.js, and save it under the fusioncharts-demo directory. The code given below will establish connectivity with the MongoDB database. Copy the code below and paste it into the dbconnection.js file.
var mongoose;

mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/fusioncharts_demo');
mongoose.Promise = global.Promise;

mongoose.connection.on("error", function() {
    console.log("[dbconnection.js] Mongodb : ERROR.");
});
mongoose.connection.once("open", function() {
    console.log("[dbconnection.js]Mongodb : Connected.");
});

module.exports = mongoose;

Step 2: Creating a Data Model

Models are advanced constructors compiled from schema definitions. Instances of these models are documents that can be saved in and retrieved from the database.

Step 2.1

Create a folder, models, under the fusioncharts-demo directory. Then, create a JS file, world.js, and save it in the fusioncharts-demo/models directory. Add the code given below to the world.js file:
var db,
    world,
    city;

db = require('../dbconnection');

city = {
    Name: String,
    Population: Number
};

world = db.model("worlds", {
    Name: String,
    Population: Number,
    cities: [city]
});

module.exports = world;

Step 2.2

Create a JSON file, data.json, and save it under the fusioncharts-demo directory. The data to be populated in the database is passed as an array of JSON objects, as shown in the code below. Add this code to the data.json file:
[{
    "Name": "China",
    "Population": 1277558000,
    "cities": [{
            "Name": "Shanghai",
            "Population": "9696300"
        },
        {
            "Name": "Peking",
            "Population": "7472000"
        },
        {
            "Name": "Chongqing",
            "Population": "6351600"
        },
        {
            "Name": "Tianjin",
            "Population": "5286800"
        },
        {
            "Name": "Wuhan",
            "Population": "4344600"
        },
        {
            "Name": "Harbin",
            "Population": "4289800"
        },
        {
            "Name": "Shenyang",
            "Population": "4265200"
        },
        {
            "Name": "Kanton [Guangzhou]",
            "Population": "4256300"
        },
        {
            "Name": "Chengdu",
            "Population": "3361500"
        },
        {
            "Name": "Nanking [Nanjing]",
            "Population": "2870300"
        }
    ]
}, {
    "Name": "India",
    "Population": 1013662000,
    "cities": [{
            "Name": "Mumbai (Bombay)",
            "Population": "10500000"
        },
        {
            "Name": "Delhi",
            "Population": "7206704"
        },
        {
            "Name": "Calcutta [Kolkata]",
            "Population": "4399819"
        },
        {
            "Name": "Chennai (Madras)",
            "Population": "3841396"
        },
        {
            "Name": "Hyderabad",
            "Population": "2964638"
        },
        {
            "Name": "Ahmedabad",
            "Population": "2876710"
        },
        {
            "Name": "Bangalore",
            "Population": "2660088"
        },
        {
            "Name": "Kanpur",
            "Population": "1874409"
        },
        {
            "Name": "Nagpur",
            "Population": "1624752"
        },
        {
            "Name": "Lucknow",
            "Population": "1619115"
        }
    ]
}, {
    "Name": "United States",
    "Population": 278357000,
    "cities": [{
            "Name": "New York",
            "Population": "8008278"
        },
        {
            "Name": "Los Angeles",
            "Population": "3694820"
        },
        {
            "Name": "Chicago",
            "Population": "2896016"
        },
        {
            "Name": "Houston",
            "Population": "1953631"
        },
        {
            "Name": "Philadelphia",
            "Population": "1517550"
        },
        {
            "Name": "Phoenix",
            "Population": "1321045"
        },
        {
            "Name": "San Diego",
            "Population": "1223400"
        },
        {
            "Name": "Dallas",
            "Population": "1188580"
        },
        {
            "Name": "San Antonio",
            "Population": "1144646"
        },
        {
            "Name": "Detroit",
            "Population": "951270"
        }
    ]
}, {
    "Name": "Indonesia",
    "Population": 212107000,
    "cities": [{
            "Name": "Jakarta",
            "Population": "9604900"
        },
        {
            "Name": "Surabaya",
            "Population": "2663820"
        },
        {
            "Name": "Bandung",
            "Population": "2429000"
        },
        {
            "Name": "Medan",
            "Population": "1843919"
        },
        {
            "Name": "Palembang",
            "Population": "1222764"
        },
        {
            "Name": "Tangerang",
            "Population": "1198300"
        },
        {
            "Name": "Semarang",
            "Population": "1104405"
        },
        {
            "Name": "Ujung Pandang",
            "Population": "1060257"
        },
        {
            "Name": "Malang",
            "Population": "716862"
        },
        {
            "Name": "Bandar Lampung",
            "Population": "680332"
        }
    ]
}, {
    "Name": "Brazil",
    "Population": 170115000,
    "cities": [{
            "Name": "Sao Paulo",
            "Population": "9968485"
        },
        {
            "Name": "Rio de Janeiro",
            "Population": "5598953"
        },
        {
            "Name": "Salvador",
            "Population": "2302832"
        },
        {
            "Name": "Belo Horizonte",
            "Population": "2139125"
        },
        {
            "Name": "Fortaleza",
            "Population": "2097757"
        },
        {
            "Name": "Brasilia",
            "Population": "1969868"
        },
        {
            "Name": "Curitiba",
            "Population": "1584232"
        },
        {
            "Name": "Recife",
            "Population": "1378087"
        },
        {
            "Name": "Porto Alegre",
            "Population": "1314032"
        },
        {
            "Name": "Manaus",
            "Population": "1255049"
        }
    ]
}, {
    "Name": "Pakistan",
    "Population": 156483000,
    "cities": [{
            "Name": "Karachi",
            "Population": "9269265"
        },
        {
            "Name": "Lahore",
            "Population": "5063499"
        },
        {
            "Name": "Faisalabad",
            "Population": "1977246"
        },
        {
            "Name": "Rawalpindi",
            "Population": "1406214"
        },
        {
            "Name": "Multan",
            "Population": "1182441"
        },
        {
            "Name": "Hyderabad",
            "Population": "1151274"
        },
        {
            "Name": "Gujranwala",
            "Population": "1124749"
        },
        {
            "Name": "Peshawar",
            "Population": "988005"
        },
        {
            "Name": "Quetta",
            "Population": "560307"
        },
        {
            "Name": "Islamabad",
            "Population": "524500"
        }
    ]
}, {
    "Name": "Russian Federation",
    "Population": 146934000,
    "cities": [{
            "Name": "Moscow",
            "Population": "8389200"
        },
        {
            "Name": "St Petersburg",
            "Population": "4694000"
        },
        {
            "Name": "Novosibirsk",
            "Population": "1398800"
        },
        {
            "Name": "Nizni Novgorod",
            "Population": "1357000"
        },
        {
            "Name": "Jekaterinburg",
            "Population": "1266300"
        },
        {
            "Name": "Samara",
            "Population": "1156100"
        },
        {
            "Name": "Omsk",
            "Population": "1148900"
        },
        {
            "Name": "Kazan",
            "Population": "1101000"
        },
        {
            "Name": "Ufa",
            "Population": "1091200"
        },
        {
            "Name": "Tseljabinsk",
            "Population": "1083200"
        }
    ]
}, {
    "Name": "Bangladesh",
    "Population": 129155000,
    "cities": [{
            "Name": "Dhaka",
            "Population": "3612850"
        },
        {
            "Name": "Chittagong",
            "Population": "1392860"
        },
        {
            "Name": "Khulna",
            "Population": "663340"
        },
        {
            "Name": "Rajshahi",
            "Population": "294056"
        },
        {
            "Name": "Narayanganj",
            "Population": "202134"
        },
        {
            "Name": "Rangpur",
            "Population": "191398"
        },
        {
            "Name": "Mymensingh",
            "Population": "188713"
        },
        {
            "Name": "Barisal",
            "Population": "170232"
        },
        {
            "Name": "Tungi",
            "Population": "168702"
        },
        {
            "Name": "Jessore",
            "Population": "139710"
        }
    ]
}, {
    "Name": "Japan",
    "Population": 126714000,
    "cities": [{
            "Name": "Tokyo",
            "Population": "7980230"
        },
        {
            "Name": "Jokohama [Yokohama]",
            "Population": "3339594"
        },
        {
            "Name": "Osaka",
            "Population": "2595674"
        },
        {
            "Name": "Nagoya",
            "Population": "2154376"
        },
        {
            "Name": "Sapporo",
            "Population": "1790886"
        },
        {
            "Name": "Kioto",
            "Population": "1461974"
        },
        {
            "Name": "Kobe",
            "Population": "1425139"
        },
        {
            "Name": "Fukuoka",
            "Population": "1308379"
        },
        {
            "Name": "Kawasaki",
            "Population": "1217359"
        },
        {
            "Name": "Hiroshima",
            "Population": "1119117"
        }
    ]
}, {
    "Name": "Nigeria",
    "Population": 111506000,
    "cities": [{
            "Name": "Lagos",
            "Population": "1518000"
        },
        {
            "Name": "Ibadan",
            "Population": "1432000"
        },
        {
            "Name": "Ogbomosho",
            "Population": "730000"
        },
        {
            "Name": "Kano",
            "Population": "674100"
        },
        {
            "Name": "Oshogbo",
            "Population": "476800"
        },
        {
            "Name": "Ilorin",
            "Population": "475800"
        },
        {
            "Name": "Abeokuta",
            "Population": "427400"
        },
        {
            "Name": "Port Harcourt",
            "Population": "410000"
        },
        {
            "Name": "Zaria",
            "Population": "379200"
        },
        {
            "Name": "Ilesha",
            "Population": "378400"
        }
    ]
}]
Our data model is now ready.

Step 3: Populating Data in the MongoDB Database

We’ll use the mongoimport command, as shown below, to create a MongoDB database and populate in it the data contained within the data.json.
$ mongoimport -d fusioncharts_demo -c worlds --type json --file data.json --jsonArray
This command takes the following information:
  1. Name of the database ( -d fusioncharts_demo )
  2. Name of the collection ( -c worlds )
  3. Type of the input data ( –type json )
  4. Location of the file containing data ( –file data.json )
  5. Option to indicate that the input is a JSON array ( –jsonArray)

Step 4: Creating the REST API for Data Retrieval

Let us expose the REST API at the URL /worlddata. This will fetch the data from the database and send a response object to the client, invoking the API. Add the code given below to the server.js file (fusioncharts-demo/server.js):
var express,
    app,
    world;

express = require('express');
app = express();
world = require('./models/world');

app.listen(3000, function() {
    console.log('[server.js] Server up: localhost:3000');
});

app.use(express.static(__dirname + '/public'));
app.use('/bower_components', express.static(__dirname + '/bower_components'));
app.use('/webapp', express.static(__dirname + '/webapp'));


app.get('/', function(req, res) {
    res.render('index');
});

app.get('/worlddata', function(req, res) {
    var promise;

    promise = world.find();
    promise.then(function(result) {
            console.log("[server.js] world : Retrieved Successfully!");
            res.status(200).json(result).end();
        })
        .catch(function(err) {
            console.log("[server.js] world : " + err);
        });
});

Step 5: Creating a Method to Fetch the Data from the Database Using the Angular Controller

Using the REST API (i.e. /worlddata), we’ve got the raw data. Next, we need to create the fusioncharts data source inside the angular controller myctrl. Add the code given below to the app.js file (fusioncharts-demo/webapp/app.js):
// In the app, include the ng-fusioncharts directive as a dependency
var app = angular.module("myapp", ['ng-fusioncharts']);

app.controller('myctrl', function($scope, $http) {
    var getdata;

    getData = function(url, callback) {
        $http({
            method: 'GET',
            dataType: 'json',
            url: url,
            headers: {
                "Content-Type": "application/json"
            }
        }).success(callback);
    };

    getData('/worlddata', function(response) {
        console.log(response);
        var datasource,
            doc,
            data = [],
            linkeddata = [],
            chart;

        chart = {
            caption: "Top 10 Most Populous Countries",
            showValues: 0,
            theme: "zune"
        };

        for (var _i = 0; _i & lt; response.length; _i++) {
            doc = response[_i];
            data.push({
                label: doc.Name,
                value: doc.Population,
                link: 'newchart-json-' + _i.toString()
            });

            linkeddata.push({
                id: _i.toString(),
                linkedchart: {
                    chart: {
                        caption: 'Top 10 Most Populous Cities - '; + doc.Name,
                        showValues: 0,
                        theme: 'zune';
                    },
                    data: doc.cities.map(function(ele) {
                        return {
                            label: ele.Name,
                            value: ele.Population
                        };
                    })
                }
            });
        }

        datasource = {
            chart: chart,
            data: data,
            linkeddata: linkeddata
        };

        $scope.data = datasource;
    });
});

Step 6: Rendering the Chart

Before we look at the template (/fusioncharts-demo/public/index.html), let us look at the directory structure we have created so far:

Step 6.1

Now that the backend is ready, we need to create views for rendering the chart. Add the code given below to the index.html file (fusioncharts-demo/public):
<!DOCTYPE html>
<html>

<head>
    <title>Angular FusionCharts Demos</title>
    <!-- angularjs plugin install -->
    <script type="text/javascript" src="bower_components/angular/angular.js"></script>
    <!-- fusioncharts js lib install -->
    <script type="text/javascript" src="bower_components/fusioncharts/fusioncharts.js"></script>
    <script type="text/javascript" src="bower_components/fusioncharts/themes/fusioncharts.theme.zune.js"></script>
    <!-- fusioncharts-angular plugin install -->
    <script type="text/javascript" src="bower_components/fusioncharts-angular/angular-fusioncharts.js"></script>
    <!-- a js file for angular operation -->
    <script type="text/javascript" src="webapp/app.js"></script>
</head>

<body>
    <!-- Define AngularJS Application using ng-app directive -->
    <div ng-app="myapp" ng-controller="myctrl">
        <!-- In your HTML, find the section where you want to add the chart -->
        <fusioncharts width="450" 
                      height="230" 
                      type="bar2d" 
                      id="chart-1" 
                      dataformat="json" 
                      datasource={ {data}}>
        </fusioncharts>
    </div>
</body>

</html>

Step 6.2

Run the server.js file from the terminal, as shown below:
 $ node server.js
This will start the server.

Step 6.3

To test the app created, open your browser, and type https://localhost:3000 in the address bar. Your chart should now render, as shown in the image below:
Nikita Jhanglani and Suvradip Saha

View Comments

  • The code for app.js contains several bugs in getData() function according to me. the chart will not render due to these bugs and after some minor changes it worked well. Other thing occurred to me is that in $http(...).success(callback), the success() method is no longer included after angularjs 1.4.3 and it is replaced with then().

    • Hi Anjana Senanayake -

      Can you please add what changes you had to make? I ran in to the same problem but not sure WHAT to change?

      Thanks!

Recent Posts

Pie Charts: A Slice of Data You Can’t Ignore

Ever had a data set that seemed more complicated than a Rubik's cube? You’re not…

3 weeks ago

Venn Diagrams: A Simple Yet Powerful Tool for Visualizing Relationships

We’ve all seen them in textbooks or presentations—those overlapping circles that simplify complex information into…

1 month ago

Announcing FusionCharts v4.1: Elevate Your Data Visualization Experience!

We’re excited to announce the upcoming release of FusionCharts v4.1—a groundbreaking step forward in the…

1 month ago

Bubble Maps: Visualizing Data Like Never Before

Have you ever been overwhelmed by a massive data set and wondered, "How do I…

1 month ago

Stock Charts: Mastering the Art of Visualizing Financial Data

If you’ve ever tried to make sense of the stock market, you’ve probably come across…

2 months ago

What is a Bar Chart Used For?

Imagine you’re comparing the sales performance of your top product lines across different regions, or…

3 months ago