diff --git a/src/chart/bar/BaseBarSeries.ts b/src/chart/bar/BaseBarSeries.ts index 8dad96d280..e21d968300 100644 --- a/src/chart/bar/BaseBarSeries.ts +++ b/src/chart/bar/BaseBarSeries.ts @@ -29,6 +29,9 @@ import { import GlobalModel from '../../model/Global'; import Cartesian2D from '../../coord/cartesian/Cartesian2D'; import SeriesData from '../../data/SeriesData'; +import {dimPermutations} from '../../component/marker/MarkAreaView'; +import { each } from 'zrender/src/core/util'; +import type Axis2D from '../../coord/cartesian/Axis2D'; export interface BaseBarSeriesOption @@ -82,16 +85,34 @@ class BaseBarSeriesModel = BaseBarSeri return createSeriesData(null, this, {useEncodeDefaulter: true}); } - getMarkerPosition(value: ScaleDataValue[]) { + getMarkerPosition(value: ScaleDataValue[], dims?: typeof dimPermutations[number], startingAtTick: boolean = false) { const coordSys = this.coordinateSystem; if (coordSys && coordSys.clampData) { // PENDING if clamp ? const pt = coordSys.dataToPoint(coordSys.clampData(value)); - const data = this.getData(); - const offset = data.getLayout('offset'); - const size = data.getLayout('size'); - const offsetIndex = (coordSys as Cartesian2D).getBaseAxis().isHorizontal() ? 0 : 1; - pt[offsetIndex] += offset + size / 2; + if (startingAtTick) { + each(coordSys.getAxes(), function (axis: Axis2D, idx: number) { + //If axis type is category, use tick coords instead + if (axis.type === 'category') { + const tickCoords = axis.getTicksCoords(); + let tickIdx = coordSys.clampData(value)[idx]; + //The index of rightmost tick of markArea is 1 larger than x1/y1 index + if (dims && (dims[idx] === 'x1' || dims[idx] === 'y1')) { + tickIdx += 1; + } + (tickIdx > tickCoords.length - 1) && (tickIdx = tickCoords.length - 1); + (tickIdx < 0) && (tickIdx = 0); + tickCoords[tickIdx] && (pt[idx] = axis.toGlobalCoord(tickCoords[tickIdx].coord)); + } + }); + } + else { + const data = this.getData(); + const offset = data.getLayout('offset'); + const size = data.getLayout('size'); + const offsetIndex = (coordSys as Cartesian2D).getBaseAxis().isHorizontal() ? 0 : 1; + pt[offsetIndex] += offset + size / 2; + } return pt; } return [NaN, NaN]; diff --git a/src/component/marker/MarkAreaView.ts b/src/component/marker/MarkAreaView.ts index 785d107d87..801a74b6ae 100644 --- a/src/component/marker/MarkAreaView.ts +++ b/src/component/marker/MarkAreaView.ts @@ -164,9 +164,28 @@ function getSingleMarkerEndPoint( else { // Chart like bar may have there own marker positioning logic if (seriesModel.getMarkerPosition) { - // Use the getMarkerPosition + //Consider the case that user input the right-bottom point first + //Pick the larger x and y as 'x1' and 'y1' + const pointValue0 = data.getValues(['x0', 'y0'], idx); + const pointValue1 = data.getValues(['x1', 'y1'], idx); + const clampPointValue0 = coordSys.clampData(pointValue0); + const clampPointValue1 = coordSys.clampData(pointValue1); + const pointValue = []; + if (dims[0] === 'x0') { + pointValue[0] = (clampPointValue0[0] > clampPointValue1[0]) ? pointValue1[0] : pointValue0[0]; + } + else { + pointValue[0] = (clampPointValue0[0] > clampPointValue1[0]) ? pointValue0[0] : pointValue1[0]; + } + if (dims[1] === 'y0') { + pointValue[1] = (clampPointValue0[1] > clampPointValue1[1]) ? pointValue1[1] : pointValue0[1]; + } + else { + pointValue[1] = (clampPointValue0[1] > clampPointValue1[1]) ? pointValue0[1] : pointValue1[1]; + } + // Use the getMarkerPoisition point = seriesModel.getMarkerPosition( - data.getValues(dims, idx) + pointValue, dims, true ); } else { @@ -202,7 +221,7 @@ function getSingleMarkerEndPoint( return point; } -const dimPermutations = [['x0', 'y0'], ['x1', 'y0'], ['x1', 'y1'], ['x0', 'y1']] as const; +export const dimPermutations = [['x0', 'y0'], ['x1', 'y0'], ['x1', 'y1'], ['x0', 'y1']] as const; class MarkAreaView extends MarkerView { diff --git a/src/coord/CoordinateSystem.ts b/src/coord/CoordinateSystem.ts index 0ebe41e916..b27f66acfa 100644 --- a/src/coord/CoordinateSystem.ts +++ b/src/coord/CoordinateSystem.ts @@ -137,6 +137,8 @@ export interface CoordinateSystem { // @param point Point in global pixel coordinate system. containPoint(point: number[]): boolean; + getAxes?: () => Axis[]; + getAxis?: (dim?: DimensionName) => Axis; getBaseAxis?: () => Axis; diff --git a/src/model/Series.ts b/src/model/Series.ts index 4c9b14186e..f4e9923dd9 100644 --- a/src/model/Series.ts +++ b/src/model/Series.ts @@ -57,6 +57,7 @@ import { defaultSeriesFormatTooltip } from '../component/tooltip/seriesFormatToo import {ECSymbol} from '../util/symbol'; import {Group} from '../util/graphic'; import {LegendIconParams} from '../component/legend/LegendModel'; +import {dimPermutations} from '../component/marker/MarkAreaView'; const inner = modelUtil.makeInner<{ data: SeriesData @@ -99,7 +100,10 @@ interface SeriesModel { /** * Get position for marker */ - getMarkerPosition(value: ScaleDataValue[]): number[]; + getMarkerPosition( + value: ScaleDataValue[], + dims?: typeof dimPermutations[number], + startingAtTick?:boolean): number[]; /** * Get legend icon symbol according to each series type diff --git a/test/bar-markArea.html b/test/bar-markArea.html new file mode 100644 index 0000000000..81de2f543a --- /dev/null +++ b/test/bar-markArea.html @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + +