| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- <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">
- <div class="panel-title">
- <div class="icon-decorator">
- <span></span>
- <span></span>
- </div>
- 价值分布
- </div>
- <div ref="chartRef" class="flex-1 min-h-0"></div>
- </div>
- </template>
- <style lang="scss" scoped>
- @import url('@/styles/kb.scss');
- </style>
|