Derzeit habe ich ein Flächendiagramm, das die Bereiche mehrerer Datenpfade anzeigt. Ich suche jedoch nach einer Möglichkeit, dies in ein gestapeltes Flächendiagramm umzuwandeln. Grundsätzlich möchte ich, dass die Datensätze übereinander gestapelt werden, sodass sie sichtbar sind und nicht von anderen größeren Bereichen verdeckt werden. Ich habe zwei Beispiele gefunden: http://bl.ocks.org/mbostock/3885211 und http://bl.ocks.org/mbostock/3020685. Das Problem, das ich habe, ist, dass meine Daten in einem ganz anderen Format sind und ich bin mir auch nicht sicher, wie d3 das tatsächlich funktioniert. Konzeptionell fällt es mir schwer zu verstehen, was d3 hinter den Kulissen macht. Mein Verständnis ist, dass es die Unterschiede zwischen der letzten hinzugefügten Schicht berechnet, aber es scheint, dass das ohne Verwendung von Stapeln getan werden könnte.Wie kann ich einen vorhandenen d3-Bereich in einen gestapelten Bereich umwandeln?
ist Meine Daten wie folgt strukturiert:
// datasets { data1: Array[10], data2: Array[10], data3: Array[10] }
// data1 [{value: 2340234, year: 1945}...]
Und die Zeichenfunktion ist dies:
function draw(series) {
var data1 = [];
var data2 = [];
var data3 = [];
var prop = 0;
for (prop in series) {
var current = series[prop];
data1.push({value: current.data1, year: current.year});
data2.push({value: current.data2, year: current.year});
data3.push({value: current.data3, year: current.year});
}
var datasets = {
data1: data1,
data2: data2,
data3: data3
};
// updated
var layers = [datasets.data1, datasets.data2, datasets.data3];
var height = 800;
var width = window.innerWidth - 100;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
// updated
var stack = d3.layout.stack()
.values(function(d) { return d.values; });
/
var stacked = stack(layers.map(function(layer) {
return {
values: layer.map(function(d) {
return { year: new Date(d.year, 0), y: +d.value};
})
};
}));
var area = d3.svg.area()
.x(function(d) {
console.log(x(d.year) + ' is the result of x(d.year)')
return x(d.year);
})
// d.year is defined correctly
.y0(height)
.y1(function(d) {
console.log(y(d.value) + ' is the result of y(d.value)')
return y(d.value);
});
// d is Object {year: Sat Jan 01 2005 00:00:00 GMT-0800 (PST), y: 47390331, y0: 0}
// here y(d.value) returns NaN for some reason
var svg = d3.select('body').append("svg")
.append("g")
.attr("transform", "translate(" + 120 + "," + 30 + ")");
// Calculate max value
var maxY = 0;
var minY = 0;
series.forEach(function(object) {
for (var key in object) {
if (object[key] > maxY) {
maxY = object[key];
}
}
});
// Calculate min value
series.forEach(function(object) {
for (var key in object) {
if (object[key] < minY) {
minY = object[key];
} else if (minY === 0) {
continue;
}
}
});
var minYear = new Date("1945");
var maxYear = new Date("2015");
x.domain([minYear, maxYear]);
y.domain([minY, maxY]);
svg.append("path").data(stacked)
.attr('d', function(d) { return area(d.values); });
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
}
Was ist der beste Weg, dies zu einer gestapelten Flächendiagramm zu konvertieren?
bearbeiten
behoben. Lösung inklusive Berechnungsbereich wie im Beispiel zu sehen:
var area = d3.svg.area()
.x(function(d) { return x(d.year); })
.y0(function(d) { return y(d.y0); })
.y1(function(d) { return y(d.y0 + d.y); });