d3js - 仅基于嵌套数据添加元素

时间:2016-03-24 11:38:06

标签: javascript d3.js

我有一些看起来像这样的数据:

[  
   {  
      "territory":"Albania",
      "titles":[
        {"status":"reverted", "contract date": "12/12/2007", "reversion":"12/12/2012"},
        {"status":"reverted", "contract date": "12/12/2007", "reversion":"12/12/2012"},
        {"status":"none", "contract date": false, "reversion":false},
        {"status":"active", "contract date": "12/12/2007", "reversion":"12/12/2017"}
      ]
   },
   {  
      "territory":"Argentina",
      "titles":[
        {"status":"reverted", "contract date": "12/12/2007", "reversion":"12/12/2012"},
        {"status":"reverted", "contract date": "12/12/2007", "reversion":"12/12/2012"},
        {"status":"none", "contract date": false,  "reversion":false},
        {"status":"active", "contract date": "12/12/2007", "reversion":"12/12/2017"}
      ]
   },
   {  
      "territory":"Bosnia Herzegovina",
      "titles":[
        {"status":"reverted", "contract date": "12/12/2007", "reversion":"12/12/2012"},
        {"status":"reverted", "contract date": "12/12/2007", "reversion":"12/12/2012"},
        {"status":"none", "contract date": false,  "reversion":false},
        {"status":"active", "contract date": "12/12/2007", "reversion":"12/12/2017"}
      ]
   }
]

我想要做的是在d3js中为嵌套的“titles”数组中的每个条目添加一个圆圈,其中圆圈的“y”位置基于父“领土”和基于位置的“x”位置在titles数组中。我可以弄清楚如何为父数组添加一个圆圈,这是我不想要的 - 但我无法弄清楚如何实现我想要的东西。

基本上我希望输出看起来像这样:

Circles

每行圆圈代表一个地区的四个标题。

到目前为止,我的代码是这样的:

var width = 940,
    height = 500

var svg = d3.select("#div")
        .append("svg")
          .attr("width", width)
          .attr("height", height)

  var circle = svg.selectAll("circle")
      .data(data)
      .enter().append("circle")
      .attr("r", "12.5")
      .attr("transform", function(d, i) { return "translate(68, " + (((i+1)*28)+64) + ")" });

这显然为每个区域绘制了一个圆圈,但我不知道如何将titles数组合并到此中。我真的不想要每个领域都有一个圆圈,我想为每个标题设一个圆圈。抱歉我的尝试到目前为止有多糟糕,但每当我试图让它变得更复杂时,它就会停止工作。

1 个答案:

答案 0 :(得分:2)

首先,您需要为1级节点创建一个选择,并为它们分配一个容器元素,让我们说g

var territories = svg.selectAll("g").data(data);
territories
    .enter().append("g");

在此选择中,使用titles键作为数据创建新选择,并分配选项circle元素:

territories.selectAll("circle")
    .data(function(d) {
        return d.titles;
    })
    .enter().append("circle")
    .attr("r", "12.5")
    .attr('class', function(d, numtitle, numterritory) {
        return 'row_'+numterritory+' col_'+numtitle;
    })
    .attr("transform", function(d, numtitle, numterritory) { 
        var x = 68 + numtitle*30,
            y = 64 + (numterritory+1)*28;
        return "translate(" + x + ", " + y + ")" 
    });

一起玩的演示



var data = [  
   {  
      "territory":"Albania",
      "titles":[
        {"status":"reverted", "contract date": "12/12/2007", "reversion":"12/12/2012"},
        {"status":"reverted", "contract date": "12/12/2007", "reversion":"12/12/2012"},
        {"status":"none", "contract date": false, "reversion":false},
        {"status":"active", "contract date": "12/12/2007", "reversion":"12/12/2017"}
      ]
   },
   {  
      "territory":"Argentina",
      "titles":[
        {"status":"reverted", "contract date": "12/12/2007", "reversion":"12/12/2012"},
        {"status":"reverted", "contract date": "12/12/2007", "reversion":"12/12/2012"},
        {"status":"none", "contract date": false,  "reversion":false},
        {"status":"active", "contract date": "12/12/2007", "reversion":"12/12/2017"}
      ]
   },
   {  
      "territory":"Bosnia Herzegovina",
      "titles":[
        {"status":"reverted", "contract date": "12/12/2007", "reversion":"12/12/2012"},
        {"status":"reverted", "contract date": "12/12/2007", "reversion":"12/12/2012"},
        {"status":"none", "contract date": false,  "reversion":false},
        {"status":"active", "contract date": "12/12/2007", "reversion":"12/12/2017"}
      ]
   }
];

var width = 320,
    height = 150

var svg = d3.select("#div")
        .append("svg")
          .attr("width", width)
          .attr("height", height)

var territories = svg.selectAll("g").data(data);
  
territories
	.enter().append("g");
      
territories.selectAll("circle")
  .data(function(d) {
  return d.titles;
})
  .enter().append("circle")
  .attr("r", "12.5")
  .attr('class', function(d, numtitle, numterritory) {
  return 'row_'+numterritory+' col_'+numtitle;
})
  .attr("transform", function(d, numtitle, numterritory) { 
  var x = 30 + numtitle*30,
      y = 10 + (numterritory+1)*28;
  return "translate(" + x + ", " + y + ")" 
});

.row_0 {fill: red}
.row_1 {fill: green}
.row_2 {fill: blue}

.col_0 {fill-opacity: 1}
.col_1 {fill-opacity: 0.75}
.col_2 {fill-opacity: 0.5}
.col_3 {fill-opacity: 0.25}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id='div'>
</div>
&#13;
&#13;
&#13;

https://jsfiddle.net/nikoshr/4tp1accu/