How do I create a definition list with d3.js?

不羁的心 提交于 2019-11-30 18:13:17

问题


I am trying to create a definition list such as this one:

<dl>
   <dt>term1</dt>
   <dd>definition1</dd>
   <dt>term2</dt>
   <dd>definition2</dd>
   <dt>term3</dt>
   <dd>definition3</dd>
</dl>

by using a JSON in this form:

{
  "term1":"definition1"
  "term1":"definition2"
  "term3":"definition3"
}

. Whch is the most elegant way to do it with d3.js?

PS: I would like to use the <dl> element because it seems the most appropriate way to semantically represent a key:value pair:

  • http://html5doctor.com/the-dl-element/
  • Semantics and Structure of Name-Value Pairs

回答1:


Solution for d3 v3.x; no longer works as of d3 4.0

I struggled with the same issue for a while. What I found was the behavior of insert() with the enter() selection does the trick. This is based on the interaction between the enter selection whose inserted or appended elements are merged into the update selection, the the way that insert works with enter selections. The relevant bits in the documentation:

selection.enter()

… The enter selection merges into the update selection when you append or insert.

selection.insert()

… For enter selections, the before selector may be omitted, in which case entering elements will be inserted immediately before the next following sibling in the update selection, if any. This allows you to insert elements into the DOM in an order consistent with bound data.

The result is that if you insert some dt elements into the enter selection, they will be merged into the update selection. Then, if you then insert some dd elements into the enter selection, they will be "inserted immediately before the next following sibling in the update selection"; that is, they'll be right after their associated dt.

var data = { a: 1, b: 2, c: 3 };
var dl = d3.select("body").append("dl").selectAll().data(Object.keys(data));
dl.enter().insert("dt").text(function(key) { return key });
dl.enter().insert("dd").text(function(key) { return data[key] });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>



回答2:


When the content is simple like you describe, the easiest way may be to just directly create paired HTML elements and bind the data to them afterward.

Also everything is much easier as a list -- D3's entries function can easily blow your object out to a list of objects:

var pairs = {
  "term1":"definition1",
  "term2":"definition2",
  "term3":"definition3"
};
var pairlist = d3.entries(pairs);  // [{"key":"term1", "value":"definition1"}, etc... ]

var dl = d3.select("dl").html( new Array(pairlist.length + 1).join("<dt/><dd/>") );

dl.selectAll("dt").data(pairlist).html(function(d) { return d.key; });
dl.selectAll("dd").data(pairlist).html(function(d) { return d.value; });

JsFiddle: http://jsfiddle.net/slushy/bbh6a4w0/




回答3:


Here is what I would do:

list = {
  "term1":"definition1",
  "term2":"definition2",
  "term3":"definition3"
}

dl = d3.select('body').append('dl')
for(var key in list) {
    dl.append('dt').text(key)
    dl.append('dd').text(list[key])
}

JsFiddle: http://jsfiddle.net/chrisJamesC/RZdQw/

Then, if you want to be more d3 specific, you can use selections (more about implementation).

By the way, using arrays might be easier than json objects to represent lists



来源:https://stackoverflow.com/questions/24116328/how-do-i-create-a-definition-list-with-d3-js

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