gpt4 book ai didi

javascript - D3.js 中堆叠图的不同分层的想法

转载 作者:行者123 更新时间:2023-11-30 00:16:27 24 4
gpt4 key购买 nike

我有第一次和之后在德国为难民寻求庇护的尝试的数据,因此有两张看起来像这样的图表

第一个 First attempt/arrivals

第二个 enter image description here

我想从一个过渡到另一个应该不是问题,但我想要的是在一张图中也显示它们。因此,每个国家/地区的两个数据集的组合。但是,如果我将国家与第一个和后面的国家(“erst/folge”)结合起来,是否可以相互区分?每个国家应该有一层分成两层,一个是这个国家的第一次尝试,另一个是第二次尝试。区分这些子层的一个想法可能是我现在尝试的自定义 coloscale。如何在一张图中显示这两个数据?是否有可能加入两个数据集并仍然看到差异?

这是我的 html:

<!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.v2.js"></script>
<div id="option">
<input name="updateButton"
type="button"
value="Show Data for second Attemp"
onclick="updateSecond('folgeantraege_monatlich_2015_mitentscheidungenbisnovember.csv')" />

</div>

<div id="option">
<input name="updateButton"
type="button"
value="Show Data for first Attemp"
onclick="updateFirst('erstantraege_monatlich_2015_mitentscheidungenbisnovember.csv')" />

</div>

<div id="option">
<input name="updateButton"
type="button"
value="Show both"
onclick="updateBoth('erstantraege_monatlich_2015_mitentscheidungenbisnovember.csv', 'folgeantraege_monatlich_2015_mitentscheidungenbisnovember.csv')" />

</div>

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

<script>

var margin = {top: 20, right: 40, bottom: 30, left: 30};
var width = document.body.clientWidth - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;

var x = d3.time.scale()
.range([0, width]);

var y = d3.scale.linear()
.range([height-10, 0]);
var dateParser = d3.time.format("%Y-%m-%d").parse;

var stack = d3.layout.stack()
.offset("zero")
.values(function(d) { return d.values; })
.x(function(d) { return d.date; })
.y(function(d) { return d.value; });

var area = d3.svg.area()
.interpolate("cardinal")
.x(function(d) { return x(d.date); })
.y0(function(d) { return y(d.y0); })
.y1(function(d) { return y(d.y0 + d.y); });
var z = d3.scale.category20()

chart("erstantraege_monatlich_2015_mitentscheidungenbisnovember.csv");

var datearray = [];
var colorrange = [];

function chart(csvpath) {

// var dateParser = d3.time.format("%Y-%m-%d").parse;
// var margin = {top: 20, right: 40, bottom: 30, left: 30};
// var width = document.body.clientWidth - margin.left - margin.right;
// var height = 400 - margin.top - margin.bottom;

// var x = d3.time.scale()
// .range([0, width]);
//
// var y = d3.scale.linear()
// .range([height-10, 0]);

// var z = d3.scale.category20()

//var color = d3.scale.category10()

var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.months);

var yAxis = d3.svg.axis()
.scale(y);

var yAxisr = d3.svg.axis()
.scale(y);

// var stack = d3.layout.stack()
// .offset("zero")
// .values(function(d) { return d.values; })
// .x(function(d) { return d.date; })
// .y(function(d) { return d.value; });

var nest = d3.nest()
.key(function(d) { return d.Land});
// var nestFiltered = nest.filter(function(d){
// return d.Land != 'Total';
// })

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

var svg = d3.select(".chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.csv(csvpath, function(data) {
data.forEach(function(d) {
d.date = dateParser(d.Datum);
d.value = +d.ErstanträgeZahl;
});

//onsole.log(data);
var layers = stack(nest.entries(data));
console.log(nest.entries(data));

x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.y0 + d.y; })]);

svg.selectAll(".layer")
.data(layers)
.enter().append("path")
.attr("class", "layer")
.attr("d", function(d) { return area(d.values); })
.style("fill", function(d, i) { return z(i); });



svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);

svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + width + ", 0)")
.call(yAxis.orient("right"));

svg.append("g")
.attr("class", "y axis")
.call(yAxis.orient("left"));

});
}

function updateSecond(csvpath) {
var nest = d3.nest()
.key(function(d) { return d.Land});

d3.csv(csvpath, function(data) {
data.forEach(function(d) {
d.date = dateParser(d.Datum);
d.value = +d.Summe;
console.log(d.date);
console.log(d.value);
});
var layers = stack(nest.entries(data));

x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.y0 + d.y; })]);
d3.selectAll("path")
.data(layers)
.transition()
.duration(750)
.style("fill", function(d, i) { return z(i); })
.attr("d", function(d) { return area(d.values); });
svg.select(".y.axis") // change the y axis
.duration(750)
.call(yAxis);


});




}

