我有一个简单的水平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>
答案 0 :(得分:0)
我没有看完整件事,但是我注意到了一些错误:
1)不要使用ID作为多个事物的选择器。 ID应该是唯一的,如果您有多个具有相同ID的内容,则选择器可能无法正常工作。改为使用类。
2)添加数据时,请确保您添加的内容与您在初始selectAll()
方法中使用的选择项相匹配。例如,如果您有.selectAll('.rectClass')
,请确保提供您创建类rectClass
的所有元素,否则选择器和数据结构可能无法正常工作。
修复后,此示例显示更新/进入/退出模式的工作原理:example