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

AMCharts 5同一图表实现堆叠柱状图与折线图多系列混合展示

AMCharts 5 堆叠柱+折线同图实现方案

你的代码无法渲染折线的核心错误如下:

  • 折线系列写在了生成柱状图的makeSeries循环里,每生成1个柱形就会重复创建1个折线系列,共生成6个重复折线引发渲染冲突
  • 折线的字段映射完全写反:Y轴数值字段应该绑定budget,X轴分类字段应该绑定year,原代码把两个字段填反了
  • 折线的样式配置API调用错误:不存在series0.LineSeries.template属性,折线的tooltip等配置需要直接在系列初始化时设置,或通过series0.bullets.push添加
  • 存在冗余无效代码:定义了未赋值的xAxis2、data2变量,会直接触发JS错误阻断整个图表渲染
  • 折线系列未设置name属性,也没有加入图例数据,就算渲染成功也不会在图例中显示
  • 额外注意:你的柱形数值总和最高不到10,而budget数值在100-155区间,如果共用同一个左侧Y轴,柱形会被压缩到几乎看不见,建议给折线配置独立的右侧Y轴。

修正后可直接运行的代码

am5.ready(function () {
    var cssId = "chartDiv"; // 替换成你自己的容器ID
    var root = am5.Root.new(cssId);
    root.setThemes([
        am5themes_Animated.new(root)
    ]);

    // 初始化图表
    var chart = root.container.children.push(am5xy.XYChart.new(root, {
        panX: false,
        panY: false,
        wheelX: "panX",
        wheelY: "zoomX",
        layout: root.verticalLayout
    }));

    var data = [{
        "year": "2021",
        "europe": 2.5,
        "namerica": 2.5,
        "asia": 2.1,
        "lamerica": 1,
        "meast": 0.8,
        "africa": 0.4,
        "budget": 155
    }, {
        "year": "2022",
        "europe": 2.6,
        "namerica": 2.7,
        "asia": 2.2,
        "lamerica": 0.5,
        "meast": 0.4,
        "africa": 0.3,
        "budget": 100
    }, {
        "year": "2023",
        "europe": 2.8,
        "namerica": 2.9,
        "asia": 2.4,
        "lamerica": 0.3,
        "meast": 0.9,
        "africa": 0.5,
        "budget": 120
    }]

    // X轴 (年份维度,柱形和折线共用)
    var xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
        categoryField: "year",
        renderer: am5xy.AxisRendererX.new(root, {}),
        tooltip: am5.Tooltip.new(root, {})
    }));
    xAxis.data.setAll(data);

    // 左侧Y轴 给堆叠柱形用
    var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
        min: 0,
        calculateTotals: true, // 要显示柱形总计需要开启该配置
        renderer: am5xy.AxisRendererY.new(root, {
            opposite: false
        })
    }));

    // 右侧Y轴 给预算折线用 (如果要共用左侧Y轴删掉这段,折线的yAxis改成yAxis即可)
    var yAxis2 = chart.yAxes.push(am5xy.ValueAxis.new(root, {
        min: 0,
        renderer: am5xy.AxisRendererY.new(root, {
            opposite: true
        })
    }));

    // 图例
    var legend = chart.children.push(am5.Legend.new(root, {
        centerX: am5.p50,
        x: am5.p50
    }));

    // 自定义配色
    chart.get("colors").set("colors", [
        am5.color("#d8764b"),
        am5.color("#ca4c6a"),
        am5.color("#188a89"),
        am5.color("#189bd0"),
        am5.color("#241047"),
        am5.color("#f59e0b") // 折线单独配色
    ]);

    // 生成堆叠柱形系列
    function makeColumnSeries(name, fieldName) {
        var series = chart.series.push(am5xy.ColumnSeries.new(root, {
            name: name,
            stacked: true,
            maskBullets: false,
            xAxis: xAxis,
            yAxis: yAxis,
            valueYField: fieldName,
            categoryXField: "year"
        }));

        series.columns.template.setAll({
            tooltipText: "{name}, {categoryX}: {valueY}",
            tooltipY: am5.percent(10)
        });
        series.data.setAll(data);

        // 柱形内部数值标签
        series.bullets.push(function () {
            return am5.Bullet.new(root, {
                sprite: am5.Label.new(root, {
                    text: "{valueY}",
                    fill: root.interfaceColors.get("alternativeText"),
                    centerY: am5.p50,
                    centerX: am5.p50,
                    populateText: true
                })
            });
        });

        legend.data.push(series);
        series.appear();
    }

    // 生成所有柱形
    makeColumnSeries("Europe", "europe");
    makeColumnSeries("North America", "namerica");
    makeColumnSeries("Asia", "asia");
    makeColumnSeries("Latin America", "lamerica");
    makeColumnSeries("Middle East", "meast");
    makeColumnSeries("Africa", "africa");

    // 柱形堆叠总计标签 放在最外层只加一次,不要在循环里重复加
    var totalSeries = chart.series.values[0]; // 取第一个柱形系列加总计标签即可
    totalSeries.bullets.push(function () {
        return am5.Bullet.new(root, {
            locationY: 1,
            sprite: am5.Label.new(root, {
                text: "{valueYTotal}",
                fill: am5.color(0x000000),
                centerY: am5.p100,
                centerX: am5.p50,
                populateText: true
            })
        });
    });

    // 单独生成预算折线系列,不要放在柱形循环里
    var budgetSeries = chart.series.push(am5xy.LineSeries.new(root, {
        name: "Budget",
        xAxis: xAxis,
        yAxis: yAxis2, // 共用左侧Y轴就改成yAxis
        valueYField: "budget",
        categoryXField: "year",
        stroke: am5.color("#f59e0b"),
        strokeWidth: 3,
        tooltip: am5.Tooltip.new(root, {
            labelText: "{name}, {categoryX}: {valueY}"
        })
    }));
    // 折线数据点标记
    budgetSeries.bullets.push(function() {
        return am5.Bullet.new(root, {
            sprite: am5.Circle.new(root, {
                radius: 5,
                fill: budgetSeries.get("stroke")
            })
        })
    })
    budgetSeries.data.setAll(data);
    legend.data.push(budgetSeries);
    budgetSeries.appear();

    chart.appear(1000, 100);
});

关键实现说明

  • 柱形和折线都绑定同一个年份X轴,不需要额外创建第二个X轴
  • 折线系列单独初始化,不放在柱形生成的循环里,避免重复创建
  • 针对柱形和折线数值量级差异大的问题,默认配置了双Y轴,柱形用左侧轴、折线用右侧轴,不会出现图形被压缩的问题
  • 堆叠总计标签只需要在第一个柱形系列上添加一次即可,不需要每个柱形系列都加
  • 折线添加了数据点圆点标记和tooltip,和柱形一起加入图例,交互逻辑统一

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:18:41