block by syntagmatic ac5b726c53ec02618de7795429c6f833

Baseball Scatterplot Matrix

Full Screen

Scatterplot matrix design invented by J. A. Hartigan. 1986 baseball statistics data from the R package Visualizing Categorical Data.

Based on Scatterplot Matrix Brushing, but still awaiting the d3.v4 brush component.

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style>

svg {
  font: 10px sans-serif;
  padding: 12px;
}

.axis,
.frame {
  shape-rendering: crispEdges;
}

.axis line {
  stroke: #e8e8e8;
}

.axis path {
  display: none;
}

.axis text {
  fill: #999;
}

.cell text {
  font-weight: bold;
  text-transform: capitalize;
  font-size: 15px;
  fill: #222;
}

.frame {
  fill: none;
  stroke: #aaa;
}

.diagonal {
  stroke: none;
  fill: #fff;
  fill-opacity: 0.8;
}

circle {
  fill-opacity: .7;
}

circle.hidden {
  fill: #ccc !important;
}

.extent {
  fill: #000;
  fill-opacity: .125;
  stroke: #fff;
}

</style>
<body>
<script src="//d3js.org/d3.v4.0.0-alpha.35.js"></script>
<script>
var traits = ["assist86", "hits86", "homer86", "runs86", "rbi86", "walks86"],
    n = traits.length;

var width = 960,
    size = (width / n) - 12,
    padding = 24;

var x = d3.scaleLinear()
    .range([padding / 2, size - padding / 2]);

var y = d3.scaleLinear()
    .range([size - padding / 2, padding / 2]);

var xAxis = d3.axisBottom()
    .scale(x)
    .ticks(5);

var yAxis = d3.axisLeft()
    .scale(y)
    .ticks(5);

var color = d3.scaleCategory20();

d3.csv("Baseball.csv", function(error, data) {
  if (error) throw error;

  data.forEach(function(d) {
    traits.forEach(function(trait) {
      return d[trait] = +d[trait];
    });
  });

  var domainByTrait = {};

  traits.forEach(function(trait) {
    domainByTrait[trait] = d3.extent(data, function(d) { return d[trait]; });
  });

  xAxis.tickSize(size * n);
  yAxis.tickSize(-size * n);

  var svg = d3.select("body").append("svg")
      .attr("width", size * n + padding)
      .attr("height", size * n + padding)
    .append("g")
      .attr("transform", "translate(" + padding + "," + padding / 2 + ")");

  svg.selectAll(".x.axis")
      .data(traits)
    .enter().append("g")
      .attr("class", "x axis")
      .attr("transform", function(d, i) { return "translate(" + (n - i - 1) * size + ",0)"; })
      .each(function(d) {
        x.domain(domainByTrait[d]).nice();
        d3.select(this).call(xAxis);
      });

  svg.selectAll(".y.axis")
      .data(traits)
    .enter().append("g")
      .attr("class", "y axis")
      .attr("transform", function(d, i) { return "translate(0," + i * size + ")"; })
      .each(function(d) { y.domain(domainByTrait[d]); d3.select(this).call(yAxis); });

  var cell = svg.selectAll(".cell")
      .data(cross(traits, traits))
    .enter().append("g")
      .attr("class", "cell")
      .attr("transform", function(d) { return "translate(" + (n - d.i - 1) * size + "," + d.j * size + ")"; })
      .each(plot);

  // Titles for the diagonal.
  cell.filter(function(d) { return d.i === d.j; }).append("text")
      .attr("x", size/2)
      .attr("y", size/2)
      .attr("text-anchor", "middle")
      .text(function(d) { return d.x; });

  //cell.call(brush);

  function plot(p) {
    var cell = d3.select(this);

    x.domain(domainByTrait[p.x]);
    y.domain(domainByTrait[p.y]);

    cell.append("rect")
        .attr("class", "frame")
        .classed("diagonal", function(d) {return d.i === d.j; })
        .attr("x", padding / 2)
        .attr("y", padding / 2)
        .attr("width", size - padding)
        .attr("height", size - padding);

    cell.filter(function(d) {return d.i !== d.j; })    // hide diagonal marks
      .selectAll("circle")
      .data(data)
      .enter().append("circle")
        .attr("cx", function(d) { return x(d[p.x]); })
        .attr("cy", function(d) { return y(d[p.y]); })
        .attr("r", 2.5)
        .style("fill", function(d) { return color(d["posit86"]); });
  }
});

function cross(a, b) {
  var c = [], n = a.length, m = b.length, i, j;
  for (i = -1; ++i < n;) for (j = -1; ++j < m;) c.push({x: a[i], i: i, y: b[j], j: j});
  return c;
}

</script>