在数据可视化项目的初期, 我们会每个图表单独的进行开发, 最后再将所有的图表合并到一个界面中.
本项目中使用的ehcarts图表官网
最终的效果如下图所示:
售票员业绩排行
-组件代码
<!--售票员销量统计的横向柱状图-->
<template>
<div class="com-container">
<div class="com-chart" ref="seller_ref"></div>
</div>
</template>
<script>
export default {
name: "Seller",
data(){
return{
chartInstance:null,
allData:null,//服务器返回的数据
currentPage:1,//当前显示的页数
totalPage:0,//总页数
timerId:null,//定时器标识
}
},
mounted(){
this.initChart();
this.getData();
window.addEventListener('resize',this.screenAdapter);
//在页面加载完成忠厚,主动进行屏幕的适配
this.screenAdapter();
},
destroy(){
//停止定时器
clearInterval(this.timerId);
//在组件销毁的时候,将窗口监听器取消掉
window.removeEventListener('resize',this.screenAdapter);
},
methods:{
//初始化echartInstance对象
initChart(){
this.chartInstance=this.echarts.init(this.$refs.seller_ref,'chalk');
//对图表初始化配置的控制
const initOption={
//标题
title:{
text:'┃ 售票员业绩排行',
top:20,
left:20
},
//坐标轴
grid:{
top:'20%',
left:'3%',
right:'6%',
bottom:'3%',
containLabel:true //设置距离包括图表上的文字
},
xAxis:{
type:'value'
},
yAxis:{
type:'category',
},
//提示工具
tooltip:{
trigger:'axis',
axisPointer:{
type:'line',
z:0,
lineStyle:{
color:'#2D3443'
}
}
},
//条目
series:[
{
type:'bar',
//条目上的文字
label:{
show:true,
position:'right',
textStyle:{
color:'white'
}
},
//每一个柱子样式
itemStyle:{
//指明颜色渐变的方向
//指明不同百分比之下颜色的值
//echart中的颜色渐变对象----参数(指明颜色渐变的方向,指明不同百分比之下颜色的值)
color:new this.echarts.graphic.LinearGradient(0,0,1,0,[
//百分之0状态下的颜色值
{
offset:0,
color:'#5052EE'
},
//状态100%下的颜色值
{
offset:1,
color:'#AB6EE5'
}
]),
}
}
]
};
this.chartInstance.setOption(initOption);
//对图表对象进行鼠标事件的监听
this.chartInstance.on('mouseover',()=>{
//鼠标移入,轮播定时器停止
clearInterval(this.timerId);
});
this.chartInstance.on('mouseout',()=>{
//鼠标移入,轮播定时器开启
this.startInterval();
});
},
//获取服务器数据
async getData(){
await this.axios.get("/order/querySellerOrder").then(res=>{
this.allData=res.data;
});
//对数组进行排序
this.allData.sort((a,b)=>{
return a.value-b.value;//从小到大的顺序排序
});
//计算总页数(3个一页)
this.totalPage=this.totalPage.length % 3 === 0 ? this.allData.length/3 : this.allData.length/3 +1;
this.updateChart();
//启动定时器
this.startInterval()
},
//更新图表
updateChart(){
const start=(this.currentPage-1)*3;
const end=(this.currentPage*3);
const showData=this.allData.slice(start,end);
const sellerNames=showData.map((item)=>{
return item.name
});
const sellerValues=showData.map((item)=>{
return item.value
});
const dataOption={
yAxis:{
data:sellerNames
},
//条目
series:[
{
data:sellerValues,
}
]
};
this.chartInstance.setOption(dataOption);
},
startInterval(){//定时换页更新图表数据
if (this.timerId) {
clearInterval(this.timerId);
}
this.timerId=setInterval(()=>{
this.currentPage++;
if (this.currentPage > this.totalPage) {
this.currentPage=1;
}
this.updateChart();
},3000)
},
//当浏览器的大小发生变化的时候,调用该方法,来完成屏幕的适配
screenAdapter(){
//console.log(this.$refs.seller_ref.offsetWidth);
const titleFontSize=this.$refs.seller_ref.offsetWidth/100 * 3.6;
//和分辨率大小相关的配置项
const adapterOption={
//标题
title:{
textStyle:{
fontSize:titleFontSize
},
},
//提示工具
tooltip:{
axisPointer:{
lineStyle:{
width:titleFontSize,
}
}
},
//条目
series:[
{
barWidth:titleFontSize,
//每一个柱子样式
itemStyle:{
barBorderRadius:[0,titleFontSize/2,titleFontSize/2,0],
}
}
]
};
this.chartInstance.setOption(adapterOption);
//手动的调用图表的resize方法
this.chartInstance.resize();
}
}
}
</script>
<style scoped>
.com-container{
width: 100%;
height: 100%;
overflow: hidden;
}
.com-chart{
width: 100%;
height: 100%;
overflow: hidden;
border-radius: 20px;
}
</style>
售票员业绩排行
-接口获取的图表数据
JSON数据
[{"name":"刘总","value":"1105"},{"name":"刘师傅","value":"6"},{"name":"小丁","value":"4"},{"name":"小陈","value":"5"}]
截图
售票员业绩排行
-设计流程
最终的效果如下图所示:
1.组件结构设计
- 在
src/components/
目录下建立Seller.vue
, 这个组件是真实展示图表的组件- 给外层div增加类样式
com-container
- 建立一个显示图表的div元素
- 给新增的这个div增加类样式
com-chart
- 给外层div增加类样式
<!-- 显示商家销量统计的图表 -->
<template>
<div class="com-containter">
Seller组件
<div class="com-chart"></div>
</div>
</template>
<script>
export default {
data(){
return {}
},
methods:{}
}
</script>
<style lang="less" scoped>
</style>
- 在
src/views/
目录下建立SellerPage.vue
,这个组件是对应于路由 /seller 而展示的- 给外层div元素增加样式
com-page
- 在
SellerPage
中引入Seller
组件,并且注册和使用
- 给外层div元素增加样式
<!--
针对于 /sellerpage 这条路径显示出来的
在这个组件中,通过子组件注册的方式,要显示除Seller.vue这个组件
-->
<template>
<div class="com-page">
<Seller></Seller>
</div>
</template>
<script>
import Seller from "../components/Seller";
export default {
name: "SellerPage",
components: {Seller},
}
</script>
<style lang='less' scoped>
</style>
- 增加路由规则,在
src/router/index.js
文件中修改
......
import SellerPage from "../views/SellerPage";
......
cost routes=[
{
path: '/sellerpage',
name: 'SellerPage',
component:SellerPage
},
]
- 新建
src/assets/css/global.less
增加宽高的样式
原则就是将所有的容器的宽度和高度设置为占满父容器
html,
body,
#app {
width:100%;
heigth:100%;
padding:0;
overflow:hidden;
}
.com-page {
width:100%;
heigth:100%;
overflow:hidden;
}
.com-container{
width:100%;
heigth:100%;
overflow:hidden;
}
.com-chart{
width:100%;
heigth:100%;
overflow:hidden;
}
在main.js
中引入样式
import './assets/css/global.less'
- 打开浏览器,输入
http://127.0.0.1:8080/sellerpage
看Seller组件是否能够显示
2.图表Seller.vue
基本功能的实现
- 1.在mounted生命周期中初始化
echartsInstance
对象 - 2.在mounted中获取服务器的数据
- 3.将获取到的数据设置到图表上
<script>
export default{
data(){
return {
charInstance:null,//echarts实例对象
allData:[]//服务器获取的所有数据
}
},
mounted (){
//由于初始化echarts实例对象需要使用到dom元素,因此必需要放到mounted中,而不是created
this.initChart();
this.getData();
},
methods:{
initChart(){
this.charInstance=this.echarts.init(this.$refs.seller_ref)//初始化echarts对象
},
async getData(){
await this.axios.get("/order/querySellerOrder").then(res=>{
this.allData=res.data;
});
//对数组进行排序
this.allData.sort((a,b)=>{
return a.value-b.value;//从小到大的顺序排序
});
this.updateChart()
},
updateChart(){
//处理数据并更新界面图表
const sellerNames=this.allData.map((item)=>{
return item.name
})
const sellervalues=this.allData.map((item)=>{
return item.value
})
const option={
xAxis:{
type:'value'
},
yAxis:{
type:'category',
data:sellerName
},
series:[
{
type:'bar',
data:sellervalues
}
]
}
this.charInstance.setOption(option)
}
}
}
</script>
- 4.拆分配置项
option
-
初始化配置项
-
拥有数据之后的配置项
-
3.分页动画的实现
-
数据的处理,每5个元素显示一页
-
数据的处理
-
动画的的启动和停止
-
鼠标事件的处理
-
-
细节的处理
- 固定x轴最大值
const option={
xAxis:{
type:'value',
max:this.allData[this.allData.length-1].value
}
}
4.ui
效果调整
-
主题文件的导入
main,js
中引入 -
主题的指定,在初始化
echarts实例对象
的时候指定src/components/Seller.vue
-
边框圆角的设置
src/assets/css/global.less
canvas{ border-radius:20px; }
-
其他图表样式的配置
-
标题的位置和颜色
const initOption={ //标题 title:{ text:'┃ 售票员业绩排行', top:20, left:20, textStyle:{ textStyle:{ "color":"#fff" } } }, }
-
坐标轴的大小
const initOption={ //坐标轴 grid:{ top:'20%', left:'3%', right:'6%', bottom:'3%', containLabel:true //设置距离包括图表上的文字 }, }
-
工具提示和背景
const initOption={ //提示工具 tooltip:{ trigger:'axis', axisPointer:{ type:'line', z:0, lineStyle:{ color:'#2D3443' } } }, }
-
文字提示和位置
const initOption={ //提示工具 series:[ { ...... label:{ show:true, position:'right', textStyle:{ color:'#fff' } } } ], }
-
柱宽度和柱圆角的实现
const initOption={ series:[ { ...... barwidth:66, itemStyle:{ barBorderRadius:[0,33,33,0] } } ], }
-
柱颜色渐变的实现
线性渐变可以通过
LinearGradient
进行实现LinearGradient
需要传递5个参数,前四个代表两点的相对位置。第五个参数代表颜色变化的范围0,0,1,0
代表的是从左往右的方向const initOption={ series:[ { ...... itemStyle:{ //指明颜色渐变的方向 //指明不同百分比之下颜色的值 //echart中的颜色渐变对象----参数(指明颜色渐变的方向,指明不同百分比之下颜色的值) color:new this.echarts.graphic.LinearGradient(0,0,1,0,[ //百分之0状态下的颜色值 { offset:0, color:'#5052EE' }, //状态100%下的颜色值 { offset:1, color:'#AB6EE5' } ]), } } ], }
-
5.分辨率适配
-
对窗口大小变化的事件进行监听
mounted
时候监听mounted(){ this.initChart(); this.getData(); window.addEventListener('resize',this.screenAdapter); },
组件销毁时取消监听
destroy(){ //停止定时器 clearInterval(this.timerId); //在组件销毁的时候,将窗口监听器取消掉 window.removeEventListener('resize',this.screenAdapter); },
-
获取图表容器的宽度计算字体的大小
screenAdapter(){ const titleFontSize=this.$refs.seller_ref.offsetWidth/100 * 3.6;
-
将字体大小的值设置给图表的某些区域
-
标题大小
-
背景大小
-
柱宽度
-
圆角大小
//当浏览器的大小发生变化的时候,调用该方法,来完成屏幕的适配 screenAdapter(){ //console.log(this.$refs.seller_ref.offsetWidth); const titleFontSize=this.$refs.seller_ref.offsetWidth/100 * 3.6; //和分辨率大小相关的配置项 const adapterOption={ //标题 title:{ textStyle:{ fontSize:titleFontSize }, }, //提示工具 tooltip:{ axisPointer:{ lineStyle:{ width:titleFontSize, } } }, //条目 series:[ { barWidth:titleFontSize, //每一个柱子样式 itemStyle:{ barBorderRadius:[0,titleFontSize/2,titleFontSize/2,0], } } ] }; this.chartInstance.setOption(adapterOption); //手动的调用图表的resize方法 this.chartInstance.resize(); }
-
下一篇:数据可视化项目—客源分析趋势图