D3.js多维数组

时间:2017-11-07 17:25:20

标签: javascript html d3.js svg

我刚刚开始使用D3.js而且这很棒,但学习曲线陡峭。 我有以下代码。

book

我不明白为什么时间没有正确显示。这就是生成的内容

book

显然我希望var local = d3.local(); var data2 = [ { id: 1, name: "reg1", movements: [ { id: 1, text: "mov1", start: new Date(2017, 1, 1, 17, 0, 0, 0), end: new Date(2017, 1, 1, 17, 30, 0, 0) }, { id: 2, text: "mov2", start: new Date(2017, 1, 1, 16, 0, 0, 0), end: new Date(2017, 1, 1, 16, 30, 0, 0) }, { id: 3, text: "mov3", start: new Date(2017, 1, 1, 15, 0, 0, 0), end: new Date(2017, 1, 1, 15, 30, 0, 0) } ] }, { id: 2, name: "reg2", movements: [ { id: 5, text: "mov4", start: new Date(2017, 1, 1, 15, 0, 0, 0), end: new Date(2017, 1, 1, 15, 45, 0, 0) }, { id: 6, text: "mov5", start: new Date(2017, 1, 1, 18, 0, 0, 0), end: new Date(2017, 1, 1, 18, 45, 0, 0) }, { id: 7, text: "mov6", start: new Date(2017, 1, 1, 22, 0, 0, 0), end: new Date(2017, 1, 1, 23, 45, 0, 0) } ] } ]; var svg = d3 .select("body") .append("svg") .attr("width", 1500) .attr("height", 500); svg .append("g") .selectAll("g") .data(data2) .enter() .append("text") .text(function(d, i, j) { return d.name; }) .attr("x", function(d, i, j) { return 40; }) .attr("y", function(d, i, j) { return i* 20 + 40; }) .attr("font-family", "sans-serif") .attr("font-size", "20px") .append("g") //removing .selectAll("text") // these .data(function(d, i, j) { local.set(this, i); return d.movements; }) //lines .enter() //text displays normally .append("text") .text(function(d, i, j) { return d.start.getHours(); }) .attr("x", function(d, i, j) { return i * 300 + 40; }) .attr("y", function(d, i, j) { return local.get(this) * 20 + 40; }) .attr("font-family", "sans-serif") .attr("font-size", "20px"); 来到 <svg width="1500" height="500"> <g> <text x="40" y="40" font-family="sans-serif" font-size="20px">reg1 <g> <text x="40" y="40" font-family="sans-serif" font-size="20px">17</text> <text x="340" y="40" font-family="sans-serif" font-size="20px">16</text> <text x="640" y="40" font-family="sans-serif" font-size="20px">15</text> </g> </text> <text x="40" y="60" font-family="sans-serif" font-size="20px">reg2 <g> <text x="40" y="60" font-family="sans-serif" font-size="20px">15</text> <text x="340" y="60" font-family="sans-serif" font-size="20px">18</text> <text x="640" y="60" font-family="sans-serif" font-size="20px">22</text> </g> </text> </g> </svg> 标签之前,但我看不出我做错了什么。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

问题是您要将<g>元素附加到<text>元素。将元素A附加到元素B将元素A作为子元素放在元素B中。这就是文本关闭标记到达它的位置的原因。

为什么你的代码会这样做?

您需要跟踪链接时每种方法返回的对象,尤其是在连续多次选择,输入和追加时。 以下代码块使用您的代码,但我已经删除了所有.attr.text方法,因为这些方法只返回他们修改的相同选择。请记住,每一行(除了第一行)都会调用上面一行返回的对象的方法:

svg.append("g")     // returns the new <g> in a selection
  .selectAll("g")   // returns a null selection with the 1st <g> as the parent element
   .data(data2)              
  .enter()          // returns a selection of elements to create in the 1st <g> based on the data  
  .append("text")   // returns a selection of text elements in the 1st <g>
  .append("g")      // returns a selection of <g> elements appended to the <text> elements 
  .selectAll("text")// returns a null selection of <text> elements in those <g> elements in the <text> elements
  .data(function(d, i, j) {  }) 
  .enter()         // returns a selection of elements to create in those <g> elements in the <text> elements in the 1st <g>
  .append("text")  // ....

您可以看到,您可以选择附加子g标签的文本元素(以及更多文本)。

相反,打破链条。立即附加父g元素以分隔不同的基准并将其存储在选择中。然后根据绑定数据将text和child g元素附加到此选择中:

var data2 = [
  {
    id: 1,
    name: "reg1",
    movements: [
      {
        id: 1,
        text: "mov1",
        start: new Date(2017, 1, 1, 17, 0, 0, 0),
        end: new Date(2017, 1, 1, 17, 30, 0, 0)
      },
      {
        id: 2,
        text: "mov2",
        start: new Date(2017, 1, 1, 16, 0, 0, 0),
        end: new Date(2017, 1, 1, 16, 30, 0, 0)
      },
      {
        id: 3,
        text: "mov3",
        start: new Date(2017, 1, 1, 15, 0, 0, 0),
        end: new Date(2017, 1, 1, 15, 30, 0, 0)
      }
    ]
  },
  {
    id: 2,
    name: "reg2",
    movements: [
      {
        id: 5,
        text: "mov4",
        start: new Date(2017, 1, 1, 15, 0, 0, 0),
        end: new Date(2017, 1, 1, 15, 45, 0, 0)
      },
      {
        id: 6,
        text: "mov5",
        start: new Date(2017, 1, 1, 18, 0, 0, 0),
        end: new Date(2017, 1, 1, 18, 45, 0, 0)
      },
      {
        id: 7,
        text: "mov6",
        start: new Date(2017, 1, 1, 22, 0, 0, 0),
        end: new Date(2017, 1, 1, 23, 45, 0, 0)
      }
    ]
  }
];

var svg = d3
  .select("body")
  .append("svg")
  .attr("width", 1500)
  .attr("height", 500);

// a group for each data array item
var g = svg.selectAll("g")
  .data(data2)
  .enter()
  .append("g")
  .attr("transform", function(d,i) { 
    return "translate("+[40,i*20+40]+ ")"
  })

// some text for each group array item
g.append("text")
  .text(function(d) {
    return d.name;
  })
  .attr("font-family", "sans-serif")
  .attr("font-size", "20px");
 
// a sub group with text for each item in the nested data array 
g.append("g") 
  .selectAll("text")   
  .data(function(d) {
    return d.movements;
  }) 
  .enter() 
  .append("text")
  .text(function(d) {
    return d.start.getHours();
  })
  .attr("x", function(d, i, j) {
    return i * 150 + 60;
  })
  .attr("font-family", "sans-serif")
  .attr("font-size", "20px");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>