vue + echarts实现数据可视化统计页面
1、该项目自行下载element-ui、moment、echarts等vue的相关依赖包;2、该项目里面的echarts样式主题“walden.js”是个人自己配置的样式,可到官网自行配置或者选择默认样式;先上效果图:标数据可视化网页代码参考:三个echarts子组件(比较懒,子组件代码就做出一个组件画一张图,可以通过JavaScript对dom元素进行操作实现一组件画多图的效果,以后会考虑写一下
·
1、该项目自行下载element-ui、moment、echarts等vue的相关依赖包;
2、该项目里面的echarts样式主题“walden.js”是个人自己配置的样式,可到官网自行配置或者选择默认样式;
先上效果图:
代码参考:
三个echarts子组件(比较懒,子组件代码就做出一个组件画一张图,可以通过JavaScript对dom元素进行操作实现一组件画多图的效果,以后会考虑写一下)
chart1.vue
<template>
<div>
<div id="myChart1" :style="{width: width + 'px', height: height + 'px'}"></div>
</div>
</template>
<script>
import 'echarts/theme/walden.js'
export default {
name: 'echart1',
props: {
digitalData: {
type: Array,
default () {
return []
}
},
xAxisText: {
type: Array,
default () {
return []
}
},
title: {
type: String,
default () {
return ''
}
},
width: {
type: Number,
default: 0
},
height: {
type: Number,
default: 0
},
xFontColor: {
type: String,
default: '#a7a7a7'
}
},
data () {
return {
}
},
mounted () {
this.drawChart()
},
methods: {
drawChart () {
// 这个地方已经写死了一个组件画一个图表,可以自行用代码获取dom节点的多图创建,
// 而且这里的 'walden'也是我自己的echarts样式,可以用默认的,用默认就直接写成
// var myChart = this.$echarts.init(document.getElementById('myChart1'))
var myChart = this.$echarts.init(document.getElementById('myChart1'), 'walden')
let option = {
title: {
text: this.title
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: this.xAxisText,
axisLabel: {
show: true,
textStyle: {
color: this.xFontColor // 这里用参数代替了
}
}
},
yAxis: {
type: 'value',
axisLabel: {
show: true,
textStyle: {
color: this.xFontColor // 这里用参数代替了
}
}
},
series: [{
barWidth: '60%',
data: this.digitalData,
type: 'bar'
}]
}
myChart.setOption(option, true)
}
}
}
</script>
<style scoped>
</style>
chart2.vue
<template>
<div>
<div id="myChart2" :style="{width: width + 'px', height: height + 'px'}"></div>
</div>
</template>
<script>
import 'echarts/theme/walden.js'
export default {
name: 'echart2',
props: {
leftText: {
type: Array,
default () {
return []
}
},
digitalData: {
type: Array,
default () {
return []
}
},
title: {
type: String,
default () {
return ''
}
},
width: {
type: Number,
default: 0
},
height: {
type: Number,
default: 0
}
},
data () {
return {
}
},
mounted () {
this.drawChart()
},
methods: {
drawChart () {
var myChart = this.$echarts.init(document.getElementById('myChart2'), 'walden')
let option = {
title: {
text: this.title,
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: 'left',
data: this.leftText
},
series: [
{
name: '占比',
type: 'pie',
radius: '60%',
center: ['60%', '50%'],
data: this.digitalData,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
}
myChart.setOption(option, true)
}
}
}
</script>
<style lang="scss" scoped>
</style>
chart3.vue
<template> <div> <div id='myChart3' :style="{width: width + 'px', height: height + 'px'}"></div> </div> </template> <script> import 'echarts/theme/walden.js' export default { name: 'echart3', props: { text: { type: Array, default () { return [] } }, digitalData: { type: Array, default () { return [] } }, title: { type: String, default () { return '' } }, width: { type: Number, default: 0 }, height: { type: Number, default: 0 }, radius: { type: Number, default: 100 } }, data () { return {} }, mounted () { this.drawChart() }, methods: { drawChart () { var myChart = this.$echarts.init(document.getElementById('myChart3'), 'walden') let option = { title: { text: this.title, left: 'center' }, tooltip: { trigger: 'item', formatter: '{a} <br/>{b} : {c} ({d}%)' }, legend: { left: 'center', top: 'bottom', data: this.text }, series: [ { name: '面积模式', type: 'pie', radius: [20, this.radius], center: ['50%', '60%'], roseType: 'area', data: this.digitalData } ] } myChart.setOption(option, true) } } } </script> <style lang='scss' scoped> </style>
数字字体是液晶的数字字体ttf,百度找得到,在app.vue入口写好:
@font-face {
font-family: 'Digital';
src: url('assets/font/Digital.ttf');
}
最后就是该页面的代码了(四百多行):
<template>
<div class="back">
<div class="top">
<div>大厅已服务监视 {{watchTime.toFixed(1)}} 小时 (h)</div>
<img src="../assets/winwatch/top.png" alt="">
<div class="title">资源共享监视平台</div>
<img src="../assets/winwatch/top.png" alt="">
<div class="time">
<div>{{time}}</div>
<div>{{date}}</div>
</div>
<div @click="toPageBack">返回<img src="../assets/winwatch/back.png" width="30px" alt=""></div>
<div @click="fullScreen(screenAll)">
<span v-if="screenAll == 0">进入全屏</span>
<span v-if="screenAll == 1">退出全屏</span>
</div>
</div>
<el-row>
<el-col :span="15">
<div class="item-left-top">
<div><chart2 :width='380' :height='250' :leftText="chart2Text" :digitalData="digitalData"
style="padding-top: 20px;"></chart2></div>
<div>
<div>轮播广告图点击量</div>
<div>100</div>
<div>昨日点击 100</div>
<div>对比点击 0</div>
</div>
<div>
<div>在线用户</div>
<div>100</div>
<div>平台资源数 100</div>
<div>今日资源点击量 90008</div>
</div>
</div>
<div class="item-left-bottom">
<div>
<p>活跃用户前五所在城市</p>
<chart3 :width='340' :height='340' :radius='80' :leftText="chart3Text" :digitalData="digitalData2"></chart3>
</div>
<div>
<p>活跃用户前五所在城市</p>
<table border="1" cellpadding="0" cellspacing="0" width="90%" class="table1">
<tr height="50px" align="center" style="font-size:15px;">
<td>分类</td>
<td>名称</td>
<td>下载量</td>
</tr>
<tr v-for="(item, index) in tableData1" :key="index" height="40px" align="center">
<td>{{item.sortName}}</td>
<td>{{item.title}}</td>
<td>{{item.downloadNum}}</td>
</tr>
</table>
</div>
</div>
</el-col>
<el-col :span="9">
<div class="item-right">
<p>近七天资源下载量</p>
<chart1 :width='400' :height='280' :xAxisText="xAxisText1"
:xFontColor="'#FFFFFF'" :digitalData="digitalData1"></chart1>
<p>排名前 8 资源 <br> 更新于2020-06-11</p>
<table border="1" cellpadding="0" cellspacing="0" width="90%" class="table2">
<tr height="50px" align="center" style="font-size:15px;">
<td>分类</td>
<td>名称</td>
<td>下载量</td>
</tr>
<tr v-for="(item, index) in tableData1" :key="index" height="40px" align="center">
<td>{{item.sortName}}</td>
<td>{{item.title}}</td>
<td>{{item.downloadNum}}</td>
</tr>
</table>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import moment from 'moment'
import chart1 from '@/components/chart1'
import chart2 from '@/components/chart2'
import chart3 from '@/components/chart3'
export default {
components: {
chart1,
chart2,
chart3
},
data () {
return {
screenAll: 0, // 0退出全屏, 1全屏
time: '',
watchTime: 0,
digitalData1: [1, 2, 3, 4, 10, 5, 1],
xAxisText1: ['07-18', '07-19', '07-20', '07-21', '07-22', '07-23', '07-24'],
chart2Text: ['广州市', '佛山市', '深圳市', '上海市', '北京市'],
digitalData: [
{value: 200, name: '广州市'},
{value: 100, name: '佛山市'},
{value: 100, name: '深圳市'},
{value: 50, name: '上海市'},
{value: 50, name: '北京市'}
],
chart3Text: ['广州市', '佛山市', '深圳市', '上海市', '北京市'],
digitalData2: [
{value: 200, name: '广州市'},
{value: 100, name: '佛山市'},
{value: 100, name: '深圳市'},
{value: 50, name: '上海市'},
{value: 50, name: '北京市'}
],
tableData1: [{sortName: '电影', title: '唐人街探案 II', downloadNum: 1866},
{sortName: '电影', title: '唐人街探案 II', downloadNum: 1866},
{sortName: '电影', title: '唐人街探案 II', downloadNum: 1866},
{sortName: '电影', title: '唐人街探案 II', downloadNum: 1866},
{sortName: '电影', title: '唐人街探案 II', downloadNum: 1866}]
}
},
mounted () {
this.timer = setInterval(() => { // 更新小时时间
this.time = moment().format('HH:mm:ss')
}, 1000)
this.watchTimer = setInterval(() => { // 更新监测时间
this.watchTime += 0.1
}, 360000)
},
beforeDestroy () { // 清除定时器
if (this.timer) {
clearInterval(this.timer)
}
if (this.watchTimer) {
clearInterval(this.watchTimer)
}
},
methods: {
toPageBack () {
this.$router.go(-1)
},
fullScreen () { // # 全屏显示
if (this.screenAll === 1) {
this.screenAll = 0
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
}
} else {
this.screenAll = 1
if (document.documentElement.requestFullscreen) {
document.documentElement.requestFullscreen()
} else if (document.documentElement.webkitRequestFullScreen) {
document.documentElement.webkitRequestFullScreen()
} else if (document.documentElement.mozRequestFullScreen) {
document.documentElement.mozRequestFullScreen()
} else if (document.documentElement.msRequestFullscreen) {
// IE11
document.documentElement.msRequestFullscreen()
}
}
}
},
computed: {
date () {
return moment().format('YYYY 年 MM 月 DD 日')
}
}
}
</script>
<style lang="scss" scoped>
tr:hover{
background: #030237;
}
.back{
background: #030237;
width: 100%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
font-size: 18px;
overflow-x: hidden;
color: #5A95DA;
.top{
width: 100%;
height: 60px;
line-height: 60px;
color: #4471A6;
// background: #050297;
border-bottom: 2px solid #4471A6;
display: flex;
align-items: center;
justify-content: center;
min-width: 1400px;
position: relative;
div:first-child{
position: relative;
left: -3%;
}
img:nth-child(2){
width: 250px;
height: 40px;
margin-left: 2%;
}
img:nth-child(4){
width: 250px;
height: 40px;
}
.title{
width: 280px;
background-image: url('../assets/winwatch/top2.png');
background-size: 100% 100%;
background-repeat: no-repeat;
text-align: center;
}
.time{
width: 200px;
height: 50px;
line-height: 25px;
display: flex;
flex-direction: column;
div{
text-align: center;
font-weight: 600;
font-size: 18px;
font-family: Digital;
}
}
div:nth-child(6){
cursor: pointer;
img{
position: relative;
top: 5px;
margin-left: 5px;
}
}
div:last-child{
font-size: 12px;
margin-left: 2%;
cursor: pointer;
}
div:last-child:hover{
color: cyan;
}
}
.el-row{
.item-left-top{
width: 100%;
height: 350px;
display: flex;
justify-content: center;
align-items: center;
// background: crimson;
div{
width: 26%;
height: 280px;
// background: cornflowerblue;
margin: auto;
display: flex;
flex-direction: column;
position: relative;
left: 1%;
}
div:first-child{
width: 400px;
height: 280px;
}
div:nth-child(2), div:last-child{
animation: dh1 5s;
-webkit-animation: dh1 5s; /* Safari and Chrome */
div{
width: 100%;
display: flex;
justify-content: center;
text-align: center;
font-family: digital;
}
div:nth-child(2){
font-size: 80px;
padding: 30px 0;
color: #D3EDFF;
}
div:nth-child(3), div:last-child{
text-align: left;
text-indent: 30px;
}
}
}
.item-left-bottom{
width: 96%;
height: 400px;
margin: auto;
border: 2px solid #0094FF;
border-radius: 10px;
margin-bottom: 30px;
background-image: radial-gradient(#1A2D5E 5%, #000337 70%);
display: flex;
justify-content: center;
align-items: center;
animation: dh2 2s;
-webkit-animation: dh2 2s; /* Safari and Chrome */
animation-delay: 2s;
animation-fill-mode: both;
div{
height: 380px;
// background: crimson;
margin: 0 10px;
p{
position: relative;
top: 30px;
}
}
div:first-child{
width: 340px;
display: flex;
flex-direction: column;
align-items: center;
div{
position: relative;
bottom: 8%;
animation: dh4 2s;
-webkit-animation: dh4 2s; /* Safari and Chrome */
animation-delay: 3s;
animation-fill-mode: both;
}
}
div:last-child{
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
}
.table1{
position: relative;
top: 50px;
border: 1px solid #5A95DA;
font-size: 12px;
animation: dh4 2s;
-webkit-animation: dh4 2s; /* Safari and Chrome */
animation-delay: 5s;
animation-fill-mode: both;
}
}
.item-right{
width: 90%;
height: 700px;
margin: 40px auto;
border: 2px solid #0094FF;
border-radius: 10px;
background-image: linear-gradient(to top, #1A2D5E, #000337);
animation: dh3 2s;
-webkit-animation: dh3 2s; /* Safari and Chrome */
animation-delay: 4s;
animation-fill-mode: both;
div{
position: relative;
left: 5%;
animation: dh4 2s;
-webkit-animation: dh4 2s; /* Safari and Chrome */
animation-delay: 6s;
animation-fill-mode: both;
}
.table2{
border: 1px solid #5A95DA;
font-size: 12px;
margin: 30px auto;
animation: dh4 2s;
-webkit-animation: dh4 2s; /* Safari and Chrome */
animation-delay: 7s;
animation-fill-mode: both;
}
p{
padding-top: 40px;
font-size: 15px;
text-align: center;
}
p:first-child{
padding-top: 20px;
margin: 0;
}
}
}
}
// 渐变效果
@keyframes dh1{
from {opacity: 0;}
to {opacity: 1;}
}
// 上移效果
@keyframes dh2{
from {opacity: 0; position: relative;top: 100px;}
to {opacity: 1; position: relative; top: 0;}
}
// 左移效果
@keyframes dh3{
from {opacity: 0; position: relative;left: 500px;}
to {opacity: 1; position: relative; left: 0;}
}
// 缩放出现效果
@keyframes dh4{
from {opacity: 0; transform: scale(0,0);}
to {opacity: 1; transform: scale(1,1);}
}
</style>
效果就是上面图片那样了,Good Luck !!
更多推荐
已为社区贡献1条内容
所有评论(0)