我正在尝试构建从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>
答案 0 :(得分:0)
这里有一些问题。第一个是您的数据集非常不同,我看不到代码中的任何地方来补偿同一年中存在多个不同的结果。您需要通过修改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
调用中,而不是将其包装在主表创建函数周围。
答案 1 :(得分:0)
我可能不清楚自己问的问题。我想出了要使其按预期工作所需要做的事情。代码在这里:
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>