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

Angular 10中Highcharts环形进度条下方添加线性进度条的问题

解决方案:避免环形进度条与线性进度条重叠

针对你遇到的布局重叠问题,以下提供两种可行的实现方案,核心思路是通过空间隔离或手动布局控制来分离两类图表元素:


方案一:拆分容器,独立渲染两个图表

这是最直观且易维护的方案,将环形进度条和线性进度条放在两个独立的DOM容器中,各自初始化Highcharts实例,彻底避免布局冲突。

1. 调整组件模板的HTML结构

<!-- 环形进度条容器,固定高度预留空间 -->
<div id="ring-chart" style="height: 300px;"></div>
<!-- 线性进度条容器,与环形图拉开间距 -->
<div id="progress-chart" style="height: 150px; margin-top: 20px;"></div>

2. 初始化环形进度条(复用原有代码,仅修改容器ID)

// 环形进度条初始化逻辑
new Highcharts.chart('ring-chart', {
  exporting: { enabled: false },
  chart: {
    type: 'solidgauge',
    events: {
      render() {
        let chart = this,
          label1 = chart.series[0].dataLabelsGroup,
          label2 = chart.series[1].dataLabelsGroup;

        label1.translate(chart.marginRight, 0);
        label2.translate(chart.marginRight, chart.plotTop - label2.getBBox().height);
      }
    }
  },
  legend: { enabled: false },
  credits: { enabled: false },
  pane: {
    startAngle: 180,
    background: this.getBackgroundSettingsForDepositStatusGraph()
  },
  tooltip: { outside: true },
  title: false,
  accessibility: { point: { valueSuffix: '' } },
  xAxis: {
    tickInterval: 1,
    minorGridLineWidth: 0,
    labels: {
      align: 'right',
      useHTML: true,
      allowOverlap: true,
      step: 1,
      y: 3,
      style: { fontSize: '13px', color: "black" }
    },
    lineWidth: 0,
  },
  yAxis: { min: 0, max: 100, lineWidth: 0, tickPositions: [] },
  plotOptions: {
    solidgauge: {
      dataLabels: { enabled: true, verticalAlign: 'middle' },
    }
  },
  series: [
    {
      name: "Total",
      data: [{
        color: Highcharts.getOptions().colors[0],
        radius: "115%",
        innerRadius: "110%",
        y: Math.round(this.data.total.percentage),
        dataLabels: { format: "{y}%", borderWidth: 0, style: { fontSize: "15px" } }
      }]
    },
    {
      name: 'Amount',
      data: [{
        color: Highcharts.getOptions().colors[2],
        radius: "105%",
        innerRadius: "100%",
        y: Math.round(this.data.amount.percentage),
        dataLabels: { format: "{y}%", borderWidth: 0, style: { fontSize: "15px" } }
      }]
    }
  ]
});

3. 初始化线性进度条(用bar图表模拟,支持显示额外数据)

// 线性进度条初始化逻辑
new Highcharts.chart('progress-chart', {
  chart: { type: 'bar' },
  exporting: { enabled: false },
  credits: { enabled: false },
  title: false,
  legend: { enabled: false },
  xAxis: {
    categories: ['Total', 'Amount'],
    lineWidth: 0,
    tickWidth: 0,
    labels: { style: { fontSize: '14px', fontWeight: 'bold' } }
  },
  yAxis: {
    min: 0,
    max: 100,
    lineWidth: 0,
    tickPositions: [],
    title: false
  },
  tooltip: { enabled: false },
  plotOptions: {
    bar: {
      borderRadius: 3,
      dataLabels: {
        enabled: true,
        align: 'right',
        // 自定义格式:百分比 + 额外数据
        format: '{point.y}% | {point.extraData1} {point.extraData2}',
        style: { fontSize: '13px' }
      }
    }
  },
  series: [{
    data: [
      {
        y: Math.round(this.data.total.percentage),
        color: Highcharts.getOptions().colors[0],
        extraData1: this.data.total.value1, // 替换为你的实际数据(如25)
        extraData2: this.data.total.value2  // 替换为你的实际数据(如60)
      },
      {
        y: Math.round(this.data.amount.percentage),
        color: Highcharts.getOptions().colors[2],
        extraData1: this.data.amount.value1,
        extraData2: this.data.amount.value2
      }
    ]
  }]
});

