Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(marker): markArea of bar series now covers whole specified categories #17098

Merged
merged 7 commits into from
Sep 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions src/chart/bar/BaseBarSeries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<StateOption, ExtraStateOption = DefaultStatesMixin>
Expand Down Expand Up @@ -82,16 +85,34 @@ class BaseBarSeriesModel<Opts extends BaseBarSeriesOption<unknown> = 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];
Expand Down
25 changes: 22 additions & 3 deletions src/component/marker/MarkAreaView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {

Expand Down
2 changes: 2 additions & 0 deletions src/coord/CoordinateSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion src/model/Series.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
184 changes: 184 additions & 0 deletions test/bar-markArea.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.