1 开发背景

如今信息化高速发展,各式各样的数据层出不穷,如何能够掌握相应的数据并将数据整合,再通过可视化的方式呈现到客户的眼前,如何能过一眼望去就对整个公司的运行和及时发现可能存在的隐患,数据可视化是一个不可忽视的部分。利用好数据可视化,辅佐公司高层更好的进行决策和预警。

2 技术构成

总览:

VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

构成:

web 标准简单来说可以分为结构、表现和行为

  • 结构方面使用html5 标签尽量采用语义化的标签,少用div这种无语义的标签

  • 表现方面使用less,less比css更有逻辑性,是css的预处理器,扩充了css

  • 行为方面使用vue3.2,vue3.2的语法糖使代码更加简便可读,可以省略很多步骤,但是vue3.2的reactive解构会失去响应式,使用ref又要加.value,有点繁琐

  • 可视化数据图表方面使用vue-echarts,vue-echarts能够使用更少的代码去完成图表

  • 数据传输方面使用axios,axios比ajax更适合现在前端的MVVM的浪潮

  • 装饰和边框方面,使用DataV,DataV里面有很多炫酷的边框、装饰和功能,随拿随用,但是存在很多兼容性问题

  • 布局方面,采用总体采用flex布局和rem实现,将不同部分划分为不同的组件.vue,例如按图表划分成不同组件,便于后期维护,也便于复用。另外,整体设计为响应式,确保在PC端不同 的分辨率下保证可读性

3 整体项目

3.1 预览

VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)
VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

main.js:

import { createApp } from 'vue'
import App from './App.vue'
import axios from 'axios'
import * as echarts from 'echarts'
import ECharts from 'vue-echarts'
import 'lib-flexible/flexible.js'
import dataV from '@jiaminghi/data-view'
const app = createApp(App)
app.config.globalProperties.$http = axios
app.config.globalProperties.echarts = echarts
app.use(dataV)
app.component('v-chart', ECharts)
app.mount('#app')

项目预览地址:http://47.106.144.95/

3.2 分析

VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

大概分为header、centre、footer部分,分别对应上面文件结构图的header、centre、footer文件夹

  • header部分主要是标题,导航(未完成)。

  • centre部分又分为三个大块,左 中 右,左右部分又可以划分为四个组件,这四个组件可以随时替换,中间部分分为:雷达车间AVG运行动图 和 带数字翻牌器的数据统计

  • footer部分主要是横幅走马灯,播报信息或者欢迎词

4 代码部分

4.1 header部分

<script setup>
import { onMounted, ref } from "vue";
function getTime() {
return new Date().toLocaleString();
}
var datetime = ref(new Date().toLocaleString())
onMounted(() => {
datetime.value = getTime();
setInterval(() => {
datetime.value = getTime();
}, 1000)
})
</script>

其中:

  • 获取当前时间,并每秒计时,利用响应式实现时间流动

4.2 centre部分

4.2.1左右部分划分的四个组件,采用插槽的方式,最大程度复用宽高样式

app.vue中

VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

使用ItemPage.vue保证插入图表宽高复用

ItemPage.vue

VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

4.2.2 图表组件

水波图:

template中
VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

其中:

  • dv-border-box-11 是DataV的边框组件

  • v-chart是vue-echart中的标签,其中的属性option和echarts用法一样,使用vue的reactive将option响应式之后将option绑定到v-chart中(可能会有响应式失效的问题);autoresize是图表根据父元素宽高进行响应式更新;

script中
VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

其中:

  • echarts-liquidfill是echarts的水波图,将series中的type设置为liquidFill即可

  • 将option使用reactive响应式赋值

多折线图:

template中:
VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)
script中:
VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

其中:

  • 多折线图的日期为最近的七日,用计算属性稍微加工一下即可

问题:

  • 堆叠折线图复制官网数据代码,y轴数据错乱

解决办法:

  • series每一组数据的stack: “Total”去掉或者设置成不同的值

象形柱图(已完成但是未展示出来的组件)(特殊的象形柱图):

展示:
VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)
template都一样,以下不展示
script中:
<script setup>
import { reactive } from "vue"
const maxData = 2000;
const IMG = "image://" + require('@/assets/img/people.png')//背景图
const option = reactive({
tooltip: {},
xAxis: {
max: maxData,
splitLine: { show: false },
offset: 10,
axisLine: {
lineStyle: {
color: '#999'
}
},
// axisLabel: {
//   margin: 10
// }
},
yAxis: {
data: ['A1车间', 'B1车间', 'Waterpik', '皓醒湾车间', '苏打水车间'],
inverse: true,
axisTick: { show: false },
axisLine: { show: false },
axisLabel: {
// margin: 10,
color: '#fff',
fontSize: 16
}
},
grid: {
top: 'center',
height: 250,
left: 100,
right: 60
},
series: [
{
type: 'pictorialBar',
symbol: IMG,
symbolRepeat: 'fixed',
symbolMargin: '5%',
symbolClip: true,
symbolSize: 30,
symbolBoundingData: maxData,
data: [891, 1220, 660, 1670, 500],
markLine: {
symbol: 'none',
label: {
formatter: 'max: {c}',
position: 'start'
},
lineStyle: {
color: 'green',
type: 'dotted',
opacity: 0.2,
width: 2
},
},
z: 10
},
{
type: 'pictorialBar',
itemStyle: {
opacity: 0.2
},
Size: 18,
animationDuration: 0,
symbolRepeat: 'fixed',
symbolMargin: '5%',
symbol: IMG,
// symbol: 'diamond',
symbolSize: 30,
symbolBoundingData: maxData,
data: [891, 1220, 660, 1670, 200],
z: 5
}
]
})
</script>

