[echarts]横向柱状图

前言

接到一个需求,需要展示一个横向的柱状图,按数量从大到小排序,并定时刷新

使用react配合echarts进行实现。

react引入echarts

javascript 复制代码
import React, { useEffect, useRef } from 'react';
import * as echarts from 'echarts';
import DeviceApi from '@/api/screen/DeviceApi';

const CenterRank = (props) => {
    const chartRef = useRef(null);

    const initEcharts = () => {
        if (chartRef.current) {
            const chart = echarts.init(chartRef.current);

            const option = {
                legend: {
                    show: true
                },
                grid: {  //控制图形大小
                    top: '12%',
                    left: '3%',
                    right: '8%',
                    bottom: '3%',
                    containLabel: true
                },
                xAxis: {
                    max: 'dataMax',
                    type: 'value',
                    boundaryGap: [0, 0.01],
                    axisLine: {
                        show: false
                    },
                    axisTick: {
                        show: false
                    },
                    splitLine: {
                        show: false
                    },
                    axisLabel: {
                        show: false
                    }
                },
                yAxis: [
                    {
                        type: 'category',
                        data: [],
                        inverse: true,
                        animationDuration: 0,
                        animationDurationUpdate: 500,
                        axisLabel: {
                            show: true,
                            inside: true,
                            interval: 0,
                            splitNumber: 50,
                            textStyle: {
                                color: '#9FFFFD',
                                verticalAlign: 'bottom',
                                fontSize: '0.8rem',
                                align: 'left',
                                padding: [0, 0, 8, -5]   //y轴在柱子上方
                            },
                            formatter: function (value) {
                                const top = value.split(' ')[0];
                                const center = value.split(' ')[1];
                                if (value.startsWith("Top1") || value.startsWith("Top2") || value.startsWith("Top3")) {
                                    return '{' + top + '|' + top + '}' + ' {center|' + center + '}';
                                } else {
                                    return '{other|' + top + '}' + ' {center|' + center + '}';
                                }
                            },
                            rich: {  //富文本样式,配置Top1 2 3的不同样式
                                Top1: {
                                    padding: 2,
                                    color: '#FA5151',
                                    backgroundColor: 'rgba(250,81,81,0.24)',
                                },
                                Top2: {
                                    padding: 2,
                                    color: '#FF8F1F',
                                    backgroundColor: 'rgba(255,143,31,0.24)',
                                },
                                Top3: {
                                    padding: 2,
                                    color: '#FFC300',
                                    backgroundColor: 'rgba(255,195,0,0.24)',
                                },
                                other: {
                                    padding: 2,
                                    color: '#9FFFFD',
                                    backgroundColor: 'rgba(159,255,253,0.24)',
                                },
                            }
                        },
                        axisLine: {
                            show: false
                        },
                        axisTick: {
                            show: false
                        },
                        splitLine: {
                            show: false
                        }
                    },
                    {  //配两个y轴,可以做出label在柱子末端展示的效果
                        type: 'category',
                        position: 'top',
                        data: [],
                        axisLabel: {
                            show: true,
                            color: '#fff',
                            formatter: (value, index) => {
                            return `${value}h`;
                        },
                        },
                        axisLine: {
                            show: false
                        },
                        axisTick: {
                            show: false
                        },
                    },
                ],
                series: [
                    {
                        realtimeSort: true,
                        type: 'bar',
                        data: [],
                        label: {
                            show: false,
                            position: 'right',
                            valueAnimation: true,
                            formatter: '{c}h',
                            fontSize: '0.8rem',
                            color: '#fff'
                        },
                        barWidth: 6,   // 条形的宽度
                        itemStyle: {
                            borderRadius: 0,
                            color: function (params) {  // 设置颜色为线性渐变
                                return new echarts.graphic.LinearGradient(
                                    1, 0, 0, 0,
                                    [
                                        { offset: 0, color: '#2FFFFD' },
                                        { offset: 1, color: 'rgba(47,255,253,0)' }
                                    ],
                                    false
                                );
                            },
                        },
                        showBackground: true,  //柱子的背景色
                        backgroundStyle: {
                            color: 'rgba(159,255,253,0.3)'
                        }
                    }
                ],
                animationDuration: 3000,
                animationDurationUpdate: 5000,
                animationEasing: 'linear',
                animationEasingUpdate: 'linear'
            };

            chart.setOption(option);

            const fetchData = async () => {
                try {
                    const response = await DeviceApi.getUsageRank();

                    response.sort((a, b) => b.occupyTime - a.occupyTime)  //根据occupyTime进行排序
                    const data = { labels: response.map(item => item.orgName), values: response.map(item => item.occupyTime) }
                    data.labels = data.labels.map((item, index) => {
                        return `Top${index + 1} ${item}`
                    })

                    chart.setOption({
                        yAxis: [
                            {
                                data: data.labels
                            },
                            {
                                data: response.map(item => item.occupyTime).reverse()
                            }
                        ],
                        series: [{
                            data: data.values
                        }]
                    });
                } catch (error) {
                    console.error('Error fetching data:', error);
                }
            }

            fetchData();
            const intervalId = setInterval(fetchData, 60 * 60 * 1000);  //1小时刷新一次

            window.addEventListener('resize', chart.resize);

            return () => {
                window.removeEventListener('resize', chart.resize);
                clearInterval(intervalId);
                chart.dispose();
            };
        }
    };

    useEffect(() => {
        initEcharts();
    }, []);
    return (
        <div title="使用时长排名">
            <div ref={chartRef} style={{ height: '100%', width: '100%' }} />
        </div>
    )
}

export default CenterRank;

最终效果

相关推荐
h_654321012 小时前
echarts实现柱状图加一条横线
前端·echarts
速易达网络12 小时前
ECharts 图表制作完全指南:从零到可视化实战
前端·javascript·echarts
paopaokaka_luck13 小时前
灾害应急物资管理系统(AI应急助手、Echarts可视化数据看板、捐赠入库联动、 物资全流程管理、库存变动追溯、灾情资讯与互动反馈、物资发放公示)
java·前端·javascript·spring boot·mysql·tomcat·echarts
paopaokaka_luck4 天前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts
腾讯数据架构师5 天前
任务跑完怎么直接出图表?CubeStudio 任务可视化 ECharts 数据格式实操(CSV/JSON + metric.json,11 种图表一键渲染)
前端·json·echarts·数据可视化
总要学点什么6 天前
第81篇:数据可视化-PM2.5分布——让圆点的胖瘦替每座城市报出浓度
前端·信息可视化·echarts·cesium·空间分析
paopaokaka_luck6 天前
社区服务平台(加权协同过滤推荐、Jieba中文词频分析、WebSocket实时聊天、求助处理闭环、 活动积分闭环、ECharts多维分析)
java·前端·spring boot·mysql·echarts·mybatis
mmsx6 天前
Android 并发考古:newThread 与 RxJava 共存,以及 GlobalScope 的三宗罪
android·echarts·rxjava
DataGear7 天前
DataGear 6.1.1 发布,数据可视化分析平台
javascript·信息可视化·数据分析·echarts·数据可视化
paopaokaka_luck7 天前
流浪动物救助与收养系统(DeepSeek AI对话、 ECharts多维分析、救助流程衔接、领养与回访衔接、 捐赠确认与公示、志愿者协作)
java·前端·javascript·人工智能·mysql·echarts·推荐算法