私の意見では、D3 用の次の JavaScript コードがあります。私はD3が初めてなので、何かが足りないかもしれませんが、まったくわかりません。問題はアラート呼び出しによってマークされます。
線として (コードから取り除かれて) 描画され、これらの線上の円/点として描画される一連のデータ セットをループします。円をクリックすると、onClick ハンドラーでいくつかのコードを実行したいと考えています。onClick ハンドラーは、D3 の on() メソッドに渡されるループ反復ごとに定義されたクローザーです。これまでのところ、ごく普通のJavaScriptのものです。しかし:
最初のアラートには、予想どおり常に正しい値が表示されます。chartDataItem の値を onClick クロージャーにバインドするので、呼び出されたときに同じ値を持つはずです。しかし、onClick が実行されると、常に最後の反復から値を取得します。
D3 の on() メソッドに、私が知らない何か特別なものはありますか?
for(var i=0; i<chartData.length; i++){
var chartDataItem = chartData[i];
var currentData = chartDataItem["data"];
alert(chartDataItem["name"]); // <- displays the correct value per iteration
var onClick = function(d){
alert(chartDataItem["name"]); // <- should bind chartDataItem to the scope of the closure?!
}
var dataLines = lineChart.dataLinesGroup.selectAll('.data-line color' + i)
.data([currentData]);
// Draw the lines
...
// Draw the points
lineChart.dataCirclesGroup = lineChart.svg.append('svg:g');
var circles = lineChart.dataCirclesGroup.selectAll('.data-point color' + i)
.data(currentData);
circles
.enter()
.append('svg:circle')
.attr('class', 'data-point color' + i)
.style('opacity', 1e-6)
... more attr and style calls ...
.on("click", onClick)
.transition()
.duration(0)
.attr('cx', function(d) { return x(d.title) })
.attr('cy', function(d) { return y(d.value) })
.style('opacity', 1);
...
}