バックグラウンド
D3.jsで再利用可能なチャートオブジェクトを作成しようとしています。chart()
縦棒グラフを作成する関数を設定しました。いずれかの列のclick
イベントで、グラフはランダムな数のデータポイントを含む新しいランダムデータ配列で更新されます(つまり、元のグラフは8列である可能性がありますが、更新時に20列または4列である可能性があります) 。
問題
元のデータセットに8つのデータポイント(したがって8つの列)があるとします。ランダムなデータでグラフを更新すると、列の高さが新しい値に適切に調整されますが、新しいバーは追加されません。さらに、列の幅はコンテナの幅と新しいデータポイントの数に合わせて適切に調整されますが、そのデータポイントの数が元のセットより少ない場合、元のデータセットの列の一部は次のように残ります。データポイントの数が元のデータ以上です。
私の最終目標は、新しいデータを動的に追加するか、新しいデータ数の範囲外の古いデータを動的に削除することです。
動作のjsfiddleを作成しました。私が説明している動作を確認するには、列を数回クリックする必要がある場合があります。さらに、以下にコードを貼り付けました。
前もって感謝します!
function chart(config) {
// set default options
var defaultOptions = {
selector: '#chartZone',
class: 'chart',
id: null,
data: [1,2,6,4, 2, 6, 7, 2],
type: 'column',
width: 200,
height: 200,
callback: null,
interpolate: 'monotone'
};
// fill in unspecified settings in the config with the defaults
var settings = $.extend(defaultOptions, config);
function my() { // generate chart with this function
var w = settings.width,
h = settings.height,
barPadding = 3,
scale = 10,
max = d3.max(settings.data);
var svg = d3.select(settings.selector) // create the main svg container
.append("svg")
.attr("width",w)
.attr("height",h);
var y = d3.scale.linear().range([h, 0]),
yAxis = d3.svg.axis().scale(y).ticks(5).orient("left"),
x = d3.scale.linear().range([w, 0]);
y.domain([0, max]).nice();
x.domain([0, settings.data.length - 1]).nice();
var rect = svg.selectAll("rect")
.data(settings.data)
.enter()
.append("rect")
.attr("x", function(d,i) {
return i * (w / settings.data.length);
})
.attr("y", function(d) {
return h - h * (d / max);
})
.attr("width", w / settings.data.length - barPadding)
.attr("height", function(d) {
return h * (d / max);
})
.attr("fill", "rgb(90,90,90)");
svg.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(-4,0)")
.call(yAxis);
svg.on("click", function() {
var newData = [], maxCap = Math.round(Math.random() * 100);
for (var i = 0; i < Math.round(Math.random()*100); i++) {
var newNumber = Math.random() * maxCap;
newData.push(Math.round(newNumber));
}
newMax = d3.max(newData);
y.domain([0, newMax]).nice();
var t = svg.transition().duration(750);
t.select(".y.axis").call(yAxis);
rect.data(newData)
.transition().duration(750)
.attr("height", function(d) {
return h * (d / newMax);
})
.attr("x", function(d,i) {
return i * (w / newData.length);
})
.attr("width", w / newData.length - barPadding)
.attr("y", function(d) {
return h - h * (d / newMax);
});
});
}
my();
return my;
}
var myChart = chart();