2022.10.20我学会如何使用echarts+DataV的使用。以下是效果图:
目录如下:
一、安装组件库
首先我们先安装组件库。
npm install @jiaminghi/data-view
二、main.js引入组件
然后在main.js中引入组件。
// 将自动注册所有组件为全局组件
import dataV from '@jiaminghi/data-view'
Vue.use(dataV)
三、把初始页面作为主页面
我们把HomeView.vue页面作为主页面。
(1)添加全屏容器
先设置全屏容器。
<dv-full-screen-container>content</dv-full-screen-container>
使用前请注意将body
的margin
设为0,否则会引起计算误差,全屏后不能完全充满屏幕。
(2)添加loading加载效果
然后在全屏容器中放入一个loading试一下效果。
<dv-full-screen-container>
//loading加载中
<dv-loading>Loading...</dv-loading>
</dv-full-screen-container>
(3)添加边框
然后就是添加边框。
<dv-full-screen-container>
//loading加载中
<dv-loading>Loading...</dv-loading>
//添加边框
<dv-border-box-11 title="大数据可视化" >
</dv-border-box-11>
</dv-full-screen-container>
做到这边的效果为
loading我就没展示了。
然后可以给loading一个条件渲染,就是在加载之后可以显示出这个页面。
给loading一个v-if=”loading“,边框为else,然后data数据里面填loading=true,添加mounted页面加载后的方法。
<dv-loading v-if="loading">Loading...</dv-loading>
<div v-else class="zhengti">
// 页面加载后
mounted(){
// 执行这个方法
this.guanbiLoading();
},
data() {
return {
// loading默认打开
loading: true,
};
},
然后在methods中调用这个方法。
methods: {
// mounted执行后调用的方法
guanbiLoading(){
// setTimeout()指定时间后调用的函数,时间为3000毫秒
setTimeout(()=>{
this.loading = false;
},1000)
}
},
具体就是在指定事件之后关闭这个loading。
(4)创建一个新的vue页面
<div class="zuo"><dv-border-box-10 style="width:400px;height:600px;background-color:#343440"><zuo /></dv-border-box-10></div>
可以让它用一个边框包裹住,里面的展示方法类似于<router-view></router-view>
(5)注册引入这个页面
// 引入组件
import zuo from './zuo.vue'
components:{
zuo
},
这样等一下在新的vue页面中的效果就可以在<zuo/>中进行展示。
(6)编写新的vue页面代码
echarts的编写需要在components中写(相当于子组件),views是用来展示这个效果的(相当于父组件)
我们在view中创建新的页面。因为是用来展示echarts的,所以代码直接上。
<template>
<div>
<div class="biaoti">
<!-- 设置标题 -->
<h4 style="color: skyblue">任务通过率</h4>
<!-- 动画 -->
<dv-decoration-3 style="width: 250px; height: 30px" />
</div>
<div>
<!-- 展示echarts页面 -->
<zuoecharts />
</div>
<div class="waibu">
<!-- 列表渲染数据 -->
<div class="item-box" v-for="(item, index) in numberData" :key="index">
<div class="neibu">
<span style="color: yellow; font-size: 30px; margin-left: 30px"
>¥</span
>
<!-- 动态数字 -->
<!-- :config是datav绑定动态数据的方式 -->
<dv-digital-flop
:config="item.number"
style="width: 100px; height: 50px;margin-left:-10px"
/>
</div>
<!-- 文字 -->
<p class="text" style="text-align: center;color:white">
{{ item.text }}
<span style="color: yellow">(件)</span>
</p>
</div>
</div>
</div>
</template>
<script>
// 引入components中的组件
import zuoecharts from "@/components/echarts/zuoecharts";
export default {
data() {
return {
numberData: [
{
number: {
number: [15],
toFixed: 1,
// data中的写法
content: "{nt}",
},
text: "今日构建总量",
},
{
number: {
number: [1144],
toFixed: 1,
// data中的写法
content: "{nt}",
},
text: "总共完成数量",
},
{
number: {
number: [361],
toFixed: 1,
// data中的写法
content: "{nt}",
},
text: "正在编译数量",
},
{
number: {
number: [157],
toFixed: 1,
// data中的写法
content: "{nt}",
},
text: "未通过数量",
},
],
};
},
// 注册组件
components: {
zuoecharts,
},
// 页面加载后
mounted() {
this.changeTiming();
},
methods: {
changeTiming() {
// setInterval指定事件间隔调用函数
setInterval(() => {
this.changeNumber();
}, 3000);
},
// 调用changeNumber方法
changeNumber() {
// forEach列出数组的每一个元素
this.numberData.forEach((item, index) => {
item.number.number[0] += ++index;
item.number = { ...item.number };
});
},
},
};
</script>
<style>
.biaoti {
display: flex;
justify-content: center;
align-items: center;
}
.waibu {
margin-top: -70px;
margin-left: 20px;
display: flex;
width: 100%;
flex-wrap: wrap;
}
.neibu {
width: 180px;
display: flex;
min-width: calc(100%/2);
}
</style>
这边引入的组件是components子组件里面的内容。所以总共需要引入两次组件(view => 主页main )(components => view)
(7)编写components建立新页面
<template>
<div id="main" style="width: 600px; height: 400px"></div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
export default {
data() {
return {
chart: null,
};
},
mixins: [echartMixins],
// 页面加载后
mounted() {
this.zuo();
},
methods: {
// 页面加载成功之后调用
zuo() {
this.chart = this.$echarts.init(document.getElementById("main"));
this.chart.setOption({
// 设置颜色依次使用
color: [
"#37a2da",
"#32c5e9",
"#9fe6b8",
"#ffdb5c",
"#ff9f7f",
"#fb7293",
"#e7bcf3",
"#8378ea",
],
// 提示框
tooltip: {
//trigger 触发类型,默认数据触发
trigger: "item",
//formatter 调用自定义的数据
formatter: "{a}<br/>{b} :{c}({d}%)",
},
// 可视化的工具箱
toolbox: {
show: true,
},
// 开关
legend: {
// orient布局方式 horizontal默认为水平布局
orient: "horizontal",
// x为水平安放位置
x: "center",
// 下边距离
bottom: 80,
// 左边距离
left: 80,
// 按钮样式为圆形
icon: "circle",
// 宽度三个为一行
width: "33.33%",
// 设置数据
data: ["rose1", "rose2", "rose3", "rose4", "rose5", "rose6"],
// textStyle 图例文字颜色
textStyle: {
color: "#fff",
},
},
// 系列
series: [
{
// 名字
name: "增值电信业务统计图",
// 类型
type: "pie",
// 整体大小
radius: [20, 100],
// roseType设置比例
roseType: "area",
// 左右 上下距离
center: ["30%", "40%"],
// 存放数据
data: [
{
value: 10,
name: "rose1",
},
{
value: 5,
name: "rose2",
},
{
value: 15,
name: "rose3",
},
{
value: 25,
name: "rose4",
},
{
value: 20,
name: "rose5",
},
{
value: 35,
name: "rose6",
},
],
},
],
});
},
// 实例销毁
destoryed() {
// onresize删除绑定事件
window.onresize = null;
},
},
};
</script>
<style>
</style>
这里面要注意的几点是建立DOM容器,然后获取id,都是mounted页面加载之后显示出这个页面的效果。echartsMinis的样式我在后面会放出来。
(8)完整代码
.1主页面
// 主页面
<template>
<div>
<!-- 全屏使用容器 -->
<dv-full-screen-container>
<!-- 加载中 -->
<!-- v-if判断loading是否为true -->
<dv-loading v-if="loading">Loading...</dv-loading>
<!-- loading为false时触发 -->
<!-- zhengti布局 -->
<div v-else class="zhengti">
<!-- 设置标题 -->
<dv-border-box-11 title="大数据可视化" >
<!-- 左页面展示 -->
<dv-decoration-1 style="width:200px;height:50px;" />
<div class="zuo"><dv-border-box-10 style="width:400px;height:600px;background-color:#343440"><zuo /></dv-border-box-10></div>
<!-- 中间页面展示 -->
<!-- <div class="center"><center/></div> -->
<!-- 右页面展示 -->
<!-- <div class="you"><you/></div> -->
</dv-border-box-11>
</div>
</dv-full-screen-container>
</div>
</template>
<script>
// 引入组件
import zuo from './zuo.vue'
import center from './center.vue'
import you from './you.vue'
export default {
data() {
return {
// loading默认打开
loading: true,
};
},
// 注册组件
components:{
zuo,
center,
you
},
// 页面加载后
mounted(){
// 执行这个方法
this.guanbiLoading();
},
methods: {
// mounted执行后调用的方法
guanbiLoading(){
// setTimeout()指定时间后调用的函数,时间为3000毫秒
setTimeout(()=>{
this.loading = false;
},1000)
}
},
};
</script>
<style>
body {
margin: 0;
}
.zhengti {
height: 100%;
}
</style>
.2view 下的新页面
<template>
<div>
<div class="biaoti">
<!-- 设置标题 -->
<h4 style="color: skyblue">任务通过率</h4>
<!-- 动画 -->
<dv-decoration-3 style="width: 250px; height: 30px" />
</div>
<div>
<!-- 展示echarts页面 -->
<zuoecharts />
</div>
<div class="waibu">
<!-- 列表渲染数据 -->
<div class="item-box" v-for="(item, index) in numberData" :key="index">
<div class="neibu">
<span style="color: yellow; font-size: 30px; margin-left: 30px"
>¥</span
>
<!-- 动态数字 -->
<!-- :config是datav绑定动态数据的方式 -->
<dv-digital-flop
:config="item.number"
style="width: 100px; height: 50px;margin-left:-10px"
/>
</div>
<!-- 文字 -->
<p class="text" style="text-align: center;color:white">
{{ item.text }}
<span style="color: yellow">(件)</span>
</p>
</div>
</div>
</div>
</template>
<script>
// 引入components中的组件
import zuoecharts from "@/components/echarts/zuoecharts";
export default {
data() {
return {
numberData: [
{
number: {
number: [15],
toFixed: 1,
// data中的写法
content: "{nt}",
},
text: "今日构建总量",
},
{
number: {
number: [1144],
toFixed: 1,
// data中的写法
content: "{nt}",
},
text: "总共完成数量",
},
{
number: {
number: [361],
toFixed: 1,
// data中的写法
content: "{nt}",
},
text: "正在编译数量",
},
{
number: {
number: [157],
toFixed: 1,
// data中的写法
content: "{nt}",
},
text: "未通过数量",
},
],
};
},
// 注册组件
components: {
zuoecharts,
},
// 页面加载后
mounted() {
this.changeTiming();
},
methods: {
changeTiming() {
// setInterval指定事件间隔调用函数
setInterval(() => {
this.changeNumber();
}, 3000);
},
// 调用changeNumber方法
changeNumber() {
// forEach列出数组的每一个元素
this.numberData.forEach((item, index) => {
item.number.number[0] += ++index;
item.number = { ...item.number };
});
},
},
};
</script>
<style>
.biaoti {
display: flex;
justify-content: center;
align-items: center;
}
.waibu {
margin-top: -70px;
margin-left: 20px;
display: flex;
width: 100%;
flex-wrap: wrap;
}
.neibu {
width: 180px;
display: flex;
min-width: calc(100%/2);
}
</style>
.3components下的新页面
<template>
<div id="main" style="width: 600px; height: 400px"></div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
export default {
data() {
return {
chart: null,
};
},
mixins: [echartMixins],
// 页面加载后
mounted() {
this.zuo();
},
methods: {
// 页面加载成功之后调用
zuo() {
this.chart = this.$echarts.init(document.getElementById("main"));
this.chart.setOption({
// 设置颜色依次使用
color: [
"#37a2da",
"#32c5e9",
"#9fe6b8",
"#ffdb5c",
"#ff9f7f",
"#fb7293",
"#e7bcf3",
"#8378ea",
],
// 提示框
tooltip: {
//trigger 触发类型,默认数据触发
trigger: "item",
//formatter 调用自定义的数据
formatter: "{a}<br/>{b} :{c}({d}%)",
},
// 可视化的工具箱
toolbox: {
show: true,
},
// 开关
legend: {
// orient布局方式 horizontal默认为水平布局
orient: "horizontal",
// x为水平安放位置
x: "center",
// 下边距离
bottom: 80,
// 左边距离
left: 80,
// 按钮样式为圆形
icon: "circle",
// 宽度三个为一行
width: "33.33%",
// 设置数据
data: ["rose1", "rose2", "rose3", "rose4", "rose5", "rose6"],
// textStyle 图例文字颜色
textStyle: {
color: "#fff",
},
},
// 系列
series: [
{
// 名字
name: "增值电信业务统计图",
// 类型
type: "pie",
// 整体大小
radius: [20, 100],
// roseType设置比例
roseType: "area",
// 左右 上下距离
center: ["30%", "40%"],
// 存放数据
data: [
{
value: 10,
name: "rose1",
},
{
value: 5,
name: "rose2",
},
{
value: 15,
name: "rose3",
},
{
value: 25,
name: "rose4",
},
{
value: 20,
name: "rose5",
},
{
value: 35,
name: "rose6",
},
],
},
],
});
},
// 实例销毁
destoryed() {
// onresize删除绑定事件
window.onresize = null;
},
},
};
</script>
<style>
</style>
.4 units.js文件
1)index.js文件
export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result;
const later = function() {
// 据上一次触发时间间隔
const last = +new Date() - timestamp;
// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args);
if (!timeout) context = args = null;
}
}
};
return function(...args) {
context = this;
timestamp = +new Date();
const callNow = immediate && !timeout;
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
}
return result;
};
}
2)resizeMixins.js文件
// 混入代码 resize-mixins.js
import { debounce } from '@/utils/index';
const resizeChartMethod = '$__resizeChartMethod';
export default {
data() {
// 在组件内部将图表init的引用映射到chart属性上
return {
chart: null,
};
},
created() {
window.addEventListener('resize', this[resizeChartMethod], false);
},
beforeDestroy() {
window.removeEventListener('reisze', this[resizeChartMethod]);
},
methods: {
// 通过lodash的防抖函数来控制resize的频率
[resizeChartMethod]: debounce(function() {
if (this.chart) {
this.chart.resize();
}
}, 100),
},
};
.5main.js文件
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import axios from 'axios'
import dataV from '@jiaminghi/data-view'
//引入echart
import * as echarts from 'echarts'
Vue.prototype.$echarts = echarts
Vue.use(dataV)
Vue.prototype.$ajax= axios
Vue.config.productionTip = false
new Vue({
router,
store,
axios,
render: function (h) { return h(App) }
}).$mount('#app')