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

使用Chart.js实现分组柱状图与折线图对齐问题求助

解决分组柱状图与折线图的对齐问题

问题核心:分组柱状图中,折线图默认将数据点渲染在每个标签的中心位置,但你需要让Linear(HC)折线的点与HC柱状图的柱子中心对齐。

解决方案(推荐动态适配)

通过Chart.js的**afterLayout插件钩子**,动态获取HC柱状图每个柱子的位置,将折线对应点的坐标同步过去,这种方式能适配任意数量的分组柱子,无需硬编码偏移值。

修改后的完整代码

在你的chartOptions的plugins配置中添加afterLayout钩子:

function draw_grouped_barchart(
  labels_data,
  billable_data,
  non_billable_data,
  total_data,
  bench_data
) {
  const max_y = Math.max(...total_data) * 1.25;
  var barChartData = {
    labels: labels_data,
    datasets: [
      {
        label: "HC",
        backgroundColor: "#64218f",
        borderColor: "#64218f",
        borderWidth: 1,
        data: total_data,
        order: 2,
      },
      {
        label: "Billable",
        backgroundColor: "#a83b8f",
        borderColor: "#a83b8f",
        borderWidth: 1,
        data: billable_data,
        order: 2,
      },
      {
        label: "Non Billable",
        backgroundColor: "#ed8394",
        borderColor: "#ed8394",
        borderWidth: 1,
        data: non_billable_data,
        order: 2,
      },
      {
        label: "Bench",
        backgroundColor: "#f8c7aa",
        borderColor: "#f8c7aa",
        borderWidth: 1,
        data: bench_data,
        order: 2,
      },
      {
        label: "Linear (HC)",
        data: total_data,
        fill: false,
        borderColor: "rgb(75, 192, 192)",
        tension: 0.1,
        type: "line",
        order: 1,
      },
    ],
  };
  var chartOptions = {
    responsive: true,
    plugins: {
      datalabels: {
        anchor: "end",
        align: "top",
        formatter: (value, context) =>
          context.datasetIndex !== 4 ? value : "",
        color: "#000000",
        font: {
          weight: "bold",
          size: 10,
        },
      },
      legend: {
        onClick: () => {
          return "";
        },
        position: "bottom",
        labels: {
          color: "#000000",
          font: {
            size: 10,
          },
          usePointStyle: true,
          generateLabels: (chart) => {
            let pointStyle = [];
            chart.data.datasets.forEach((dataset) => {
              if (dataset.type === "line") {
                pointStyle.push("line");
              } else {
                pointStyle.push("rect");
              }
            });
            return chart.data.datasets.map((dataset, index) => ({
              text: dataset.label,
              fillStyle: dataset.backgroundColor,
              strokeStyle: dataset.borderColor,
              pointStyle: pointStyle[index],
            }));
          },
        },
      },
      title: {
        display: false,
        text: "Allocations Projections (in FTE)",
      },
      // 新增:动态对齐折线点与HC柱子
      afterLayout: (chart) => {
        // 获取HC柱状图的元数据(第一个数据集,索引0)
        const barDatasetMeta = chart.getDatasetMeta(0);
        // 获取折线图的元数据(第五个数据集,索引4)
        const lineDatasetMeta = chart.getDatasetMeta(4);
        
        // 将每个折线点的x坐标设置为对应HC柱子的x坐标
        lineDatasetMeta.data.forEach((linePoint, index) => {
          const barPoint = barDatasetMeta.data[index];
          if (barPoint) {
            linePoint.x = barPoint.x;
          }
        });
      }
    },
    scales: {
      y: {
        display: false,
        beginAtZero: true,
        max: max_y,
      },
      x: {
        display: true,
        grid: {
          display: false,
        },
        ticks: {
          color: "#000000",
          font: {
            size: 10,
          },
        },
        border: {
          color: "#000000",
          width: 2,
          z: 1,
        },
      },
    },
  };
  Chart.register(ChartDataLabels);
  $("#canvas").remove();
  $("#mycanvas").append(
    '<canvas class="w-100" id="canvas" height="350"></canvas>'
  );
  var ctx = document.getElementById("canvas").getContext("2d");
  window.myBar = new Chart(ctx, {
    type: "bar",
    data: barChartData,
    options: chartOptions,
  });
}

为什么之前的offset/transform无效?

offset是针对整个X轴的全局偏移,transform是对图表整体的变换,都无法精准定位到每个分组内的单个柱子位置。而上述方法直接获取HC柱子的实际渲染坐标,能实现点对点的精准对齐。

内容的提问来源于stack exchange,提问作者SRI CHARAN PENDLI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:05:05