d3 堆叠条形图未正确更新
d3 stacked bar chart not updating correctly
我有一个使用 d3 创建的堆叠条形图。
我正在尝试使用按钮使用来自不同 .csv 的数据更新我的条形图。
到目前为止,这是我的代码:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<style>
#title {
font-family: serif;
font-variant: small-caps;
font-size: 20px;
text-align: left;
text-decoration: underline;
text-shadow: 2px 2px 2px gray;
}
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
.exit {
opacity: 0;
}
</style>
</head>
<body>
<p id="title">Server/Client Relationship with Groups Algorithm</p>
<div id="option">
<input name="updateButton"
type="button"
value="Update"
onclick="updateData()" />
<input name="revertButton"
type="button"
value="Revert"
onclick="revertData()" />
</div>
<script type="text/javascript" src="d3.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 1100 - margin.left - margin.right,
height = 700 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.rangeRound([height, 0]);
var color = d3.scale.category20();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
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("before.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Servers"; }));
data.forEach(function(d) {
var y0 = 0;
d.ages = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.ages[d.ages.length - 1].y1;
});
x.domain(data.map(function(d) { return d.Servers; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Number of Clients");
var servers = svg.selectAll(".servers")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x(d.Servers) + ",0)"; });
servers.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
var legend = svg.selectAll(".legend")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
});
function updateData() {
d3.csv("after.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Servers"; }));
data.forEach(function(d) {
var y0 = 0;
d.ages = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.ages[d.ages.length - 1].y1;
});
x.domain(data.map(function(d) { return d.Servers; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]);
svg.select(".x.axis").transition()
.duration(750)
.call(xAxis);
svg.select(".y.axis").transition()
.duration(750)
.call(yAxis);
var servers = svg.selectAll(".servers")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x(d.Servers) + ",0)"; });
servers.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.transition()
servers.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
});
}
function revertData() {
d3.csv("before.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Servers"; }));
data.forEach(function(d) {
var y0 = 0;
d.ages = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.ages[d.ages.length - 1].y1;
});
x.domain(data.map(function(d) { return d.Servers; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]);
svg.select(".x.axis").transition()
.duration(750)
.call(xAxis);
svg.select(".y.axis").transition()
.duration(750)
.call(yAxis);
var servers = svg.selectAll(".servers")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x(d.Servers) + ",0)"; });
servers.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.transition()
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
});
}
</script>
</body>
before.csv:
Servers,Group 1,Group 2,Group 3,Group 4,Group 5,Group 6,Group 7,Group 8,Group 9,Group 10
Server 1,2,0,0,0,0,3,1,0,0,1
Server 2,1,0,2,0,0,0,2,1,1,0
Server 3,2,0,1,0,2,2,1,0,0,0
Server 4,0,0,1,0,0,2,0,2,1,0
Server 5,0,0,0,2,0,1,1,1,1,3
Server 6,5,0,0,1,0,1,1,1,0,3
Server 7,1,0,2,3,0,0,0,0,0,2
Server 8,3,1,0,1,0,0,1,1,1,0
Server 9,0,1,0,0,0,0,1,0,1,0
Server 10,1,2,1,1,0,2,2,2,0,1
Server 11,2,1,1,0,1,2,2,2,3,0
Server 12,1,0,1,1,0,0,0,0,2,1
after.csv:
Servers,Group 1,Group 2,Group 3,Group 4,Group 5,Group 6,Group 7,Group 8,Group 9,Group 10
Server 1,0,0,0,0,0,13,0,0,0,0
Server 2,0,0,9,0,0,0,12,0,0,0
Server 3,0,0,0,0,3,0,0,0,0,0
Server 4,0,0,0,0,0,0,0,10,10,0
Server 5,0,0,0,0,0,0,0,0,0,11
Server 6,18,0,0,0,0,0,0,0,0,0
Server 7,0,0,0,9,0,0,0,0,0,0
Server 8,0,0,0,0,0,0,0,0,0,0
Server 9,0,0,0,0,0,0,0,0,0,0
Server 10,0,5,0,0,0,0,0,0,0,0
Server 11,0,0,0,0,0,0,0,0,0,0
Server 12,0,0,0,0,0,0,0,0,0,0
问题是每当我按下按钮而不是只显示新图表时,图表就会重叠。
我是 d3 的新手,所以我很难做到在按下按钮后只显示指定的图形。
我研究了使用 d3 中内置的转换、退出和删除功能的不同方法,但似乎无法正确使用。
有人能给我指出正确的方向吗?
而不是使用 body
追加。添加如下内容:
<div id="chart"></div>
并将变量更改为
var svg = d3.select("#chart").append("svg")....
这样做之后,您可以使用
删除里面的元素
$("#chart").empty();
在您的 updateData
和 revertData
方法中。
或者,如果您只想使用 d3js
代码,我主要使用的是一种简单的方式
d3.select("svg").remove();
我有一个使用 d3 创建的堆叠条形图。
我正在尝试使用按钮使用来自不同 .csv 的数据更新我的条形图。
到目前为止,这是我的代码:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<style>
#title {
font-family: serif;
font-variant: small-caps;
font-size: 20px;
text-align: left;
text-decoration: underline;
text-shadow: 2px 2px 2px gray;
}
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
.exit {
opacity: 0;
}
</style>
</head>
<body>
<p id="title">Server/Client Relationship with Groups Algorithm</p>
<div id="option">
<input name="updateButton"
type="button"
value="Update"
onclick="updateData()" />
<input name="revertButton"
type="button"
value="Revert"
onclick="revertData()" />
</div>
<script type="text/javascript" src="d3.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 1100 - margin.left - margin.right,
height = 700 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.rangeRound([height, 0]);
var color = d3.scale.category20();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
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("before.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Servers"; }));
data.forEach(function(d) {
var y0 = 0;
d.ages = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.ages[d.ages.length - 1].y1;
});
x.domain(data.map(function(d) { return d.Servers; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Number of Clients");
var servers = svg.selectAll(".servers")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x(d.Servers) + ",0)"; });
servers.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
var legend = svg.selectAll(".legend")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
});
function updateData() {
d3.csv("after.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Servers"; }));
data.forEach(function(d) {
var y0 = 0;
d.ages = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.ages[d.ages.length - 1].y1;
});
x.domain(data.map(function(d) { return d.Servers; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]);
svg.select(".x.axis").transition()
.duration(750)
.call(xAxis);
svg.select(".y.axis").transition()
.duration(750)
.call(yAxis);
var servers = svg.selectAll(".servers")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x(d.Servers) + ",0)"; });
servers.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.transition()
servers.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
});
}
function revertData() {
d3.csv("before.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Servers"; }));
data.forEach(function(d) {
var y0 = 0;
d.ages = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.ages[d.ages.length - 1].y1;
});
x.domain(data.map(function(d) { return d.Servers; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]);
svg.select(".x.axis").transition()
.duration(750)
.call(xAxis);
svg.select(".y.axis").transition()
.duration(750)
.call(yAxis);
var servers = svg.selectAll(".servers")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x(d.Servers) + ",0)"; });
servers.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.transition()
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
});
}
</script>
</body>
before.csv:
Servers,Group 1,Group 2,Group 3,Group 4,Group 5,Group 6,Group 7,Group 8,Group 9,Group 10
Server 1,2,0,0,0,0,3,1,0,0,1
Server 2,1,0,2,0,0,0,2,1,1,0
Server 3,2,0,1,0,2,2,1,0,0,0
Server 4,0,0,1,0,0,2,0,2,1,0
Server 5,0,0,0,2,0,1,1,1,1,3
Server 6,5,0,0,1,0,1,1,1,0,3
Server 7,1,0,2,3,0,0,0,0,0,2
Server 8,3,1,0,1,0,0,1,1,1,0
Server 9,0,1,0,0,0,0,1,0,1,0
Server 10,1,2,1,1,0,2,2,2,0,1
Server 11,2,1,1,0,1,2,2,2,3,0
Server 12,1,0,1,1,0,0,0,0,2,1
after.csv:
Servers,Group 1,Group 2,Group 3,Group 4,Group 5,Group 6,Group 7,Group 8,Group 9,Group 10
Server 1,0,0,0,0,0,13,0,0,0,0
Server 2,0,0,9,0,0,0,12,0,0,0
Server 3,0,0,0,0,3,0,0,0,0,0
Server 4,0,0,0,0,0,0,0,10,10,0
Server 5,0,0,0,0,0,0,0,0,0,11
Server 6,18,0,0,0,0,0,0,0,0,0
Server 7,0,0,0,9,0,0,0,0,0,0
Server 8,0,0,0,0,0,0,0,0,0,0
Server 9,0,0,0,0,0,0,0,0,0,0
Server 10,0,5,0,0,0,0,0,0,0,0
Server 11,0,0,0,0,0,0,0,0,0,0
Server 12,0,0,0,0,0,0,0,0,0,0
问题是每当我按下按钮而不是只显示新图表时,图表就会重叠。
我是 d3 的新手,所以我很难做到在按下按钮后只显示指定的图形。
我研究了使用 d3 中内置的转换、退出和删除功能的不同方法,但似乎无法正确使用。
有人能给我指出正确的方向吗?
而不是使用 body
追加。添加如下内容:
<div id="chart"></div>
并将变量更改为
var svg = d3.select("#chart").append("svg")....
这样做之后,您可以使用
删除里面的元素$("#chart").empty();
在您的 updateData
和 revertData
方法中。
或者,如果您只想使用 d3js
代码,我主要使用的是一种简单的方式
d3.select("svg").remove();