Skip to content

Instantly share code, notes, and snippets.

@mbostock
Forked from mbostock/.block
Last active July 2, 2023 13:49
Show Gist options
  • Select an option

  • Save mbostock/4063663 to your computer and use it in GitHub Desktop.

Select an option

Save mbostock/4063663 to your computer and use it in GitHub Desktop.

Revisions

  1. mbostock revised this gist Jun 15, 2019. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions .block
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,4 @@
    license: gpl-3.0
    border: no
    height: 960
    redirect: https://observablehq.com/@d3/brushable-scatterplot-matrix
  2. mbostock revised this gist Jun 2, 2016. 2 changed files with 2 additions and 2 deletions.
    2 changes: 2 additions & 0 deletions .block
    Original file line number Diff line number Diff line change
    @@ -1 +1,3 @@
    license: gpl-3.0
    border: no
    height: 960
    2 changes: 0 additions & 2 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -175,8 +175,6 @@
    function brushend() {
    if (brush.empty()) svg.selectAll(".hidden").classed("hidden", false);
    }

    d3.select(self.frameElement).style("height", size * n + padding + 20 + "px");
    });

    function cross(a, b) {
  3. mbostock revised this gist Feb 9, 2016. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions .block
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    license: gpl-3.0
  4. mbostock revised this gist Dec 30, 2015. 1 changed file with 16 additions and 11 deletions.
    27 changes: 16 additions & 11 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -20,6 +20,11 @@
    display: none;
    }

    .cell text {
    font-weight: bold;
    text-transform: capitalize;
    }

    .frame {
    fill: none;
    stroke: #aaa;
    @@ -45,8 +50,8 @@
    <script>

    var width = 960,
    size = 150,
    padding = 19.5;
    size = 230,
    padding = 20;

    var x = d3.scale.linear()
    .range([padding / 2, size - padding / 2]);
    @@ -57,12 +62,12 @@
    var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .ticks(5);
    .ticks(6);

    var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .ticks(5);
    .ticks(6);

    var color = d3.scale.category10();

    @@ -141,7 +146,7 @@
    .enter().append("circle")
    .attr("cx", function(d) { return x(d[p.x]); })
    .attr("cy", function(d) { return y(d[p.y]); })
    .attr("r", 3)
    .attr("r", 4)
    .style("fill", function(d) { return color(d.species); });
    }

    @@ -171,13 +176,13 @@
    if (brush.empty()) svg.selectAll(".hidden").classed("hidden", false);
    }

    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;
    }

    d3.select(self.frameElement).style("height", size * n + padding + 20 + "px");
    });

    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>
  5. mbostock revised this gist Oct 31, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -41,7 +41,7 @@

    </style>
    <body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
    <script src="//d3js.org/d3.v3.min.js"></script>
    <script>

    var width = 960,
  6. mbostock revised this gist Jun 11, 2015. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -41,7 +41,7 @@

    </style>
    <body>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
    <script>

    var width = 960,
    @@ -67,6 +67,8 @@
    var color = d3.scale.category10();

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

    var domainByTrait = {},
    traits = d3.keys(data[0]).filter(function(d) { return d !== "species"; }),
    n = traits.length;
    @@ -178,4 +180,4 @@
    d3.select(self.frameElement).style("height", size * n + padding + 20 + "px");
    });

    </script>
    </script>
  7. mbostock revised this gist Nov 22, 2013. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1 +1,3 @@
    The scatterplot matrix visualizations pairwise correlations for multi-dimensional data; each cell in the matrix is a scatterplot. This example uses Anderson's data of iris flowers on the Gaspé Peninsula. Scatterplot matrix design invented by J. A. Hartigan; see also [R](http://www.r-project.org/) and [GGobi](http://www.ggobi.org/). Data on *Iris* flowers collected by Edgar Anderson and published by Ronald Fisher.

    See also this simpler static [version without brushing](/mbostock/3213173).
  8. mbostock revised this gist Aug 13, 2013. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -119,6 +119,8 @@
    .attr("dy", ".71em")
    .text(function(d) { return d.x; });

    cell.call(brush);

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

    @@ -139,19 +141,17 @@
    .attr("cy", function(d) { return y(d[p.y]); })
    .attr("r", 3)
    .style("fill", function(d) { return color(d.species); });

    cell.call(brush);
    }

    var brushCell;

    // Clear the previously-active brush, if any.
    function brushstart(p) {
    if (brushCell !== p) {
    cell.call(brush.clear());
    if (brushCell !== this) {
    d3.select(brushCell).call(brush.clear());
    x.domain(domainByTrait[p.x]);
    y.domain(domainByTrait[p.y]);
    brushCell = p;
    brushCell = this;
    }
    }

  9. mbostock revised this gist Nov 13, 2012. 1 changed file with 0 additions and 0 deletions.
    Binary file modified thumbnail.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  10. mbostock revised this gist Nov 13, 2012. 1 changed file with 10 additions and 9 deletions.
    19 changes: 10 additions & 9 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -29,6 +29,10 @@
    fill-opacity: .7;
    }

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

    .extent {
    fill: #000;
    fill-opacity: .125;
    @@ -78,7 +82,7 @@
    .x(x)
    .y(y)
    .on("brushstart", brushstart)
    .on("brush", brush)
    .on("brush", brushmove)
    .on("brushend", brushend);

    var svg = d3.select("body").append("svg")
    @@ -152,20 +156,17 @@
    }

    // Highlight the selected circles.
    function brush(p) {
    function brushmove(p) {
    var e = brush.extent();
    svg.selectAll("circle").attr("class", function(d) {
    return e[0][0] <= d[p.x] && d[p.x] <= e[1][0]
    && e[0][1] <= d[p.y] && d[p.y] <= e[1][1]
    ? d.species : null;
    svg.selectAll("circle").classed("hidden", function(d) {
    return e[0][0] > d[p.x] || d[p.x] > e[1][0]
    || e[0][1] > d[p.y] || d[p.y] > e[1][1];
    });
    }

    // If the brush is empty, select all circles.
    function brushend() {
    if (brush.empty()) svg.selectAll("circle").attr("class", function(d) {
    return d.species;
    });
    if (brush.empty()) svg.selectAll(".hidden").classed("hidden", false);
    }

    function cross(a, b) {
  11. mbostock revised this gist Nov 13, 2012. 1 changed file with 6 additions and 0 deletions.
    6 changes: 6 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -29,6 +29,12 @@
    fill-opacity: .7;
    }

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

    </style>
    <body>
    <script src="http://d3js.org/d3.v3.min.js"></script>
  12. mbostock revised this gist Nov 13, 2012. 1 changed file with 38 additions and 0 deletions.
    38 changes: 38 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -68,6 +68,13 @@
    xAxis.tickSize(size * n);
    yAxis.tickSize(-size * n);

    var brush = d3.svg.brush()
    .x(x)
    .y(y)
    .on("brushstart", brushstart)
    .on("brush", brush)
    .on("brushend", brushend);

    var svg = d3.select("body").append("svg")
    .attr("width", size * n + padding)
    .attr("height", size * n + padding)
    @@ -122,6 +129,37 @@
    .attr("cy", function(d) { return y(d[p.y]); })
    .attr("r", 3)
    .style("fill", function(d) { return color(d.species); });

    cell.call(brush);
    }

    var brushCell;

    // Clear the previously-active brush, if any.
    function brushstart(p) {
    if (brushCell !== p) {
    cell.call(brush.clear());
    x.domain(domainByTrait[p.x]);
    y.domain(domainByTrait[p.y]);
    brushCell = p;
    }
    }

    // Highlight the selected circles.
    function brush(p) {
    var e = brush.extent();
    svg.selectAll("circle").attr("class", function(d) {
    return e[0][0] <= d[p.x] && d[p.x] <= e[1][0]
    && e[0][1] <= d[p.y] && d[p.y] <= e[1][1]
    ? d.species : null;
    });
    }

    // If the brush is empty, select all circles.
    function brushend() {
    if (brush.empty()) svg.selectAll("circle").attr("class", function(d) {
    return d.species;
    });
    }

    function cross(a, b) {
  13. mbostock revised this gist Nov 13, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -72,7 +72,7 @@
    .attr("width", size * n + padding)
    .attr("height", size * n + padding)
    .append("g")
    .attr("transform", "translate(" + padding + ",0)");
    .attr("transform", "translate(" + padding + "," + padding / 2 + ")");

    svg.selectAll(".x.axis")
    .data(traits)
  14. mbostock revised this gist Nov 13, 2012. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -66,11 +66,13 @@
    });

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

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

    svg.selectAll(".x.axis")
    .data(traits)
  15. mbostock revised this gist Nov 13, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -51,7 +51,7 @@

    var yAxis = d3.svg.axis()
    .scale(y)
    .orient("right")
    .orient("left")
    .ticks(5);

    var color = d3.scale.category10();
  16. mbostock revised this gist Nov 13, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -128,7 +128,7 @@
    return c;
    }

    d3.select(self.frameElement).style("height", size * n + padding + "px");
    d3.select(self.frameElement).style("height", size * n + padding + 20 + "px");
    });

    </script>
  17. mbostock revised this gist Nov 13, 2012. 1 changed file with 3 additions and 4 deletions.
    7 changes: 3 additions & 4 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -4,6 +4,7 @@

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

    .axis,
    @@ -68,10 +69,8 @@
    yAxis.tickSize(size * n);

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

    svg.selectAll(".x.axis")
    .data(traits)
  18. mbostock revised this gist Nov 13, 2012. 1 changed file with 25 additions and 21 deletions.
    46 changes: 25 additions & 21 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -33,7 +33,8 @@
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script>

    var size = 150,
    var width = 960,
    size = 150,
    padding = 19.5;

    var x = d3.scale.linear()
    @@ -42,32 +43,35 @@
    var y = d3.scale.linear()
    .range([size - padding / 2, padding / 2]);

    var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .ticks(5);

    var yAxis = d3.svg.axis()
    .scale(y)
    .orient("right")
    .ticks(5);

    var color = d3.scale.category10();

    d3.csv("flowers.csv", function(error, flowers) {
    var traits = d3.keys(flowers[0]).filter(function(d) { return d !== "species"; }),
    d3.csv("flowers.csv", function(error, data) {
    var domainByTrait = {},
    traits = d3.keys(data[0]).filter(function(d) { return d !== "species"; }),
    n = traits.length;

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

    var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .ticks(5)
    .tickSize(size * n);

    var yAxis = d3.svg.axis()
    .scale(y)
    .orient("right")
    .ticks(5)
    .tickSize(size * n);
    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);
    .attr("width", width)
    .attr("height", size * n + padding)
    .append("g")
    .attr("transform", "translate(" + (width - size * n - padding) / 2 + ",0)");

    svg.selectAll(".x.axis")
    .data(traits)
    @@ -100,8 +104,8 @@
    function plot(p) {
    var cell = d3.select(this);

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

    cell.append("rect")
    .attr("class", "frame")
    @@ -111,7 +115,7 @@
    .attr("height", size - padding);

    cell.selectAll("circle")
    .data(flowers)
    .data(data)
    .enter().append("circle")
    .attr("cx", function(d) { return x(d[p.x]); })
    .attr("cy", function(d) { return y(d[p.y]); })
  19. mbostock revised this gist Nov 13, 2012. 2 changed files with 37 additions and 28 deletions.
    1 change: 1 addition & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    The scatterplot matrix visualizations pairwise correlations for multi-dimensional data; each cell in the matrix is a scatterplot. This example uses Anderson's data of iris flowers on the Gaspé Peninsula. Scatterplot matrix design invented by J. A. Hartigan; see also [R](http://www.r-project.org/) and [GGobi](http://www.ggobi.org/). Data on *Iris* flowers collected by Edgar Anderson and published by Ronald Fisher.
    64 changes: 36 additions & 28 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -30,54 +30,59 @@

    </style>
    <body>
    <script src="http://d3js.org/d3.v2.min.js?2.9.6"></script>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script>

    d3.csv("flowers.csv", function(flowers) {
    var size = 150,
    padding = 19.5;

    // Size parameters.
    var size = 150,
    padding = 19.5,
    traits = d3.keys(flowers[0]).filter(function(d) { return d !== "species"; }),
    var x = d3.scale.linear()
    .range([padding / 2, size - padding / 2]);

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

    var color = d3.scale.category10();

    d3.csv("flowers.csv", function(error, flowers) {
    var traits = d3.keys(flowers[0]).filter(function(d) { return d !== "species"; }),
    n = traits.length;

    // Position scales.
    var x = {}, y = {}, z = d3.scale.category10();
    var domainByTrait = {};
    traits.forEach(function(trait) {
    var value = function(d) { return d[trait]; },
    domain = [d3.min(flowers, value), d3.max(flowers, value)],
    range = [padding / 2, size - padding / 2];
    x[trait] = d3.scale.linear().domain(domain).range(range);
    y[trait] = d3.scale.linear().domain(domain).range(range.slice().reverse());
    domainByTrait = d3.extent(flowers, function(d) { return d[trait]; });
    });

    // Axes.
    var axis = d3.svg.axis()
    var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .ticks(5)
    .tickSize(size * n);

    var yAxis = d3.svg.axis()
    .scale(y)
    .orient("right")
    .ticks(5)
    .tickSize(size * n);

    // Root panel.
    var svg = d3.select("body").append("svg")
    .attr("width", size * n + padding)
    .attr("height", size * n + padding);

    // X-axis.
    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) { d3.select(this).call(axis.scale(x[d]).orient("bottom")); });
    .each(function(d) { x.domain(domainByTrait[d]); d3.select(this).call(xAxis); });

    // Y-axis.
    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) { d3.select(this).call(axis.scale(y[d]).orient("right")); });
    .each(function(d) { y.domain(domainByTrait[d]); d3.select(this).call(yAxis); });

    // Cell and plot.
    var cell = svg.selectAll(".cell")
    .data(cross(traits, traits))
    .enter().append("g")
    @@ -95,29 +100,32 @@
    function plot(p) {
    var cell = d3.select(this);

    // Plot frame.
    x.domain(domainByExtent(p.x));
    y.domain(domainByExtent(p.y));

    cell.append("rect")
    .attr("class", "frame")
    .attr("x", padding / 2)
    .attr("y", padding / 2)
    .attr("width", size - padding)
    .attr("height", size - padding);

    // Plot dots.
    cell.selectAll("circle")
    .data(flowers)
    .enter().append("circle")
    .style("fill", function(d) { return z(d.species); })
    .attr("cx", function(d) { return x[p.x](d[p.x]); })
    .attr("cy", function(d) { return y[p.y](d[p.y]); })
    .attr("r", 3);
    .attr("cx", function(d) { return x(d[p.x]); })
    .attr("cy", function(d) { return y(d[p.y]); })
    .attr("r", 3)
    .style("fill", function(d) { return color(d.species); });
    }

    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;
    }

    d3.select(self.frameElement).style("height", size * n + padding + "px");
    });

    </script>
    </script>
  20. mbostock revised this gist Oct 12, 2012. 1 changed file with 0 additions and 0 deletions.
    Binary file added thumbnail.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  21. mbostock revised this gist Jul 31, 2012. 3 changed files with 169 additions and 42 deletions.
    151 changes: 151 additions & 0 deletions flowers.csv
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,151 @@
    sepal length,sepal width,petal length,petal width,species
    5.1,3.5,1.4,0.2,setosa
    4.9,3.0,1.4,0.2,setosa
    4.7,3.2,1.3,0.2,setosa
    4.6,3.1,1.5,0.2,setosa
    5.0,3.6,1.4,0.2,setosa
    5.4,3.9,1.7,0.4,setosa
    4.6,3.4,1.4,0.3,setosa
    5.0,3.4,1.5,0.2,setosa
    4.4,2.9,1.4,0.2,setosa
    4.9,3.1,1.5,0.1,setosa
    5.4,3.7,1.5,0.2,setosa
    4.8,3.4,1.6,0.2,setosa
    4.8,3.0,1.4,0.1,setosa
    4.3,3.0,1.1,0.1,setosa
    5.8,4.0,1.2,0.2,setosa
    5.7,4.4,1.5,0.4,setosa
    5.4,3.9,1.3,0.4,setosa
    5.1,3.5,1.4,0.3,setosa
    5.7,3.8,1.7,0.3,setosa
    5.1,3.8,1.5,0.3,setosa
    5.4,3.4,1.7,0.2,setosa
    5.1,3.7,1.5,0.4,setosa
    4.6,3.6,1.0,0.2,setosa
    5.1,3.3,1.7,0.5,setosa
    4.8,3.4,1.9,0.2,setosa
    5.0,3.0,1.6,0.2,setosa
    5.0,3.4,1.6,0.4,setosa
    5.2,3.5,1.5,0.2,setosa
    5.2,3.4,1.4,0.2,setosa
    4.7,3.2,1.6,0.2,setosa
    4.8,3.1,1.6,0.2,setosa
    5.4,3.4,1.5,0.4,setosa
    5.2,4.1,1.5,0.1,setosa
    5.5,4.2,1.4,0.2,setosa
    4.9,3.1,1.5,0.2,setosa
    5.0,3.2,1.2,0.2,setosa
    5.5,3.5,1.3,0.2,setosa
    4.9,3.6,1.4,0.1,setosa
    4.4,3.0,1.3,0.2,setosa
    5.1,3.4,1.5,0.2,setosa
    5.0,3.5,1.3,0.3,setosa
    4.5,2.3,1.3,0.3,setosa
    4.4,3.2,1.3,0.2,setosa
    5.0,3.5,1.6,0.6,setosa
    5.1,3.8,1.9,0.4,setosa
    4.8,3.0,1.4,0.3,setosa
    5.1,3.8,1.6,0.2,setosa
    4.6,3.2,1.4,0.2,setosa
    5.3,3.7,1.5,0.2,setosa
    5.0,3.3,1.4,0.2,setosa
    7.0,3.2,4.7,1.4,versicolor
    6.4,3.2,4.5,1.5,versicolor
    6.9,3.1,4.9,1.5,versicolor
    5.5,2.3,4.0,1.3,versicolor
    6.5,2.8,4.6,1.5,versicolor
    5.7,2.8,4.5,1.3,versicolor
    6.3,3.3,4.7,1.6,versicolor
    4.9,2.4,3.3,1.0,versicolor
    6.6,2.9,4.6,1.3,versicolor
    5.2,2.7,3.9,1.4,versicolor
    5.0,2.0,3.5,1.0,versicolor
    5.9,3.0,4.2,1.5,versicolor
    6.0,2.2,4.0,1.0,versicolor
    6.1,2.9,4.7,1.4,versicolor
    5.6,2.9,3.6,1.3,versicolor
    6.7,3.1,4.4,1.4,versicolor
    5.6,3.0,4.5,1.5,versicolor
    5.8,2.7,4.1,1.0,versicolor
    6.2,2.2,4.5,1.5,versicolor
    5.6,2.5,3.9,1.1,versicolor
    5.9,3.2,4.8,1.8,versicolor
    6.1,2.8,4.0,1.3,versicolor
    6.3,2.5,4.9,1.5,versicolor
    6.1,2.8,4.7,1.2,versicolor
    6.4,2.9,4.3,1.3,versicolor
    6.6,3.0,4.4,1.4,versicolor
    6.8,2.8,4.8,1.4,versicolor
    6.7,3.0,5.0,1.7,versicolor
    6.0,2.9,4.5,1.5,versicolor
    5.7,2.6,3.5,1.0,versicolor
    5.5,2.4,3.8,1.1,versicolor
    5.5,2.4,3.7,1.0,versicolor
    5.8,2.7,3.9,1.2,versicolor
    6.0,2.7,5.1,1.6,versicolor
    5.4,3.0,4.5,1.5,versicolor
    6.0,3.4,4.5,1.6,versicolor
    6.7,3.1,4.7,1.5,versicolor
    6.3,2.3,4.4,1.3,versicolor
    5.6,3.0,4.1,1.3,versicolor
    5.5,2.5,4.0,1.3,versicolor
    5.5,2.6,4.4,1.2,versicolor
    6.1,3.0,4.6,1.4,versicolor
    5.8,2.6,4.0,1.2,versicolor
    5.0,2.3,3.3,1.0,versicolor
    5.6,2.7,4.2,1.3,versicolor
    5.7,3.0,4.2,1.2,versicolor
    5.7,2.9,4.2,1.3,versicolor
    6.2,2.9,4.3,1.3,versicolor
    5.1,2.5,3.0,1.1,versicolor
    5.7,2.8,4.1,1.3,versicolor
    6.3,3.3,6.0,2.5,virginica
    5.8,2.7,5.1,1.9,virginica
    7.1,3.0,5.9,2.1,virginica
    6.3,2.9,5.6,1.8,virginica
    6.5,3.0,5.8,2.2,virginica
    7.6,3.0,6.6,2.1,virginica
    4.9,2.5,4.5,1.7,virginica
    7.3,2.9,6.3,1.8,virginica
    6.7,2.5,5.8,1.8,virginica
    7.2,3.6,6.1,2.5,virginica
    6.5,3.2,5.1,2.0,virginica
    6.4,2.7,5.3,1.9,virginica
    6.8,3.0,5.5,2.1,virginica
    5.7,2.5,5.0,2.0,virginica
    5.8,2.8,5.1,2.4,virginica
    6.4,3.2,5.3,2.3,virginica
    6.5,3.0,5.5,1.8,virginica
    7.7,3.8,6.7,2.2,virginica
    7.7,2.6,6.9,2.3,virginica
    6.0,2.2,5.0,1.5,virginica
    6.9,3.2,5.7,2.3,virginica
    5.6,2.8,4.9,2.0,virginica
    7.7,2.8,6.7,2.0,virginica
    6.3,2.7,4.9,1.8,virginica
    6.7,3.3,5.7,2.1,virginica
    7.2,3.2,6.0,1.8,virginica
    6.2,2.8,4.8,1.8,virginica
    6.1,3.0,4.9,1.8,virginica
    6.4,2.8,5.6,2.1,virginica
    7.2,3.0,5.8,1.6,virginica
    7.4,2.8,6.1,1.9,virginica
    7.9,3.8,6.4,2.0,virginica
    6.4,2.8,5.6,2.2,virginica
    6.3,2.8,5.1,1.5,virginica
    6.1,2.6,5.6,1.4,virginica
    7.7,3.0,6.1,2.3,virginica
    6.3,3.4,5.6,2.4,virginica
    6.4,3.1,5.5,1.8,virginica
    6.0,3.0,4.8,1.8,virginica
    6.9,3.1,5.4,2.1,virginica
    6.7,3.1,5.6,2.4,virginica
    6.9,3.1,5.1,2.3,virginica
    5.8,2.7,5.1,1.9,virginica
    6.8,3.2,5.9,2.3,virginica
    6.7,3.3,5.7,2.5,virginica
    6.7,3.0,5.2,2.3,virginica
    6.3,2.5,5.0,1.9,virginica
    6.5,3.0,5.2,2.0,virginica
    6.2,3.4,5.4,2.3,virginica
    5.9,3.0,5.1,1.8,virginica
    1 change: 0 additions & 1 deletion flowers.json
    Original file line number Diff line number Diff line change
    @@ -1 +0,0 @@
    {"traits":["sepalLength","sepalWidth","petalLength","petalWidth"],"species":["setosa","versicolor","virginica"],"values":[{"sepalLength":5.1,"sepalWidth":3.5,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.9,"sepalWidth":3.0,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.7,"sepalWidth":3.2,"petalLength":1.3,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.6,"sepalWidth":3.1,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.6,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.4,"sepalWidth":3.9,"petalLength":1.7,"petalWidth":0.4,"species":"setosa"},{"sepalLength":4.6,"sepalWidth":3.4,"petalLength":1.4,"petalWidth":0.3,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.4,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.4,"sepalWidth":2.9,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.9,"sepalWidth":3.1,"petalLength":1.5,"petalWidth":0.1,"species":"setosa"},{"sepalLength":5.4,"sepalWidth":3.7,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.8,"sepalWidth":3.4,"petalLength":1.6,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.8,"sepalWidth":3.0,"petalLength":1.4,"petalWidth":0.1,"species":"setosa"},{"sepalLength":4.3,"sepalWidth":3.0,"petalLength":1.1,"petalWidth":0.1,"species":"setosa"},{"sepalLength":5.8,"sepalWidth":4.0,"petalLength":1.2,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.7,"sepalWidth":4.4,"petalLength":1.5,"petalWidth":0.4,"species":"setosa"},{"sepalLength":5.4,"sepalWidth":3.9,"petalLength":1.3,"petalWidth":0.4,"species":"setosa"},{"sepalLength":5.1,"sepalWidth":3.5,"petalLength":1.4,"petalWidth":0.3,"species":"setosa"},{"sepalLength":5.7,"sepalWidth":3.8,"petalLength":1.7,"petalWidth":0.3,"species":"setosa"},{"sepalLength":5.1,"sepalWidth":3.8,"petalLength":1.5,"petalWidth":0.3,"species":"setosa"},{"sepalLength":5.4,"sepalWidth":3.4,"petalLength":1.7,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.1,"sepalWidth":3.7,"petalLength":1.5,"petalWidth":0.4,"species":"setosa"},{"sepalLength":4.6,"sepalWidth":3.6,"petalLength":1.0,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.1,"sepalWidth":3.3,"petalLength":1.7,"petalWidth":0.5,"species":"setosa"},{"sepalLength":4.8,"sepalWidth":3.4,"petalLength":1.9,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.0,"petalLength":1.6,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.4,"petalLength":1.6,"petalWidth":0.4,"species":"setosa"},{"sepalLength":5.2,"sepalWidth":3.5,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.2,"sepalWidth":3.4,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.7,"sepalWidth":3.2,"petalLength":1.6,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.8,"sepalWidth":3.1,"petalLength":1.6,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.4,"sepalWidth":3.4,"petalLength":1.5,"petalWidth":0.4,"species":"setosa"},{"sepalLength":5.2,"sepalWidth":4.1,"petalLength":1.5,"petalWidth":0.1,"species":"setosa"},{"sepalLength":5.5,"sepalWidth":4.2,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.9,"sepalWidth":3.1,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.2,"petalLength":1.2,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.5,"sepalWidth":3.5,"petalLength":1.3,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.9,"sepalWidth":3.6,"petalLength":1.4,"petalWidth":0.1,"species":"setosa"},{"sepalLength":4.4,"sepalWidth":3.0,"petalLength":1.3,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.1,"sepalWidth":3.4,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.5,"petalLength":1.3,"petalWidth":0.3,"species":"setosa"},{"sepalLength":4.5,"sepalWidth":2.3,"petalLength":1.3,"petalWidth":0.3,"species":"setosa"},{"sepalLength":4.4,"sepalWidth":3.2,"petalLength":1.3,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.5,"petalLength":1.6,"petalWidth":0.6,"species":"setosa"},{"sepalLength":5.1,"sepalWidth":3.8,"petalLength":1.9,"petalWidth":0.4,"species":"setosa"},{"sepalLength":4.8,"sepalWidth":3.0,"petalLength":1.4,"petalWidth":0.3,"species":"setosa"},{"sepalLength":5.1,"sepalWidth":3.8,"petalLength":1.6,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.6,"sepalWidth":3.2,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.3,"sepalWidth":3.7,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.3,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":7.0,"sepalWidth":3.2,"petalLength":4.7,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":6.4,"sepalWidth":3.2,"petalLength":4.5,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":6.9,"sepalWidth":3.1,"petalLength":4.9,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":5.5,"sepalWidth":2.3,"petalLength":4.0,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.5,"sepalWidth":2.8,"petalLength":4.6,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":5.7,"sepalWidth":2.8,"petalLength":4.5,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.3,"sepalWidth":3.3,"petalLength":4.7,"petalWidth":1.6,"species":"versicolor"},{"sepalLength":4.9,"sepalWidth":2.4,"petalLength":3.3,"petalWidth":1.0,"species":"versicolor"},{"sepalLength":6.6,"sepalWidth":2.9,"petalLength":4.6,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":5.2,"sepalWidth":2.7,"petalLength":3.9,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":5.0,"sepalWidth":2.0,"petalLength":3.5,"petalWidth":1.0,"species":"versicolor"},{"sepalLength":5.9,"sepalWidth":3.0,"petalLength":4.2,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":6.0,"sepalWidth":2.2,"petalLength":4.0,"petalWidth":1.0,"species":"versicolor"},{"sepalLength":6.1,"sepalWidth":2.9,"petalLength":4.7,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":5.6,"sepalWidth":2.9,"petalLength":3.6,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.7,"sepalWidth":3.1,"petalLength":4.4,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":5.6,"sepalWidth":3.0,"petalLength":4.5,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":5.8,"sepalWidth":2.7,"petalLength":4.1,"petalWidth":1.0,"species":"versicolor"},{"sepalLength":6.2,"sepalWidth":2.2,"petalLength":4.5,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":5.6,"sepalWidth":2.5,"petalLength":3.9,"petalWidth":1.1,"species":"versicolor"},{"sepalLength":5.9,"sepalWidth":3.2,"petalLength":4.8,"petalWidth":1.8,"species":"versicolor"},{"sepalLength":6.1,"sepalWidth":2.8,"petalLength":4.0,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.3,"sepalWidth":2.5,"petalLength":4.9,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":6.1,"sepalWidth":2.8,"petalLength":4.7,"petalWidth":1.2,"species":"versicolor"},{"sepalLength":6.4,"sepalWidth":2.9,"petalLength":4.3,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.6,"sepalWidth":3.0,"petalLength":4.4,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":6.8,"sepalWidth":2.8,"petalLength":4.8,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":6.7,"sepalWidth":3.0,"petalLength":5.0,"petalWidth":1.7,"species":"versicolor"},{"sepalLength":6.0,"sepalWidth":2.9,"petalLength":4.5,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":5.7,"sepalWidth":2.6,"petalLength":3.5,"petalWidth":1.0,"species":"versicolor"},{"sepalLength":5.5,"sepalWidth":2.4,"petalLength":3.8,"petalWidth":1.1,"species":"versicolor"},{"sepalLength":5.5,"sepalWidth":2.4,"petalLength":3.7,"petalWidth":1.0,"species":"versicolor"},{"sepalLength":5.8,"sepalWidth":2.7,"petalLength":3.9,"petalWidth":1.2,"species":"versicolor"},{"sepalLength":6.0,"sepalWidth":2.7,"petalLength":5.1,"petalWidth":1.6,"species":"versicolor"},{"sepalLength":5.4,"sepalWidth":3.0,"petalLength":4.5,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":6.0,"sepalWidth":3.4,"petalLength":4.5,"petalWidth":1.6,"species":"versicolor"},{"sepalLength":6.7,"sepalWidth":3.1,"petalLength":4.7,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":6.3,"sepalWidth":2.3,"petalLength":4.4,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":5.6,"sepalWidth":3.0,"petalLength":4.1,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":5.5,"sepalWidth":2.5,"petalLength":4.0,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":5.5,"sepalWidth":2.6,"petalLength":4.4,"petalWidth":1.2,"species":"versicolor"},{"sepalLength":6.1,"sepalWidth":3.0,"petalLength":4.6,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":5.8,"sepalWidth":2.6,"petalLength":4.0,"petalWidth":1.2,"species":"versicolor"},{"sepalLength":5.0,"sepalWidth":2.3,"petalLength":3.3,"petalWidth":1.0,"species":"versicolor"},{"sepalLength":5.6,"sepalWidth":2.7,"petalLength":4.2,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":5.7,"sepalWidth":3.0,"petalLength":4.2,"petalWidth":1.2,"species":"versicolor"},{"sepalLength":5.7,"sepalWidth":2.9,"petalLength":4.2,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.2,"sepalWidth":2.9,"petalLength":4.3,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":5.1,"sepalWidth":2.5,"petalLength":3.0,"petalWidth":1.1,"species":"versicolor"},{"sepalLength":5.7,"sepalWidth":2.8,"petalLength":4.1,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.3,"sepalWidth":3.3,"petalLength":6.0,"petalWidth":2.5,"species":"virginica"},{"sepalLength":5.8,"sepalWidth":2.7,"petalLength":5.1,"petalWidth":1.9,"species":"virginica"},{"sepalLength":7.1,"sepalWidth":3.0,"petalLength":5.9,"petalWidth":2.1,"species":"virginica"},{"sepalLength":6.3,"sepalWidth":2.9,"petalLength":5.6,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.5,"sepalWidth":3.0,"petalLength":5.8,"petalWidth":2.2,"species":"virginica"},{"sepalLength":7.6,"sepalWidth":3.0,"petalLength":6.6,"petalWidth":2.1,"species":"virginica"},{"sepalLength":4.9,"sepalWidth":2.5,"petalLength":4.5,"petalWidth":1.7,"species":"virginica"},{"sepalLength":7.3,"sepalWidth":2.9,"petalLength":6.3,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.7,"sepalWidth":2.5,"petalLength":5.8,"petalWidth":1.8,"species":"virginica"},{"sepalLength":7.2,"sepalWidth":3.6,"petalLength":6.1,"petalWidth":2.5,"species":"virginica"},{"sepalLength":6.5,"sepalWidth":3.2,"petalLength":5.1,"petalWidth":2.0,"species":"virginica"},{"sepalLength":6.4,"sepalWidth":2.7,"petalLength":5.3,"petalWidth":1.9,"species":"virginica"},{"sepalLength":6.8,"sepalWidth":3.0,"petalLength":5.5,"petalWidth":2.1,"species":"virginica"},{"sepalLength":5.7,"sepalWidth":2.5,"petalLength":5.0,"petalWidth":2.0,"species":"virginica"},{"sepalLength":5.8,"sepalWidth":2.8,"petalLength":5.1,"petalWidth":2.4,"species":"virginica"},{"sepalLength":6.4,"sepalWidth":3.2,"petalLength":5.3,"petalWidth":2.3,"species":"virginica"},{"sepalLength":6.5,"sepalWidth":3.0,"petalLength":5.5,"petalWidth":1.8,"species":"virginica"},{"sepalLength":7.7,"sepalWidth":3.8,"petalLength":6.7,"petalWidth":2.2,"species":"virginica"},{"sepalLength":7.7,"sepalWidth":2.6,"petalLength":6.9,"petalWidth":2.3,"species":"virginica"},{"sepalLength":6.0,"sepalWidth":2.2,"petalLength":5.0,"petalWidth":1.5,"species":"virginica"},{"sepalLength":6.9,"sepalWidth":3.2,"petalLength":5.7,"petalWidth":2.3,"species":"virginica"},{"sepalLength":5.6,"sepalWidth":2.8,"petalLength":4.9,"petalWidth":2.0,"species":"virginica"},{"sepalLength":7.7,"sepalWidth":2.8,"petalLength":6.7,"petalWidth":2.0,"species":"virginica"},{"sepalLength":6.3,"sepalWidth":2.7,"petalLength":4.9,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.7,"sepalWidth":3.3,"petalLength":5.7,"petalWidth":2.1,"species":"virginica"},{"sepalLength":7.2,"sepalWidth":3.2,"petalLength":6.0,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.2,"sepalWidth":2.8,"petalLength":4.8,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.1,"sepalWidth":3.0,"petalLength":4.9,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.4,"sepalWidth":2.8,"petalLength":5.6,"petalWidth":2.1,"species":"virginica"},{"sepalLength":7.2,"sepalWidth":3.0,"petalLength":5.8,"petalWidth":1.6,"species":"virginica"},{"sepalLength":7.4,"sepalWidth":2.8,"petalLength":6.1,"petalWidth":1.9,"species":"virginica"},{"sepalLength":7.9,"sepalWidth":3.8,"petalLength":6.4,"petalWidth":2.0,"species":"virginica"},{"sepalLength":6.4,"sepalWidth":2.8,"petalLength":5.6,"petalWidth":2.2,"species":"virginica"},{"sepalLength":6.3,"sepalWidth":2.8,"petalLength":5.1,"petalWidth":1.5,"species":"virginica"},{"sepalLength":6.1,"sepalWidth":2.6,"petalLength":5.6,"petalWidth":1.4,"species":"virginica"},{"sepalLength":7.7,"sepalWidth":3.0,"petalLength":6.1,"petalWidth":2.3,"species":"virginica"},{"sepalLength":6.3,"sepalWidth":3.4,"petalLength":5.6,"petalWidth":2.4,"species":"virginica"},{"sepalLength":6.4,"sepalWidth":3.1,"petalLength":5.5,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.0,"sepalWidth":3.0,"petalLength":4.8,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.9,"sepalWidth":3.1,"petalLength":5.4,"petalWidth":2.1,"species":"virginica"},{"sepalLength":6.7,"sepalWidth":3.1,"petalLength":5.6,"petalWidth":2.4,"species":"virginica"},{"sepalLength":6.9,"sepalWidth":3.1,"petalLength":5.1,"petalWidth":2.3,"species":"virginica"},{"sepalLength":5.8,"sepalWidth":2.7,"petalLength":5.1,"petalWidth":1.9,"species":"virginica"},{"sepalLength":6.8,"sepalWidth":3.2,"petalLength":5.9,"petalWidth":2.3,"species":"virginica"},{"sepalLength":6.7,"sepalWidth":3.3,"petalLength":5.7,"petalWidth":2.5,"species":"virginica"},{"sepalLength":6.7,"sepalWidth":3.0,"petalLength":5.2,"petalWidth":2.3,"species":"virginica"},{"sepalLength":6.3,"sepalWidth":2.5,"petalLength":5.0,"petalWidth":1.9,"species":"virginica"},{"sepalLength":6.5,"sepalWidth":3.0,"petalLength":5.2,"petalWidth":2.0,"species":"virginica"},{"sepalLength":6.2,"sepalWidth":3.4,"petalLength":5.4,"petalWidth":2.3,"species":"virginica"},{"sepalLength":5.9,"sepalWidth":3.0,"petalLength":5.1,"petalWidth":1.8,"species":"virginica"}]}
    59 changes: 18 additions & 41 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -6,69 +6,46 @@
    font: 10px sans-serif;
    }

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

    .axis line {
    stroke: #ddd;
    stroke-width: .5px;
    }

    .axis path {
    display: none;
    }

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

    rect.frame {
    fill: #fff;
    fill-opacity: .7;
    .frame {
    fill: none;
    stroke: #aaa;
    }

    circle {
    fill: #ccc;
    fill-opacity: .5;
    }

    .cell text {
    pointer-events: none;
    }

    .setosa {
    fill: #800;
    }

    .versicolor {
    fill: #080;
    }

    .virginica {
    fill: #008;
    fill-opacity: .7;
    }

    </style>
    <body>
    <script src="http://d3js.org/d3.v2.js?2.9.6"></script>
    <script src="http://d3js.org/d3.v2.min.js?2.9.6"></script>
    <script>

    d3.json("flowers.json", function(flower) {
    d3.csv("flowers.csv", function(flowers) {

    // Size parameters.
    var size = 150,
    padding = 19.5,
    n = flower.traits.length;
    traits = d3.keys(flowers[0]).filter(function(d) { return d !== "species"; }),
    n = traits.length;

    // Position scales.
    var x = {}, y = {};
    flower.traits.forEach(function(trait) {
    var x = {}, y = {}, z = d3.scale.category10();
    traits.forEach(function(trait) {
    var value = function(d) { return d[trait]; },
    domain = [d3.min(flower.values, value), d3.max(flower.values, value)],
    domain = [d3.min(flowers, value), d3.max(flowers, value)],
    range = [padding / 2, size - padding / 2];
    x[trait] = d3.scale.linear().domain(domain).range(range);
    y[trait] = d3.scale.linear().domain(domain).range(range.slice().reverse());
    @@ -86,30 +63,30 @@

    // X-axis.
    svg.selectAll(".x.axis")
    .data(flower.traits)
    .data(traits)
    .enter().append("g")
    .attr("class", "x axis")
    .attr("transform", function(d, i) { return "translate(" + (n - i - 1) * size + ",0)"; })
    .each(function(d) { d3.select(this).call(axis.scale(x[d]).orient("bottom")); });

    // Y-axis.
    svg.selectAll(".y.axis")
    .data(flower.traits)
    .data(traits)
    .enter().append("g")
    .attr("class", "y axis")
    .attr("transform", function(d, i) { return "translate(0," + i * size + ")"; })
    .each(function(d) { d3.select(this).call(axis.scale(y[d]).orient("right")); });

    // Cell and plot.
    var cell = svg.selectAll(".cell")
    .data(cross(flower.traits, flower.traits))
    .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")
    cell.filter(function(d) { return d.i === d.j; }).append("text")
    .attr("x", padding)
    .attr("y", padding)
    .attr("dy", ".71em")
    @@ -128,9 +105,9 @@

    // Plot dots.
    cell.selectAll("circle")
    .data(flower.values)
    .data(flowers)
    .enter().append("circle")
    .attr("class", function(d) { return d.species; })
    .style("fill", function(d) { return z(d.species); })
    .attr("cx", function(d) { return x[p.x](d[p.x]); })
    .attr("cy", function(d) { return y[p.y](d[p.y]); })
    .attr("r", 3);
  22. mbostock created this gist Jul 31, 2012.
    1 change: 1 addition & 0 deletions flowers.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    {"traits":["sepalLength","sepalWidth","petalLength","petalWidth"],"species":["setosa","versicolor","virginica"],"values":[{"sepalLength":5.1,"sepalWidth":3.5,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.9,"sepalWidth":3.0,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.7,"sepalWidth":3.2,"petalLength":1.3,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.6,"sepalWidth":3.1,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.6,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.4,"sepalWidth":3.9,"petalLength":1.7,"petalWidth":0.4,"species":"setosa"},{"sepalLength":4.6,"sepalWidth":3.4,"petalLength":1.4,"petalWidth":0.3,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.4,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.4,"sepalWidth":2.9,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.9,"sepalWidth":3.1,"petalLength":1.5,"petalWidth":0.1,"species":"setosa"},{"sepalLength":5.4,"sepalWidth":3.7,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.8,"sepalWidth":3.4,"petalLength":1.6,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.8,"sepalWidth":3.0,"petalLength":1.4,"petalWidth":0.1,"species":"setosa"},{"sepalLength":4.3,"sepalWidth":3.0,"petalLength":1.1,"petalWidth":0.1,"species":"setosa"},{"sepalLength":5.8,"sepalWidth":4.0,"petalLength":1.2,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.7,"sepalWidth":4.4,"petalLength":1.5,"petalWidth":0.4,"species":"setosa"},{"sepalLength":5.4,"sepalWidth":3.9,"petalLength":1.3,"petalWidth":0.4,"species":"setosa"},{"sepalLength":5.1,"sepalWidth":3.5,"petalLength":1.4,"petalWidth":0.3,"species":"setosa"},{"sepalLength":5.7,"sepalWidth":3.8,"petalLength":1.7,"petalWidth":0.3,"species":"setosa"},{"sepalLength":5.1,"sepalWidth":3.8,"petalLength":1.5,"petalWidth":0.3,"species":"setosa"},{"sepalLength":5.4,"sepalWidth":3.4,"petalLength":1.7,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.1,"sepalWidth":3.7,"petalLength":1.5,"petalWidth":0.4,"species":"setosa"},{"sepalLength":4.6,"sepalWidth":3.6,"petalLength":1.0,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.1,"sepalWidth":3.3,"petalLength":1.7,"petalWidth":0.5,"species":"setosa"},{"sepalLength":4.8,"sepalWidth":3.4,"petalLength":1.9,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.0,"petalLength":1.6,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.4,"petalLength":1.6,"petalWidth":0.4,"species":"setosa"},{"sepalLength":5.2,"sepalWidth":3.5,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.2,"sepalWidth":3.4,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.7,"sepalWidth":3.2,"petalLength":1.6,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.8,"sepalWidth":3.1,"petalLength":1.6,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.4,"sepalWidth":3.4,"petalLength":1.5,"petalWidth":0.4,"species":"setosa"},{"sepalLength":5.2,"sepalWidth":4.1,"petalLength":1.5,"petalWidth":0.1,"species":"setosa"},{"sepalLength":5.5,"sepalWidth":4.2,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.9,"sepalWidth":3.1,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.2,"petalLength":1.2,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.5,"sepalWidth":3.5,"petalLength":1.3,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.9,"sepalWidth":3.6,"petalLength":1.4,"petalWidth":0.1,"species":"setosa"},{"sepalLength":4.4,"sepalWidth":3.0,"petalLength":1.3,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.1,"sepalWidth":3.4,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.5,"petalLength":1.3,"petalWidth":0.3,"species":"setosa"},{"sepalLength":4.5,"sepalWidth":2.3,"petalLength":1.3,"petalWidth":0.3,"species":"setosa"},{"sepalLength":4.4,"sepalWidth":3.2,"petalLength":1.3,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.5,"petalLength":1.6,"petalWidth":0.6,"species":"setosa"},{"sepalLength":5.1,"sepalWidth":3.8,"petalLength":1.9,"petalWidth":0.4,"species":"setosa"},{"sepalLength":4.8,"sepalWidth":3.0,"petalLength":1.4,"petalWidth":0.3,"species":"setosa"},{"sepalLength":5.1,"sepalWidth":3.8,"petalLength":1.6,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.6,"sepalWidth":3.2,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.3,"sepalWidth":3.7,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.0,"sepalWidth":3.3,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":7.0,"sepalWidth":3.2,"petalLength":4.7,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":6.4,"sepalWidth":3.2,"petalLength":4.5,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":6.9,"sepalWidth":3.1,"petalLength":4.9,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":5.5,"sepalWidth":2.3,"petalLength":4.0,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.5,"sepalWidth":2.8,"petalLength":4.6,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":5.7,"sepalWidth":2.8,"petalLength":4.5,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.3,"sepalWidth":3.3,"petalLength":4.7,"petalWidth":1.6,"species":"versicolor"},{"sepalLength":4.9,"sepalWidth":2.4,"petalLength":3.3,"petalWidth":1.0,"species":"versicolor"},{"sepalLength":6.6,"sepalWidth":2.9,"petalLength":4.6,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":5.2,"sepalWidth":2.7,"petalLength":3.9,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":5.0,"sepalWidth":2.0,"petalLength":3.5,"petalWidth":1.0,"species":"versicolor"},{"sepalLength":5.9,"sepalWidth":3.0,"petalLength":4.2,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":6.0,"sepalWidth":2.2,"petalLength":4.0,"petalWidth":1.0,"species":"versicolor"},{"sepalLength":6.1,"sepalWidth":2.9,"petalLength":4.7,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":5.6,"sepalWidth":2.9,"petalLength":3.6,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.7,"sepalWidth":3.1,"petalLength":4.4,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":5.6,"sepalWidth":3.0,"petalLength":4.5,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":5.8,"sepalWidth":2.7,"petalLength":4.1,"petalWidth":1.0,"species":"versicolor"},{"sepalLength":6.2,"sepalWidth":2.2,"petalLength":4.5,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":5.6,"sepalWidth":2.5,"petalLength":3.9,"petalWidth":1.1,"species":"versicolor"},{"sepalLength":5.9,"sepalWidth":3.2,"petalLength":4.8,"petalWidth":1.8,"species":"versicolor"},{"sepalLength":6.1,"sepalWidth":2.8,"petalLength":4.0,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.3,"sepalWidth":2.5,"petalLength":4.9,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":6.1,"sepalWidth":2.8,"petalLength":4.7,"petalWidth":1.2,"species":"versicolor"},{"sepalLength":6.4,"sepalWidth":2.9,"petalLength":4.3,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.6,"sepalWidth":3.0,"petalLength":4.4,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":6.8,"sepalWidth":2.8,"petalLength":4.8,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":6.7,"sepalWidth":3.0,"petalLength":5.0,"petalWidth":1.7,"species":"versicolor"},{"sepalLength":6.0,"sepalWidth":2.9,"petalLength":4.5,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":5.7,"sepalWidth":2.6,"petalLength":3.5,"petalWidth":1.0,"species":"versicolor"},{"sepalLength":5.5,"sepalWidth":2.4,"petalLength":3.8,"petalWidth":1.1,"species":"versicolor"},{"sepalLength":5.5,"sepalWidth":2.4,"petalLength":3.7,"petalWidth":1.0,"species":"versicolor"},{"sepalLength":5.8,"sepalWidth":2.7,"petalLength":3.9,"petalWidth":1.2,"species":"versicolor"},{"sepalLength":6.0,"sepalWidth":2.7,"petalLength":5.1,"petalWidth":1.6,"species":"versicolor"},{"sepalLength":5.4,"sepalWidth":3.0,"petalLength":4.5,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":6.0,"sepalWidth":3.4,"petalLength":4.5,"petalWidth":1.6,"species":"versicolor"},{"sepalLength":6.7,"sepalWidth":3.1,"petalLength":4.7,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":6.3,"sepalWidth":2.3,"petalLength":4.4,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":5.6,"sepalWidth":3.0,"petalLength":4.1,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":5.5,"sepalWidth":2.5,"petalLength":4.0,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":5.5,"sepalWidth":2.6,"petalLength":4.4,"petalWidth":1.2,"species":"versicolor"},{"sepalLength":6.1,"sepalWidth":3.0,"petalLength":4.6,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":5.8,"sepalWidth":2.6,"petalLength":4.0,"petalWidth":1.2,"species":"versicolor"},{"sepalLength":5.0,"sepalWidth":2.3,"petalLength":3.3,"petalWidth":1.0,"species":"versicolor"},{"sepalLength":5.6,"sepalWidth":2.7,"petalLength":4.2,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":5.7,"sepalWidth":3.0,"petalLength":4.2,"petalWidth":1.2,"species":"versicolor"},{"sepalLength":5.7,"sepalWidth":2.9,"petalLength":4.2,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.2,"sepalWidth":2.9,"petalLength":4.3,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":5.1,"sepalWidth":2.5,"petalLength":3.0,"petalWidth":1.1,"species":"versicolor"},{"sepalLength":5.7,"sepalWidth":2.8,"petalLength":4.1,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.3,"sepalWidth":3.3,"petalLength":6.0,"petalWidth":2.5,"species":"virginica"},{"sepalLength":5.8,"sepalWidth":2.7,"petalLength":5.1,"petalWidth":1.9,"species":"virginica"},{"sepalLength":7.1,"sepalWidth":3.0,"petalLength":5.9,"petalWidth":2.1,"species":"virginica"},{"sepalLength":6.3,"sepalWidth":2.9,"petalLength":5.6,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.5,"sepalWidth":3.0,"petalLength":5.8,"petalWidth":2.2,"species":"virginica"},{"sepalLength":7.6,"sepalWidth":3.0,"petalLength":6.6,"petalWidth":2.1,"species":"virginica"},{"sepalLength":4.9,"sepalWidth":2.5,"petalLength":4.5,"petalWidth":1.7,"species":"virginica"},{"sepalLength":7.3,"sepalWidth":2.9,"petalLength":6.3,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.7,"sepalWidth":2.5,"petalLength":5.8,"petalWidth":1.8,"species":"virginica"},{"sepalLength":7.2,"sepalWidth":3.6,"petalLength":6.1,"petalWidth":2.5,"species":"virginica"},{"sepalLength":6.5,"sepalWidth":3.2,"petalLength":5.1,"petalWidth":2.0,"species":"virginica"},{"sepalLength":6.4,"sepalWidth":2.7,"petalLength":5.3,"petalWidth":1.9,"species":"virginica"},{"sepalLength":6.8,"sepalWidth":3.0,"petalLength":5.5,"petalWidth":2.1,"species":"virginica"},{"sepalLength":5.7,"sepalWidth":2.5,"petalLength":5.0,"petalWidth":2.0,"species":"virginica"},{"sepalLength":5.8,"sepalWidth":2.8,"petalLength":5.1,"petalWidth":2.4,"species":"virginica"},{"sepalLength":6.4,"sepalWidth":3.2,"petalLength":5.3,"petalWidth":2.3,"species":"virginica"},{"sepalLength":6.5,"sepalWidth":3.0,"petalLength":5.5,"petalWidth":1.8,"species":"virginica"},{"sepalLength":7.7,"sepalWidth":3.8,"petalLength":6.7,"petalWidth":2.2,"species":"virginica"},{"sepalLength":7.7,"sepalWidth":2.6,"petalLength":6.9,"petalWidth":2.3,"species":"virginica"},{"sepalLength":6.0,"sepalWidth":2.2,"petalLength":5.0,"petalWidth":1.5,"species":"virginica"},{"sepalLength":6.9,"sepalWidth":3.2,"petalLength":5.7,"petalWidth":2.3,"species":"virginica"},{"sepalLength":5.6,"sepalWidth":2.8,"petalLength":4.9,"petalWidth":2.0,"species":"virginica"},{"sepalLength":7.7,"sepalWidth":2.8,"petalLength":6.7,"petalWidth":2.0,"species":"virginica"},{"sepalLength":6.3,"sepalWidth":2.7,"petalLength":4.9,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.7,"sepalWidth":3.3,"petalLength":5.7,"petalWidth":2.1,"species":"virginica"},{"sepalLength":7.2,"sepalWidth":3.2,"petalLength":6.0,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.2,"sepalWidth":2.8,"petalLength":4.8,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.1,"sepalWidth":3.0,"petalLength":4.9,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.4,"sepalWidth":2.8,"petalLength":5.6,"petalWidth":2.1,"species":"virginica"},{"sepalLength":7.2,"sepalWidth":3.0,"petalLength":5.8,"petalWidth":1.6,"species":"virginica"},{"sepalLength":7.4,"sepalWidth":2.8,"petalLength":6.1,"petalWidth":1.9,"species":"virginica"},{"sepalLength":7.9,"sepalWidth":3.8,"petalLength":6.4,"petalWidth":2.0,"species":"virginica"},{"sepalLength":6.4,"sepalWidth":2.8,"petalLength":5.6,"petalWidth":2.2,"species":"virginica"},{"sepalLength":6.3,"sepalWidth":2.8,"petalLength":5.1,"petalWidth":1.5,"species":"virginica"},{"sepalLength":6.1,"sepalWidth":2.6,"petalLength":5.6,"petalWidth":1.4,"species":"virginica"},{"sepalLength":7.7,"sepalWidth":3.0,"petalLength":6.1,"petalWidth":2.3,"species":"virginica"},{"sepalLength":6.3,"sepalWidth":3.4,"petalLength":5.6,"petalWidth":2.4,"species":"virginica"},{"sepalLength":6.4,"sepalWidth":3.1,"petalLength":5.5,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.0,"sepalWidth":3.0,"petalLength":4.8,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.9,"sepalWidth":3.1,"petalLength":5.4,"petalWidth":2.1,"species":"virginica"},{"sepalLength":6.7,"sepalWidth":3.1,"petalLength":5.6,"petalWidth":2.4,"species":"virginica"},{"sepalLength":6.9,"sepalWidth":3.1,"petalLength":5.1,"petalWidth":2.3,"species":"virginica"},{"sepalLength":5.8,"sepalWidth":2.7,"petalLength":5.1,"petalWidth":1.9,"species":"virginica"},{"sepalLength":6.8,"sepalWidth":3.2,"petalLength":5.9,"petalWidth":2.3,"species":"virginica"},{"sepalLength":6.7,"sepalWidth":3.3,"petalLength":5.7,"petalWidth":2.5,"species":"virginica"},{"sepalLength":6.7,"sepalWidth":3.0,"petalLength":5.2,"petalWidth":2.3,"species":"virginica"},{"sepalLength":6.3,"sepalWidth":2.5,"petalLength":5.0,"petalWidth":1.9,"species":"virginica"},{"sepalLength":6.5,"sepalWidth":3.0,"petalLength":5.2,"petalWidth":2.0,"species":"virginica"},{"sepalLength":6.2,"sepalWidth":3.4,"petalLength":5.4,"petalWidth":2.3,"species":"virginica"},{"sepalLength":5.9,"sepalWidth":3.0,"petalLength":5.1,"petalWidth":1.8,"species":"virginica"}]}
    146 changes: 146 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,146 @@
    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>

    svg {
    font: 10px sans-serif;
    }

    .axis {
    shape-rendering: crispEdges;
    }

    .axis line {
    stroke: #ddd;
    stroke-width: .5px;
    }

    .axis path {
    display: none;
    }

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

    rect.frame {
    fill: #fff;
    fill-opacity: .7;
    stroke: #aaa;
    }

    circle {
    fill: #ccc;
    fill-opacity: .5;
    }

    .cell text {
    pointer-events: none;
    }

    .setosa {
    fill: #800;
    }

    .versicolor {
    fill: #080;
    }

    .virginica {
    fill: #008;
    }

    </style>
    <body>
    <script src="http://d3js.org/d3.v2.js?2.9.6"></script>
    <script>

    d3.json("flowers.json", function(flower) {

    // Size parameters.
    var size = 150,
    padding = 19.5,
    n = flower.traits.length;

    // Position scales.
    var x = {}, y = {};
    flower.traits.forEach(function(trait) {
    var value = function(d) { return d[trait]; },
    domain = [d3.min(flower.values, value), d3.max(flower.values, value)],
    range = [padding / 2, size - padding / 2];
    x[trait] = d3.scale.linear().domain(domain).range(range);
    y[trait] = d3.scale.linear().domain(domain).range(range.slice().reverse());
    });

    // Axes.
    var axis = d3.svg.axis()
    .ticks(5)
    .tickSize(size * n);

    // Root panel.
    var svg = d3.select("body").append("svg")
    .attr("width", size * n + padding)
    .attr("height", size * n + padding);

    // X-axis.
    svg.selectAll(".x.axis")
    .data(flower.traits)
    .enter().append("g")
    .attr("class", "x axis")
    .attr("transform", function(d, i) { return "translate(" + (n - i - 1) * size + ",0)"; })
    .each(function(d) { d3.select(this).call(axis.scale(x[d]).orient("bottom")); });

    // Y-axis.
    svg.selectAll(".y.axis")
    .data(flower.traits)
    .enter().append("g")
    .attr("class", "y axis")
    .attr("transform", function(d, i) { return "translate(0," + i * size + ")"; })
    .each(function(d) { d3.select(this).call(axis.scale(y[d]).orient("right")); });

    // Cell and plot.
    var cell = svg.selectAll(".cell")
    .data(cross(flower.traits, flower.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", padding)
    .attr("y", padding)
    .attr("dy", ".71em")
    .text(function(d) { return d.x; });

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

    // Plot frame.
    cell.append("rect")
    .attr("class", "frame")
    .attr("x", padding / 2)
    .attr("y", padding / 2)
    .attr("width", size - padding)
    .attr("height", size - padding);

    // Plot dots.
    cell.selectAll("circle")
    .data(flower.values)
    .enter().append("circle")
    .attr("class", function(d) { return d.species; })
    .attr("cx", function(d) { return x[p.x](d[p.x]); })
    .attr("cy", function(d) { return y[p.y](d[p.y]); })
    .attr("r", 3);
    }

    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>