矩形数组上的 d3 js 转换不起作用

d3 js transition over the array of rectangles does not work

我正在处理水平线段条形图。我想让条形图根据每隔几秒随机生成的值来动画各个段之间的颜色过渡。

一开始我设置了两个变量 midRange 和 highRange 将我的片段分成 3 组 - 绿色、黄色和红色。然后我创建一个 2 数组。 rectArrays 持有我的 segments/rectangles。 colorArray 保存每个矩形的颜色。

在 animate() 函数中,我将这些数组用于过渡目的。目前,前 25 段动画应为绿色,然后是黄色,其余部分应为红色。当应该打开超过 25 个段时,颜色之间的过渡不起作用。它们都是黄色或红色的。似乎过渡只记住在我的动画函数中退出 for 循环之前存储在最后一个索引上的颜色。有 3 种情况,所以动画可以从左到右,反之亦然。

This 图片显示不需要的 effect.First 一半的片段应该是绿色的,remein 5 是黄色的。但出于某种原因,它们都是黄色的。 这是我的fiddlecode

感谢您的任何建议

var configObject = {

    svgWidth : 1000,
    svgHeight : 500,


    minValue : 1,
    maxValue : 100,

    midRange : 50,
    highRange : 75,

    numberOfSegments : 50
};
//define variables
var newValue;
var gaugeValue = configObject.minValue - 1;
var mySegmentMappingScale;
var reverseScale;
var rectArray=[];
var segmentIndex=configObject.maxValue/configObject.numberOfSegments;
var dynamicArc=true;
var staticArc="yellow";
var gradientArray=[];
var colorArray=[];
var rectWidth=(configObject.svgWidth/1.5)/configObject.numberOfSegments;
var rectPadding=3;


getColor();
setmySegmentMappingScale(); 
//define svg
var svg = d3.select("body").append("svg")
    .attr("width", configObject.svgWidth)
    .attr("height", configObject.svgHeight)
    .append("g")
    .attr("transform", 'translate('+ 0 +',' + configObject.svgHeight/2 + ')');


var valueLabel= svg.append("text")
    .attr('x',0)
    .attr('y', (configObject.svgHeight/13)+15)
    .attr('transform',"translate(" + 0 + "," + 0 + ")")
    .text(configObject.minValue)
    .attr('fill', "white");




    var HueGreenIndex=1;
    var HueYellowIndex=1;
    var HueRedIndex=1;
    function addGradient(c){
        //debugger
         if (c=="green"){
             var hslString =d3.hsl(HueGreenIndex + 160, .40, .29).toString();
                HueGreenIndex=HueGreenIndex+0.5;
                return hslString; 
         }
        else if(c=="yellow"){
            var hslString=d3.hsl(HueYellowIndex + 39, .67, .57).toString();
                HueYellowIndex=HueYellowIndex+0.5;
                return hslString;

        }
        else if (c=="red"){
            var hslString=d3.hsl(1+HueRedIndex , 1, .58).toString();
                HueRedIndex=HueRedIndex+0.10;
             return hslString;  

        }
    }

    function getColor(){
            if (dynamicArc){

                for(i = 0; i <= configObject.numberOfSegments; i++){
                   if(i<=(configObject.numberOfSegments/100)*configObject.midRange){

                        //gradientArray.push(addGradient("green"));
                        colorArray.push("green");
                    }
                    else if(i > ((configObject.numberOfSegments/100)*configObject.midRange) && i<= ((configObject.numberOfSegments/100)*configObject.highRange)){
                        //gradientArray.push(addGradient("yellow"));
                        colorArray.push("yellow");
                    }
                    else if (i > ((configObject.numberOfSegments/100)*configObject.highRange)){
                        //gradientArray.push(addGradient("red"));
                        colorArray.push("red");
                    }

                }
            }
            else{
                if (staticArc=="green"){
                    //gradientArray.push(addGradient("green"));
                    colorArray.push("green")
                }
                else if(staticArc=="yellow"){
                    //gradientArray.push(addGradient("yellow"));
                    colorArray.push("yellow")
                }
                else {
                    //gradientArray.push(addGradient("red"));
                    colorArray.push("red")
                }
            }

    }


    for(i = 0; i <= configObject.numberOfSegments; i++){
        var myRect=svg.append("rect")
            .attr("fill", "#2D2D2D")
            .attr("x",i * rectWidth) 
            .attr("y", 0)
            .attr("id","rect"+i)
            .attr("width", rectWidth-rectPadding)
            .attr("height",  configObject.svgHeight/13);    

             rectArray.push(myRect);

        }
