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

Chart.js中能否在一个Box Annotation上叠加绘制另一个?

实现双层级带状区域:能否用两个Box Annotation替代三个?

我需要实现两个层级的带状区域,目前已通过三个Box Annotation实现该效果,但希望仅使用两个注释(一个设置yMin: 4, yMax: 14,另一个设置yMin: 2, yMax: 18)来完成,请问是否可行?

原实现代码

<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.1.1/dist/chart.umd.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@2.1.1/dist/chartjs-plugin-annotation.min.js"></script>

</head>
<body>
  <div>
    <canvas id="myChart"></canvas>
  </div>

  <script>
    const ctx = document.getElementById('myChart');

    const inner = {
      type: 'box',
      borderWidth: 0,
      drawTime: 'beforeDraw',
      yMin: 4,
      yMax: 14,
      backgroundColor: '#bdc3c7'
    };

    const outerUpper = {
      type: 'box',
      borderWidth: 0,
      drawTime: 'beforeDraw',
      yMin: 2,
      yMax: 4,
      backgroundColor: '#ecf0f1'
    };

    const outerLower = {
      type: 'box',
      borderWidth: 0,
      drawTime: 'beforeDraw',
      yMin: 14,
      yMax: 18,
      backgroundColor: '#ecf0f1'
    };

    new Chart(ctx, {
      type: 'line',
      data: {
        datasets: [{
          data: [12, 19, 3, 5, 2, 3],
        }]
      },
      options: {
        scales: {
          y: {
            beginAtZero: true
          }
        },
        plugins: {
          legend: {
            display: false
          },
          annotation: {
            annotations: {
              inner,
              outerUpper,
              outerLower
            }
          }
        }
      },
    });
  </script>
</body>
</html>

解决方案:用两个Box Annotation实现

可行,核心思路是利用绘制顺序让内层区域覆盖外层区域的中间部分,最终呈现双层带状效果。

修改后的代码

<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.1.1/dist/chart.umd.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@2.1.1/dist/chartjs-plugin-annotation.min.js"></script>
</head>
<body>
  <div>
    <canvas id="myChart"></canvas>
  </div>

  <script>
    const ctx = document.getElementById('myChart');

    // 先绘制外层大区域,覆盖y=2到y=18的范围
    const outerArea = {
      type: 'box',
      borderWidth: 0,
      drawTime: 'beforeDraw',
      yMin: 2,
      yMax: 18,
      backgroundColor: '#ecf0f1'
    };

    // 后绘制内层区域,覆盖外层的中间部分(y=4到y=14)
    const innerArea = {
      type: 'box',
      borderWidth: 0,
      drawTime: 'afterDraw',
      yMin: 4,
      yMax: 14,
      backgroundColor: '#bdc3c7'
    };

    new Chart(ctx, {
      type: 'line',
      data: {
        datasets: [{
          data: [12, 19, 3, 5, 2, 3],
        }]
      },
      options: {
        scales: {
          y: {
            beginAtZero: true
          }
        },
        plugins: {
          legend: {
            display: false
          },
          annotation: {
            annotations: {
              outerArea,
              innerArea
            }
          }
        }
      },
    });
  </script>
</body>
</html>

关键说明

  • 控制drawTime属性:外层用beforeDraw优先绘制,内层用afterDraw随后绘制,确保内层能覆盖外层的中间区域
  • 无需额外处理边界,Box Annotation的矩形填充特性会让后绘制的区域完全覆盖先绘制的重叠部分,最终视觉效果和三个Box的实现完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 07:35:11