如何为每个x值绘制具有多个y值的散点图?

时间:2019-04-15 09:20:33

标签: javascript d3.js data-visualization visualization

我有以下格式的数据,我想使用d3进行绘制:

data = [
        { x: 0.2, y: [ 1, 2, 4 ] },
        { x: 0.3, y: [ 2 ] },
        { x: 0.5, y: [ 4, 7, 8, 12, 19 ] }
        { x: 1.4, y: [ 1, 3 ] }
       ]

通常y轴值是整数,但是这里它们是数组,因此以下代码无法按预期运行:

svg.selectAll("circle")
    .data(data)
    .enter()
    .append("circle")
        .attr("cx", function(d){ return x(d.x) })
        .attr("cy", function(d){ return y(d.y) })
        .attr("r", 2)

我没有为数组中的每个值绘制多个圆,而是得到一个圆。

该网站上的其他类似问题仅涉及具有固定数量y轴值的数据,因此我还没有找到修改此问题的解决方案的方法。

2 个答案:

答案 0 :(得分:1)

传统的D3答案是为每个对象添加一个组,然后为每个组的每个y值添加一个圆圈。

但是,由于您似乎是D3初学者(如果我输入错了,请纠正我),因此建议您创建一个对象数组,然后将其传递给data

有几种方法可以做到这一点,例如:

const newData = data.reduce(function(a, c) {
  return a.concat(c.y.map(function(d) {
    return {
      x: c.x,
      y: d
    }
  }));
}, []);

这是您所做的更改的代码:

const data = [{
    x: 0.2,
    y: [1, 2, 4]
  },
  {
    x: 0.3,
    y: [2]
  },
  {
    x: 0.5,
    y: [4, 7, 8, 12, 19]
  }, {
    x: 1.4,
    y: [1, 3]
  }
];

const newData = data.reduce(function(a, c) {
  return a.concat(c.y.map(function(d) {
    return {
      x: c.x,
      y: d
    }
  }));
}, []);

const x = d3.scaleLinear()
  .domain([0, 2])
  .range([0, 300]);

const y = d3.scaleLinear()
  .domain([0, 20])
  .range([0, 150]);

const svg = d3.select("svg");
svg.selectAll("circle")
  .data(newData)
  .enter()
  .append("circle")
  .attr("cx", function(d) {
    return x(d.x)
  })
  .attr("cy", function(d) {
    return y(d.y)
  })
  .attr("r", 4)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>

答案 1 :(得分:0)

为什么不先尝试解开数据数组?那应该很容易处理。

data = [{
    x: 0.2,
    y: [1, 2, 4]
  },
  {
    x: 0.3,
    y: [2]
  },
  {
    x: 0.5,
    y: [4, 7, 8, 12, 19],
  },
  {
    x: 1.4,
    y: [1, 3]
  }
];
unwrappedData = [];

for (b in data) {
  var temp = data[b].y.map((foo) => {
    return {
      x: data[b].x,
      y: foo
    }
  })
  unwrappedData = unwrappedData.concat(temp);

}

console.log(unwrappedData);

var svg = d3.select("body").append("svg")
  .attr("width", 100)
  .attr("height", 100)
  .style("margin-top", "58px");

svg.selectAll("circle")
  .data(unwrappedData)
  .enter()
  .append("circle")
  .attr("cx", function(d) {
    return d.x
  })
  .attr("cy", function(d) {
    return d.y
  })
  .attr("r", 2)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

此外,cx和cy属性是否不应该返回d.xd.y