基于react框架,用div+css完成类似echarts柱状图展示效果(柱状内部显示名称标签,顶部显示数值)

首先附上代码:

import { FC } from 'react';
import './index.scss';

const WaterIndicator: FC = () => {
    const colors = ['#19CEFA', '#0083E5', '#BCBA80', '#ADD8E6', '#03968C'];
    
    // 定义每个指标项的数据
    const indicatorItems = [
        {
            name: '吨乙烯取水量(t/t)',
            items: [
                { name: '月分解指标', value: 61.09, color: colors[0] },
                { name: '同比', value: 30.26, color: colors[1] },
                { name: '8月', value: 36.70, color: colors[2] },
                { name: '累计同比', value: 78.09, color: colors[3] },
                { name: '年累计', value: 25.8, color: colors[4] }
            ]
        },
        {
            name: '单耗(t)',
            items: [
                { name: '月分解指标', value: 45.5, color: colors[0] },
                { name: '同比', value: 28.3, color: colors[1] },
                { name: '8月', value: 32.1, color: colors[2] }
            ]
        },
        {
            name: '用水当量(t)',
            items: [
                { name: '月分解指标', value: 0, color: colors[0] },
                { name: '同比', value: 0, color: colors[1] },
                { name: '8月', value: 0, color: colors[2] }
            ]
        },
        {
            name: '吨乙烯取水量(t/t)',
            items: [
                { name: '月分解指标', value: 61.09, color: colors[0] },
                { name: '同比', value: 30.26, color: colors[1] },
                { name: '8月', value: 36.70, color: colors[2] },
                { name: '累计同比', value: 78.09, color: colors[3] },
                { name: '年累计', value: 25.8, color: colors[4] }
            ]
        },
        {
            name: '单耗(t)',
            items: [
                { name: '月分解指标', value: 50.2, color: colors[0] },
                { name: '同比', value: 35.7, color: colors[1] },
                { name: '8月', value: 42.3, color: colors[2] }
            ]
        }
    ];

    // 计算最大高度用于比例缩放
    const calculateMaxValue = (items: { value: number }[]) => {
        return Math.max(...items.map(item => item.value), 1); // 最小为1避免除以0
    };

    // 计算高度百分比
    const calculateHeight = (value: number, maxValue: number) => {
        if (value === 0) return '0%';
        return `${(value / maxValue) * 100}%`;
    };

    return (
        <div className="water-indicator">
            {indicatorItems.map((indicator, index) => {
                const maxValue = calculateMaxValue(indicator.items);
                
                return (
                    <div key={index} className="indicator-item">
                        {indicator.items.map((item, itemIndex) => (
                            <div
                                key={itemIndex}
                                className="item-bar"
                                style={{
                                    height: calculateHeight(item.value, maxValue),
                                    backgroundColor: item.color
                                }}
                            >
                                <span className="item-name">{item.name}</span>
                                <span className="item-value">{item.value.toFixed(2)}</span>
                            </div>
                        ))}
                        <div className="name">{indicator.name}</div>
                    </div>
                );
            })}
        </div>
    );
};

export default WaterIndicator;

css代码:

.water-indicator {
  height: 100%;
  display: flex;
  border-bottom: 2px solid rgba(255, 255, 255, .15);
  padding: 0 20px;
  margin: 30px 0 45px 0;
  .indicator-item {
    height: 100%;
    margin-right: 7%;
    display: flex;
    align-items: flex-end;
    position: relative;
    &:last-child {
      margin-right: 0;
    }
    .name {
      position: absolute;
      bottom: -32px;
      font-size: 14px;
      color: #FFFFFF;
      font-weight: 500;
      line-height: 20px;
      left: 50%;
      transform: translateX(-50%);
      width: 100%;
      white-space: nowrap;
    }
  }

  .item-name {
    font-size: 14px;
    color: #FFFFFF;
    width: 15px;
    text-orientation: upright;
  }
  .item-bar {
    position: relative;
    width: 22px;
    margin-right: 15px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .item-value {
    font-size: 14px;
    font-weight: 700;
    color: #FFFFFF;
    position: absolute;
    top: -22px;
    left: 50%;
    transform: translateX(-50%);
  }
}

具体实现效果如图:

最开始尝试用echarts中柱状图实现如图效果,但是不达预期,所以直接改成了html+css手写!完美实现~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值