如何阻止d3对象在每次更新时返回零?

trnvg8h3  于 2023-04-30  发布在  其他
关注(0)|答案(1)|浏览(104)

在d3中制作一个指南针,我创建了一个箭头,它将围绕一个圆圈过渡,每次更新一个新的Angular 时,箭头总是先返回到零,然后移动到新的Angular 。如何避免每次更新箭头返回零?

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.6.1/d3.min.js" charset="utf-8"></script>

<style>
.arrowgreen {
 margin-top: 12.5px;
 margin-left: 0px;
}
.circ {
 margin-top: -145px;
 margin-left: 0px;
}
</style>
 
<div class="arrowgreen">
<svg width="140" height="140" style="border:0px solid green" id="arrow" viewBox="0 0 140 140"></svg>
</div>
<div class="circ"> 
<svg width="140" height="140" style="border:0px solid blue" id="circ" viewBox="0 0 140 140"></svg>
</div>

<script>

var angle = 180; // "<?php echo $wind["direction"];?>";  

var svg = d3.select("#circ")
        .append("svg")
        .attr("height", 140)            
        .attr("width", 140)
        .append("g");
            
    svg.append("circle")
        .attr("cx", 70) // center circle
        .attr("cy", 70)
        .style("stroke", "rgba(59, 60, 63, 1)")
        .style("stroke-width", "7")
        .style("fill", "none")
        .attr("r", 60);

    svg.append("text")
        .attr("x", 70)
        .attr("y", 74)
        .style("fill", "silver")
        .style("font-family", "Helvetica")
        .style("font-size", "11px")
        .style("text-anchor", "middle")
        .style("font-weight", "normal")
        .text(angle+"°");   
      
var dataArrow = [[70, 22], [75, 2], [70, 8], [65, 2]];
  
var lineGenerator = d3.line();
var pathString = lineGenerator(dataArrow);
 
var compassArrow = d3.select("#arrow")
        compassArrow.append("path")
        .attr('d', pathString)    
        .attr("fill", "rgba(0,127,255,1)")
        compassArrow.transition()
        .ease(d3.easePoly)
        .duration(1500)
        .attr("transform", "rotate(" + angle + ", 0, 0)");

我确实找到了一个可能的解决方案,但这将打破过渡期

zphenhs4

zphenhs41#

好吧,我用一个承诺拼凑了一些东西。这并不完美,但它的工作。参见:https://codepen.io/kikosoft/pen/mdKmNNy
使此工作的位是:

compassArrow.append("path")
        .attr('d', pathString)    
        .attr("fill", "rgba(0,127,255,1)")
compassArrow.transition()
        .ease(d3.easePoly)
        .duration(1500)
        .attr("transform", "rotate(" + angle + ", 0, 0)")
        .end()
        .then( function () {
     angle = 10;
     compassArrow.transition()
        .ease(d3.easePoly)
        .duration(1500)
        .attr("transform", "rotate(" + angle + ", 0, 0)");
          
});

基本上,我等待第一个动画完成.end(),然后执行下一个动画。
参见:How to use promises

相关问题