function updateFirst(csvpath) {
var nest = d3.nest()
.key(function(d) { return d.Land});

d3.csv(csvpath, function(data) {
data.forEach(function(d) {
d.date = dateParser(d.Datum);
d.value = +d.ErstanträgeZahl;
console.log(d.date);
console.log(d.value);
});
var layers = stack(nest.entries(data));

x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.y0 + d.y; })]);
d3.selectAll("path")
.data(layers)
.transition()
.duration(750)
.style("fill", function(d, i) { return z(i); })
.attr("d", function(d) { return area(d.values); });
svg.select(".y.axis") // change the y axis
.duration(750)
.call(yAxis);



});
}
function updateBoth(csvpathFirst, csvpathSecond){
var nest = d3.nest()
.key(function(d) { return d.Land});

d3.csv(csvpathFirst, function(data1) {
d3.csv(csvpathSecond, function(data2) {

});

});


}
</script>

我的数据在我的 repo

编辑1:例如 csv1 包含

Datum,Land,Summe,Position,Antragsart,EntscheidungenInsgesamt,Asylberechtigt,Flüchtling,GewährungVonSubsidiäremSchutz,Abschiebungsverbot,UnbegrenzteAblehnungen,Ablehnung,sonstigeVerfahrenserledigungen
2015-01-01,Afghanistan,1129,5,Erst,418,0,105,4,58,66,6,179
2015-02-01,Afghanistan,969,5,Erst,849,9,186,16,100,131,10,397
2015-03-01,Afghanistan,885,5,Erst,1376,17,309,58,158,201,11,622
2015-04-01,Afghanistan,1119,6,Erst,1838,21,384,75,202,261,15,880
2015-05-01,Afghanistan,1151,6,Erst,2272,21,499,91,249,303,16,1093
2015-06-01,Afghanistan,2051,6,Erst,2911,23,683,132,313,377,19,1364
2015-07-01,Afghanistan,2104,6,Erst,3340,27,767,160,366,431,21,1568
2015-08-01,Afghanistan,2270,5,Erst,3660,28,922,172,409,453,23,1653
2015-09-01,Afghanistan,2724,4,Erst,4057,36,1049,201,455,475,26,1815
2015-10-01,Afghanistan,3770,4,Erst,4540,37,1188,234,516,538,29,1998
2015-11-01,Afghanistan,4929,0,Erst,5026,46,1340,253,620,623,49,2095

csv2包含

Datum,Antragsart,Land,Summe,Position,Datum2,Position,Herkunft,Entscheidungeninsgesamt,Asylberechtigt,Prozent,Flüchtling,Pronzent,GewährungvonsubisdiäremSchutz,Prozent,Abschiebungsverbot,Prozent,UnbegrenzteAblehnungen,Prozent,Ablehnung,Prozent,keinweiteresverfahren,Prozent,sonstigeVerfahrenserledigungen,Prozent
2015-01-01,Folge,Afghanistan,33,10,2015-01-01,10,Afghanistan,29,0,0,5,17.2,2,6.9,8,27.6,0,0,0,0,1,3.4,13,44.8
2015-02-01,Folge,Afghanistan,29,10,2015-02-01,10,Afghanistan,81,0,0,13,16,4,4.9,22,27.2,0,0,0,0,10,12.3,32,39.5
2015-03-01,Folge,Afghanistan,41,9,2015-03-01,9,Afghanistan,135,0,0,21,15.6,10,7.4,37,27.4,1,0.7,0,0,23,17,43,31.9
2015-04-01,Folge,Afghanistan,25,10,2015-04-01,10,Afghanistan,165,0,0,34,20.6,12,7.3,41,24.8,4,2.4,0,0,30,18.2,44,26.7
2015-05-01,Folge,Afghanistan,37,9,2015-05-01,9,Afghanistan,212,0,0,54,25.5,12,5.7,50,23.6,4,1.9,0,0,32,15.1,60,28.3
2015-06-01,Folge,Afghanistan,35,9,2015-06-01,9,Afghanistan,261,0,0,72,27.6,17,6.5,59,22.6,6,2.3,0,0,35,13.4,72,27.6
2015-07-01,Folge,Afghanistan,35,9,2015-07-01,9,Afghanistan,288,0,0,82,28.5,17,5.9,64,22.2,6,2.1,0,0,42,14.6,77,26.7
2015-08-01,Folge,Afghanistan,34,9,2015-08-01,9,Afghanistan,321,0,0,100,31.2,20,6.2,66,20.6,6,1.9,0,0,52,16.2,77,24
2015-09-01,Folge,Afghanistan,27,4,2015-09-01,9,Afghanistan,354,0,0,120,33.9,20,5.6,72,20.3,7,2,0,0,54,15.3,81,22.9
2015-10-01,Folge,Afghanistan,24,9,2015-10-01,9,Afghanistan,389,0,0,136,35,20,5.1,83,21.3,7,1.8,0,0,54,13.9,89,22.9
2015-11-01,Folge,Afghanistan,47,,,,,431,1,0.2,148,34.3,23,5.3,97,22.5,8,1.9,0,0,58,13.5,96,22.3

