Skip to content

Commit 583711e

Browse files
authored
Merge pull request #17098 from jiawulin001/issue#17021
fix: markArea of bar series now covers whole categories specified
2 parents 9c00766 + 70db7c6 commit 583711e

5 files changed

Lines changed: 240 additions & 10 deletions

File tree

src/chart/bar/BaseBarSeries.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ import {
2929
import GlobalModel from '../../model/Global';
3030
import Cartesian2D from '../../coord/cartesian/Cartesian2D';
3131
import SeriesData from '../../data/SeriesData';
32+
import {dimPermutations} from '../../component/marker/MarkAreaView';
33+
import { each } from 'zrender/src/core/util';
34+
import type Axis2D from '../../coord/cartesian/Axis2D';
3235

3336

3437
export interface BaseBarSeriesOption<StateOption, ExtraStateOption = DefaultStatesMixin>
@@ -82,16 +85,34 @@ class BaseBarSeriesModel<Opts extends BaseBarSeriesOption<unknown> = BaseBarSeri
8285
return createSeriesData(null, this, {useEncodeDefaulter: true});
8386
}
8487

85-
getMarkerPosition(value: ScaleDataValue[]) {
88+
getMarkerPosition(value: ScaleDataValue[], dims?: typeof dimPermutations[number], startingAtTick: boolean = false) {
8689
const coordSys = this.coordinateSystem;
8790
if (coordSys && coordSys.clampData) {
8891
// PENDING if clamp ?
8992
const pt = coordSys.dataToPoint(coordSys.clampData(value));
90-
const data = this.getData();
91-
const offset = data.getLayout('offset');
92-
const size = data.getLayout('size');
93-
const offsetIndex = (coordSys as Cartesian2D).getBaseAxis().isHorizontal() ? 0 : 1;
94-
pt[offsetIndex] += offset + size / 2;
93+
if (startingAtTick) {
94+
each(coordSys.getAxes(), function (axis: Axis2D, idx: number) {
95+
//If axis type is category, use tick coords instead
96+
if (axis.type === 'category') {
97+
const tickCoords = axis.getTicksCoords();
98+
let tickIdx = coordSys.clampData(value)[idx];
99+
//The index of rightmost tick of markArea is 1 larger than x1/y1 index
100+
if (dims && (dims[idx] === 'x1' || dims[idx] === 'y1')) {
101+
tickIdx += 1;
102+
}
103+
(tickIdx > tickCoords.length - 1) && (tickIdx = tickCoords.length - 1);
104+
(tickIdx < 0) && (tickIdx = 0);
105+
tickCoords[tickIdx] && (pt[idx] = axis.toGlobalCoord(tickCoords[tickIdx].coord));
106+
}
107+
});
108+
}
109+
else {
110+
const data = this.getData();
111+
const offset = data.getLayout('offset');
112+
const size = data.getLayout('size');
113+
const offsetIndex = (coordSys as Cartesian2D).getBaseAxis().isHorizontal() ? 0 : 1;
114+
pt[offsetIndex] += offset + size / 2;
115+
}
95116
return pt;
96117
}
97118
return [NaN, NaN];

src/component/marker/MarkAreaView.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,28 @@ function getSingleMarkerEndPoint(
164164
else {
165165
// Chart like bar may have there own marker positioning logic
166166
if (seriesModel.getMarkerPosition) {
167-
// Use the getMarkerPosition
167+
//Consider the case that user input the right-bottom point first
168+
//Pick the larger x and y as 'x1' and 'y1'
169+
const pointValue0 = data.getValues(['x0', 'y0'], idx);
170+
const pointValue1 = data.getValues(['x1', 'y1'], idx);
171+
const clampPointValue0 = coordSys.clampData(pointValue0);
172+
const clampPointValue1 = coordSys.clampData(pointValue1);
173+
const pointValue = [];
174+
if (dims[0] === 'x0') {
175+
pointValue[0] = (clampPointValue0[0] > clampPointValue1[0]) ? pointValue1[0] : pointValue0[0];
176+
}
177+
else {
178+
pointValue[0] = (clampPointValue0[0] > clampPointValue1[0]) ? pointValue0[0] : pointValue1[0];
179+
}
180+
if (dims[1] === 'y0') {
181+
pointValue[1] = (clampPointValue0[1] > clampPointValue1[1]) ? pointValue1[1] : pointValue0[1];
182+
}
183+
else {
184+
pointValue[1] = (clampPointValue0[1] > clampPointValue1[1]) ? pointValue0[1] : pointValue1[1];
185+
}
186+
// Use the getMarkerPoisition
168187
point = seriesModel.getMarkerPosition(
169-
data.getValues(dims, idx)
188+
pointValue, dims, true
170189
);
171190
}
172191
else {
@@ -202,7 +221,7 @@ function getSingleMarkerEndPoint(
202221
return point;
203222
}
204223

205-
const dimPermutations = [['x0', 'y0'], ['x1', 'y0'], ['x1', 'y1'], ['x0', 'y1']] as const;
224+
export const dimPermutations = [['x0', 'y0'], ['x1', 'y0'], ['x1', 'y1'], ['x0', 'y1']] as const;
206225

207226
class MarkAreaView extends MarkerView {
208227

src/coord/CoordinateSystem.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ export interface CoordinateSystem {
137137
// @param point Point in global pixel coordinate system.
138138
containPoint(point: number[]): boolean;
139139

140+
getAxes?: () => Axis[];
141+
140142
getAxis?: (dim?: DimensionName) => Axis;
141143

142144
getBaseAxis?: () => Axis;

src/model/Series.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import { defaultSeriesFormatTooltip } from '../component/tooltip/seriesFormatToo
5757
import {ECSymbol} from '../util/symbol';
5858
import {Group} from '../util/graphic';
5959
import {LegendIconParams} from '../component/legend/LegendModel';
60+
import {dimPermutations} from '../component/marker/MarkAreaView';
6061

6162
const inner = modelUtil.makeInner<{
6263
data: SeriesData
@@ -99,7 +100,10 @@ interface SeriesModel {
99100
/**
100101
* Get position for marker
101102
*/
102-
getMarkerPosition(value: ScaleDataValue[]): number[];
103+
getMarkerPosition(
104+
value: ScaleDataValue[],
105+
dims?: typeof dimPermutations[number],
106+
startingAtTick?:boolean): number[];
103107

104108
/**
105109
* Get legend icon symbol according to each series type

test/bar-markArea.html

Lines changed: 184 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)