【发布时间】:2014-07-21 19:40:55
【问题描述】:
我有一个简单的水平 D3 堆叠条形图。我使用下拉菜单选择不同的数据集以更新图表值。
如果 ds1 和 ds2 具有相同数量的数据,即 ds1 有 2 个数据点,ds2 有 2 个数据点,则过渡是平滑的,并且我的值会很好地更新。
但是,如果我有两个数据点数量不同的数据集,即 ds1 有 3 个数据点,而 ds2 只有 2 个或可能 4 个数据点,我无法让 Enter、Update 和 Exit 正常工作。
我认为这与 D3 堆栈函数有关,该函数将值转换为不构成 D3 中更新和退出方法的一部分的对象。
如果你能告诉我我应该做什么,将不胜感激?我的完整代码粘贴在下面。
<!DOCTYPE html>
<html>
<head>
<title>Update horizontal stacked bar chart</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<div >
<select id="dropdown" onchange="updateData()">
<!--need blank value in order to have title in selection-->
<option value="ds1">ds1</option>
<option value="ds2">ds2</option>
<option value="ds3">ds3</option>
<option value="ds4">ds4</option>
</select>
</div>
<script type="text/javascript">
var w = 1500,
h = 300;
var rectW = 100 * 5;
var color = d3.scale.ordinal()
.range(["#1459D9", "#daa520","#F7C319"]);
var ds1 = [[{x:0,y:15}],[{x:0,y:85}]];
var ds2 = [[{x:0,y:35}],[{x:0,y:65}]];
var ds3 = [[{x:0,y:10}],[{x:0,y:20}],[{x:0,y:70}]];
var ds4 = [[{x:0,y:60}]];
//Set up stack method
var stack = d3.layout.stack();
//Data, stacked
stack(ds1);
var canvas = d3.select("body")
.append("svg")
.attr("width",w)
.attr("height",300)
;
var appending = canvas.selectAll("q")
.data(ds1)
.enter()
.append("g")
.style("fill", function(d,i){return color(i);})
;
appending.selectAll("stackrect")
.data(function (d){return d;})
.enter()
.append("rect")
.attr("id","recth")
.attr("x",function (d){return (w *.50 - (rectW/2)) + d.y0 * 5 ;})
.attr("y",90)
.attr("width",function (d){return (d.y * 5 );})
.attr("height",50);
function updateData() {
stack(eval("("+dropdown.value+")"));
appending.data(eval("("+dropdown.value+")"));
//ds1 and ds2 equal number of datum. Update works fine.
appending.selectAll("#recth")
.data(function (d){return d;})
.transition().duration(600)
.style("opacity", 0.5)
.transition().duration(600)
.style("opacity", 1.0)
.attr("x",function (d){return (w *.50 - (rectW/2)) + d.y0 * 5 ;})
.attr("y",90)
.attr("width",function (d){return (d.y * 5 );})
.attr("height",50);
//update method not working
appending.selectAll("#recth")
.data(function (d){return d;})
.enter()
.append("rect")
.transition().duration(600)
.style("opacity", 0.5)
.transition().duration(600)
.style("opacity", 1.0)
.attr("x",function (d){return (w *.50 - (rectW/2)) + d.y0 * 5 ;})
.attr("y",90)
.attr("width",function (d){return (d.y * 5 );})
.attr("height",50);
//exit method not working
appending.selectAll("#recth")
.data(function (d){return d;})
.exit()
.transition().duration(600)
.style("opacity", 0.5)
.transition().duration(600)
.style("opacity", 1.0)
.attr("x",function (d){return (w *.50 - (rectW/2)) + d.y0 * 5 ;})
.attr("y",90)
.attr("width",function (d){return (d.y * 5 );})
.attr("height",50)
.remove();
}
</script>
</body>
</html>
【问题讨论】:
-
@ckersch 是正确的,您应该使用
class而不是id。 HERE 是 HTML5 规范所说的,这几乎是所有其他 HTML 规范所说的,它应该是独一无二的。您“发现 id 在其他示例中工作得非常好”这一事实仅意味着您很幸运能够使用能够容忍呈现无效标记的浏览器。 -
我同意你所说的两个。但是,由于在上面的示例中我只调用了一个元素,所以使用 id 就可以了。上课也试过了,还是不行。
标签: javascript html d3.js