You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中如何为ApexCharts哑铃图的每个标记点单独设色

问题描述

需要为Next.js中ApexCharts的哑铃图(rangeBar类型)的每个标记点单独设置颜色。尝试在数据项中添加colors属性(如{ x: 'Amarela', y: [2100, 3000], colors: "#808089"}),但目前所有标记点颜色默认由plotOptions > dumbbellColors统一配置,官方文档描述模糊,求可行实现方法。

示例图:
标记点颜色示例图

代码示例
'use client';
import Image from 'next/image';
import ReactApexChart from 'react-apexcharts';
import React, { Component } from 'react';
import { Show } from '@chakra-ui/react';
import { Colors } from 'chart.js';

interface GraficoDumbbleState {
  series: {
    data: { x: string; y: [number, number]; colors?: string | string[] }[];
    dataLabels?: {
      enabled: boolean;
    };
  }[];
  options: {
    chart: {
      height: number;
      type: string;
      zoom: {
        enabled: boolean;
      };
      events?: {
        render?: (chart: any) => void;
      };
    };
    colors: string[];
    plotOptions: {
      bar: {
        horizontal: boolean;
        isDumbbell: boolean;
        dumbbellColors?: string[][];
      };
    };
    legend: {
      show: boolean;
      showForSingleSeries: boolean;
      position: string;
      horizontalAlign: string;
      customLegendItems: string[];
    };
    fill: {
      type: string;
      gradient: {
        gradientToColors: string[];
        inverseColors: boolean;
        stops: number[];
      };
    };
    grid: {
      xaxis: {
        lines: {
          show: boolean;
        };
        labels?: {
          show: boolean;
        };
      };
      yaxis: {
        lines: {
          show: boolean;
        };
        yaxis: {
          lines: {
            show: boolean;
          };
        };
      };
    };
    xaxis?: {
      labels: {
        show: boolean;
      };
    };
  };
}

export default class GraficoDumbble extends Component<{}, GraficoDumbbleState> {
  constructor(props: any) {
    super(props);

    this.state = {
      series: [
        {
          data: [
            { x: 'Amarela', y: [2100, 3000], colors: "#808089"},
            { x: 'Amarela', y: [3000, 5000], colors: "#ff0000"},
            { x: 'Amarela', y: [5000, 6500], colors: "#00ff00"},
            { x: 'Amarela', y: [6500, 8000], colors: "#0000ff"},

            {x: 'Branca', y: [2100, 5000], colors: "#ffa500"},
            {x: 'Branca', y: [5000, 8000], colors: "#800080"},
            {
              x: 'Indígina',
              y: [2100, 8000],
              colors: "#008080"
            },
            {
              x: 'Parda',
              y: [2100, 8000],
              colors: "#f0e68c"
            },
            {
              x: 'Preta',
              y: [2100, 8000],
              colors: "#000000"
            },
          ],
          dataLabels: {
            enabled: false,
          },
        },
      ],
      options: {
        chart: {
          height: 390,
          type: 'rangeBar',
          zoom: {
            enabled: false,
          },
          events: {
            render: function(chart) {
              const markers = chart.wrapper.querySelectorAll('.apexcharts-dumbbell-marker');
              chart.series[0].data.forEach((item: any, index: number) => {
                if (item.colors) {
                  const colorLeft = Array.isArray(item.colors) ? item.colors[0] : item.colors;
                  const colorRight = Array.isArray(item.colors) ? item.colors[1] : item.colors;
                  markers[index * 2].setAttribute('fill', colorLeft);
                  markers[index * 2 + 1].setAttribute('fill', colorRight);
                }
              });
            }
          }
        },
        
        colors: ['#808080', '#808080'],
        plotOptions: {
          bar: {
            horizontal: true,
            isDumbbell: true,
          },
        },
        legend: {
          show: false,
          showForSingleSeries: false,
          position: 'top',
          horizontalAlign: 'left',
          customLegendItems: ['Female', 'Male'],
        },
        fill: {
          type: 'gradient',
          gradient: {
            gradientToColors: ['#808080'],
            inverseColors: false,
            stops: [0, 100],
          },
        },
        grid: {
          xaxis: {
            lines: {
              show: false,
            },
            labels: {
              show: false,
            },
          },
          yaxis: {
            lines: {
              show: false,
            },
            yaxis: { lines: { show: false } },
          },
        },
        xaxis: {
          labels: {
            show: false,
          },
        },
      },
    };
  }

  render() {
    return (
      <div>
        <div id="chart">
          <ReactApexChart
            options={this.state.options as any}
            series={this.state.series}
            type="rangeBar"
            height={390}
          />
        </div>
        <div id="html-dist"></div>
      </div>
    );
  }
}
可行实现方法

方法一:利用dumbbellColors二维数组精准配置

ApexCharts的哑铃图支持通过plotOptions.bar.dumbbellColors设置每个数据项的标记点颜色,该属性是一个二维数组,每个子数组对应一个数据项的左右两个标记点颜色。

示例配置:

plotOptions: {
  bar: {
    horizontal: true,
    isDumbbell: true,
    dumbbellColors: [
      ['#808089', '#808089'], // 对应第一个Amarela数据项的两个标记点
      ['#ff0000', '#ff0000'], // 第二个Amarela数据项
      ['#00ff00', '#00ff00'], // 第三个Amarela数据项
      ['#0000ff', '#0000ff'], // 第四个Amarela数据项
      ['#ffa500', '#ffa500'], // Branca第一个数据项
      ['#800080', '#800080'], // Branca第二个数据项
      ['#008080', '#008080'], // Indígina数据项
      ['#f0e68c', '#f0e68c'], // Parda数据项
      ['#000000', '#000000'], // Preta数据项
    ]
  }
}

这种方法无需修改DOM,但需要严格保持数组顺序与data项一致,适合颜色固定的场景。

方法二:通过渲染事件动态修改DOM(灵活支持自定义数据属性)

如果需要从数据项的自定义colors属性读取颜色,可以通过ApexCharts的render事件,在图表渲染完成后手动修改标记点的DOM元素颜色:

  1. 首先在数据项接口中添加colors字段(支持单个颜色字符串或颜色数组):
data: { x: string; y: [number, number]; colors?: string | string[] }[]
  1. 在chart.events中添加render回调函数,遍历数据项并修改对应标记点的填充色:
chart: {
  height: 390,
  type: 'rangeBar',
  zoom: { enabled: false },
  events: {
    render: function(chart) {
      // 获取所有哑铃标记点DOM
      const markers = chart.wrapper.querySelectorAll('.apexcharts-dumbbell-marker');
      // 遍历每个数据项,设置对应标记点颜色
      chart.series[0].data.forEach((item: any, index: number) => {
        if (item.colors) {
          // 兼容单个颜色或两个端点不同颜色的情况
          const leftColor = Array.isArray(item.colors) ? item.colors[0] : item.colors;
          const rightColor = Array.isArray(item.colors) ? item.colors[1] : item.colors;
          // 每个数据项对应两个标记点,索引为index*2和index*2+1
          markers[index * 2].setAttribute('fill', leftColor);
          markers[index * 2 + 1].setAttribute('fill', rightColor);
        }
      });
    }
  }
}

这种方法更灵活,支持动态颜色配置,且无需手动维护颜色数组的顺序。

内容的提问来源于stack exchange,提问作者Mikael Carvalho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 18:55:53