{"record":{"id":"9fb6a7ddbf771102","repo":"apache/echarts","slug":"heatmap-on-cartesian-must-have-two-category-axes","errorCode":null,"errorMessage":"Heatmap on cartesian must have two category axes","messagePattern":"Heatmap on cartesian must have two category axes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/chart/heatmap/HeatmapView.ts","lineNumber":185,"sourceCode":"        start: number,\n        end: number,\n        useIncremental?: boolean\n    ) {\n        const coordSys = seriesModel.coordinateSystem as Cartesian2D | Calendar | Matrix;\n        const isCartesian2d = isCoordinateSystemType<Cartesian2D>(coordSys, 'cartesian2d');\n        const isMatrix = isCoordinateSystemType<Matrix>(coordSys, 'matrix');\n        let width;\n        let height;\n        let xAxisExtent;\n        let yAxisExtent;\n\n        if (isCartesian2d) {\n            const xAxis = coordSys.getAxis('x');\n            const yAxis = coordSys.getAxis('y');\n\n            if (__DEV__) {\n                if (!(xAxis.type === 'category' && yAxis.type === 'category')) {\n                    throw new Error('Heatmap on cartesian must have two category axes');\n                }\n                if (!(xAxis.onBand && yAxis.onBand)) {\n                    throw new Error('Heatmap on cartesian must have two axes with boundaryGap true');\n                }\n            }\n\n            // add 0.5px to avoid the gaps\n            width = calcBandWidth(xAxis).w + .5;\n            height = calcBandWidth(yAxis).w + .5;\n            xAxisExtent = xAxis.scale.getExtent();\n            yAxisExtent = yAxis.scale.getExtent();\n        }\n\n        const group = this.group;\n        const data = seriesModel.getData();\n\n        let emphasisStyle = seriesModel.getModel(['emphasis', 'itemStyle']).getItemStyle();\n        let blurStyle = seriesModel.getModel(['blur', 'itemStyle']).getItemStyle();","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/apache/echarts/blob/30076aedcd7b7f65d8dd8e8d9ece46ce778133a3/src/chart/heatmap/HeatmapView.ts#L167-L203","documentation":"DEV-only guard in HeatmapView rendering: when a heatmap is placed on a cartesian2d coordinate system, BOTH the x and y axes must be of type 'category'. A cartesian heatmap lays cells out on category bands, so value axes are unsupported there. Stripped in production.","triggerScenarios":"Heatmap series on a grid whose xAxis.type or yAxis.type is 'value' (the implicit default in some axis setups) instead of 'category'.","commonSituations":"Reusing a line/bar grid (value axes) for a heatmap; forgetting to set xAxis.type='category' on both axes; data-driven axis config that flips type.","solutions":["Set xAxis.type='category' AND yAxis.type='category' on the grid the heatmap uses","Supply matching category data arrays on both axes","Use a different coordSys (calendar or matrix) if categories do not fit a grid"],"exampleFix":"// before\nxAxis: { type: 'value' }, yAxis: { type: 'value' },\nseries: [{ type: 'heatmap', data: [...] }]\n\n// after\nxAxis: { type: 'category', data: hours },\nyAxis: { type: 'category', data: days },\nseries: [{ type: 'heatmap', data: [...] }]","handlingStrategy":"validation","validationCode":"const hm = (option.series || []).find((s: any) => s.type === 'heatmap');\nif (hm && (hm.coordinateSystem == null || hm.coordinateSystem === 'cartesian2d')) {\n  const xa = (option.xAxis && option.xAxis[0]) || {};\n  const ya = (option.yAxis && option.yAxis[0]) || {};\n  if (xa.type !== 'category' || ya.type !== 'category') {\n    console.error('[heatmap] both cartesian axes must be category');\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use category axes for cartesian heatmaps","Validate axis types before setOption","Reuse the canonical heatmap grid config rather than a bar/grid config"],"tags":["heatmap","cartesian","axis-type","dev-only"],"backgroundTag":null,"analyzedSha":"30076aedcd7b7f65d8dd8e8d9ece46ce778133a3","analyzedAt":"2026-08-12T12:42:28.134Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}