Building a Chart Component with Angular 2 and FusionCharts

Share this article

This article was peer reviewed by Vildan Softic. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

As a web developer, if there is something that you can’t miss, it is Angular 2. It is a complete rewrite of the popular JavaScript framework from Google and is constantly in news for all the right reasons. It offers some major improvements over the previous versions and that’s why we’re choosing it today to build some beautiful charts.

For the charts, we will use the JavaScript chart library provided by FusionCharts. It offers a good collection of charts and is compatible with all major browsers. Although FusionCharts offers a dedicated plugin for Angular, it is not yet compatible with Angular 2. So I am not going to use it and instead code directly using JavaScript and Angular 2. (Note: it is recommended you use the plugin if you are using Angular 1 in your app).

The chart we are going to plot will depict an interesting statistic—the revenue of five top tech companies (Amazon, Apple, Facebook, Google and Microsoft) and will have an option to switch between revenue data for 2014 and 2015. We will first go through the step-by-step process of creating charts in Angular 2. After building a basic chart, we will cover some advanced topics such as adding annotations and updating chart data.

As ever, you can download the code for this tutorial from our GitHub repo, or you can jump to a demo of the finished chart at the end of the article.

Angular 2 vs Angular 1.x

Angular 2 has some significant changes over its previous major version (Angular 1.x), for example its support for languages such as TypeScript and Dart, and the way it computes updates to the DOM. If you’d like to learn more about how Angular 1 concepts and techniques map to Angular 2, you can check out the official quick reference. If you are interested in migrating your app from Angular 1.x to Angular 2, you can read the official migration guide.

Although Angular 2 supports TypeScript and Dart, we will use native JavaScript to write the Angular 2 application in this tutorial because of its familiarity. Using TypeScript or Dart would also introduce an unnecessary build step.

Setup

There are number of ways to get up and running with an Angular 2 project. The easiest is probably to head over to the official site and follow their 5 Min Quickstart tutorial.

One slight caveat to this approach however, is that it relies on you having Node and npm installed on your machine. We do have a guide for this, but if you’d prefer to follow this tutorial without installing these, you can use the following template:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Angular 2 FusionCharts Demo</title>

    <!-- 1. Load custom CSS & fonts-->
    <link rel="stylesheet" href="styles.css">
    <link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:300' rel='stylesheet'>

    <!-- 2. Load Angular 2 specific libraries -->
    <script src="https://code.angularjs.org/2.0.0-beta.17/angular2-polyfills.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.17/Rx.umd.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.17/angular2-all.umd.dev.js"></script>

    <!-- 3. Load FusionCharts library-->
    <script src="https://static.fusioncharts.com/code/latest/fusioncharts.js"></script>

    <!-- 4. Load component -->
    <script src='main.js'></script>
  </head>
  <body>

    <!-- 5. Display the application -->
    <angular-chart>Loading...</angular-chart>
  </body>
</html>

Creating the Chart Component

Components are the building blocks of any Angular 2 application. They are reusable pieces of code consisting of a view, and some logic. If you’re familiar with Angular 1, you can think of them as directives with a template and a controller.

Here’s the basis of our chart component:

(function(chartApp){
  chartApp.AppComponent = ng.core.Component({
    selector: 'angular-chart',
    template: '<div>Chart will render here</div>'
  }).Class({
    constructor: function(){}
  });

  document.addEventListener('DOMContentLoaded', function() {
    ng.platform.browser.bootstrap(chartApp.AppComponent);
  });
})(window.chartApp || (window.chartApp = {}));

Let’s take a second to see what’s going on.

We start with an IIFE (immediately invoked function expression) which we use to namespace our app. We pass it window.chartApp as an argument, which is initialized to an empty object if it isn’t defined. This is where our application is going to live—in a single property on the global object.

Inside the IIFE we create our component (AppComponent) by chaining the Component and Class methods from ng.core (a collection of Angular’s core components). We’re passing the Component method a configuration object containing the following propeties:

  • selector: a simple CSS selector which specifies a host HTML element. Angular will create and display an instance of the component whenever it encounters a HTML element matching this selector.

  • template: the template to be used when the component is rendered. Currently we’re passing a string containing a placeholder <div> element, but ideally we should move this out into its own template.

The Class method is where we add behavior and event bindings for the template.

Having defined our basic component, we initialize it using Angular’s browser bootstrap function.

You should be able to run the code in your browser at this point and see the message “Chart will render here”.

Creating the Chart

Let’s move on to creating the chart and displaying some data for 2014.

