2013-04-08 67 views
2

我是新来d3js并努力适应从这里http://bl.ocks.org/mbostock/4060954的streamgraph例如:D3.js streamgraph例子 - 生成正确的区域函数值

enter image description here

...我自己的数据的工作,跟踪来自不同地方(在线,留言簿,博物馆)的艺术展览的访客。我已经取得了一些进展,我认为我的数据格式正确,但是我得到了一些非常奇怪的最终y值,我的示例没有显示任何内容。

我的数据开始为CSV:

index,date,venue,num_visitors 
0,4/6/2013,online,3844 
0,4/6/2013,museum,789 
0,4/6/2013,guestbook,20 
1,4/7/2013,online,217 
1,4/7/2013,museum,718 
1,4/7/2013,guestbook,20 

然后我窝它组织成3层/由会场流(在线,博物馆,留言板):

layer0 = [ 
    { 
    "key": "online", 
    "values": [ 
     { "x": 0, "y": 3844}, 
     { "x": 1, "y": 217} 
     etc 

    ] 
    }, 
    { 
    "key": "museum", 
    "values": [ 
     { "x": 0, "y": 789}, 
     { "x": 1, "y": 718} 
     etc 
    ] 
    } 
]; 

当页生成的y值始终为800,svg路径对象测量1400px宽度和0高度。我不确定这是如何将输入域扩展到输出范围的问题,或者是区域函数如何生成y值时出现问题。这是一个什么样的点值显示为所生成路径的一个样本:

d="M0,800L17.72151898734177,800L35.44303797468354,800L53.164556962025316,800L70.88607594936708, etc" 

这里是我完整的页面 - 真的很感激一些指导,我觉得我失去了一些东西简单在这里。

<!DOCTYPE html> 
<meta charset="utf-8"> 
<title>Streamgraph</title> 
<style> 

body { 
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 
    margin: 0; 
    position: relative; 
    width: 1400px; 
} 

button { 
    position: absolute; 
    right: 10px; 
    top: 10px; 
} 

</style> 
<button onclick="transition()">Update</button> 
<script src="d3.js"></script> 
<script> 

var format = d3.time.format("%m/%d/%Y"); 

d3.csv("streamdata.csv", function(error, data) { 
     data.forEach(function(d) { 
      d.date = format.parse(d.date); 
      d.y = d.num_visitors; 
      d.x = d.index; 

     }); 
     window.data = data; 

     drawVisitorStats(); 
}); 

function drawVisitorStats(){ 
    var nest = d3.nest() 
      .key(function(d){ return d.venue}); 
    var n = window.data.length, // number of layers, online, guestbook & museum 

     stack = d3.layout.stack().offset("wiggle").offset("zero") 
      .values(function(d) { return d.values; }), 

     //group data by venue 
     layers0 = stack(nest.entries(data)), 
     layers1 = stack(nest.entries(data)); 

    var m = layers0[0].values.length; // number of samples per layer 

    var yDomain = d3.max(layers0.concat(layers1), function(layer) { 
     return d3.max(layer, 
      function(d) { 
       return d.y0 + d.y; 
      }); 
    }); 

    var width = 1400, 
     height = 800; 

    var x = d3.scale.linear() 
    .domain([0, m - 1]) 
    .range([0, width]); 

    var y = d3.scale.linear() 
    .domain([0, yDomain]) 
    .range([height, 0]); 

    var color = d3.scale.linear() 
     .range(["#ff0c00", "#ffc000"]); 

    var area = d3.svg.area() 
     .x(
     function(d) { 
      return x(d.x); 
     }) 
     .y0(function(d) { 
      return y(d.y0); 
     }) 
     .y1(function(d) { 
      return y(d.y0 + d.y); 
     }); 

    var svg = d3.select("body").append("svg") 
     .attr("width", width) 
     .attr("height", height); 

    svg.selectAll("path") 
     .data(layers0) 
     .enter().append("path") 
     .attr("d", function(d) { return area(d.values); }) 
     .style("fill", function() { return color(Math.random()); }); 
} 
function transition() { 
    d3.selectAll("path") 
     .data(function() { 
     var d = layers1; 
     layers1 = layers0; 
     return layers0 = d; 
     }) 
    .transition() 
     .duration(2500) 
     .attr("d", area); 
} 



</script> 

这里是CSV文件

