2017-05-13 32 views
0

我有很多的麻烦来更新我的堆积柱形图工作。 (TL; DR:there's a fiddle here,并且误差在线路194-5发生时)。无法获得更新的数据连接模式上d3.stack数据结构

作为一个例子,由stack函数创建的数据结构是这样的:

[ 
    [ [0,5], [0,4], [0,6], [0,3] ], // key: apple 
    [ [5,7], [4,7], [6,7], [3,3] ] // key: banana 
] 

想象每一列代表维生素,然后一个苹果将具有5个单位vitimin A的,维生素B的4等...,和橙色将具有2个单位的维生素A,3 O维生素B等

我可以在ES6类创建图表:

this.svg.append("g") 
     .attr("class", "seriesGroup") 
    .selectAll("g") 
    .data(stack(this.data)) 
    .enter() 
    .append("g") 
     .attr("class", (d,i) => { return "series" + i}) 
    .selectAll("rect") 
    .data((d) => { return d; }) 
    .enter() 
    .append("rect") 
     .attr("class", ("bar")) 
     .attr("x", (d) => { return this.x(d.data.perception); }) 
     .attr("y", (d) => { return this.y(d[1]); }) 
     .attr("height", (d) => { return this.y(d[0])- this.y(d[1]); }); 
     .attr("width", this.x.bandwidth()) 

即代码创建结构:

<g class="seriesGroup"> 
    <g class="series0> //apple 
    <rect class="bar"> 
    ... 
    </g> 
    <g class="series1"> //banana 
    ... 

但更新也很难。如果我改变了数据零出苹果系列,并再次调用stack,我现在有:

[ 
    [ [0,0], [0,0], [0,0], [0,0] ], // key: apple 
    [ [0,2], [0,3], [0,1], [0,0] ] // key: banana 
] 

这里是我的更新代码:

let seriesGroup = this.svg.selectAll(".seriesGroup") 
     .data(stack(newData)) 
     .attr("class", "seriesGroup updated"); 

    let series = seriesGroup.enter() 
     .selectAll((d,i) => { console.log(i + " series data is " + d); return ".series" + i }) 
     .data((d) => { console.log(d); return d; }) 
     .enter() 
      .attr("class", (d) => { console.log(d); return "series updated2" }); 

    series.enter() 
     .selectAll("rect") 
     .data((d) => { console.log(d); return d; }) 
      .attr("class", ("bar updated")) 
      .transition().duration(this.settings.transitionDuration) 
      .attr("y", (d) => { 
      console.log("Now setting y to " + this.y(d[1]) + " and height to " + (this.y(d[0]) - this.y(d[1])) + " for data " + d); 
      return this.y(d[1]); }) 
      .attr("height", (d) => { return this.y(d[0])- this.y(d[1]); }); 

不知怎的,这个代码/ SVG结构组合造成来自d3库的TypeError: this.setAttribute is not a function。导致错误的行是:

.attr("class", (d) => { console.log(d); return "series updated2" }); 

显然我搞砸了数据连接,但我不知道如何。我究竟做错了什么?

+0

看看'series':你有** 3 **'输入()'功能,**无** append()函数和一堆'attr()'函数。我不知道你在这里做什么。 –

+0

这三个输入函数反映了数据结构的三个层次:首先是,其数据是整个堆栈数组,其次是',其数据是单个“关键”行,第三其数据的是堆叠'[lowerValue,upperValue]'对从行。没有'append()',因为svg元素的数目不应该改变;我只是想改变现有的''元素的高度。提供的小提琴链接显示它应该如何工作,以及它如何在中途通过。 – Escher

+1

阅读上面的评论后,我劝你学习什么是“进入”选择和什么是'输入()'方法的目的。这是一个建设性的批评。 –

回答

0

此错误的根本原因是糟糕的选择。 selectAll不能承担它似乎数据映射匿名函数,所以这条线将不起作用:

.selectAll((d,i) => { return ".series" + i })

概念我觉得这有点奇怪,因为家长选择seriesGroup确实已经有数据绑定它 - 希望有人可以评论和解释为什么该行不起作用。解决的办法是声明每个.seriesN基作为.series类也一样,并选择。

.selectAll(".series")

然后一个新的数据连接,可以进行,例如:

.selectAll(".series") 
    .data((d) => { return d; }) 
    .attr("class", (d,i) => { return "series updated2 series" + i});