To do this we need to use the FusionCharts constructor function to which we pass an object containing all configuration parameters for the chart instance:

  • type: the type of chart we wish to create
  • renderAt: the DOM selector into which our chart will be rendered
  • width and height: the chart dimensions
  • id: the ID of the generated chart
  • dataFormat: the format of data passed to the dataSource option
  • dataSource: the configuration for the actual chart, as well as the data it should display
new FusionCharts({
  "type": "column2d",
  "renderAt": "chart-container",
  "width": "550",
  "height": "400",
  "id": "revenue-chart",
  "dataFormat": "json",
  "dataSource": {
    "chart": {
      "yAxisName": "Revenue (In USD Billion)",
      "yAxisMaxValue": "200",
      ...
    },
    "data": [{
      "label": "Amazon",
      "value": "88.99"
    }, {
      "label": "Apple",
      "value": "182.8"
    }
    ...
    ]
  }
});

Here’s the complete configuration file.

If you are unsure as to what any of the chart options actually do, or if you would like to find out how else the appearance of the chart can be configured, you can refer to the Chart Attributes page in the FusionCharts documentation.

The other thing we have to do is update our template to include the container our chart should render into. You can either do this by specifying a string to the Component’s template property (as we did previously), or by moving the template into its own file and referencing it using templateUrl.

chartApp.AppComponent = ng.core.Component({
  selector: 'angular-chart',
  templateUrl: 'chart.html'
}).Class({
  ...
});

Either way, this is what our template should look like.

<div class="container">
  <h1>Revenue of Top Tech Companies (2014)</h1>
  <div id ="chart-container"></div>
</div>

Here’s a demo of what we have so far:

You can view the code for this demo on Plunker.

If you click through to the demo on Plunker, in the file main.js you might notice that we have separated the FusionCharts configuration data into its own file, which we are then fetching using Angular’s HTTP class. This is for the sake of clarity (it makes the Angular-specific code easier to follow) and also because making a request for the data is what you’d typically do in a real life scenario.

However, this is not absolutely necessary, and you’d get the same result by doing everything directly in the chartApp constructor:

(function(chartApp) {
  chartApp.AppComponent = ng.core.Component({
    selector: 'angular-chart',
    template: '<div class="container"><h1>Revenue of Top Tech Companies (2014)</h1><div id ="chart-container"></div></div>'
  }).Class({
    constructor: function() {
      FusionCharts.ready(function(){
        var revenueChart = new FusionCharts({
          // config data here
        }).render();
      });
    }
  });

  document.addEventListener('DOMContentLoaded', function() {
    ng.platform.browser.bootstrap(chartApp.AppComponent);
  });
})(window.chartApp || (window.chartApp = {}));

The only other thing to mention is that the initialization code is wrapped within the FusionCharts.ready method. This safeguards your chart instantiation code from being called before the FusionCharts library is loaded.

With the basic chart ready, it is time to add more functionality, such as using company logos instead of names and updating the chart with new data for the year 2015.

Adding Annotations

For adding company logos to the x-axis, we will use one of FusionCharts’ powerful features—annotations. Annotations on a FusionCharts object allow you to draw custom shapes or images at designated positions on the chart.

Suppose you want to add your company logo at the center of chart. You can do it using annotations and macros. Macros will give you the coordinates of the center of the chart and annotation will let you add an image at that location.

Things get interesting when you use dynamic annotations to, for example, get information on positions which are dependent on the chart’s data. Imagine you want to draw something exactly where the column ends. You can use the dynamic annotation macro $dataset.0.set.1.endX and $dataset.0.set.1.endY to determine the x and y coordinates of the column end point, then draw something over there. You can learn more about annotations and how to use them on this FusionCharts documentation page.

For our chart, we will use dynamic annotation macros to get each column’s starting and ending coordinates, which is where we will then draw the respective company logos. We will also disable default x-axis labels using the chart attribute "showLabels": "0".

To achieve the above goals, add the following code to the chart’s configuration:

