将d3交互式矩阵散点图更新到v4的问题 [英] Issue with updating d3 interactive matrix scatterplot to v4

查看:112
本文介绍了将d3交互式矩阵散点图更新到v4的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过将各种我感兴趣的v3脚本更新到v4来提高D3.js的技能,但是在尝试移植" Mike Bostok在此处发布的交互式散点图矩阵时遇到了麻烦: https://bl.ocks.org/mbostock/4063663

I'm trying to improve my skills with D3.js by updating various v3 scripts I'm interested in to v4, but I got stuck while trying to "port" the interactive scatterplot matrix that Mike Bostok posted here: https://bl.ocks.org/mbostock/4063663

虽然我毫无问题地移植了静态版本的代码(没有画笔),但是当尝试以与v3中相同的方式实现画笔时,我发现了一个实际的D3问题,而不仅仅是一个问题.与我的D3新手有关:笔刷似乎粘在散点图矩阵的错误单元格上! 特别是,如果我删除了brushmove部件,并且只是登录以控制数量p.i和p.j(它们确定了要在散点图矩阵中进行刷涂的单元格),那么我的i = 3索引就会卡住.

While I've ported with no problem the static version of the code (with no brush), when trying to implement the brush in the same fashion as in v3, I have found an issue that seems an actual D3 problem more than being related to my D3 noob-ness: brush seems to stick on the wrong cell on the scatterplot matrix! In particular, if I remove the brushmove part and I just log to console the quantities p.i and p.j (which identify which cell in the scatterplot matrix we are brushing on), I got a stuck i = 3 index.

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

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(6);

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

var color = d3.scaleOrdinal(d3.schemeCategory10);

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

data = iris;

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

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

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

var brush = d3.brush()
  .on("start", brushstart)
  .on("brush", brushmove)
  .on("end", brushend);

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]); 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", padding)
  .attr("y", padding)
  .attr("dy", ".71em")
  .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")
    .attr("x", padding / 2)
    .attr("y", padding / 2)
    .attr("width", size - padding)
    .attr("height", size - padding);

  cell.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", 4)
    .style("fill", function(d) { return color(d.species); });
}

var brushCell;

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

// Highlight the selected circles.
function brushmove(p) {
  // ??
  console.log(p.i +" " + p.j)
}

// If the brush is empty, select all circles.
function brushend(p) {
  if (!d3.event.selection) 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;
}

该代码以及虹膜对象也将在JSFiddle上进行审查: https://jsfiddle. net/fabio_p/pmpjawmm/

The code is up for review at JSFiddle as well together with the iris object: https://jsfiddle.net/fabio_p/pmpjawmm/

请注意,在函数brushstart中定义的变量brushcell也是错误的(建议这是传递给brush函数的"this"是错误的)

Notice that the variable brushcell defined in function brushstart is the wrong one as well (suggesting that it's the "this" passed to the brush functions to be wrong)

即使很奇怪(至少在我的经验不足的人看来),如果我更改添加单元格的顺序,事情似乎也会以更好的方式进行,如您在另一个小提琴中看到的: https://jsfiddle.net/fabio_p/7pf4cqrg/ 在这里,我只是在第220行更改了索引(并在第206行更改了标度的一致性),而索引i不再停留在3 ......

Even weirder (at least to my unexperienced eyes), things seem to go in a better way if I change the order in which I add cells, as you can see at this other fiddle: https://jsfiddle.net/fabio_p/7pf4cqrg/ Here I just changed indexes at line 220 (and for scale consistency at line 206), and the index i is not stuck anymore at 3...

关于我在做什么错或D3在哪里出错的任何见解?

Any insights about what I'm doing wrong or where is D3 going wrong?

推荐答案

d3没问题,您的代码中只有两个小问题.

No problems with d3, you just have two minor problems in your code.

1)从v3过渡到v4(如

1) The move from v3 to v4 (as noted in the CHANGELOG) added the .extent() method for denoting the selection area. The default extent falls back to the size of the svg. If you look at each of your overlay objects they are the size of the entire svg document, that is what is causing your indexing to be wonky. The simple fix is to set the extent,

var brush = d3.brush()
  .on("start", brushstart)
  .on("brush", brushmove)
  .on("end", brushend)
  .extent([[0, 0], [size, size]]);

