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)