Highcharts 使用百分比的堆叠柱形图(千字长文)

Highcharts 使用百分比的堆叠柱形图:从零开始掌握可视化表达

在数据可视化领域,柱形图是最常见的图表类型之一。而当你需要对比多个类别中各组成部分的占比关系时,堆叠柱形图就显得尤为重要。特别是在展示时间序列、销售区域分布或用户行为构成时,Highcharts 使用百分比的堆叠柱形图能清晰地揭示“总量不变,结构变化”的核心信息。

想象一下,你是一家电商公司的数据分析师,要向管理层汇报各季度的销售额构成。如果只是用普通柱形图,会看到不同季度的总销售额高低不同,但无法直观看出“每个产品线占总销售额的比例是否稳定”。这时候,百分比堆叠柱形图就是最佳选择——它把每根柱子的总高度统一设为 100%,每个颜色区块代表一个分类的占比,一眼就能看出结构变化趋势。

这篇文章,我将手把手带你构建一个完整的 Highcharts 使用百分比的堆叠柱形图,从环境搭建到动态配置,再到实际业务场景的适配。全程不讲理论堆砌,只讲你能用得上的实战技巧。


准备工作:引入 Highcharts 库

在使用 Highcharts 之前,你需要先将它引入你的项目。最简单的方式是通过 CDN 直接加载。

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8" />
  <title>百分比堆叠柱形图示例</title>
  <!-- 引入 Highcharts 官方 CDN -->
  <script src="https://cdn.jsdelivr.net/npm/highcharts@9.3.3/dist/highcharts.min.js"></script>
  <!-- 如果需要支持导出功能,可额外引入 export-tools -->
  <script src="https://cdn.jsdelivr.net/npm/highcharts@9.3.3/modules/exporting.js"></script>
</head>
<body>
  <!-- 图表容器 -->
  <div id="container" style="width: 100%; height: 400px;"></div>
</body>
</html>

说明highcharts.min.js 是 Highcharts 的核心库,exporting.js 可选,用于支持导出为 PNG、PDF 等格式。我们这里只用核心功能,所以可以省略。


数据结构解析:理解堆叠数据格式

在 Highcharts 中,要实现百分比堆叠,数据必须以“数组中的对象”形式组织,每个对象代表一个类别(如“第一季度”),其 data 属性是一个子数组,包含每个堆叠项的数值。

const data = [
  {
    name: '第一季度',
    data: [30, 40, 30]  // 三个产品线的销售额
  },
  {
    name: '第二季度',
    data: [20, 50, 30]
  },
  {
    name: '第三季度',
    data: [25, 45, 30]
  },
  {
    name: '第四季度',
    data: [35, 40, 25]
  }
];

关键点:这个 data 数组的每一项对应图表中的一根柱子,data 中的数字代表每个子项的原始值。Highcharts 会自动计算每根柱子的总和,并将每个子项除以总和,得出百分比。


配置图表选项:开启百分比堆叠模式

现在我们进入核心配置环节。要让 Highcharts 识别这是“百分比堆叠”,需要设置 stacking'percent',并指定 type'column'

const options = {
  chart: {
    type: 'column'  // 柱形图类型
  },
  title: {
    text: '各季度产品销售额占比(百分比堆叠柱形图)'
  },
  xAxis: {
    categories: ['第一季度', '第二季度', '第三季度', '第四季度'],
    title: {
      text: '季度'
    }
  },
  yAxis: {
    title: {
      text: '占比 (%)'
    },
    // 设置纵轴最大值为 100,表示百分比
    max: 100,
    // 保持刻度为整数,避免小数显示
    tickInterval: 20
  },
  // 核心配置:开启百分比堆叠
  plotOptions: {
    column: {
      stacking: 'percent'  // 这是实现百分比堆叠的关键!
    }
  },
  series: data  // 将之前定义的数据传入
};

重点解释stacking: 'percent' 是实现“百分比堆叠”的唯一配置。它告诉 Highcharts:“不要按原始数值堆叠,而是将每根柱子的总高度归一化为 100%,每个子项按比例显示。” 如果你改成 stacking: 'normal',那就是普通堆叠柱形图(总高度随数据变化)。


自定义样式:让图表更美观

一个优秀的数据可视化作品,不仅数据准确,还要有良好的视觉表现。我们可以为图表添加颜色、标签和提示信息。

series: [
  {
    name: 'A 产品线',
    data: [30, 20, 25, 35],
    color: '#7cb5ec'  // 蓝色
  },
  {
    name: 'B 产品线',
    data: [40, 50, 45, 40],
    color: '#434348'  // 深灰
  },
  {
    name: 'C 产品线',
    data: [30, 30, 30, 25],
    color: '#90ed7d'  // 绿色
  }
]

同时,还可以添加数据标签,让每个区块显示百分比数值:

