2014-08-29 184 views
1

我正在使用d3.js处理径向直方图图表。悬停转换停止初始转换

问题如下:我有一个初始转换,使条“增长”到它们的实际高度(eyecandy)。

这一切工作正常。现在我想添加悬停转场,即悬停状态结束时,所有项目的不透明度应该在悬停时过渡到.5,并返回到1。

这也适用于自己。

如果悬停状态在初始转换仍然发生时触发,它会停止工作。然后,初始转换停止,杆不能达到最终高度。

问题:如何使两个转换一起工作,以便悬停转换不会停止初始转换?

Here is a jsfiddle。这里是代码本身:

<script src="http://d3js.org/d3.v3.js"></script> 

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

<script> 
    var margin = { 
      top: 0, 
      right: 0, 
      bottom: 0, 
      left: 0 
     }, 
     width = 500 - margin.left - margin.right, 
     height = 500 - margin.top - margin.bottom; 

    var arcMin = 150; 
    var arcMax = 250; 
    var pi = Math.PI; 

    var color = d3.scale.category10(); 


    var data = [ 
     { 
      "value": 20, 
      "category": "category1" 
    }, 
     { 
      "value": 24, 
      "category": "category1" 
    }, 
     { 
      "value": 9, 
      "category": "category1" 
    }, 
     { 
      "value": 93, 
      "category": "category1" 
    }, 
     { 
      "value": 82, 
      "category": "category1" 
    }, 
     { 
      "value": 56, 
      "category": "category1" 
    }, 
     { 
      "value": 29, 
      "category": "category1" 
    }, 
     { 
      "value": 6, 
      "category": "category1" 
    }, 
     { 
      "value": 10, 
      "category": "category1" 
    }, 
     { 
      "value": 4, 
      "category": "category1" 
    }, 
     { 
      "value": 45, 
      "category": "category1" 
    }, 
     { 
      "value": 25, 
      "category": "category1" 
    }, 
     { 
      "value": 26, 
      "category": "category2" 
    }, 
     { 
      "value": 53, 
      "category": "category2" 
    }, 
     { 
      "value": 60, 
      "category": "category2" 
    }, 
     { 
      "value": 87, 
      "category": "category2" 
    }, 
     { 
      "value": 77, 
      "category": "category2" 
    }, 
     { 
      "value": 40, 
      "category": "category2" 
    }, 
     { 
      "value": 12, 
      "category": "category2" 
    }, 
     { 
      "value": 80, 
      "category": "category2" 
    }, 
     { 
      "value": 23, 
      "category": "category2" 
    }, 
     { 
      "value": 53, 
      "category": "category2" 
    }, 
     { 
      "value": 26, 
      "category": "category2" 
    }, 
     { 
      "value": 34, 
      "category": "category2" 
    }, 
     { 
      "value": 79, 
      "category": "category2" 
    }, 
     { 
      "value": 98, 
      "category": "category3" 
    }, 
     { 
      "value": 1, 
      "category": "category3" 
    }, 
     { 
      "value": 13, 
      "category": "category3" 
    }, 
     { 
      "value": 80, 
      "category": "category3" 
    }, 
     { 
      "value": 66, 
      "category": "category3" 
    }, 
     { 
      "value": 5, 
      "category": "category3" 
    }, 
     { 
      "value": 36, 
      "category": "category3" 
    }, 
     { 
      "value": 74, 
      "category": "category3" 
    }, 
     { 
      "value": 32, 
      "category": "category3" 
    }, 
     { 
      "value": 4, 
      "category": "category3" 
    }, 
     { 
      "value": 54, 
      "category": "category3" 
    }, 
     { 
      "value": 8, 
      "category": "category3" 
    }, 
     { 
      "value": 64, 
      "category": "category3" 
    }, 
     { 
      "value": 5, 
      "category": "category3" 
    }, 
     { 
      "value": 58, 
      "category": "category3" 
    }, 
     { 
      "value": 41, 
      "category": "category3" 
    }, 
     { 
      "value": 81, 
      "category": "category3" 
    }, 
     { 
      "value": 73, 
      "category": "category3" 
    }, 
     { 
      "value": 20, 
      "category": "category3" 
    }, 
     { 
      "value": 32, 
      "category": "category3" 
    }, 
     { 
      "value": 42, 
      "category": "category3" 
    }, 
     { 
      "value": 55, 
      "category": "category3" 
    }, 
     { 
      "value": 74, 
      "category": "category3" 
    }, 
     { 
      "value": 17, 
      "category": "category3" 
    }, 
     { 
      "value": 6, 
      "category": "category3" 
    }, 
     { 
      "value": 96, 
      "category": "category3" 
    }, 
     { 
      "value": 18, 
      "category": "category3" 
    }, 
     { 
      "value": 1, 
      "category": "category3" 
    }, 
     { 
      "value": 18, 
      "category": "category3" 
    }, 
     { 
      "value": 40, 
      "category": "category3" 
    }, 
     { 
      "value": 9, 
      "category": "category3" 
    }, 
     { 
      "value": 30, 
      "category": "category3" 
    }, 
     { 
      "value": 28, 
      "category": "category3" 
    }, 
     { 
      "value": 25, 
      "category": "category3" 
    }, 
     { 
      "value": 44, 
      "category": "category3" 
    }, 
     { 
      "value": 20, 
      "category": "category3" 
    }, 
     { 
      "value": 99, 
      "category": "category3" 
    }, 
     { 
      "value": 95, 
      "category": "category3" 
    }, 
     { 
      "value": 50, 
      "category": "category3" 
    }, 
     { 
      "value": 65, 
      "category": "category3" 
    }, 
     { 
      "value": 66, 
      "category": "category3" 
    }, 
     { 
      "value": 7, 
      "category": "category3" 
    }, 
     { 
      "value": 70, 
      "category": "category4" 
    }, 
     { 
      "value": 39, 
      "category": "category4" 
    }, 
     { 
      "value": 12, 
      "category": "category4" 
    }, 
     { 
      "value": 94, 
      "category": "category4" 
    }, 
     { 
      "value": 55, 
      "category": "category4" 
    }, 
     { 
      "value": 15, 
      "category": "category4" 
    }, 
     { 
      "value": 84, 
      "category": "category4" 
    }, 
     { 
      "value": 31, 
      "category": "category4" 
    }, 
     { 
      "value": 48, 
      "category": "category4" 
    }, 
     { 
      "value": 26, 
      "category": "category4" 
    }, 
     { 
      "value": 70, 
      "category": "category4" 
    }, 
     { 
      "value": 30, 
      "category": "category4" 
    }, 
     { 
      "value": 26, 
      "category": "category4" 
    }, 
     { 
      "value": 75, 
      "category": "category4" 
    }, 
     { 
      "value": 43, 
      "category": "category4" 
    }, 
     { 
      "value": 83, 
      "category": "category4" 
    }, 
     { 
      "value": 64, 
      "category": "category5" 
    }, 
     { 
      "value": 52, 
      "category": "category5" 
    }, 
     { 
      "value": 37, 
      "category": "category5" 
    }, 
     { 
      "value": 11, 
      "category": "category5" 
    }, 
     { 
      "value": 77, 
      "category": "category6" 
    }, 
     { 
      "value": 94, 
      "category": "category6" 
    }, 
     { 
      "value": 37, 
      "category": "category6" 
    }, 
     { 
      "value": 64, 
      "category": "category6" 
    }, 
     { 
      "value": 92, 
      "category": "category6" 
    }, 
     { 
      "value": 58, 
      "category": "category6" 
    }, 
     { 
      "value": 70, 
      "category": "category6" 
    }, 
     { 
      "value": 47, 
      "category": "category6" 
    }, 
     { 
      "value": 87, 
      "category": "category6" 
    }, 
     { 
      "value": 6, 
      "category": "category6" 
    }, 
     { 
      "value": 87, 
      "category": "category6" 
    }, 
     { 
      "value": 32, 
      "category": "category6" 
    }, 
     { 
      "value": 70, 
      "category": "category6" 
    }, 
     { 
      "value": 38, 
      "category": "category6" 
    }, 
     { 
      "value": 38, 
      "category": "category6" 
    }, 
     { 
      "value": 31, 
      "category": "category6" 
    }, 
     { 
      "value": 82, 
      "category": "category6" 
    }, 
     { 
      "value": 44, 
      "category": "category6" 
    }, 
     { 
      "value": 21, 
      "category": "category6" 
    }, 
     { 
      "value": 78, 
      "category": "category6" 
    }, 
     { 
      "value": 97, 
      "category": "category6" 
    }, 
     { 
      "value": 67, 
      "category": "category6" 
    }, 
     { 
      "value": 29, 
      "category": "category6" 
    }, 
     { 
      "value": 6, 
      "category": "category6" 
    } 
]; 


    var vis = d3.select("#chart").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 + ")"); 

    var min = 1; 
    var max = data.length; 

    var middle = Math.round((max + min)/2) - 0.5; 

    var innerArc = d3.svg.arc() 
     .innerRadius(arcMin) 
     .outerRadius(arcMin + 10) 
     .startAngle(function (d, i) { 
      return (i + 0.1 - middle) * (pi/middle); 
     }) 
     .endAngle(function (d, i) { 
      return (i + 1 - 0.1 - middle) * (pi/middle); 
     }); 

    var outerArc = d3.svg.arc() 
     .innerRadius(arcMin) 
     .outerRadius(function (d, i) { 
      // Use min-max-normalization to scale value into interval [arcMin, arcMax] 
      return (d.value - min) * ((arcMax - arcMin)/(max - min)) + arcMin; 
     }) 
     .startAngle(function (d, i) { 
      return (i + 0.1 - middle) * (pi/middle); 
     }) 
     .endAngle(function (d, i) { 
      return (i - 0.1 + 1 - middle) * (pi/middle); 
     }); 

    var lines = vis.selectAll(".line") 
     .data(data) 
     .enter() 
     .append("path") 
     .attr("class", function (d) { 
      return d.category + " line"; 
     }) 
     .attr("d", innerArc) 
     .attr("transform", "translate(" + width/2 + "," + height/2 + ")") 
     .attr("fill", function (d) { 
      return color(d.category); 
     }) 
     .on("mouseleave", function() { 
      d3.selectAll(".line") 
       .transition() 
       .duration(300) 
       .style("opacity", 1); 
     }) 
     .on("mouseenter", function (d, i) { 
      d3.selectAll(".line") 
       .transition() 
       .duration(150) 
       .style("opacity", .5); 
     }) 
     .transition() 
     .duration(2000) 
     .delay(function (d) { 
      return ((d.value - min)/(max - min)) * 500; 
     }) 
     .attr("d", outerArc); 
