apache/echarts · error

Heatmap on cartesian must have two axes with boundaryGap tru

Error message

Heatmap on cartesian must have two axes with boundaryGap true

What it means

DEV-only guard immediately following [4]: for a cartesian heatmap, both category axes must have boundaryGap true (exposed by the helper as axis.onBand). boundaryGap centers categories into bands so heatmap cells align with band centers rather than tick lines. Stripped in production.

Source

Thrown at src/chart/heatmap/HeatmapView.ts:188

    ) {
        const coordSys = seriesModel.coordinateSystem as Cartesian2D | Calendar | Matrix;
        const isCartesian2d = isCoordinateSystemType<Cartesian2D>(coordSys, 'cartesian2d');
        const isMatrix = isCoordinateSystemType<Matrix>(coordSys, 'matrix');
        let width;
        let height;
        let xAxisExtent;
        let yAxisExtent;

        if (isCartesian2d) {
            const xAxis = coordSys.getAxis('x');
            const yAxis = coordSys.getAxis('y');

            if (__DEV__) {
                if (!(xAxis.type === 'category' && yAxis.type === 'category')) {
                    throw new Error('Heatmap on cartesian must have two category axes');
                }
                if (!(xAxis.onBand && yAxis.onBand)) {
                    throw new Error('Heatmap on cartesian must have two axes with boundaryGap true');
                }
            }

            // add 0.5px to avoid the gaps
            width = calcBandWidth(xAxis).w + .5;
            height = calcBandWidth(yAxis).w + .5;
            xAxisExtent = xAxis.scale.getExtent();
            yAxisExtent = yAxis.scale.getExtent();
        }

        const group = this.group;
        const data = seriesModel.getData();

        let emphasisStyle = seriesModel.getModel(['emphasis', 'itemStyle']).getItemStyle();
        let blurStyle = seriesModel.getModel(['blur', 'itemStyle']).getItemStyle();
        let selectStyle = seriesModel.getModel(['select', 'itemStyle']).getItemStyle();
        let borderRadius = seriesModel.get(['itemStyle', 'borderRadius']);
        let labelStatesModels = getLabelStatesModels(seriesModel);

View on GitHub (pinned to 30076aedcd)

Solutions

  1. Set boundaryGap:true (or omit it so the category default applies) on both axes
  2. Remove any explicit boundaryGap:false inherited from another chart's config

Example fix

// before
xAxis: { type: 'category', boundaryGap: false },
yAxis: { type: 'category', boundaryGap: false }

// after
xAxis: { type: 'category', boundaryGap: true },
yAxis: { type: 'category', boundaryGap: true }
Defensive patterns

Strategy: validation

Validate before calling

const axes = [...(option.xAxis || []), ...(option.yAxis || [])];
axes.forEach((a: any) => {
  if (a && a.type === 'category' && a.boundaryGap === false) {
    console.warn('[heatmap] boundaryGap:false conflicts with cartesian heatmap');
  }
});

Prevention

When it happens

Trigger: Setting xAxis.boundaryGap=false (or a [false, ...] pair) on a cartesian heatmap axis; same for yAxis.

Common situations: Reusing an axis config tuned for a bar/candlestick chart with explicit boundaryGap:false; copying config from a K-line example into a heatmap.

Related errors


AI-assisted analysis of apache/echarts@30076aedcd (2026-08-12). Data as JSON: /api/errors/c061b0d867564a4f. Report an issue: GitHub.