我进入d3.js已经2天了,我已经建立了用于网球锦标赛的抽奖结构。
我开始的数据低于 -
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]}]}];
......我无法弄清楚我的代码应该改变什么。
当然,我有另一个问题。您可以看到我没有连接各级别获胜者的链接。我需要他们。我考虑了群集布局,但我想我将不得不根据数据进行重组。我的情况与集群案例相反。 (穆库尔)
答案 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映射。因此,您有一项任务就是弄清楚如何从数据结构中提取这些链接。但在此之前,您必须弄清source
和target
实际上是什么,而且我并不完全确定最有效的方法。它不仅仅是一个玩家对象,因为在你的情况下它在两个地方都是同一个玩家。因此,source
和target
也必须封装level
,无论如何,您需要level
才能确定每行末尾的x位置。在seq
和source
中,target
是您需要的第三件事,因为这是确定线条的方法。的y位置。我的建议是将两个这样的链接手工编写成links
数组,然后弄清楚如何将它们呈现为行。一旦你找到了有效的方法,就可以从links
找出如何以编程方式构建data
。希望有所帮助。