| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- <script lang="ts" setup>
- import * as echarts from 'echarts'
- import { ANIMATION, CHART_RENDERER, createTooltip, FONT_FAMILY, THEME } from '@/utils/kb'
- interface DeviceStatusItem {
- name: string
- value: number
- }
- const chartData: DeviceStatusItem[] = [
- {
- name: '正常',
- value: 269
- },
- {
- name: '带病运行',
- value: 1
- },
- {
- name: '故障',
- value: 6
- }
- ]
- const chartRef = ref<HTMLDivElement>()
- let chart: echarts.ECharts | null = null
- function getChartLayout() {
- const { clientWidth = 0, clientHeight = 0 } = chartRef.value ?? {}
- const compact = clientHeight > 0 && (clientHeight < 210 || clientWidth < 520)
- return {
- pieRadius: compact ? ['42%', '62%'] : ['48%', '68%'],
- pieCenterY: compact ? '50%' : '50%',
- legendBottom: compact ? 0 : 8,
- legendItemSize: compact ? 9 : 13,
- legendGap: compact ? 10 : 18,
- legendFontSize: compact ? 10 : 14
- }
- }
- function getChartOption(): echarts.EChartsOption {
- const layout = getChartLayout()
- return {
- ...ANIMATION,
- color: [THEME.color.blue.line, THEME.color.orange.line, THEME.color.red.line],
- tooltip: createTooltip({
- trigger: 'item',
- formatter(params: any) {
- return `${params.marker}${params.name}<br/>数量:${params.value} 台<br/>占比:${params.percent}%`
- }
- }),
- legend: {
- type: 'scroll',
- bottom: layout.legendBottom,
- left: 'center',
- itemWidth: layout.legendItemSize,
- itemHeight: layout.legendItemSize,
- itemGap: layout.legendGap,
- textStyle: {
- color: THEME.text.regular,
- fontSize: layout.legendFontSize,
- fontWeight: 600,
- fontFamily: FONT_FAMILY
- },
- formatter(name: string) {
- const item = chartData.find((status) => status.name === name)
- return item ? `${name} ${item.value}台` : name
- }
- },
- series: [
- {
- name: '设备状态',
- type: 'pie',
- radius: layout.pieRadius,
- center: ['50%', layout.pieCenterY],
- minAngle: 5,
- label: { show: false },
- data: chartData
- }
- ]
- }
- }
- function initChart() {
- if (!chartRef.value) return
- chart?.dispose()
- chart = echarts.init(chartRef.value, undefined, {
- renderer: CHART_RENDERER
- })
- renderChart()
- }
- function renderChart() {
- chart?.setOption(getChartOption(), true)
- }
- function resizeChart() {
- chart?.resize()
- renderChart()
- }
- function destroyChart() {
- chart?.dispose()
- chart = null
- }
- onMounted(() => {
- initChart()
- window.addEventListener('resize', resizeChart)
- window.addEventListener('rdkb:resize', resizeChart)
- })
- onUnmounted(() => {
- window.removeEventListener('resize', resizeChart)
- window.removeEventListener('rdkb:resize', resizeChart)
- destroyChart()
- })
- </script>
- <template>
- <div class="panel device-status-panel flex flex-col">
- <div class="panel-title">
- <div class="icon-decorator">
- <span></span>
- <span></span>
- </div>
- 设备状态
- </div>
- <div class="device-status-body">
- <div ref="chartRef" class="device-status-chart"></div>
- </div>
- </div>
- </template>
- <style lang="scss" scoped>
- @import url('@/styles/kb.scss');
- .device-status-panel {
- overflow: hidden;
- }
- .device-status-body {
- display: flex;
- min-height: 0;
- flex: 1;
- padding: calc(10px * var(--kb-scale, 1)) calc(16px * var(--kb-scale, 1))
- calc(14px * var(--kb-scale, 1));
- }
- .device-status-chart {
- min-height: 0;
- flex: 1;
- }
- </style>
|