echarts、dataV 数据可视化大屏
一、项目描述 (包含echarts中国地图、dataV科技炫酷边框等等)
一个基于 Vue、Datav、Echart 框架的 " 数据大屏项目 ",通过 Vue 组件实现数据动态刷新渲染,内部图表可实现自由替换。部分图表使用 DataV 自带组件, 组件库基于Vue (React版) ,主要用于构建大屏(全屏)数据展示页面即数据可视化,具有多种类型组件可供使用。
项目环境:Vue-cli、DataV、Echarts、node
友情链接:
- Vue 官 方文档
- Vue CLI
- DataV 官方文档
- echarts 实例,echarts API 文档
项目展示
二、主要文件介绍
文件 | 作用/功能 |
---|---|
main.js | 主目录文件,引入 Echart/DataV 等文件 |
utils | 工具函数与 mixins 函数等 |
components/ HomeWord.vue | 项目主结构 |
assets | 静态资源目录,放置 logo 与背景图片 |
三、项目注意点
引用的模块(先下载 install)
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import * as echarts from 'echarts' //echarts 引用使用断言,否则可能报错
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import dataV from '@jiaminghi/data-view'
Vue.use(ElementUI); //部分图标使用 element-ui
Vue.use(dataV) //全局启用 dataVVue.prototype.$echarts=echarts //将echarts挂载到Vue原型上,全局可使用this.$echarts 调用
Vue.config.productionTip = false
new Vue({router,store,render: h => h(App)
}).$mount('#app')
封装组件渲染图表
所有的 ECharts 图表已经对数据和屏幕改动进行了监听,能够动态渲染图表数据。在监听窗口小大的模块。
中间部分中国地图json数据来源 (地址)
我这边直接复制内容存到本地 (把复制的链接在网页打开Ctrl+A Ctrl+C 全选复制粘贴): assets > json > china.json
渲染地图的子组件
有几个注意点:
- 需要地图json文件
- 需要监听数据变化
- tooltip: formatter 鼠标移入的提示信息框
<template><divid="map":style="{width: '700px',height: '730px',marginTop: '10px',}"></div>
</template><script>
import china from "../assets/json/china.json"; //引入地图json文件
export default {mounted() {this.initChart();},props: {mapData: { //接收父组件传过来的值type: Object,default: () => ({}),},},data() {return {options: {},chart: null,};methods: {// 地图initChart() {this.$echarts.registerMap("china", china); //echarts的map需要注册,根据引入的json文件名,并定义map的名称this.chart = this.$echarts.init(document.getElementById("map"), null, {renderer: "svg",}); //init()挂载在某个元素,所以还需要在mounted调用, { renderer: "svg" } 将原来的canvas绘图改为svg 清晰度更高this.drawMap();},drawMap() {this.chart.setOption({title: {text: "平台运营实时数据",textStyle: {color: "#fff",fontSize: 28,},},tooltip: { //鼠标移入的提示信息框show: true,trigger: "item",formatter: function (a, b) {// 将人数改千分位let a2 = "";let olda = Number(a["data"].value);if (olda >= 0) {a2 = olda;if (olda > 999) {let parts = olda.toString().split(".");parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");a2 = parts.join(".");}}// 日活兼容let a3 = a["data"].ratio ? a["data"].ratio : 0;let a1 = a["name"];if (a1 == "台湾省" && !a2) { // 台湾省显示暂无数据return `${a1}<br/> 暂无数据`;}return `${a1}<br/>累计注册: ${a2} <br/>日活: ${a3} %`;},},series: [{type: "map", map: "china", //对应registerMap() 对应的名称top: "150", //调整地图在页面的位置zoom: 1.3, //缩放比例emphasis: {label: { show: false },itemStyle: {areaColor: "rgba(136, 132, 216)",},},itemStyle: {borderColor: "#fff",},data: this.mapData.mapArr, //有数据才显示颜色},],visualMap: {show: true,type: "continuous",calculable: true,orient: "horizontal", textStyle: {color: "#fff",},min: 0,max: 10000000,text: ["累计注册/人", ""],color: ["#df3d20", "#fff"],inRange: {// color: [ "#fff","#44effb", "#3399ff","#2b8afe", "#006699"],color: ["#44effb", "#3399ff", "#2b8afe", "#006699"], //地图颜色},},},true);},},watch: {// handler 监听数据发生变化需要具体执行的方法// deep 需要监听的数据的深度,一般用来监听对象中某个属性的变化mapData: {handler() {this.drawMap();},deep: true, },},
};
</script><style></style>
复用图表组件(可以研究下)
更换边框 (炫酷的科技感动态边框)
边框是使用了 DataV 自带的组件,只需要去 views 目录下去寻找对应的位置去查找并替换就可以,具体的种类请去 DavaV 官网查看
如:
<dv-border-box-1> 内容撑开 </dv-border-box-1>
<dv-border-box-2> 内容撑开 </dv-border-box-2>
<dv-border-box-3> 内容撑开 </dv-border-box-3>
Mixins 解决自适应适配功能
使用 mixins 注入解决了界面大小变动图表自适应适配的功能,函数在 utils/resizeMixins.js
中,应用在 common/echart/index.vue
的封装渲染组件,主要是对 this.chart
进行了功能注入。
屏幕适配
使用更流程通用的 css3:scale
缩放方案,通过 ref
指向 主页面的元素,基准尺寸是 1980px*1080px
,所以支持同比例屏幕 100% 填充,如果非同比例则会自动计算比例居中填充,不足的部分则留白。实现代码在 `src/utils/drawMixin ,如果有其它的适配方案,欢迎交流。
src > utils > drawMixin.js
// 屏幕适配 mixin 函数
//需要先设置index.html meta 标签 user-scalable=no
//<meta name="viewport" content="width=device-width,initial-scale=1.0 ,user-scalable=no">
//并且需要绑定ref // * 默认缩放值
const scale = {width: '1',height: '1',}// * 设计稿尺寸(px)// 1920×1080const baseWidth =1920const baseHeight = 1080// * 需保持的比例(默认1.77778)const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))export default {data() {return {// * 定时函数drawTiming: null}},mounted () {this.calcRate()window.addEventListener('resize', this.resize)},beforeDestroy () {window.removeEventListener('resize', this.resize)},methods: {calcRate () {const appRef = this.$refs["appRef"]if (!appRef) return // 当前宽高比const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5))if (appRef) {if (currentRate > baseProportion) {// 表示更宽scale.width = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5)scale.height = (window.innerHeight / baseHeight).toFixed(5)appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`} else {// 表示更高scale.height = ((window.innerWidth / baseProportion) / baseHeight).toFixed(5)scale.width = (window.innerWidth / baseWidth).toFixed(5)appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`}}},resize () {clearTimeout(this.drawTiming)this.drawTiming = setTimeout(() => {this.calcRate()}, 200)}},}
homeword.vue
<template><div id="index" ref="appRef">...页面内容...</div>
</template><script>
import drawMixin from "../utils/drawMixin";
export default {components: {//.....},mixins: [drawMixin], //混入 (保持页面缩放比例)} </script>
请求数据
使用 axios
进行数据请求,在 main.js
位置进行全局配置。
src > request
文件统一处理所有的请求
src > request > request.js
请求和响应拦截
// 封装axios实例的拦截器(请求, 响应)
import axios from 'axios';// 1. 创建axios实例
const instance = axios.create({timeout: 15000, // 超时时间15sbaseURL: '这里是你请求是ip地址', // ip+端口, 公用的前缀路径
});// 重写实例请求前拦截器
instance.interceptors.request.use((config) => {return config;
}, (err) => {return Promise.reject(err);
})// 重写实例响应后拦截器
instance.interceptors.response.use((result) => {return result.data;
}, (err) => {return Promise.reject(err);
})// 导出axios实例
export default instance;
src > request > request.js
请求拼接地址
import request from './request';// 主要指标 /mcpbd-data/data/mainIndex
export const getMainIndex= () => request.get('/mainIndex') //这里是get请求,"/mainIndex" 是接口文档的请求拼接字段//......
在homeword.vue
引入,并发送请求数据
由于一个页面要发送多个请求,并且成功获取数据再渲染,我使用了promise.all
并发请求,但是发现请求很慢(不知道有什么方法可以优化)
<template>...
</template><script>
import drawMixin from "../utils/drawMixin";//接口
import { getMainIndex,
} from "../request/httpApi";export default {components: {//...},mixins: [drawMixin],name: "HelloWorld",props: {},data() {return {//渲染子组件,还未请求到数据的时候,需要放数据的所有元素不显示falg: false,loading: true,loadTimer: null,resd: [],realVal: 0,MainIndicators: {// 主要指标 默认数据userAllCnt: "",userNewCnt: "",userDailyActvCnt: "",userDailyActvRatio: "",userMonthlyActvCnt: "",userMonthlyActvRatio: "",mctAllCnt: "",},//累计注册用户数折线//....mapData: {//地图数据mapArr: [],},};},mounted() {this.cancelLoading();},filters: {//过滤数据numFilter(val) {return (parseFloat(val) * 100).toFixed(1);},},created() {this.getJ();this.getShishi();// 实时更新数据(隔一个小时请求数据)setInterval(() => {this.getJ();}, 3600000);//左下角数据实时更新(1分钟)setInterval(() => {this.getShishi();}, 60000);},methods: {getShishi() {//左下角数据 (因为这部分数据需要每分钟更新一次所以单独拎出来)getRealTimeIndex() //发送请求.then((res) => {this.RealTimeIndex.newUserAllUserCnt = [];this.RealTimeIndex.newUserAllUserDate = [];this.resd = res;this.resd.forEach((item) => {this.RealTimeIndex.newUserAllUserCnt.push(Number(item.userAllCnt).toFixed()),this.RealTimeIndex.newUserAllUserDate.push(item.calTime.substring(11));});}).catch((err) => {return;});},sortData(attr) {return function (a, b) {return b[attr] - a[attr];};},getJ() {// 累计注册用户let p1 = new Promise((resolve, reject) => {getUserAllCnt().then((res) => {resolve(res);}).catch((err) => {reject(err);});});// 用户let p2 = new Promise((resolve, reject) => {//....});// 累计用户数let p3 = new Promise((resolve, reject) => {//....});// 日活用户数let p4 = new Promise((resolve, reject) => {//....});// 新增用户数let p5 = new Promise((resolve, reject) => {//....});// 指标排行表let p6 = new Promise((resolve, reject) => {//....});// 主要指标let p7 = new Promise((resolve, reject) => {getMainIndex().then((res) => {setTimeout(() => {resolve(res);}, 700);}).catch((err) => {reject(err);});});// 地图数据省份let p8 = new Promise((resolve, reject) => {//....});Promise.all([p1, p2, p3, p4, p5, p6, p7, p8]).then((res) => {// 累计注册用户//数据处理。。。// 日活//数据处理。。。// 累计用户数 (只展示前5条数据)//数据处理。。。// 日活用户数//数据处理。。。// 新增用户数//数据处理。。。// 指标排行表//数据处理。。。// 主要指标let mainIndex = res[6];this.MainIndicators.userAllCnt = Number(mainIndex.userAllCnt).toLocaleString("en-US"); //使用千分符this.MainIndicators.userNewCnt = Number(mainIndex.userNewCnt).toLocaleString("en-US");this.MainIndicators.userDailyActvCnt = Number(mainIndex.userDailyActvCnt).toLocaleString("en-US");this.MainIndicators.userDailyActvRatio = mainIndex.userDailyActvRatio;this.MainIndicators.userMonthlyActvCnt = Number(mainIndex.userMonthlyActvCnt).toLocaleString("en-US");this.MainIndicators.userMonthlyActvRatio =mainIndex.userMonthlyActvRatio;this.MainIndicators.mctAllCnt = Number(mainIndex.mctAllCnt).toLocaleString("en-US");// 地图省份指标let FenUserMap = res[7];this.mapData.mapArr = FenUserMap.map((item) => ({name: item.regionName,value: Number(item.userAllCnt).toFixed(),ratio: (Number(item.userActvDailyRatio) * 100).toFixed(1),}));//由于暂无数据隐藏南海诸岛,不太好,后面想到既然可以隐藏也可以将提示信息改成暂无数据this.mapData.mapArr.push({ name: "南海诸岛",value: 0,itemStyle: { opacity: 0, label: { show: false } },});this.falg = true; //子组件渲染}).catch((err) => {});},cancelLoading() {if (!this.loadTimer) {this.loadTimer = setTimeout(() => {this.loading = false;}, 500);} else {clearTimeout(this.loadTimer);}},},destroyed() {},
};
</script>
echarts、dataV 数据可视化大屏相关推荐
- 【echarts画数据可视化大屏】
目录 前言 一.数据清洗 1.去除重复值 2.处理缺失值 3.处理异常值 二.数据处理(将数据打包成绘制需要的格式) 1.条形图数据处理 2.折线图数据处理 3.玫瑰图数据处理 4.柱状图数据处理 5 ...
- 基于js+echarts实现数据可视化大屏展示
vue+echarts大屏数据可视化展示点击进入 写在前面: 本项目中使用的是echarts图表库,ECharts 提供了常规的折线图.柱状图.散点图.饼图.K线图,用于统计的盒形图,用于地理数据可视 ...
- 前端使用echarts实现数据可视化大屏展示
1.vue中如何使用echarts完成大屏展示:移步到这里 2.原生js项目中如何使用echarts完成大屏展示:移步到这里
- Datav:从零开始的数据可视化大屏搭建系统
本文首发于「Shopee技术团队」微信公众号 摘要 随着 Shopee 业务数据的不断扩大,仅通过表格这样的数据分析方式已经无法满足日常的数据分析需求,丰富的图表分析 Dashboard 就显得格外重 ...
- 27【源码】数据可视化大屏:基于 Echarts + Python Flask 实现的32-9超宽大屏范例 - 监控指挥中心
目录 效果展示 1. 效果动图 2. 多种主题效果 一. 确定需求方案 1. 屏幕分辨率 2. 部署方式 二. 整体架构设计 三. 编码实现 (基于篇幅及可读性考虑,此处展示部分关键代码) 1. 前端 ...
- 29【源码】数据可视化大屏:基于 Echarts + Python Flask 实现的32-9超宽大屏 - 企业综合信息
我是 YYDataV数据可视化 专注于 数据可视化大屏,工厂扫码装箱系统 等 我的微信 6550523,多多交流 ~ 本案例为32:9超宽分辨率的大屏. 效果展示 1.动态实时更新数据效果图 2.鼠 ...
- 基于vue+echarts 数据可视化大屏展示[附源码]
获取 ECharts 的路径有以下几种,请根据您的情况进行选择: 1) 最直接的方法是在 ECharts 的官方网站中挑选适合您的版本进行下载,不同的打包下载应用于不同的开发者功能与体积的需求,或者您 ...
- 数据可视化大屏电商数据展示平台开发实录(Echarts柱图曲线图、mysql筛选统计语句、时间计算、大数据量统计)
数据可视化大屏电商数据展示平台 一.前言 二.项目介绍 三.项目展示 四.项目经验分享 4.1 翻牌器 4.1.1 翻牌器-今日实时交易 4.1.2.翻牌器后端统计SUM函数的使用 4.2 不同时间指 ...
- 基于JavaScript+Koa2实现 Echarts 电商平台数据可视化大屏全栈【100010415】
全新 Echarts 电商平台数据可视化大屏全栈 1. 前言 五一假期重学了新版 Echarts,一个基于 JavaScript 的开源可视化图表库,收集参考了很多网上资料,最终选择电商平台作为练手项 ...
- 数据可视化大屏应急管理综合指挥调度系统完整案例详解(PHP-API、Echarts、百度地图)
文章目录 项目说明 一.项目说明 单位信息数据库字段: 资源数据库字段 项目需求 二.项目开发 1.项目分析 2.引入库 3.项目开发 (1)地图容器构建 (2)筛选和返回按钮事件 (3)企业筛选功能 ...
最新文章
- matlab中实时脚本与纯代码脚本
- openstack代码解读之 neutron.agent.linux.iptables_manager模块
- 网站过度优化该怎样解决?
- QT实现不同内置主题的外观
- 软件安装(JDK+MySQL+TOMCAT)
- 12种食物最养男人 10种食物最养女人 太值得收藏了
- PSD分层电商促销模板|换季大促销,不怕老板催你做海报了
- 【Qt教程】1.11 - Qt5 标准对话框QMessageBox(关于、错误、信息、警告、问题、颜色、字体、文件对话框)
- redis学习篇(九)-----高级特性之事务处理
- export project from intellij to myeclipse
- Hbase安装教程详解
- 2021计算机视觉-包揽所有前沿论文源码 -上半年
- 如何批量修改图片尺寸而不变形?
- google搜索语法与技巧
- 【开发经验】springboot配置文件加密详解
- 家用简单电线路图_这6张图在手,简单的家庭电路,电线还怕不会装?不存在的!...
- 应用程序正常初始化(0xc0000034)失败
- nodejs使用Moment.js操作日期时间
- 利用Python学习数据挖掘【2】
- 6000字长文,终于将数据中台架构体系讲明白了
热门文章
- php 有道翻译api,php有道翻译api调用方法实例
- vue项目px自动转rem适用于pc端
- Mybatis 传入多个参数查询数据 (3种方法)
- 用形态学及HSV完成车牌照识别
- Termux中proot-distro安装备份还原linux发行版笔记
- lisp 获取横断面数据_那位大神能帮忙写个从CAD图上提取横断面数据提取程序??...
- unity实现mmd功能(跳舞)
- swagger分页查询报错500
- 数字ic前端设计工程师是做什么的?就业前景如何?
- PROFIBUS DP和PROFINET IO区别