Streamgraph示例D3的正确的JSON格式结构 [英] right JSON format structure for Streamgraph example D3

查看:191
本文介绍了Streamgraph示例D3的正确的JSON格式结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用这个 streamgraph 布局D3.js做一些例子。我的数据有这种格式。所以我的对象有对象与国家的名称andy在那些对象我有几个数组,每个月和每个月的日期(基准)不同的值

  {
Irak:{
Asylberechtigt:[
65,
60,
54,
47,
47,
30,
25,
21,
12,
6
],
EntscheidungenInsgesamt :[
8645,
7559,
6533,
5425,
4351,
3336,
2643,

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,
04-01,
2015-03-01,
2015-02-01,
2015-01-01
]
}
}

对于流图,我需要.values和我理解,它必须返回一些x和y值我使用这个函数访问(0是Irak例如,但最终我必须遍历所有国家)。我认为这不是永久的解决方案。但是我的数据应该是什么样子,因为我意识到嵌套对我来说很混乱。 所以需要什么结构,以便我可以使用函数来可视化流图。

  var stack = d3.layout.stack()
.offset(wiggle)
.values(function(d){
for(var i = 0; 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]]。 })
.y(function(d){return d [countries [0]]。InsgesamtMonat;});

我还需要.x和.y? p>

这是我的完整代码



 <!DOCTYPE html>< html lang = en>< head> < meta charset =UTF-8> < title>测试流图< / title> < link rel =stylesheethref =main.css> < script type =text / javascriptsrc =d3.min.js>< / script>< / head>< body><! - 将所有DOM元素放在这里 - >< ; 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 //每层样本数//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 ){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  



我没有得到如何声明我的数据的层完全可以帮助我吗? p>

解决方案

我支持这个问题,主要是无聊,但我想我有点苛刻的评论。正如我所说,你的数据有太多的by变量,所以让我们假设我们想要按国家流可选过滤器InsgesamtMonat,EntscheidungenInsgesamt等流图。所以问题变成我们如何得到此数据在 中以 d3.layout.stack 的格式可以理解?

  //给定一个堆栈定义为... 
var stack = d3.layout.stack()
.offset(wiggle)
。值(函数(d){
return d.values;
});

//转换数据
// varToStackOn是EntscheidungenInsgesamt
var properData = [];
for(country in json){
var obj = {};
obj.name = country;
obj.values = [];
json [country] [varToStackOn] .forEach(function(d,i){
obj.values.push({
x:format.parse(json [country] [Datum] [i]),
y:d
});
})
properData.push(obj);
}

//并堆栈
var stackData = stack(properData);

一旦这样做,下面的例子就很容易了。



