2016-08-03 4 views
1

Используя D3.js v4, я пытаюсь обновить радиус круга при нажатии кнопки.Переход по радиусу круга D3.js v4 не работает должным образом

Проблема заключается в том, что вместо smooth transitions between the radii круг перерисовывается (от радиуса 1 до 0 и только затем до «радиуса2») при каждом обновлении.

Вот полный код: https://jsfiddle.net/4r6hp9my/

Вот круг код обновления сниппет:

 var circles = svg.selectAll('circle').data(dataset); 

     var enter = circles 
     .enter() 
     .append('circle') 
     .attrs({ 
      cx: w/2, 
      cy: h/2, 
      fill: colorsScale, 
      r: function(d,i){ 
       if(i == myCounter){ 
        var x = rScale(d) 
       return x; 
       } 
      } 
     }); 

     d3.select('#theButton') 
      .on('click',function(){ 
       myCounter++ 
       if(myCounter == dataset.length){ 
        myCounter = 0; 
       }; 
       updateData() 
      }); 

     function updateData(){ 
      circles 
      .merge(enter) 
      .transition() 
      .attr('r',function(d,i){ 
       if(i == myCounter){ 
        return rScale(d); 
       } 
      }); 
      labels 
      .text(function(d,i){ 
       if(i == myCounter){ 
       return d; 
       } 
      }); 

     }; 
+0

Сколько кругов вы думаете, когда вы впервые открываете скрипку? – echonax

+0

Не уверен, что, если я понимаю вопрос, предполагается, что будет только один круг, радиус которого обновляется (основываясь на значениях в одномерном массиве) при каждом нажатии кнопки –

+0

:) Откройте своего инспектора и загляните в свой элемент svg. вы добавили 9 кругов к вашему svg. То есть, 1 для каждого из ваших элементов 'dataset'. – echonax

ответ

3

Как отметил echonax, вопрос вы создаете несколько кругов на основе набора данных. Чтобы получить плавный переход, нарисуйте только один круг и обновите радиус на основе «myCounter». Пример:

var dataset = [2184,2184,3460,2610,2610,2452,842,1349,2430]; 
 

 
var myCounter = 0; 
 
//svg dimensions 
 
var h = 200; 
 
var w = 200; 
 

 
var svg = d3.select('body') 
 
.append('svg') 
 
.attrs({ 
 
    width: w, 
 
    height: h 
 
}) 
 
.classed('middle',true); 
 
//color mapping 
 
var colorsScale = d3.scaleLinear() 
 
.domain([d3.min(dataset),d3.max(dataset)]) 
 
.range(['#FFB832','#C61C6F']); 
 
//radius mapping 
 
var rScale = d3.scaleLinear().domain([0, d3.max(dataset)]).range([0,50]) 
 
//labels 
 
var label = svg.append("text").attrs({ 
 
    x: w/2, 
 
    y: 20 
 
}).text(function(){ return dataset[myCounter] }); 
 

 
//draw the circles 
 
var circle = svg.append('circle') 
 
.attrs({ 
 
    cx: w/2, 
 
    cy: h/2, 
 
    fill: function() { return colorsScale(dataset[myCounter]) }, 
 
    r: function() { return rScale(dataset[myCounter]) } 
 
}); 
 
//button click 
 
d3.select('#theButton') 
 
    .on('click',function(){ 
 
    updateData() 
 
}); 
 

 
function updateData(){ 
 
\t myCounter++; 
 
    if (myCounter > dataset.length - 1) myCounter = 0; 
 
    circle.transition().attr('r',function(){ return rScale(dataset[myCounter]) }).attr('fill', function() { return colorsScale(dataset[myCounter]) }); 
 
    label.text(function(){ return dataset[myCounter] }); 
 
};
html, body{ 
 
\t height: 100%; 
 
} 
 

 
.middle{ 
 
\t margin: 100px auto; 
 
} 
 

 
#theButton{ 
 
\t position: absolute; 
 
\t left:50px; 
 
\t top:50px; 
 
}
<script src="https://d3js.org/d3.v4.js"></script> 
 
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script> 
 
     
 
<button id="theButton" type="button">Click Me!</button>

На основании данных, есть несколько раз, что круг не изменится, так как данные то же самое, но переход должен работать, когда он делает.

+1

Ницца, поддерживается, но вы можете отказаться от этого 'g'. –

+1

Даже не понял, что я бы положил его туда! Удалены. –

+1

Большое спасибо! –

 Смежные вопросы

  • Нет связанных вопросов^_^