[英]transition between two datasets, from a single line chart to a multiline chart, in d3
我正在嘗試構建從1條線到多條線的圖表。 我已經分別構建了兩個圖表,但是在合並它們時遇到了麻煩。 我的想法是,我要顯示每年出售的所有水果的總數,然后顯示每年出售的每種水果的數量。
這是我正在使用的模板: http : //bl.ocks.org/d3noob/a048edddbf83bff03a34
在我的代碼中,單行顯示得很好。 當我單擊更新時,軸將按其應有的方式進行更新,但數據不會更新。 任何幫助將不勝感激。
我的代碼在一個插件中,在這里: https ://plnkr.co/edit/dgwsGLIRbZ2qm7faEvSw?p = preview
代碼也在下面。
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body { font: 12px Arial;}
path {
stroke: #333;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
</style>
<body>
<div id="option">
<input name="updateButton" id="updateData" type="button" value="Update" />
<input name="revertButton" type="button" value="Revert" onclick="revertData()" />
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script>
var margin = {top: 30, right: 20, bottom: 30, left: 50},
width = 800 - margin.left - margin.right,
height = 470 - margin.top - margin.bottom;
var x = d3.scaleLinear().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
var xAxis = d3.axisBottom().scale(x)
.ticks(7)
.tickFormat(d3.format("d"))
var yAxis = d3.axisLeft().scale(y)
.ticks(5);
var valueline = d3.line()
.x(function(d) { return x(d.Year); })
.y(function(d) { return y(d.Count); });
var svg = d3.select("body")
.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("datab.csv", function(error, data2) {
d3.csv("dataa.csv", function(error, data) {
data.forEach(function(d) {
d.Year = +d.Year;
d.Count = +d.Count;
});
x.domain(d3.extent(data, function(d) { return d.Year; }));
y.domain([0, d3.max(data, function(d) { return d.Count; })]);
dataNest1 = d3.nest()
.key(function(d) {return d.Type;})
.entries(data);
var result1 = dataNest1.filter(function(val,idx, arr){
return $("." + val.key)
})
var calls = d3.select("svg").selectAll(".line")
.data(result1, function(d){return d.key})
var color1 = d3.scaleOrdinal().range(["#333", "none", "none", "none", "none", "none"]);
calls.enter().append("path")
.attr("class", "line")
.attr("stroke","#333")
.attr("d", function(d){
return valueline(d.values)
})
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
d3.select('#updateData').on('click',function(){
updateData(data2)
})
});
});
function updateData(data2) {
data2.forEach(function(d) {
d.Year = +d.Year;
d.Count = +d.Count;
});
dataNest = d3.nest()
.key(function(d) {return d.Descriptor;})
.entries(data2);
var result = dataNest.filter(function(val,idx, arr){
return $("." + val.key)
})
x.domain(d3.extent(data2, function(d) { return d.Year; }));
y.domain([0, d3.max(data2, function(d) { return d.Count; })]);
var svg = d3.select("body").transition();
svg.selectAll('.circle').duration(0).remove()
d3.select("svg").selectAll(".line")
.data(result, function(d){return d.key})
d3.select("svg").selectAll("path.line")
.transition()
.duration(700)
.style("stroke", "#333")
.attr("d", function(d){
return valueline(d.values)
});
// svg.select(".line") // change the line
// .duration(750)
// .attr("d", valueline(rats));
svg.select(".x.axis")
.transition()
.duration(750)
.call(xAxis);
svg.select(".y.axis")
.duration(750)
.call(yAxis);
}
function revertData() {
// Get the data again
d3.csv("totalsbyyear.csv", function(error, data) {
data.forEach(function(d) {
d.Year = +d.Year;
d.Count = +d.Count;
});
// Scale the range of the data again
x.domain(d3.extent(data, function(d) { return d.Year; }));
y.domain([0, d3.max(data, function(d) { return d.Count; })]);
// Select the section we want to apply our changes to
var svg = d3.select("body").transition();
// Make the changes
svg.select(".line") // change the line
.duration(750)
.attr("d", valueline(data));
svg.select(".x.axis") // change the x axis
.duration(750)
.call(xAxis);
svg.select(".y.axis") // change the y axis
.duration(750)
.call(yAxis);
});
}
</script>
</body>
這里有一些問題。 第一個是您的數據集非常不同,我看不到代碼中的任何地方來補償同一年中存在多個不同的結果。 您需要通過修改csv文件或在updateData函數中僅提取單個水果來解決此問題。
我已經對您的監聽器進行了一些更改,這些更新將允許updateFunction起作用,但是如果不修復輸入數據,那將不會有什么實質性的影響。
https://plnkr.co/edit/DSg09NWPrBADLLbcL5cx?p=preview
需要解決的主要問題是
d3.select("svg").selectAll("path.line")
.data(result, function(d){return d.key})
.transition()
.duration(700)
.style("stroke", "#337")
.attr("d", function(d){
return valueline(result)
});
並將d3.csv放在updateData函數中的datab.csv
調用上,而不是將其包裝在主表創建函數周圍。
我的問題可能不清楚。 我想出了要使其按預期工作所需要做的事情。 代碼在這里:
https://plnkr.co/edit/YrABkbc8l9oeT1ywMspy?p=preview
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body { font: 12px Arial;}
path {
stroke: #333;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
</style>
<body>
<div id="option">
<input name="updateButton" id="updateData" type="button" value="Update" />
<input name="revertButton" type="button" value="Revert" onclick="revertData()" />
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script>
var margin = {top: 30, right: 200, bottom: 30, left: 50},
width = 850 - margin.left - margin.right,
height = 470 - margin.top - margin.bottom;
var x = d3.scaleLinear().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
var xAxis = d3.axisBottom().scale(x)
.ticks(7)
.tickFormat(d3.format("d"))
var yAxis = d3.axisLeft().scale(y)
.ticks(5);
var valueline = d3.line()
.x(function(d) { return x(d.Year); })
.y(function(d) { return y(d.Count); });
var svg = d3.select("body")
.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("datab.csv", function(error, data2) {
d3.csv("dataa.csv", function(error, data) {
data.forEach(function(d) {
d.Year = +d.Year;
d.Count = +d.Count;
});
x.domain(d3.extent(data, function(d) { return d.Year; }));
y.domain([0, d3.max(data, function(d) { return d.Count; })]);
svg.append("path")
.attr("class", "line")
.attr("d", valueline(data));
svg.append("text")
.attr("transform", function(d) { return "translate(" + x(2017) + "," + y(35074) + ")"; })
.attr("x", 3)
.attr("dy", "0.35em")
.attr('class','toplinetext')
.style("font", "10px sans-serif")
.text(function(d) { return "All"; });
circles = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr('class','circle')
.attr('cx',function(d){ return x(d.Year)})
.attr('cy',function(d){ return y(d.Count)})
.attr('r',3)
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.exit().remove();
d3.select('#updateData').on('click',function(){
updateData(data2)
})
});
});
function updateData(data2) {
data2.forEach(function(d) {
d.Year = +d.Year;
d.Count = +d.Count;
});
var notapples = data2.filter(function(d){return d.Descriptor == "Peach" || d.Descriptor == "Pear" || d.Descriptor == "Plum" || d.Descriptor == "Banana"})
dataNest = d3.nest()
.key(function(d) {return d.Descriptor;})
.entries(notapples);
var result = dataNest.filter(function(val,idx, arr){
return $("." + val.key)
})
$('.toplinetext').text('Apples');
x.domain(d3.extent(data2, function(d) { return d.Year; }));
y.domain([0, d3.max(data2, function(d) { return d.Count; })]);
var svg = d3.select("body").transition();
svg.selectAll('.circle').duration(0).remove()
var typeOfCall = d3.select("svg").selectAll(".dline")
.data(result, function(d){return d.key})
.enter().append("g")
.attr("class", function(d){return "type " + d.key})
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
var color2 = d3.scaleOrdinal().range(["#ff0000", "#333", "#333", "#333", "#333", "#333"]);
typeOfCall.append("path")
.attr("height", 0)
.transition()
.duration(700)
.attr("class", "line")
.style("stroke", function(d,i) { return color2(d.key); })
.attr("d", function(d){
return valueline(d.values)
});
typeOfCall.append("text")
.datum(function(d) { return {id: d.Descriptor, value: d.values[d.values.length - 1]}; })
.attr("transform", function(d) { return "translate(" + x(d.value.Year) + "," + y(d.value.Count) + ")"; })
.attr("x", 3)
.attr("dy", "0.35em")
.style("font", "10px sans-serif")
.text(function(d) { return d.value.Descriptor; });
typeOfCall.exit().remove();
apples = data2.filter(function(d){return d.Descriptor == "Apple"})
svg.select(".line")
.duration(750)
.attr("d", valueline(apples));
svg.select(".x.axis")
.transition()
.duration(750)
.call(xAxis);
svg.select(".y.axis")
.duration(750)
.call(yAxis);
}
function revertData() {
// Get the data again
d3.csv("totalsbyyear.csv", function(error, data) {
data.forEach(function(d) {
d.Year = +d.Year;
d.Count = +d.Count;
});
$('.toplinetext').text('All');
$('.Peach,.Pear,.Banana,.Plum').remove();
// Scale the range of the data again
x.domain(d3.extent(data, function(d) { return d.Year; }));
y.domain([0, d3.max(data, function(d) { return d.Count; })]);
// Select the section we want to apply our changes to
var svg = d3.select("body").transition();
// Make the changes
svg.select(".line") // change the line
.duration(750)
.attr("d", valueline(data));
svg.select(".x.axis") // change the x axis
.duration(750)
.call(xAxis);
svg.select(".y.axis") // change the y axis
.duration(750)
.call(yAxis);
});
}
</script>
</body>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.