Skip to content

Commit

Permalink
Merge pull request #12775 from apache/custom-series-enhance
Browse files Browse the repository at this point in the history
Custom series enhancement (for-next)
  • Loading branch information
100pah authored Jun 23, 2020
2 parents 55794d0 + a7d4f69 commit 9963aa4
Show file tree
Hide file tree
Showing 19 changed files with 5,009 additions and 436 deletions.
1,745 changes: 1,411 additions & 334 deletions src/chart/custom.ts

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion src/component/axis/RadiusAxisView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,18 @@ class RadiusAxisView extends AxisView {

axisPointerClass = 'PolarAxisPointer';

private _axisGroup: graphic.Group;

render(radiusAxisModel: RadiusAxisModel, ecModel: GlobalModel) {
this.group.removeAll();
if (!radiusAxisModel.get('show')) {
return;
}

const oldAxisGroup = this._axisGroup;
const newAxisGroup = this._axisGroup = new graphic.Group();
this.group.add(newAxisGroup);

const radiusAxis = radiusAxisModel.axis;
const polar = radiusAxis.polar;
const angleAxis = polar.getAngleAxis();
Expand All @@ -58,7 +65,9 @@ class RadiusAxisView extends AxisView {
const layout = layoutAxis(polar, radiusAxisModel, axisAngle);
const axisBuilder = new AxisBuilder(radiusAxisModel, layout);
zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);
this.group.add(axisBuilder.getGroup());
newAxisGroup.add(axisBuilder.getGroup());

graphic.groupTransition(oldAxisGroup, newAxisGroup, radiusAxisModel);

zrUtil.each(selfBuilderAttrs, function (name) {
if (radiusAxisModel.get([name, 'show']) && !radiusAxis.scale.isBlank()) {
Expand Down
2 changes: 1 addition & 1 deletion src/component/visualMap/PiecewiseModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class PiecewiseModel extends VisualMapModel<PiecewiseVisualMapOption> {
const isCategory = this.isCategory();

zrUtil.each(option.pieces, function (piece) {
zrUtil.each(visualTypes, function (visualType) {
zrUtil.each(visualTypes, function (visualType: BuiltinVisualProperty) {
if (piece.hasOwnProperty(visualType)) {
visualTypesInPieces[visualType] = 1;
}
Expand Down
3 changes: 3 additions & 0 deletions src/coord/CoordinateSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { BoundingRect } from '../util/graphic';
import { MatrixArray } from 'zrender/src/core/matrix';
import ComponentModel from '../model/Component';
import { RectLike } from 'zrender/src/core/BoundingRect';
import { PrepareCustomInfo } from '../chart/custom';


export interface CoordinateSystemCreator {
Expand Down Expand Up @@ -151,6 +152,8 @@ export interface CoordinateSystem {
// Currently only Cartesian2D implements it.
// But if other coordinate systems implement it, should follow this signature.
getAxesByScale?: (scaleType: string) => Axis[];

prepareCustoms?: PrepareCustomInfo;
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/coord/polar/prepareCustom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import RadiusAxis from './RadiusAxis';

function dataToCoordSize(this: Polar, dataSize: number[], dataItem: number[]) {
// dataItem is necessary in log axis.
dataItem = dataItem || [0, 0];
return zrUtil.map(['Radius', 'Angle'], function (dim, dimIdx) {
const getterName = 'get' + dim + 'Axis' as 'getAngleAxis'| 'getRadiusAxis';
// TODO: TYPE Check Angle Axis
Expand Down
4 changes: 4 additions & 0 deletions src/echarts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1802,6 +1802,9 @@ class ECharts extends Eventful {
};

updateZ = function (model: ComponentModel, view: ComponentView | ChartView): void {
if (model.preventAutoZ) {
return;
}
const z = model.get('z');
const zlevel = model.get('zlevel');
// Set z and zlevel
Expand All @@ -1816,6 +1819,7 @@ class ECharts extends Eventful {
textContent.z = el.z;
textContent.zlevel = el.zlevel;
// lift z2 of text content
// TODO if el.emphasis.z2 is spcefied, what about textContent.
textContent.z2 = el.z2 + 1;
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/model/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ class ComponentModel<Opt extends ComponentOption = ComponentOption> extends Mode
*/
static layoutMode: ComponentLayoutMode | ComponentLayoutMode['type'];

/**
* Prevent from auto set z, zlevel, z2 by the framework.
*/
preventAutoZ: boolean;

// Injectable properties:
__viewId: string;

Expand Down
2 changes: 1 addition & 1 deletion src/model/mixin/itemStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type ItemStyleKeys = 'fill'
| 'shadowOffsetY'
| 'shadowColor';

type ItemStyleProps = Pick<PathStyleProps, ItemStyleKeys>;
export type ItemStyleProps = Pick<PathStyleProps, ItemStyleKeys>;

class ItemStyleMixin {

Expand Down
108 changes: 63 additions & 45 deletions src/util/graphic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
DataModel,
ECEventData,
ZRStyleProps,
TextCommonOption,
SeriesOption,
ParsedValue,
CallbackDataParams
Expand All @@ -73,13 +74,13 @@ import {
trim,
isArrayLike,
map,
defaults
defaults,
isObject
} from 'zrender/src/core/util';
import * as numberUtil from './number';
import SeriesModel from '../model/Series';
import {OnframeCallback, interpolateNumber} from 'zrender/src/animation/Animator';
import {interpolateNumber} from 'zrender/src/animation/Animator';
import List from '../data/List';
import DataFormatMixin from '../model/mixin/dataFormat';


const mathMax = Math.max;
Expand All @@ -89,13 +90,6 @@ const EMPTY_OBJ = {};

export const Z2_EMPHASIS_LIFT = 10;

// key: label model property nane, value: style property name.
export const CACHED_LABEL_STYLE_PROPERTIES = {
color: 'textFill',
textBorderColor: 'textStroke',
textBorderWidth: 'textStrokeWidth'
};

const EMPHASIS = 'emphasis';
const NORMAL = 'normal';

Expand Down Expand Up @@ -134,8 +128,6 @@ type TextCommonParams = {

forceRich?: boolean

getTextPosition?: (textStyleModel: Model, isEmphasis?: boolean) => string | string[] | number[]

defaultOutsidePosition?: LabelOption['position']

textStyle?: ZRStyleProps
Expand Down Expand Up @@ -398,12 +390,14 @@ function singleEnterEmphasis(el: Element) {
if (!hasFillOrStroke(emphasisStyle.stroke)) {
disp.style.stroke = liftColor(currentStroke);
}
disp.z2 += Z2_EMPHASIS_LIFT;
const z2EmphasisLift = (disp as ECElement).z2EmphasisLift;
disp.z2 += z2EmphasisLift != null ? z2EmphasisLift : Z2_EMPHASIS_LIFT;
}

const textContent = el.getTextContent();
if (textContent) {
textContent.z2 += Z2_EMPHASIS_LIFT;
const z2EmphasisLift = (textContent as ECElement).z2EmphasisLift;
textContent.z2 += z2EmphasisLift != null ? z2EmphasisLift : Z2_EMPHASIS_LIFT;
}
// TODO hover layer
}
Expand Down Expand Up @@ -793,6 +787,7 @@ export function createTextConfig(
opt: TextCommonParams,
isEmphasis: boolean
) {
opt = opt || {};
const textConfig: ElementTextConfig = {};
let labelPosition;
let labelRotate = textStyleModel.getShallow('rotate');
Expand All @@ -801,16 +796,11 @@ export function createTextConfig(
);
const labelOffset = textStyleModel.getShallow('offset');

if (opt.getTextPosition) {
labelPosition = opt.getTextPosition(textStyleModel, isEmphasis);
}
else {
labelPosition = textStyleModel.getShallow('position')
|| (isEmphasis ? null : 'inside');
// 'outside' is not a valid zr textPostion value, but used
// in bar series, and magric type should be considered.
labelPosition === 'outside' && (labelPosition = opt.defaultOutsidePosition || 'top');
}
labelPosition = textStyleModel.getShallow('position')
|| (isEmphasis ? null : 'inside');
// 'outside' is not a valid zr textPostion value, but used
// in bar series, and magric type should be considered.
labelPosition === 'outside' && (labelPosition = opt.defaultOutsidePosition || 'top');

if (labelPosition != null) {
textConfig.position = labelPosition;
Expand Down Expand Up @@ -1054,7 +1044,10 @@ function setTokenTextStyle(
}
}

export function getFont(opt: LabelOption, ecModel: GlobalModel) {
export function getFont(
opt: Pick<TextCommonOption, 'fontStyle' | 'fontWeight' | 'fontSize' | 'fontFamily'>,
ecModel: GlobalModel
) {
const gTextStyleModel = ecModel && ecModel.getModel('textStyle');
return trim([
// FIXME in node-canvas fontWeight is before fontStyle
Expand All @@ -1065,22 +1058,36 @@ export function getFont(opt: LabelOption, ecModel: GlobalModel) {
].join(' '));
}

type AnimateOrSetPropsOption = {
dataIndex?: number;
cb?: () => void;
during?: (percent: number) => void;
isFrom?: boolean;
};

function animateOrSetProps<Props>(
isUpdate: boolean,
el: Element<Props>,
props: Props,
animatableModel?: Model<AnimationOptionMixin> & {
getAnimationDelayParams?: (el: Element<Props>, dataIndex: number) => AnimationDelayCallbackParam
},
dataIndex?: number | (() => void),
cb?: () => void,
during?: (percent: number) => void
dataIndex?: AnimateOrSetPropsOption['dataIndex'] | AnimateOrSetPropsOption['cb'] | AnimateOrSetPropsOption,
cb?: AnimateOrSetPropsOption['cb'] | AnimateOrSetPropsOption['during'],
during?: AnimateOrSetPropsOption['during']
) {
let isFrom = false;
if (typeof dataIndex === 'function') {
during = cb;
cb = dataIndex;
dataIndex = null;
}
else if (isObject(dataIndex)) {
cb = dataIndex.cb;
during = dataIndex.during;
isFrom = dataIndex.isFrom;
dataIndex = dataIndex.dataIndex;
}
// Do not check 'animation' property directly here. Consider this case:
// animation model is an `itemModel`, whose does not have `isAnimationEnabled`
// but its parent model (`seriesModel`) does.
Expand Down Expand Up @@ -1109,20 +1116,31 @@ function animateOrSetProps<Props>(
}

duration > 0
? el.animateTo(props, {
duration,
delay: animationDelay || 0,
easing: animationEasing,
done: cb,
force: !!cb || !!during,
during: during
})
: (el.stopAnimation(), el.attr(props), cb && cb());
? (
isFrom
? el.animateFrom(props, {
duration,
delay: animationDelay || 0,
easing: animationEasing,
done: cb,
force: !!cb || !!during,
during: during
})
: el.animateTo(props, {
duration,
delay: animationDelay || 0,
easing: animationEasing,
done: cb,
force: !!cb || !!during,
during: during
})
)
: (el.stopAnimation(), el.attr(props), cb && (cb as AnimateOrSetPropsOption['cb'])());
}
else {
el.stopAnimation();
el.attr(props);
cb && cb();
!isFrom && el.attr(props);
cb && (cb as AnimateOrSetPropsOption['cb'])();
}
}

Expand All @@ -1147,9 +1165,9 @@ function updateProps<Props>(
props: Props,
// TODO: TYPE AnimatableModel
animatableModel?: Model<AnimationOptionMixin>,
dataIndex?: number | (() => void),
cb?: () => void,
during?: () => void
dataIndex?: AnimateOrSetPropsOption['dataIndex'] | AnimateOrSetPropsOption['cb'] | AnimateOrSetPropsOption,
cb?: AnimateOrSetPropsOption['cb'] | AnimateOrSetPropsOption['during'],
during?: AnimateOrSetPropsOption['during']
) {
animateOrSetProps(true, el, props, animatableModel, dataIndex, cb, during);
}
Expand All @@ -1168,9 +1186,9 @@ export function initProps<Props>(
el: Element<Props>,
props: Props,
animatableModel?: Model<AnimationOptionMixin>,
dataIndex?: number | (() => void),
cb?: () => void,
during?: () => void
dataIndex?: AnimateOrSetPropsOption['dataIndex'] | AnimateOrSetPropsOption['cb'] | AnimateOrSetPropsOption,
cb?: AnimateOrSetPropsOption['cb'] | AnimateOrSetPropsOption['during'],
during?: AnimateOrSetPropsOption['during']
) {
animateOrSetProps(false, el, props, animatableModel, dataIndex, cb, during);
}
Expand Down
Loading

0 comments on commit 9963aa4

Please sign in to comment.