//define scale
    function setmySegmentMappingScale(){
            var domainArray = [];
            var x=0;
            for(i = configObject.minValue; i <= configObject.maxValue+1; i = i + (configObject.maxValue - configObject.minValue)/configObject.numberOfSegments){
              if(Math.floor(i) != domainArray[x-1]){ 
                   var temp=Math.floor(i);
                   domainArray.push(Math.floor(i));
                   x++;
               }
           }

            var rangeArray = [];
            for(i = 0; i <= configObject.numberOfSegments+1; i++){//  <=
                rangeArray.push(i);
            }
            mySegmentMappingScale = d3.scale.threshold().domain(domainArray).range(rangeArray);
            reverseScale= d3.scale.threshold().domain(rangeArray).range(domainArray);

        }
    function widgetScale (x,y,r){   
        return (x*r)/y;
    }
//generate random number
    function generate(){
        var randomNumber = Math.random() * (configObject.maxValue - configObject.minValue) + configObject.minValue;     
        newValue = Math.floor(randomNumber);
        animateSVG();
    }



    function animateSVG(){

    var previousSegment = mySegmentMappingScale(gaugeValue) -1;
    var newSegment = mySegmentMappingScale(newValue) -1;


        if(previousSegment <= -1 && newSegment > -1){

            for(i = 0; i <= newSegment; i++){ 
            var temp=colorArray[i];

                rectArray[i].transition()
                    .ease("linear")
                    .duration(50)
                    .delay(function(d){return i * 90})
                    .styleTween("fill", function() { return d3.interpolateRgb( getComputedStyle(this).getPropertyValue("fill"), temp );});

                valueLabel.transition()
                    .ease("linear")
                    .duration(50)
                    .delay(function(d){return i * 90})
                    .text(i==newSegment ? newValue : i*segmentIndex);

                valueLabel.transition()
                    .ease("linear")
                    .duration(50)
                    .delay(function(d){return i * 90})
                    .attr("transform","translate(" + (i * (rectWidth)+(rectWidth)) + "," + 0 + ")")

            }
        }
        else if(newSegment > previousSegment){

            for(i = previousSegment; i <= newSegment; i++){

            var temp=colorArray[i];
                rectArray[i].transition()
                    .ease("linear")
                    .duration(50)
                    .delay(function(d){return i * 90})
                    .styleTween("fill", function() { return d3.interpolateRgb( getComputedStyle(this).getPropertyValue("fill"),temp);});

                valueLabel.transition()
                    .ease("linear")
                    .duration(50)
                    .delay(function(d){return i * 90})
                    .text(i==newSegment ? newValue : i*segmentIndex);

                valueLabel.transition()
                    .ease("linear")
                    .duration(50)
                    .delay(function(d){return i * 90})
                    .attr("transform","translate(" + (i * (rectWidth)+(rectWidth)) + "," + 0 + ")")

            }
        }
        else if(newSegment < previousSegment){


            for(i = previousSegment; i > newSegment; i--){
            var temp=colorArray[i];

                rectArray[i].transition()
                    .ease("linear")
                    .duration(50)
                    .delay(function(d){return Math.abs(i -previousSegment)*90})
                    .styleTween("fill", function() { return d3.interpolateRgb( getComputedStyle(this).getPropertyValue("fill"),"#2D2D2D"); });

                valueLabel.transition()
                    .ease("linear")
                    .duration(50)
                    .delay(function(d){return Math.abs(i -previousSegment)*90})
                    .text(i==newSegment+1 ? newValue : i*segmentIndex);          

                valueLabel.transition()
                    .ease("linear")
                    .duration(50)
                    .delay(function(d){return Math.abs(i -previousSegment)*90})
                    .attr("transform","translate(" + (i * (rectWidth)-(rectWidth)) + "," + 0 + ")")

            }
        }   
     gaugeValue = newValue;

    }


setInterval(function() {
   generate()
}, 6000);

如果您希望每个 styleTween 获得一个不同的 i 实例,您必须使用 let,而不是 var

只需更改:

var temp = colorArray[i];

收件人:

let temp = colorArray[i];

这是更新后的 fiddle:https://jsfiddle.net/x2mL97x7/