d3.js中包装圆圈的散点图?

时间:2015-01-16 06:09:18

标签: svg d3.js visualization scatter-plot circle-pack

有没有办法创建稀疏的散点图可视化,其中图上的每个“点”都是一级packed circle?我一直试图用d3做这个,但我不知道是否有可能在同一个svg中制作多个不同的包布局...(或者如果这甚至是我应该如何处理它)。任何帮助将不胜感激!

我希望它最终看起来像下面的草图:  enter image description here

2 个答案:

答案 0 :(得分:2)

把它扔到一起。它需要d3耀斑数据,并将分散出第一级儿童及其子女。

数据结构:

var flareData = {
  "name": "root",
  "children": [{
    "name": "pointOne",
    "scatX": 10,
    "scatY": 20,
    "children": [{
      "name": "pointOneA",
      "children": [{
        "name": "A",
        "size": 40
      }, {
        "name": "B",
        "size": 50
      }]
    }, {
      "name": "pointOneB",
      "children": [{
        "name": "C",
        "size": 10
      }, {
        "name": "D",
        "size": 23
      }]
    }]
  }, {
    "name": "pointTwo",
...

创建绘图和轴的典型d3代码:

var
 WIDTH = 600,
  HEIGHT = 600,
  DIAMETER = 200;

var vis = d3.select('body')
  .append('svg')
  .attr('width', WIDTH)
  .attr('height', HEIGHT);

var MARGINS = {
  top: 20,
  right: 20,
  bottom: 20,
  left: 50
},
  xRange = d3.scale
    .linear()
    .range([MARGINS.left, WIDTH - MARGINS.right])
    .domain([d3.min(flareData.children, function(d) {
      return d.scatX;
    }) - 10, d3.max(flareData.children, function(d) {
      return d.scatX;
    }) + 10]),
  yRange = d3.scale
    .linear()
    .range([HEIGHT - MARGINS.top, MARGINS.bottom])
    .domain([d3.min(flareData.children, function(d) {
      return d.scatY;
    }) - 10, d3.max(flareData.children, function(d) {
      return d.scatY;
    }) + 10]),
  xAxis = d3.svg.axis()
    .scale(xRange)
    .tickSize(5)
    .tickSubdivide(true),
  yAxis = d3.svg.axis()
    .scale(yRange)
    .tickSize(5)
    .orient('left')
    .tickSubdivide(true);

vis.append('svg:g')
  .attr('class', 'x axis')
  .attr('transform', 'translate(0,' + (HEIGHT - MARGINS.bottom) + ')')
  .call(xAxis);

vis.append('svg:g')
  .attr('class', 'y axis')
  .attr('transform', 'translate(' + (MARGINS.left) + ',0)')
  .call(yAxis);

让滥用打包布局开始:

// normal packed layout
var pack = d3.layout.pack()
  .size([DIAMETER - 4, DIAMETER - 4])
  .value(function(d) {
    return d.size;
  });

// classify each level
var node = vis.datum(flareData).selectAll(".node")
  .data(pack.nodes)
  .enter().append("g")
  .attr("class", function(d) {        
    // root level
    if (!d.parent) {
      return "node rootNode";
    // first level children, these are our scatter points
    } else if (d.children && !d.parent.parent) {
      return "node pointNode";
    // an intermediate circle
    } else if (d.children) {
      return "node innerNode";
    // last level packing
    } else {
      return "node innerNode packedNode";
    }
  });

// use calculated radius
node.append("circle")
  .attr("r", function(d) {
    return d.r;
  });

// we don't care about root circle, move off page
node.filter(".rootNode")
  .attr("transform", "translate(" + -100 + "," + -100 + ")");

// this is our scatter point
node.filter(".pointNode")
  .attr("transform", function(d) {
    return "translate(" + xRange(d.scatX) + "," + yRange(d.scatY) + ")";
  });

// any circle in a scatter point
node.filter(".innerNode")
  .attr("transform", function(d) {
    var iter = d;
    while(!iter.scatX){
      iter = iter.parent;
    }
    // diff from scatter point...
    var difX = iter.x - d.x,
        difY = iter.y - d.y;
    return "translate(" + (xRange(iter.scatX) + difX) + "," + (yRange(iter.scatY) + difY) + ")";
  })

// finally label our last level
node.filter(".packedNode")
  .append("text")
  .attr("dy", ".3em")
  .style("text-anchor", "middle")
  .text(function(d) {
    return d.name;
  });

示例here

产地:

enter image description here

答案 1 :(得分:0)

以下是您要实现的目标示例:

http://bl.ocks.org/donaldh/2920551