需要d3.js逻辑来处理JSON数据

时间:2014-11-21 19:12:10

标签: javascript json d3.js

我进入d3.js已经2天了,我已经建立了用于网球锦标赛的抽奖结构。

enter image description here

我开始的数据低于 -

var data = [
            [["Andy","Marin"],["David","Kei"],["Novak","Stani"],["Roger","Gael"],["Phili","John"],["Milos","Rafa"],["Tomas","Grig"],["Jo-Wi","Gill"]],
            [["Marin","Kei"],["Stani","Roger"],["John","Rafa"],["Tomas","Jo-Wi"]],
            [["Marin","Stani"],["John","Jo-Wi"]],
            [["Stani","John"]]
           ];

我不知道怎么但是我到达了下面的代码来实现这个(我使用了很多mbostock的代码) -

var playerOffsetX = 20;
	rectY= 20;
	rectGapY = 10;
	matchGapY = 30;
	rectX = 100;
	matchY = 2 * rectY + rectGapY + matchGapY;
	totalY = 8 * matchY;

var svg = d3.selectAll("svg");

var level = svg.selectAll(".level")
		.data(data)
	.enter().append("g")
		.attr("transform", function(d, i) { return "translate(" + (i * 200) + "," + Math.pow(2,i)*matchY/2 + ")"; })
		.attr("class", "level");

var match = level.selectAll(".match")
		.data(function(d) { return d ; })
	.enter().append("g")
		.attr("transform", function(d, i, j) { return "translate(0," + (Math.pow(2,j)*i*matchY) + ")"; })
		.attr("class", "match");
		
var player = match.selectAll(".player")
	.data(function(d) { return d; })
	.enter()
	.append("g")	
		.attr("transform", function(d, i) { return "translate("+ (playerOffsetX) + "," + (i == 0 ? 0 : (rectY+rectGapY)) + ")"; })
		.attr("class", "player");
		
player.append("rect")
	.attr("width", rectX)
	.attr("height", rectY)
	.attr("class", "player");
	
player.append("text")
	.attr("x", 3)
	.attr("y", rectY / 2)
	.attr("dy", ".35em")
	.text(function(d) { return d; });

</script>

现在这是我的问题。我希望通过数据进行重组 -

var data = [{ "level": 1, "matches": [{"seq": 1, "seeds": [1,16]}, {"seq": 2, "seeds": [8,9]},  {"seq": 3, "seeds": [4,13]}, {"seq": 4, "seeds": [5,12]},
                               		  {"seq": 5, "seeds": [2,15]}, {"seq": 6, "seeds": [7,10]}, {"seq": 7, "seeds": [3,14]}, {"seq": 8, "seeds": [6,11]}]},
            { "level": 2, "matches": [{"seq": 9, "seeds": [0,0]}, {"seq": 10, "seeds": [0,0]}, {"seq": 11, "seeds": [0,0]}, {"seq": 12, "seeds": [0,0]}]},
            { "level": 3, "matches": [{"seq": 13, "seeds": [0,0]}, "seq": 14, "seeds": [0,0]}]},
            { "level": 4, "matches": [{"seq": 15, "seeds": [0,0]}]}];

......我无法弄清楚我的代码应该改变什么。

当然,我有另一个问题。您可以看到我没有连接各级别获胜者的链接。我需要他们。我考虑了群集布局,但我想我将不得不根据数据进行重组。我的情况与集群案例相反。 (穆库尔)

1 个答案:

答案 0 :(得分:1)

你想要它的结构应该和原来的结构一样好,因为它仍然像以前一样基本上是一个3级数组,但是因为你现在把东西包裹在对象中,你必须调整渲染时子阵列的访问方式。我已经标记了<-- THIS这三个地方:

var level = svg.selectAll(".level")
    .data(data)
  .enter().append("g")
    .attr("transform", function(d, i) { return "translate(" + (i * 200) + "," + Math.pow(2,i)*matchY/2 + ")"; })
    .attr("class", "level");

var match = level.selectAll(".match")
    .data(function(d) { return d.matches ; })// <-- THIS
  .enter().append("g")
    .attr("transform", function(d, i, j) { return "translate(0," + (Math.pow(2,j)*i*matchY) + ")"; })
    .attr("class", "match");

var player = match.selectAll(".player")
  .data(function(d) { return d.seeds; })// <-- THIS
  .enter()
  .append("g")  
    .attr("transform", function(d, i) { return "translate("+ (playerOffsetX) + "," + (i == 0 ? 0 : (rectY+rectGapY)) + ")"; })
    .attr("class", "player");

player.append("rect")
  .attr("width", rectX)
  .attr("height", rectY)
  .attr("class", "player");

player.append("text")
  .attr("x", 3)
  .attr("y", rectY / 2)
  .attr("dy", ".35em")
  .text(function(d) { return getPlayerByIdOrSomethingLikeThat(d); });// <-- THIS

除非我忽略了某些东西,否则它将起作用。

关于第二个问题,我认为力布局(不是群集)是你想要看到和学习​​的东西 - 不是因为力布局是移动节点(你不是),而是因为大多数强制布局示例都有节点和链接(您也可以这样做)。在这种情况下,您希望将链接表示为将source映射到target的对象数组:

[
  { source: {...}, target: {...} },
  { source: {...}, target: {...} }, 
  { source: {...}, target: {...} },
  ...
]

因为那样你就可以照常完成整个d3.select(...).selectAll(...).data(...).enter().append('line')业务,追加连接它们的行。即这将是方便的,因为它是源 - 目标对与SVG <line> s)之间的1对1映射。因此,您有一项任务就是弄清楚如何从数据结构中提取这些链接。但在此之前,您必须弄清sourcetarget实际上是什么,而且我并不完全确定最有效的方法。它不仅仅是一个玩家对象,因为在你的情况下它在两个地方都是同一个玩家。因此,sourcetarget也必须封装level,无论如何,您需要level才能确定每行末尾的x位置。在seqsource中,target是您需要的第三件事,因为这是确定线条的方法。的y位置。我的建议是将两个这样的链接手工编写成links数组,然后弄清楚如何将它们呈现为行。一旦你找到了有效的方法,就可以从links找出如何以编程方式构建data。希望有所帮助。