首页 文章

d3 js过渡到矩形数组不起作用

提问于
浏览
2

我正在研究水平段条形图 . 我想这样做,条形图将根据每隔几秒随机生成的值为各个段之间的颜色过渡设置动画 .

在开始时,我设置了两个变量midRange和highRange,将我的片段分成3组 - 绿色,黄色和红色 . 然后我创建了一个2阵列 . rectArrays保存我的段/矩形 . colorArray保存每个矩形的颜色 .

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

This图片显示了不良影响 . 前半部分应该是绿色并且重新记录为5黄色 . 但由于某些原因,它们都是黄色的 . 这是我的小提琴code

谢谢你的任何建议

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);

1 回答

  • 1

    如果你想要每个 styleTween 获得一个不同的 i 实例,你将不得不使用 let ,而不是 var .

    只是改变:

    var temp = colorArray[i];
    

    至:

    let temp = colorArray[i];
    

    这是更新的小提琴:https://jsfiddle.net/x2mL97x7/

相关问题