数据结构:
var data = [
{name: "male",
values: [
{ count: 12345,
date: Date 2015-xxx,
name: "male" },
{...}
]
},
{name: "female",
values: [
{ count: 6789,
date: Date 2015-xxx,
name: "female" },
{...}
]
}
]
我想访问的值是dataa.valuesb.count。
这些值用于为我的绘图绘制圆圈。
圆图代码:
focus.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("cx", function(d,i) { return x(d.values[i].date); })
.attr("cy", function(d,i) { return y(d.values[i].count); })
.attr("r", 4)
.style("fill", function(d,i) { return color(d.values[i].name); })
问题是,i = 1
是因为它在对象中的位置。
我想要做的是循环遍历values
下的所有values
。我怎么能这么做?
编辑:我想学习如何做到这一点,而不改变数据,以提高我的技能。
谢谢。
发布于 2016-08-21 00:59:12
最简单的方法是使用像underscore.js这样的库来编辑数据数组。
来自下划线文档:
平面化_.flatten(数组,浅)使嵌套数组变平(嵌套可以是任意深度的)。如果您通过浅层,>数组将只被平坦一个级别。 _.flatten([1,2,[3,[4]]);-> 1,2,3,4;_.flatten([1,2,[3,[4]],真);-> [1,2,3,[4]]; map _.map(列表、迭代器、上下文)别名: collect通过>转换函数( iteratee )映射列表中的每个值,从而产生一个新的值数组。迭代器传递三个参数:>值,然后是迭代的索引(或键),最后是对>整个列表的引用。 _.map(1,2,3,函数( num ){返回num * 3;});=> 3,6,9_.map({1: 1,2: 2,3: 3},函数(num,key){ three num* 3;});=> 3,6,9 _.map([1,2,3,4],_.first);=> 1,3
在您的代码中,您可以这样做:
var flatData = _.flatten(_.map(data, (d)=>d.values));
focus.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("cx", function(d,i) { return x(d.date); })
.attr("cy", function(d,i) { return y(d.count); })
.attr("r", 4)
.style("fill", function(d,i) { return color(d.name); })
发布于 2016-08-21 05:35:51
有几种方法只使用D3,不使用任何其他库,也不更改数据。其中之一是使用groups
来处理“较高”级别的数据(关于嵌套数据)。让我们在下面的代码中看到:
首先,我模拟了一个和您一样的数据集:
var data = [
{name: "male",
values: [{ x: 123,y: 234},
{ x: 432,y: 221},
{ x: 199,y: 56}]
},
{name: "female",
values: [{ x: 223,y: 111},
{ x: 67,y: 288},
{ x: 19, y: 387}]
}
];
这是我们要用的数据。我将在这里绘制一个散点图(就像一个例子),因此,让我们为访问第二级数据的天平设置域(x
和y
I values
):
var xScale = d3.scaleLinear().range([20, 380])
.domain([0, d3.max(data, function(d){
return d3.max(d.values, function(d){
return d.x;
})
})]);
var yScale = d3.scaleLinear().range([20, 380])
.domain([0, d3.max(data, function(d){
return d3.max(d.values, function(d){
return d.y;
})
})]);
现在是最重要的部分:我们要将数据绑定到“组”,而不是循环元素:
var circlesGroups = svg.selectAll(".circlesGroups")
.data(data)
.enter()
.append("g")
.attr("fill", function(d){ return (d.name == "male") ? "blue" : "red"});
一旦在第一级数据中我们有了2个对象,D3将为我们创建两个组。
我还用这些组来设置圆圈的颜色:如果name
是“男性”,圆圈是蓝色的,否则是红色的:
.attr("fill", function(d){ return (d.name == "male") ? "blue" : "red"});
现在,在创建组之后,我们根据每个组的数据中的values
创建圆圈,按如下方式绑定数据:
var circles = circlesGroups.selectAll(".circles")
.data(function(d){ return d.values})
.enter()
.append("circle");
在这里,function(d){ return d.values}
将根据values
数组中的对象将数据绑定到圆圈。
然后你定位你的圆圈。这是整个代码,单击“运行代码段”查看它:
var data = [
{name: "male",
values: [{ x: 123,y: 234},
{ x: 432,y: 221},
{ x: 199,y: 56}]
},
{name: "female",
values: [{ x: 223,y: 111},
{ x: 67,y: 288},
{ x: 19, y: 387}]
}
];
var xScale = d3.scaleLinear().range([20, 380])
.domain([0, d3.max(data, function(d){
return d3.max(d.values, function(d){
return d.x;
})
})]);
var yScale = d3.scaleLinear().range([20, 380])
.domain([0, d3.max(data, function(d){
return d3.max(d.values, function(d){
return d.y;
})
})]);
var xAxis = d3.axisBottom(xScale).tickSizeInner(-360);
var yAxis = d3.axisLeft(yScale).tickSizeInner(-360);
var svg = d3.select("body")
.append("svg")
.attr("width", 400)
.attr("height", 400);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0,380)")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(20,0)")
.call(yAxis);
var circlesGroups = svg.selectAll(".circlesGroups")
.data(data)
.enter()
.append("g")
.attr("fill", function(d){ return (d.name == "male") ? "blue" : "red"});
var circles = circlesGroups.selectAll(".circles")
.data(function(d){ return d.values})
.enter()
.append("circle");
circles.attr("r", 10)
.attr("cx", function(d){ return xScale(d.x)})
.attr("cy", function(d){ return yScale(d.y)});
.axis path, line{
stroke: gainsboro;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
https://stackoverflow.com/questions/39059870
复制相似问题