d3.js v5 实现横向直方图,并实现显示动画效果
横向直方图效果(没截gif,不过代码可以实现动画):
代码实现:
<html>
<body></body>
<style>
div{
background: #F2F4FF;
width: 100px;
height: 40px;
position: absolute;
opacity: 0;
text-align: center;
font-size: 12px;
line-height: 40px;
}
</style>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
//数据
let data = [{
key: 'aa',
value: 32
},
{
key: 'bb',
value: 26
},
{
key: 'cc',
value: 45
},
{
key: 'dd',
value: 38
},
{
key: 'ee',
value: 52
},
{
key: 'ff',
value: 48
},
{
key: 'gg',
value: 50
},
{
key: 'hh',
value: 34
},
{
key: 'ii',
value: 37
},
{
key: 'jj',
value: 36
},
{
key: 'kk',
value: 40
}
];
let Xdatas = data.map(function(d) {return d.value}),
Ydatas = data.map(function(d) {return d.key});
let width = 800, height = 500;
let x = d3.scaleLinear().domain([d3.min(Xdatas) - 10, d3.max(Xdatas)]).rangeRound([0, width]);
let y = d3.scaleBand().domain(Ydatas).rangeRound([height, 0]);
let padding = {left: 50, top: 20, right: 50, bottom: 50};
let svg = d3.select('body').append('svg').attr('width', width + padding.left).attr('height', height + padding.bottom);
let g = svg.append('g').attr('transform', 'translate(' + padding.left + ',' + padding.top + ')');
// 表头
g.append('text').attr('transform', 'translate(' + (width/2 - padding.left) + ',0)')
.attr('font-weight', 600).text('D3.js 横向直方图');
// x轴和y轴
g.append('g').attr('transform', 'translate(0,' + height + ')')
.call(d3.axisBottom(x));
g.append('g').call(d3.axisLeft(y).ticks(10));
chart = g.selectAll('.bar').data(data).enter().append('g');
// 矩形
chart.append('rect')
.attr('x', function(d) {
return x(x.domain()[0]) + 5;
})
.attr('cursor', 'pointer')
.attr('y', function(d) {
return y(d.key);
})
.attr('fill', function(d) {
// 随机颜色
return '#' + Math.floor(Math.random() * 0xffffff).toString(16);
})
.attr('stroke', '#FFF').attr('stroke-width', '3px')
.transition()
.delay(function(d, i) {
return (i + 1) * 50;
}).duration(2000).ease(d3.easeBounceIn)
.attr('width', function(d) {
return x(d.value);
}).attr('height', y.bandwidth());
// 矩形文字
chart.append('text').attr('fill', '#FFF')
.attr('y', function(d) {
return y(d.key) + 12;
})
.attr('x', function(d) {
return x(x.domain()[0]);
})
.transition().delay(function(d, i) {
return (i + 1) * 100
})
.duration(2000).ease(d3.easeBounceIn)
.attr('dx', function(d) {
return x(d.value) - 30;
}).attr('dy', 15)
.text(function(d) {return d.value});
// 悬浮提示框
tooltip = d3.select('body').append('div');
// hover事件
chart.on('mouseover', function() {
d3.select(this).attr('opacity', 0.5);
// 悬浮在直方图上时,显示提示框
tooltip.html('我是提示框').transition().duration(500).style('left', d3.event.pageX - 20).style('top', d3.event.pageY + 20).style('opacity', 1.0);
}).on('mouseout', function() {
d3.select(this).transition().delay(100).duration(500).attr('opacity', 1.0);
});
// 当鼠标移出svg画布时,就将提示框隐藏掉,考虑到鼠标移出时显示的动画还未完成,需要加transition()过滤
svg.on('mouseout', function() {
tooltip.transition().style('opacity', 0);
});
</script>
</html>
这是横向的直方图,竖向的可以查看 竖向直方图