D3.js - 如何迭代我的数据集中的子数组 [英] D3.js - how can I iterate through subarrays in my dataset

查看:140
本文介绍了D3.js - 如何迭代我的数据集中的子数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让d3在我的数据中遍历子数组并生成多个饼图。



这里是完整的代码href =https://gist.github.com/mbostock/1305111 =nofollow> https://gist.github.com/mbostock/1305111
https://gist.github.com/enjalot/1203641 ):

 <!DOCTYPE html> 
< html lang =en>
< head>
< meta charset =utf-8>
< title> D3页面测试< / title>
< script type =text / javascriptsrc =http://mbostock.github.com/d3/d3.js>< / script>
< style type =text / css>

body {
text-align:center;
}

< / style>
< / head>
< body>
< script type =text / javascript>

//将数据定义为二​​维数字数组。如果你有其他
//数据与每个数字相关联,用一个对象替换每个数字,例如
//`{key:value}`。
var datad = [
{s:[20,1,1],l:[10,100]},
{s:[1,20,1],l: 200]},
{s:[1,1,20],l:[30,300]}
];

//定义边距,半径和颜色标度。颜色标度将是
//通过索引分配,但是如果使用对象定义数据,则可以从数据对象的命名字段中传递
//,例如`d.name` 。颜色
//被延迟分配,因此如果你想要确定性行为,为颜色标度定义一个域
//。
var m = 10,
r = 100,
z = d3.scale.category20c();

//为数据集中的每一行插入一个svg:svg元素(带边距)。 A
// child svg:g element将原点转换为饼图中心。
var svg = d3.select(body)。selectAll(svg)
.data([datad])
.enter()。append(svg:svg)
.attr(width,(r + m)* 2)
.attr(height,(r + m)* 2)
.append(svg:g )
.attr(transform,translate(+(r + m)+,+(r + m)+)

var pie = d3.layout.pie()//这将为我们创建弧数据给定值列表
.value(function(d,i){return ds [i ];}); //我们必须告诉它访问数据数组中每个元素的值


//每个svg:svg元素的数据是一行数字(一个数组)。我们将
//传递给d3.layout.pie来计算每个弧的角度。这些开始和结束
//角度传递给d3.svg.arc以绘制弧线!注意,圆弧半径是在圆弧上指定的
//,而不是布局。
svg.selectAll(path)
.data(pie)
.enter()。append(svg:path)
.attr(d,d3 .svg.arc()
.innerRadius(0)
.outerRadius(r + 2))
.style(fill,function(d,i){return z ;});

< / script>
< / body>
< / html>

我得到一个饼图,它由每个我的数据集中的s数组。



第一个饼图从datad [0] [0]绘制,第二个从datad [1] ],第三个饼图是从datad [2] [2]中绘制的。



我想要三个饼图数据)。



我认为我的问题是:

  var pie = d3.layout.pie()//这将为我们创建弧数据给定一个值列表
.value(function(d,i){return ds [i];}); //我们必须告诉它访问数据数组中每个元素的值

我如何告诉它对每个s数组进行迭代,而不是同时迭代datad和s数组。也就是说,我想迭代datad [0] s [0],datad [0] s [1],datad [0] s [2] ... datad [2] s [0],datad [2] [1](1)[2]



提示[1]或指针赞赏!



编辑:这里是小提琴:jsfiddle.net/H2SKt/701 /

解决方案

这里有一些问题,所有的加起来得到一个好的饼图,而不是你想绘制的图表。



对于初学者,当你做数据加入你的svg选择:

  var svg = d3.select (body)。selectAll(svg)
.data([datad])

您正在将数据数组嵌套在新数组(方括号)中,其中数据数组是唯一的元素。因此,您只需从 enter()语句中获取一个< svg> ,而不是三个。将其更改为

  var svg = d3.select(body)selectAll(svg)
。 data(datad)

你会得到三个< svg> 元素,如你所愿。但是没有一个有饼图,因为你的饼图函数没有找到你要查找的数据值:

  var pie = d3.layout.pie()
.value(function(d,i){return ds [i];});

svg.selectAll(path)
.data(pie)
.enter()。append(svg:path)

饼图函数需要传递一个数组,它会调用指定的 value 函数在数组元素上。你告诉它数组的每个元素都有一个 s 属性,它是一个数组,它应该从该数组访问一个元素。这是工作(排序),当你的饼图功能传递整个原始数据数组,但现在,我们已经拆分成不同的SVG元素的原始数据数组。现在饼形函数正在传递形式为 {s:[1,1,20],l:[30,300]} 的数据对象,



所以你需要改变两件事:你需要确保饼图函数只传递它应该使用的值数组,并且您需要告诉它如何从该数组的每个元素访问值。除非你实际上没有做第二部分,因为值只是原始数字,默认值函数将工作:

  var pie = d3.layout.pie()
// .value(function(d,i){return d;}); //默认,不需要

svg.selectAll(path)
.data(function(d){return pie(ds);})
.enter .append(svg:path)

d value在数据连接函数中是附加到每个< svg> 元素的数据对象;匿名函数提取子数组并调用其上的饼形函数,以返回该SVG中的< path> 元素中的每一个的数据数组。 p>

