我有以下格式的数据,我想使用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轴值的数据,因此我还没有找到修改此问题的解决方案的方法。
答案 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.x
和d.y
?