2013-12-24 43 views
0

我似乎无法弄清楚如何在重新排列排名数据时更新条形标签;基本上标签名称将保持不变,但其顺序会改变。d3.js排序数据后更新条形图标签

本来我有:

// University Names 
    labelsContainer = chart.append('g') 
          .attr('transform', 'translate(' + (uniLabel - barLabelPadding) + ',' + (gridLabelHeight + topMargin) + ')') 
          .selectAll('text') 
          .data(sortedData) 
          .enter() 
          .append('text') 
          .attr('x', xoffset) 
          .attr('y', yText) 
          .attr('stroke', 'none') 
          .attr('fill', 'black') 
          .attr("dy", ".35em") // vertical-align: middle 
          .attr('text-anchor', 'end') 
          .text(barLabel); 

我不同的数据,我还是叫sortedData排序。图更新的矩形和休息成功...保存标签

在一个新的功能,我想(我有只有一个矩形条列):

 // update University Names (this overwrites, however... I want to select the existing label instead of appending text on top of the original text) 
     labelsContainer = chart.append('g') 
           .attr('transform', 'translate(' + (uniLabel - barLabelPadding) + ',' + (gridLabelHeight + topMargin) + ')') 
           .selectAll('text') 
           .data(sortedData) 
           .enter()    // using transition ... or selecting the group ... does not allow the new text to appear! 
           .append('text') 
           .attr('x', xoffset) 
           .attr('y', yText) 
           .attr('stroke', 'none') 
           .attr('fill', 'black') 
           .attr("dy", ".35em") // vertical-align: middle 
           .attr('text-anchor', 'end') 
           .text(barLabel); 

这里的问题是这只是在现有的标签上添加新的(正确的)标签,而不是替换它们。

使用transition()我能够更新图形的其余部分,但不能更新标签。

任何想法如何解决?乐意为您提供更多信息/语境如果需要的话......

更新12/24:的jsfiddle:http://jsfiddle.net/myhrvold/BVB2d/

的jsfiddle显示过渡,但标签被覆盖:http://jsfiddle.net/myhrvold/BVB2d/embedded/result/

我知道,通过追加,我在覆盖;但在试图更换时,没有任何反应,原始文本仍然存在,所以这里的想法是,我表明我至少生成了正确的新标签并将它们放在正确的位置......只是我是而不是用我的原始标签替换它们...

+0

你可以把你的代码放到jsfiddle来显示数据 –

+0

你在'.selectAll('text')'前调用'chart.append('g')',它选择新容器中的'text'节点。试试'chart.select('g')'来选择'g'。虽然:你可能需要添加更多的类,以使其在图表内唯一可识别。 'g.univerity的标签,container'。 –

+0

您必须在尝试更新标签时使用d3的“更新”选项。请参阅此[链接](http://bost.ocks.org/mike/join/)以获取详细的连接记录。您也可以在调用['.data()'](https://github.com/mbostock/d3/wiki/Selections#wiki-data)方法时指定'key'函数访问器。如果您需要更多帮助,请粘贴小提琴。 – jacquard

回答

2

当您更新数据时,您完全重复了您的代码 - 包括创建新组的chart.append('g'),然后向其添加文本标签。因为您刚刚将其创建为新组,所以当您在其中选择内容时,无法选择第一次创建的任何标签,因此最终会创建所有新标签。

解决方法:首先,如@musically_ut建议,为每个组分配一个唯一的类名称。然后,在您的更新方法中,使用chart.select(g.univerity-labels-container).selectAll("text")选择该组及其包含的文本元素。然而,你会发现你仍然有问题,因为你已经把所有东西链接到一个enter();由于您不希望在排序时添加新元素,只需取出该行即可。 *

这应该让它工作,但该程序仍然痛苦地复杂,你想要做什么。对于初学者来说,所有这些都可以作为一个HTML表格来处理,它可以为你处理大量的布局。更重要的是,如果不按列将元素按行分组,则可以节省大量工作。这样,您只需将数据连接到组,而不是对每个变量进行单独的数据连接。如果我在接下来的几天内有机会,我可能会试着写一篇关于如何解决这个问题的解释。同时,谷歌“d3排序表”为几个例子,或者看看这个NYT graphic by Mike Bostock的源代码。

*若要更新enter()步骤,我发现大多数教程并未很清楚地描述更新过程,但我昨天写下了一步一步的分解细节here

+0

感谢您的详细解释。我第一次尝试开始工作,只为标签容器添加独特的类名。我在我的原始标签容器的chart.append('g')下面添加:.attr(“class”,“univerity-labels-container”)。然后,在我的sort_orig()函数中添加:chart.select(g.univerity-labels-container).selectAll(“text”)到labelsContainer中,同时删除enter()语句(和selectAll(“text”))我在下面)。但是我得到一个错误:'Uncaught ReferenceError:g is not defined'。这是一个范围界定问题吗?已经玩弄,但无法去工作... – Conor

+0

更新JFiddle:http://jsfiddle.net/myhrvold/C99pP/2/(注意sort_orig()函数现在不工作,即使JSFiddle说该代码是确定的)。结果:http://jsfiddle.net/myhrvold/C99pP/3/embedded/result/ – Conor

+0

对不起,那是我的错误。选择器周围应该总是有引号,即:'chart.select(“g.univerity-labels-container”)。selectAll(“text”)'g没有定义'错误通常是一个好兆头,我忘记了把东西放在引号中,而javascript正在寻找这个名字的变量。 – AmeliaBR