react ts 封装3D柱状图,支持渐变

news2025/1/13 10:08:41

留档,以防忘记

bar3D.tsx

import React, { useEffect, useRef, useState } from 'react';
import * as echarts from 'echarts';
import 'echarts/lib/chart/bar';
import 'echarts/lib/chart/pictorialBar';
import 'echarts/lib/component/grid';
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/title';
import 'echarts/lib/component/legend';


interface IProps {
    name: string;
    tooltipUnit?: string;
    xdata: Array<string>;
    ydata: Array<number>;
    xLabelRotate?: number;
    barWidth?: number;
    barColor?: {
        left: {
            top: string;
            bottom: string;
        },
        right: {
            top: string;
            bottom: string;
        }
    }
    barCovers?: {
        left: string;
        right: string;
    }
    labelShow?: boolean
    labelColor?: string
    labelFont?: number
    offsetTop?: number | string
}


/**
 *
 * 3D柱状图,支持柱子上下渐变
 *
 * @param name string 图表名称
 * @param tooltipUnit string tooips 中显示的单位
 * @param xdata string[] x轴数据
 * @param ydata number[] y轴数据
 * @param xLabelRotate  number x轴标签旋转角度
 * @param barWidth number 柱状图宽度
 * @param barColor object 柱状图颜色
 * @param barCovers object 柱状图顶部和底部盖子颜色
 * @param labelShow boolean 是否显示柱状图上方文字
 * @param labelColor string 柱状图上方文字颜色
 * @param labelFont number 柱状图上方文字大小
 * @param offsetTop number | string 柱状图上方文字偏移量
 *
 * @returns
 */

const Bar3D = ({
    name = '安全监管',
    tooltipUnit = '%',
    xdata = ['bar1', 'bar2', 'bar3', 'bar4', 'bar5'],
    ydata = [18, 9, 15, 4],
    xLabelRotate = 0,
    barWidth = 25,
    barColor = {
        left: {
            top: '#37F1FD', // 柱子左侧顶部颜色
            bottom: '#12276F' // 柱子左侧底部颜色
        },
        right: {
            top: '#179DD1', // 柱子右侧底部颜色
            bottom: '#08154D'// 柱子右侧底部颜色
        }
    },
    barCovers = {
        left: '#34DFF1', // 柱子顶部和底部左侧盖子颜色
        right: '#1B5590'// 柱子顶部和底部右侧盖子颜色
    },
    labelShow = true,
    labelColor = '#fff',
    labelFont = 10,
    offsetTop = '-5'

}: IProps) => {

    const echartDomRef = useRef<any>();

    useEffect(() => {
        setEchart();
    }, []);

    const setEchart = () => {
        const myChart = echarts.init(echartDomRef.current);


        const topArr: any = []; // 顶部棱盖
        const bottomArr: any = []; // 底部棱盖
        const leftArr: any = []; // 左侧柱子
        const rightArr: any = []; // 右侧柱子


        ydata.map((item: number, index: number) => {
            topArr.push({
                value: item,
                symbol: 'diamond',
                symbolOffset: [0, '-50%'],
                symbolPosition: 'end', // 图形边缘与柱子结束的地方内切
                symbolSize: [barWidth, barWidth * 0.4], // 根据柱子大小来做调整
                itemStyle: {
                    normal: {
                        color: {
                            x: 1,
                            y: 0,
                            x2: 0,
                            y2: 0,
                            type: 'linear',
                            global: false,
                            colorStops: [
                                { offset: 0, color: barCovers.left },
                                { offset: 1, color: barCovers.right }
                            ]
                        }
                    }
                }
            });

            bottomArr.push({
                value: item,
                symbol: 'triangle',
                symbolOffset: [0, barWidth * 0.25],
                symbolSize: [-barWidth, barWidth * 0.25],
                symbolRotate: 180,
                itemStyle: {
                    color: {
                        x: 0,
                        y: 0,
                        x2: 1,
                        y2: 0,
                        type: 'linear',
                        global: false,
                        colorStops: [
                            { offset: 0, color: barColor.left.bottom },
                            { offset: 0.5, color: barColor.left.bottom },
                            { offset: 0.5, color: barColor.right.bottom },
                            { offset: 1, color: barColor.right.bottom }
                        ]
                    }
                }
            });

            leftArr.push({
                value: item,
                itemStyle: {
                    color: {
                        x: 0,
                        y: 0,
                        x2: 0,
                        y2: 1,
                        type: 'linear',
                        global: false,
                        colorStops: [
                            { offset: 0, color: barColor.left.top },
                            { offset: 1, color: barColor.left.bottom }
                        ]
                    }
                }
            });

            rightArr.push({
                value: item,
                itemStyle: {
                    color: {
                        x: 0,
                        y: 0,
                        x2: 0,
                        y2: 1,
                        type: 'linear',
                        global: false,
                        colorStops: [
                            { offset: 0, color: barColor.right.top },
                            { offset: 1, color: barColor.right.bottom }
                        ]
                    }
                }
            });
        });

        const option = {
            grid: {
                left: 15,
                right: 15,
                bottom: 10,
                top: 30,
                containLabel: true
            },
            tooltip: {
                trigger: 'axis',
                confine: true,
                formatter: function (param: any) {
                    let str = '';
                    param.map((el: any, index: number) => {
                        if (el.componentSubType === 'bar') {
                            str = el.seriesName + '<br>' + el.marker + el.name + ':' + el.data.value + '' + tooltipUnit;
                        }
                    });
                    return str;
                }
            },
            xAxis: [
                {
                    type: 'category',
                    data: xdata,
                    axisTick: {
                        show: false
                    },
                    axisLine: {
                        show: false
                    },
                    splitLine: {
                        show: false
                    },
                    axisLabel: {
                        show: true,
                        color: '#76A5D1',
                        fontSize: 10,
                        fontWeight: 300,
                        rotate: xLabelRotate
                    }
                }
            ],
            yAxis: [
                {
                    type: 'value',
                    axisTick: {
                        show: false
                    },
                    axisLine: {
                        show: false
                    },
                    splitLine: {
                        show: true,
                        lineStyle: {
                            color: '#082745'
                        }
                    },
                    axisLabel: {
                        show: true,
                        color: '#76A5D1',
                        fontSize: 10,
                        fontWeight: 300
                    }
                }
            ],
            series: [
                {
                    type: 'pictorialBar',
                    name: '顶部棱盖',
                    z: 10,
                    data: topArr
                },
                {
                    type: 'bar',
                    name: name,
                    barGap: '-50%',
                    // symbol: 'image://' + params.picture, // 图片自己切或者让UI设计切喔
                    symbolOffset: [0, 0],
                    barWidth: barWidth / 2,
                    z: 2,
                    label: {
                        show: labelShow,
                        color: labelColor,
                        fontSize: labelFont,
                        position: 'top',
                        offset: [barWidth / 4, Number(offsetTop)]
                    },
                    data: leftArr,
                },
                {
                    type: 'bar',
                    name: name,
                    barGap: '-5%',
                    // symbol: 'image://' + params.picture, // 图片自己切或者让UI设计切喔
                    symbolOffset: [0, 0],
                    barWidth: barWidth / 2,
                    z: 3,
                    data: rightArr
                },
                {
                    type: 'pictorialBar',
                    name: '底部棱盖',
                    barGap: '-100%',
                    z: 6,
                    data: bottomArr
                }
            ]
        };

        myChart.setOption(option);
    };
    return <div className='w-full h-full' ref={echartDomRef}></div>;
};

