Skip to content
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
66 changes: 50 additions & 16 deletions src/chart/custom/CustomView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ import {
applyKeyframeAnimation,
stopPreviousKeyframeAnimationAndRestore
} from '../../animation/customGraphicKeyframeAnimation';
import { SeriesModel } from '../../echarts.all';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import source is incorrect.


const EMPHASIS = 'emphasis' as const;
const NORMAL = 'normal' as const;
Expand Down Expand Up @@ -1264,16 +1265,21 @@ function retrieveStyleOptionOnState(


// Usage:
// (1) By default, `elOption.$mergeChildren` is `'byIndex'`, which indicates that
// the existing children will not be removed, and enables the feature that
// update some of the props of some of the children simply by construct
// (1) By default, `elOption.$mergeChildren` is `'byIndex'`, which indicates
// that the existing children will not be removed, and enables the feature
// that update some of the props of some of the children simply by construct
// the returned children of `renderItem` like:
// `var children = group.children = []; children[3] = {opacity: 0.5};`
// (2) If `elOption.$mergeChildren` is `'byName'`, add/update/remove children
// by child.name. But that might be lower performance.
// (3) If `elOption.$mergeChildren` is `false`, the existing children will be
// replaced totally.
// (4) If `!elOption.children`, following the "merge" principle, nothing will happen.
// (4) If `!elOption.children`, following the "merge" principle, nothing will
// happen.
// (5) If `elOption.$mergeChildren` is not `false` neither `'byName'` and the
// `el` is a group, and if any of the new child is null, it means to remove
// the element at the same index, if exists. On the other hand, if the new
// child is and empty object `{}`, it means to keep the element not changed.
//
// For implementation simpleness, do not provide a direct way to remove sinlge
// child (otherwise the total indicies of the children array have to be modified).
Expand Down Expand Up @@ -1316,24 +1322,52 @@ function mergeChildren(
// might be better performance.
let index = 0;
for (; index < newLen; index++) {
newChildren[index] && doCreateOrUpdateEl(
api,
el.childAt(index),
dataIndex,
newChildren[index] as CustomElementOption,
seriesModel,
el
);
const newChild = newChildren[index];
const oldChild = el.childAt(index);
if (newChild) {
if (newChild.ignore == null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be:

if (newChild.ignore) {
    newChild.ignore = false;
}

or

newChild.ignore = null; // or false

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newChild is the user-provided option. So if newChild.ignore is true, it means the user want to ignore the element so I don't think we should set newChild.ignore = false in this situation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got it wrong

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if users set a child as null / undefined at the first time ? (rather than the second time)

// The old child is set to be ignored if null (see comments
// below). So we need to set ignore to be false back.
newChild.ignore = false;
}
doCreateOrUpdateEl(
api,
oldChild,
dataIndex,
newChild as CustomElementOption,
seriesModel,
el
);
}
else {
// If the new element option is null, it means to remove the old
// element. But we cannot really remove the element from the group
// directly, because the element order may not be stable when this
// element is added back. So we set the element to be ignored.
oldChild.ignore = true;
}
}
for (let i = el.childCount() - 1; i >= index; i--) {
// Do not support leave elements that are not mentioned in the latest
// `renderItem` return. Otherwise users may not have a clear and simple
// concept that how to control all of the elements.
const child = el.childAt(i);
child && applyLeaveTransition(child, customInnerStore(el).option, seriesModel);
removeChildFromGroup(el, child, seriesModel);
}
}

function removeChildFromGroup(
group: graphicUtil.Group,
child: Element,
seriesModel: SeriesModel
) {
// Do not support leave elements that are not mentioned in the latest
// `renderItem` return. Otherwise users may not have a clear and simple
// concept that how to control all of the elements.
child && applyLeaveTransition(
child,
customInnerStore(group).option,
seriesModel
);
}

type DiffGroupContext = {
api: ExtensionAPI;
oldChildren: Element[];
Expand Down
229 changes: 229 additions & 0 deletions test/custom-update.html

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

1 change: 1 addition & 0 deletions test/runTest/actions/__meta__.json

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

1 change: 1 addition & 0 deletions test/runTest/actions/custom-update.json

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