我有一个甘特图,我用D3构建了一个相关的过滤器,用户可以选择最短的时间,最长的时间等。所以当过滤器改变时,xAxis会修改并且一些元素随时间移动。< / p>
A还绘制了一些连接过滤器所选元素的线条。
当在滤镜中进行选择时,我删除线条(通过移除),更改矩形的颜色,并将轴更改为新的时间刻度。但是,当我去绘制新线条时,在更新之前,引用将从旧矩形中拉出。
以下是显示问题的JSFiddle: https://jsfiddle.net/3afumu4d/12/
要查看问题:点击过滤器图标,然后选择&#34;最短时间&#34;,箭头将重绘但位置错误。它是在过渡之前将它们绘制在矩形的位置。
这是我的更新方法。
function updateData(){
//remove the lines
d3.select("#barsGroup").selectAll('line').remove();
//remove the arrows
d3.select("#barsGroup").selectAll('polyline').remove();
//based on selection, calculate start and end times
var checked = $('input[type=radio][name=timeline]:checked').attr('id');
taskArray.forEach(function(entry){
//if it is selected calculate its new start time.
if(illuminate(entry,checked)){
var newVal = root.startYear + getDelay(entry, checked);
entry.startTime = newVal.toString();
entry.endTime = (newVal + entry.time).toString();
}
});
var minX = d3.min(taskArray, function(d) {return dateFormat.parse(d.startTime);});
var maxX = d3.max(taskArray, function(d) {return dateFormat.parse(d.endTime);});
timeScale = d3.time.scale().domain([minX,maxX]).range([0,w-150]);
//update the boxes
var chart = d3.select("#innercontainer").transition();
//get all the rectangles, update all the rectangles
var updateBoxes = d3.select("#barsGroup").selectAll('rect')
.data(taskArray)
.transition()
.attr("x", function(d){return timeScale(dateFormat.parse(d.startTime)) + sidePadding;})
.attr("y", function(d, i){return i*gap + topPadding;})
.attr("width", function(d){return (timeScale(dateFormat.parse(d.endTime))-timeScale(dateFormat.parse(d.startTime)))})
.attr("fill", function(d){
for (var i = 0; i < categories.length; i++){
if (d.component == categories[i]){
//if true matches selection in filter
var checked = $('input[type=radio][name=timeline]:checked').attr('id');
if(illuminate(d,checked)){
return d3.rgb(colorScale(i));
}else{
return d3.rgb(colorScale(i)).darker(5);
}
//else show darker
}
}
})
.attr("opacity", function(d){
for (var i = 0; i < categories.length; i++){
if (d.component == categories[i]){
//if true matches selection in filter
var checked = $('input[type=radio][name=timeline]:checked').attr('id');
if(illuminate(d,checked)){
return 1.0;
}else{
return 0.4;
}
//else show darker
}
}
});
//Update the text boxes
var textlist = d3.select("#barsGroup").selectAll('text')
.data(taskArray)
.transition()
.attr("x", function(d){
return (timeScale(dateFormat.parse(d.endTime))-timeScale(dateFormat.parse(d.startTime)))/2 + timeScale(dateFormat.parse(d.startTime)) + sidePadding;
})
.attr("y", function(d, i){
return i*gap + 8+ topPadding;
})
.attr("fill", function(d){
for (var i = 0; i < categories.length; i++){
if (d.component == categories[i]){
//if true matches selection in filter
var checked = $('input[type=radio][name=timeline]:checked').attr('id');
if(illuminate(d,checked)){
return "#fff";
}else{
return "#3f3f3f";
}
}
}
}
);
//update grid lines
//scale the axis
xAxis = d3.svg.axis()
.scale(timeScale)
.orient('bottom')
.ticks(d3.time.year, 5) //TODO: change to years (skip every ten?)
.tickSize(-h+topPadding+20, 0, 0)
.tickFormat(d3.time.format('%Y'))
d3.select(".grid")
.transition()
.duration(750)
.call(xAxis)
.selectAll("text")
.style("text-anchor", "middle")
.attr("fill", "#fff")
.attr("stroke", "none")
.attr("font-size", 10)
.attr("dy", "1em")
.each("end",drawArrows(taskArray,checked));;
}
drawArrows方法是通过甘特图向新突出显示的路径添加箭头的方法。但它没有获得新的价值。
有没有办法在DOM元素更新后触发drawArrows方法?
答案 0 :(得分:0)
我在另一个Stack Overflow问题中找到了答案。
基本上我需要等待所有“rect”转换完成,因此更新了rect x,y,width值。
我使用了此处的endAll方法:d3.js transition end event