Adding a #D3.js line chart to an #Angular.io project

D3.js (Data Driven Documents) is a powerful JavaScript library. At a basic level you can transform data into interactive charts and graphics that are easy to digest by your visitors. If you aren’t familiar with the library then take a look at their site for examples. I’ve also added a few links to other sites that showcase the capabilities.

While D3 provides documentation on the API and tutorials they also recommend looking at the examples from other developers to see how it all works. If you are looking for an example to show you how to get a basic line chart then you can use this post or look at their Line Chart example for a pure JavaScript implementation.

The example I’ve built for this post displays three different types of weather information for Philadelphia, Pennsylvania, Tempareture, Dewpoint, and Visibility. The example also has a button that the user can click on to change the displayed weather information. The data for the chart is stored in a JSON file in the assets directory of the project but it could have just as easily been an HTTP request to an API. To see the code for the example take a look at my GitHub repository angular-d3-line-chart-demo. If you’d like to see the chart in action then head over to Stackblitz.com for a running example. The rest of the post will go over the implementation as a technical discussion with references back to the code in the repository.

Adding D3.js to the Angular project requires adding the D3 core logic package and it’s associated Types files to the project. You may also need to add these other packages: d3-array, d3-axis, d3-scale, and d3-shape. Keep these packages in mind if you run into errors mentioning those packages. While I didn’t need them in my personal project, it is in Angular.io 8, I did need them when I was building this example on Stackblitz.com which is in Angular.io 9.

npm install --save d3
npm install --save-dev @types/d3

In order to encapsulate the chart related elements I created a custom component called line-chart.component. This component holds the chart, labels and controls to show the current type of data being displayed as well as a button to change the data. The encapsulated component can now be reused on the same page to show different data while providing the same user experience.

ng g component LineChart

When the component first initializes we need to configure the element that will contain the graph. When working with D3.js charts the element is an SVG. Within the buildSVG() function you’ll see all of the initial configuration performed on this SVG.

  • Grab the SVG element owned by this component, a simple task since it is owned by the component and there is only one SVG element
  • Set the height and width of SVG based on margin calculations
  • Add text to serve as a watermark in the chart

Because the chart data is dynamic the configuring of the X and Y axis aren’t performed during the initial configuration of the SVG. Instead, once the data is retrieved we’ll transform it into a format that is easily digested by the chart and the maximum/minimum values for the axis can be extracted.

The starting point for the data selection, transformation, and update of the graph occurs in the updateGraphData() function. This function is called during the component initialization as well as when the user clicks Change Chart Data button. From here the following functions are executed that will refresh the chart with the latest information.

  • clearChartData() – finds all path elements, lines on the chart, and removes them from SVG element.
  • buildChartData() – transforms the original JSON data into a simplified object containing a value and date field for consumption by the chart logic.
  • configureYaxis() – the Y-axis is going to represent some kind of numerical data. For this we can use the d3Array.scaleLinear(). Because we don’t want to have any of the data resting on the X-axis line we reduce minimum of the Y-axis range by 1. D3.js provides a function that will retrieve the minimum and maximum values in an array called d3Array.extent().
  • configureXaxis() – the X-axis is going to represent a time series so we’ll generate a scale based on the date property of the data and using d3Array.scaleTime().
  • drawLineAndPath() – the function uses the d3Shape.line() function to configure which parts of the data will be associated with the X and Y-axis. It also defines the look of the line, i.e. color and thickness.

With all of these functions combined we are able to initialize, configure, and draw the line chart as part of an Angular.io component. Other features that could be added are line tool tips, transitions between chart drawing, and showing two sets of data at one time. As I learn more about building charts with D3.js I will add new posts to describe how to add those features.

As mentioned earlier, take a look at the GitHub repository for all of the code. I’m going to continue updating and cleaning up the project as I learn more about D3.js line charts. Because of that I didn’t include any of the code in this post. I didn’t want to leave readers with one version discussed in the blog post while a newer version exists in the repo. If you have any questions or run into problems leave me a comment and I’ll see if I can help out.