Khnum Temu
Khnum Temu

Reputation: 21

Remove Duplicates from D3js Dropdown

I was able to create and load data into a Select element (Dropdown) purely with D3.js. The main issue I am having is that within the dropdown I see all of the names (duplicates). I would like to only see the distinct name. Here is a working example: http://jsfiddle.net/khnumtemu/43oaczq8/

 var dataset = [
   {
      "SalesRepName":"KIM MIKE (110)",
      "FieldSalesManagerName":"MILLER BRIAN"
   },
   {
      "SalesRepName":"JAISWAL LOKESH (111)",
      "FieldSalesManagerName":"MILLER BRIAN"
   },
   {
      "SalesRepName":"QUINTERN GEOFFREY (112)",
      "FieldSalesManagerName":"MILLER BRIAN"
   },
   {
      "SalesRepName":"OKOYE MAXIMUS (114)",
      "FieldSalesManagerName":"MILLER BRIAN"
   },
   {
      "SalesRepName":"STARGHILL TREVOR (115)",
      "FieldSalesManagerName":"OPEN POSITION"
   },
   {
      "SalesRepName":"JARDOT BENJAMIN (318)",
      "FieldSalesManagerName":"MILLER BRIAN"
   },
   {
      "SalesRepName":"MICCICHE TERRY (319)",
      "FieldSalesManagerName":"MILLER BRIAN",
   },
   {
      "SalesRepName":"KAMENOVA TEODORA (401)",
      "FieldSalesManagerName":"OPEN POSITION"
   },
   {
      "SalesRepName":"SHERIDAN BRIAN (402)",
      "FieldSalesManagerName":"OPEN POSITION"
   },
   {
      "SalesRepName":"KNEIP CHARLES (403)",
      "FieldSalesManagerName":"OPEN POSITION"
   }
]


d3.select("body").append("select")
    .classed('colorSelect',true)
    .selectAll("option")
    .data(dataset)
    .enter()
    .append("option")
    .attr("value",function(d){ return d.FieldSalesManagerName;})
    .text(function(d){ return d.FieldSalesManagerName;})
    .sort(function(a, b) {return d3.ascending(a.FieldSalesManagerName, b.FieldSalesManagerName);});


  // Data OnLoad
  d3.select("body").selectAll("p")
    .data(dataset)
    .enter()
    .append("p")


  // Data Updated on Selected Change
  d3.select("select")
    .on("change", function(d){

      var sel = d3.select(".colorSelect").node().value;
      d3.select("body").selectAll("p")
        .data(dataset)
        .text(function(d){
          if(d.FieldSalesManagerName === sel){
            return d.SalesRepName;
          }
        })

    });

Upvotes: 2

Views: 1417

Answers (1)

Mark
Mark

Reputation: 108527

With that much data duplication, your code is dying for a better data structure. Since you are using d3, I'd coerce it into a map first.

var map = d3.map();
dataset.forEach(function(d){
    if (!map.has(d.FieldSalesManagerName)){
        map.set(d.FieldSalesManagerName, [d.SalesRepName])
    } else {
        map.get(d.FieldSalesManagerName).push(d.SalesRepName);
    }
});

Your drop down then simply becomes:

d3.select("body").append("select")
 .classed('colorSelect',true)
 .selectAll("option")
 .data(map.keys())
 .enter()
 .append("option")
 .attr("value",function(d){ return d;})
 .text(function(d){ return d; }); 

And your on change can then avoid looping and comparisons:

d3.select("select")
  .on("change", function(d){      
    var sel = d3.select(".colorSelect").node().value;
    d3.select("body").selectAll("p")
      .data(map.get(sel))
      .text(function(d){
        return d;
      })        
  });

Updated fiddle.

Upvotes: 2

Related Questions