2017-12-28 30 views
0

私はドーナツチャートにD3の凡例を追加しようとしていますが、ここの例はhttp://bl.ocks.org/ZJONSSON/3918369です。ドーナツチャートはうまく描画されます。`d3.legend`を使用したエラー:未知の型エラー:node.getAttributeは関数ではありません

しかし、私は以下のエラーに実行しています:d3.legend()関数内で

、私はこのエラーを取得しています「キャッチされない例外TypeError:node.getAttributeは関数ではありません」:このと」キャッチされない例外TypeError。 querySelectorAllは関数ではありません '。

私はなぜ...任意の考えですか?

// Alerts.js 
renderBody() { 
    const {list, currentProgram} = this.props 
    const width = 260; 
    const height = 260; 
    const radius = width/2; // 130 

    // arc & label generator 
    let arc = d3.arc() 
     .outerRadius(radius - 10) 
     .innerRadius(90) 
     .padAngle(0.02); 

    let labelArc = d3.arc() 
     .outerRadius(radius + 60) 
     .innerRadius(radius - 90); 

    // pie generator 
    let pie = d3.pie() 
     .sort(null) 
     .value(d => { return d; }); 

    // define svg 
    let svg = d3.select('.enrolled-statistics-svg').append('svg') 
     .attr('width', width) 
     .attr('height', height) 
     .append('g') // group similar elements together 
     .attr('transform', 'translate(' + width/2 + ', ' + height/2 + ')'); 

    // append g elements (arc) 
    const g = svg.selectAll('.arc') 
     .data(pie(testData)) 
     .enter().append('g') 
     .attr('class', 'arc'); 

    // append the path of the arc 
    g.append('path') 
     .attr('d', arc) 
     .attr('data-legend', val => { 
     return val.data; 
     }) 
     .attr('data-legend-pos', (val) => { 
     return val.index; 
     }) 
     .style('fill', val => { 
     return COLOR_ARRAY[val.index]; 
     }); 

    // append with label 
    g.append('text') 
     .attr('transform', d => { 
     return 'translate(' + labelArc.centroid(d) + ')'; 
     }) 
     .attr('dy', '0.35em') 
     .text(val => { 
     return (val.data/testResp.data.enrolledStatistics.total) * 100 + '%'; 
     }); 

    // define d3.legend() 
    d3.legend = (g) => { 

     g.each(() => { 
     let g = d3.select(this); 
     console.log('------- g: ', g); 

     let items = {}; 
     let svg = d3.select(g.property('nearestViewportElement')); 
     let legendPadding = g.attr('data-style-padding') || 5; // ERROR: Uncaught TypeError: node.getAttribute is not a function 
     let legendBox = g.selectAll('.legend-box').data([true]); // ERROR: Uncaught TypeError: this.querySelectorAll is not a function 
     let legendItems = g.selectAll('.legend-items').data([true]); 

     legendBox.enter().append('rect').classed('legend-box', true); 
     legendItems.enter().append('g').classed('legend-items', true); 

     svg.selectAll('[data-legend]').each(() => { 
      let self = d3.select(this) 
      items[self.attr('data-legend')] = { 
      pos: self.attr("data-legend-pos") || this.getBBox().y, 
      color: self.attr("data-legend-color") != undefined ? self.attr("data-legend-color") 
       : self.style("fill") != 'none' ? self.style("fill") : self.style("stroke") 
      } 
     }); 

     items = d3.entries(items).sort(function (a, b) { 
      return a.value.pos - b.value.pos 
     }); 

     console.log('------- items: ', items); 

     legendBox.selectAll('text') 
      .data(items, val => val.key) 
      .call(val => { 
      val.enter().append('text') 
      }) 
      .call(val => { 
      val.exit().remove() 
      }) 
      .attr('y', (val, i) => { 
      return `${i}em` 
      }) 
      .attr('x', '1em') 
      .text(val => val.key); 

     legendItems.selectAll("circle") 
      .data(items, function (d) { 
      return d.key 
      }) 
      .call(val => val.enter().append("circle")) 
      .call(val => val.exit().remove()) 
      .attr('cy', (val, i) => `${i - 0.25}em`) 
      .attr('cx', 0) 
      .attr('r', '0.4em') 
      .style('fill', val => { 
      console.log(val.value.color); 
      return val.value.color 
      }); 

     // Reposition and resize the box 
     let lbbox = li[0][0].getBBox(); 

     lbbox.attr("x", (lbbox.x - legendPadding)) 
      .attr("y", (lbbox.y - legendPadding)) 
      .attr("height", (lbbox.height + 2 * legendPadding)) 
      .attr("width", (lbbox.width + 2 * legendPadding)); 
     }); 

     return g; 
    } 

    // define legend svg 
    let padding = 20; 
    let legx = radius + padding; 
    let legendSVG = d3.select('.enrolled-statistics').append('svg') 
     .attr('width', 150) 
     .attr('height', 150) 
     .append('g') 
     .attr('class', 'legend') 
     .attr('transform', 'translate(' + legx + ', 0)') 
     .style('font-size', '12px') 
     .style('fill', 'blue') 
     .call(d3.legend); 

    return(....) 
    } 

答えて

2

矢印機能を使用してeachコールバックを定義しています。これにより、thisキーワードの詳細情報が変更されます。here)。だから基本的にd3.select(this)はあなたが期待するものを選択しません。また、2つの異なる方法で変数としてgを使用していますが、予期しない動作につながる可能性があります(とにかく混乱を避けるために別名で変数を作成することをお勧めします)。

関連する問題