2016-05-03 14 views
0

今日、私は単純な円グラフでd3.jsを使って作業しています。なぜd3.js円グラフの移行が機能しないのですか?

チュートリアルhereを使用して最初の円グラフを作成しましたが、少しカスタマイズしたかったので、私のコードはまったく同じようには見えません。

ステップ6で作業中に問題が発生しました。チャートに対話性を追加しました。

図のように、円グラフを使用すると、凡例をクリックしてデータを切り替えることができます。しかし、ホバーツールが自分のコードで作業している場合(ホバーボックス内の値を効果的に切り替える)、チャート自体は変更されません。

トグル、私のブラウザコンソールはそのエラースロー:と同じである

var path = g.data(pie(data)); 

    path.transition() 
    .duration(750) 
    .attrTween('d', function(d) { 
      var interpolate = d3.interpolate(this._current, d); 
      this._current = interpolate(0); 
      return function(t) { 
       return arc(interpolate(t)); 
      }; 

:いくつかのテストの後

d3.v3.js:5737 Uncaught TypeError: Cannot use 'in' operator to search for 'data' in undefined 

を、私はエラーが原因のjavascriptのその部分の発生した実現しましたデモで。だから、残りのコードは間違いかもしれないが、私は何が原因か分からない。

スタイリング:

#chart { 
    height: 360px; 
    margin: 0 auto; 
    position: relative; 
    width: 360px; 
} 


.tool { 
    background: #eee; 
    box-shadow: 0 0 5px #999999; 
    color: #333; 
    display: none; 
    font-size: 12px; 
    left: 130px; 
    padding: 10px; 
    position: absolute; 
    text-align: center; 
    top: 95px; 


width: 80px; 
    z-index: 10; 
} 

/* replace bootstrap css */ 
.label { 
    color: #000000 
} 

/* css for the legend*/ 
.legend { 
    font-size: 12px; 
    } 

rect { 
    cursor: pointer; 
    stroke-width: 2; 
    } 

rect.disabled { 
    fill: transparent !important; 
} 

スクリプト:あなたの助けを

// var definition 
var legendRectSize = 18; 
var legendSpacing = 4; 

// defines chart boundaries 
var width = 960; 
var height = 500; 
var radius = Math.min(width, height)/2; 
var DonutWidth = 80; 

// defines a charter of colors for the chart 
var color = d3.scale.ordinal() 
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]); 

// defines graphical attributes for the chart 
var arc = d3.svg.arc() 
    .outerRadius(radius - 10) 
    .innerRadius(radius - DonutWidth); 

var labelArc = d3.svg.arc() 
    .outerRadius(radius - 40) 
    .innerRadius(radius - 40); 


var pie = d3.layout.pie() 
    .sort(null) 
    .value(function(d) { return d.TST; }); 

// add the chart to the html doc 
var svg = d3.select('#chart').append("svg") 
    .attr("width", width) 
    .attr("height", height) 
    .append("g") 
    .attr("transform", "translate(" + width/2 + "," + height/2 + ")"); 

// add objects needed for the hover tool 
var tool = d3.select('#chart') 
    .append('div') 
    .attr('class', 'tool'); 

tool.append('div') 
    .attr('class', 'label'); 

tool.append('div') 
    .attr('class', 'count'); 

tool.append('div') 
    .attr('class', 'percent'); 

