Files
xh-medical-sign-web/clinical-web/src/views/management/reports/components/SignatureTrendChart.vue
2026-08-27 16:48:17 +08:00

115 lines
2.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { computed } from 'vue'
import type { ReportTrendPoint } from '../types'
const props = defineProps<{
points: ReportTrendPoint[]
}>()
const chartBars = computed(() => {
const width = 640
const height = 200
const paddingX = 30
const paddingY = 30
const slotWidth = (width - paddingX * 2) / Math.max(props.points.length, 1)
const barWidth = slotWidth * 0.55
const maxValue = Math.max(...props.points.map((point) => point.value), 3) * 1.2
return props.points.map((point, index) => {
const barHeight = (point.value / maxValue) * (height - paddingY * 2)
const x = paddingX + slotWidth * index + (slotWidth - barWidth) / 2
const y = height - paddingY - barHeight
return {
...point,
x,
y,
width: barWidth,
height: Math.max(barHeight, 2),
}
})
})
const gridLines = [0, 1, 2, 3].map((index) => 30 + ((200 - 60) / 3) * index)
</script>
<template>
<div v-if="points.length" class="chart-wrap">
<svg viewBox="0 0 640 200" role="img" aria-label="每日签署量趋势柱状图">
<defs>
<linearGradient id="report-bar-gradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#18a0c0" />
<stop offset="1" stop-color="#0e6e8c" />
</linearGradient>
</defs>
<line
v-for="line in gridLines"
:key="line"
x1="30"
:y1="line"
x2="610"
:y2="line"
stroke="#e6eef2"
stroke-dasharray="3 4"
/>
<g v-for="bar in chartBars" :key="bar.date">
<rect
:x="bar.x"
:y="bar.y"
:width="bar.width"
:height="bar.height"
rx="4"
:fill="bar.value ? 'url(#report-bar-gradient)' : '#e2ebef'"
>
<title>{{ bar.label }}{{ bar.value }} </title>
</rect>
<text
v-if="bar.value"
:x="bar.x + bar.width / 2"
:y="bar.y - 6"
text-anchor="middle"
font-size="10.5"
fill="#0a4f66"
font-weight="bold"
>
{{ bar.value }}
</text>
<text
:x="bar.x + bar.width / 2"
y="190"
text-anchor="middle"
font-size="9.5"
fill="#687f8b"
>
{{ bar.label }}
</text>
</g>
</svg>
</div>
<div v-else class="empty-chart">暂无趋势数据</div>
</template>
<style scoped>
.chart-wrap {
width: 100%;
min-height: 200px;
}
.chart-wrap svg {
display: block;
width: 100%;
height: auto;
}
.empty-chart {
display: grid;
min-height: 200px;
color: var(--mut);
font-size: 13px;
place-items: center;
}
</style>