diff --git a/src/chart/bar/BarSeries.ts b/src/chart/bar/BarSeries.ts index de03a19eaf..2be64628a4 100644 --- a/src/chart/bar/BarSeries.ts +++ b/src/chart/bar/BarSeries.ts @@ -81,6 +81,8 @@ export interface BarSeriesOption showBackground?: boolean + startValue?: number + backgroundStyle?: ItemStyleOption & { borderRadius?: number | number[] } diff --git a/src/coord/axisCommonTypes.ts b/src/coord/axisCommonTypes.ts index fbfaf9cf43..cdbef2acd2 100644 --- a/src/coord/axisCommonTypes.ts +++ b/src/coord/axisCommonTypes.ts @@ -80,6 +80,7 @@ export interface AxisBaseOptionCommon extends ComponentOption, * + null/undefined: auto decide max value (consider pretty look and boundaryGap). */ max?: ScaleDataValue | 'dataMax' | ((extent: {min: number, max: number}) => ScaleDataValue); + startValue?: number; } diff --git a/src/coord/scaleRawExtentInfo.ts b/src/coord/scaleRawExtentInfo.ts index 52f6b8d062..78c29cc0cf 100644 --- a/src/coord/scaleRawExtentInfo.ts +++ b/src/coord/scaleRawExtentInfo.ts @@ -98,7 +98,11 @@ export class ScaleRawExtentInfo { const isOrdinal = this._isOrdinal = scale.type === 'ordinal'; this._needCrossZero = scale.type === 'interval' && model.getNeedCrossZero && model.getNeedCrossZero(); - const modelMinRaw = this._modelMinRaw = model.get('min', true); + let axisMinValue = model.get('min', true); + if (axisMinValue == null) { + axisMinValue = model.get('startValue', true); + } + const modelMinRaw = this._modelMinRaw = axisMinValue; if (isFunction(modelMinRaw)) { // This callback always provides users the full data extent (before data is filtered). this._modelMinNum = parseAxisModelMinMax(scale, modelMinRaw({ diff --git a/src/layout/barGrid.ts b/src/layout/barGrid.ts index 726c084f82..3f6aeb4fb6 100644 --- a/src/layout/barGrid.ts +++ b/src/layout/barGrid.ts @@ -512,14 +512,13 @@ export function createProgressiveLayout(seriesType: string): StageHandler { while ((dataIndex = params.next()) != null) { const value = store.get(stacked ? stackedDimIdx : valueDimIdx, dataIndex); const baseValue = store.get(baseDimIdx, dataIndex) as number; - let baseCoord = valueAxisStart; - let startValue; + let stackStartValue; // Because of the barMinHeight, we can not use the value in // stackResultDimension directly. if (stacked) { - startValue = +value - (store.get(valueDimIdx, dataIndex) as number); + stackStartValue = +value - (store.get(valueDimIdx, dataIndex) as number); } let x; @@ -530,7 +529,7 @@ export function createProgressiveLayout(seriesType: string): StageHandler { if (isValueAxisH) { const coord = cartesian.dataToPoint([value, baseValue]); if (stacked) { - const startCoord = cartesian.dataToPoint([startValue, baseValue]); + const startCoord = cartesian.dataToPoint([stackStartValue, baseValue]); baseCoord = startCoord[0]; } x = baseCoord; @@ -545,7 +544,7 @@ export function createProgressiveLayout(seriesType: string): StageHandler { else { const coord = cartesian.dataToPoint([baseValue, value]); if (stacked) { - const startCoord = cartesian.dataToPoint([baseValue, startValue]); + const startCoord = cartesian.dataToPoint([baseValue, stackStartValue]); baseCoord = startCoord[1]; } x = coord[0] + columnOffset; @@ -603,5 +602,13 @@ function isInLargeMode(seriesModel: BarSeriesModel) { // See cases in `test/bar-start.html` and `#7412`, `#8747`. function getValueAxisStart(baseAxis: Axis2D, valueAxis: Axis2D) { - return valueAxis.toGlobalCoord(valueAxis.dataToCoord(valueAxis.type === 'log' ? 1 : 0)); + let startValue = valueAxis.model.get('startValue'); + if (!startValue) { + startValue = 0; + } + return valueAxis.toGlobalCoord( + valueAxis.dataToCoord( + valueAxis.type === 'log' + ? (startValue > 0 ? startValue : 1) + : startValue)); } diff --git a/src/layout/barPolar.ts b/src/layout/barPolar.ts index 48d8b4fa95..6e1d054fe0 100644 --- a/src/layout/barPolar.ts +++ b/src/layout/barPolar.ts @@ -27,6 +27,7 @@ import RadiusAxis from '../coord/polar/RadiusAxis'; import GlobalModel from '../model/Global'; import ExtensionAPI from '../core/ExtensionAPI'; import { Dictionary } from '../util/types'; +import { PolarAxisModel } from '../coord/polar/AxisModel'; type PolarAxis = AngleAxis | RadiusAxis; @@ -104,7 +105,10 @@ function barLayoutPolar(seriesType: string, ecModel: GlobalModel, api: Extension const clampLayout = baseAxis.dim !== 'radius' || !seriesModel.get('roundCap', true); - const valueAxisStart = valueAxis.dataToCoord(0); + const valueAxisModel = valueAxis.model as PolarAxisModel; + const startValue = valueAxisModel.get('startValue'); + const valueAxisStart = valueAxis.dataToCoord(startValue || 0); + for (let idx = 0, len = data.count(); idx < len; idx++) { const value = data.get(valueDim, idx) as number; const baseValue = data.get(baseDim, idx) as number; diff --git a/test/bar-startValue.html b/test/bar-startValue.html new file mode 100644 index 0000000000..57cb62b06d --- /dev/null +++ b/test/bar-startValue.html @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + +