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

最终效果

相关推荐
盼哥PyAI实验室1 天前
纯前端打造个人成长网站:零后端、零部署、零服务器的实践分享
运维·服务器·前端·javascript·echarts·个人开发
Lsx_1 天前
详解ECharts中的convertToPixel和convertFromPixel
前端·javascript·echarts
java水泥工2 天前
基于Echarts+HTML5可视化数据大屏展示-工厂信息监控台
echarts·html5·可视化大屏·大屏模版
菩提树下的杨过2 天前
dify+LLM+echarts打造智能可视化数据分析AI助手
echarts·dify
合作小小程序员小小店5 天前
web网页,在线%抖音,舆情%分析系统demo,基于python+web+echart+nlp+知识图谱,数据库mysql
数据库·python·自然语言处理·flask·nlp·echarts·知识图谱
一川_6 天前
《Echarts内存泄漏惊魂记:我的页面在导航切换中“炸”了!》
echarts
合作小小程序员小小店6 天前
大屏开发,在线歌词舆情分析系统demo,基于python,flask,web,echart,nlp,自然语言数据库mysql。
后端·python·flask·nlp·echarts
Lsx_7 天前
ECharts 全局触发click点击事件(柱状图、折线图增大点击范围)
前端·javascript·echarts
xiaohe06018 天前
🚀 拥抱 create-uni,一行命令轻松集成 Uni ECharts!
vue.js·uni-app·echarts
知识分享小能手10 天前
uni-app 入门学习教程,从入门到精通,uni-app中uCharts组件学习((8)
vue.js·学习·ui·微信小程序·小程序·uni-app·echarts