Reputation: 21
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
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