There is continually increasing demand from organizations to find ways to make data-driven decisions. In this climate, providing highly-interpretable and usable data visualizations is key to enhancing user experience. This post will briefly overview Plotly.js as a visualization solution and we’ll walk through the creation of a simple scatter plot in Angular.

Choosing Plotly

In developing a recent Angular project, we’ve begun transitioning D3 visualizations to Plotly as well as implementing new visualizations. This opportunity provides our users with an awesome amount of interactivity that remains functionally consistent and visually cohesive across the application.

Along with this added value, we’ve experienced other notable side-effects. Development is eased by the Plotly API’s straightforward figure interfaces and time to implementation is less than that of D3. The amount of code required is also measurably reduced.

We’ve observed that Plotly thrives in use cases where providing clean, consistently coded, and interactive graphs takes precedence over the granular SVG implementation and customization required by data-visualization mainstay D3.

 

Adding Plotly in an existing Angular project

First, download the latest Plotly release.

Add the plotly.min.js file included in the download to the assets/scripts folder of your Angular project, or wherever you choose to keep external scripts.

Next, add the script path to the build object scripts in angular.json

"scripts": [
	"src/assets/scripts/plotly.min.js"
]

Note that we’re referencing Plotly as an external script, when we would typically add project dependencies using npm and package.json. We’ve used this method to work around a known bug related to importing Plotly in current versions of Angular which are targeting es6 for compilation. Plotly can still be added using the plotly.js or angular-plotly packages through npm, and imported via the PlotlyViaCDNModule. For more detail visit the angular-plotly library documentation, here.

 

Implementing Plotly in Angular components

Now that we’ve made the library known to the application, we can add graphs in our component. For our example data, we’re using a publicly available bike share dataset from Nice Ride Minnesota. To keep our example simple, we’re importing the cleaned data (that used to be there) directly into the component as a Typescript object.

 Overview

  •  Component Typescript creates a reference to the Plotly library and defines a graph object representing plot data (coordinates) and layout
  • A div element is added as a container for the Plotly canvas.
  • Plotly is called to render and update graph objects as SVG or WebGL.

 Adding the Graph

 In the component template, add the div element and template reference variable #rideshareGraph.

<h1 class="text-center">Minneapolis Bike Share Rides: Week Day vs. Weekend</h1>

<!-- For responsive graphs, the parent element must be 100% width -->
<div class="w-100" #rideShareGraph></div>

In the component Typescript we’ll declare the Plotly object from our external script, use ViewChild to access the graph container template reference, and declare the rideShareGraph object which will be populated on component initialization.

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { rideShareData, RideShareData } from './bike-data';

declare const Plotly;

@Component({
  selector: 'app-data-visualization',
  templateUrl: './data-visualization.component.html',
  styleUrls: ['./data-visualization.component.css']
})
export class DataVisualizationComponent implements OnInit {
  @ViewChild("rideShareGraph", { static: false }) rideShareGraphContainer: ElementRef;
  
  rideShareGraph;
  rideShareData: RideShareData;

  constructor() {}

In ngOnInit we initialize the graph and assign our coordinate data to the object x and y arrays, where each object of the data array represents a Plotly trace. In this case we have two traces: a scatter trace for weekend rides, and one for weekday rides.

ngOnInit() {
    this.rideShareData = rideShareData;

    this.rideShareGraph = {
      data: [
        {
          x: this.rideShareData.hours,
          y: this.rideShareData.weekendRides,
          type: 'scatter',
          name: 'Weekend Rides',
        },
        {
          x: this.rideShareData.hours,
          y: this.rideShareData.weekdayRides,
          type: 'scatter',
          name: 'Week Day Rides',
        },
      ],
      layout: {
        responsive: true,
        title: { text: 'July 2019' },
        xaxis: { 
          title: { text: "Hour of the day" },
        },
        yaxis: {
          title: { text: "Rides" },
        },
      }
    };
  }

Plotly is flexible with respect to which trace or layout properties are required for rendering, providing default values for most properties. This allows developers to create great visualizations with very little effort or configuration.

Moving on to the last step of our setup, we’ll call Plotly.newPlot, passing in our graph data. This is done in the ngAfterViewInit lifecycle method to ensure that Angular has fully rendered the rideShareGraphContainer element to the DOM.

ngAfterViewInit() {
    Plotly.newPlot(
        this.rideShareGraphContainer.nativeElement,
        this.rideShareGraph.data,
        this.rideShareGraph.layout,
        this.rideShareGraph.config
      );
  }

The Result

Below: Plotly includes hover tags for each trace, which can be further customized through trace and layout properties in the graph object. The upper right hand ‘modebar’ includes zoom, panning, reset, and other options which allow users to manipulate and customize the canvas.

Going Forward

We now have a graph that provides an interesting way to assess our data. Though the current graph object is minimally configured, we could easily customize it through properties outlined in the figure reference. We could, for example, autorange our graph or implement a log scale over the y-axis. We could also customize tick marks and style hover data. Finally, Plotly supplies various event handlers which can further amplify our opportunities for customization.

Plotly Benefits Recap

  • Quick implementation
  • Built-in interactivity provided by the library
  • Many customization properties available through the figure reference documentation

For full documentation and additional examples, visit https://plotly.com/javascript/.