in src/component/graphic/GraphicView.ts [280:365]
private _relocate(graphicModel: GraphicComponentModel, api: ExtensionAPI): void {
const elOptions = graphicModel.option.elements;
const rootGroup = this.group;
const elMap = this._elMap;
const apiWidth = api.getWidth();
const apiHeight = api.getHeight();
const xy = ['x', 'y'] as const;
// Top-down to calculate percentage width/height of group
for (let i = 0; i < elOptions.length; i++) {
const elOption = elOptions[i];
const id = modelUtil.convertOptionIdName(elOption.id, null);
const el = id != null ? elMap.get(id) : null;
if (!el || !el.isGroup) {
continue;
}
const parentEl = el.parent;
const isParentRoot = parentEl === rootGroup;
// Like 'position:absolut' in css, default 0.
const elInner = inner(el);
const parentElInner = inner(parentEl);
elInner.width = parsePercent(
(elInner.option as GraphicComponentGroupOption).width,
isParentRoot ? apiWidth : parentElInner.width
) || 0;
elInner.height = parsePercent(
(elInner.option as GraphicComponentGroupOption).height,
isParentRoot ? apiHeight : parentElInner.height
) || 0;
}
// Bottom-up tranvese all elements (consider ec resize) to locate elements.
for (let i = elOptions.length - 1; i >= 0; i--) {
const elOption = elOptions[i];
const id = modelUtil.convertOptionIdName(elOption.id, null);
const el = id != null ? elMap.get(id) : null;
if (!el) {
continue;
}
const parentEl = el.parent;
const parentElInner = inner(parentEl);
const containerInfo = parentEl === rootGroup
? {
width: apiWidth,
height: apiHeight
}
: {
width: parentElInner.width,
height: parentElInner.height
};
// PENDING
// Currently, when `bounding: 'all'`, the union bounding rect of the group
// does not include the rect of [0, 0, group.width, group.height], which
// is probably weird for users. Should we make a break change for it?
const layoutPos = {} as Record<'x' | 'y', number>;
const layouted = layoutUtil.positionElement(
el, elOption, containerInfo, null,
{ hv: elOption.hv, boundingMode: elOption.bounding },
layoutPos
);
if (!inner(el).isNew && layouted) {
const transition = elOption.transition;
const animatePos = {} as Record<'x' | 'y', number>;
for (let k = 0; k < xy.length; k++) {
const key = xy[k];
const val = layoutPos[key];
if (transition && (isTransitionAll(transition) || zrUtil.indexOf(transition, key) >= 0)) {
animatePos[key] = val;
}
else {
el[key] = val;
}
}
updateProps(el, animatePos, graphicModel, 0);
}
else {
el.attr(layoutPos);
}
}
}