sha*_*gtq 5 javascript json d3.js
数据结构:
var data = [
{name: "male",
values: [
{ count: 12345,
date: Date 2015-xxx,
name: "male" },
{...}
]
},
{name: "female",
values: [
{ count: 6789,
date: Date 2015-xxx,
name: "female" },
{...}
]
}
]
Run Code Online (Sandbox Code Playgroud)
我想要访问的值是data [a] .values [b] .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); })
Run Code Online (Sandbox Code Playgroud)
问题是i = 1
因为它在对象中的位置.
我想要做的是遍历所有objects
下面values
.我怎样才能做到这一点?
编辑:我希望在不改变数据的情况下学习如何做到这一点,以提高我的技能.
谢谢.
有几种方法可以仅使用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}]
}
];
Run Code Online (Sandbox Code Playgroud)
这就是我们要使用的数据。我将在此处绘制一个散点图(仅作为示例),因此,让我们为访问第二级数据(x
和y
内部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;
})
})]);
Run Code Online (Sandbox Code Playgroud)
现在是最重要的部分:我们将数据绑定到“组”,而不是圆元素:
var circlesGroups = svg.selectAll(".circlesGroups")
.data(data)
.enter()
.append("g")
.attr("fill", function(d){ return (d.name == "male") ? "blue" : "red"});
Run Code Online (Sandbox Code Playgroud)
在第一级数据中,我们有2个对象,D3将为我们创建2个组。
我还使用组来设置圆圈的颜色:如果name
是“ male”,则圆圈为蓝色,否则为红色:
.attr("fill", function(d){ return (d.name == "male") ? "blue" : "red"});
Run Code Online (Sandbox Code Playgroud)
现在,在创建了组之后,我们根据values
每个组的数据创建圆,并将数据绑定如下:
var circles = circlesGroups.selectAll(".circles")
.data(function(d){ return d.values})
.enter()
.append("circle");
Run Code Online (Sandbox Code Playgroud)
在这里,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}]
}
];
Run Code Online (Sandbox Code Playgroud)
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;
})
})]);
Run Code Online (Sandbox Code Playgroud)
var circlesGroups = svg.selectAll(".circlesGroups")
.data(data)
.enter()
.append("g")
.attr("fill", function(d){ return (d.name == "male") ? "blue" : "red"});
Run Code Online (Sandbox Code Playgroud)
最简单的方法是使用像 underscore.js 这样的库来编辑数据数组。
来自下划线文档:
flatten _.flatten(array, [shallow]) 展平嵌套数组(嵌套可以是任意深度)。如果你传递shallow,>数组只会被展平一个级别。
Run Code Online (Sandbox Code Playgroud)_.flatten([1, [2], [3, [[4]]]]); -> [1, 2, 3, 4]; _.flatten([1, [2], [3, [[4]]]], true); -> [1, 2, 3, [[4]]];
map _.map(list, iteratee, [context]) 别名:collect 通过 > 转换函数 (iteratee) 映射 list 中的每个值,生成一个新的值数组。迭代器传递三个参数:>值,然后是迭代的索引(或键),最后是对>整个列表的引用。
Run Code Online (Sandbox Code Playgroud)_.map([1, 2, 3], function(num){ return num * 3; }); => [3, 6, 9] _.map({one: 1, two: 2, three: 3}, function(num, key){ return 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); })
Run Code Online (Sandbox Code Playgroud)