首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >d3.js:向下嵌套2级访问数据

d3.js:向下嵌套2级访问数据
EN

Stack Overflow用户
提问于 2016-08-21 00:30:25
回答 2查看 3.4K关注 0票数 5

数据结构:

代码语言:javascript
运行
复制
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。

这些值用于为我的绘图绘制圆圈。

圆图代码:

代码语言:javascript
运行
复制
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。我怎么能这么做?

编辑:我想学习如何做到这一点,而不改变数据,以提高我的技能。

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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

下划线文档

在您的代码中,您可以这样做:

代码语言:javascript
运行
复制
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); })
票数 4
EN

Stack Overflow用户

发布于 2016-08-21 05:35:51

有几种方法只使用D3,不使用任何其他库,也不更改数据。其中之一是使用groups来处理“较高”级别的数据(关于嵌套数据)。让我们在下面的代码中看到:

首先,我模拟了一个和您一样的数据集:

代码语言:javascript
运行
复制
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}]
    }
];

这是我们要用的数据。我将在这里绘制一个散点图(就像一个例子),因此,让我们为访问第二级数据的天平设置域(xy I values):

代码语言:javascript
运行
复制
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;
        })
})]);

现在是最重要的部分:我们要将数据绑定到“组”,而不是循环元素:

代码语言:javascript
运行
复制
var circlesGroups = svg.selectAll(".circlesGroups")
    .data(data)
    .enter()
    .append("g")
    .attr("fill", function(d){ return (d.name == "male") ? "blue" : "red"});

一旦在第一级数据中我们有了2个对象,D3将为我们创建两个组。

我还用这些组来设置圆圈的颜色:如果name是“男性”,圆圈是蓝色的,否则是红色的:

代码语言:javascript
运行
复制
.attr("fill", function(d){ return (d.name == "male") ? "blue" : "red"});

现在,在创建组之后,我们根据每个组的数据中的values创建圆圈,按如下方式绑定数据:

代码语言:javascript
运行
复制
    var circles = circlesGroups.selectAll(".circles")
        .data(function(d){ return d.values})
        .enter()
        .append("circle");

在这里,function(d){ return d.values}将根据values数组中的对象将数据绑定到圆圈。

然后你定位你的圆圈。这是整个代码,单击“运行代码段”查看它:

代码语言:javascript
运行
复制
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)});
代码语言:javascript
运行
复制
.axis path, line{
	stroke: gainsboro;
}
代码语言:javascript
运行
复制
<script src="https://d3js.org/d3.v4.min.js"></script>

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39059870

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档