2016-01-28 16 views
0

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

В настоящее время круговая диаграмма отображается в порядке, но когда я выбираю другой сервер в раскрывающемся меню, он не может обновить изображение. Журналы консоли показывают, что набор данных действительно изменяется. Я проверил онлайн, и кажется, что мои элементы не удаляются правильно? Тем не менее, всякий раз, когда я пытаюсь использовать path.exit(). Remove(), он ничего не отображает.

Вот мой код и jsfiddle: http://jsfiddle.net/36q95k1c/2/

var ds1 = [1,1,1,1,1,1,1,3,0,0]; 
var ds2 = [0,0,0,1,1,1,1,1,1,1]; 
var ds3 = [0,0,1,1,0,0,0,0,0,0]; 
var ds4 = [0,0,2,0,5,3,0,0,0,0]; 
var ds5 = [0,0,0,0,0,0,0,0,0,0]; 
var ds6 = [0,0,0,0,0,0,0,0,0,0]; 
var ds7 = [0,0,0,0,0,0,0,0,0,0]; 
var ds8 = [0,0,0,0,0,0,0,0,0,0]; 
var ds9 = [0,0,0,0,0,0,0,0,0,0]; 
var ds10 = [0,0,0,0,0,0,0,0,0,0]; 
var ds11 = [0,0,0,0,0,0,0,0,0,0]; 
var ds12 = [0,0,0,0,0,0,0,0,0,0]; 
var ds13 = [0,0,0,0,0,0,0,0,0,0]; 
var ds14 = [0,0,0,0,0,0,0,0,0,0]; 



var dataset = {inner: [4,1,31,28,13,65,6,6,4,3], 
    middle: ds1, 
    outer: [1175,1802,8126,11926,37264,4267,2961,2909,850,12432]}; 

var victim_total = 4+1+31+28+13+65+6+6+4+3; 
var killer_total = 22+4+37+72+2+20+2+11+3+3; 
var general_total = 1175+1802+8126+11926+37264+4267+2961+2909+850+12432; 
var legendRectSize = 25; 
var legendSpacing = 6; 



//Width and height 
var w = 750; 
var h = 750; 
var r = 100; 
var donutWidth = 225 


var outerRadius = w/2; 
var innerRadius = donutWidth; 
var arc = d3.svg.arc() 
    .innerRadius(innerRadius) 
    .outerRadius(outerRadius); 

var pie = d3.layout.pie() 
    .sort(null); 

// Easy colors accessible via a 10-step ordinal scale 
var color = d3.scale.category20(); 

// Create SVG element 
var svg = d3.select("body") 
    .append("svg") 
    .attr("width", 2*w) 
    .attr("height", h) 
    .append('g') 
    .attr('transform', 'translate(' + (w/2) + 
    ',' + (h/2) + ')'); 

// Define the div for the tooltip 
var div = d3.select("body").append("div") 
    .attr("class", "tooltip")    
    .style("opacity", 0); 