值(“Summe”)应该总结每个国家(阿富汗)每月的值,但也应该反射(reflect)他们自己的堆栈值(现在我正在尝试弄清楚如何使用 texture.jscustom scales 使用纹理来区分颜色,因为每个国家在这张图中都应该有自己的颜色,但正如我已经提到的,它们在子层中应该不同 Scribble当我尝试将两个 csv 字段放在一个文件中时,我得到的不完全是,但类似于此 Fail1 enter image description here你能给我一些如何归档子层的提示(数据结构/算法或我为实现此目的所采取的方法)以便我可以继续并尝试实现纹理吗?

提前致谢

最终编辑作为对 Cyrils 的回答:

var margin = {top: 20, right: 40, bottom: 30, left: 30};
var width = document.body.clientWidth - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;

var x = d3.time.scale()
.range([0, width]);

var y = d3.scale.linear()
.range([height-10, 0]);
var dateParser = d3.time.format("%Y-%m-%d").parse;

var stack = d3.layout.stack()
.offset("zero")
.values(function(d) { return d.values; })
.x(function(d) { return d.graphDate; })
.y(function(d) { return d.value; });

var area = d3.svg.area()
.interpolate("cardinal")
.x(function(d) { return x(d.graphDate); })
.y0(function(d) { return y(d.y0); })
.y1(function(d) { return y(d.y0 + d.y); });
var z = d3.scale.category20()

doInit();
updateFirst('data/all.csv');

function doInit(){
//make the svg and axis
xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.months);

yAxis = d3.svg.axis()
.scale(y);

yAxisr = d3.svg.axis()
.scale(y);
//make svg
var graph = d3.select(".chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

graph.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);

graph.append("g")
.attr("class", "y axis yright")
.attr("transform", "translate(" + width + ", 0)")
.call(yAxis.orient("right"));

graph.append("g")
.attr("class", "y axis yleft")

.call(yAxis.orient("left"));
}

function updateFirst(csvpath) {
var nest = d3.nest()
.key(function(d) { return d.Land+ "-" + d.Antragsart});
//console.log(nest);

d3.csv(csvpath, function(data) {
data.forEach(function(d) {
//console.log(data);
d.graphDate = dateParser(d.Datum);
d.value = +d.Summe;
d.type= d.Antragsart;
});

var layers = stack(nest.entries(data)).sort(function(a,b){return d3.ascending(a.key, b.key)});
console.log(layers);
x.domain(d3.extent(data, function(d) { return d.graphDate; }));
y.domain([0, d3.max(data, function(d) { return d.y0 + d.y; })]);
var k = d3.select("g .x")
.call(xAxis);


d3.select("g .yright")
.call(yAxis);
d3.select("g .yleft")
.call(yAxis);
d3.selectAll("defs").remove();
d3.select(".chart svg g").selectAll("path").remove();

d3.select(".chart svg g").selectAll("path")
.data(layers).enter().append("path")
//.style("fill", function(d, i) { console.log(d.key);return z(d.key); })
.attr("class", function(d){
var country = d.key.split("-")[0];
var src = d.key.split("-")[1];
return src;
})
.style("fill", function(d){
var country = d.key.split("-")[0];
var src = d.key.split("-")[1];
if (src === "Folge"){
var t = textures.lines().thicker(2).stroke(z(country));
d3.select(".chart").select("svg").call(t);
return t.url();
} else {
return z(country);
}
})
.attr("d", function(d) { return area(d.values); });
});
}

最佳答案

为了合并记录,我使用了 d3 队列。阅读 here

这样做的目的是通过 ajax 加载 2 个 CSV,并在加载时调用回调。

  queue()
.defer(d3.csv, csvpathFirst) //using queue so that callback is called after loading both CSVs
.defer(d3.csv, csvpathSecond)
.await(makeMyChart);

function makeMyChart(error, first, second) {
var data = [];

根据国家和csv制作嵌套函数

var nest = d3.nest() .key(函数(d) { 返回 d.Land + "-"+ d.src;//d.src 是第一个如果第一个 csv 第二个如果反之亦然 });

接下来我将像这样合并记录:

//iterate first
first.forEach(function(d) {
d.graphDate = dateParser(d.Datum);
d.value = +d.Summe;
d.src = "first"
data.push(d)
});
//iterate second
second.forEach(function(d) {
d.graphDate = dateParser(d.Datum);
d.value = +d.Summe;
d.src = "second"
data.push(d)
});
//sort layers on basis of country
var layers = stack(nest.entries(data)).sort(function(a, b) {
return d3.ascending(a.key, b.key)
});

像这样重新生成轴:

//regenerate the axis with new domains
var k = d3.select("g .x")
.call(xAxis);
d3.select("g .yright")
.call(yAxis);
d3.select("g .yleft")
.call(yAxis);

像这样删除所有旧路径和 defs DOM:

d3.selectAll("defs").remove();
d3.select(".chart svg g").selectAll("path").remove();

接下来根据国家和第一个 csv 和第二个 csv 添加样式填充。

  .style("fill", function(d) {
var country = d.key.split("-")[0];
var src = d.key.split("-")[1];
if (src === "first") {
//use texture.js for pattern
var t = textures.lines().thicker().stroke(z(country));
d3.select(".chart").select("svg").call(t);
return t.url();
} else {
return z(country);
}
})

工作代码 here

希望这对您有所帮助!

关于javascript - D3.js 中堆叠图的不同分层的想法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34500622/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com