[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;

最终效果

相关推荐
hhb_6187 小时前
一键生成数据看板,ECharts实战演示
前端·javascript·echarts
志尊宝15 小时前
Vue3 零基础每日笔记(085):项目上线前 Checklist——环境变量、报错监控、安全自查
前端·javascript·笔记·安全·信息可视化·echarts
paopaokaka_luck1 天前
滑雪场管理系统(AI智能助手流式对话,ECharts 运营数据分析、教练、雪具与场地一体化预约,钱包支付退款、订单核销与服务评价)
java·人工智能·spring boot·网络协议·数据分析·echarts
志尊宝2 天前
Vue3 零基础每日笔记(081):富文本编辑器集成 wangEditor 5——封装
前端·javascript·vue.js·笔记·信息可视化·echarts
志尊宝2 天前
Vue3 零基础每日笔记(080):Vue3 + ECharts 数据可视化——封装可复用图表组件
前端·javascript·vue.js·笔记·信息可视化·echarts
paopaokaka_luck3 天前
基于springboot+vue的智慧家政管理系统(AI问答、 WebSocket实时沟通、ECharts运营分析、订单规则与服务追踪)
java·javascript·spring boot·数据分析·echarts·mybatis
paopaokaka_luck9 天前
高校社团管理(AI辅助任务分配、协同过滤算法推荐、ECharts数据可视化、活动参与闭环、校园交流与反馈、器材借还管理)
java·前端·javascript·spring boot·数据分析·echarts
paopaokaka_luck11 天前
非遗文物数字化小程序(AI非遗问答、ONNX图像识别、协同过滤推荐、ECharts数据分析、非遗知识浏览与互动、文创商城订单闭环、文化活动报名签到、社区交流)
javascript·spring boot·mysql·数据分析·echarts·mybatis
樱花落木兰15 天前
SpringBoot + ECharts 后台数据统计报表模块实战
java·javascript·spring boot·ai·log4j·github·echarts
小小尚@15 天前
WebGIS 开发利器|MapLand 在线行政区划 GeoJSON 边界预览下载平台
echarts·地图·geojson·webgis