You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2020/10/19 09:35:28 UTC
[incubator-echarts] branch next updated: refact(label): provide
general method for value animation
This is an automated email from the ASF dual-hosted git repository.
shenyi pushed a commit to branch next
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git
The following commit(s) were added to refs/heads/next by this push:
new c358735 refact(label): provide general method for value animation
c358735 is described below
commit c3587358caf147b30fc99757caadb5aa2ec56766
Author: pissang <bm...@gmail.com>
AuthorDate: Mon Oct 19 17:32:44 2020 +0800
refact(label): provide general method for value animation
---
src/chart/bar/BarView.ts | 30 +++++---------
src/chart/helper/labelHelper.ts | 2 +-
src/label/LabelManager.ts | 23 +++++++----
src/label/labelStyle.ts | 87 ++++++++++++++++++++++++++++++++++++++++-
src/util/graphic.ts | 78 +-----------------------------------
5 files changed, 113 insertions(+), 107 deletions(-)
diff --git a/src/chart/bar/BarView.ts b/src/chart/bar/BarView.ts
index 8cb3556..8e4469e 100644
--- a/src/chart/bar/BarView.ts
+++ b/src/chart/bar/BarView.ts
@@ -25,13 +25,11 @@ import {
Sector,
updateProps,
initProps,
- updateLabel,
- initLabel,
removeElementWithFadeOut
} from '../../util/graphic';
import { getECData } from '../../util/innerStore';
import { enableHoverEmphasis, setStatesStylesFromModel } from '../../util/states';
-import { setLabelStyle, getLabelStatesModels, labelInner } from '../../label/labelStyle';
+import { setLabelStyle, getLabelStatesModels, labelInner, setLabelValueAnimation } from '../../label/labelStyle';
import {throttle} from '../../util/throttle';
import {createClipPath} from '../helper/createClipPathFromCoordSys';
import Sausage from '../../util/shape/sausage';
@@ -291,16 +289,10 @@ class BarView extends ChartView {
el, data, dataIndex, itemModel, layout,
seriesModel, isHorizontalOrRadial, coord.type === 'polar'
);
-
- initLabel(
- el, data, dataIndex, itemModel.getModel('label'), seriesModel, animationModel, defaultTextGetter
- );
if (isInitSort) {
(el as Rect).attr({ shape: layout });
}
else if (realtimeSort) {
- (el as unknown as ECElement).disableLabelAnimation = true;
-
updateRealtimeAnimation(
seriesModel,
axis2DModel,
@@ -381,17 +373,12 @@ class BarView extends ChartView {
el, data, newIndex, itemModel, layout,
seriesModel, isHorizontalOrRadial, coord.type === 'polar'
);
- updateLabel(
- el, data, newIndex, itemModel.getModel('label'), seriesModel, animationModel, defaultTextGetter
- );
}
if (isInitSort) {
(el as Rect).attr({ shape: layout });
}
else if (realtimeSort) {
- (el as unknown as ECElement).disableLabelAnimation = true;
-
updateRealtimeAnimation(
seriesModel,
axis2DModel,
@@ -863,9 +850,10 @@ function updateStyle(
const labelPositionOutside = isHorizontal
? ((layout as RectLayout).height > 0 ? 'bottom' as const : 'top' as const)
: ((layout as RectLayout).width > 0 ? 'left' as const : 'right' as const);
+ const labelStatesModels = getLabelStatesModels(itemModel);
setLabelStyle(
- el, getLabelStatesModels(itemModel),
+ el, labelStatesModels,
{
labelFetcher: seriesModel,
labelDataIndex: dataIndex,
@@ -876,11 +864,13 @@ function updateStyle(
);
const label = el.getTextContent();
- if (label) {
- const obj = labelInner(label);
- obj.prevValue = obj.value;
- obj.value = seriesModel.getRawValue(dataIndex) as ParsedValue | ParsedValue[];
- }
+
+ setLabelValueAnimation(
+ label,
+ labelStatesModels,
+ seriesModel.getRawValue(dataIndex) as ParsedValue,
+ (value: number) => getDefaultInterpolatedLabel(data, value)
+ );
}
const emphasisModel = itemModel.getModel(['emphasis']);
diff --git a/src/chart/helper/labelHelper.ts b/src/chart/helper/labelHelper.ts
index 2396e93..5e45f21 100644
--- a/src/chart/helper/labelHelper.ts
+++ b/src/chart/helper/labelHelper.ts
@@ -49,7 +49,7 @@ export function getDefaultLabel(
export function getDefaultInterpolatedLabel(
data: List,
interpolatedValue: ParsedValue | ParsedValue[]
-) {
+): string {
const labelDims = data.mapDimensionsAll('defaultedLabel');
if (!isArray(interpolatedValue)) {
return interpolatedValue + '';
diff --git a/src/label/LabelManager.ts b/src/label/LabelManager.ts
index eb7e65e..76a41ca 100644
--- a/src/label/LabelManager.ts
+++ b/src/label/LabelManager.ts
@@ -51,6 +51,7 @@ import { retrieve2, each, keys, isFunction, filter, indexOf } from 'zrender/src/
import { PathStyleProps } from 'zrender/src/graphic/Path';
import Model from '../model/Model';
import { prepareLayoutList, hideOverlap, shiftLayoutOnX, shiftLayoutOnY } from './labelLayoutHelper';
+import { labelInner, animateLabelValue } from './labelStyle';
interface LabelDesc {
label: ZRText
@@ -495,20 +496,26 @@ class LabelManager {
if (textEl && !textEl.ignore && !textEl.invisible && !(el as ECElement).disableLabelAnimation) {
const layoutStore = labelLayoutInnerStore(textEl);
const oldLayout = layoutStore.oldLayout;
- const dataIndex = getECData(el).dataIndex;
+ const ecData = getECData(el);
+ const dataIndex = ecData.dataIndex;
const newProps = {
x: textEl.x,
y: textEl.y,
rotation: textEl.rotation
};
+ const data = seriesModel.getData(ecData.dataType);
+
if (!oldLayout) {
textEl.attr(newProps);
- const oldOpacity = retrieve2(textEl.style.opacity, 1);
- // Fade in animation
- textEl.style.opacity = 0;
- initProps(textEl, {
- style: { opacity: oldOpacity }
- }, seriesModel, dataIndex);
+ // Disable fade in animation if value animation is enabled.
+ if (!labelInner(textEl).valueAnimation) {
+ const oldOpacity = retrieve2(textEl.style.opacity, 1);
+ // Fade in animation
+ textEl.style.opacity = 0;
+ initProps(textEl, {
+ style: { opacity: oldOpacity }
+ }, seriesModel, dataIndex);
+ }
}
else {
textEl.attr(oldLayout);
@@ -538,6 +545,8 @@ class LabelManager {
extendWithKeys(layoutEmphasis, newProps, LABEL_LAYOUT_PROPS);
extendWithKeys(layoutEmphasis, textEl.states.emphasis, LABEL_LAYOUT_PROPS);
}
+
+ animateLabelValue(textEl, dataIndex, data, seriesModel);
}
if (guideLine && !guideLine.ignore && !guideLine.invisible) {
diff --git a/src/label/labelStyle.ts b/src/label/labelStyle.ts
index d166dcd..4471fb8 100644
--- a/src/label/labelStyle.ts
+++ b/src/label/labelStyle.ts
@@ -17,7 +17,10 @@ import GlobalModel from '../model/Global';
import { isFunction, retrieve2, extend, keys, trim } from 'zrender/src/core/util';
import { SPECIAL_STATES, DISPLAY_STATES } from '../util/states';
import { deprecateReplaceLog } from '../util/log';
-import { makeInner } from '../util/model';
+import { makeInner, interpolateRawValues } from '../util/model';
+import List from '../data/List';
+import SeriesModel from '../model/Series';
+import { initProps, updateProps } from '../util/graphic';
type TextCommonParams = {
/**
@@ -586,7 +589,87 @@ export const labelInner = makeInner<{
*/
value?: ParsedValue | ParsedValue[]
/**
+ * If enable value animation
+ */
+ valueAnimation?: boolean
+ /**
+ * Label value precision during animation.
+ */
+ precision?: number | 'auto'
+
+ /**
+ * If enable value animation
+ */
+ statesModels?: LabelStatesModels<LabelModelForText>
+ /**
+ * Default text getter during interpolation
+ */
+ defaultInterpolatedText?: (value: ParsedValue[] | ParsedValue) => string
+ /**
* Change label text from interpolated text during animation
*/
setLabelText?(overrideValue?: ParsedValue | ParsedValue[]): void
-}, ZRText>();
\ No newline at end of file
+}, ZRText>();
+
+export function setLabelValueAnimation(
+ label: ZRText,
+ labelStatesModels: LabelStatesModels<LabelModelForText>,
+ value: ParsedValue | ParsedValue[],
+ getDefaultText: (value: ParsedValue[] | ParsedValue) => string
+) {
+ if (!label) {
+ return;
+ }
+
+ const obj = labelInner(label);
+ obj.prevValue = obj.value;
+ obj.value = value;
+
+ const normalLabelModel = labelStatesModels.normal;
+
+ obj.valueAnimation = normalLabelModel.get('valueAnimation');
+
+ if (obj.valueAnimation) {
+ obj.precision = normalLabelModel.get('precision');
+ obj.defaultInterpolatedText = getDefaultText;
+ obj.statesModels = labelStatesModels;
+ }
+}
+
+export function animateLabelValue(
+ textEl: ZRText,
+ dataIndex: number,
+ data: List,
+ seriesModel: SeriesModel
+) {
+ const labelInnerStore = labelInner(textEl);
+ if (!labelInnerStore.valueAnimation) {
+ return;
+ }
+ const defaultInterpolatedText = labelInnerStore.defaultInterpolatedText;
+ const prevValue = labelInnerStore.prevValue;
+ const currentValue = labelInnerStore.value;
+
+ function during(percent: number) {
+ const interpolated = interpolateRawValues(
+ data,
+ labelInnerStore.precision,
+ prevValue,
+ currentValue,
+ percent
+ );
+
+ const labelText = getLabelText({
+ labelDataIndex: dataIndex,
+ // labelFetcher: seriesModel,
+ defaultText: defaultInterpolatedText
+ ? defaultInterpolatedText(interpolated)
+ : interpolated + ''
+ }, labelInnerStore.statesModels, interpolated);
+
+ setLabelText(textEl, labelText);
+ }
+
+ (prevValue == null ? initProps
+ : updateProps)(textEl, {}, seriesModel, dataIndex, null, during);
+}
\ No newline at end of file
diff --git a/src/util/graphic.ts b/src/util/graphic.ts
index 01490d7..dfeb952 100644
--- a/src/util/graphic.ts
+++ b/src/util/graphic.ts
@@ -45,15 +45,13 @@ import IncrementalDisplayable from 'zrender/src/graphic/IncrementalDisplayable';
import * as subPixelOptimizeUtil from 'zrender/src/graphic/helper/subPixelOptimize';
import { Dictionary } from 'zrender/src/core/types';
import Displayable, { DisplayableProps } from 'zrender/src/graphic/Displayable';
-import Element, { ElementProps } from 'zrender/src/Element';
+import Element from 'zrender/src/Element';
import Model from '../model/Model';
import {
AnimationOptionMixin,
- LabelOption,
AnimationDelayCallbackParam,
ZRRectLike,
ZRStyleProps,
- ParsedValue,
PayloadAnimationPart
} from './types';
import {
@@ -63,12 +61,8 @@ import {
defaults,
isObject
} from 'zrender/src/core/util';
-import SeriesModel from '../model/Series';
-import List from '../data/List';
-import { getLabelText, setLabelText, labelInner } from '../label/labelStyle';
import { AnimationEasing } from 'zrender/src/animation/easing';
import { getECData } from './innerStore';
-import {interpolateRawValues} from './model';
const mathMax = Math.max;
@@ -531,76 +525,6 @@ export function isElementRemoved(el: Element) {
return false;
}
-function animateOrSetLabel<Props extends PathProps>(
- animationType: 'init' | 'update' | 'remove',
- el: Element<Props>,
- data: List,
- dataIndex: number,
- labelModel: Model<LabelOption>,
- seriesModel: SeriesModel,
- animatableModel?: Model<AnimationOptionMixin>,
- getDefaultText?: (value: ParsedValue[] | ParsedValue) => string
-) {
- const valueAnimationEnabled = labelModel && labelModel.get('valueAnimation');
- const label = el.getTextContent();
- if (valueAnimationEnabled && label) {
- const precision = labelModel ? labelModel.get('precision') : null;
- const host = labelInner(label);
-
- const sourceValue = host.prevValue;
- const targetValue = host.value;
-
- const during = (percent: number) => {
- const text = el.getTextContent();
- if (!text || !host) {
- return;
- }
-
- const interpolated = interpolateRawValues(data, precision, sourceValue, targetValue, percent);
-
- const labelText = getLabelText({
- labelDataIndex: dataIndex,
- labelFetcher: seriesModel,
- defaultText: getDefaultText
- ? getDefaultText(interpolated)
- : interpolated + ''
- }, {normal: labelModel}, interpolated);
-
- setLabelText(text, labelText);
- };
-
- host.prevValue = targetValue;
-
- const props: ElementProps = {};
- animateOrSetProps(animationType, el, props, animatableModel, dataIndex, null, during);
- }
-}
-
-
-export function updateLabel<Props>(
- el: Element<Props>,
- data: List,
- dataIndex: number,
- labelModel: Model<LabelOption>,
- seriesModel: SeriesModel,
- animatableModel?: Model<AnimationOptionMixin>,
- defaultTextGetter?: (value: ParsedValue[] | ParsedValue) => string
-) {
- animateOrSetLabel('update', el, data, dataIndex, labelModel, seriesModel, animatableModel, defaultTextGetter);
-}
-
-export function initLabel<Props>(
- el: Element<Props>,
- data: List,
- dataIndex: number,
- labelModel: Model<LabelOption>,
- seriesModel: SeriesModel,
- animatableModel?: Model<AnimationOptionMixin>,
- defaultTextGetter?: (value: ParsedValue[] | ParsedValue) => string
-) {
- animateOrSetLabel('init', el, data, dataIndex, labelModel, seriesModel, animatableModel, defaultTextGetter);
-}
-
/**
* Get transform matrix of target (param target),
* in coordinate of its ancestor (param ancestor)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org