最终效果如图
组件结构设计
外部 Rankpage.vue
<template>
<div class="comP1">
<Rank></Rank>
</div>
</template>
<script>
import Rank from "@/components/Rank";
export default {
name: "Rankpage",
components:{Rank}
}
</script>
<style scoped>
</style>
内部 Rank.vue
<!-- 显示地区销量排行的柱形图表 -->
<template>
<div class="comP2" ref="rank_1"></div>
</template>
<script>
export default {
data () {
return {}
},
methods: {}
}
</script>
<style lang="less" scoped>
</style>
初始化图表+数据的获取+更新图表
挂载的生命周期中 注册图表、发送请求获取数据、添加响应页面尺寸的事件
卸载的生命周期中 取消定时器、解绑响应页面尺寸的事件
mounted() {
// 渲染DOM元素之后 初始化图表实例 请求数据 监听页面尺寸变化
this.initChart()
this.getData()
window.addEventListener('resize',this.screenAdapter)
this.screenAdapter()
},
destroyed() {
clearInterval(this.timerID)
window.removeEventListener('resize',this.screenAdapter)
},
初始化图表:绑定鼠标移入移除反应定时器事件
initChart(){
this.chartsInstance = this.$echarts.init(this.$refs.rank_1,this.theme)
const initOption = {
title:{
text:'▎地区销售排行',
left:20,
top:15
},
grid:{
top: '36%',
left: '6%',
right:'6%',
bottom:'4%',
containLabel: true // 距离是包含坐标轴上的文字
},
xAxis:{
type:'category',
},
yAxis:{
type: 'value',
},
tooltip:{
trigger:'axis',
axisPointer:{
type:'line',
z:0,
lineStyle:{
color:'#2d3443'
}
}
},
series:[
{
type:'bar', // 柱状图
label:{
show:true,// 显示柱内数值
position:'top',// 数值显示位置
textStyle: {
color:'#fff'// 数值显示颜色
}
},
},
]
}
this.chartsInstance.setOption(initOption)
// 对图表进行 鼠标移入移出 事件的监听
this.chartsInstance.on('mouseover',()=>{
clearInterval(this.timerID)
})
this.chartsInstance.on('mouseout',()=>{
this.startInterval()
})
},
获取数据 整合配置 渲染图表 默认开启定时器
- 请求过来数据 进行sort 排序 赋值给 allData
- 使用数据更新 图表 先定义三个渐变值、map重新映射出来 每一项的名字和数值 itemStyle每个柱子的颜色动态决定 返回函数 生成一个渐变值
- 设置图表开启定时器 定时器相加的是 startValue endValue 改变 dataZoom 的具体缩放位置来达到流动柱状图的效果
getData(){
const {data:res} = await this.$http.get('rank')
this.allData = res
this.allData.sort((a,b) =>{
return b.value - a.value // 从大到小排序
})
this.updateChart()
this.startInterval()
},
updateChart(){
// 定义不同数值的渐变颜色
const colorArr = [
['#0ba82c','#4ff778'],
['#2e72bf','#23e5e5'],
['#5052ee','#ab6ee5']
]
const rankNames = this.allData.map((item) =>{
return item.name
})
const rankValues = this.allData.map((item) =>{
return item.value
})
const dataOption = {
xAxis:{data:rankNames},
series:[{data:rankValues}],
dataZoom:{
show:false,
startValue: this.startValue,
endValue: this.endValue
},
itemStyle:{
// 设置渐变 x1,y1,x2,y2(指明渐变的方向) [{指明不同百分比下颜色的值}]
color:arg =>{
let targetColorArr = null
if (arg.value > 260){
targetColorArr = colorArr[0]
}else if (arg.value > 180){
targetColorArr = colorArr[1]
}else {
targetColorArr = colorArr[2]
}
return new this.$echarts.graphic.LinearGradient(0,0,0,1,[
{
offset:0,
color:targetColorArr[0]
},
{
offset: 1,
color: targetColorArr[1]
}
])
}
}
}
this.chartsInstance.setOption(dataOption)
},
startInterval(){
if (this.timerID){
clearInterval(this.timerID)
}
this.timerID = setInterval(()=>{
this.startValue++
this.endValue++
if (this.endValue > this.allData.length - 1){
this.startValue = 0
this.endValue = 9
}
this.updateChart()
},2500)
},
每个图表都有的 响应页面尺寸的回调:
screenAdapter(){
const titleFontSize = this.$refs.rank_1.offsetWidth / 100 * 3.6
// 分辨率改变时更新的配置
const adapterOption = {
title:{
textStyle:{
fontSize: titleFontSize
}
},
tooltip:{
axisPointer:{
lineStyle:{
width:titleFontSize,
}
}
},
series:[
{
barWidth:titleFontSize,// 柱状宽度
itemStyle:{
barBorderRadius:[titleFontSize/2,titleFontSize/2,0,0],// 柱状的圆角
}
},
]
}
this.chartsInstance.setOption(adapterOption)
this.chartsInstance.resize()
},