D3.js的V5版本-Vue框架中使用(第五章) ---让图表动起来

一. api讲解

* .attr(xxx) .transition() .attr(xxx),transition()表示添加过渡,也就是从前一个属性过渡到后一个属性
* .duration(2000),表示过渡时间持续2秒
* .delay(500),表示延迟0.4秒后再进行过渡
* .ease(d3.easeElasticInOut)表示过渡方式,注意这里和v3版本的区别

二. vue使用

< template lang= 'pug' >
div .histogram-pane( :id= "id")
svg
</ template >

< script >
/**
* 含有动画的图表
*/
import * as d3 from 'd3'
export default {
name: '',
data () {
return {
id: ''
}
},
methods: {
uuid () {
function s4 () {
return Math. floor(( 1 + Math. random()) * 0x10000)
. toString( 16)
. substring( 1)
}
return (
s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4()
)
},
},
created () {
this. id = this. uuid()
},
mounted () {
//1.创建svg画布
let marge = { top: 60, bottom: 60, left: 60, right: 60 }
// let width = document.getElementById(this.id).clientWidth
// let height = document.getElementById(this.id).clientHeight
let width = 600
let height = 400
const svg = d3. select( this. $el). select( 'svg'). attr( 'width', width). attr( 'height', height)
let g = svg. append( 'g'). attr( 'transform', 'translate(' + marge. top + ',' + marge. left + ')')
//2.数据集
let dataset = [ 10, 20, 30, 23, 13, 40, 27, 35, 20, 33];
//3.坐标轴
//x轴序数比例尺(d3.scaleBand()并不是一个连续性的比例尺,domain()中使用一个数组,不过range()需要是一个连续域)
let ranges = d3. range( dataset. length)
let xcale = d3. scaleBand(). domain( ranges). range([ 0, width - marge. left - marge. right])
let xAxis = d3. axisBottom( xcale)
g. append( 'g')
. attr( 'transform', 'translate(' + 0 + ',' + ( height - marge. top - marge. bottom) + ')')
. call( xAxis)
//y轴线性比例尺
let yscale = d3. scaleLinear(). domain([ 0, d3. max( dataset)]). range([ height - marge. top - marge. bottom, 0])
let yAxis = d3. axisLeft( yscale)
g. append( 'g')
. attr( 'transform', 'translate(0, 0)')
. call( yAxis)
//4.为每个矩形和对应的文字创建一个分组<g>
let gs = g. selectAll( 'rect')
. data( dataset)
. enter()
. append( 'g')
//5.绘制矩形
//设置矩形之间的间隙
let rectPadding = 20
gs. append( 'rect')
. attr( 'x', function( d, i) {
//xcale(i): 画布真实宽度(48)横坐标且从0开始, 0, 48, 96 ... 432
return xcale( i) + rectPadding/ 2
})
. attr( 'width', function() {
//xcale.step() 画布真实宽度(48):width-marge.left-marge.right/dataset.lenght
return xcale. step() - rectPadding
})
. attr( 'y', function( d){
let min = yscale. domain()[ 0] //0 ; yscale(0) --- 280
return yscale( min) //返回的是最大值
})
. attr( 'height', function( d){
//默认开始高度为0
return 0
})
. attr( 'fill', 'blue')
. transition()
. duration( 1000)
. delay( function( d, i){
return i * 200
})
// .ease(d3.easeElasticInOut)
. attr( 'y', function( d){
return yscale( d)
})
. attr( 'height', function( d){
return height - marge. top - marge. bottom - yscale( d)
})
//6.绘制文字
gs. append( 'text')
. attr( 'x', function( d, i) {
return xcale( i) + rectPadding/ 2
})
. attr( 'width', function() {
return xcale. step() - rectPadding
})
. attr( 'y', function( d) {
// return yscale(d)
let min = yscale. domain()[ 0] //0 ; yscale(0) --- 280
return yscale( min) //返回的是最大值, 即在最底部
})
. attr( 'dy', rectPadding)
. text( function( d) {
return d
})
. transition()
        . duration( 1000)
        . delay( function( d, i){
             return i * 200;
        })
         //.ease(d3.easeElasticInOut)
    . attr( "y", function( d){
             return yscale( d);
        });
}
}
</ script >

< style lang= "scss" scoped >
.histogram-pane {
width: 100%;
height: 1000px;
}
</ style >


猜你喜欢

转载自blog.csdn.net/davidpan1234/article/details/80714010