index,date,venue,num_visitors 
0,4/6/2013,online,3844 
0,4/6/2013,museum,789 
0,4/6/2013,guestbook,20 
1,4/7/2013,online,217 
1,4/7/2013,museum,718 
1,4/7/2013,guestbook,20 
2,4/8/2013,online,203 
2,4/8/2013,museum,741 
2,4/8/2013,guestbook,6 
3,4/9/2013,online,1445 
3,4/9/2013,museum,874 
3,4/9/2013,guestbook,7 
4,4/10/2013,online,3098 
4,4/10/2013,museum,755 
4,4/10/2013,guestbook,3 
5,4/11/2013,online,744 
5,4/11/2013,museum,368 
5,4/11/2013,guestbook,6 
6,4/12/2013,online,1342 
6,4/12/2013,museum,826 
6,4/12/2013,guestbook,17 
7,4/13/2013,online,694 
7,4/13/2013,museum,826 
7,4/13/2013,guestbook,17 
8,4/14/2013,online,213 
8,4/14/2013,museum,261 
8,4/14/2013,guestbook,7 
9,4/15/2013,online,3215 
9,4/15/2013,museum,776 
9,4/15/2013,guestbook,14 
10,4/16/2013,online,2663 
10,4/16/2013,museum,331 
10,4/16/2013,guestbook,12 
11,4/17/2013,online,172 
11,4/17/2013,museum,633 
11,4/17/2013,guestbook,10 
12,4/18/2013,online,4516 
12,4/18/2013,museum,543 
12,4/18/2013,guestbook,5 
13,4/19/2013,online,988 
13,4/19/2013,museum,792 
13,4/19/2013,guestbook,19 
14,4/20/2013,online,2556 
14,4/20/2013,museum,663 
14,4/20/2013,guestbook,0 
15,4/21/2013,online,2814 
15,4/21/2013,museum,449 
15,4/21/2013,guestbook,18 
16,4/22/2013,online,596 
16,4/22/2013,museum,445 
16,4/22/2013,guestbook,15 
17,4/23/2013,online,4790 
17,4/23/2013,museum,217 
17,4/23/2013,guestbook,5 
18,4/24/2013,online,733 
18,4/24/2013,museum,655 
18,4/24/2013,guestbook,12 
19,4/25/2013,online,362 
19,4/25/2013,museum,321 
19,4/25/2013,guestbook,20 
20,4/26/2013,online,637 
20,4/26/2013,museum,420 
20,4/26/2013,guestbook,3 
21,4/27/2013,online,2916 
21,4/27/2013,museum,910 
21,4/27/2013,guestbook,6 
22,4/28/2013,online,1097 
22,4/28/2013,museum,468 
22,4/28/2013,guestbook,0 
23,4/29/2013,online,796 
23,4/29/2013,museum,687 
23,4/29/2013,guestbook,9 
24,4/30/2013,online,821 
24,4/30/2013,museum,951 
24,4/30/2013,guestbook,12 
25,5/1/2013,online,2466 
25,5/1/2013,museum,810 
25,5/1/2013,guestbook,6 
26,5/2/2013,online,1005 
26,5/2/2013,museum,291 
26,5/2/2013,guestbook,19 
27,5/3/2013,online,1243 
27,5/3/2013,museum,446 
27,5/3/2013,guestbook,5 
28,5/4/2013,online,4623 
28,5/4/2013,museum,538 
28,5/4/2013,guestbook,0 
29,5/5/2013,online,547 
29,5/5/2013,museum,457 
29,5/5/2013,guestbook,11 
30,5/6/2013,online,4132 
30,5/6/2013,museum,407 
30,5/6/2013,guestbook,8 
31,5/7/2013,online,3083 
31,5/7/2013,museum,741 
31,5/7/2013,guestbook,9 
32,5/8/2013,online,2854 
32,5/8/2013,museum,516 
32,5/8/2013,guestbook,1 
33,5/9/2013,online,2122 
33,5/9/2013,museum,932 
33,5/9/2013,guestbook,14 
34,5/10/2013,online,587 
34,5/10/2013,museum,701 
34,5/10/2013,guestbook,0 
35,5/11/2013,online,698 
35,5/11/2013,museum,887 
35,5/11/2013,guestbook,18 
36,5/12/2013,online,3538 
36,5/12/2013,museum,223 
36,5/12/2013,guestbook,4 
37,5/13/2013,online,2413 
37,5/13/2013,museum,799 
37,5/13/2013,guestbook,13 
38,5/14/2013,online,3581 
38,5/14/2013,museum,744 
38,5/14/2013,guestbook,7 
39,5/15/2013,online,1750 
39,5/15/2013,museum,845 
39,5/15/2013,guestbook,17 
40,5/16/2013,online,3025 
40,5/16/2013,museum,630 
40,5/16/2013,guestbook,10 
41,5/17/2013,online,2038 
41,5/17/2013,museum,342 
41,5/17/2013,guestbook,7 
42,5/18/2013,online,148 
42,5/18/2013,museum,447 
42,5/18/2013,guestbook,20 
43,5/19/2013,online,886 
43,5/19/2013,museum,755 
43,5/19/2013,guestbook,20 
44,5/20/2013,online,1168 
44,5/20/2013,museum,305 
44,5/20/2013,guestbook,10 
45,5/21/2013,online,190 
45,5/21/2013,museum,378 
45,5/21/2013,guestbook,11 
46,5/22/2013,online,1416 
46,5/22/2013,museum,276 
46,5/22/2013,guestbook,13 
47,5/23/2013,online,1753 
47,5/23/2013,museum,380 
47,5/23/2013,guestbook,7 
48,5/24/2013,online,2573 
48,5/24/2013,museum,221 
48,5/24/2013,guestbook,17 
49,5/25/2013,online,2425 
49,5/25/2013,museum,610 
49,5/25/2013,guestbook,11 
50,5/26/2013,online,3359 
50,5/26/2013,museum,492 
50,5/26/2013,guestbook,1 
51,5/27/2013,online,1853 
51,5/27/2013,museum,873 
51,5/27/2013,guestbook,4 
52,5/28/2013,online,4106 
52,5/28/2013,museum,543 
52,5/28/2013,guestbook,7 
53,5/29/2013,online,591 
53,5/29/2013,museum,894 
53,5/29/2013,guestbook,11 
54,5/30/2013,online,2938 
54,5/30/2013,museum,565 
54,5/30/2013,guestbook,4 
55,5/31/2013,online,2237 
55,5/31/2013,museum,313 
55,5/31/2013,guestbook,4 
56,6/1/2013,online,3754 
56,6/1/2013,museum,622 
56,6/1/2013,guestbook,10 
57,6/2/2013,online,1529 
57,6/2/2013,museum,309 
57,6/2/2013,guestbook,2 
58,6/3/2013,online,1482 
58,6/3/2013,museum,636 
58,6/3/2013,guestbook,8 
59,6/4/2013,online,1607 
59,6/4/2013,museum,655 
59,6/4/2013,guestbook,8 
60,6/5/2013,online,364 
60,6/5/2013,museum,485 
60,6/5/2013,guestbook,0 
61,6/6/2013,online,555 
61,6/6/2013,museum,219 
61,6/6/2013,guestbook,3 
62,6/7/2013,online,4209 
62,6/7/2013,museum,674 
62,6/7/2013,guestbook,18 
63,6/8/2013,online,4767 
63,6/8/2013,museum,824 
63,6/8/2013,guestbook,11 
64,6/9/2013,online,4788 
64,6/9/2013,museum,877 
64,6/9/2013,guestbook,2 
65,6/10/2013,online,295 
65,6/10/2013,museum,873 
65,6/10/2013,guestbook,14 
66,6/11/2013,online,2057 
66,6/11/2013,museum,559 
66,6/11/2013,guestbook,13 
67,6/12/2013,online,3199 
67,6/12/2013,museum,592 
67,6/12/2013,guestbook,15 
68,6/13/2013,online,2453 
68,6/13/2013,museum,907 
68,6/13/2013,guestbook,12 
69,6/14/2013,online,3688 
69,6/14/2013,museum,267 
69,6/14/2013,guestbook,12 
70,6/15/2013,online,352 
70,6/15/2013,museum,389 
70,6/15/2013,guestbook,15 
71,6/16/2013,online,1583 
71,6/16/2013,museum,304 
71,6/16/2013,guestbook,7 
72,6/17/2013,online,4202 
72,6/17/2013,museum,438 
72,6/17/2013,guestbook,3 
73,6/18/2013,online,2652 
73,6/18/2013,museum,392 
73,6/18/2013,guestbook,1 
74,6/19/2013,online,3988 
74,6/19/2013,museum,764 
74,6/19/2013,guestbook,17 
75,6/20/2013,online,3025 
75,6/20/2013,museum,663 
75,6/20/2013,guestbook,18 
76,6/21/2013,online,4057 
76,6/21/2013,museum,266 
76,6/21/2013,guestbook,9 
77,6/22/2013,online,4853 
77,6/22/2013,museum,614 
77,6/22/2013,guestbook,15 
78,6/23/2013,online,1334 
78,6/23/2013,museum,745 
78,6/23/2013,guestbook,6 
79,6/24/2013,online,4729 
79,6/24/2013,museum,506 
79,6/24/2013,guestbook,8 

谢谢!

回答

3

在您的yDomain定义中,您需要返回每个图层值的最大值,因为每个图层都是一张图 - 它同时具有一个键和一个值数组,而不仅仅是一个平面数组。

var yDomain = d3.max(layers0.concat(layers1), function(layer) { 
    return d3.max(layer.values, //Used to be layer 
     function(d) { 
      return d.y0 + d.y; 
     }); 
}); 

而且,你的栈定义,你需要删除第二偏移呼叫..它否定了“摆动”之一,所以你会得到一个正常的叠式图,而不是streamgraph。

stack = d3.layout.stack().offset("wiggle") // Used to have .offset("zero") here 
     .values(function(d) { return d.values; }) 

下面是这两个变化的例子:http://jsfiddle.net/G6dTy/3/。这个留言本的数字很小,并且被其他两个值所忽略。

这可能是信息采取看看Stacked area chart例如

1

感谢minikomi!这非常有帮助。我意识到的另一件事是,我没有将y值解析为数字,而是将它们作为字符串读取,并使点计算变得疯狂。所以,当它的迭代通过CSV的行文件,它需要使用parseInt函数:

data.forEach(function(d) { 
     d.date = format.parse(d.date); 
     d.y = parseInt(d.num_visitors); 
     d.x = parseInt(d.index); 

    }); 

这里是万一有人想用这个作为未来的一个例子我更新的文件。

HTML

<!DOCTYPE html> 
<meta charset="utf-8"> 
<title>Streamgraph</title> 
<script type="text/javascript" charset="utf-8" src="http://code.jquery.com/jquery-1.8.3.min.js"></script> 
<script src="bootstrap/js/bootstrap.min.js"></script> 
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet"> 
<style> 

body { 
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 
    margin: 0; 
    position: relative; 
    width: 1400px; 
    background-color: #053749; 
} 

button { 
    position: absolute; 
    right: 10px; 
    top: 10px; 
} 
svg{ 
    margin-top: 450px; 
} 

</style> 
<script src="d3.js"></script> 
<body> 
    <div id="layerTitle"></div> 
</body> 
<script> 


var format = d3.time.format("%m/%d/%Y"); 

d3.csv("streamdata.csv", function(error, data) { 
     data.forEach(function(d) { 
      d.date = format.parse(d.date); 
      d.y = parseInt(d.num_visitors) + 1; 
      d.x = parseInt(d.index); 

     }); 
     window.data = data; 

     drawVisitorStats(); 
     //$('path').tooltip('{container:layerTitle}'); 
     $("path").tooltip({ 
      'container': 'body', 
      'placement': 'bottom' 
     }); 


}); 

function drawVisitorStats(){ 
    var nest = d3.nest() 
      .key(function(d){ return d.venue}); 
    var n = window.data.length, // number of layers, online, guestbook & museum 

    stack = d3.layout.stack().offset("wiggle") 
      .values(function(d) { return d.values; }); 

    //group data by venue 
    layers0 = stack(nest.entries(data)); 

    var m = layers0[0].values.length; // number of samples per layer 

    var allValues = layers0[0].values.concat(layers0[1].values).concat(layers0[2].values); 

    var yDomain = d3.max(allValues, function(d) { 
     return d.y0 + d.y; 
    }); 

    var width = 1400, 
     height = 200; 

    var x = d3.scale.linear() 
     .domain([0, m - 1]) 
     .range([0, width]); 

    var y = d3.scale.linear() 
    .domain([1, yDomain]) 
    .range([height, 0]); 

    var color = d3.scale.linear() 
     .range(["#053749", "#6bb9d6"]); 

    var area = d3.svg.area() 
     .x(
     function(d) { 
      return x(d.x); 
     }) 
     .y0(function(d) {   
      return y(d.y0); 
     }) 
     .y1(function(d) { 
      return y(d.y0 + d.y); 
     }) 
     .interpolate("cardinal") 
     .tension(0.6); 

    var svg = d3.select("body").append("svg") 
     .attr("width", width) 
     .attr("height", height); 

    svg.selectAll("path") 
     .data(layers0) 
     .enter().append("path") 
     .attr("d", function(d) { return area(d.values); }) 
     .attr("id", function(d) { 
      return d.key; 
     }) 
     .attr("title", function(d) { 
      return "visitors from " + d.key; 
     }) 
     .style("fill", function() { return color(Math.random()); }); 
} 

</script> 
</html> 

DATA文件

index,date,venue,num_visitors 
0,4/8/2013,online,1721 
0,4/8/2013,museum,826 
0,4/8/2013,guestbook,333 
1,4/9/2013,online,1377 
1,4/9/2013,museum,840 
1,4/9/2013,guestbook,61 
2,4/10/2013,online,1849 
2,4/10/2013,museum,539 
2,4/10/2013,guestbook,191 
3,4/11/2013,online,1205 
3,4/11/2013,museum,810 
3,4/11/2013,guestbook,65 
4,4/12/2013,online,1960 
4,4/12/2013,museum,957 
4,4/12/2013,guestbook,221 
5,4/13/2013,online,1215 
5,4/13/2013,museum,658 
5,4/13/2013,guestbook,384 
6,4/14/2013,online,1565 
6,4/14/2013,museum,621 
6,4/14/2013,guestbook,94 
7,4/15/2013,online,1678 
7,4/15/2013,museum,710 
7,4/15/2013,guestbook,35 
8,4/16/2013,online,1267 
8,4/16/2013,museum,964 
8,4/16/2013,guestbook,8 
9,4/17/2013,online,1781 
9,4/17/2013,museum,896 
9,4/17/2013,guestbook,238 
10,4/18/2013,online,1185 
10,4/18/2013,museum,712 
10,4/18/2013,guestbook,318 
11,4/19/2013,online,1097 
11,4/19/2013,museum,753 
11,4/19/2013,guestbook,132 
12,4/20/2013,online,1053 
12,4/20/2013,museum,927 
12,4/20/2013,guestbook,399 
13,4/21/2013,online,1738 
13,4/21/2013,museum,653 
13,4/21/2013,guestbook,78 
14,4/22/2013,online,1491 
14,4/22/2013,museum,568 
14,4/22/2013,guestbook,72 
15,4/23/2013,online,1403 
15,4/23/2013,museum,997 
15,4/23/2013,guestbook,184 
16,4/24/2013,online,1335 
16,4/24/2013,museum,987 
16,4/24/2013,guestbook,26 
17,4/25/2013,online,1964 
17,4/25/2013,museum,753 
17,4/25/2013,guestbook,239 
18,4/26/2013,online,1260 
18,4/26/2013,museum,815 
18,4/26/2013,guestbook,249 
19,4/27/2013,online,1404 
19,4/27/2013,museum,817 
19,4/27/2013,guestbook,360 
20,4/28/2013,online,1790 
20,4/28/2013,museum,840 
20,4/28/2013,guestbook,163 
21,4/29/2013,online,1698 
21,4/29/2013,museum,700 
21,4/29/2013,guestbook,129 
22,4/30/2013,online,1479 
22,4/30/2013,museum,921 
22,4/30/2013,guestbook,347 
23,5/1/2013,online,1093 
23,5/1/2013,museum,720 
23,5/1/2013,guestbook,278 
24,5/2/2013,online,1148 
24,5/2/2013,museum,655 
24,5/2/2013,guestbook,162 
25,5/3/2013,online,1521 
25,5/3/2013,museum,806 
25,5/3/2013,guestbook,267 
26,5/4/2013,online,1365 
26,5/4/2013,museum,662 
26,5/4/2013,guestbook,232 
27,5/5/2013,online,1809 
27,5/5/2013,museum,659 
27,5/5/2013,guestbook,398 
28,5/6/2013,online,1078 
28,5/6/2013,museum,999 
28,5/6/2013,guestbook,51 
29,5/7/2013,online,1477 
29,5/7/2013,museum,512 
29,5/7/2013,guestbook,385 
0

只是要注意,有基于相同的CSV数据,但尝试使用转换的后续问题here。同样,错误与“区域”有关,但在转换函数内。

+0

这可以发布为评论而不是答案。 – user2314737 2014-02-21 23:41:48

+0

点击“添加评论”链接告诉我,我必须有50的评论信誉。 – user1744863 2014-02-22 19:28:53

+0

我知道,很难成为Stackoverflow上的新手。 – user2314737 2014-02-22 19:43:37