【问题标题】:d3js, what does it mean when the 2nd param in .data() is a function?d3js,当 .data() 中的第二个参数是一个函数时,这意味着什么?
【发布时间】:2016-08-06 15:34:33
【问题描述】:

我尝试了以下代码:

var data = [
  {name: "Locke", number: 4},
  {name: "Reyes", number: 8},
  {name: "Ford", number: 15},
  {name: "Jarrah", number: 16},
  {name: "Shephard", number: 31},
  {name: "Kwon", number: 34}
];

d3.selectAll("div")
  .data(data, function(d) { return d ? d.name : this.id; })
                           // it should return a value, right? Where is the return value stored? Why doing this? 
     .enter()
     .append('h4')
    .text(function(d) { return d.number; });

我不明白这行代码是做什么的:

.data(data, function(d) { return d ? d.name : this.id; })

应该对数据数组中的每个项目执行回调函数,但是然后呢?他们为什么要这样做?返回值存放在哪里?

这是附加元素的样子,仍然没有返回值。这是official document for data() function。找不到解释。

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    data 函数中第二个参数的documentation 以给定文档开头:

    <div id="Ford"></div>
    <div id="Jarrah"></div>
    <div id="Kwon"></div>
    <div id="Locke"></div>
    <div id="Reyes"></div>
    <div id="Shephard"></div>
    

    现在,您想将数据应用到这个现有的 HTML 结构中:

    var data = [
      {name: "Locke", number: 4},
      {name: "Reyes", number: 8},
      {name: "Ford", number: 15},
      {name: "Jarrah", number: 16},
      {name: "Shephard", number: 31},
      {name: "Kwon", number: 34}
    ];
    

    所以你从一个选择开始:

    d3.selectAll("div")
    

    选择将返回文档中已存在的 HTML 元素列表。文档中的代码所做的是:通过将数据中的names 与元素的ids 匹配,将数据中的numbers 插入相应的divs,例如&lt;div id="Ford"&gt;15&lt;/div&gt;.

    但是,d3 不知道如何匹配这些。如果您不指定第二个参数,它将尝试按索引 将数据与您的元素连接(数据中的第一个条目进入第一个元素,第二个进入第二个,等等)。所以,你会得到:

    <div id="Ford">4</div>
    <div id="Jarrah">8</div>
    <div id="Kwon">15</div>
    ...
    

    但是,如果您提供第二个参数,称为 key 函数,您可以告诉 d3 您要将这些数字插入到哪里。

    可以指定一个键函数来控制将哪个数据分配给哪个元素,替换默认的按索引连接。为每个选定元素评估此键函数,按顺序传递当前数据 (d)、当前索引 (i) 和当前组(节点),并将 this 作为当前 DOM 元素。然后还为 data 中的每个新数据评估 key 函数,传递当前数据 (d)、当前索引 (i) 和组的新数据,并将 this 作为组的父 DOM 元素。给定键的数据将分配给具有匹配键的元素。

    // d is the current datum (the __data__ object on element, if any)
    function(d) {
      // for every element let's see if there is a __data__ object;
      // existing elements that haven't been handled by d3 yet don't have it:
      return d ?
        d.name : // use `name` property from `data`
        this.id; // use element's id, same as this.getAttribute('id')
    }
    

    现在,使用上面的函数作为 key 函数,你的 HTML 将如下所示:

    <div id="Ford">15</div>
    <div id="Jarrah">16</div>
    <div id="Kwon">34</div>
    <div id="Locke">4</div>
    <div id="Reyes">8</div>
    <div id="Shephard">31</div>
    

    您可以在这个 DEMO 中使用它。我添加了一个 console 调用到 key 函数。请注意,它被调用了 12 次(每个元素 6 次,然后数据中的每个数据(条目)调用 6 次)。前 6 个日志 undefined 因为这些元素上还没有 __data__

    返回值不存储在任何地方。它用于将元素与基准匹配一次,然后被丢弃。

    【讨论】:

    • "function(d) { return d ? d.name : this.id; }" 返回一个值,但数据是一个对象(例如:{name: "Locke", number: 4 }),d3 如何知道对象中的哪个键与键函数返回的值进行比较?
    • @NicolasS.Xu "d3 如何知道要比较对象中的哪个键" – d3 将为您数据中的每个元素和每个项目执行 key 函数,并将使用返回值(d.namethis.id)进行比较。例如,对象中的键 name ("Locke", "Reyes", ...) 将与元素的 id ("Ford", "Jarrah", ...) 进行比较。
    • @NicholaS.Xu,无论键功能是否存在,数据都将是一个对象。关键功能不会更改基础数据。为了更好地理解有界数据,请查看此文档示例:stackoverflow.com/documentation/d3.js/876/introduction-to-d3-js/…
    猜你喜欢
    • 2014-12-26
    • 1970-01-01
    • 2018-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-15
    相关资源
    最近更新 更多