d3堆积条形图未正确更新

时间:2015-02-25 18:59:04

标签: javascript html csv d3.js

我有一个使用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中的函数的不同方法,但似乎无法正确使用。

有人可以指出我正确的方向吗?

1 个答案:

答案 0 :(得分:0)

而不是使用body追加。添加如下内容:

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

将变量更改为

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

执行此操作后,您可以使用

删除内部元素
$("#chart").empty();

在您的updateDatarevertData方法中。

或者,如果您只想以我主要使用的简单方式使用d3js代码

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