Create versatile visualizations with D3 and Angular

Learn how to combine the D3 data visualization tool and the Angular cross-platform application development platform to create interactive visualizations.
Register or Login to like
An introduction to GNU Screen

Opensource.com

Our world is based on data. We gather it everywhere: forms, feedback, learning techniques, data mining, etc. When it comes to working with that data, we need to do more than show numbers back to our users; we need to make it easy for them to understand what the numbers mean.

By combining the D3 data visualization tool and the Angular cross-platform application development platform, we can take that data and create versatile and interactive visualizations that respond to dynamic data. This squeezes that last 10% out of your data and takes your data-based application to the next level for your users.

What is D3?

D3.js is an open source JavaScript library that provides powerful manipulation of the Document Object Model (DOM) driven by data. It gives you all the tools you need to create any visualization you can imagine. You get data transformations to prepare the data, shape creation for visualizing the data, layouts to transform the data into different representational layouts, transitions to give visual flair as the data and shapes change, and powerful tools for interaction. It's based on web standards, allowing you to transform your data and give it life with HTML, CSS, and SVG.

Getting started with D3 is easy. To create a visualization, we first need an SVG element to work with:

var width = 500,
    height = 500;
var svg = d3.select('body')
    .append('svg')
    .attr('width', width)
    .attr('height', height)
    .append('g')
    .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ') rotate(-90 0 0)');

Let's have a little fun creating a sunburst. Think of it like a multi-level donut chart, great for displaying hierarchical data. (It’s also more fun than a simple bar chart example.) To get started, we need a generator for our shape, in our case an arc. D3 provides a generator to create a circular sector that you can customize.

var arc = d3.svg.arc()
    .startAngle(function(d) {
      return Math.max(0, Math.min(2 * Math.PI, xScale(d.x)));
    })
    .endAngle(function(d) {
      return Math.max(0, Math.min(2 * Math.PI, xScale(d.x + d.dx)));
    })
    .innerRadius(function(d) {
      return Math.max(0, yScale(d.y));
    })
    .outerRadius(function(d) {
      return Math.max(0, yScale(d.y + d.dy));
    });

Now we're ready for the data.

General update pattern

D3 has a pattern for how to deal with your data. The pattern is join, enter, update, and exit. This involves a data join for merging new and existing data, followed by the entering, updating, and removing of data. The pattern is easy with D3 using data(), append(), transition(), and exit().

/* JOIN new data with old elements */
var gs = svg.selectAll('g')
  .data(partition.nodes(root));

/* ENTER new elements present in new data */
var g = gs.enter().append('g')
  .on('click', click)
  .on('mouseover', mouseoverArc)
  .on('mousemove', mousemoveArc)
  .on('mouseout', mouseoutArc);

var path = g.append('path');

/* UPDATE old elements present in new data */
gs.select('path')
  .style('fill', function(d) {
      return color((d.co ? d.co : 'base'));
  })
  .transition().duration(500)
  .attr('d', arc)
  .each(function(d) {
      this.x0 = d.x;
      this.dx0 = d.dx;
  });

/* EXIT old elements not present in new data */
gs.exit()
  .transition()
  .duration(500)
  .style('fill-opacity', 0)
  .remove();

By putting this all together with some data, D3 will do the heavy lifting of creating our sunburst chart. We even have functions set up to provide interactivity (see the ENTER section of the code). But what if we want this chart to communicate with other charts? Enter Angular components.

What is Angular?

Angular is a platform for building mobile and desktop web applications. It's an opinionated framework made for building applications, giving you all the pieces you need. It's a lot of things, but we're going to concentrate on one piece: components. They're the base building block of the UI and the Angular code that will interact with our D3 code.

With our powers combined

The two powerful pieces of the component that enhance D3 visualization are inputs and outputs. Inputs allow our components to receive data, meaning we can have a component to generate our sunburst that knows nothing about how to get the data, but still will render it when it comes in. Outputs allow our components to pass data back up to parent components, communicating events and data back up the stack.

@Input()
sunData: dataPoint[];

@Input()
filters: string[];

@Output()
onFilter: EventEmitter<string[]> = new EventEmitter<string[]>();

Angular uses both decorators and TypeScript in its code, which adds a lot of value and power to your code. The property decorators of @Input and @Output define inputs and outputs to our component. By defining the property this way, the Angular compiler automatically creates a binding to the property and links it. On the input, we can assign a type to our data. It creates better code by defining what data it expects, which will come in handy when you connect the component to other code within your Angular application. Angular can also optimize components with different change-detection strategies. You can tell a component to update itself only on push, where it will look at the input's reference and update only if it changes.

On our output, we use an EventEmitter. This gives our component the ability to emit data to a function provided to our component. We can connect this to our visualization and the click event. As we click points, we can pass values out to our containing component, such as a DashboardComponent. The DashboardComponent can then update the data either by filtering the data or querying an API. Our D3 sunburst component and any others we create will see the change, and the general update pattern will take over.

Open source to the future

One of the great parts of working with both Angular and D3 is they are both open source and provide a wealth of examples from each community. For example, D3 has a great community with a plethora of charts, from the basic through the imaginative. They can act as inspiration for your data or as jumping-off points to help you start creating that big idea.

To learn more, attend John Niedzwiecki's talk, "D3 + Angular = Visual Awesomesauce," at Connect.Tech, September 21-22, 2017, in Atlanta.

User profile image.
our friendly neighborhood kilted coder. Developer of the web, JavaScript, D3, and Angular. Ginger geek dad.

7 Comments

This article is a bit of a let down following such an ambitious title/sub-title

There are around a thousand "import d3, draw a line in Angular. Now, go create cool stuff" tutorials out there already

Sorry that it let you down. This article was actually meant as a lead into a talk I'm going to be giving on the topic at Connect.Tech, so it was only introductory. I tried to show more than just drawing a line with the use of arc and creating the sunburst. I invite you to check after next week on my personal Github / blog for the full presentation that I'll post after the conference, and hopefully that will give you more of what you're looking for. And on that note, what is it you would like to see or were expecting? Is it just the brevity of this that was a problem, that you'd like to see a full working prototype?

In reply to by colin_adsf (not verified)

Thanks for article John .. But could you post the full source code. I was not really able to follow along. I'm not able to see what you trying to create / present - Big picture. Thanks

JJ,

This is a section of code that I'm writing for a talk next week (the post meant as a preview), so I'll have a fully working version up and running before too long. You can check my personal Github (rhgeek) but I'll also be sure to come back and post a direct link for you once it's ready to let you know.

In reply to by JJ

From right clicking and inspecting (combined with a little googling of class names) it looks like they specifically using a tool called image map pro for wordpress. Now, with that said, you could recreate that functionality yourself. How it is done from a technical level is they load an image, based on if you want skull, muscles, etc and then overlay and SVG on top of it. If you inspect, you’ll see a lot of polygons. What it creates is shapes over the image to define the area you want to show a div with more information, like a tooltip. So they draw a shape over the image to represent what is the frontal bone and when you hover they show the div with all the text about it.

You could create something like this yourself with D3 or with SVG directly. D3 can give you the code to create those pieces and interaction. It would depend on the overall goals that it might be more of a hybrid solution, or maybe on that doesn’t even need D3. The most difficult part in this particular example would be defining the regions to match your region, since it’s over top of a fixed image. That is something their tool obviously does, and I think you could likely google and fine tools to help you define that as well to then be used by other code.

Hope that helps put you down the right path.

In reply to by Nathan

Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.