工作小提琴:
http:// jsfiddle。 net / H2SKt / 706 /


I'm trying to get d3 to iterate through sub-arrays in my data and generate multiple pie charts.

Here is the complete code (hacked from https://gist.github.com/mbostock/1305111 and https://gist.github.com/enjalot/1203641):

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>D3 Page Test</title>
        <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
 <style type="text/css">

body {
  text-align: center;
}

    </style>
  </head>
  <body>
    <script type="text/javascript">

// Define the data as a two-dimensional array of numbers. If you had other
// data to associate with each number, replace each number with an object, e.g.,
// `{key: "value"}`.
var datad = [
  {s:[ 20,  1, 1], l:[10,100]},
  {s:[ 1, 20, 1], l:[ 20, 200]},
  {s:[ 1, 1, 20], l:[ 30,300 ]}
];

// Define the margin, radius, and color scale. The color scale will be
// assigned by index, but if you define your data using objects, you could pass
// in a named field from the data object instead, such as `d.name`. Colors
// are assigned lazily, so if you want deterministic behavior, define a domain
// for the color scale.
var m = 10,
    r = 100,
    z = d3.scale.category20c();

// Insert an svg:svg element (with margin) for each row in our dataset. A
// child svg:g element translates the origin to the pie center.
var svg = d3.select("body").selectAll("svg")
    .data([datad])
  .enter().append("svg:svg")
    .attr("width", (r + m) * 2)
    .attr("height", (r + m) * 2)
  .append("svg:g")
    .attr("transform", "translate(" + (r + m) + "," + (r + m) + ")");

 var pie = d3.layout.pie()           //this will create arc data for us given a list of values
        .value(function(d, i) { return d.s[i]; });    //we must tell it out to access the value of each element in our data array


// The data for each svg:svg element is a row of numbers (an array). We pass
// that to d3.layout.pie to compute the angles for each arc. These start and end
// angles are passed to d3.svg.arc to draw arcs! Note that the arc radius is
// specified on the arc, not the layout.
svg.selectAll("path")
    .data(pie)
  .enter().append("svg:path")
    .attr("d", d3.svg.arc()
    .innerRadius(0)
    .outerRadius(r + 2))
    .style("fill", function(d, i) { return z(i); });

    </script>
  </body>
</html>

I am getting a single pie chart, and it is comprised of the value of "20" from each of my "s" arrays in my data set.

The first pie piece is drawn from datad[0][0], the second from datad[1][1], and the third pie piece is drawn from datad[2][2].

I'm expecting three pie charts (one for each "s" array in my data).

I think my problem is in:

     var pie = d3.layout.pie()  //this will create arc data for us given a list of values
        .value(function(d, i) { return d.s[i]; });  //we must tell it out to access the value of each element in our data array

How can I tell it to iterate over each s array, instead of iterating over both the datad and s array at the same time. That is, I want to iterate datad[0]s[0], datad[0]s[1], datad[0]s[2] ... datad[2]s[0], datad[2]s[1] (etc) instead of datad[0]s[0], datad[1]s[1], datad[2]s[2]

Tips or pointers appreciated!

Edit: here is the fiddle: jsfiddle.net/H2SKt/701/

解决方案

There are a few things going wrong here that are all adding up to get a nice pie chart that isn't the chart you're trying to draw.

For starters, when you do the data join to your svg selection:

var svg = d3.select("body").selectAll("svg")
    .data([datad])

You are nesting your data array inside a new array (the square brackets), of which your data array is the only element. So you only get one <svg> from your enter() statement, not three. Change it to

var svg = d3.select("body").selectAll("svg")
    .data(datad)

And you get three <svg> elements, as you intended. But none of them have pie charts, because your pie chart function is failing to find the data values you told it to look for:

 var pie = d3.layout.pie()    
        .value(function(d, i) { return d.s[i]; });   

svg.selectAll("path")
    .data(pie)
  .enter().append("svg:path")

The pie chart function expects to be passed an array of data, and it will call the specified value function on each element of the array. You're telling it that each element of the array has an s property that is an array, and it should access an element from that array. That was working (sort of) when your pie function was being passed your entire original data array, but not now that we've split up the original data array into different SVG elements. Now the pie function is being passed a data object of the form {s:[ 1, 1, 20], l:[ 30,300 ]}, and doesn't know what to do with it.

So you need to change two things: you need to make sure that the pie function only gets passed the array of values it is supposed to use, and you need to tell it how to access the value from each element of that array. Except you don't actually have to do that second part, since the values are just raw numbers and the default value function will work:

 var pie = d3.layout.pie() 
       // .value(function(d, i) { return d; });  //default, not required

svg.selectAll("path")
      .data( function(d) { return pie(d.s); })
  .enter().append("svg:path")

The d value in the data join function is the data object attached to each <svg> element; the anonymous function extracts the sub-array and calls the pie function on it, to return the array of data for each of the <path> elements in that SVG.

Working fiddle: http://jsfiddle.net/H2SKt/706/

这篇关于D3.js - 如何迭代我的数据集中的子数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