简体   繁体   English

d3堆积条形图未正确更新

[英]d3 stacked bar chart not updating correctly

I have a stacked bar chart created using d3. 我有一个使用d3创建的堆积条形图。

I am trying to update my bar graph with data from a different .csv using buttons. 我正在尝试使用来自不同.csv的数据使用按钮更新我的条形图。

Here is my code so far: 到目前为止,这是我的代码:

 <!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: 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: 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 

The problem is that whenever I press the buttons instead of it just displaying the new graph, the graphs overlap. 问题在于,每当我按下按钮而不是仅显示新图形时,图形就会重叠。

I'm fairly new to d3, so I was having trouble making it so that after a button press only the specified graph is displayed. 我是d3的新手,所以我在制作它时遇到了麻烦,按下按钮后只显示指定的图形。

I've looked into different ways to use the transition, exit, and remove functions that are built into d3, but can't seem to get it right. 我已经研究了使用转换,退出和删除内置到d3中的函数的不同方法,但似乎无法正确使用它。

Can someone please point me in the right direction? 有人可以指点我正确的方向吗?

Instead of using the body to append. 而不是使用body追加。 Add something like this: 添加如下内容:

<div id="chart"></div>

And change the variable to 并将变量更改为

var svg = d3.select("#chart").append("svg")....

After doing this, you can remove inside the elements inside using 执行此操作后,您可以删除内部元素内部使用

$("#chart").empty();

in your updateData and revertData method. 在您的updateDatarevertData方法中。

Or if you want use only d3js code in a simply way which I use mostly 或者,如果您只想以我主要使用的简单方式使用d3js代码

d3.select("svg").remove(); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM