Jacob Orshalick is a software consultant, open source developer, and author. He is the owner of solutionsfit, a consulting firm dedicated to aligning businesses with technology. His software development experience spans the retail, financial, real estate, media, telecommunications, and health care industries. Jacob is a DZone MVB and is not an employee of DZone and has posted 13 posts at DZone. You can read more from them at their website. View Full User Profile

Power up your HTML5 with D3

09.20.2012
| 1201 views |
  • submit to reddit

The power of HTML5 is remarkable. I’ve seen impressive demos in presentations and great looking example pages that people have developed in their spare time, but it always looks highly complex. In addition, the examples are usually just that, examples, with little to no real world application. Here we’ll look at an example that shows how D3 enables HTML5 to provide real business value.

D3 helps to hide some of that complexity, allows you to operate directly on data sets, and provides the capabilities necessary to quickly apply the power of HTML5 in real-world scenarios. This javascript library uses HTML5 standards to generate some of the flashiest (sans Flash) visualizations I’ve seen from a library. While it has a feel similar to jQuery, the use of SVG makes the animations much more advanced.

Let’s look at an example that creates a simple bar graph. You can review the example by itself here. Or, simply click “GO” below the to see the bar graph in action.

101812241513178GO

This animation uses no images or flash, just HTML5 standards with the help of D3. When you view the source, you’ll notice that an <svg> element is defined, sized to the expected width and height of our bar graph.

 

<svg id="bargraph" width="800" height="400"></svg>

The bar graph is generated from the following logic:

bargraph().data([10, 18, 12, 24, 15, 13, 22, 17, 8]).plot();

Defining the bargraph object

The first step is to define our object:

function bargraph() {
  var colors = ["#2d578b", "steelblue", "#777"],
    data = [10, 15, 20],
    xCoordinateSpacing = 50,
    yCoordinateSpacing = 70;

  function bargraph() {

  }

  bargraph.data = function(d) {
    data = d;
    return bargraph;
  }

  // … …
}

The bargraph object defines a set of attributes. The colors attribute defines the various colors the bars will be. The data attribute is an array of numbers that will be plotted on the bar graph. We can change the default list of data points by invoking the data() method. The xCoordinateSpacing and yCoordinateSpacing attributes are simply common attributes for plotting shapes consistently.

Now let’s look at the render() method.

bargraph.plot = function() {
  svg = d3.select("#bargraph").append("g");

  renderDataPointsAsStrings(svg);
  renderGoButton(svg);
}

The first step is to define a group within the <svg> element to contain our SVG shapes. Once the group is defined, we pass it to the methods that render our data points and the “GO” button.

Rendering the data points

Now let’s render the data points.

function renderDataPointsAsStrings(svg) {
  var text = svg.selectAll("text").data(data, String);

  text.enter().append("text")
    .text(String)
    .attr("x", function(d, i) {
      return i * xCoordinateSpacing + 20;
    })
    .attr("y", yCoordinateSpacing);
}

This method appends the data points as <text> elements. If you are unfamiliar with the syntax of D3, here is a quick rundown:

  • svg.selectAll(selector) – follows similar selector syntax to jQuery and returns a list of results matching your selector
  • data – defines the data points you want to operate on across the selected elements
  • elements.enter() – for each data point the enter logic will be invoked

This is a common pattern in D3 that you will see consistently. Notice that for every data point we append a text element. The attributes of the text element can be calculated by a function or simply provided directly. Here we show both options.

The actual text we are going to show in each text element is the data element itself. By passing the javascript String function to the text method we are indicating this.

We make use of the xCoordinateSpacing and yCoordinateSpacing attributes to determine the starting points of each data element. The “x” attribute is simply a calculation that evenly spaces the text elements. The functions can receive both a d and i parameter providing both the data point itself and the index of the data point respectively.

Showing the bar graph

The “GO” button itself is rendered by the renderGoButton method, but once rendered, an onclick event is attached that shows the bar graph:

svg.selectAll(".gobutton").on("click", function() {
  showBarGraph(svg);
  // … …
});

Here we select on a CSS class selector and attach a function to fire onclick. The showBarGraph() method performs the magic necessary to render the bar graph:

  function showBarGraph(svg) {
    var rect = svg.selectAll("rect").data(data, String);

    rect.enter().append("rect")
      .attr("class", "bargraph")
      .attr("x", function(d, i) {
        return i * xCoordinateSpacing;
      })
      .attr("y", yCoordinateSpacing + 10)
      .attr("width", xCoordinateSpacing - 10)
      .attr("height", 0)
      .attr("fill", function(d, i) {
        return colors[i % colors.length];
      });

    svg.selectAll(".bargraph").transition().duration(1000)
      .attr("height", function(d) {
        return d * 5;
      });
  }

Here we again follow the pattern we described previously. For each data point we append a rectangle shape below the text we rendered previously. By using the xCoordinateSpacing and yCoordinateSpacing attributes to calculate the “x”, “y”, and “width” attributes, we are provided consistency in the location of are rectangles in comparison to the text.

Notice the use of the “fill” attribute. Here we utilize the index of each data point to vary the color of each rectangle based on our colors array. Finally, we apply a transition to the bars that causes them to expand to a height representative of each data point over the course of 1 second. We are using the most basic transition, but through the use of the ease() method, you can vary the style of transition.

That’s it! There’s more to the example as you review the source code, so if you have any questions please feel free to post them in the comments. Also, for more complex examples and some great tutorials, visit the D3 website.

 

Published at DZone with permission of Jacob Orshalick, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)