diff --git a/src/chart/heatmap/HeatmapView.ts b/src/chart/heatmap/HeatmapView.ts index f8b912a3d7..bfa781a31f 100644 --- a/src/chart/heatmap/HeatmapView.ts +++ b/src/chart/heatmap/HeatmapView.ts @@ -121,6 +121,13 @@ class HeatmapView extends ChartView { this.group.removeAll(); const coordSys = seriesModel.coordinateSystem; + // The coordinate system may be unresolved, e.g. a heatmap that + // references a `calendar`/`geo`/`bmap` coordinate system whose component + // is missing. Skip rendering instead of throwing on `coordSys.type` + // (`incrementalRender` already guards this the same way). See #19060. + if (!coordSys) { + return; + } if (coordSys.type === 'cartesian2d' || coordSys.type === 'calendar' || coordSys.type === 'matrix' diff --git a/src/coord/Axis.ts b/src/coord/Axis.ts index 1bcb13a01b..e4f986ed25 100644 --- a/src/coord/Axis.ts +++ b/src/coord/Axis.ts @@ -336,8 +336,10 @@ function fixOnBandTicksCoords( return false; } + const axisExtent = axis.getExtent(); + const coordStep = axisExtent[1] >= axisExtent[0] ? bandWidth : -bandWidth; each(preTicksCoords, function (ticksItem) { - ticksItem.coord -= bandWidth / 2; + ticksItem.coord -= coordStep / 2; }); const dataExtent = axis.scale.getExtent(); @@ -346,7 +348,7 @@ function fixOnBandTicksCoords( preTicksCoords.pop(); } preTicksCoords.push({ - coord: oldLast.coord + bandWidth, + coord: oldLast.coord + coordStep, tick: {value: dataExtent[1] + 1}, }); diff --git a/src/coord/View.ts b/src/coord/View.ts index 0cba662625..ac2c75616e 100644 --- a/src/coord/View.ts +++ b/src/coord/View.ts @@ -559,12 +559,18 @@ function legacyCopyOverallTrans( target: Transformable | NullUndefined, overallTrans: Transformable, mtOverall: MatrixArray, - mtOverallInv: MatrixArray + mtOverallInv: MatrixArray | NullUndefined ): void { if (target) { copyTransform(target, overallTrans); matrixCopy(target.transform || (target.transform = []), mtOverall); - matrixCopy(target.invTransform || (target.invTransform = []), mtOverallInv); + const invTransform = target.invTransform || (target.invTransform = matrixCreate()); + if (mtOverallInv) { + // `matrixInvert` returns null if the overall transform is singular (e.g., a + // zero-sized view rect when the chart container is hidden or sized 0x0); + // keep the last inverse in that case rather than crash. + matrixCopy(invTransform, mtOverallInv); + } } } diff --git a/src/processor/dataStack.ts b/src/processor/dataStack.ts index ab41b864d8..eb167cb965 100644 --- a/src/processor/dataStack.ts +++ b/src/processor/dataStack.ts @@ -150,7 +150,11 @@ function calculateStack(stackInfoList: StackInfo[]) { // Considering positive stack, negative stack and empty data if ( - stackStrategy === 'all' // single stack group + // A null/NaN value in a lower series must be excluded from the + // stack, otherwise it corrupts the sum. The other strategies + // already reject it via their `val > 0`/`val < 0` checks, but + // `all` needs an explicit guard. See #21685. + (stackStrategy === 'all' && !isNaN(val)) // single stack group || (stackStrategy === 'positive' && val > 0) || (stackStrategy === 'negative' && val < 0) || (stackStrategy === 'samesign' && sum >= 0 && val > 0) // All positive stack diff --git a/test/bar-markArea.html b/test/bar-markArea.html index fc2eefe9f0..755fb4d8dc 100644 --- a/test/bar-markArea.html +++ b/test/bar-markArea.html @@ -43,6 +43,7 @@
+ + + +