【问题标题】:d3 stacked bar chart not updating correctlyd3堆积条形图未正确更新
【发布时间】:2015-02-25 18:59:04
【问题描述】:

我有一个使用 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>

之前.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

.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 内置的转换、退出和删除功能的不同方法,但似乎无法正确使用。

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

【问题讨论】:

    标签: javascript html csv d3.js


    【解决方案1】:

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

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

    并将变量更改为

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

    这样做之后,你可以删除里面的元素使用

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

    在您的 updateDatarevertData 方法中。

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

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

    【讨论】:

    • 谢谢!我现在得到了我想要的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 2016-10-13
    • 2013-06-26
    • 1970-01-01
    相关资源
    最近更新 更多