function updateLegend(newData) { 
    //https://dl.dropboxusercontent.com/s/hfho50s0xd2dcpn/craftinggeneralstats1.csv?dl=1" 
    //https://dl.dropboxusercontent.com/s/i152v8ccetr5gj0/craftinggeneralstats.csv?dl=1 
    //Import CSV file 
d3.csv("https://dl.dropboxusercontent.com/s/i152v8ccetr5gj0/craftinggeneralstats.csv?dl=1", function(data) { 
    data.forEach(function(d) { 
    d.outer = +d.count; 
    d.middle = +d.countkiller; 
    d.inner = +d.countvictim; 
    d.label = d.label; 
    }); 
// function updateLegend(newData) { 
    /*var step; 
    for (step = 0; step < 10; step++) { 
    // Runs 5 times, with values of step 0 through 4. 
    data[step].countkiller = 1; 
}*/ 
//data[i].countkiller = 0; 
console.log(dataset.middle); 
// Set up groups 
var arcs = svg.selectAll("g.arc") 
    .data(d3.values(dataset)); 
    arcs.enter() 
    .append("g")  
    .attr("class", "arc") 
    .attr("transform", "translate(" +0+ "," +0+ ")"); 



var path = arcs.selectAll("path") 
    .data(function(d) { return pie(d); }); 
    path.enter().append("path") 
    .on("mouseover", function(d, i, j) { 
// console.log(d); 
    //console.log(dataset.middle[3]); 
    div.transition()  
       .duration(200)  
       .style("opacity", .9) 
       .style("left", (d3.event.pageX) + "px")  
       .style("top", (d3.event.pageY - 28) + "px"); 
      if (j ==0) 
       div.html("Victim" + "<br/>" + Math.round(1000 * d.value/victim_total)/10 +"%") 
      if (j ==1) 
       div.html("Killer" + "<br/>" + Math.round(1000 * d.value/killer_total)/10 +"%") 
      if (j ==2) 
      { 
       div.html("Overall" + "<br/>" + Math.round(1000 * d.value/general_total)/10 +"%") 
       } 

      })     
     .on("mouseout", function(d) {  
      div.transition()   
       .duration(500)  
       .style("opacity", 0); 
     }) 
    .attr("fill", function(d, i) { return color(i); }) 
    .attr("d", function(d, i, j) { return arc.innerRadius(10+r*j).outerRadius(r*(j+1))(d); }); 


    // .attr("text-anchor", "middle") 
    /* .text(function (d, i) { 
    return data[i].label; 
});*/ 


// Setup legend 
var legend = svg.selectAll('.legend')      
      .data(color.domain())         
      .enter()             
      .append('g')            
      .attr('class', 'legend')         
      .attr('transform', function(d, i) {      
      var height = legendRectSize + legendSpacing;   
      var offset = height * color.domain().length/2;  
      var horz = -2 * legendRectSize;      
      var vert = i * height - offset;      
      return 'translate(' + (horz +(w/2)) + ',' + vert + ')';   
      });              

     legend.append('rect')          
      .attr('width', legendRectSize)       
      .attr('height', legendRectSize)       
      .style('fill', color)         
      .style('stroke', color)         
      .on('click', function(label) {        
       var rect = d3.select(this);        
       var enabled = true;          


       if (rect.attr('class') === 'disabled') {     
       rect.attr('class', '');        
       } else {             
       if (totalEnabled < 2) return;       
       rect.attr('class', 'disabled');      
       enabled = false;          
       }              

       pie.value(function(d) {         
       if (d.label === label) d.enabled = enabled;   
       return (d.enabled) ? d.count : 0;      
       });              
       arcs = arcs.data(d3.values(dataset))         
      });              
     legend.append('text')          
      .attr('x', legendRectSize + legendSpacing)    
      .attr('y', legendRectSize - legendSpacing)    
      .text(function (d, i) { 
     return data[i].label; 
});  
    path.exit().remove(); 
d3.select('#opts') 
    .on('change', function(d) { 
    var server = eval(d3.select(this).property('value')); 
    dataset.middle = server; 
    updateLegend(dataset); 
}); 

}); 
} 

    updateLegend(dataset); 

ответ

0

В текущей версии, вы просто добавить объявления для enter выбора, которая влияет только дуги, вставляемые. Вам нужно направлять D3, как обрабатывать выбор update, который влияет на дуги, которые обновляются , и выбор exit, который влияет на дуги, которые удаляются . Вы можете добавить эти строки кода перед оператором path.enter().

path.attr("d", function(d, i, j) { 
    return arc.innerRadius(10 + r * j).outerRadius(r * (j + 1))(d); 
}); 

path.exit().remove(); 

Обновленная скрипка: http://jsfiddle.net/36q95k1c/5/

+0

Это имеет больший смысл, спасибо за помощь! – DippedNSauce

+0

Вы действительно знаете, как добавить анимацию? Мне трудно понять, как плавно переходить между наборами данных. – DippedNSauce

+0

Я еще не работал с дуговыми переходами. Тем не менее, вы можете посмотреть на этот пример, я думаю, что это хорошая идея в вашем случае http://bl.ocks.org/mbostock/5100636 –

0

Чтобы добавить хороший ответ Хьеу Le, за ваш запрос о анимации, она может быть немного сложнее, чтобы выяснить правильную точку, в которой добавить переход() вызов. Попробуйте положить его на линии 100 jsfiddle Хьеу Le чтобы увидеть, если это то, что вы после:

path.transition().attr("d", function(d, i, j) { 
    return arc.innerRadius(10 + r * j).outerRadius(r * (j + 1))(d); 
}); 

После того как вы получили его анимировать, проверить the docs для получения информации о различных интерполяций и подростков.

Cheers!

+0

Большое спасибо! Я пробовал эту позицию раньше, основываясь на других сообщениях в Интернете, но, похоже, я пропустил «.». – DippedNSauce

+0

Я использовал этот метод в своем фактическом html-файле, и по какой-то причине он дает мне ошибку «Ошибка: недопустимое значение для атрибута d =« MNaN, NaNANaN, NaN -0.0037720432607528664 -0.0051702697839743905,1.006368000000009 NaN, NaNL0.006400000000013506,0Z ». Однако моя обновленная скрипка (с добавлением другого выпадающего меню) по какой-то причине отлично работает на jsfiddle. Вот мой js, который показывает, как работают внутренние круги http://jsfiddle.net/L7kqnvot/3/ – DippedNSauce

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