2023-12-15 18:08:45 +08:00
|
|
|
<template>
|
|
|
|
|
<div class="chart-box">
|
|
|
|
|
<div class="date-btn text-color">
|
2023-12-21 17:31:28 +08:00
|
|
|
<div class="btn-box">
|
|
|
|
|
<el-icon @click="getData(upMonth)">
|
|
|
|
|
<ArrowLeft />
|
|
|
|
|
</el-icon>
|
|
|
|
|
<el-date-picker v-model="currentMonth" format="YYYY年MM月" type="month" :editable="false" :clearable="false" @change="getData" />
|
|
|
|
|
<el-icon @click="getData(downMonth)">
|
|
|
|
|
<ArrowRight />
|
|
|
|
|
</el-icon>
|
2023-12-15 18:08:45 +08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div ref="chartDom" class="chart-dom"></div>
|
2023-12-21 17:31:28 +08:00
|
|
|
<div class="total-mini">本月共计{{ total.toFixed(0) }}小时{{ Number((total % 1).toFixed(1)) * 60 }}分钟</div>
|
2023-12-15 18:08:45 +08:00
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script lang='ts' setup>
|
|
|
|
|
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
|
|
|
|
|
import * as echarts from 'echarts';
|
|
|
|
|
import { dateFormater, getMonthDays } from '@/utils/date-util';
|
|
|
|
|
|
|
|
|
|
const chartDom = ref()
|
|
|
|
|
|
|
|
|
|
const currentMonth = ref(new Date())
|
|
|
|
|
const upMonth = ref()
|
|
|
|
|
const downMonth = ref()
|
|
|
|
|
const total = ref(0)
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
getData(new Date())
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
function initChart(chartData: any) {
|
|
|
|
|
const chart = echarts.init(chartDom.value as HTMLElement);
|
|
|
|
|
chart.clear();
|
|
|
|
|
const option = {
|
|
|
|
|
color: [],
|
|
|
|
|
tooltip: {
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
formatter: (params: any) => {
|
|
|
|
|
return dateFormater('yyyy年MM月', currentMonth.value) + params[0].axisValue + '<br>手术时长 <b>' + params[0].value + '</b> h'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
grid: {
|
|
|
|
|
left: 20,
|
|
|
|
|
right: 50,
|
|
|
|
|
bottom: 5,
|
|
|
|
|
top: 50,
|
|
|
|
|
containLabel: true,
|
|
|
|
|
},
|
|
|
|
|
xAxis: {
|
|
|
|
|
name: '日期',
|
|
|
|
|
show: true,
|
|
|
|
|
type: 'category',
|
|
|
|
|
boundaryGap: false,
|
2023-12-21 17:31:28 +08:00
|
|
|
nameTextStyle: { color: '#909399' },
|
2023-12-15 18:08:45 +08:00
|
|
|
axisLine: { show: true, lineStyle: { color: '#D58301', width: 2 } },
|
|
|
|
|
axisTick: { show: false },
|
|
|
|
|
axisLabel: { show: true, interval: chartData.xData.length - 2 },
|
|
|
|
|
splitLine: { show: true, lineStyle: { color: 'rgba(212, 130, 1, .05)', width: 1, type: 'solid' } },
|
|
|
|
|
data: chartData.xData,
|
|
|
|
|
},
|
|
|
|
|
yAxis: {
|
2023-12-21 17:31:28 +08:00
|
|
|
name: '时间',
|
2023-12-15 18:08:45 +08:00
|
|
|
show: true,
|
|
|
|
|
type: 'value',
|
|
|
|
|
min: 0,
|
2023-12-21 17:31:28 +08:00
|
|
|
nameTextStyle: { color: '#909399', align: 'center', verticalAlign: 'top', padding: [0, 0] },
|
2023-12-15 18:08:45 +08:00
|
|
|
axisLine: { show: true, lineStyle: { color: '#D58301', width: 2 } },
|
|
|
|
|
axisTick: { show: false },
|
|
|
|
|
axisLabel: { show: false },
|
|
|
|
|
splitLine: { show: false, lineStyle: { color: '#D4E8F0', width: 1, type: 'solid' } },
|
|
|
|
|
},
|
|
|
|
|
series: [{
|
|
|
|
|
type: 'line',
|
|
|
|
|
symbol: 'none',
|
|
|
|
|
smooth: true,
|
|
|
|
|
showSymbol: false,
|
|
|
|
|
lineStyle: {
|
|
|
|
|
color: 'rgb(212, 130, 1)',
|
|
|
|
|
width: 2,
|
|
|
|
|
shadowColor: 'rgba(212, 130, 1, .3)',
|
|
|
|
|
shadowBlur: 10,
|
|
|
|
|
shadowOffsetY: 20
|
|
|
|
|
},
|
|
|
|
|
areaStyle: {
|
|
|
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
|
|
|
|
offset: 0,
|
|
|
|
|
color: 'rgba(212, 130, 1, 1)'
|
|
|
|
|
}, {
|
|
|
|
|
offset: 0.8,
|
|
|
|
|
color: 'rgba(255, 255, 255, 0.1)'
|
|
|
|
|
}], false)
|
|
|
|
|
},
|
|
|
|
|
data: chartData.data
|
|
|
|
|
}],
|
|
|
|
|
};
|
|
|
|
|
chart.setOption(option);
|
|
|
|
|
chart.resize();
|
|
|
|
|
window.addEventListener('resize', () => {
|
|
|
|
|
chart.resize();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getData = (date: any) => {
|
|
|
|
|
currentMonth.value = new Date(date)
|
|
|
|
|
upMonth.value = new Date(currentMonth.value.getFullYear(), currentMonth.value.getMonth() - 1, 1)
|
|
|
|
|
downMonth.value = new Date(currentMonth.value.getFullYear(), currentMonth.value.getMonth() + 1, 1)
|
|
|
|
|
const days = getMonthDays(currentMonth.value)
|
|
|
|
|
const xData = []
|
|
|
|
|
const data = []
|
|
|
|
|
let num = 0
|
|
|
|
|
for (let i = 0; i < days; i++) {
|
|
|
|
|
xData.push((i < 9 ? '0' : '') + (i + 1))
|
2023-12-21 17:31:28 +08:00
|
|
|
data.push(Number((Math.random() * 16 + 2).toFixed(1)))
|
2023-12-15 18:08:45 +08:00
|
|
|
num += data[i]
|
|
|
|
|
}
|
|
|
|
|
total.value = Number(num.toFixed(1))
|
|
|
|
|
initChart({ xData, data })
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang='scss' scoped>
|
2023-12-21 17:31:28 +08:00
|
|
|
.chart-box {
|
|
|
|
|
position: relative;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
|
|
.date-btn {
|
|
|
|
|
position: absolute;
|
|
|
|
|
height: 50px;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 20px;
|
|
|
|
|
right: 230px;
|
2023-12-15 18:08:45 +08:00
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
2023-12-21 17:31:28 +08:00
|
|
|
z-index: 1;
|
|
|
|
|
|
|
|
|
|
.btn-box {
|
|
|
|
|
height: 30px;
|
2023-12-15 18:08:45 +08:00
|
|
|
display: flex;
|
2023-12-21 17:31:28 +08:00
|
|
|
align-items: center;
|
|
|
|
|
color: $text2-color;
|
|
|
|
|
|
|
|
|
|
&>:deep(.el-date-editor) {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
.el-input__wrapper {
|
|
|
|
|
box-shadow: none;
|
|
|
|
|
padding: 0;
|
|
|
|
|
.el-input__prefix,
|
|
|
|
|
.el-input__suffix {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
.el-input__inner {
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
width: 100px;
|
|
|
|
|
color: $text2-color;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
2023-12-15 18:08:45 +08:00
|
|
|
}
|
|
|
|
|
}
|
2023-12-21 17:31:28 +08:00
|
|
|
|
|
|
|
|
.el-icon {
|
|
|
|
|
cursor: pointer;
|
2023-12-15 18:08:45 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-12-21 17:31:28 +08:00
|
|
|
|
|
|
|
|
.chart-dom {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.total-mini {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 0;
|
|
|
|
|
right: 40px;
|
|
|
|
|
color: #D58301;
|
|
|
|
|
border: 1px solid #D58301;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
padding: 3px 8px;
|
|
|
|
|
}
|
|
|
|
|
}</style>
|