Animate Basic Charts Examples

React and D3 are match made in heaven. In this article we will create basic pie, bar, line charts with event driven animation using D3 for visualization and React for the view, data, and state management.

The code samples in this article use the ReactSpeed ES6 Starter Project which you can reuse to speed launch mobile-web apps coded in React, Redux, and ES6. Live demo of the charts sample is available at ReactSpeed.com website.

Of course, the title of this article is a play on ABCD and React. Cheesy, but essentially true to the content, as you shall see.

Selecting a Vendor Library

Why reinvent the wheel? There are several charting libraries worth consideration when coding in React. However, if you are looking for D3 goodness, your options narrow down to just a few contenders. For us Rumble Charts comes out top because of these reasons:

Documentation. Very well documented charting API with editable, playable examples. React components. Good React component-oriented design including nesting of chart elements, convenient property management, and ES6 samples. NPM, GitHub. Code, tests available on GitHub, package downloadable from NPM. Design strategy. Rumble Charts design strategy is available in this awesome deck which compares other charting solutions and D3-React strategies with editable samples! Payload. Rumble Charts includes D3 dependencies. Core D3 is around 150KB. In future your app may have other libraries that may reuse D3. Rumble Charts adds around 65KB on top of that to add D3 based libraries (D3 Cloud, D3 Timer) and React chart components. So payload cost is acceptable. Premium charting library Highcharts, with similar options, “weighs” around 111KB, D3 not included. All sizes are unzipped and minified.

React D3 Goodness

For the uninitiated, here is a little bit about D3 before we dig into code.

D3.js is one of the most popular open source JavaScript libraries for visualizing data using HTML, CSS, and SVG. D3 is standards compliant, fast, includes powerful visualization components and Math that goes with these.

Square does an awesome introductory tutorial on D3.

Here is how the various standards come together in a React D3 app structure.

React D3 App Structure

These five points explain a typical React D3 app structure.

If we want to get to charts on the browser, we need to render to the HTML DOM. SVG is an XML structure or a set of parent-child elements, for basic shapes like circle, rect, line, and polygon, available within HTML DOM. SVG allows us to render Scalable Vector Graphics based images. CSS can style SVG elements just like HTML. These elements respond to UI events just like HTML elements. D3 library provides a way to include visualization data as Plain Old JavaScript Objects (POJO), an API in JavaScript to simplify SVG authoring, and easier access to HTML DOM and events, in a manner similar to jQuery. Examples of D3 API include handling chart scale, coordinates, axes, transitions (animation), and chart data binding to SVG element attributes. React enables composition of D3 API as component hierarchy. Representing data objects into components with properties and UI state management. Managing event handling. React also renders the D3 visualization using Virtual DOM.

React ES6 Starter and Sample

Let us review the fixture for our charts data that helps us draw our charts.

The data is straight forward JavaScript arrays of objects representing charts that take single or multiple series data, and chart that takes key:value pairs for generating a word cloud.

Now we can install Rumble Charts within our project using NPM.

npm install --save rumble-charts

Next let us review how we render six different charts using Rumble Charts and our ReactSpeed starter project.

React Component Hierarchy

We make a copy of CardStack component which in turn uses Flexbox to layout Card components as visual containers for our six charts.

Let us understand the code in relation to React D3 app structure explained earlier.

The second import statement right at the top of our component code imports that data fixture for series, singleSeries, and cloudSeries making these data objects available to our component definition which follows.

import { series, singleSeries, cloudSeries } from ‘../fixtures/charts/series’;

In our constructor definition, we use the imported data objects to initialize state for our component. We are using the ES6 shorthand notation to specify same named key:value pair.

this.state = { series, cloudSeries, singleSeries };

We are also using the constructor to bind a method called updateSeries with our component. The method will be used to update series data using random number generator when user clicks on any of the graphs. This will in turn demonstrate the transition and animation capability of our app.

The third import statement imports specific components from Rumble Charts which we will use to create our React app.

const { Chart, Cloud, Labels, Lines, Pies, RadialLines, Ticks, Layer, Animate, Transform} = require(‘rumble-charts’);

In our render method we are rendering Card component six times to layout six samples for our charts. Let us pick the simplest one (third from top row, radial lines chart).

<Chart

onClick={this.updateSeries}

width={300}

height={200}

series={this.state.series}

minY={0}

>

<RadialLines />

</Chart>

Our charting library exposes properties on Chart component to specify event handling method, dimensions of our chart, series data for the chart, among others.

The RadialLines component is an excellent example of how React is used to pass on the properties (series data) to child components, within a parent-child component hierarchy. You do not have to specify any of the properties again.

Other sample charts extend this basic design principle. Include chart features as child components, like chart type, ticks, transforms, layers, and even animation. Pass relevant properties from parent to child components in the hierarchy. This makes our overall app design highly modular, iterative, and reusable.

Let us consider another example, this time using Transform component from Rumble Charts.

<Chart onClick={this.updateSeries} width={300} height={200}

series={this.state.series} minY={0}>

<Transform method={[‘transpose’, ‘stack’]}>

<Pies combined innerPadding=”3%” innerRadius=”20%” />

</Transform>

</Chart>

The Transform component takes multiple values to apply a transform on our chart. These include “stack”, “stackNormalized”, “sort”, “unstack”, “transpose”, “rotate”, and “reverse”. Another example of elegant React design where Transform component is applying these transforms on its child component, Pies in this case.

Having used several charting libraries, this is the first time one can perform such complex charting transforms and styling practically in three lines of HTML-like JSX code. Thank you React + D3!

Animating React D3 Charts

Finally let us consider the animation aspects of our charts. As all charts have onClick handler defined as updateSeries, clicking on any chart calls this method to update component state for series and singleSeries with random values.

As state is updated, React re-renders the component, calling the render method again. All charts update (seem to animate) based on new values. Our cloud chart also seems to update as the word cloud itself uses random placement of the “words” on every new render.

Another way we are animating our charts is by transitioning the chart styles based on UI events. This is used to change color of first pie chart and the second bar + line chart as you hover mouse over these charts.

onMouseMove: (e) => e.target.style.opacity = 1,

onMouseLeave: (e) => e.target.style.opacity = 0.5

We are using ES6 arrow function shorthand to specify the event handler methods inline within the component props setup.

We further do explicit animation of the second chart in top row, the combined bar, line chart. This is again done similar to how we did the transform in earlier example.

We wrap the Layer component with an Animate component to perform the chart animation on a particular layer. Layer in turn renders multiple components to create a complex chart with Line, Bar, and Tick components.

<Animate _ease=”bounce” _ease=”elastic”> <Layer width=”80%” height=”80%” position=”middle center”>

// multiple chart components... </Layer> </Animate>

As you can see, React and D3 can be great friends. You can easily add compelling interactivity to your apps using these two libraries.