现在,当您进行选择时,区域再次局限于每个图形,并且它们具有正确的索引.

Now when you do your selections, the area is again limited to each graph and they have the correct indexes.

问题2) 由于从使用比例转换为使用坐标,您需要将选择范围内的绝对坐标转换为您的比例,如上面链接的更改日志中所述,可以在定义的比例上使用.invert()来完成.

Problem 2) Due to the change from using a scale to using coordinates, you need to translate the absolute coordinate within the selection to your scale, as noted in the change log linked above, this can be done using .invert() on the defined scales.

 // Highlight the selected circles.
function brushmove(p) {
 if(d3.event.selection){
  var e = d3.event.selection;
  svg.selectAll("circle").classed("hidden", function(d) {
   return x.invert(e[0][0]) > d[p.x] || x.invert(e[1][0]) < d[p.x] 
   || y.invert(e[0][1]) < d[p.y] || y.invert(e[1][1]) > d[p.y];
  });
 }
}


插入这两个修复程序可以使我们恢复到正确的功能,


Putting these two fixes in gets us back to the correct functionality,

iris = [{
  "sepal.length": "5.1",
  "sepal.width": "3.5",
  "petal.length": "1.4",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "4.9",
  "sepal.width": "3",
  "petal.length": "1.4",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "4.7",
  "sepal.width": "3.2",
  "petal.length": "1.3",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "4.6",
  "sepal.width": "3.1",
  "petal.length": "1.5",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5",
  "sepal.width": "3.6",
  "petal.length": "1.4",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "4.9",
  "sepal.width": "3.1",
  "petal.length": "1.5",
  "petal.width": "0.1",
  "species": "setosa"
}, {
  "sepal.length": "5.4",
  "sepal.width": "3.7",
  "petal.length": "1.5",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "4.8",
  "sepal.width": "3.4",
  "petal.length": "1.6",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "4.8",
  "sepal.width": "3",
  "petal.length": "1.4",
  "petal.width": "0.1",
  "species": "setosa"
}, {
  "sepal.length": "4.3",
  "sepal.width": "3",
  "petal.length": "1.1",
  "petal.width": "0.1",
  "species": "setosa"
}, {
  "sepal.length": "5.8",
  "sepal.width": "4",
  "petal.length": "1.2",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5.7",
  "sepal.width": "4.4",
  "petal.length": "1.5",
  "petal.width": "0.4",
  "species": "setosa"
}, {
  "sepal.length": "5.4",
  "sepal.width": "3.9",
  "petal.length": "1.3",
  "petal.width": "0.4",
  "species": "setosa"
}, {
  "sepal.length": "5.1",
  "sepal.width": "3.5",
  "petal.length": "1.4",
  "petal.width": "0.3",
  "species": "setosa"
}, {
  "sepal.length": "5.7",
  "sepal.width": "3.8",
  "petal.length": "1.7",
  "petal.width": "0.3",
  "species": "setosa"
}, {
  "sepal.length": "5.1",
  "sepal.width": "3.8",
  "petal.length": "1.5",
  "petal.width": "0.3",
  "species": "setosa"
}, {
  "sepal.length": "5.4",
  "sepal.width": "3.4",
  "petal.length": "1.7",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5.1",
  "sepal.width": "3.7",
  "petal.length": "1.5",
  "petal.width": "0.4",
  "species": "setosa"
}, {
  "sepal.length": "4.6",
  "sepal.width": "3.6",
  "petal.length": "1",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5.1",
  "sepal.width": "3.3",
  "petal.length": "1.7",
  "petal.width": "0.5",
  "species": "setosa"
}, {
  "sepal.length": "4.8",
  "sepal.width": "3.4",
  "petal.length": "1.9",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5",
  "sepal.width": "3",
  "petal.length": "1.6",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5",
  "sepal.width": "3.4",
  "petal.length": "1.6",
  "petal.width": "0.4",
  "species": "setosa"
}, {
  "sepal.length": "5.2",
  "sepal.width": "3.5",
  "petal.length": "1.5",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5.2",
  "sepal.width": "3.4",
  "petal.length": "1.4",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "4.7",
  "sepal.width": "3.2",
  "petal.length": "1.6",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "4.8",
  "sepal.width": "3.1",
  "petal.length": "1.6",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5.4",
  "sepal.width": "3.4",
  "petal.length": "1.5",
  "petal.width": "0.4",
  "species": "setosa"
}, {
  "sepal.length": "5.2",
  "sepal.width": "4.1",
  "petal.length": "1.5",
  "petal.width": "0.1",
  "species": "setosa"
}, {
  "sepal.length": "5.5",
  "sepal.width": "4.2",
  "petal.length": "1.4",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "4.9",
  "sepal.width": "3.1",
  "petal.length": "1.5",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5",
  "sepal.width": "3.2",
  "petal.length": "1.2",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5.5",
  "sepal.width": "3.5",
  "petal.length": "1.3",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "4.9",
  "sepal.width": "3.6",
  "petal.length": "1.4",
  "petal.width": "0.1",
  "species": "setosa"
}, {
  "sepal.length": "4.4",
  "sepal.width": "3",
  "petal.length": "1.3",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5.1",
  "sepal.width": "3.4",
  "petal.length": "1.5",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5",
  "sepal.width": "3.5",
  "petal.length": "1.3",
  "petal.width": "0.3",
  "species": "setosa"
}, {
  "sepal.length": "4.5",
  "sepal.width": "2.3",
  "petal.length": "1.3",
  "petal.width": "0.3",
  "species": "setosa"
}, {
  "sepal.length": "4.4",
  "sepal.width": "3.2",
  "petal.length": "1.3",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5",
  "sepal.width": "3.5",
  "petal.length": "1.6",
  "petal.width": "0.6",
  "species": "setosa"
}, {
  "sepal.length": "5.1",
  "sepal.width": "3.8",
  "petal.length": "1.9",
  "petal.width": "0.4",
  "species": "setosa"
}, {
  "sepal.length": "4.8",
  "sepal.width": "3",
  "petal.length": "1.4",
  "petal.width": "0.3",
  "species": "setosa"
}, {
  "sepal.length": "5.1",
  "sepal.width": "3.8",
  "petal.length": "1.6",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "4.6",
  "sepal.width": "3.2",
  "petal.length": "1.4",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5.3",
  "sepal.width": "3.7",
  "petal.length": "1.5",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "5",
  "sepal.width": "3.3",
  "petal.length": "1.4",
  "petal.width": "0.2",
  "species": "setosa"
}, {
  "sepal.length": "7",
  "sepal.width": "3.2",
  "petal.length": "4.7",
  "petal.width": "1.4",
  "species": "versicolor"
}, {
  "sepal.length": "6.4",
  "sepal.width": "3.2",
  "petal.length": "4.5",
  "petal.width": "1.5",
  "species": "versicolor"
}, {
  "sepal.length": "6.9",
  "sepal.width": "3.1",
  "petal.length": "4.9",
  "petal.width": "1.5",
  "species": "versicolor"
}, {
  "sepal.length": "5.5",
  "sepal.width": "2.3",
  "petal.length": "4",
  "petal.width": "1.3",
  "species": "versicolor"
}, {
  "sepal.length": "6.5",
  "sepal.width": "2.8",
  "petal.length": "4.6",
  "petal.width": "1.5",
  "species": "versicolor"
}, {
  "sepal.length": "5.7",
  "sepal.width": "2.8",
  "petal.length": "4.5",
  "petal.width": "1.3",
  "species": "versicolor"
}, {
  "sepal.length": "6.3",
  "sepal.width": "3.3",
  "petal.length": "4.7",
  "petal.width": "1.6",
  "species": "versicolor"
}, {
  "sepal.length": "4.9",
  "sepal.width": "2.4",
  "petal.length": "3.3",
  "petal.width": "1",
  "species": "versicolor"
}, {
  "sepal.length": "6.6",
  "sepal.width": "2.9",
  "petal.length": "4.6",
  "petal.width": "1.3",
  "species": "versicolor"
}, {
  "sepal.length": "5.2",
  "sepal.width": "2.7",
  "petal.length": "3.9",
  "petal.width": "1.4",
  "species": "versicolor"
}, {
  "sepal.length": "5",
  "sepal.width": "2",
  "petal.length": "3.5",
  "petal.width": "1",
  "species": "versicolor"
}, {
  "sepal.length": "5.9",
  "sepal.width": "3",
  "petal.length": "4.2",
  "petal.width": "1.5",
  "species": "versicolor"
}, {
  "sepal.length": "6",
  "sepal.width": "2.2",
  "petal.length": "4",
  "petal.width": "1",
  "species": "versicolor"
}, {
  "sepal.length": "6.1",
  "sepal.width": "2.9",
  "petal.length": "4.7",
  "petal.width": "1.4",
  "species": "versicolor"
}, {
  "sepal.length": "5.6",
  "sepal.width": "2.9",
  "petal.length": "3.6",
  "petal.width": "1.3",
  "species": "versicolor"
}, {
  "sepal.length": "6.7",
  "sepal.width": "3.1",
  "petal.length": "4.4",
  "petal.width": "1.4",
  "species": "versicolor"
}, {
  "sepal.length": "5.6",
  "sepal.width": "3",
  "petal.length": "4.5",
  "petal.width": "1.5",
  "species": "versicolor"
}, {
  "sepal.length": "5.8",
  "sepal.width": "2.7",
  "petal.length": "4.1",
  "petal.width": "1",
  "species": "versicolor"
}, {
  "sepal.length": "6.2",
  "sepal.width": "2.2",
  "petal.length": "4.5",
  "petal.width": "1.5",
  "species": "versicolor"
}, {
  "sepal.length": "5.6",
  "sepal.width": "2.5",
  "petal.length": "3.9",
  "petal.width": "1.1",
  "species": "versicolor"
}, {
  "sepal.length": "5.9",
  "sepal.width": "3.2",
  "petal.length": "4.8",
  "petal.width": "1.8",
  "species": "versicolor"
}, {
  "sepal.length": "6.1",
  "sepal.width": "2.8",
  "petal.length": "4",
  "petal.width": "1.3",
  "species": "versicolor"
}, {
  "sepal.length": "6.3",
  "sepal.width": "2.5",
  "petal.length": "4.9",
  "petal.width": "1.5",
  "species": "versicolor"
}, {
  "sepal.length": "6.1",
  "sepal.width": "2.8",
  "petal.length": "4.7",
  "petal.width": "1.2",
  "species": "versicolor"
}, {
  "sepal.length": "6.4",
  "sepal.width": "2.9",
  "petal.length": "4.3",
  "petal.width": "1.3",
  "species": "versicolor"
}, {
  "sepal.length": "6.6",
  "sepal.width": "3",
  "petal.length": "4.4",
  "petal.width": "1.4",
  "species": "versicolor"
}, {
  "sepal.length": "6.8",
  "sepal.width": "2.8",
  "petal.length": "4.8",
  "petal.width": "1.4",
  "species": "versicolor"
}, {
  "sepal.length": "6.7",
  "sepal.width": "3",
  "petal.length": "5",
  "petal.width": "1.7",
  "species": "versicolor"
}, {
  "sepal.length": "6",
  "sepal.width": "2.9",
  "petal.length": "4.5",
  "petal.width": "1.5",
  "species": "versicolor"
}, {
  "sepal.length": "5.7",
  "sepal.width": "2.6",
  "petal.length": "3.5",
  "petal.width": "1",
  "species": "versicolor"
}, {
  "sepal.length": "5.5",
  "sepal.width": "2.4",
  "petal.length": "3.8",
  "petal.width": "1.1",
  "species": "versicolor"
}, {
  "sepal.length": "5.5",
  "sepal.width": "2.4",
  "petal.length": "3.7",
  "petal.width": "1",
  "species": "versicolor"
}, {
  "sepal.length": "5.8",
  "sepal.width": "2.7",
  "petal.length": "3.9",
  "petal.width": "1.2",
  "species": "versicolor"
}, {
  "sepal.length": "6",
  "sepal.width": "2.7",
  "petal.length": "5.1",
  "petal.width": "1.6",
  "species": "versicolor"
}, {
  "sepal.length": "5.4",
  "sepal.width": "3",
  "petal.length": "4.5",
  "petal.width": "1.5",
  "species": "versicolor"
}, {
  "sepal.length": "6",
  "sepal.width": "3.4",
  "petal.length": "4.5",
  "petal.width": "1.6",
  "species": "versicolor"
}, {
  "sepal.length": "6.7",
  "sepal.width": "3.1",
  "petal.length": "4.7",
  "petal.width": "1.5",
  "species": "versicolor"
}, {
  "sepal.length": "6.3",
  "sepal.width": "2.3",
  "petal.length": "4.4",
  "petal.width": "1.3",
  "species": "versicolor"
}, {
  "sepal.length": "5.6",
  "sepal.width": "3",
  "petal.length": "4.1",
  "petal.width": "1.3",
  "species": "versicolor"
}, {
  "sepal.length": "5.5",
  "sepal.width": "2.5",
  "petal.length": "4",
  "petal.width": "1.3",
  "species": "versicolor"
}, {
  "sepal.length": "5.5",
  "sepal.width": "2.6",
  "petal.length": "4.4",
  "petal.width": "1.2",
  "species": "versicolor"
}, {
  "sepal.length": "6.1",
  "sepal.width": "3",
  "petal.length": "4.6",
  "petal.width": "1.4",
  "species": "versicolor"
}, {
  "sepal.length": "5.8",
  "sepal.width": "2.6",
  "petal.length": "4",
  "petal.width": "1.2",
  "species": "versicolor"
}, {
  "sepal.length": "5",
  "sepal.width": "2.3",
  "petal.length": "3.3",
  "petal.width": "1",
  "species": "versicolor"
}, {
  "sepal.length": "5.6",
  "sepal.width": "2.7",
  "petal.length": "4.2",
  "petal.width": "1.3",
  "species": "versicolor"
}, {
  "sepal.length": "5.7",
  "sepal.width": "3",
  "petal.length": "4.2",
  "petal.width": "1.2",
  "species": "versicolor"
}, {
  "sepal.length": "5.7",
  "sepal.width": "2.9",
  "petal.length": "4.2",
  "petal.width": "1.3",
  "species": "versicolor"
}, {
  "sepal.length": "6.2",
  "sepal.width": "2.9",
  "petal.length": "4.3",
  "petal.width": "1.3",
  "species": "versicolor"
}, {
  "sepal.length": "5.1",
  "sepal.width": "2.5",
  "petal.length": "3",
  "petal.width": "1.1",
  "species": "versicolor"
}, {
  "sepal.length": "5.7",
  "sepal.width": "2.8",
  "petal.length": "4.1",
  "petal.width": "1.3",
  "species": "versicolor"
}, {
  "sepal.length": "6.3",
  "sepal.width": "3.3",
  "petal.length": "6",
  "petal.width": "2.5",
  "species": "virginica"
}, {
  "sepal.length": "5.8",
  "sepal.width": "2.7",
  "petal.length": "5.1",
  "petal.width": "1.9",
  "species": "virginica"
}, {
  "sepal.length": "7.1",
  "sepal.width": "3",
  "petal.length": "5.9",
  "petal.width": "2.1",
  "species": "virginica"
}, {
  "sepal.length": "6.3",
  "sepal.width": "2.9",
  "petal.length": "5.6",
  "petal.width": "1.8",
  "species": "virginica"
}, {
  "sepal.length": "6.5",
  "sepal.width": "3",
  "petal.length": "5.8",
  "petal.width": "2.2",
  "species": "virginica"
}, {
  "sepal.length": "7.6",
  "sepal.width": "3",
  "petal.length": "6.6",
  "petal.width": "2.1",
  "species": "virginica"
}, {
  "sepal.length": "4.9",
  "sepal.width": "2.5",
  "petal.length": "4.5",
  "petal.width": "1.7",
  "species": "virginica"
}, {
  "sepal.length": "7.3",
  "sepal.width": "2.9",
  "petal.length": "6.3",
  "petal.width": "1.8",
  "species": "virginica"
}, {
  "sepal.length": "6.7",
  "sepal.width": "2.5",
  "petal.length": "5.8",
  "petal.width": "1.8",
  "species": "virginica"
}, {
  "sepal.length": "7.2",
  "sepal.width": "3.6",
  "petal.length": "6.1",
  "petal.width": "2.5",
  "species": "virginica"
}, {
  "sepal.length": "6.5",
  "sepal.width": "3.2",
  "petal.length": "5.1",
  "petal.width": "2",
  "species": "virginica"
}, {
  "sepal.length": "6.4",
  "sepal.width": "2.7",
  "petal.length": "5.3",
  "petal.width": "1.9",
  "species": "virginica"
}, {
  "sepal.length": "6.8",
  "sepal.width": "3",
  "petal.length": "5.5",
  "petal.width": "2.1",
  "species": "virginica"
}, {
  "sepal.length": "5.7",
  "sepal.width": "2.5",
  "petal.length": "5",
  "petal.width": "2",
  "species": "virginica"
}, {
  "sepal.length": "5.8",
  "sepal.width": "2.8",
  "petal.length": "5.1",
  "petal.width": "2.4",
  "species": "virginica"
}, {
  "sepal.length": "6.4",
  "sepal.width": "3.2",
  "petal.length": "5.3",
  "petal.width": "2.3",
  "species": "virginica"
}, {
  "sepal.length": "6.5",
  "sepal.width": "3",
  "petal.length": "5.5",
  "petal.width": "1.8",
  "species": "virginica"
}, {
  "sepal.length": "7.7",
  "sepal.width": "3.8",
  "petal.length": "6.7",
  "petal.width": "2.2",
  "species": "virginica"
}, {
  "sepal.length": "7.7",
  "sepal.width": "2.6",
  "petal.length": "6.9",
  "petal.width": "2.3",
  "species": "virginica"
}, {
  "sepal.length": "6",
  "sepal.width": "2.2",
  "petal.length": "5",
  "petal.width": "1.5",
  "species": "virginica"
}, {
  "sepal.length": "6.9",
  "sepal.width": "3.2",
  "petal.length": "5.7",
  "petal.width": "2.3",
  "species": "virginica"
}, {
  "sepal.length": "5.6",
  "sepal.width": "2.8",
  "petal.length": "4.9",
  "petal.width": "2",
  "species": "virginica"
}, {
  "sepal.length": "7.7",
  "sepal.width": "2.8",
  "petal.length": "6.7",
  "petal.width": "2",
  "species": "virginica"
}, {
  "sepal.length": "6.3",
  "sepal.width": "2.7",
  "petal.length": "4.9",
  "petal.width": "1.8",
  "species": "virginica"
}, {
  "sepal.length": "6.7",
  "sepal.width": "3.3",
  "petal.length": "5.7",
  "petal.width": "2.1",
  "species": "virginica"
}, {
  "sepal.length": "7.2",
  "sepal.width": "3.2",
  "petal.length": "6",
  "petal.width": "1.8",
  "species": "virginica"
}, {
  "sepal.length": "6.2",
  "sepal.width": "2.8",
  "petal.length": "4.8",
  "petal.width": "1.8",
  "species": "virginica"
}, {
  "sepal.length": "6.1",
  "sepal.width": "3",
  "petal.length": "4.9",
  "petal.width": "1.8",
  "species": "virginica"
}, {
  "sepal.length": "6.4",
  "sepal.width": "2.8",
  "petal.length": "5.6",
  "petal.width": "2.1",
  "species": "virginica"
}, {
  "sepal.length": "7.2",
  "sepal.width": "3",
  "petal.length": "5.8",
  "petal.width": "1.6",
  "species": "virginica"
}, {
  "sepal.length": "7.4",
  "sepal.width": "2.8",
  "petal.length": "6.1",
  "petal.width": "1.9",
  "species": "virginica"
}, {
  "sepal.length": "7.9",
  "sepal.width": "3.8",
  "petal.length": "6.4",
  "petal.width": "2",
  "species": "virginica"
}, {
  "sepal.length": "6.4",
  "sepal.width": "2.8",
  "petal.length": "5.6",
  "petal.width": "2.2",
  "species": "virginica"
}, {
  "sepal.length": "6.3",
  "sepal.width": "2.8",
  "petal.length": "5.1",
  "petal.width": "1.5",
  "species": "virginica"
}, {
  "sepal.length": "6.1",
  "sepal.width": "2.6",
  "petal.length": "5.6",
  "petal.width": "1.4",
  "species": "virginica"
}, {
  "sepal.length": "7.7",
  "sepal.width": "3",
  "petal.length": "6.1",
  "petal.width": "2.3",
  "species": "virginica"
}, {
  "sepal.length": "6.3",
  "sepal.width": "3.4",
  "petal.length": "5.6",
  "petal.width": "2.4",
  "species": "virginica"
}, {
  "sepal.length": "6.4",
  "sepal.width": "3.1",
  "petal.length": "5.5",
  "petal.width": "1.8",
  "species": "virginica"
}, {
  "sepal.length": "6",
  "sepal.width": "3",
  "petal.length": "4.8",
  "petal.width": "1.8",
  "species": "virginica"
}, {
  "sepal.length": "6.9",
  "sepal.width": "3.1",
  "petal.length": "5.4",
  "petal.width": "2.1",
  "species": "virginica"
}, {
  "sepal.length": "6.7",
  "sepal.width": "3.1",
  "petal.length": "5.6",
  "petal.width": "2.4",
  "species": "virginica"
}, {
  "sepal.length": "6.9",
  "sepal.width": "3.1",
  "petal.length": "5.1",
  "petal.width": "2.3",
  "species": "virginica"
}, {
  "sepal.length": "5.8",
  "sepal.width": "2.7",
  "petal.length": "5.1",
  "petal.width": "1.9",
  "species": "virginica"
}, {
  "sepal.length": "6.8",
  "sepal.width": "3.2",
  "petal.length": "5.9",
  "petal.width": "2.3",
  "species": "virginica"
}, {
  "sepal.length": "6.7",
  "sepal.width": "3.3",
  "petal.length": "5.7",
  "petal.width": "2.5",
  "species": "virginica"
}, {
  "sepal.length": "6.7",
  "sepal.width": "3",
  "petal.length": "5.2",
  "petal.width": "2.3",
  "species": "virginica"
}, {
  "sepal.length": "6.3",
  "sepal.width": "2.5",
  "petal.length": "5",
  "petal.width": "1.9",
  "species": "virginica"
}, {
  "sepal.length": "6.5",
  "sepal.width": "3",
  "petal.length": "5.2",
  "petal.width": "2",
  "species": "virginica"
}, {
  "sepal.length": "6.2",
  "sepal.width": "3.4",
  "petal.length": "5.4",
  "petal.width": "2.3",
  "species": "virginica"
}, {
  "sepal.length": "5.9",
  "sepal.width": "3",
  "petal.length": "5.1",
  "petal.width": "1.8",
  "species": "virginica"
}];


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

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(6);

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

