echarts记录(柱状、折线、环形饼图,双柱,日期组件封装)
涉及到日期组件封装,echarts柱状图、折线图、饼图(环形)的绘制,
1.柱状+折线图的option配置
//数据接入统计图表
const initAccessChat = () => {
accessChartDom = echarts.init(accessChartEl.value)
const accessOption = {
grid: {
left: '1%',
right: '1%',
bottom: '1%',
top: '20%',
containLabel: true,
},
legend: {
itemHeight: 12,
itemWidth: 12,
itemGap: 30, // 图例元素间隔
icon: 'rect', //方形
top: '5%',
data: ['路口', '智慧车辆'],
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(255,255,255,0.65)', //设置自定义背景
confine: true,
extraCssText:
//额外附加到浮层的css样式,此处为为浮层添加阴影及padding
'box-shadow: 0px 2px 12px 0px rgba(0,0,0,0.2)',
},
xAxis: [
{
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
axisPointer: {
type: 'shadow',
},
},
],
yAxis: {
type: 'value',
},
series: [
{
name: '路口',
type: 'bar',
barWidth: 16,
itemStyle: {
// 添加 itemStyle
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// 渐变方向:从上到下
{ offset: 0, color: '#0EECE4' }, // 顶部颜色
{ offset: 1, color: '#058FE7' }, // 底部颜色
]),
},
data: [110, 50, 220, 200, 135, 135, 135],
},
{
name: '智慧车辆',
type: 'line',
symbol: 'none',
itemStyle: {
color: '#FFD15C', // 明确指定系列颜色
},
lineStyle: {
color: '#FFD15C',
width: 3,
},
data: [110, 50, 220, 200, 135, 135, 135],
},
],
}
accessChartDom.setOption(accessOption)
}
2.需要绘制出圆弧渐变的线条,主要通过lineStyle去修改渐变由浅入深以及线条下方的阴影控制
const initDelChat = () => {
delChartDom = echarts.init(delChartEl.value)
const delOption = {
grid: {
left: '1%',
right: '1%',
bottom: '1%',
top: '20%',
containLabel: true,
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(255,255,255,0.65)', //设置自定义背景
confine: true,
extraCssText:
//额外附加到浮层的css样式,此处为为浮层添加阴影及padding
'box-shadow: 0px 2px 12px 0px rgba(0,0,0,0.2)',
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
legend: {
itemHeight: 12,
itemWidth: 12,
itemGap: 30, // 图例元素间隔
icon: 'rect', //方形
top: '5%',
data: ['日志', '视频', '图片', '轨迹数据'],
},
series: [
{
name: '日志',
type: 'line',
smooth: true,
symbol: 'none',
data: [120, 132, 101, 134, 90, 230, 210],
itemStyle: {
color: '#FEB729', // 明确指定系列颜色
},
lineStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
// 渐变方向:从左到右
{ offset: 0, color: 'rgba(255,255,255,0.5)' },
{ offset: 0.2, color: '#FEB729' },
{ offset: 1, color: '#FEB729' },
]),
shadowColor: '#FEB729', // 阴影颜色
shadowBlur: 8, // 阴影模糊程度
shadowOffsetY: 2.5, //阴影向下偏移
},
},
{
name: '视频',
type: 'line',
smooth: true,
symbol: 'none',
data: [220, 182, 191, 234, 290, 330, 310],
itemStyle: {
color: '#4B85FF',
},
lineStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: 'rgba(255,255,255,0.5)' },
{ offset: 0.2, color: '#4B85FF' },
{ offset: 1, color: '#4B85FF' },
]),
shadowColor: '#4B85FF',
shadowBlur: 8,
shadowOffsetY: 2.5,
},
},
{
name: '图片',
type: 'line',
smooth: true,
symbol: 'none',
data: [150, 232, 201, 154, 190, 330, 410],
itemStyle: {
color: '#F2465E',
},
lineStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: 'rgba(255,255,255,0.5)' },
{ offset: 0.2, color: '#F2465E' },
{ offset: 1, color: '#F2465E' },
]),
shadowColor: '#F2465E',
shadowBlur: 8,
shadowOffsetY: 2.5,
},
},
{
name: '轨迹数据',
type: 'line',
smooth: true,
symbol: 'none',
data: [320, 332, 301, 334, 390, 330, 320],
itemStyle: {
color: '#57CC9B',
},
lineStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: 'rgba(255,255,255,0.5)' },
{ offset: 0.2, color: '#57CC9B' },
{ offset: 1, color: '#57CC9B' },
]),
shadowColor: '#57CC9B',
shadowBlur: 8,
shadowOffsetY: 2.5,
},
},
],
// ],
}
delChartDom.setOption(delOption)
}
3.饼图,主要是右半边的legend自定义字段,以及自定义字体样式
//仓库存储统计图表
const initStorageChat = () => {
storageChartDom = echarts.init(storageChartEl.value)
const storageOption = {
title: {
text: '4500',
subtext: '数据总量',
left: '34%',
top: '40%',
textAlign: 'center',
textStyle: {
fontSize: 30,
color: '#333',
},
subtextStyle: {
fontSize: 14,
color: '#333',
},
itemGap: 5, //标题间距
},
legend: {
x: 'right',
orient: 'vertical',
align: 'left',
left: '55%',
top: '20%',
itemHeight: 16,
itemWidth: 16,
itemGap: 25, // 图例元素间隔
icon: 'rect', //方形
data: ['日志', '视频', '图片', '轨迹数据'],
formatter: name => {
const data = storageOption.series[0].data
const item = data.find(item => item.name === name)
if (item) {
const total = data.reduce((sum, item) => sum + item.value, 0)
const percentage = ((item.value / total) * 100).toFixed(2)
let arr = ['{name|' + item.name + '}', '{value|' + item.value + '}', '{percentage|' + percentage + '%}']
return arr.join(' ')
} else {
return name
}
},
textStyle: {
rich: {
name: {
padding: [0, 0, 0, 6],
width: 80,
},
value: {
fontSize: 20,
width: 70,
color: '#333',
align: 'center',
},
percentage: {
fontSize: 20,
align: 'center',
},
},
},
},
series: [
{
type: 'pie',
// right: '50%',
center: ['35%', '50%'],
radius: ['58%', '80%'], // 设置饼图内外半径
avoidLabelOverlap: false,
label: {
show: false, // 不显示标签
},
labelLine: {
show: false,
},
data: [
{
value: 1048,
name: '日志',
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
// 从左到右渐变
{ offset: 0, color: '#5A96FF' },
{ offset: 1, color: '#26D5FD' },
]),
},
},
{
value: 735,
name: '视频',
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: '#FBDA37' },
{ offset: 1, color: '#F95145' },
]),
},
},
{
value: 580,
name: '图片',
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: '#2CD57E' },
{ offset: 1, color: '#27F1C2' },
]),
},
},
{
value: 484,
name: '轨迹数据',
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: '#FA8A56' },
{ offset: 1, color: '#F94564' },
]),
},
},
],
// 饼图的阴影效果
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.2)',
borderRadius: 0, // 设置圆角半径为 10px
borderWidth: 0, // 去除扇形之间的边框
},
// 饼图的hover效果
emphasis: {
itemStyle: {
borderWidth: 2, // 设置边框宽度
borderColor: '#FFFFFF', // 设置边框颜色
},
},
},
],
}
storageChartDom.setOption(storageOption)
}
4.这个就没什么难度了,直接上代码
//数据应用统计图表
const initApplyChat = () => {
applyChartDom = echarts.init(applyChartEl.value)
const applyOption = {
grid: {
left: '1%',
right: '1%',
bottom: '1%',
top: '20%',
containLabel: true,
},
legend: {
itemHeight: 12,
itemWidth: 12,
itemGap: 30, // 图例元素间隔
icon: 'rect', //方形
top: '5%',
data: ['路口', '车辆'],
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(255,255,255,0.65)', //设置自定义背景
confine: true,
extraCssText:
//额外附加到浮层的css样式,此处为为浮层添加阴影及padding
'box-shadow: 0px 2px 12px 0px rgba(0,0,0,0.2)',
},
xAxis: [
{
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
axisPointer: {
type: 'shadow',
},
},
],
yAxis: [
{
type: 'value',
},
],
series: [
{
name: '路口',
type: 'bar',
barWidth: 16,
itemStyle: {
// 添加 itemStyle
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// 渐变方向:从上到下
{ offset: 0, color: '#FBDA37' }, // 顶部颜色
{ offset: 1, color: '#F94564' }, // 底部颜色
]),
},
data: [220, 182, 191, 234, 290, 330, 310],
},
{
name: '车辆',
type: 'bar',
barWidth: 16,
itemStyle: {
// 添加 itemStyle
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// 渐变方向:从上到下
{ offset: 0, color: '#0EECE4' }, // 顶部颜色
{ offset: 1, color: '#058FE7' }, // 底部颜色
]),
},
data: [320, 332, 301, 334, 390, 330, 320],
},
],
}
applyChartDom.setOption(applyOption)
}
完整代码,包含布局样式
<template>
<div class="commmon-container data-overview">
<!-- 上方数据统计显示 -->
<div class="search_container total-card">
----省略上方其他代码
</div>
<div class="table_container chart-container">
<div class="chart-item">
<TimePicker
title="近一周数据接入统计"
@time-range-change="handleTimeRangeChange1"
></TimePicker>
<div
class="echarts-style"
ref="accessChartEl"
></div>
</div>
<div class="chart-item">
<TimePicker
title="近一月数据处理统计"
@time-range-change="handleTimeRangeChange2"
></TimePicker>
<div
class="echarts-style"
ref="delChartEl"
></div>
</div>
<div class="chart-item">
<TimePicker @time-range-change="handleTimeRangeChange3">
<template #title>
<a-select
ref="select"
v-model:value="stashName"
style="width: 164px"
>
<a-select-option value="jack">Jack</a-select-option>
<a-select-option value="lucy">Lucy</a-select-option>
<a-select-option value="Yiminghe">yiminghe</a-select-option>
</a-select>
</template>
</TimePicker>
<div
class="echarts-style"
ref="storageChartEl"
></div>
</div>
<div class="chart-item">
<TimePicker
title="近一周数据应用统计"
@time-range-change="handleTimeRangeChange4"
></TimePicker>
<div
class="echarts-style"
ref="applyChartEl"
></div>
</div>
</div>
</div>
</template>
<script setup>
import { onMounted, reactive, ref, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { SettingFilled } from '@ant-design/icons-vue'
import accessBack from '@/assets/dataManage/access_back.png'
import delBack from '@/assets/dataManage/del_back.png'
import storageBack from '@/assets/dataManage/storage_back.png'
import applyBack from '@/assets/dataManage/apply_back.png'
import TimePicker from './components/timePicker.vue'
import * as echarts from 'echarts'
const router = useRouter()
const stashName = ref('') //仓库名称
//时间选择
const handleTimeRangeChange1 = timeRange => {
console.log('选择的时间段1:', timeRange)
}
const handleTimeRangeChange2 = timeRange => {
console.log('选择的时间段2:', timeRange)
}
const handleTimeRangeChange3 = timeRange => {
console.log('选择的时间段3:', timeRange)
}
const handleTimeRangeChange4 = timeRange => {
console.log('选择的时间段4:', timeRange)
}
//图表
const delChartEl = ref(null) //数据处理
const accessChartEl = ref(null) //数据接入
const storageChartEl = ref(null) //仓库
const applyChartEl = ref(null) //数据应用
let delChartDom = null
let accessChartDom = null
let storageChartDom = null
let applyChartDom = null
//数据接入统计图表
const initAccessChat = () => {
accessChartDom = echarts.init(accessChartEl.value)
const accessOption = {
grid: {
left: '1%',
right: '1%',
bottom: '1%',
top: '20%',
containLabel: true,
},
legend: {
itemHeight: 12,
itemWidth: 12,
itemGap: 30, // 图例元素间隔
icon: 'rect', //方形
top: '5%',
data: ['路口', '智慧车辆'],
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(255,255,255,0.65)', //设置自定义背景
confine: true,
extraCssText:
//额外附加到浮层的css样式,此处为为浮层添加阴影及padding
'box-shadow: 0px 2px 12px 0px rgba(0,0,0,0.2)',
},
xAxis: [
{
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
axisPointer: {
type: 'shadow',
},
},
],
yAxis: {
type: 'value',
},
series: [
{
name: '路口',
type: 'bar',
barWidth: 16,
itemStyle: {
// 添加 itemStyle
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// 渐变方向:从上到下
{ offset: 0, color: '#0EECE4' }, // 顶部颜色
{ offset: 1, color: '#058FE7' }, // 底部颜色
]),
},
data: [110, 50, 220, 200, 135, 135, 135],
},
{
name: '智慧车辆',
type: 'line',
symbol: 'none',
itemStyle: {
color: '#FFD15C', // 明确指定系列颜色
},
lineStyle: {
color: '#FFD15C',
width: 3,
},
data: [110, 50, 220, 200, 135, 135, 135],
},
],
}
accessChartDom.setOption(accessOption)
}
// 数据处理统计图表
const initDelChat = () => {
delChartDom = echarts.init(delChartEl.value)
const delOption = {
grid: {
left: '1%',
right: '1%',
bottom: '1%',
top: '20%',
containLabel: true,
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(255,255,255,0.65)', //设置自定义背景
confine: true,
extraCssText:
//额外附加到浮层的css样式,此处为为浮层添加阴影及padding
'box-shadow: 0px 2px 12px 0px rgba(0,0,0,0.2)',
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
legend: {
itemHeight: 12,
itemWidth: 12,
itemGap: 30, // 图例元素间隔
icon: 'rect', //方形
top: '5%',
data: ['日志', '视频', '图片', '轨迹数据'],
},
series: [
{
name: '日志',
type: 'line',
smooth: true,
symbol: 'none',
data: [120, 132, 101, 134, 90, 230, 210],
itemStyle: {
color: '#FEB729', // 明确指定系列颜色
},
lineStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
// 渐变方向:从左到右
{ offset: 0, color: 'rgba(255,255,255,0.5)' },
{ offset: 0.2, color: '#FEB729' },
{ offset: 1, color: '#FEB729' },
]),
shadowColor: '#FEB729', // 阴影颜色
shadowBlur: 8, // 阴影模糊程度
shadowOffsetY: 2.5, //阴影向下偏移
},
},
{
name: '视频',
type: 'line',
smooth: true,
symbol: 'none',
data: [220, 182, 191, 234, 290, 330, 310],
itemStyle: {
color: '#4B85FF',
},
lineStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: 'rgba(255,255,255,0.5)' },
{ offset: 0.2, color: '#4B85FF' },
{ offset: 1, color: '#4B85FF' },
]),
shadowColor: '#4B85FF',
shadowBlur: 8,
shadowOffsetY: 2.5,
},
},
{
name: '图片',
type: 'line',
smooth: true,
symbol: 'none',
data: [150, 232, 201, 154, 190, 330, 410],
itemStyle: {
color: '#F2465E',
},
lineStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: 'rgba(255,255,255,0.5)' },
{ offset: 0.2, color: '#F2465E' },
{ offset: 1, color: '#F2465E' },
]),
shadowColor: '#F2465E',
shadowBlur: 8,
shadowOffsetY: 2.5,
},
},
{
name: '轨迹数据',
type: 'line',
smooth: true,
symbol: 'none',
data: [320, 332, 301, 334, 390, 330, 320],
itemStyle: {
color: '#57CC9B',
},
lineStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: 'rgba(255,255,255,0.5)' },
{ offset: 0.2, color: '#57CC9B' },
{ offset: 1, color: '#57CC9B' },
]),
shadowColor: '#57CC9B',
shadowBlur: 8,
shadowOffsetY: 2.5,
},
},
],
// ],
}
delChartDom.setOption(delOption)
}
//仓库存储统计图表
const initStorageChat = () => {
storageChartDom = echarts.init(storageChartEl.value)
const storageOption = {
title: {
text: '4500',
subtext: '数据总量',
left: '34%',
top: '40%',
textAlign: 'center',
textStyle: {
fontSize: 30,
color: '#333',
},
subtextStyle: {
fontSize: 14,
color: '#333',
},
itemGap: 5, //标题间距
},
legend: {
x: 'right',
orient: 'vertical',
align: 'left',
left: '55%',
top: '20%',
itemHeight: 16,
itemWidth: 16,
itemGap: 25, // 图例元素间隔
icon: 'rect', //方形
data: ['日志', '视频', '图片', '轨迹数据'],
formatter: name => {
const data = storageOption.series[0].data
const item = data.find(item => item.name === name)
if (item) {
const total = data.reduce((sum, item) => sum + item.value, 0)
const percentage = ((item.value / total) * 100).toFixed(2)
let arr = ['{name|' + item.name + '}', '{value|' + item.value + '}', '{percentage|' + percentage + '%}']
return arr.join(' ')
} else {
return name
}
},
textStyle: {
rich: {
name: {
padding: [0, 0, 0, 6],
width: 80,
},
value: {
fontSize: 20,
width: 70,
color: '#333',
align: 'center',
},
percentage: {
fontSize: 20,
align: 'center',
},
},
},
},
series: [
{
type: 'pie',
// right: '50%',
center: ['35%', '50%'],
radius: ['58%', '80%'], // 设置饼图内外半径
avoidLabelOverlap: false,
label: {
show: false, // 不显示标签
},
labelLine: {
show: false,
},
data: [
{
value: 1048,
name: '日志',
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
// 从左到右渐变
{ offset: 0, color: '#5A96FF' },
{ offset: 1, color: '#26D5FD' },
]),
},
},
{
value: 735,
name: '视频',
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: '#FBDA37' },
{ offset: 1, color: '#F95145' },
]),
},
},
{
value: 580,
name: '图片',
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: '#2CD57E' },
{ offset: 1, color: '#27F1C2' },
]),
},
},
{
value: 484,
name: '轨迹数据',
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: '#FA8A56' },
{ offset: 1, color: '#F94564' },
]),
},
},
],
// 饼图的阴影效果
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.2)',
borderRadius: 0, // 设置圆角半径为 10px
borderWidth: 0, // 去除扇形之间的边框
},
// 饼图的hover效果
emphasis: {
// scale: 0.3,
itemStyle: {
borderWidth: 2, // 设置边框宽度
borderColor: '#FFFFFF', // 设置边框颜色
},
// itemStyle: {
// margin:'0 10px'
// },
},
},
],
}
storageChartDom.setOption(storageOption)
}
//数据应用统计图表
const initApplyChat = () => {
applyChartDom = echarts.init(applyChartEl.value)
const applyOption = {
grid: {
left: '1%',
right: '1%',
bottom: '1%',
top: '20%',
containLabel: true,
},
legend: {
itemHeight: 12,
itemWidth: 12,
itemGap: 30, // 图例元素间隔
icon: 'rect', //方形
top: '5%',
data: ['路口', '车辆'],
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(255,255,255,0.65)', //设置自定义背景
confine: true,
extraCssText:
//额外附加到浮层的css样式,此处为为浮层添加阴影及padding
'box-shadow: 0px 2px 12px 0px rgba(0,0,0,0.2)',
},
xAxis: [
{
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
axisPointer: {
type: 'shadow',
},
},
],
yAxis: [
{
type: 'value',
},
],
series: [
{
name: '路口',
type: 'bar',
barWidth: 16,
itemStyle: {
// 添加 itemStyle
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// 渐变方向:从上到下
{ offset: 0, color: '#FBDA37' }, // 顶部颜色
{ offset: 1, color: '#F94564' }, // 底部颜色
]),
},
data: [220, 182, 191, 234, 290, 330, 310],
},
{
name: '车辆',
type: 'bar',
barWidth: 16,
itemStyle: {
// 添加 itemStyle
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// 渐变方向:从上到下
{ offset: 0, color: '#0EECE4' }, // 顶部颜色
{ offset: 1, color: '#058FE7' }, // 底部颜色
]),
},
data: [320, 332, 301, 334, 390, 330, 320],
},
],
}
applyChartDom.setOption(applyOption)
}
//数据统计展示
const totalData = ref([
{ label: '数据接入', value: 201, backImg: accessBack },
{ label: '数据处理', value: 202, backImg: delBack },
{ label: '仓库存储', value: 203, hasBtn: true, backImg: storageBack },
{ label: '应用统计', value: 204, backImg: applyBack },
])
//仓库管理
const goStashManage = () => {
router.push({
path: '/dataManage/stashManage',
})
}
const handleResize = () => {
// 调整图表尺寸
delChartDom.resize()
accessChartDom.resize()
storageChartDom.resize()
applyChartDom.resize()
}
onMounted(() => {
initDelChat()
initAccessChat()
initStorageChat()
initApplyChat()
window.addEventListener('resize', handleResize) // 监听 resize 事件
})
onUnmounted(() => {
window.removeEventListener('resize', handleResize) // 移除 resize 事件监听
// 组件卸载时销毁图表实例
delChartDom.dispose()
accessChartDom.dispose()
storageChartDom.dispose()
applyChartDom.dispose()
})
</script>
<style lang="less" scoped>
@import '@/style/public.less';
.custom-btn-manage {
margin-left: 16px;
border: none;
padding: 6px 12px;
}
.data-overview {
display: flex;
flex-direction: column;
background-color: #f5f5f5;
}
.total-card {
display: flex;
justify-content: space-between;
.card-item {
width: calc(25% - 20px);
height: 126px;
display: flex;
flex-direction: column;
align-items: flex-start;
border-radius: 8px;
padding: 24px;
color: #ffffff;
justify-content: space-between;
background-repeat: no-repeat;
background-size: cover;
background-position: right;
.label {
font-size: 18px;
font-weight: 400;
}
.number {
font-size: 32px;
font-weight: 500;
}
}
}
.chart-container {
flex: 1;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.chart-item {
width: calc(50% - 10px);
height: calc(50% - 20px);
display: flex;
padding: 16px;
background-color: #fff;
border-radius: 8px;
flex-direction: column;
.echarts-style {
flex: 1;
}
}
}
</style>
另外附上TimePicker组件封装的代码,其实我封装得不太好,但是懒得优化了
<template>
<div class="total-top">
<div
v-if="title !== ''"
class="total-title"
>
{{ title }}
</div>
<slot name="title"></slot>
<div class="time-options">
<div
class="time-item"
v-for="item in timeOptions"
:key="item.label"
:class="{ active: currentTime === item.label }"
@click="getTimeRange(item)"
>
{{ item.label }}
</div>
<a-range-picker
v-model:value="timeValue"
valueFormat="YYYY-MM-DD"
style="margin-left: 12px"
@change="getTimeRange"
/>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import dayjs from 'dayjs'
const props = defineProps({
//标题
title: {
type: String,
default: '',
},
})
const currentTime = ref('今日') //默认时间
const timeOptions = ref([
{
label: '今日',
time: [dayjs().startOf('day').format('YYYY-MM-DD'), dayjs().endOf('day').format('YYYY-MM-DD')],
},
{
label: '本周',
time: [dayjs().startOf('week').format('YYYY-MM-DD'), dayjs().endOf('week').format('YYYY-MM-DD')],
},
{
label: '本月',
time: [dayjs().startOf('month').format('YYYY-MM-DD'), dayjs().endOf('month').format('YYYY-MM-DD')],
},
])
const timeValue = ref()
const emit = defineEmits(['time-range-change'])
// 点击默认时间选项和时间选择器都调用此方法
const getTimeRange = item => {
if (item && item.label) {
currentTime.value = item.label
timeValue.value = item.time
} else {
currentTime.value = ''
}
emit('time-range-change', timeValue.value)
}
onMounted(() => {
getTimeRange(timeOptions.value[0]) // 默认显示今日
})
</script>
<style lang="less" scoped>
.total-top {
display: flex;
align-items: center;
width: 100%;
justify-content: space-between;
.total-title {
font-weight: bold;
font-size: 18px;
color: #333;
&::before {
content: '';
display: inline-block;
width: 8px;
height: 16px;
background-color: #0084f6;
margin-right: 12px;
border-radius: 9px 9px 9px 9px;
}
}
.time-options {
display: flex;
.time-item {
padding: 6px 12px;
background-color: #f5f5f5;
border-radius: 24px;
margin: 0 6px;
cursor: pointer;
}
.active {
background-color: #0084f6;
color: #fff;
}
}
}
</style>