这里一切都在一起:



 <!DOCTYPE html>< meta charset =utf-8> ;< style> body {font:10px sans-serif; } .chart {background:#fff; } p {font:12px helvetica; } .axis path,.axis line {fill:none; stroke:#000; stroke-width:2px; shape-rendering:crispEdges; } button {position:absolute; right:50px; top:10px; }< / style>< body> < script src =http://d3js.org/d3.v3.js>< / script> < div class =chart> < / div> < script> var json = {Irak:{Asylberechtigt:[65,60,54,47,47,30,25,21,12,6],EntscheidungenInsgesamt:[8645,7559,6533,5425,4351, 3366,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:[50,20,10,14,10,6,18,32, 30,12],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]}} var format = d3.time格式(%Y-%d-%m); var stack = d3.layout.stack().offset(wiggle).values(function(d){return d.values;}); var width = 300,height = 300; var x = d3.time.scale().range([0,width]).domain(d3.extent([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],function(d){return format.parse(d);})); var y = d3.scale.linear().range([height,0]); var color = d3.scale.category10()var area = d3.svg.area().x(function(d){return x(dx);}).y0(function(d){return y(d.y0 );}).y1(function(d){return y(d.y0 + dy);}); var svg = d3.select(body)。append(svg).attr(width,width).attr(height,height); var stackOn =InsgesamtMonat; stackon =InsgesamtMonat; else if(stackOn ===EntscheidungenInsgesamt)setInterval(function(){if(stackOn ===InsgesamtMonat)stackOn =EntscheidungenInsgesamt; else if(stackOn ===Asylberechtigt stackOn =Asylberechtigt; updateGraph(stackOn);},1000); function updateGraph(varToStackOn){var properData = []; for(country in json){var obj = {}; obj.name = country; obj.values = []; json [country] [varToStackOn] .forEach(function(d,i){obj.values.push({x:format.parse(json [country] [Datum] [i]),y:d}); })properData.push(obj); } var stackedData = stack(properData); y.domain([0,d3.max(stackedData,function(layer){return d3.max(layer.values,function(d){return d.y0 + d.y;});})]); var path = svg.selectAll(path).data(stack(properData))path .enter()。append(path).style(fill,function(d,i) ;}); paths.transition().attr(d,function(d){return area(d.values);}); }< / script>< / body>< / html>  


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?

解决方案

I double-backed to this question, mostly out of boredom, but I think I was a bit to harsh in my comments. As I said, your data has too many "by" variables, so let's assume that we want to stream graph by country with an optional filter of "InsgesamtMonat", "EntscheidungenInsgesamt", etc... So the question becomes how do we get this data, in JavaScript, into a format that d3.layout.stack will understand?

  // give a stack defined as...
  var stack = d3.layout.stack()
    .offset("wiggle")
    .values(function(d) {
      return d.values;
    });

  // convert data
  // varToStackOn is "EntscheidungenInsgesamt"
  var properData = [];
  for (country in json) {
    var obj = {};
    obj.name = country;
    obj.values = [];
    json[country][varToStackOn].forEach(function(d, i) {
      obj.values.push({
        x: format.parse(json[country]["Datum"][i]),
        y: d
      });
    })
    properData.push(obj);
  }

  // and stack it
  var stackedData = stack(properData);

Once this is done, following the examples becomes easy.

Here it all is all together:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  body {
    font: 10px sans-serif;
  }
  
  .chart {
    background: #fff;
  }
  
  p {
    font: 12px helvetica;
  }
  
  .axis path,
  .axis line {
    fill: none;
    stroke: #000;
    stroke-width: 2px;
    shape-rendering: crispEdges;
  }
  
  button {
    position: absolute;
    right: 50px;
    top: 10px;
  }
</style>

<body>
  <script src="http://d3js.org/d3.v3.js"></script>


  <div class="chart">
  </div>


  <script>
    var json = {
      "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": [50, 20, 10, 14, 10, 6, 18, 32, 30, 12],
        "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"
        ]
      }
    }

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

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

    var width = 300,
      height = 300;

    var x = d3.time.scale()
      .range([0, width])
      .domain(d3.extent(["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"], function(d) {
        return format.parse(d);
      }));

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

    var color = d3.scale.category10()

    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);
      
    var stackOn = "InsgesamtMonat";
    setInterval(function(){
      if (stackOn === "InsgesamtMonat")
        stackOn = "EntscheidungenInsgesamt";
      else if (stackOn === "Asylberechtigt")
        stackOn = "InsgesamtMonat";
      else if (stackOn === "EntscheidungenInsgesamt")
        stackOn = "Asylberechtigt";
  
      updateGraph(stackOn);
    }, 1000);

    function updateGraph(varToStackOn) {

      var properData = [];
      for (country in json) {
        var obj = {};
        obj.name = country;
        obj.values = [];
        json[country][varToStackOn].forEach(function(d, i) {
          obj.values.push({
            x: format.parse(json[country]["Datum"][i]),
            y: d
          });
        })
        properData.push(obj);
      }
      
      var stackedData = stack(properData);

      y.domain([0, d3.max(stackedData, function(layer) {
        return d3.max(layer.values, function(d) {
          return d.y0 + d.y;
        });
      })]);

      var paths = svg.selectAll("path")
        .data(stack(properData))
      
      paths
        .enter().append("path")
        .style("fill", function(d, i) {
          return color(i);
        });
      
      paths.transition()
        .attr("d", function(d) {
          return area(d.values);
        });
    }
  </script>
</body>

</html>

这篇关于Streamgraph示例D3的正确的JSON格式结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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