问题
I'm having trouble understanding when and how to use nested data.
In this example I have a CSV with names ('Name') and locations ('starting point'). By assigning keys to the locations I am able to make a dropdown containing them all, and I would like to use this to filter the names associated with each location.
However I am unable to find the data's values, in this case 'd.Name'
Here inside the update function I have tried to access the 'values' on the data join.
var adventurer = canvas
.selectAll(".adventurer")
.data(function(d) {
return d.values;
})
Ive also tried creating an extra data variable but thats not working for me either.
Sorry I can't make a jsfiddle but here is a plunk
DATA
,,Name,First names,s,r,Nat,born,starting point,starting date,arrival date,days,km,Assist,Support,Style,note,arrival date 2
1,1,KAGGE,Erling,,,Nor,1/15/1963,Berkner Island,11/18/1992,1/7/1993,50,appr. 1300,n,n,solo,first solo unassisted,
2,2,ARNESEN,Liv,f,,Nor,6/1/1953,Hercules Inlet,11/4/1994,12/24/1994,50,1130,n,n,solo,first woman unassisted,
3,3,HAUGE,Odd Harald,,,Nor,1956,Berkner Island,11/4/1994,12/27/1994,54,appr. 1300,n,n,,,
HTML
<div id="menu"></div>
<div id="chart"></div>
SCRIPT
d3.csv("data.csv", function(csv_data) {
var data = d3.nest()
.key(function(d) {
return d['starting point'];})
.sortKeys(d3.ascending)
.entries(csv_data)
console.log(data);
//create dropdown select
var list = d3.select("#menu").append("select")
list.selectAll("option")
.data(data)
.enter().append("option")
.attr("value", function(d) {
return d.key;
})
.text(function(d) {
return d.key;
});
//chart config
var w = 375,
h = 1000;
var canvas = d3.select('#chart')
.append('svg')
.attr('width', w)
.attr('height', h)
.append('g')
.attr('transform', 'translate (0,50)');
//function (bind, add, remove, update)
function updateLegend(data) {
var adventurer = canvas
.selectAll(".adventurer")
.data(function(d) {
return d.values;
})
var adventurerEnter = adventurer
.enter().append("g")
.attr('class', 'adventurer');
adventurerEnter
.append("text")
.attr('class', 'name')
.attr('x', 0);
adventurer.select('.name')
.text(function(d, i) {
return d.Name;
})
.attr('y', function(d, i) {
return i * 30;
});
// remove old elements
adventurer.exit().remove();
};
// generate initial legend
updateLegend(data);
});
// handle on click event
d3.select('#menu')
.on('change', function() {
var data = eval(d3.select(this).property('value'));
console.log(data)
updateLegend(data);
});
回答1:
You need to display both the locations and the names. You have a nest (in the plunk but not in your question) of location/name, but you also need a distinct list of names, or possibly a list of name/location:
var locations = d3.nest()
.key(function(d) {return d['starting point'];})
.sortKeys(function(a,b){ return a > b && 1 || b > a && -1 || 0})
.key(function(d) {return d.Name;})
.entries(csv_data)
var names = d3.nest()
.key(function(d) {return d.Name;})
.sortKeys(function(a,b){ return a > b && 1 || b > a && -1 || 0})
.key(function(d) {return d['starting point'];})
.entries(csv_data)
Then you have to display your names however you want. Then you need an .on('change', function()...) handler (or on click or whatever fits your needs) that actually filters the names wherever those are displayed.
I also fixed your sorting. d3.ascending is for numbers, not strings.
来源:https://stackoverflow.com/questions/35157825/accessing-nested-data-in-d3