2016-10-10 2 views
2

Я работаю над горизонтальной диаграммой горизонтального сегмента. Я хочу сделать так, чтобы гистограмма отображала переход цвета между отдельными сегментами в зависимости от значения, которое генерируется случайным образом каждые несколько секунд.d3 js переход по массиву прямоугольников не работает

В начале я установил две переменные midRange и highRange, которые разделили мои сегменты на 3 группы - зеленый, желтый и красный. Затем я создаю 2 массива. rectArrays содержит мои сегменты/прямоугольники. colorArray сохраняет цвет для каждого прямоугольника.

В функции animate() Я использую эти массивы для целей перехода. В настоящий момент первые 25 сегментов должны быть анимированы зелеными, а затем несколько желтых, а остальные сегменты должны быть красными. Переход между цветами не работает, когда должно быть включено более 25 сегментов. Все они либо желтые, либо красные. Кажется, что переход запоминает только цвет, который хранится в последнем индексе перед выходом из цикла for в моей функции анимации. Есть 3 случая, поэтому анимация может идти слева направо и наоборот.

This изображение показывает нежелательный эффект. Первая половина сегментов должна быть зеленой и remein 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

Если вы хотите, чтобы каждый styleTween получает другой i экземпляр, вы должны будете использовать let, не var.

Просто изменение:

var temp = colorArray[i]; 

To:

let temp = colorArray[i]; 

Вот дополненная скрипку: https://jsfiddle.net/x2mL97x7/

+0

Еще раз спасибо Geraldo Фуртадо. Он работает так, как ожидалось. Не знаю, что я мог бы использовать let вместо var. – alexis