export default Bar3D;

使用

<Bar3D name='近半年系统攻击统计' xdata={['自然安全', '事故安全', '公共卫生', '社会安全', '其他']} ydata={[100, 200, 300, 400, 900]} barWidth={15} />

效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1895823.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[C++][CMake][CMake基础]详细讲解

目录 1.CMake简介2.大小写&#xff1f;3.注释1.注释行2.注释块 4.日志 1.CMake简介 CMake是一个项目构建工具&#xff0c;并且是跨平台的 问题 – 解决 如果自己动手写Makefile&#xff0c;会发现&#xff0c;Makefile通常依赖于当前的编译平台&#xff0c;而且编写Makefile的…

利用redis数据库管理代理库爬取cosplay网站-cnblog

爬取cos猎人 数据库管理主要分为4个模块&#xff0c;代理获取模块&#xff0c;代理储存模块&#xff0c;代理测试模块&#xff0c;爬取模块 cos猎人已经倒闭&#xff0c;所以放出爬虫源码 api.py 为爬虫评分提供接口支持 import requests import concurrent.futures import …

鸿蒙应用实践:利用扣子API开发起床文案生成器

前言 扣子是一个新一代 AI 应用开发平台&#xff0c;无需编程基础即可快速搭建基于大模型的 Bot&#xff0c;并发布到各个渠道。平台优势包括无限拓展的能力集&#xff08;内置和自定义插件&#xff09;、丰富的数据源&#xff08;支持多种数据格式和上传方式&#xff09;、持…

lodash中flush的使用(debounce、throttle)

在项目的配置中&#xff0c;看到了一个请求&#xff0c;类似是这样的 import { throttle } from lodash-es// 请求函数 async function someFetch(){const {data} await xxx.post()return data }// 节流函数 async function throttleFn(someFetch,1000)// 执行拿到数据函数 a…

掌握电路交换与分组交换:计算机网络的核心技术

计算机网络是现代信息社会的基石&#xff0c;而交换技术是实现网络通信的核心。本文将详细介绍两种典型的交换方式&#xff1a;电路交换和分组交换&#xff0c;帮助基础小白快速掌握这两种技术的基本概念和区别。 什么是电路交换&#xff1f; 电路交换&#xff08;Circuit Swi…

斯坦福提出首个开源视觉语言动作大模型OpenVLA

OpenVLA&#xff1a;开源视觉语言动作大模型 摘要模型结构训练数据训练设施实验总结和局限性 项目主页 代码链接 论文链接 模型链接 摘要 现有的VLA(Vision-Language-Action )模型具有这些局限性&#xff1a; 1)大多封闭且开放&#xff1b; 2)未能探索高效地为新任务微调VLA的方…

