使用 d3.js 绑定数据内的数组(动态生成具有恒定性的 d3.svg.line)

Posted

技术标签:

【中文标题】使用 d3.js 绑定数据内的数组(动态生成具有恒定性的 d3.svg.line)【英文标题】:Array within bound data (dynamically generating d3.svg.line with constancy) with d3.js 【发布时间】:2015-04-09 03:28:03 【问题描述】:

我正在尝试(动态)生成一组divs,绑定到一些数据,每个 div 都包含一些文本和一个带线条的 SVG。

如果我想一次做一个,这段代码可以工作:

var ccg = [40, 100, 1, 5, 25, 10];

var lineFunction = d3.svg.line()
                      .x(function(d, i)  return width-(i*10); )
                      .y(function(d, i)  return height-d; )

var myContainer = d3.select("body").append("div")

var svgContainer = myContainer.append("svg")
                                 .attr("width", "10px")
                                 .attr("height", "10px");

var correlogram = svgContainer.append("path")
                         .attr("d", lineFunction(ccg))

到目前为止一切顺利。现在我想更新一个数据数组并让它动态更新 DOM:

var width=100,
    height=100;

var clusters = [
id: "1",
    ccg: [40, 100, 1, 5, 25, 10] ,
id: "2", 
    ccg: [41, 101, 11, 51, 21, 11] ,
id: "3", 
    ccg: [42, 130, 13, 53, 21, 101] ,
]

var lineFunction = d3.svg.line()
                    .x(function(d, i)  return width-(i*10); )
                    .y(function(d, i)  return height-d; )
                    .interpolate("step-after");

var clusterView = d3.select("body").append("div")

var clusterDivs = clusterView.selectAll(".cluster")
                        .data(clusters, function(d) return d.id);

var cluster = clusterDivs.enter()
                        .insert("div", ".cluster")

var lineFunction = d3.svg.line()
                     .x(function(d, i)  return width-(i*10); )
                     .y(function(d, i)  return height-d; )
                     .interpolate("step-after");

var svgContainer = cluster.append("svg")
                    .attr("width", width)
                    .attr("height", height);


svgContainer.append("path")
.data(function (d) return d.ccg;)
.enter()
.attr("d", function(d) return lineFunction(d))

cluster.append("div")
    .text(function(d)  return d.id; );

...我收到一个错误。 "TypeError: Cannot read property 'ccg' of undefined"

我尝试了各种方法:将函数直接放入 .attr 似乎“有效”,只是它不返回该属性的任何输出。

基本上,给定输入数组clusters:如何从每个子数组ccg 生成不同的行?我已经阅读了有关嵌套选择的教程,但不确定它是否真的回答了我的问题,因为您无法将每个线顶点绑定到数据点...

【问题讨论】:

【参考方案1】:

见http://jsfiddle.net/henbox/9my6Lznc/

替换:

svgContainer.append("path")
  .data(function (d) return d.ccg;)
  .enter()
  .attr("d", function(d) return lineFunction(d))

与:

svgContainer.append("path")
  .datum(function (d) return d.ccg;)
  .attr("d", function(d) return lineFunction(d))

data 切换为datum 并摆脱enter()。有关datadatum 之间区别的更多讨论,请参阅:https://***.com/a/13728584/3442309。

data 加入一个数组,而你有对象(例如id: "2", ccg: Array[6]

【讨论】:

以上是关于使用 d3.js 绑定数据内的数组(动态生成具有恒定性的 d3.svg.line)的主要内容,如果未能解决你的问题,请参考以下文章

一个初学者的指南,使用D3做数据绑定

D3.js

d3.js--02(data和datum原理)

理解d3.js中的UpdateEnterExit

了解 D3.js 如何将数据绑定到节点

使用 Retrofit 解析数组内的动态数组