Creating a scatter plot chart

A scatter plot or scatter graph is another common type of diagram used to display data points on Cartesian coordinates with two different variables. Scatter plot is especially useful when exploring the problem of clustering and classification. In this recipe, we will learn how to implement a multi-series scatter plot chart in D3.

Getting ready

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

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

How to do it...

A scatter plot is another chart which uses Cartesian coordinates. Thus, a large part of its implementation is very similar to the charts we have introduced so far, therefore the code concerning peripheral graphical elements are again omitted to save space in this book. Please review the companion code for the complete implementation.

...
_symbolTypes = d3.scale.ordinal() // <-A
  .range(["circle",
    "cross",
    "diamond",
    "square",
    "triangle-down",
    "triangle-up"]);
...
function renderBody(svg) {
  if (!_bodyG)
    _bodyG = svg.append("g")
      .attr("class", "body")                    
      .attr("transform", "translate(" 
        + xStart() + "," 
        + yEnd() + ")") 
      .attr("clip-path", "url(#body-clip)");

  renderSymbols();
}

function renderSymbols() { // <-B
  _data.forEach(function (list, i) {
    _bodyG.selectAll("path._" + i)
      .data(list)
      .enter()
      .append("path")
      .attr("class", "symbol _" + i);

    _bodyG.selectAll("path._" + i)
      .data(list)
      .classed(_symbolTypes(i), true)
      .transition()
      .attr("transform", function(d){
        return "translate("
          + _x(d.x)
          + ","
          + _y(d.y)
          + ")";
      })
      .attr("d", 
    d3.svg.symbol().type(_symbolTypes(i)));
  });
}
...

This recipe generates a scatter plot chart:

How to do it...

Scatter plot chart

How it works...

The content of the scatter plot chart is mainly rendered by the renderSymbols function on line B. You probably have already noticed that the renderSymbols function implementation is very similar to the renderDots function we discussed in the Creating a line chart recipe. This is not by accident since both are trying to plot data points on Cartesian coordinates with two variables (x and y). In the case of plotting dots, we were creating svg:circle elements, while in scatter plot we need to create d3.svg.symbol elements. D3 provides a list of predefined symbols that can be generated easily and rendered using an svg:path element. On line A we defined an ordinal scale to allow mapping of data series index to different symbol types:

_symbolTypes = d3.scale.ordinal() // <-A
  .range(["circle",
    "cross",
    "diamond",
    "square",
    "triangle-down",
    "triangle-up"]);

Plotting the data points with symbols is quite straight-forward. First we loop through the data series array and for each data series we create a set of svg:path elements representing each data point in the series.

_data.forEach(function (list, i) {
  _bodyG.selectAll("path._" + i)
    .data(list)
    .enter()
    .append("path")
    .attr("class", "symbol _" + i);
    ...
});

Whenever data series are updated, as well as for newly created symbols, we apply the update with transition (line C) placing them on the right coordinates with an SVG translation transformation (line D).

_bodyG.selectAll("path._" + i)
  .data(list)
    .classed(_symbolTypes(i), true)
  .transition() // <-C
    .attr("transform", function(d){
      return "translate(" // <-D
        + _x(d.x) 
        + "," 
        + _y(d.y) 
        + ")";
    })
    .attr("d", 
      d3.svg.symbol() // <-E
      .type(_symbolTypes(i))
  );

Finally, the d attribute of each svg:path element is generated using the d3.svg.symbol generator function as shown on line E.

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

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