广东GZ033-任务E:数据可视化(15 分)
用柱状图展示销售金额最高的6 个月
编写Vue 工程代码, 读取虚拟机bigdata-spark 的/opt/data 目录下的 supermarket_visualization.csv,用柱状图展示2024 年销售金额最高的6 个月, 同时将用于图表展示的数据结构在vscode 终端中进行打印输出,将图表可视化 结果和vscode 终端打印结果分别截图并粘贴至物理机桌面【Release\任务E 提 交结果.docx】中对应的任务序号下。
展示结果:
解题思路:
查看supermarket_visualization.csv数据结构
查看表头:
bash
顾客编号,大类编码,大类名称,中类编码,中类名称,小类编码,小类名称,销售日期,商品编码,规格型号,商品类型,单位,销售数量,销售金额,商品单价,是否促销
筛选出要用的数据
html
// 1. 数据获取和处理
// 从public目录读取CSV文件
const response = await fetch('/supermarket_visualization.csv')
const csvData = await response.text()
// 解析CSV数据,跳过表头
const rows = csvData.trim().split('\n')
// 将CSV数据转换为结构化对象数组
const data = rows.slice(1).map(row => {
const columns = row.split(',')
const date = columns[7] // 获取销售日期
const [year, month] = date.split('/').map(Number) // 解析年月
return {
year, // 年份
month, // 月份
monthKey: `${year}/${month}`, // 年月组合键
amount: parseFloat(columns[13]), // 销售金额
}
})
筛选出2024年月份汇总销售额
html
// 2. 数据筛选和统计
// 筛选2024年数据并按月份汇总销售金额
const monthlyData = {}
data.filter(item => item.year === 2024).forEach(item => {
if (!monthlyData[item.monthKey]) {
monthlyData[item.monthKey] = 0
}
monthlyData[item.monthKey] += item.amount
})
将数据进行排序,选择销售额最高的6个月份
html
// 3. 数据排序和格式化
// 转换为数组并按销售金额降序排序,取前6个月
const sortedData = Object.entries(monthlyData)
.map(([monthKey, amount]) => ({
month: monthKey.split('/')[1] + '月', // 格式化月份显示
amount: Number(amount.toFixed(2)) // 保留2位小数
}))
.sort((a, b) => b.amount - a.amount)
.slice(0, 6)
然后数据展现
全部代码:
html
<template>
<!-- 图表容器 -->
<div id="salesChart" ref="chartRef" style="width: 800px; height: 400px;"></div>
</template>
<script>
// 导入ECharts库和Vue组合式API
import * as echarts from '@/assets/echarts.min.js'
import { onMounted, ref } from 'vue'
export default {
name: 'SalesBarChart',
setup() {
// 创建图表DOM引用
const chartRef = ref(null)
// 初始化图表的主函数
const initChart = async () => {
try {
// 1. 数据获取和处理
// 从public目录读取CSV文件
const response = await fetch('/supermarket_visualization.csv')
const csvData = await response.text()
// 解析CSV数据,跳过表头
const rows = csvData.trim().split('\n')
// 将CSV数据转换为结构化对象数组
const data = rows.slice(1).map(row => {
const columns = row.split(',')
const date = columns[7] // 获取销售日期
const [year, month] = date.split('/').map(Number) // 解析年月
return {
year, // 年份
month, // 月份
monthKey: `${year}/${month}`, // 年月组合键
amount: parseFloat(columns[13]), // 销售金额
// category: columns[2] // 商品类别
}
})
// 2. 数据筛选和统计
// 筛选2024年数据并按月份汇总销售金额
const monthlyData = {}
data.filter(item => item.year === 2024).forEach(item => {
if (!monthlyData[item.monthKey]) {
monthlyData[item.monthKey] = 0
}
monthlyData[item.monthKey] += item.amount
})
// 3. 数据排序和格式化
// 转换为数组并按销售金额降序排序,取前6个月
const sortedData = Object.entries(monthlyData)
.map(([monthKey, amount]) => ({
month: monthKey.split('/')[1] + '月', // 格式化月份显示
amount: Number(amount.toFixed(2)) // 保留2位小数
}))
.sort((a, b) => b.amount - a.amount)
.slice(0, 6)
// 准备图表所需的数据数组
const months = sortedData.map(item => item.month)
const amounts = sortedData.map(item => item.amount)
console.log('2024年销售金额最高的6个月:', months, amounts)
// 4. 图表初始化和渲染
// 等待DOM更新
await new Promise(resolve => setTimeout(resolve, 0))
// 获取图表容器
const chartDom = chartRef.value
if (!chartDom) {
throw new Error('图表容器不存在')
}
// 清理已存在的图表实例
echarts.dispose(chartDom)
// 创建新的图表实例
const myChart = echarts.init(chartDom)
// 5. 图表配置
const option = {
// 图表布局
grid: {
top: 50,
right: 30,
bottom: 50,
left: 60
},
// 标题
title: {
text: '2024年销售金额最高的6个月',
left: 'center'
},
// 提示框
tooltip: {
trigger: 'axis',
formatter: '{b}<br/>销售金额: ¥{c}'
},
// X轴配置
xAxis: {
type: 'category',
data: months,
axisLabel: {
interval: 0 // 显示所有标签
}
},
// Y轴配置
yAxis: {
type: 'value',
name: '销售金额(元)',
axisLabel: {
formatter: '¥{value}'
}
},
// 数据系列
series: [{
name: '销售金额',
type: 'bar',
data: amounts,
label: {
show: true,
position: 'top',
formatter: '¥{c}'
}
}]
}
// 应用图表配置
await myChart.setOption(option)
// 6. 响应式处理
// 添加窗口大小变化的自适应
window.addEventListener('resize', () => {
myChart.resize()
})
} catch (error) {
console.error('图表渲染失败:', error)
}
}
// 组件挂载时初始化图表
onMounted(() => {
initChart()
})
return {
chartRef
}
}
}
</script>
<style scoped>
/* 图表容器样式 */
#salesChart {
margin: 20px auto;
border: 1px solid #eee;
}
</style>