如何使用d3扩展select标签中的选项数量?

时间:2018-05-24 20:08:24

标签: javascript html d3.js

考虑一个select html标记,其中只有一个选项用作标题或占位符。

我正在使用d3.js渲染html视图,并根据数据向此标记添加新元素或选项。根据不同的数据集,这将发生很大变化。这就是我使用这种方法的原因。

但是,此方法不会返回数据中的第一个选项或第一个元素,如您在代码段示例中所示。我在此示例中有三个主要键:abc。它刚刚添加了其中两个。

如果我删除html视图中的第一个选项,它可以正常工作。那么,扩展新选项以选择标签的最佳方法是什么?

为了添加新代码,我使用了以下代码:

Object.keys(data).map((k) => {
  if (k == 'a') {
    options.push(k)
    options.push(k)
  } else {
    options.push(k)
  }
}) 

然而,这意味着要知道第一个元素是什么,在大多数情况下这不是真的。

如何实现这一结果?



var data = {
  'a': {
    'aa': 'aa'
  },
  'b': {
    'bb': 'bb'
  },
  'c': {
    'cc': 'cc'
  }
}

var options = []
Object.keys(data).map(function (k) {
  options.push(k)
})

var selector = d3.select('#myid')
var opts = selector.selectAll('option')
    .data(options.sort())
    .enter()
    .append('option')
    .attr('value', function (d) {
      return d
    })
    .text(function (d) {
      return d
    })

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<select id='myid' name='name' class='form-control'>
  <option disabled selected>Select one item</option>
</select>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:3)

而是选择所有option传递null

var opts = selector.selectAll(null)

&#13;
&#13;
var data = {
  'a': {
    'aa': 'aa'
  },
  'b': {
    'bb': 'bb'
  },
  'c': {
    'cc': 'cc'
  }
}

var options = []
Object.keys(data).map(function (k) {
  options.push(k)
})

var selector = d3.select('#myid')
var opts = selector.selectAll(null)
    .data(options.sort())
    .enter()
    .append('option')
    .attr('value', function (d) {
      return d
    })
    .text(function (d) {
      return d
    })
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<select id='myid' name='name' class='form-control'>
  <option disabled selected>Select one item</option>
</select>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

注意:此答案已根据@GerardoFurtado's in depth explanation of this behaviour进行了修改和更正。

使用selectAll("option").data(data)时,由于选择了所有option元素,因此也会选择页面中已存在的元素(在html(<option disabled selected>Select one item</option>)中硬编码的元素)。

因此,当.enter()进行此选择时,所考虑的第一个数据点将绑定到页面中已存在的此选项,从而跳过从数据中插入第一个选项。

对于要追加的其余2个数据点,当我们达到现有option元素的限制时,只会创建新的option元素。

在这种情况下,最恰当的回答是将.selectAll(null)用作answered by @estebanpdl

以下是处理此用例的另一种方法(为了演示当页面中已存在此类元素时插入某种类型的新元素的影响)。我们可以选择并插入具有特定类别的新数据option,以避免考虑现有数据:

var opts = selector.selectAll('option .values')
  .data(options.sort())
  .enter()
  .append('option')
  .attr("class", "values")
  .attr('value', function (d) { return d; })
  .text(function (d) { return d; });

这是一个演示:

var data = {
  'a': { 'aa': 'aa' },
  'b': { 'bb': 'bb' },
  'c': { 'cc': 'cc' }
}

var options = [];
Object.keys(data).map(function (k) { options.push(k) });

var selector = d3.select('#myid');

var opts = selector.selectAll('option .values')
  .data(options.sort())
  .enter()
  .append('option')
  .attr("class", "values")
  .attr('value', function (d) { return d; })
  .text(function (d) { return d; });
<script src="https://d3js.org/d3.v5.min.js"></script>
<select id='myid' name='name' class='form-control'>
  <option disabled selected>Select one item</option>
</select>