数据可视化技术是将把比较复杂、抽象的数据通过可视的技术以人们更易理解的形式展示出来,数据可视化技术促进了数据信息的传播和应用。 数据可视化技术是抽象数据的具象表达。
大屏数据可视化是以大屏为主要展示载体的数据可视化。目前市场上大屏设备有1280768的笔记本,也有76804320的8K显示屏,设备分辨率宽泛。“面积大、炫酷动效、丰富色彩、可交互”是大屏数据可视化的特点。大屏数据可视化技术主要应用场景有:信息展示、数据分析和监控预警三类。
本文阐述基于VUE.js、echarts图表和Grid布局的大屏数据可视化技术。
- vue
- echarts
- Grid布局
echarts官网:https://www.echartsjs.com/zh/index.html
- echarts导入VUE项目
import echarts from 'echarts'
Vue.prototype.$echarts = echarts
- echarts 使用性能优化
当window resize时,echart需要重新绘制。若window resize实时对echart重绘,页面会卡顿,页面性能会降低,因此需要考虑dom渲染的性能,加入函数防抖。 下面简单解释一下函数防抖和函数节流。
函数节流throttle通俗解释:假设你正在乘电梯上楼,当电梯门关闭之前发现有人也要乘电梯,礼貌起见,你会按下开门开关,然后等他进电梯; 但是,你是个没耐心的人,你最多只会等待电梯停留一分钟; 在这一分钟内,你会开门让别人进来,但是过了一分钟之后,你就会关门,让电梯上楼。
所以函数节流throttle的作用是,预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新的时间周期。
函数节流throttle应用:在指定时间,事件最多触发一次。
函数防抖debounce通俗解释假设你正在乘电梯上楼,当电梯门关闭之前发现有人也要乘电梯,礼貌起见,你会按下开门开关,然后等他进电梯; 如果在电梯门关闭之前,又有人来了,你会继续开门; 这样一直进行下去,你可能需要等待几分钟,最终没人进电梯了,才会关闭电梯门,然后上楼。
所以函数防抖debounce的作用是,当调用动作触发一段时间后,才会执行该动作,若在这段时间间隔内又调用此动作则将重新计算时间间隔。
函数防抖debounce应用:百度首页的搜索按钮。
函数节流throttle和函数防抖debounce在函数式编程,如lodash库都有实现。
函数防抖debounce的封装:
// 函数防抖
export function debounce(fn, wait, immediate) {
let timer;
return function () {
if (timer) clearTimeout(timer);
if (immediate) {
// 如果已经执行过,不再执行
var callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, wait)
if (callNow) {
fn.apply(this, arguments)
}
} else {
timer = setTimeout(() => {
fn.apply(this, arguments)
}, wait);
}
}
}
Vue项目main.js中引入函数防抖:
import { debounce } from './libs/util'
Vue.prototype.$debounce = debounce
echarts图表组件初始化函数防抖:
mounted() {
// 窗口改变时重新绘制
window.addEventListener("resize", this.$debounce(myChart.resize, 500));
}
- 图例区域太大导致遮挡住图表
在option中设置grid,主要设置top值。
grid: {
left: "3%",
right: "3%",
top: "3%",
containLabel: true
},
- 防止坐标轴标签显示空间不全
在option中设置interval和rotate:
axisLabel: {
// 防止坐标轴标签显示空间不全
rotate: -30
},
// 防止坐标轴标签显示空间不全
interval: 0
首先说明的是grid布局不是bootstrap框架,element ui等UI的栅格布局。目前CSS布局方式有table,浮动,定位,flex和grid布局。
Grid布局说明:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout
Grid和flex布局十分相似,但却有极大的不同。Flex 布局是一维布局,即轴线布局,只能指定"项目"针对轴线的位置。Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,因此是二维布局。 在大屏数据可视化技术需要解决屏幕的响应式布局。常见的响应式布局有媒体查询,flex布局、百分比布局和Grid布局。相比于媒体查询,flex布局和百分比布局,Grid布局在实现大屏数据可视化技术响应式布局更便捷。有一点需要注意的是Grid存在浏览器兼容,请参考:https://caniuse.com/#search=grid,即在IE浏览器不兼容,对于Edge、Fifefox和Chrome主流浏览器兼容性良好。
- Grid布局三行三列布局核心配置示例
/* 网格布局 */
display: grid;
grid-template-columns: 29% 40% 29%;
grid-template-rows: 32.333% 33.333% 32.333%;
/* 行与行的间隔(行间距) */
/* grid-row-gap: 20px; */
/* 列与列的间隔(列间距) */
/* grid-column-gap: 20px; */
/* 行间距和列间距均是1% */
grid-gap: 1% 1%;
- Grid布局中行合并示例配置
html:
<div class='dashboard'>
<div class="item item-1">
<button>操作相关按钮</button>
<line-chart></line-chart>
</div>
<div class="item">
<bar-chart></bar-chart>
</div>
<div class="item">
<pie-chart></pie-chart>
</div>
<div class="item">
<scatter-chart></scatter-chart>
</div>
<div class="item">
<radar-chart></radar-chart>
</div>
<div class="item">
<graph-chart></graph-chart>
</div>
<div class="item">
<gauge-chart></gauge-chart>
</div>
<div class="item">
<dataset-chart></dataset-chart>
</div>
</div>
css:
<style scoped>
.dashboard {
width: 100%;
height: 100%;
/* public文件夹下文件使用绝对路径即可 */
background: #000 url(/bg.jpg) no-repeat center center;
/* 网格布局 */
display: grid;
grid-template-columns: 29% 40% 29%;
grid-template-rows: 32.333% 33.333% 32.333%;
/* 行与行的间隔(行间距) */
/* grid-row-gap: 20px; */
/* 列与列的间隔(列间距) */
/* grid-column-gap: 20px; */
/* 行间距和列间距均是1% */
grid-gap: 1% 1%;
}
.item{
border: 2px solid red
}
.item-1 {
/* 行合并 */
grid-column-start: 1;
grid-column-end: 3;
}
</style>
- Grid布局中列合并示例配置
html:
<div class='dashboard'>
<div class="item item-1">
<button>操作相关按钮</button>
<line-chart></line-chart>
</div>
<div class="item">
<bar-chart></bar-chart>
</div>
<div class="item">
<pie-chart></pie-chart>
</div>
<div class="item">
<scatter-chart></scatter-chart>
</div>
<div class="item">
<radar-chart></radar-chart>
</div>
<div class="item">
<graph-chart></graph-chart>
</div>
<div class="item">
<gauge-chart></gauge-chart>
</div>
<div class="item">
<dataset-chart></dataset-chart>
</div>
</div>
css:
<style scoped>
.dashboard {
width: 100%;
height: 100%;
/* public文件夹下文件使用绝对路径即可 */
background: #000 url(/bg.jpg) no-repeat center center;
/* 网格布局 */
display: grid;
grid-template-columns: 29% 40% 29%;
grid-template-rows: 32.333% 33.333% 32.333%;
/* 行与行的间隔(行间距) */
/* grid-row-gap: 20px; */
/* 列与列的间隔(列间距) */
/* grid-column-gap: 20px; */
/* 行间距和列间距均是1% */
grid-gap: 1% 1%;
}
.item{
border: 2px solid red
}
.item-1 {
/* 行合并 */
grid-row-start: 1;
grid-row-end: 3;
}
</style>
- Grid布局左侧固定,右侧自适应布局示例配置
display: grid;
/* 左侧固定,右侧自适应布局 */
grid-template-columns: 150px 1fr;
/* grid-template-columns: 150px auto; */
- Grid布局repeat属性
将页面水平和垂直方向均分为100分。
.grid {
height: 100%;
display: grid;
grid-template-columns: repeat(100, 1%);
grid-template-rows: repeat(100, 1%);
}
.item {
border: 1px solid red;
}
.item-1 {
/* item-1 dom元素在水平和垂直页面占据左上角的20% */
grid-column-start: 1;
grid-column-end: 21;
grid-row-start: 1;
grid-row-end: 21;
}
grid布局参考grid
<style scoped>
@import '/css/normalize.min.css'
</style>