动态轮播表:

template中:
VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

其中:

  • dv-scroll-board 为DataV的轮播表组件,config为script中配置的轮播表配置

问题:

  • dv-scroll-board配置config中加入表头时出现问题,表中数据会塌陷,宽度为0不显示

解决办法:

  • 自制表头

script中:
VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

具体配置信息可以参考dataV官网

数字翻牌器:

父组件(规定样式,获取初始值,实时获取改变后的值,将值传给子)

template中:

VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

其中:

  • 将num父传子,使用props传值,使用v-model使其响应式

  • title变化不大,因此没有赋值响应式

script中:

VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

其中:

  • 初始值是死数据,后期可以转变为axios获取,再用ref赋值

  • 在onMounted中挂载一个定时器,模拟数据更新

  • 在onUnmounted中卸载定时器,避免不必要的浪费

  • 由于vue3.2中没有this获取全局变量,使用getCurrentInstance()获取currentInstance,再通过.appContext.config.globalProperties获取全局属性

子组件

template中

VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

其中:

  • 通过props.title获取父传值

  • dv-digital-flop是dataV中的数字翻牌器功能,将配置好的config配置进config即可

script中:

VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

其中:

  • 使用defineProps接收父传过来的值,并用type规定类型,设置默认值

  • 将num配置到config中

  • 用watch监听num,实现当props.num改变,动态改变config的值

问题:

  • 当num改变时,config改变,但是页面没有变化,响应式失效

解决办法:

  • 使用watch解构赋值

雷达图+动态小车地图

template中:
VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

其中:

  • dv-decoration-12为dataV的雷达图,在此用作背景

script中:
<script setup>
import { getCurrentInstance, ref } from 'vue';
import * as echarts from 'echarts'
import svgtest from '@/assets/img/3.svg'
const currentInstance = getCurrentInstance()
const { $http } = currentInstance.appContext.config.globalProperties
var option = ref({
})
$http.get(svgtest).then(res => {
echarts.registerMap('zhusuchejian', {
svg: res.data
})
option.value = ({
tooltip: {},
geo: {
map: 'zhusuchejian',
layoutSize: '150%',
zoom: 1.2,
},
series: [
{
name: 'Route',
type: 'lines',
coordinateSystem: 'geo',
geoIndex: 0,
emphasis: {
label: {
show: false
}
},
polyline: true,
lineStyle: {
color: '#c46e54',
width: 0
},
effect: {
show: true,
period: 8,
trailLength: 0,
symbolSize: [12, 30],
symbol:
'path://M87.1667 3.8333L80.5.5h-60l-6.6667 3.3333L.5 70.5v130l10 10h80l10 -10v-130zM15.5 190.5l15 -20h40l15 20zm75 -65l-15 5v35l15 15zm-80 0l15 5v35l-15 15zm65 0l15 -5v-40l-15 20zm-50 0l-15 -5v-40l15 20zm 65,-55 -15,25 c -15,-5 -35,-5 -50,0 l -15,-25 c 25,-15 55,-15 80,0 z'
},
z: 100,
data: [
{
effect: {
color: '#a10000',
constantSpeed: 100,
delay: 0
},
coords: [
[30, 200],
[790, 200],
[790, 50],
[460, 50],
]
},
{
effect: {
color: '#00067d',
constantSpeed: 80,
delay: 0
},
coords: [
[30, 430],
[790, 430],
[790, 50],
[460, 50],
]
},
{
effect: {
color: '#997405',
constantSpeed: 60,
delay: 0
},
coords: [
[30, 485],
[790, 485],
[790, 50],
[460, 50],
]
},
{
effect: {
color: '#997405',
constantSpeed: 60,
delay: 0
},
coords: [
[30, 710],
[790, 710],
[790, 50],
[460, 50],
]
},
{
effect: {
color: '#997405',
constantSpeed: 60,
delay: 0
},
coords: [
[30, 770],
[790, 770],
[790, 50],
[460, 50],
]
},
{
effect: {
color: '#997405',
constantSpeed: 60,
delay: 0
},
coords: [
[30, 990],
[790, 990],
[790, 50],
[460, 50],
]
}
]
}
]
});
})
</script>

其中:

  • $http为将axios全局配置的别名

  • registerMap中放做好的svg图

  • 雷达图设置图层靠后实现背景

问题:

  • svg不能直接导入使用

解决办法:

  • 导入后使用axios获取

还有一些组件没有放上来,但是代码和上面的差不多

柱状图
VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)
饼状图
VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

等等就不在赘述。

4.3 footer部分

template中:

VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

其中:

  • 使用ref标记横幅走马灯的部分

script中:

VUE3.2 + vue-echarts + DataV 数据可视化大屏(项目)

其中:

  • vue3.2中没有this.$ref直接在script中用ref响应式赋值一个同名的slogan即可找到标记ref的template

问题:

  • 直接调用方法sloganMove无效,因为vue3.2中setup中为oncreate的生命周期内,此时html还未渲染完成,找不到相应的slogan的属性

解决办法:

  • 将sloganMove放入onMounted中,挂在完成后操作

5 结语

代码十分粗糙简陋所以暂未发布到github,等后期技术积累起来完善功能后再发布。

写博客不易,有兴趣的话点个赞。

作为一个前端小白,第一次独立完成vue+echarts项目,内容还很粗糙,技术也很浅薄,有很多问题和不理解的地方,如有不对的地方,欢迎指正。

欢迎评论 💬点赞👍🏻 收藏 📂加关注+

发表回复