香橙派AIpro做目标检测

使用香橙派AIpro做目标检测 文章目录 使用香橙派AIpro做目标检测香橙派AIpro开发板介绍香橙派AIpro应用体验快速体验香橙派的AI功能YOLOV5s目标检测使用场景描述图像目标检测视频目标检测摄像头目标检测YOLOv5s 目标检测的运行结果分析香橙派 AIpro 在运行过程中的表现 香橙派A…

【Vue报错】v-bind动态绑定src无效

今天遇到v-bind动态绑定video的src&#xff0c;出现无效的问题 但是翻看以前的项目都是没问题的 之前的项目 现在的项目 发现并不能呈现视频效果 进行了改进&#xff0c;成功展示

Java数据结构9-排序

1. 排序的概念及引用 1.1 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录…

【ROS2】Ubuntu 24.04 源码编译安装 Jazzy Jalisco

目录 系统要求 系统设置 设置区域启用所需的存储库安装开发工具 构建 ROS 2 获取 ROS 2 代码使用 rosdep 安装依赖项安装额外的 RMW 实现&#xff08;可选&#xff09;在工作区构建代码 设置环境 尝试一些例子 下一步 备用编译器 Clang保持最新状态 故障排除 卸载 系统要求 当前…

mac如何安装nvm

​ vue项目开发&#xff0c;热更新&#xff0c;webpack&#xff0c;前辈造的轮子&#xff1a;各类的工具&#xff0c;库&#xff0c;像axios,qs,cookie等轮子在npm上可以拿来直接用&#xff0c;需要node作为环境支撑。 开发时同时有好几个项目&#xff0c;每个项目的需求不同…

自然语言处理领域介绍及其发展历史

自然语言处理领域介绍及其发展历史 1 NLP2 主要任务3 主要的方法1 基于规则的方法&#xff08;1950-1980&#xff09;2 基于统计的方法&#xff08;传统的机器学习的方法&#xff09;3 Connectionist approach&#xff08;Neural networks&#xff09; 1 NLP 自动的理解人类语…

C++(第四天----拷贝函数、类的组合、类的继承)

一、拷贝构造函数&#xff08;复制构造函数&#xff09; 1、概念 拷贝构造函数&#xff0c;它只有一个参数&#xff0c;参数类型是本类的引用。如果类的设计者不写拷贝构造函数&#xff0c;编译器就会自动生成拷贝构造函数。大多数情况下&#xff0c;其作用是实现从源对象到目…

mmdetection3增加12种注意力机制

在mmdetection/mmdet/models/layers/目录下增加attention_layers.py import torch.nn as nn from mmdet.registry import MODELS #自定义注意力机制算法 from .attention.CBAM import CBAMBlock as _CBAMBlock from .attention.BAM import BAMBlock as _BAMBlock from .attent…

语音声控灯:置入NRK3301离线语音识别ic 掌控的灯具新风尚

一、语音声控灯芯片开发背景 我们不难发现&#xff0c;传统的灯具控制方式已难以满足现代人对便捷性和智能化的追求。传统的开关控制方式需要人们手动操作&#xff0c;不仅繁琐且不便&#xff0c;特别是在夜晚或光线昏暗的环境下&#xff0c;更容易造成不便甚至安全隐患。而语音…

Spring学习03-[Spring容器核心技术IOC学习进阶]

IOC学习进阶 Order使用Order改变注入顺序实现Ordered接口&#xff0c;重写getOrder方法来改变自动注入顺序 DependsOn使用 Lazy全局设置-设置所有bean启动时候懒加载 Scopebean是单例的&#xff0c;会不会有线程安全问题 Order 可以改变自动注入的顺序 比如有个animal的接口&a…

海外仓一件代发功能自动化:海外仓WMS系统配置方法

根据数据显示&#xff0c;2014-2019年短短几年之间&#xff0c;跨境电商销售总额增长了160%以上。这为跨境电商商家和海外仓&#xff0c;国际物流等服务端企业都提供了巨大的发展机遇。 然而&#xff0c;作为海外仓&#xff0c;要想服务好跨境电商&#xff0c;仓库作业的每一个…

JAVA进阶学习10

文章目录 一、创建不可变集合二、Stream流2.1 Stream流的获取2.1 Stream流的中间方法2.2 Stream流的终结方法 一、创建不可变集合 意义&#xff1a;如果一个集合中的数据在复制或使用过程中不能修改&#xff0c;或者被其他对象调用时不能改变内部数据&#xff0c;即增加数据的安…

【C++ 】解决 C++ 语言报错:Null Pointer Dereferenc

文章目录 引言 在 C 编程中&#xff0c;空指针解引用&#xff08;Null Pointer Dereference&#xff09;是一种常见且危险的错误。当程序试图通过空指针访问内存时&#xff0c;会导致程序崩溃或产生不可预期的行为。本文将详细探讨空指针解引用的成因、检测方法及其预防和解决…

Unity之VS脚本自动添加头部注释Package包开发

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity之VS脚本自动添加头部注释Package包开发 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&…