</script> 
+0

http://stackoverflow.com/questions/16335781/d3-js-stop-transitions-being-interrupted – 2014-08-29 08:54:12

+0

@LarsKotthoff从我个人理解,这如果我希望我的第二次转换在第一次结束后启动,而不是在悬停时启动。 – Baz 2014-08-29 08:54:49

+0

是的,主要的一点是新的转换总是会覆盖现有的转换。因此,在你的情况下,当第二次转换开始并手动合并转换时(参见[here](http://xaedes.de/dev/transitions/)获取指针)或者在不同元素上转换时,需要捕获状态。 – 2014-08-29 09:13:19

回答

1

更新:自D3的版本3.5(2014年10月)以来,可以通过使用命名的转换对元素执行并发转换。

Here你可以看到命名转换问题的原始jsfiddle。

var lines = vis.selectAll(".line") 
    .data(data) 
    .enter() 
    .append("path") 
    .attr("class", function (d) { 
     return d.category + " line"; 
    }) 
    .attr("d", innerArc) 
    .attr("transform", "translate(" + width/2 + "," + height/2 + ")") 
    .attr("fill", function (d) { 
     return color(d.category); 
    }) 
    .on("mouseleave", function() { 
     d3.selectAll(".line") 
      .transition("opacity") // NAMED TRANSITION 
      .duration(300) 
      .style("opacity", 1); 
    }) 
    .on("mouseenter", function (d, i) { 
     d3.selectAll(".line") 
      .transition("opacity") // NAMED TRANSITION 
      .duration(150) 
      .style("opacity", .5); 
    }) 
    .transition("creation") // NAMED TRANSITION 
    .duration(2000) 
    .delay(function (d) { 
     return ((d.value - min)/(max - min)) * 500; 
    }) 
    .attr("d", outerArc); 

从博斯托克的网页又如: http://bl.ocks.org/mbostock/5d8039fb983a29e2ad49

+0

非常好,谢谢你的更新!将其标记为保持最新状态的可接受答案。 – Baz 2015-05-22 07:58:05

1

这只是一个d3“限制”。无论是否由悬停或其他事件触发,转场都不能同时运行。

尝试将悬停过渡移至CSS,并保持d3中的高度过渡。

http://jsfiddle.net/w21gunej/

.hovertest { 
    background: steelblue; 
    transition: background 1s ease; 
} 

.hovertest:hover { 
    background: gray;  
} 
+0

如果我只想转换其中一个小节,但不是所有小节都可以。 – Baz 2014-08-29 09:16:52

0

的解决方法是我的具体问题,我只是推迟了另外的代码这是负责的初始转移的同一时间悬停效果:

setTimeout(function() { 
    lines.on("mouseleave", function() { 
     tip.hide(); 

     d3.selectAll(".line") 
      .transition() 
      .duration(300) 
      .style("opacity", 1); 
    }) 
     .on("mouseenter", function (d, i) { 
      tip.show(d, container.node()); 

      d3.selectAll(".line") 
       .transition() 
       .duration(150) 
       .style("opacity", .5); 
     }) 
}, 2000); 

有关一般解决方案,请参阅Pablo EMLars Kotthoff的回答。

+0

我在这里有一个类似的问题:http://stackoverflow.com/questions/24924360/path-color-goes-black-if-selection-is-made-during-transition我最终咨询了Bostck的转换页面:http:/ /bost.ocks.org/mike/transition/这里有一些解决方案,其中最好的一点是确保使用正确的RGB代码类型。 – 2014-08-29 19:23:49

2

其他转换开始后添加的转换始终会取消那些较早的转换,请参阅参考资料。 the documentation

给定时间在给定元素上只能有一个转换处于活动状态。但是,可以在同一个元素上安排多个转换;只要它们在时间上交错,每个过渡将按顺序进行。如果新的转换运行在给定的元素上,它会隐式取消任何旧的转换,包括任何已安排但尚未运行的转换。

,特别是:

这使得新的转变,如在应对新的用户事件,以取代即使那些年长的转变都在上演或已交错延迟年长的转变。

因此,您要查找的用例是明确不受D3支持。

要实现您想要的操作,需要在第二次转换启动时手动合并转换(请参阅here指针),或在不同元素上转换。