今天来讲解一下最近工作中学习到的一些新的知识点,也是自己第一次接触到的新内容,和小伙伴们一起分享学习下。
本次案例是使用vue3和Echarts图表进行实现的,整个书写代码过程相对来说还算比较简单,易于理解,项目开始之初肯定离不开框架的搭建,vue框架的搭建这里主要使用的是vue-cli来构建项目,不过小伙伴们也可以使用vite来构建,这个可能相对来说需要后期自己去书写里面的比如像路由这些。这里省略掉框架搭建的具体过程,来主要阐述一下项目是如何实现的吧!
(1)首先需要将视图的样式框架书写好,下图中展示的是整个项目的一个框架以及搭建的样式框架:
这里是views文件夹中HomePageView文件的代码
<template>
<div>
<!-- 标题部分 -->
<header>
<h4>数据可视化项目实践</h4>
</header>
<!-- 标题部分 end-->
<!-- 主题内容部分 -->
<section class="container">
<!-- 左边部分 -->
<section class="itemLeft">
<ItemPage>
<ItemOne></ItemOne>
</ItemPage>
<ItemPage>
<ItemTwo></ItemTwo>
</ItemPage>
</section>
<!-- 中间部分 -->
<section class="itemCenter">
<MapPage></MapPage>
</section>
<!-- 右边边部分 -->
<section class="itemRight">
<ItemPage>
<ItemTree></ItemTree>
</ItemPage>
<ItemPage>
<ItemFour></ItemFour>
</ItemPage>
</section>
</section>
</div>
</template>
<script setup>
import ItemPage from '@/components/itemPage.vue'
import ItemOne from '@/components/itemOne.vue'
import ItemTwo from '@/components/itemTwo.vue'
import ItemTree from '@/components/itemThree.vue'
import ItemFour from '@/components/itemFour.vue'
import MapPage from '@/components/mapPage.vue'
import {inject} from 'vue'
let $echart=inject('echarts')
let $http=inject('axios')
console.log($echart)
console.log($http)
</script>
<style scoped>
*{
margin: 0;
padding: 0;
}
header{
height: 1rem;
width: 100%;
background-color: rgb(6, 6, 200);
}
h4{
font-size: 0.2rem;
color: #fff;
text-align: center;
line-height: 1rem;
}
.container{
min-width: 1200px;
max-width: 2048px;
margin: 0 auto;
border: 1px rgb(85, 0, 255) solid;
padding: 0.125rem 0.125rem 0;
/* height: 500px;
background: #fc0; */
display: flex;
background: url('../assets/bg.jpeg');
}
.itemLeft,.itemRight{
flex: 3;
}
.itemCenter{
flex: 5;
height: 4.125rem;
border: 1px solid rgb(60, 0, 255);
padding: 0.125rem;
margin: 0.1rem;
}
</style>
(2)其次就是在app.vue中需要引入echarts以及其他内容,对于echarts刚开始需要安装,安装过程请查看echarts官方文档:在项目中引入 ECharts - 入门篇 - Handbook - Apache ECharts
<template>
<router-view />
</template>
<script setup>
import { provide } from 'vue';
import * as echarts from 'echarts';//引入echarts
import axios from 'axios'//引入数据
axios.defaults.baseURL='http://127.0.0.1:8888/'//基础数据连接
provide("echarts",echarts)
provide("axios",axios)
</script>
<style scoped>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
(3)下面就是各个组件里面的具体代码,这里我会将每个组件的代码一一罗列出
itemPage.vue文件是书写了一个插槽,用来盛放相同样式
<template>
<div class="item">
<slot></slot>
</div>
</template>
<script setup>
</script>
<style scoped>
.item{
height: 2.125rem;
border: 1px solid rgb(60, 0, 255);
margin: 0.1rem;
background: rgba(12, 135, 255, 0.85);
}
</style>
产品销售总量itemOne.vue文件代码
<template>
<div>
<h6>产品销售总量</h6>
<div class="chart" id="oneChart">
</div>
</div>
</template>
<script setup>
import {inject,onMounted,reactive} from 'vue'
let $echart=inject('echarts')
let $http=inject('axios')
let data=reactive({})
let xdata=reactive([])
let ydata=reactive([])
function setData(){
xdata=data.data.chartData.chartData.map(v=>v.title)
ydata=data.data.chartData.chartData.map(v=>v.num)
console.log('xdata',xdata)
console.log('ydata',ydata)
}
async function getState(){
data=await $http({url:'/one/data'})
// console.log(oneData)
}
onMounted(()=>{
let myChart=$echart.init(document.getElementById("oneChart"))
getState().then(()=>{
setData()
myChart.setOption({
grid:{
top:'3%',
left:'1%',
right:'6%',
bottom:'7%',
containLabel:true
},
xAxis:{
type:'value',
axisLine :{
lineStyle:{
color:'#fff'
}
}
},
yAxis:{
type:'category',
data:xdata,
axisLine :{
lineStyle:{
color:'#fff'
}
}
},
series:[
{
data:ydata,
type:'bar',
itemStyle:{
normal:{
barBorderRadius: [0, 20, 20, 0],
color:new $echart.graphic.LinearGradient(0,0,1,0,[
{
offset:0,
color:'#005EAA'
},
{
offset:0.5,
color:'#339ca8'
},
{
offset:1,
color:'#cda819'
}
])
}
}
}
]
})
})
})
</script>
<style scoped>
*{
margin: 0;
padding: 0;
}
.chart{
height: 2rem;
}
h6{
height: 0.25rem;
color: #fff;
font-weight: 400;
font-size: 0.125rem;
text-align: center;
line-height: 0.25rem;
}
</style>
产品月销统计itemTwo.vue代码
<template>
<div>
<h6>产品月销统计</h6>
<div class="chart" id="twoChart">
</div>
</div>
</template>
<script setup>
import {inject,onMounted,reactive} from 'vue'
let $echart=inject('echarts')
let $http=inject('axios')
let data=reactive({})
async function getState(){
data=await $http({url:'/two/data'})
// console.log(oneData)
}
onMounted(()=>{
let myChart=$echart.init(document.getElementById("twoChart"))
getState().then(()=>{
// console.log('折线图',data)
myChart.setOption({
tooltip:{
trigger:'axis',
axisPointer:{
type:'cross',
label:{
backgroundColor:'#e6b600'
}
}
},
legend:{
data:['服饰','数码','家电','家居','日化']
},
grid:{
right:'2%',
},
xAxis:{
type:'category',
data:data.data.chartTwo.chartData.day,
boundaryGap:false,
axisLine :{
lineStyle:{
color:'#fff'
}
}
},
yAxis:{
type:'value',
axisLine :{
lineStyle:{
color:'#fff'
}
}
},
series:[
{
name:'服饰',
type:'line',
data:data.data.chartTwo.chartData.num.Chemicals,
smooth:true,
showSymbol :false,
stack:'Total',
lineStyle:{
width:0
},
emphasis:{
focus:'series'
},
areaStyle:{
opacity:0.8,
color:new $echart.graphic.LinearGradient(0,0,1,0,[
{
offset:0,
color:'rgb(128,255,165)'
},
{
offset:1,
color:'rgb(1,191,236)'
},
])
}
},
{
name:'数码',
type:'line',
data:data.data.chartTwo.chartData.num.Clothes,
smooth:true,
showSymbol :false,
stack:'Total',
lineStyle:{
width:0
},
emphasis:{
focus:'series'
},
areaStyle:{
opacity:0.8,
color:new $echart.graphic.LinearGradient(0,0,1,0,[
{
offset:0,
color:'rgb(255, 0, 0)'
},
{
offset:1,
color:'rgb(244, 192, 192)'
},
])
}
},
{
name:'家电',
type:'line',
data:data.data.chartTwo.chartData.num.Electrical,
smooth:true,
showSymbol :false,
stack:'Total',
lineStyle:{
width:0
},
emphasis:{
focus:'series'
},
areaStyle:{
opacity:0.8,
color:new $echart.graphic.LinearGradient(0,0,1,0,[
{
offset:0,
color:'rgb(2, 178, 253)'
},
{
offset:1,
color:'rgb(196, 234, 250)'
},
])
}
},
{
name:'家居',
type:'line',
data:data.data.chartTwo.chartData.num.digit,
smooth:true,
showSymbol :false,
stack:'Total',
lineStyle:{
width:0
},
emphasis:{
focus:'series'
},
areaStyle:{
opacity:0.8,
color:new $echart.graphic.LinearGradient(0,0,1,0,[
{
offset:0,
color:'rgb(247, 186, 3)'
},
{
offset:1,
color:'rgb(249, 235, 193)'
},
])
}
},
{
name:'日化',
type:'line',
data:data.data.chartTwo.chartData.num.gear,
smooth:true,
showSymbol :false,
stack:'Total',
lineStyle:{
width:0
},
emphasis:{
focus:'series'
},
areaStyle:{
opacity:0.8,
color:new $echart.graphic.LinearGradient(0,0,1,0,[
{
offset:0,
color:'rgb(253, 83, 5)'
},
{
offset:1,
color:'rgb(247, 198, 175)'
},
])
}
},
]
})
})
})
</script>
<style scoped>
*{
margin: 0;
padding: 0;
}
.chart{
height: 2rem;
}
h6{
height: 0.25rem;
color: #fff;
font-weight: 400;
font-size: 0.125rem;
text-align: center;
line-height: 0.25rem;
}
</style>
库存统计itemThree.vue中代码
<template>
<div>
<h6>库存统计</h6>
<div class="chart" id="threeChart">
</div>
</div>
</template>
<script setup>
import {inject,onMounted,reactive} from 'vue'
let $echart=inject('echarts')
let $http=inject('axios')
let data=reactive({})
async function getState(){
data=await $http({url:'/three/data'})
// console.log(oneData)
}
onMounted(()=>{
let myChart=$echart.init(document.getElementById("threeChart"))
getState().then(()=>{
myChart.setOption({
legend:{
bottom:'6%',
// right:0,
left:'center',
textStyle:{
color:'#fff'
}
},
tooltip:{
show:true
},
series:[
{
type:'pie',
data:data.data.chartThree.chartData,
radius:[10,70],
center:['50%','35%'],
roseType:'area',
itemStyle:{
borderRadius:10
}
}
]
})
})
})
</script>
<style scoped>
*{
margin: 0;
padding: 0;
}
.chart{
height: 2rem;
}
h6{
height: 0.25rem;
color: #fff;
font-weight: 400;
font-size: 0.125rem;
text-align: center;
line-height: 0.25rem;
}
</style>
产品类别itemFour.vue中代码
<template>
<div>
<h6>产品类别</h6>
<div class="chart" id="fourChart">
</div>
</div>
</template>
<script setup>
import {inject,onMounted,reactive} from 'vue'
let $echart=inject('echarts')
let $http=inject('axios')
let data=reactive({})
async function getState(){
data=await $http({url:'/four/data'})
// console.log(oneData)
}
onMounted(()=>{
let myChart=$echart.init(document.getElementById("fourChart"))
getState().then(()=>{
console.log('折线图',data)
myChart.setOption({
xAxis:{
type:'category',
data:data.data.chartFour.chartData.day,
axisLine :{
lineStyle:{
color:'#fff'
}
}
},
yAxis:{
type:'value',
axisLine :{
lineStyle:{
color:'#fff'
}
}
},
tooltip:{
trigger:'axis',
axisPointer:{
type:'shadow',
}
},
legend:{
// bottom:'4%'
},
grid:{
right:'2%',
},
series:[
{
name:'服饰',
type:'bar',
data:data.data.chartFour.chartData.num.Chemicals,
stack:'Total',
label:{
show:true
},
emphasis:{
focus:'series'
},
},
{
name:'数码',
type:'bar',
data:data.data.chartFour.chartData.num.Clothes,
stack:'Total',
label:{
show:true
},
emphasis:{
focus:'series'
},
},
{
name:'家电',
type:'bar',
data:data.data.chartFour.chartData.num.Electrical,
stack:'Total',
label:{
show:true
},
emphasis:{
focus:'series'
},
},
{
name:'家居',
type:'bar',
data:data.data.chartFour.chartData.num.digit,
stack:'Total',
label:{
show:true
},
emphasis:{
focus:'series'
},
},
{
name:'日化',
type:'bar',
data:data.data.chartFour.chartData.num.gear,
stack:'Total',
label:{
show:true
},
emphasis:{
focus:'series'
},
},
]
})
})
})
</script>
<style scoped>
*{
margin: 0;
padding: 0;
}
.chart{
height: 2rem;
}
h6{
height: 0.25rem;
color: #fff;
font-weight: 400;
font-size: 0.125rem;
text-align: center;
line-height: 0.25rem;
}
</style>
最后是地图mapPage.vue代码
<template>
<div class="map" id="map">
</div>
</template>
<script setup>
import axios from 'axios'
import { onMounted ,reactive,inject} from 'vue';
let $echart=inject('echarts')
let mapData=reactive({})
async function getState(){
mapData=await axios.get('/china/data')
// console.log(oneData)
}
onMounted(()=>{
getState().then(()=>{
$echart.registerMap("china",mapData.data.chinaData)
let myChart=$echart.init(document.getElementById("map"))
myChart.setOption({
geo:{
map:'china',
itemStyle:{
areaColor:'#0099ff',
borderColor:'#00ffff',
shadowColor:'rgba(230,130,70,0.5)',
shadowBlur:30,
emphasis:{
focus:'self'
}
}
},
tooltip:{
trigger:'item'
},
title:{
text:'城市销量',
left:'45%',
textStyle:{
color:'#fc0',
fontSize:20,
textShadowBlur:10,
textShadowColor:'#33ffff'
}
},
visualMap:{
type:'continuous',
min:100,
max:5000,
calculable:true,
inRange:{
color:['#350a3ba','#eac736','#d94e5d']
},
textStyle:{
color:'#fc0'
}
},
series:[
{
type:'scatter',
itemStyle:{
color:'rgb(255, 128, 0)'
},
coordinateSystem:'geo',
data:[
{name:'北京',value:[116.46,39.92,4367]},
{name:'江苏',value:[118.76,32.04,8675]},
{name:'深圳',value:[114.07,22.62,2461]},
{name:'西安',value:[108.45,34,3421]},
]
}
]
})
})
})
</script>
<style scoped>
.map{
width: 100%;
height: 100%;
color: rgb(255, 128, 0);
}
</style>
(4)最后就是后端数据,需要另外新建文件夹,在里面书写各个图表的数据,这里将具体的数据文档放置serve: vue3+Echarts数据可视化后端数据
(5)下面就是最后的效果展示,图表是动态效果,只做图片展示