2016-05-17 9 views
3

Я совершенно новичок в D3 и кодировании в целом. Я пытаюсь настроить гистограмму, которая включает/исключает данные в зависимости от флажка. У меня есть набор групп продуктов и стран, которые я хочу включить/выключить из общей суммы, представленной баром. Выход должен быть один бар на продукт.Динамическая фильтрация с D3

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

Я не уверен, где эта функция должна сидеть в моем коде или что он должен выглядеть ... Это то, что я работаю с на данный момент:

var data = data.filter(function(d) { 
    if (document.getElementById("nz_button").checked) { 
     return d.country == 'NZ' 
    } 
    if (document.getElementById("au_button").checked) { 
     return d.country == 'AU' 
    } 
    if (document.getElementById("us_button").checked) { 
     return d.country == 'US' 
    } 
    }) 


    // to see how many distinct groups there are and sum volume 
    var products = d3.nest() 
    .key(function(d) { 
     return d.product 
    }) 
    .rollup(function(leaves) { 
     var sum = 0; 
     leaves.forEach(function(d) { 
     sum += d.volume; 
     }) 
     return sum 
    }) 
    .entries(data); 

Полный код: http://plnkr.co/edit/qezdwMLt48RPc8KH17hS?p=preview

Может быть, я должен работать с выборами и повторным запуском гнезда/накопителя, когда это необходимо?

Любая помощь приветствуется. Спасибо :)

ответ

2

Вы можете переместить весь код, который делает граф в новой функции, как это:

function makeDataGraph(data) {//function to make the graph. 
     // 
     // FILTER 
     // 
     var data = data.filter(function(d) { 
     if (document.getElementById("au_button").checked) { 
      return d.country == 'AU' 
     } 
     if (document.getElementById("us_button").checked) { 
      return d.country == 'US' 
     } 
     if (document.getElementById("nz_button").checked) { 
      return d.country == 'NZ' 
     } 

     }) 


     // to see how many distinct groups there are and sum volume 
     var products = d3.nest() 
     .key(function(d) { 
      return d.product 
     }) 
     .rollup(function(leaves) { 
      var sum = 0; 
      leaves.forEach(function(d) { 
      sum += d.volume; 
      }) 
      return sum 
     }) 
     .entries(data); 

     // sorting on descending total 
     console.log(products); 
     products.sort(function(a, b) { 
     return b.values - a.values 
     }) 

     var max = d3.max(products, function(d) { 
     return d.values; 
     }); 
     var xscale = d3.scale.linear() 
     .domain([0, max]) 
     .range([0, 600]) 

     var svg = d3.select("svg"); 



     // 
     // Still needs to be cleaned up \/ \/ 
     // 

     var rects = svg.selectAll("rect.product") 
     .data(products) 
     rects.exit().remove(); 
     rects.enter().append("rect").classed("product", true) 
     rects.attr({ 
     x: 200, 
     y: function(d, i) { 
      return 100 + i * 50 
     }, 
     width: function(d, i) { 
      return xscale(d.values) 
     }, 
     height: 50 
     }).on("click", function(d, i) { 
     console.log(i, d); 
     }) 


     var labels = svg.selectAll("text.label") 
     .data(products) 
     labels.exit().remove(); 
     labels.enter().append("text").classed("label", true) 
     labels.attr({ 
     x: 195, 
     y: function(d, i) { 
      return 128 + i * 50 
     }, 
     "text-anchor": "end", 
     "alignment-baseline": "middle" 
     }).text(function(d) { 
     return d.key || "N/A" 
     }) 


     var volume = svg.selectAll("text.volume") 
     .data(products); 
     volume.exit().remove(); 
     volume.enter().append("text").classed("volume", true) 
     volume.attr({ 
     x: function(d, i) { 
      return 205 + xscale(d.values) 
     }, 
     y: function(d, i) { 
      return 128 + i * 50 
     }, 
     "text-anchor": "start", 
     "alignment-baseline": "middle" 
     }).text(function(d) { 
     return d.values || "N/A" 
     }) 
    } 

Remember делать rects.exit().remove(); так, что, когда данные изменяются по щелчку флажок, прямоугольники, связанные к старым данным удаляется.

Теперь вы можете вызвать эту функцию из события щелчка, а также afterloading в ТСВ, как это:

d3.tsv("data.tsv", function(err, udata) { 

    var udata = udata.map(process); 
    console.log("udata", udata); 

    var data = udata // making new var to preserve unfiltered data 
    makeDataGraph(data);//call the function to make graph 

    function handleClick() { // event handler... 
    makeDataGraph(data) 
    } 
    //add listener to all check boxes. 
    d3.selectAll(".filter_button").on("click", handleClick); 
}); 

рабочий код here

+1

Спасибо! Это дает мне большую часть пути, теперь, чтобы выяснить инструкции if в фильтре ... – alexalex

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