【问题标题】:d3 js transition over the array of rectangles does not work矩形数组上的d3 js过渡不起作用
【发布时间】:2017-02-19 02:06:46
【问题描述】:

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

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

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

This 图片显示了不希望的效果。前半部分应为绿色,其余为黄色。但由于某种原因,它们都是黄色的。 这是我的小提琴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);

【问题讨论】:

    标签: javascript d3.js transition


    【解决方案1】:

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

    只是改变:

    var temp = colorArray[i];
    

    收件人:

    let temp = colorArray[i];
    

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

    【讨论】:

    • 再次感谢 Geraldo Furtado。它按预期工作。不知道我可以用 let 代替 var。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    • 2012-07-07
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多