plotOptions: {
  column: {
    stacking: 'percent',
    dataLabels: {
      enabled: true,  // 开启数据标签
      formatter: function () {
        // 自定义显示格式:保留一位小数,加百分号
        return this.y + '%';
      },
      style: {
        color: 'black',
        fontSize: '10px',
        fontWeight: 'bold'
      }
    }
  }
}

技巧提示formatter 函数中,this.y 表示当前数据点的百分比值(如 40.5),你可以通过 Math.round(this.y) 来四舍五入,避免显示太多小数。


动态更新数据:模拟实时场景

在真实项目中,数据往往是动态变化的。Highcharts 支持通过 chart.series[0].setData() 方法动态更新数据。

假设我们想模拟“第四季度数据更新后”的效果:

// 模拟新数据(更新后)
const newData = [30, 40, 30, 32]; // 第四季度 A 产品线增长

// 更新第一个系列(A 产品线)的数据
chart.series[0].setData(newData);

注意chart 是通过 Highcharts.chart() 创建的对象,必须在图表初始化后保存引用。例如:

const chart = Highcharts.chart('container', options);

这样你就可以随时调用 chart.series[0].setData(...) 来刷新数据,而无需重新渲染整个图表。


实际应用:电商销售分析案例

让我们结合一个真实业务场景,完整演示一次 Highcharts 使用百分比的堆叠柱形图 的全过程。

假设我们有如下数据:

季度 A 产品线 B 产品线 C 产品线
第一季度 30 40 30
第二季度 20 50 30
第三季度 25 45 30
第四季度 35 40 25

我们将其转换为 Highcharts 所需的格式:

const salesData = [
  { name: '第一季度', data: [30, 40, 30] },
  { name: '第二季度', data: [20, 50, 30] },
  { name: '第三季度', data: [25, 45, 30] },
  { name: '第四季度', data: [35, 40, 25] }
];

完整图表配置如下:

const chart = Highcharts.chart('container', {
  chart: {
    type: 'column'
  },
  title: {
    text: '2023 年各季度产品销售额占比分析'
  },
  xAxis: {
    categories: ['第一季度', '第二季度', '第三季度', '第四季度'],
    title: {
      text: '季度'
    }
  },
  yAxis: {
    title: {
      text: '占比 (%)'
    },
    max: 100,
    tickInterval: 20
  },
  plotOptions: {
    column: {
      stacking: 'percent',
      dataLabels: {
        enabled: true,
        formatter: function () {
          return this.y ? this.y.toFixed(1) + '%' : '';
        },
        style: {
          color: '#333',
          fontSize: '10px'
        }
      }
    }
  },
  series: [
    {
      name: 'A 产品线',
      data: [30, 20, 25, 35],
      color: '#7cb5ec'
    },
    {
      name: 'B 产品线',
      data: [40, 50, 45, 40],
      color: '#434348'
    },
    {
      name: 'C 产品线',
      data: [30, 30, 30, 25],
      color: '#90ed7d'
    }
  ],
  legend: {
    enabled: true,
    layout: 'horizontal',
    align: 'center',
    verticalAlign: 'bottom'
  }
});

效果预览:每根柱子都高 100%,三个颜色区块分别代表三个产品线的占比。第四季度 A 产品线占比上升至 35%,B 产品线下降至 40%,C 产品线下降至 25%。结构变化一目了然。


常见问题与解决方案

1. 图表显示不全或标签重叠?

原因dataLabels 太多,空间不足。

解决:降低字体大小或关闭部分标签:

dataLabels: {
  enabled: true,
  formatter: function() {
    return this.y > 10 ? this.y.toFixed(1) + '%' : ''; // 只显示大于 10% 的标签
  }
}

2. 百分比不准确,总和不是 100%?

原因:数据输入错误或存在 null 值。

解决:确保每根柱子的 data 数组中没有 nullundefined,且所有数值为正数。

3. 图表不响应式?

原因:容器未设置宽度或未启用响应式。

解决:在 chart 选项中添加:

chart: {
  type: 'column',
  responsive: {
    rules: [{
      condition: { maxWidth: 500 },
      chartOptions: {
        legend: { layout: 'horizontal', align: 'center', verticalAlign: 'bottom' }
      }
    }]
  }
}

总结:掌握可视化表达的核心能力

Highcharts 使用百分比的堆叠柱形图,看似只是图表类型的选择,实则是一种数据洞察的思维方式。它让你从“总量”转向“结构”,从“谁多谁少”转向“占比变化”。

通过本文,你已经掌握了:

  • 如何准备正确的数据结构
  • 如何配置 stacking: 'percent' 实现百分比堆叠
  • 如何自定义颜色、标签和样式
  • 如何动态更新数据
  • 如何应对常见问题

这些技能不仅适用于 Highcharts,也适用于其他可视化工具(如 ECharts、Chart.js)中的类似场景。真正重要的,不是某一个库,而是你能否用数据讲故事。

当你下次需要展示“不同时间段的用户行为构成”或“各渠道转化率对比”时,不妨试试 Highcharts 使用百分比的堆叠柱形图 —— 它会让你的报告,多一分说服力,少一分模糊感。