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

2019-02-15 01:24发布

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:

3条回答
甜甜的少女心
2楼-- · 2019-02-15 01:56

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

查看更多
We Are One
3楼-- · 2019-02-15 02:15

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/

查看更多
姐就是有狂的资本
4楼-- · 2019-02-15 02:18

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>

查看更多
登录 后发表回答