// loads data 
d3.json("/media/Storage/bar_chart.json", function(data) { 
    // creates a variable to know if a column will be displayed or not 
    data.forEach(function(d) { 
    d.TST = +d.TST; 
    d.enabled = true; 
    }); 
    // creates the pie chart from data 
    var g = svg.selectAll(".arc") 
     .data(pie(data)) 
    .enter().append("g") 
     .attr("class", "arc"); 

    g.append("path") 
     .attr("d", arc) 
     .attr("fill", function(d, i) { return color(d.data.OPCODE); }) 
     .each(function(d){this._current = d;}); 

    // displays data on hover 
    g.on('mouseover',function(d){ 
    var total = d3.sum(data.map(function(d) { 
    return (d.enabled) ? d.TST : 0; 
    })); 

    var percent = Math.round(1000 * d.data.TST/total)/10; 

    tool.select('.label').html(d.data.OPCODE); 
    tool.select('.count').html(d.data.TST); 
    tool.select('.percent').html(percent + '%'); 
    tool.style('display', 'block'); 
    }); 

    // toggles off hoverbox 
    g.on('mouseout', function(d){ 
     tool.style('display', 'none'); 
    }); 


    // add the legend to the chart 
    var legend = svg.selectAll('.legend') 
    .data(color.domain()) 
    .enter() 
    .append('g') 
    .attr('class', 'legend') 
    .attr('transform', function(d, i) { 
    var height = legendRectSize + legendSpacing; 
    var offset = height * color.domain().length/2; 
    var horz = -2 * legendRectSize; 
    var vert = i * height - offset; 
    return 'translate(' + horz + ',' + vert + ')'; 
    }); 

    legend.append('rect') 
    .attr('width', legendRectSize) 
    .attr('height', legendRectSize) 
    .style('fill', color) 
    .style('stroke', color) 
    // function which toggles data to exclude of display 
    .on('click', function(OPCODE){ 
     var rect = d3.select(this); 
     var enabled = true; 
     var totalEnabled = d3.sum(data.map(function(d) { 
      return (d.enabled) ? 1 : 0; 
     })); 
     if (rect.attr('class') === 'disabled') { 
     rect.attr('class', ''); 
     } else { 
      if (totalEnabled < 2) return; 
      rect.attr('class', 'disabled'); 
      enabled = false; 
      } 
     // defines a new way to retrieve data for the chart, selecting only enabled data 
     pie.value(function(d) { 
     if (d.OPCODE === OPCODE) d.enabled = enabled; 
     return (d.enabled) ? d.TST : 0; 
     }); 

     //incriminated part of the script 
     var path = g.data(pie(data)); 

     // animation for the chart 
     path.transition() 
     .duration(750) 
     .attrTween('d', function(d) { 
       var interpolate = d3.interpolate(this._current, d); 
       this._current = interpolate(0); 
       return function(t) { 
        return arc(interpolate(t)); 
       }; 
     }); 
    }); 


    legend.append('text') 
    .attr('x', legendRectSize + legendSpacing) 
    .attr('y', legendRectSize - legendSpacing) 
    .text(function(d) { return d; }); 
}); 

おかげで多くのことをここで

は、私がこれまで行ってきたものです。

EDIT:

Link to a JSFiddle

私は私のアプリでローカルにロードしていJSONファイルを使用していますので、ここで私はJSONが置かれたローカル変数を使用していた、まだそれ明らかに非効率で、他のバグをもたらしました...

+1

コードに[fiddle](https://jsfiddle.net/)または[bin](http://jsbin.com/?html、出力)を追加してください。 – SiddP

+0

@SiddP JSFiddleを追加しました。しかしそれほど効率的ではありません。ローカルファイルではなくローカル変数を使用するコードを用意していないので、これは正確に動作しません。 Gerardo Furtadoは、粘度、または私が提供したコードで与えられた例を意味しますか?それが第2のケースであれば、これは私のjsonファイルから問題が発生する可能性がありますか? –

+0

申し訳ありません、@カル、私の間違い、私は第2のリンク(plunkr)があなたのコードだと思った。 –

答えて

0

この行にはthis._currentが定義されていません。var i = d3.interpolate(this._current, d);はそれを修正し、残りは十分です。 this.currentの代わりにtemp varを試してください。コード内のどこでもアクセスできます。new dataold dataと異なる場合は、two sets of json and onClickで新しいjsonデータを渡してみてください。

+0

こんにちは。回答ありがとうございます。とにかくこれはまさに私の問題ではありません。はい、私はあなたがこれについて何を意味しているか知っています。現在、それは例でコード化されていて動作しています。理由を知らない。また、onClick関数では、現在有効になっているデータに応じて変数pieのデータが変更されます。したがって、これは問題ではありません。この例のようにすべてを使いこなしてパイを作ったので、私のコードの問題は何ですか?:( –

関連する問題