I was trying to do some examples with this streamgraph layout of D3.js. My data has this format. So the my object has objects with the name of the country andy in those objects i have several arrays with different values per month and the date for each month ("Datum")
{
"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"
]
}
}
For the streamgraph i need .values and I understood that it has to return some x and y values I'm accessing with this function (0 is Irak for example but in the end i have to iterate through all countries). I think this is no permanent solution. But what should my data look like in general because I realized that nesting is pretty confusing for me. So What structure is required so i can use the functions to visualize the streamgraph?
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; });
Do I still need the .x and the .y ?
Here is my full code
<!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>
I don't get how to declare the layer for my data exactly can you also help me with that?