我在CSV文件中有一个标签列表,第二列显示了它们所属的捆绑包。带有空标记名称的其他CSV行表示包。
我使用D3读取CSV并为每个捆绑生成父DIV,并使用该捆绑中列出的所有标记填充捆绑DIV。我在这个块中有一个工作示例:http://bl.ocks.org/anilsg/225acdf41638140959ae72aca039b815
我认为我的方法很尴尬。我必须删除最初在错误级别创建的节点,并使用过程方法对数据进行第二次传递。
有更好的方法吗?我注意到了D3 key()
函数和d3.hierarchy
模块,但我不确定它们是否适合作为候选者。也许有更好的方式来使用filter()
和选择?
答案 0 :(得分:1)
有两种方法可以处理'层次结构' d3.js中的数据结构: d3.hierarchy , d3.stratify
使用d3.hierarchy,您的输入数据应为JSON格式 使用d3.stratif,您的输入数据应该是CSV或文本,并且只有一个根节点。
你在这里演示的但是 tag.txt,它可以使用d3.nest()来简化事情。另一个可以修改代码的概念是嵌套选择(further reading)使用selectAll和chaing data()在使用d3.nest()转换后利用修改后的数据。
此外,在您的方案中, 追加 和 插入 的工作方式相同。仅当您需要以交互方式更新时, 删除 也不是必需的。
以下是我的代码和一些建议的解释(供讨论开放)
首先,由于你所有的bundle元素都在容器下,所以我只是从html的主体中添加它。
const container = bodyG.append('div')
.attr('id','container');
第二次,我们可以开始在容器选择上添加第一个bundler元素。
const bundles = container.selectAll('div.bundle')
.data(d3nest)
.enter()
.append('div')
.classed('bundle', true)
//d3nest is created by using d3.nest(), refer to the demo in the last line on Observable
第三次,为了使代码更清晰,我从定义bundle元素中分离了div文本的添加过程。
bundles.insert('h2')
.text((d)=> d.key);
第四,从这里开始,我们使用嵌套选择的概念,使用SelectAll和data()来输入嵌套的数据结构。
const tags = bundles.selectAll('p.tag')
.data((d)=> d.values) // below here, all d mean d.values
.enter() // which is the enter to the nest data.
.append('p')
.classed('tag', true)
.text((d)=> d.tag);
希望这可能会给你一些想法!它可能不是让原始代码更好的唯一方法!
关于Observable https://beta.observablehq.com/@weitinglin/is-there-a-better-way-to-use-d3-to-create-hierarchical-conten 的演示