Creating a bubble chart

A bubble chart is a typical visualization capable of displaying three data dimensions. Every data entity with its three data points is visualized as a bubble (or disk) on Cartesian coordinates, with two different variables represented using x axis and y axis, similar to the scatter plot chart. While the third dimension is represented using the radius of the bubble (size of the disk). Bubble chart is particularly useful when used to facilitate understanding of relationships between data entities.

Getting ready

Open your local copy of the following file in your web browser:

https://github.com/NickQiZhu/d3-cookbook/blob/master/src/chapter8/bubble-chart.html

How to do it...

In this recipe we will explore techniques and ways of implementing a typical bubble chart using D3. The following code example shows the important implementation aspects of a bubble chart with accessors and peripheral graphic implementation details omitted.

...
var _width = 600, _height = 300,
  _margins = {top: 30, left: 30, right: 30, bottom: 30},
  _x, _y, _r, // <-A
  _data = [],
  _colors = d3.scale.category10(),
  _svg,
  _bodyG;

  _chart.render = function () {
    if (!_svg) {
      _svg = d3.select("body").append("svg")
      .attr("height", _height)
      .attr("width", _width);

    renderAxes(_svg);

    defineBodyClip(_svg);
  }

  renderBody(_svg);
};
...
function renderBody(svg) {
  if (!_bodyG)
    _bodyG = svg.append("g")
      .attr("class", "body")
      .attr("transform", "translate(" 
        + xStart() 
        + "," 
        + yEnd() + ")")
      .attr("clip-path", "url(#body-clip)");
  renderBubbles();
}

function renderBubbles() {
  _r.range([0, 50]); // <-B
  
  _data.forEach(function (list, i) {
    _bodyG.selectAll("circle._" + i)
      .data(list)
      .enter()
      .append("circle") // <-C
      .attr("class", "bubble _" + i);

    _bodyG.selectAll("circle._" + i)
      .data(list)
      .style("stroke", function (d, j) { 
        return _colors(j); 
      })
      .style("fill", function (d, j) { 
        return _colors(j); 
      })
      .transition()
      .attr("cx", function (d) { 
        return _x(d.x); // <-D
      })
      .attr("cy", function (d) { 
        return _y(d.y); // <-E
      })
      .attr("r", function (d) { 
        return _r(d.r); // <-F
      });
  });
}
...

This recipe generates the following visualization:

How to do it...

Bubble chart

How it works...

Overall, bubble chart implementation follows the same pattern as other chart implementations introduced in this chapter so far. However, since in bubble chart we want to visualize three different dimensions (x, y, and radius) instead of two, therefore a new scale _r was added in this implementation (line A).

var _width = 600, _height = 300,
  _margins = {top: 30, left: 30, right: 30, bottom: 30},
  _x, _y, _r, // <-A
  _data = [],
  _colors = d3.scale.category10(),
  _svg,
  _bodyG;

Most of the bubble chart related implementation details are handled by the renderBubbles function. It starts with setting the range on the radius scale (line B). Of course we can also make the radius range configurable in our chart implementation; however, for simplicity we chose to set it explicitly here:

function renderBubbles() {
  _r.range([0, 50]); // <-B
  
  _data.forEach(function (list, i) {
    _bodyG.selectAll("circle._" + i)
      .data(list)
      .enter()
      .append("circle") // <-C
      .attr("class", "bubble _" + i);

    _bodyG.selectAll("circle._" + i)
      .data(list)
      .style("stroke", function (d, j) { 
        return _colors(j); 
      })
      .style("fill", function (d, j) { 
        return _colors(j); 
      })
      .transition()
      .attr("cx", function (d) { 
        return _x(d.x); // <-D
      })
      .attr("cy", function (d) { 
        return _y(d.y); // <-E
      })
      .attr("r", function (d) { 
        return _r(d.r); // <-F
      });
  });
}

Once the range is set, then we iterated through our data series and for each series we created a set of svg:circle elements (line C). Finally we handled the newly created bubble as well as its update in the last section, where svg:circle elements are colored and placed to the correct coordinates using its cx and cy attributes (line D and E). In the end, the bubble size is controlled using its radius attribute r mapped using the _r scale we defined earlier (line F).

Tip

In some bubble chart implementations, the implementer also leverages the color of each bubble to visualize a fourth data dimension, though some believe this kind of visual representation is hard to grasp and superfluous.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset