【发布时间】:2016-03-25 01:35:11
【问题描述】:
我试图用这个streamgraph D3.js 布局做一些例子。我的数据有这种格式。所以我的对象在这些对象中有带有国家名称和名称的对象我有几个数组,每个月都有不同的值和每个月的日期(“基准”)
{
"Irak": {
"Asylberechtigt": [
65,
60,
54,
47,
47,
30,
25,
21,
12,
6
],
"EntscheidungenInsgesamt": [
8645,
7559,
6533,
5425,
4351,
3336,
2643,
2022,
1270,
645
],
"InsgesamtMonat": [
1086,
1026,
1108,
1074,
1015,
693,
621,
752,
625,
645
],
"Datum": [
"2015-10-01",
"2015-09-01",
"2015-08-01",
"2015-07-01",
"2015-06-01",
"2015-05-01",
"2015-04-01",
"2015-03-01",
"2015-02-01",
"2015-01-01"
]
},
"Mazedonien": {
"Asylberechtigt": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"EntscheidungenInsgesamt": [
4734,
4091,
3527,
3268,
2715,
2238,
1923,
1489,
1094,
604
],
"InsgesamtMonat": [
643,
564,
259,
553,
477,
315,
434,
395,
490,
604
],
"Datum": [
"2015-10-01",
"2015-09-01",
"2015-08-01",
"2015-07-01",
"2015-06-01",
"2015-05-01",
"2015-04-01",
"2015-03-01",
"2015-02-01",
"2015-01-01"
]
}
}
对于流图,我需要 .values 并且我知道它必须返回一些我正在使用此函数访问的 x 和 y 值(例如,0 是伊拉克,但最后我必须遍历所有国家/地区)。我认为这不是永久的解决方案。但是我的数据一般应该是什么样子,因为我意识到嵌套对我来说非常混乱。 那么需要什么结构才能使用函数来可视化流图?
var stack = d3.layout.stack()
.offset("wiggle")
.values(function(d){
for (var i = 0; i < d[countries[0]].Datum.length; i++) {
var dx = d[countries[0]].Datum[i];
var dy = d[countries[0]].InsgesamtMonat[i];
//console.log("Countries with InsgesamtMonat "+ countries[i]+" "+test);
dStack[i] = { x: dx, y: dy};
}
return dStack;
});
//.values(function(d) { return d[countries[0]].values; })
.x(function(d) { return d[countries[0]].Datum; })
.y(function(d) { return d[countries[0]].InsgesamtMonat; });
我还需要 .x 和 .y 吗?
这是我的完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Testing Streamgraph</title>
<link rel="stylesheet" href="main.css">
<script type="text/javascript" src="d3.min.js"></script>
</head>
<body>
<!--Place all DOM elements here -->
<script>
d3.json("data.json", function(error, data){
console.log(data)
plot(data);
//console.log(data);
})
function plot(data) {
var dStack = [];
var w = 800;
var h = 450;
var margin = {
top: 100,
bottom: 0,
left: 80,
right: 40
};
var width = w - margin.left - margin.right;
var height = h - margin.top - margin.bottom;
var svg = d3.select("body").append("svg")
.attr("id", "chart")
.attr("width", w)
.attr("height", h)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var dateParser = d3.time.format("%Y-%m-%d").parse;
var colorScale = d3.scale.category20();
var n = Object.keys(data).length;
var m = 10 // number of samples per layer
//console.log(data[Object.keys("Asylberechtigt")[13]])
//var test = Object.keys(data).Asylberechtigt;
var countries = Object.keys(data);
console.log(countries);
var stack = d3.layout.stack()
.offset("wiggle")
.values(function(d){
for (var i = 0; i < d[countries[0]].Datum.length; i++) {
var dx = d[countries[0]].Datum[i];
var dy = d[countries[0]].InsgesamtMonat[i];
//console.log("Countries with InsgesamtMonat "+ countries[i]+" "+test);
dStack[i] = { x: dx, y: dy};
}
return dStack;
});
//.values(function(d) { return d[countries[0]].values; })
.x(function(d) { return d[countries[0]].Datum; })
.y(function(d) { return d[countries[0]].InsgesamtMonat; });
var nest = d3.nest()
.key(function(d) { return d.countries });
console.log(nest);
var area = d3.svg.area()
.interpolate("cardinal")
.x(function(d){
var xStack = []
for (var i = 0; i < d[countries[0]].Datum.length; i++) {
var dx = d[countries[0]].Datum[i];
xStack[i] = dx;
}
return xStack })
.y0(function(d) { return y(d.y0); })
.y1(function(d) { return y(d.y0 + d.y); });
var layers = stack(nest.countries(data)); //Do i need to nest again because i already have the Countries as objects
var x = d3.time.scale()
.domain(d3.extent(data, function(d, i){
var date = dateParser(Object.keys(d).Datum(i)); // Do't know if this is legit either
// date= 0;
return date;
}))
.range([0+margin.left,width]);
var y = d3.scale.linear()
.domain([0, d3.max(data, function(d){
return d.value;
})])
.range([height,0+margin.top]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
//enter()
svg.selectAll(".point")
.data(layers)
.enter()
}
</script>
</body>
</html>
我不知道如何准确地为我的数据声明层,您也可以帮我解决这个问题吗?
【问题讨论】:
-
有很多流图示例(例如here)。你看过他们使用的数据吗?
-
我关闭了几天前与此相同的重复问题,我回答了您的
csv问题,这与几分钟前的问题非常相似。回答这个问题有点困难。首先,流图由一个变量“堆叠”。在你的情况下,我假设它是国家,但是我们要如何处理“Asylberechtigt”、“EntscheidungenInsgesamt”等...... -
第二,你对
d3的数据accessors的工作方式不是很了解。它们的目的不是直接操作数据,而是告诉d3哪些属性包含感兴趣的数据。第三,你的 json 格式一团糟。我会在生成 json 的任何地方修复它(服务器端,我假设?)。你想要这个[{name: country1, values:[{date: '1/1/10', value: 3535},{date: '1/2/10', value: 6635}]},{name: country2, values[{等等......如果你必须在 JavaScript 中修复它可以完成,但同样,你有太多的“堆栈”变量。
标签: javascript json d3.js stream-graph