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

最终效果

相关推荐
Ticnix4 小时前
函数封装实现Echarts多表渲染/叠加渲染
前端·echarts
小徐_23331 天前
uni-app vue3 也能使用 Echarts?Wot Starter 是这样做的!
前端·uni-app·echarts
java水泥工2 天前
基于Echarts+HTML5可视化数据大屏展示-白茶大数据溯源平台V2
大数据·echarts·html5
码上暴富3 天前
Echarts雷达图根据数值确定颜色
前端·javascript·echarts
懒大王95273 天前
uni-app + Vue3 开发展示 echarts 图表
前端·uni-app·echarts
小谭鸡米花5 天前
uni小程序中使用Echarts图表
前端·小程序·echarts
@AfeiyuO6 天前
分类别柱状图(Vue3)
typescript·vue·echarts
Pu_Nine_96 天前
10 分钟上手 ECharts:从“能跑”到“生产级”的完整踩坑之旅
前端·javascript·echarts·css3·html5
小白_ysf6 天前
uniapp和vue3项目中引入echarts 、lime-echart(微信小程序、H5等)
微信小程序·uni-app·echarts·h5·lime-echart
Chan167 天前
【智能协同云图库】基于统一接口架构构建多维度分析功能、结合 ECharts 可视化与权限校验实现用户 / 管理员图库统计、通过 SQL 优化与流式处理提升数据
java·spring boot·后端·sql·spring·intellij-idea·echarts