Accessing nested data in D3

旧时模样 提交于 2020-01-07 01:50:07

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!