d3.js實現柱形圖
var width = 500, height = 400;
var padding = {
left: 50,
top: 50
};
var dataSet = [22, 26, 9, 20, 40, 60, 90, 20, 60, 40];
var svg = d3.select("body").append("svg").attr("width", width + padding.left * 2).attr("height", height + padding.top * 2);
var xGAxis = svg.append("g").attr('transform', 'translate(' + padding.left + ',' + (height + padding.top) + ')').attr('class', 'axis');
var yGAxis = svg.append("g").attr('transform', 'translate(' + padding.left + ',' + (padding.top) + ')').attr('class', 'axis');
function drawHistogram(dataSet) {
// rangeRoundBands第二個參數是間隔邊距 第三個參數是兩邊的邊距 長度都是為x*間隔長度
// axis.scale(anyScale)時會去判斷是否有rangeBand如果有的會 則會是anyScale(i)+rangeBand()/2
// 于是就會比柱形圖的x坐標多了rangeBand()/2
// 此時柱形圖的寬為rangeBand()的話就剛好在坐標軸的中間了
var xScale = d3.scale.ordinal().domain(d3.range(dataSet.length)).rangeRoundBands([0, width], .2);
// 0-數組最大數映射到 0-Y軸高度
var yScale = d3.scale.linear().domain([0, d3.max(dataSet)]).range([0, height]);
// 柱形處理
yScale.range([0, height]);
var update = svg.attr('class', 'axis')
.selectAll("rect")
.data(dataSet);
var enter = update.enter();
var exit = update.exit();
// enter處理
enter.append("rect")
.attr("x", function (d, i) {
return padding.left + xScale(i);
})
.attr("y", function (d) {
return height + padding.top - yScale(d);
})
.attr("width", xScale.rangeBand()).attr("height", function (d) {
return yScale(d);
});
// exit處理
exit.remove();
// update處理
update.transition().duration(2000).ease("bounce").attr("x", function (d, i) {
return padding.left + xScale(i);
})
.attr("y", function (d) {
return height + padding.top - yScale(d);
})
.attr("width", xScale.rangeBand()).attr("height", function (d) {
return yScale(d);
});
// 文字處理
var textUp = svg.selectAll("text.title")
.data(dataSet);
var textEnter = textUp.enter();
var textExit = textUp.exit();
textEnter.append("text")
.attr('class', 'title')
.attr("x", function (d, i) {
return padding.left + xScale(i);
})
.attr("y", function (d) {
return height + padding.top - yScale(d);
})
// dx dy表示在 x y的基礎上增加
.attr("dx", xScale.rangeBand() / 2)
.attr("dy", "1em")
.attr("fill", "white")
.attr("text-anchor", 'middle').text(function (d) {
return d;
});
textExit.remove();
textUp.transition().duration(2000).ease("bounce").attr("x", function (d, i) {
return padding.left + xScale(i);
})
.attr("y", function (d) {
return height + padding.top - yScale(d);
})
// dx dy表示在 x y的基礎上增加
.attr("dx", xScale.rangeBand() / 2)
.attr("dy", "1em")
.attr("fill", "white")
.attr("text-anchor", 'middle').text(function (d) {
return d;
});
// 反轉Y比例尺
// 因為實際顯示的Y軸應該是從高到低的
// 橫過來看 也就是數組中最大數應該對應到Y軸的最左邊 也就是比例尺的0 所以需要反轉一下
// 反轉后相當于0-數組最大數~長度-0
// 就實現了數組最大數對應x為0的位置
yScale.range([height, 0]);
var xAxis = d3.svg.axis().scale(xScale).tickFormat(d3.format("0.1f")).orient("bottom");
var yAxis = d3.svg.axis().scale(yScale).ticks(10).orient("left");
xGAxis.transition().duration(2000).ease("elastic").call(xAxis);
yGAxis.transition().duration(2000).ease("elastic").call(yAxis);
}
drawHistogram(dataSet);
setInterval(function () {
drawHistogram([Math.floor(Math.random()*100),Math.floor(Math.random()*100),Math.floor(Math.random()*100),Math.floor(Math.random()*100),Math.floor(Math.random()*100),Math.floor(Math.random()*100)]);
}, 2500)
?
?