|
|
@@ -1,9 +1,410 @@
|
|
|
-import React from 'react'
|
|
|
+import React, { useCallback, useEffect } from 'react'
|
|
|
import styles from './index.module.scss'
|
|
|
+import { Select } from 'antd'
|
|
|
+import { iconUrl } from '@/utils/http'
|
|
|
+import * as echarts from 'echarts'
|
|
|
+
|
|
|
+const chartData1 = [
|
|
|
+ { name: '啤酒产品类', value: 2500, percentage: '10%' },
|
|
|
+ { name: '饮用器皿类', value: 1800, percentage: '5%' },
|
|
|
+ { name: '品牌文化与节庆类', value: 1200, percentage: '2%' },
|
|
|
+ { name: '企业文化与档案类', value: 800, percentage: '3%' },
|
|
|
+ { name: '艺术与礼品类', value: 1000, percentage: '10%' },
|
|
|
+ { name: '工具与设备类', value: 900, percentage: '5%' },
|
|
|
+ { name: '其他综合类', value: 2500, percentage: '10%' }
|
|
|
+]
|
|
|
+
|
|
|
+const chartData2 = [
|
|
|
+ { name: '酒类实物', value: 2500, percentage: '10%' },
|
|
|
+ { name: '包装与标识', value: 1800, percentage: '8%' },
|
|
|
+ { name: '杯子', value: 1200, percentage: '6%' },
|
|
|
+ { name: '品牌节庆活动', value: 1800, percentage: '8%' },
|
|
|
+ { name: '品牌视觉传播', value: 1800, percentage: '8%' },
|
|
|
+ { name: '文书档案', value: 1800, percentage: '8%' },
|
|
|
+ { name: '影像资料', value: 1800, percentage: '8%' },
|
|
|
+ { name: '荣誉与表彰', value: 1800, percentage: '8%' },
|
|
|
+ { name: '企业藏品', value: 1800, percentage: '8%' },
|
|
|
+ { name: '艺术藏品', value: 1800, percentage: '8%' },
|
|
|
+ { name: '纪念礼品', value: 1800, percentage: '8%' },
|
|
|
+ { name: '酿造与开启工具', value: 1800, percentage: '8%' },
|
|
|
+ { name: '设备模型或实物', value: 1800, percentage: '8%' },
|
|
|
+ { name: '其他', value: 1800, percentage: '6%' }
|
|
|
+]
|
|
|
+
|
|
|
+const DEFAULT_COLORS = ['#c11b2d', '#243220', '#24664b', '#8acfb2', '#806e4c', '#988364', '#972d00']
|
|
|
+
|
|
|
+const binData1 = [
|
|
|
+ {
|
|
|
+ name: '啤酒产品类',
|
|
|
+ value: 2500
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '饮用器皿类',
|
|
|
+ value: 1800
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '品牌文化与节庆类',
|
|
|
+ value: 1200
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '企业历史与档案类',
|
|
|
+ value: 800
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '艺术与礼品类',
|
|
|
+ value: 1000
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '工具与设备类',
|
|
|
+ value: 900
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '其他综合类',
|
|
|
+ value: 600
|
|
|
+ }
|
|
|
+]
|
|
|
+
|
|
|
+const binData2 = [
|
|
|
+ {
|
|
|
+ name: '酒起',
|
|
|
+ value: 400
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '杯子',
|
|
|
+ value: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '护肤品',
|
|
|
+ value: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '冰箱贴',
|
|
|
+ value: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '衣服',
|
|
|
+ value: 100
|
|
|
+ }
|
|
|
+]
|
|
|
+
|
|
|
+// 先写一些静态的
|
|
|
function A1statistics() {
|
|
|
+ // 生成柱状图
|
|
|
+ const initEchFu = useCallback((data: any[], dom: any) => {
|
|
|
+ if (!dom) return
|
|
|
+ const myChart = echarts.getInstanceByDom(dom) || echarts.init(dom)
|
|
|
+
|
|
|
+ const option: echarts.EChartsOption = {
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ axisPointer: {
|
|
|
+ type: 'shadow'
|
|
|
+ },
|
|
|
+ formatter: (params: any) => {
|
|
|
+ const param = params[0]
|
|
|
+ return `
|
|
|
+ <div style="font-weight: bold;">${param.name}</div>
|
|
|
+ <div>数量: ${param.value}</div>
|
|
|
+ <div>占比: ${param.data.percentage}</div>
|
|
|
+ `
|
|
|
+ },
|
|
|
+ backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
|
|
+ borderColor: '#ddd',
|
|
|
+ textStyle: {
|
|
|
+ color: '#000'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ left: '5%',
|
|
|
+ right: '5%',
|
|
|
+ // 减小底部距离 - 调整这个值可以让柱子更靠近底部
|
|
|
+ bottom: '5%',
|
|
|
+ top: '5%',
|
|
|
+ containLabel: true
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ data: data.map(item => item.name),
|
|
|
+ axisLabel: {
|
|
|
+ interval: 0,
|
|
|
+ rotate: 30,
|
|
|
+ fontSize: 12,
|
|
|
+ color: '#000',
|
|
|
+ margin: 15 // 调整标签与柱子的距离
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: '#999'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ axisTick: {
|
|
|
+ show: true,
|
|
|
+ alignWithLabel: true,
|
|
|
+ length: 4
|
|
|
+ },
|
|
|
+ // 调整X轴位置,使其更靠近柱子底部
|
|
|
+ offset: 10
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'value',
|
|
|
+ name: '',
|
|
|
+ nameTextStyle: {
|
|
|
+ fontSize: 14,
|
|
|
+ color: '#000',
|
|
|
+ padding: [0, 0, 0, 10]
|
|
|
+ },
|
|
|
+ axisLabel: {
|
|
|
+ fontSize: 12,
|
|
|
+ color: '#000',
|
|
|
+ formatter: (value: number) => {
|
|
|
+ if (value >= 1000) {
|
|
|
+ return `${value / 1000}k`
|
|
|
+ }
|
|
|
+ return value.toString()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed',
|
|
|
+ color: '#e0e0e0'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 设置Y轴最大值
|
|
|
+ max: 3000,
|
|
|
+ min: 0,
|
|
|
+ // 调整Y轴刻度
|
|
|
+ interval: 500
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '数量',
|
|
|
+ type: 'bar',
|
|
|
+ data: data.map((item, index) => ({
|
|
|
+ value: item.value,
|
|
|
+ percentage: item.percentage,
|
|
|
+ // 为每个柱子设置独立的渐变
|
|
|
+ itemStyle: {
|
|
|
+ // 关键修改:使用线性渐变实现单个柱子的渐变效果
|
|
|
+ color: new echarts.graphic.LinearGradient(
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ 1, // 0,0表示起点,0,1表示终点(垂直方向渐变)
|
|
|
+ [
|
|
|
+ { offset: 0, color: '#bb1e2e' }, // 顶部颜色
|
|
|
+ { offset: 1, color: '#29644a' } // 底部颜色(更浅/白色)
|
|
|
+ ]
|
|
|
+ ),
|
|
|
+ borderRadius: [10, 10, 10, 10],
|
|
|
+ // 添加阴影效果增强立体感
|
|
|
+ shadowColor: 'rgba(0, 0, 0, 0.1)',
|
|
|
+ shadowBlur: 4,
|
|
|
+ shadowOffsetY: 2
|
|
|
+ }
|
|
|
+ })),
|
|
|
+ barWidth: '50%', // 稍微调窄柱子
|
|
|
+ // 调整标签位置和样式
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: 'top',
|
|
|
+ formatter: (params: any) => {
|
|
|
+ const itemData = params.data
|
|
|
+ return `${itemData.value}\n${itemData.percentage}`
|
|
|
+ },
|
|
|
+ fontSize: 10,
|
|
|
+ fontWeight: 'bold',
|
|
|
+ color: '#000',
|
|
|
+ lineHeight: 16
|
|
|
+ },
|
|
|
+
|
|
|
+ emphasis: {
|
|
|
+ itemStyle: {
|
|
|
+ shadowColor: 'rgba(0, 0, 0, 0.3)',
|
|
|
+ shadowBlur: 10,
|
|
|
+ shadowOffsetY: 3
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+
|
|
|
+ myChart.setOption(option)
|
|
|
+ }, [])
|
|
|
+
|
|
|
+ // 生成饼图
|
|
|
+ const binInitFu = useCallback((data: any[], dom: any) => {
|
|
|
+ if (!dom) return
|
|
|
+
|
|
|
+ // 计算总数用于百分比
|
|
|
+ const total = data.reduce((sum, item) => sum + item.value, 0)
|
|
|
+
|
|
|
+ const myChart = echarts.getInstanceByDom(dom) || echarts.init(dom)
|
|
|
+ const option = {
|
|
|
+ color: DEFAULT_COLORS, // 设置颜色方案
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'item',
|
|
|
+ formatter: '{b}: {c} ({d}%)'
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ type: 'scroll',
|
|
|
+ orient: 'vertical',
|
|
|
+ left: '52%',
|
|
|
+ top: 'center',
|
|
|
+ itemGap: 15,
|
|
|
+ textStyle: {
|
|
|
+ fontSize: 12
|
|
|
+ },
|
|
|
+ formatter: function (name: string) {
|
|
|
+ const item = data.find(d => d.name === name)
|
|
|
+ if (item) {
|
|
|
+ const percent = ((item.value / total) * 100).toFixed(1)
|
|
|
+ return `${name} ${item.value} ${percent}%`
|
|
|
+ }
|
|
|
+ return name
|
|
|
+ }
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '品类分布',
|
|
|
+ type: 'pie',
|
|
|
+ center: ['25%', '50%'], // 设置饼图中心位置
|
|
|
+ radius: ['50%', '90%'],
|
|
|
+ avoidLabelOverlap: false,
|
|
|
+ itemStyle: {
|
|
|
+ borderRadius: 0,
|
|
|
+ borderColor: '#fff',
|
|
|
+ borderWidth: 2
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ labelLine: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ itemStyle: {
|
|
|
+ shadowBlur: 10,
|
|
|
+ shadowOffsetX: 0,
|
|
|
+ shadowColor: 'rgba(0, 0, 0, 0.5)'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data: data.map(item => ({
|
|
|
+ name: item.name,
|
|
|
+ value: item.value
|
|
|
+ }))
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ myChart.setOption(option)
|
|
|
+ }, [])
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ initEchFu(chartData1, document.querySelector('#echBox1'))
|
|
|
+ initEchFu(chartData2, document.querySelector('#echBox2'))
|
|
|
+
|
|
|
+ binInitFu(binData1, document.querySelector('#echBox3'))
|
|
|
+ binInitFu(binData2, document.querySelector('#echBox4'))
|
|
|
+ }, [binInitFu, initEchFu])
|
|
|
+
|
|
|
return (
|
|
|
<div className={styles.A1statistics}>
|
|
|
<div className='pageTitle'>数据统计</div>
|
|
|
+
|
|
|
+ <div className='A1_1'>
|
|
|
+ <div>
|
|
|
+ <div>
|
|
|
+ <img src={iconUrl + '/a11.png'} alt='' />
|
|
|
+ <h3>藏品总数</h3>
|
|
|
+ </div>
|
|
|
+ <p>
|
|
|
+ <span>3741</span>(件/套)
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <div>
|
|
|
+ <img src={iconUrl + '/a22.png'} alt='' />
|
|
|
+ <h3>藏品总数量</h3>
|
|
|
+ </div>
|
|
|
+ <p>
|
|
|
+ <span>5834</span>(个)
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className='A1_1_3'>
|
|
|
+ <div>
|
|
|
+ <img src={iconUrl + '/a33.png'} alt='' />
|
|
|
+ <h3>定级文物数量</h3>
|
|
|
+ </div>
|
|
|
+ <p>
|
|
|
+ <span>120</span>(件/套)
|
|
|
+ <i>
|
|
|
+ 一级<i>20</i>
|
|
|
+ </i>
|
|
|
+ <i>
|
|
|
+ 二级<i>30</i>
|
|
|
+ </i>
|
|
|
+ <i>
|
|
|
+ 三级<i>40</i>
|
|
|
+ </i>
|
|
|
+ <i>
|
|
|
+ 一般<i>30</i>
|
|
|
+ </i>
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className='A1_1_4'>
|
|
|
+ <div>
|
|
|
+ <img src={iconUrl + '/a44.png'} alt='' />
|
|
|
+ <h3>年度新增产品数量</h3>
|
|
|
+ <div className='A1_1_4_1'>
|
|
|
+ <Select
|
|
|
+ defaultValue={2026}
|
|
|
+ options={[
|
|
|
+ { value: 2026, label: '2026年度' },
|
|
|
+ { value: 2025, label: '2025年度' },
|
|
|
+ { value: 2024, label: '2024年度' }
|
|
|
+ ]}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <p>
|
|
|
+ <span>123</span>(件/套)
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className='A1_box'>
|
|
|
+ <div className='A1_2'>
|
|
|
+ <div className='A1_2row'>
|
|
|
+ <div className='A1tit'>一级分类</div>
|
|
|
+ <div className='A1_2ech' id='echBox1'></div>
|
|
|
+ </div>
|
|
|
+ <div className='A1_2row'>
|
|
|
+ <div className='A1tit'>二级分类</div>
|
|
|
+ <div className='A1_2ech' id='echBox2'></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div className='A1_3'>
|
|
|
+ <div className='A1_3row'>
|
|
|
+ <div className='A1tit2'>
|
|
|
+ <div>材质统计</div>
|
|
|
+ <Select defaultValue={'杯子'} options={[{ value: '杯子', label: '杯子' }]} />
|
|
|
+ </div>
|
|
|
+ <div className='A1_3ech' id='echBox3'></div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className='A1_3row'>
|
|
|
+ <div className='A1tit2'>
|
|
|
+ <div>品类统计</div>
|
|
|
+ <Select
|
|
|
+ defaultValue={'文创产品'}
|
|
|
+ options={[{ value: '文创产品', label: '文创产品' }]}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div className='A1_3ech' id='echBox4'></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
)
|
|
|
}
|