{
  "type": "column2d",
  ...
  "dataSource": {
    "chart": {
      "showLabels": "0",
      ...
    },
    "data": [{ ... }],
    "annotations": {
      "groups": [{
        "id": "logo-images",
        "xScale": "30",
        "yScale": "30",
        "showBelow": "0",
        "items": [{
          "type": "image",
          "url": "https://uploads.sitepoint.com/wp-content/uploads/2016/06/1465735364amazon.jpg",
          "x": "$dataset.0.set.0.startx + 25",
          "y": "$dataset.0.set.0.endY + 10"
        }, {
          "type": "image",
          "url": "https://uploads.sitepoint.com/wp-content/uploads/2016/06/1465735362apple.jpg",
          "x": "$dataset.0.set.1.startx + 85",
          "y": "$dataset.0.set.1.endY + 10"
        }, {
          "type": "image",
          "url": "https://uploads.sitepoint.com/wp-content/uploads/2016/06/1465735369facebook.jpg",
          "x": "$dataset.0.set.2.startx + 20",
          "y": "$dataset.0.set.2.endY + 10"
        }, {
          "type": "image",
          "url": "https://uploads.sitepoint.com/wp-content/uploads/2016/06/1465735358google.jpg",
          "x": "$dataset.0.set.3.startx + 5",
          "y": "$dataset.0.set.3.endY + 5"
        }, {
          "type": "image",
          "url": "https://uploads.sitepoint.com/wp-content/uploads/2016/06/1465735372microsoft.jpg",
          "x": "$dataset.0.set.4.startx + 30",
          "y": "$dataset.0.set.4.endY + 10"
        }]
      }]
    }
  }
}

In the above code:

  • type is setting the type of annotation.
  • url is setting the address of the image.
  • x and y are setting the starting x and y-coordinates of the images.

After adding the above code you should see company logos rendered on the x-axis. To learn more about using annotations and what else is possible, please refer to the documentation page (mentioned above).

Toggling Between Datasets

The final thing we want to implement is to allow the user to toggle between years, seeing a different dataset depending on the year selected (2014 or 2015).

Structuring the data.

We therefore need to consider how to structure our data in a way that we can define different datasets for the different years. As mentioned previously, FusionCharts is expecting the configuration options to contain a data property, which should be an array containing sets of label/value pairs.

{
  "type": "column2d",
  ...
  "dataSource": {
    "chart": {},
    "data": [
      {
        "label": "whatever",
        "value": "a value"
      }
    ]
  }
}

One way of handling multiple datasets would be to define a dataSet object at the top of our constructor function and attach it to the constructor using an alias.

var chartComp= this;
chartComp.dataSet = {
  "2014": [{
    "label": "Amazon",
    "value": "88.99"
  }, {
    "label": "Apple",
    "value": "182.8"
  }, {
    "label": "Facebook",
    "value": "12.47"
  }, {
    "label": "Google",
    "value": "65.67"
  }, {
    "label": "Microsoft",
    "value": "86.83"
  }],
  "2015": [{
    "label": "Amazon",
    "value": "107.01"
  }, {
    "label": "Apple",
    "value": "233.72"
  }, {
    "label": "Facebook",
    "value": "17.93"
  }, {
    "label": "Google",
    "value": "74.54"
  }, {
    "label": "Microsoft",
    "value": "93.58"
  }]
}

Then, in the configuration options we pass to the FusionCharts constructor, we can do:

"data": chartComp.dataSet['2014'],

Updating Chart Data on Toggle

We also want the chart to be updated with the data for 2015 once somebody clicks the 2015 button and toggle back to showing the data for 2014, when the 2014 button is clicked.

Let’s add the two buttons, which will be used to perform this action and give them some styling. Amend the component template as follows:

<div class="container">
  <h1>Revenue of Top Tech-companies</h1>

  <div class="actions">
    <button (click)="yearChange(2014)"
            [ngClass] = "{selected: selectedYear== 2014}">2014
    </button>
    <button (click)="yearChange(2015)"
            [ngClass] = "{selected: selectedYear== 2015}">2015
    </button>
  </div>
  <div id ="chart-container"></div>
</div>

Notice the new syntax for adding an event listener and adding the ngClass directive in Angular 2. They are almost the same as Angular 1, barring some braces and parentheses.

I’ve added an ngClass directive to highlight the current selected year by applying a selected CSS class to button element. This is based on the selectedYear property on the component which gets updated on the click of buttons.

We can set the current selected year to 2014 when the component renders by adding the following line to the top of the constructor:

chartComp.selectedYear = 2014;

The logic to handle the button clicks will be added to a new yearChange function.

