【Vue3+ECharts 实战】构建可视化销售数据分析看板!
本文介绍了如何通过前端技术将接口数据渲染为图表。首先,提供了接口返回的数据格式示例,包含销售明细、导购员信息、交易时间等字段。接着,展示了如何在Vue.js框架中使用ECharts库绘制多种图表,包括柱状图、折线图和饼状图。柱状图用于展示2024年销售金额最高的前10名导购员,折线图展示2023年不同月份的销售量变化,饼状图则展示2023-2024年不同门店的销售金额。每个图表的实现步骤包括数据处
·
本文我简单讲解分享一下vue实现可视化图表前端的核心逻辑,看完本篇使用 vue3 + echarts 手搓几个针对数据渲染的图表不在话下
在企业级数据管理场景中,可视化图表是呈现业务数据的核心载体。本文将基于 Vue3 和 ECharts,实现一个包含柱状图、饼状图等;读取接口的数据渲染出图表格,这里为了照顾前端的朋友,直接给出接口请求到的数据格式,可以参考我的数据制作mock数据!
[
{
"日销单明细ID": "RXDMX-04dd397d319628747d4be54ab4aefbad-3",
"日销单ID": "RXD-SLFS01452-1534299369-1",
"款式组合编码": "SL-D03-X02-D1-TS-70-7006",
"销售数量": "17",
"零售单价": "75.0",
"折扣率": "0.27",
"折后单价": "54.75",
"折后总价": "930.75",
"门店编码": "SLFS01452",
"导购员编码": "SL6624111",
"交易时间": "2024-08-15 10:16:09",
"款式组合名称": "中档-短袖T恤D1-70(L)-米灰色",
"款式编码": "SL-D03-X02-D1",
"导购员姓名": "仵朝阳",
"是否门店经理": "1",
"门店名称": "盛利服饰(向阳路店)"
},
{
"日销单明细ID": "RXDMX-439caa8c685ec12ada4c7c8d3e097ee6-5",
"日销单ID": "RXD-SLFS01211-1505042108-1",
"款式组合编码": "SL-D05-X01-C5-TY-M-9022",
"销售数量": "20",
"零售单价": "130.0",
"折扣率": "0.34",
"折后单价": "85.8",
"折后总价": "1716.0",
"门店编码": "SLFS01211",
"导购员编码": "SL5221332",
"交易时间": "2023-09-10 19:15:08",
"款式组合名称": "低档-光皮皮衣C5-M-珍珠浅灰",
"款式编码": "SL-D05-X01-C5",
"导购员姓名": "曹智超",
"是否门店经理": "0",
"门店名称": "盛利服饰(银信广场店)"
},
]
很好接下来就是代码部分,清晰可见,当然这里echats 是下载在本地了, 读者看到可以使用script直接引入到组件或者下载,参考 快速上手 - 使用手册 - Apache ECharts
app.vue
<template>
<!-- <HelloWorld msg="Welcome to Your Vue.js App"/> -->
<!-- <TopTenSellman/> --> <br><br>
<!-- <LowNumShop/> --> <br><br>
<LineMonthSell/> <br><br>
<PieMonthShop/> <br><br>
<RoseTenShop/> <br><br>
</template>
<script setup>
// import HelloWorld from './components/HelloWorld.vue'
import TopTenSellman from './components/TopTenSellman.vue'
import LowNumShop from './components/LowNumShop.vue'
import LineMonthSell from './components/LineMonthSell.vue'
import PieMonthShop from './components/PieMonthShop.vue'
import RoseTenShop from './components/RoseTenShop.vue'
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
前10排名的柱形图
topTenSellMan.vue 组件
<template>
<div ref="chartRef" class="chart-container"></div>
</template>
<script setup>
// todo 用柱状图展示2024年销售金额最高的前10个导购
import { ref, onMounted } from 'vue'
import * as echarts from '../assets/echarts.js'
import clothingSalesData from '../data/clothing_sales_data.json'
const processData = (data) => {
// 按照 x轴的数据 分组
const groupData = {}
data.forEach(el => {
const sellman = el.导购员姓名
// 保留两位小数
// 四舍五入这个数值
const sellAmount = Number(el.折后单价)
const year = new Date(el.交易时间).getFullYear()
// console.log('sellman ',sellman,'; sellAmount ',sellAmount ,'; year ',year);
if (year === 2024) {
/* toFixed(2) 将数字格式化为保留2位小数的字符串
parseFloat() 将字符串转回数字,这样可以继续进行数学运算 */
groupData[sellman] = parseFloat((groupData[sellman] || 0) + sellAmount).toFixed(2)
}
})
// 排序取前n位
const finalData = Object.entries(groupData)
.map(([sellman, sellAmount]) => ({
sellman,
sellAmount
}))
.sort((a, b) => b.sellAmount - b.sellAmount)
.slice(0, 10)
// console.log('finalData', finalData)
return finalData
}
// todo 绘制 echarts 图表
const chartRef = ref()
const initChart = (data) => {
const myChart = echarts.init(chartRef.value)
const sellman = data.map(el => el.sellman)
const sellAmount = data.map(el => el.sellAmount)
const option = {
title: {
text: '一、用柱状图展示2024年销售金额最高的前10个导购',
left: 'center'
},
xAxis: {
type: 'category',
data: sellman,
axisLabel:{
rotate:26,
}
},
yAxis: {
type: 'value',
name: '销售金额(元)'
},
tooltip: {
trigger: 'axis', // 触发类型
axisPointer: {
type: 'shadow', // 鼠标悬停时显示阴影
}
},
series: [{
name: '销售金额',
type: 'bar',
data: sellAmount,
label: {
show: true,
position: 'top'
}
}]
}
myChart.setOption(option)
}
onMounted(() => {
const chartdata = processData(clothingSalesData)
console.log('chartdata', chartdata)
initChart(chartdata)
})
</script>
<style scoped>
.chart-container {
width: 700px;
height: 400px;
background-color: #f1f6ff;
/* 浅蓝灰色背景,柔和不抢眼 */
box-shadow: 0 0 8px 1px #748ede66;
/* 使用主色调的透明阴影 */
border-radius: 10px;
margin-left: 50px;
}
</style>
柱形图2
<template>
<div ref="chartRef" class="chart-container"></div>
</template>
<script setup>
// todo 子任务三:折线图展示 2023 年不同月份销售量变化
import { ref, onMounted } from 'vue'
import * as echarts from '../assets/echarts.js'
import clothingSalesData from '../data/clothing_sales_data.json'
const processData = (data) => {
// 按照 x轴的数据 分组
const groupData = {}
data.forEach(el => {
const sellAmount = Number(el.折后单价)
const month = new Date(el.交易时间).getMonth()
const year = new Date(el.交易时间).getFullYear()
if (year === 2023) {
/* toFixed(2) 将数字格式化为保留2位小数的字符串
parseFloat() 将字符串转回数字,这样可以继续进行数学运算 */
groupData[month] = parseFloat((groupData[month] || 0) + sellAmount).toFixed(2)
}
})
// 排序取前n位
const finalData = Object.entries(groupData)
.map(([sellman, sellAmount]) => ({
sellman,
sellAmount
}))
.sort((a, b) => b.sellAmount - b.sellAmount)
.slice(0, 10)
// console.log('finalData', finalData)
return finalData
}
// todo 绘制 echarts 图表
const chartRef = ref()
const initChart = (data) => {
const myChart = echarts.init(chartRef.value)
const sellman = data.map(el => el.sellman)
const sellAmount = data.map(el => el.sellAmount)
const option = {
title: {
text: '子任务三:折线图展示 2023 年不同月份销售量变化',
left: 'center'
},
xAxis: {
type: 'category',
data: sellman,
// axisLabel:{
// rotate:26,
// }
},
yAxis: {
type: 'value',
name: '销售金额(元)'
},
tooltip: {
trigger: 'axis', // 触发类型
axisPointer: {
type: 'shadow', // 鼠标悬停时显示阴影
}
},
series: [{
name: '销售金额',
type: 'line',
smooth: true,
// 线下面渐变颜色
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#748ede51' },
{ offset: 1, color: '#748ede01' }
]),
},
data: sellAmount,
label: {
show: true,
position: 'top'
}
}]
}
myChart.setOption(option)
}
onMounted(() => {
const chartdata = processData(clothingSalesData)
console.log('chartdata', chartdata)
initChart(chartdata)
})
</script>
<style scoped>
.chart-container {
width: 700px;
height: 400px;
background-color: #f1f6ff;
/* 浅蓝灰色背景,柔和不抢眼 */
box-shadow: 0 0 8px 1px #748ede66;
/* 使用主色调的透明阴影 */
border-radius: 10px;
margin-left: 50px;
}
</style>
图像渲染效果呈现
折线图 LineMonthSell.vue
<template>
<div ref="chartRef" class="chart-container"></div>
</template>
<script setup>
// todo 子任务三:折线图展示 2023 年不同月份销售量变化
import { ref, onMounted } from 'vue'
import * as echarts from '../assets/echarts.js'
import clothingSalesData from '../data/clothing_sales_data.json'
const processData = (data) => {
// 按照 x轴的数据 分组
const groupData = {}
data.forEach(el => {
const sellAmount = Number(el.折后单价)
const month = new Date(el.交易时间).getMonth()
const year = new Date(el.交易时间).getFullYear()
if (year === 2023) {
/* toFixed(2) 将数字格式化为保留2位小数的字符串
parseFloat() 将字符串转回数字,这样可以继续进行数学运算 */
groupData[month] = parseFloat((groupData[month] || 0) + sellAmount).toFixed(2)
}
})
// 排序取前n位
const finalData = Object.entries(groupData)
.map(([sellman, sellAmount]) => ({
sellman,
sellAmount
}))
.sort((a, b) => b.sellAmount - b.sellAmount)
.slice(0, 10)
// console.log('finalData', finalData)
return finalData
}
// todo 绘制 echarts 图表
const chartRef = ref()
const initChart = (data) => {
const myChart = echarts.init(chartRef.value)
const sellman = data.map(el => el.sellman)
const sellAmount = data.map(el => el.sellAmount)
const option = {
title: {
text: '子任务三:折线图展示 2023 年不同月份销售量变化',
left: 'center'
},
xAxis: {
type: 'category',
data: sellman,
// axisLabel:{
// rotate:26,
// }
},
yAxis: {
type: 'value',
name: '销售金额(元)'
},
tooltip: {
trigger: 'axis', // 触发类型
axisPointer: {
type: 'shadow', // 鼠标悬停时显示阴影
}
},
series: [{
name: '销售金额',
type: 'line',
smooth: true,
// 线下面渐变颜色
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#748ede51' },
{ offset: 1, color: '#748ede01' }
]),
},
data: sellAmount,
label: {
show: true,
position: 'top'
}
}]
}
myChart.setOption(option)
}
onMounted(() => {
const chartdata = processData(clothingSalesData)
console.log('chartdata', chartdata)
initChart(chartdata)
})
</script>
<style scoped>
.chart-container {
width: 700px;
height: 400px;
background-color: #f1f6ff;
/* 浅蓝灰色背景,柔和不抢眼 */
box-shadow: 0 0 8px 1px #748ede66;
/* 使用主色调的透明阴影 */
border-radius: 10px;
margin-left: 50px;
}
</style>
饼状图
<template>
<div ref="chartRef" class="chart-container"></div>
</template>
<script setup>
// todo 饼状图展示2023-2024 年不同门店的销售金额
import { ref, onMounted } from 'vue'
import * as echarts from '../assets/echarts.js'
import clothingSalesData from '../data/clothing_sales_data.json'
const processData = (data) => {
// 按照 x轴的数据 分组
const groupData = {}
data.forEach(el => {
const shopName = el.门店名称
const sellAmount = Number(el.折后单价)
const year = new Date(el.交易时间).getFullYear()
if (year >= 2023 && year <= 2024) {
/* toFixed(2) 将数字格式化为保留2位小数的字符串
parseFloat() 将字符串转回数字,这样可以继续进行数学运算 */
groupData[shopName] = parseFloat((groupData[shopName] || 0) + sellAmount).toFixed(2)
}
})
// 排序取前n位
const finalData = Object.entries(groupData)
.map(([shopName, sellAmount]) => ({
name:shopName,
value:sellAmount
}))
.sort((a, b) => b.value - b.value)
.slice(0, 10)
// console.log('finalData', finalData)
return finalData
}
// todo 绘制 echarts 图表
const chartRef = ref()
const initChart = (processData) => {
const myChart = echarts.init(chartRef.value)
const option = {
title: {
text: '任务四、饼状图展示 2023-2024 年不同门店的销售金额',
left: 'center'
},
legend: {
orient: 'vertical',
left: 'left',
top: 'middle'
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} 元 ({d}%)'
},
series: [{
name: '销售数量',
type: 'pie',
data: processData,
radius: '50%',
// roseType: 'radius',
label: {
show: true,
formatter: ' {c} 元'
}
}]
}
myChart.setOption(option)
}
onMounted(() => {
const chartdata = processData(clothingSalesData)
console.log('chartdata', chartdata)
initChart(chartdata)
})
</script>
<style scoped>
.chart-container {
width: 700px;
height: 400px;
background-color: #f1f6ff;
/* 浅蓝灰色背景,柔和不抢眼 */
box-shadow: 0 0 8px 1px #748ede66;
/* 使用主色调的透明阴影 */
border-radius: 10px;
margin-left: 50px;
}
</style>
更多推荐
所有评论(0)