方案二:同一容器内调整布局,用Renderer绘制线性进度条

如果希望保持单一容器,可通过扩展环形图的容器高度、预留底部空间,再用Highcharts的Renderer手动绘制线性进度条和文本,避免元素重叠。

修改原有环形图配置并添加绘制逻辑

new Highcharts.chart('container', {
  exporting: { enabled: false },
  chart: {
    type: 'solidgauge',
    height: 450, // 增加容器总高度
    spacingBottom: 150, // 预留底部空间给线性进度条
    events: {
      render() {
        let chart = this;
        // 原有标签定位逻辑
        let label1 = chart.series[0].dataLabelsGroup,
            label2 = chart.series[1].dataLabelsGroup;
        label1.translate(chart.marginRight, 0);
        label2.translate(chart.marginRight, chart.plotTop - label2.getBBox().height);

        // 清除上一次渲染的自定义元素,避免重复绘制
        if (chart.customElements) {
          chart.customElements.forEach(el => el.destroy());
        }
        chart.customElements = [];

        // 定义进度条基础参数
        const barWidth = chart.plotWidth * 0.7;
        const barHeight = 20;
        const startX = chart.plotLeft + (chart.plotWidth - barWidth) / 2;
        const totalBarY = chart.plotTop + chart.plotHeight + 20;
        const amountBarY = totalBarY + barHeight + 15;

        // 绘制Total进度条
        // 灰色背景条
        const totalBg = chart.renderer.rect(startX, totalBarY, barWidth, barHeight, 3)
          .attr({ fill: '#e0e0e0' })
          .add();
        chart.customElements.push(totalBg);
        // 彩色进度条
        const totalProgress = chart.renderer.rect(startX, totalBarY, (this.data.total.percentage / 100) * barWidth, barHeight, 3)
          .attr({ fill: Highcharts.getOptions().colors[0] })
          .add();
        chart.customElements.push(totalProgress);
        // 显示文本:Total 25 60 85%
        const totalText = chart.renderer.text(
          `Total ${this.data.total.value1} ${this.data.total.value2} ${Math.round(this.data.total.percentage)}%`,
          startX + 10, totalBarY + barHeight / 2 + 5
        ).attr({ style: { fontSize: '14px' } })
        .add();
        chart.customElements.push(totalText);

        // 绘制Amount进度条
        const amountBg = chart.renderer.rect(startX, amountBarY, barWidth, barHeight, 3)
          .attr({ fill: '#e0e0e0' })
          .add();
        chart.customElements.push(amountBg);
        const amountProgress = chart.renderer.rect(startX, amountBarY, (this.data.amount.percentage / 100) * barWidth, barHeight, 3)
          .attr({ fill: Highcharts.getOptions().colors[2] })
          .add();
        chart.customElements.push(amountProgress);
        const amountText = chart.renderer.text(
          `Amount ${this.data.amount.value1} ${this.data.amount.value2} ${Math.round(this.data.amount.percentage)}%`,
          startX + 10, amountBarY + barHeight / 2 + 5
        ).attr({ style: { fontSize: '14px' } })
        .add();
        chart.customElements.push(amountText);
      }
    }
  },
  // 其余原有配置(pane、xAxis、yAxis、series等)保持不变
  // ...
});

方案对比

  • 方案一:代码逻辑清晰,两个图表独立维护,无耦合,适合后续需要单独调整样式或交互的场景;
  • 方案二:保持单一容器,视觉上更紧凑,但需要手动管理自定义元素的渲染与销毁,适合布局要求严格的场景。

内容的提问来源于stack exchange,提问作者Athulya Ratheesh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:08:08