.Class({
  constructor: function(){ ... },
  yearChange: function(){ // button logic here }
);

For this we’re going to use FusionChart’s setChartData method which requires both chart configuration options and the actual chart data. Instead of storing the chart attributes first and then referencing them, we will get the chart attributes from the chart that is already rendered, using the getChartData method and modify that data with year specific data.

yearChange: function(year) {
  var revenueChart = FusionCharts.items['revenue-chart'];
  var chartJson = revenueChart.getChartData('json');
  chartJson.data = this.dataSet[year];
  revenueChart.setChartData(chartJson);
  this.selectedYear = year;
}

After adding the HTML for buttons and the above click handler for those buttons, clicking on those buttons should load that year’s data for the chart.

Demo

And here’s the final demo.

You can view the code for this demo on Plunker. Or you can download the code from our GitHub repo.

If you click through to the Plunker, you’ll see that we have defined the dataSet property in the config.json file directly. This keeps things much tidier in our component.

Conclusion and Next Steps

We started by building a simple Angular chart, and then went on to add more functionality to it using annotations and other FusionCharts’ APIs. But this is just the tip of the iceberg and a lot more can be done using both Angular 2 and FusionCharts. Some things that you can explore on your own:

  • Include more charts: A column chart is not always the best way to represent a dataset. Depending on your use case you might want to use different charts like waterfall, radar, gauge etc. So try using the process explained in this tutorial to plot a different chart and see if you are able to do it successfully.

  • Include charts in your app: If you are into making hybrid mobile apps, then you must be aware that Ionic 2(latest version of Ionic) is based on Angular 2. And that’s a good news because you can use this tutorial as a base to create charts for your Ionic apps as well.

  • Explore more events: In this tutorial, I explained how to use setChartData method, but there are plenty more events and methods that you can use to enhance your app’s user experience. Check out the above linked pages to learn more about the various events and methods offered by FusionCharts.

If you face any difficulty while trying to make charts on your own, please refer to documentation of Angular or FusionCharts (depending on the issue), or just leave a comment below. I will be more than happy to help!

Frequently Asked Questions about Chart Component in Angular2 FusionCharts

How do I install FusionCharts in Angular2?

To install FusionCharts in Angular2, you need to first install FusionCharts and Angular FusionCharts via npm. Use the following commands in your terminal:
npm install fusioncharts
npm install angular-fusioncharts
After installation, import FusionCharts and Angular FusionCharts into your component file. Then, add FusionChartsModule to your NgModule imports array.

Can I use FusionCharts with Angular CLI?

Yes, FusionCharts is compatible with Angular CLI. After installing FusionCharts and Angular FusionCharts via npm, you can import them into your Angular CLI project. Remember to add FusionChartsModule to your NgModule imports array.

How do I create a basic chart using FusionCharts in Angular2?

To create a basic chart, you need to first define the chart configuration in your component. This includes the chart type, data source, and other options. Then, use the FusionCharts component in your template to render the chart. You can customize the chart by modifying the chart configuration.

What types of charts can I create with FusionCharts in Angular2?

FusionCharts supports a wide variety of chart types, including line, bar, pie, area, doughnut, and more. You can also create advanced charts like combination charts, zoomline charts, and treemaps. Each chart type has its own configuration options, which you can customize to suit your needs.

How do I update the data in my FusionCharts chart?

To update the data in your chart, you need to modify the data source in your chart configuration. FusionCharts will automatically update the chart when the data source changes. You can also use the setJSONData or setChartData methods to update the data programmatically.

Can I use FusionCharts in Angular2 with TypeScript?

Yes, FusionCharts is compatible with TypeScript. You can import FusionCharts and Angular FusionCharts into your TypeScript file and use them as you would in a regular JavaScript file.

How do I handle events in FusionCharts in Angular2?

FusionCharts provides a number of events that you can listen to, such as dataPlotClick, chartClick, and beforeRender. To handle these events, you need to define an event handler in your component and bind it to the FusionCharts component in your template.

Can I customize the appearance of my FusionCharts chart?

Yes, FusionCharts provides a wide range of customization options. You can customize the colors, fonts, borders, backgrounds, and more. These options can be set in the chart configuration.

How do I export my FusionCharts chart?

FusionCharts provides built-in export functionality. You can export your chart as an image, PDF, or SVG. To enable export, you need to set the exportEnabled option to true in your chart configuration.

How do I debug issues with my FusionCharts chart?

FusionCharts provides a debug mode that logs detailed information about the chart rendering process. To enable debug mode, set the debugMode option to true in your chart configuration. You can then view the logs in your browser’s console.

Rohit BoggarapuRohit Boggarapu
View Author

Rohit Boggarapu is currently a software engineer at Adobe. He loves developing cool things and writing for the web. When not writing code, you will find him either practicing Yoga or biking.

Angular 2angular 2 componentsAngular Tutorialscharting librariesChartsjamesh
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week