var color = d3.scaleOrdinal(d3.schemeCategory10);

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

data = iris;

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

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

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

var brush = d3.brush()
  .on("start", brushstart)
  .on("brush", brushmove)
  .on("end", brushend)
  .extent([
    [0, 0],
    [size, size]
  ]);

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]);
    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", padding)
  .attr("y", padding)
  .attr("dy", ".71em")
  .text(function(d) {
    return d.x;
  });

cell.call(brush);

//console.log(traits.map(function(d) { return domainByTrait[d];}));

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

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

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

  cell.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", 4)
    .style("fill", function(d) {
      return color(d.species);
    });
}

var brushCell;

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

// Highlight the selected circles.
function brushmove(p) {
  if (d3.event.selection) {
    var e = d3.event.selection;
    svg.selectAll("circle").classed("hidden", function(d) {
      return x.invert(e[0][0]) > d[p.x] || x.invert(e[1][0]) < d[p.x] || y.invert(e[0][1]) < d[p.y] || y.invert(e[1][1]) > d[p.y];
    });
  }
}

// If the brush is empty, select all circles.
function brushend(p) {
    if (!d3.event.selection) 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;
}

svg {
  font: 10px sans-serif;
  padding: 10px;
}
.axis,
.frame {
  shape-rendering: crispEdges;
}
.axis line {
  stroke: #ddd;
}
.axis path {
  display: none;
}
.cell text {
  font-weight: bold;
  text-transform: capitalize;
}
.frame {
  fill: none;
  stroke: #aaa;
}
circle {
  fill-opacity: .7;
}
circle.hidden {
  fill: #ccc !important;
}
.extent {
  fill: #000;
  fill-opacity: .125;
  stroke: #fff;
}

<!DOCTYPE html>

<body>
  <script src="//d3js.org/d3.v4.min.js"></script>
</body>

这篇关于将d3交互式矩阵散点图更新到v4的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