Skip to content

Commit

Permalink
feat: comboCombined Layout; feat: combo supports position configurati…
Browse files Browse the repository at this point in the history
…ons for any situations; 4.6.0-beta (#3510)

* docs: add indented tree and brief node demos

* feat: combo supports being assigned positions

* fix: run layout promise only when the layout is configured;

* chore: rebase and version number unpdate

* chore: upgrade

* chore: refine

* chore: refine

* fix: no animate when a node has no previous position

* fix: fix the hidden combos not set correctly (#3509)

close #3508

* chore: update version

* chore: register dagreCompound layout (#3548)

* fix: #3513 切换节点文字位置,文字位置出现错误 (#3531)

Co-authored-by: daichaofan <[email protected]>

* chore: update versions

Co-authored-by: simplejason <[email protected]>
Co-authored-by: daichaofan <[email protected]>
Co-authored-by: daichaofan <[email protected]>
  • Loading branch information
4 people authored Mar 3, 2022
1 parent d86be42 commit 5dd6a79
Show file tree
Hide file tree
Showing 27 changed files with 1,913 additions and 152 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# ChangeLog

#### 4.6.0-beta

- feat: comboCombined Layout from @antv/layout;
- feat: combo supports position configurations for any situations;
- fix: run layout promise only when the layout is configured;

#### 4.5.5

- fix: tooltip with wrong duplicated child DOM nodes;
Expand All @@ -23,6 +29,7 @@
- fix: edge label background with clearItemStates problem;
- fix: edge label with autoRotate false and padding problem;
- fix: changeData in the process of create-edge behavior, an error occurs, closes: #3384;
- fix: node update from no icon to iconfont icon failed;

#### 4.5.1

Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@antv/g6-core",
"version": "0.5.5",
"version": "0.6.0",
"description": "A Graph Visualization Framework in JavaScript",
"keywords": [
"antv",
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/element/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const singleNode: ShapeOptions = {

// 默认的位置(最可能的情形),所以放在最上面
if (labelPosition === 'center') {
return { x: 0, y: 0, text: cfg!.label as string };
return { x: 0, y: 0, text: cfg!.label as string, textBaseline: 'middle', textAlign: 'center' };
}

let { offset } = labelCfg;
Expand All @@ -70,26 +70,30 @@ const singleNode: ShapeOptions = {
x: 0,
y: -size[1] / 2 - (offset as number),
textBaseline: 'bottom', // 文本在图形的上面
textAlign: 'center',
};
break;
case 'bottom':
style = {
x: 0,
y: size[1] / 2 + (offset as number),
textBaseline: 'top',
textAlign: 'center',
};
break;
case 'left':
style = {
x: -size[0] / 2 - (offset as number),
y: 0,
textBaseline: 'middle',
textAlign: 'right',
};
break;
default:
style = {
x: size[0] / 2 + (offset as number),
y: 0,
textBaseline: 'middle',
textAlign: 'left',
};
break;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const colorSet = {
};

export default {
version: '0.5.5',
version: '0.6.0',
rootContainerClassName: 'root-container',
nodeContainerClassName: 'node-container',
edgeContainerClassName: 'edge-container',
Expand Down
118 changes: 88 additions & 30 deletions packages/core/src/graph/controller/item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,22 @@ export default class ItemController {
const children: ComboTree[] = (model as ComboConfig).children;

const comboBBox = getComboBBox(children, graph);
if (!isNaN(comboBBox.x)) model.x = comboBBox.x;
else if (isNaN(model.x)) model.x = Math.random() * 100;
if (!isNaN(comboBBox.y)) model.y = comboBBox.y;
else if (isNaN(model.y)) model.y = Math.random() * 100;
let bboxX, bboxY;
if (!isNaN(comboBBox.x)) bboxX = comboBBox.x;
else if (isNaN(model.x)) bboxX = Math.random() * 100;
if (!isNaN(comboBBox.y)) bboxY = comboBBox.y;
else if (isNaN(model.y)) bboxY = Math.random() * 100;

if (isNaN(model.x) || isNaN(model.y)) {
model.x = bboxX;
model.y = bboxY;
} else {
// if there is x y in model, place the combo according to it and move its succeed items. that means, the priority of the combo's position is higher than succeed items'
const dx = model.x - bboxX;
const dy = model.y - bboxY;
// In the same time, adjust the children's positions
this.updateComboSucceeds(model.id, dx, dy, children);
}

const comboGroup = parent.addGroup();
comboGroup.setZIndex((model as ComboConfig).depth as number);
Expand Down Expand Up @@ -215,6 +227,7 @@ export default class ItemController {

const mapper = graph.get(type + MAPPER_SUFFIX);
const model = item.getModel();
const { x: oriX, y: oriY } = model;

const updateType = item.getUpdateType(cfg);

Expand Down Expand Up @@ -263,30 +276,35 @@ export default class ItemController {
(item as IEdge).setTarget(target);
}
item.update(cfg);
}

// item.update(cfg);

if (type === NODE || type === COMBO) {
} else if (type === NODE) {
item.update(cfg, updateType);
const edges: IEdge[] = (item as INode).getEdges();
const refreshEdge = updateType?.includes('bbox') || updateType === 'move';
if (type === NODE) {
if (updateType === 'move') {
each(edges, (edge: IEdge) => {
this.edgeToBeUpdateMap[edge.getID()] = {
edge: edge,
updateType
};
this.throttleRefresh();
});
} else if (refreshEdge) {
each(edges, (edge: IEdge) => {
edge.refresh(updateType);
});
}
if (updateType === 'move') {
each(edges, (edge: IEdge) => {
this.edgeToBeUpdateMap[edge.getID()] = {
edge: edge,
updateType
};
this.throttleRefresh();
});
} else if (refreshEdge) {
each(edges, (edge: IEdge) => {
edge.refresh(updateType);
});
}
else if (refreshEdge && type === COMBO) {
} else if (type === COMBO) {
item.update(cfg, updateType);
if (!isNaN(cfg.x) || !isNaN(cfg.y)) {
// if there is x y in model, place the combo according to it and move its succeed items. that means, the priority of the combo's position is higher than succeed items'
const dx = (cfg.x - oriX) || 0;
const dy = (cfg.y - oriY) || 0;
// In the same time, adjust the children's positions
this.updateComboSucceeds(model.id, dx, dy);
}
const edges: IEdge[] = (item as INode).getEdges();
const refreshEdge = updateType?.includes('bbox') || updateType === 'move';
if (refreshEdge && type === COMBO) {
const shapeFactory = item.get('shapeFactory');
const shapeType = (model.type as string) || 'circle';
const comboAnimate =
Expand All @@ -311,7 +329,6 @@ export default class ItemController {
}
graph.emit('afterupdateitem', { item, cfg });
}

/**
* 更新边限流,同时可以防止相同的边频繁重复更新
* */
Expand All @@ -324,6 +341,9 @@ export default class ItemController {
Object.keys(edgeToBeUpdateMap).forEach(eid => {
const edge = edgeToBeUpdateMap[eid].edge;
if (!edge || edge.destroyed) return;
const source = edge.getSource();
const target = edge.getTarget();
if (!source || source.destroyed || !target || target.destroyed) return;
edge.refresh(edgeToBeUpdateMap[eid].updateType);
});
this.edgeToBeUpdateMap = {};
Expand All @@ -342,7 +362,7 @@ export default class ItemController {
* @returns
* @memberof ItemController
*/
public updateCombo(combo: ICombo | string, children: ComboTree[]) {
public updateCombo(combo: ICombo | string, children: ComboTree[], followCombo?: boolean) {
const { graph } = this;

if (isString(combo)) {
Expand All @@ -358,10 +378,17 @@ export default class ItemController {
const { x: comboX, y: comboY } = comboBBox;

combo.set('bbox', comboBBox);
combo.update({
x: comboX || model.x,
y: comboY || model.y,
});
let x = comboX, y = comboY;
if (followCombo) {
// position of combo model first
x = isNaN(model.x) ? comboX : model.x;
y = isNaN(model.y) ? comboY : model.y;
} else {
// position of succeed items first
x = isNaN(comboX) ? model.x : comboX;
y = isNaN(comboY) ? model.y : comboY;
}
combo.update({ x, y });

const shapeFactory = combo.get('shapeFactory');
const shapeType = (model.type as string) || 'circle';
Expand Down Expand Up @@ -415,6 +442,37 @@ export default class ItemController {
});
}

/**
* 根据位置差量 dx dy,更新 comboId 后继元素的位置
* */
public updateComboSucceeds(comboId, dx, dy, children = []) {
const { graph } = this;
if (!dx && !dy) return;
let kids = children;
if (!kids?.length) {
const comboTrees = graph.get('comboTrees');
comboTrees?.forEach(child => {
traverseTree(child, subTree => {
if (subTree.id === comboId) {
kids = subTree.children;
return false;
}
return true;
});
});
}
kids?.forEach(child => {
const childItem = graph.findById(child.id);
if (childItem) {
const childModel = childItem.getModel();
this.updateItem(child.id, {
x: (childModel.x || 0) + dx,
y: (childModel.y || 0) + dy
});
}
});
}

/**
* 展开 combo,相关元素出现
* 若子 combo 原先是收起状态,则保持它的收起状态
Expand Down
26 changes: 14 additions & 12 deletions packages/core/src/graph/controller/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ export default abstract class LayoutController {

// 绘制
public refreshLayout() {
const { graph } = this;
const { graph, layoutType, data } = this;
if (!graph) return;
if (graph.get('animate')) {
graph.positionsAnimate();
graph.positionsAnimate(layoutType === 'comboCombined');
} else {
graph.refreshPositions();
graph.refreshPositions(layoutType === 'comboCombined');
}
}

Expand Down Expand Up @@ -154,7 +154,7 @@ export default abstract class LayoutController {
if (comboItem.destroyed) continue;
const model = comboItem.getModel();
if (!comboItem.isVisible()) {
hiddenEdges.push(model);
hiddenCombos.push(model);
continue;
}
combos.push(model);
Expand Down Expand Up @@ -214,13 +214,15 @@ export default abstract class LayoutController {
start = start.then(() => this.reLayoutMethod(layoutMethod, currentCfg));
});

start
.then(() => {
if (layoutCfg.onAllLayoutEnd) layoutCfg.onAllLayoutEnd();
})
.catch((error) => {
console.warn('relayout failed', error);
});
if (layoutMethods?.length) {
start
.then(() => {
if (layoutCfg.onAllLayoutEnd) layoutCfg.onAllLayoutEnd();
})
.catch((error) => {
console.warn('relayout failed', error);
});
}
}

// 筛选参与布局的nodes和edges
Expand Down Expand Up @@ -279,7 +281,7 @@ export default abstract class LayoutController {

// 控制布局动画
// eslint-disable-next-line class-methods-use-this
public layoutAnimate() { }
public layoutAnimate() {}

// 将当前节点的平均中心移动到原点
public moveToZero() {
Expand Down
Loading

0 comments on commit 5dd6a79

Please sign in to comment.