|
|
@@ -1,4 +1,269 @@
|
|
|
-<script lang="ts" setup></script>
|
|
|
+<script lang="ts" setup>
|
|
|
+import * as echarts from 'echarts'
|
|
|
+import {
|
|
|
+ ANIMATION,
|
|
|
+ CHART_RENDERER,
|
|
|
+ createLegend,
|
|
|
+ createTooltip,
|
|
|
+ FONT_FAMILY,
|
|
|
+ THEME
|
|
|
+} from '@/utils/kb'
|
|
|
+
|
|
|
+interface ValueDistributionItem {
|
|
|
+ projectDept: string
|
|
|
+ originalValue: number
|
|
|
+ netValue: number
|
|
|
+}
|
|
|
+
|
|
|
+const chartData: ValueDistributionItem[] = [
|
|
|
+ {
|
|
|
+ projectDept: '公摊',
|
|
|
+ originalValue: 2760.06,
|
|
|
+ netValue: 622.61
|
|
|
+ },
|
|
|
+ {
|
|
|
+ projectDept: '新疆',
|
|
|
+ originalValue: 3051.49,
|
|
|
+ netValue: 920.62
|
|
|
+ },
|
|
|
+ {
|
|
|
+ projectDept: '青海',
|
|
|
+ originalValue: 10038.67,
|
|
|
+ netValue: 3388.01
|
|
|
+ },
|
|
|
+ {
|
|
|
+ projectDept: '东部',
|
|
|
+ originalValue: 6060.15,
|
|
|
+ netValue: 881.46
|
|
|
+ },
|
|
|
+ {
|
|
|
+ projectDept: '西南连油',
|
|
|
+ originalValue: 4059.36,
|
|
|
+ netValue: 743.24
|
|
|
+ },
|
|
|
+ {
|
|
|
+ projectDept: '西南压裂',
|
|
|
+ originalValue: 11557.18,
|
|
|
+ netValue: 4401.63
|
|
|
+ },
|
|
|
+ {
|
|
|
+ projectDept: '伊拉克',
|
|
|
+ originalValue: 15417.01,
|
|
|
+ netValue: 6318.24
|
|
|
+ },
|
|
|
+ {
|
|
|
+ projectDept: '利比亚',
|
|
|
+ originalValue: 1942.14,
|
|
|
+ netValue: 1700.17
|
|
|
+ }
|
|
|
+]
|
|
|
+
|
|
|
+const chartRef = ref<HTMLDivElement>()
|
|
|
+let chart: echarts.ECharts | null = null
|
|
|
+const BAR_WIDTH = 22
|
|
|
+const LABEL_FONT_SIZE = 13
|
|
|
+
|
|
|
+function getBarStyle(color: (typeof THEME.color)[keyof typeof THEME.color]) {
|
|
|
+ return {
|
|
|
+ borderRadius: [12, 12, 0, 0],
|
|
|
+ shadowBlur: 12,
|
|
|
+ shadowColor: color.bg,
|
|
|
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
+ { offset: 0, color: color.light },
|
|
|
+ { offset: 0.55, color: color.mid },
|
|
|
+ { offset: 1, color: color.line }
|
|
|
+ ])
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function formatMoney(value: number | string) {
|
|
|
+ return Number(value || 0).toLocaleString('en-US', {
|
|
|
+ minimumFractionDigits: 2,
|
|
|
+ maximumFractionDigits: 2
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function formatProjectDept(value: string) {
|
|
|
+ if (value.length <= 5) return value
|
|
|
+ return value.replace('项目部', '\n项目部').replace('折算RMB', '\n折算RMB')
|
|
|
+}
|
|
|
+
|
|
|
+function getChartOption(data: ValueDistributionItem[]): echarts.EChartsOption {
|
|
|
+ const projectDepts = data.map((item) => item.projectDept)
|
|
|
+
|
|
|
+ return {
|
|
|
+ ...ANIMATION,
|
|
|
+ grid: {
|
|
|
+ ...THEME.grid,
|
|
|
+ top: 58,
|
|
|
+ right: 20,
|
|
|
+ bottom: 4
|
|
|
+ },
|
|
|
+ tooltip: createTooltip({
|
|
|
+ trigger: 'axis',
|
|
|
+ axisPointer: {
|
|
|
+ type: 'shadow',
|
|
|
+ shadowStyle: {
|
|
|
+ color: THEME.split
|
|
|
+ }
|
|
|
+ },
|
|
|
+ valueFormatter(value: number | string) {
|
|
|
+ return `${formatMoney(value)} 万元`
|
|
|
+ }
|
|
|
+ }),
|
|
|
+ legend: createLegend(
|
|
|
+ {
|
|
|
+ top: 4,
|
|
|
+ itemWidth: 12,
|
|
|
+ itemHeight: 12
|
|
|
+ },
|
|
|
+ ['原值', '净值']
|
|
|
+ ),
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ data: projectDepts,
|
|
|
+ axisLine: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ axisTick: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ axisLabel: {
|
|
|
+ interval: 0,
|
|
|
+ color: THEME.text.regular,
|
|
|
+ fontSize: 12,
|
|
|
+ fontFamily: FONT_FAMILY,
|
|
|
+ formatter(value: string) {
|
|
|
+ return formatProjectDept(value)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'value',
|
|
|
+ name: '价值(万元)',
|
|
|
+ splitNumber: 4,
|
|
|
+ nameTextStyle: {
|
|
|
+ color: THEME.text.regular,
|
|
|
+ fontSize: 13,
|
|
|
+ fontFamily: FONT_FAMILY
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ axisTick: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ axisLabel: {
|
|
|
+ color: THEME.text.regular,
|
|
|
+ fontSize: 12,
|
|
|
+ fontFamily: FONT_FAMILY,
|
|
|
+ formatter(value: number) {
|
|
|
+ return formatMoney(value)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: THEME.split,
|
|
|
+ type: 'dashed'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '原值',
|
|
|
+ type: 'bar',
|
|
|
+ data: data.map((item) => item.originalValue),
|
|
|
+ barWidth: BAR_WIDTH,
|
|
|
+ barMaxWidth: 28,
|
|
|
+ barGap: '18%',
|
|
|
+ itemStyle: getBarStyle(THEME.color.blue),
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: 'top',
|
|
|
+ distance: 10,
|
|
|
+ color: THEME.color.blue.strong,
|
|
|
+ fontSize: LABEL_FONT_SIZE,
|
|
|
+ fontWeight: 700,
|
|
|
+ fontFamily: FONT_FAMILY,
|
|
|
+ formatter(params: any) {
|
|
|
+ return Number(params.value) ? formatMoney(params.value) : ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ focus: 'series',
|
|
|
+ itemStyle: {
|
|
|
+ ...getBarStyle(THEME.color.blue),
|
|
|
+ shadowColor: THEME.color.blue.shadow,
|
|
|
+ shadowBlur: 18
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '净值',
|
|
|
+ type: 'bar',
|
|
|
+ data: data.map((item) => item.netValue),
|
|
|
+ barWidth: BAR_WIDTH,
|
|
|
+ barMaxWidth: 28,
|
|
|
+ itemStyle: getBarStyle(THEME.color.green),
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: 'top',
|
|
|
+ distance: 6,
|
|
|
+ color: THEME.color.green.strong,
|
|
|
+ fontSize: LABEL_FONT_SIZE,
|
|
|
+ fontWeight: 700,
|
|
|
+ fontFamily: FONT_FAMILY,
|
|
|
+ formatter(params: any) {
|
|
|
+ return Number(params.value) ? formatMoney(params.value) : ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ focus: 'series',
|
|
|
+ itemStyle: {
|
|
|
+ ...getBarStyle(THEME.color.green),
|
|
|
+ shadowColor: THEME.color.green.shadow,
|
|
|
+ shadowBlur: 18
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function initChart() {
|
|
|
+ if (!chartRef.value) return
|
|
|
+ chart?.dispose()
|
|
|
+ chart = echarts.init(chartRef.value, undefined, {
|
|
|
+ renderer: CHART_RENDERER
|
|
|
+ })
|
|
|
+ renderChart()
|
|
|
+}
|
|
|
+
|
|
|
+function renderChart() {
|
|
|
+ chart?.setOption(getChartOption(chartData), true)
|
|
|
+}
|
|
|
+
|
|
|
+function resizeChart() {
|
|
|
+ chart?.resize()
|
|
|
+}
|
|
|
+
|
|
|
+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 flex flex-col">
|