Skip to content

Commit

Permalink
fix: combo collapsed edge problems, closes: #3839; (#3885)
Browse files Browse the repository at this point in the history
* fix: combo collapsed edge problems, closes: #3839;

* feat: fitItems function (#3838)

* feat: fitItems function

* Add test

* Fix bbox lower boundary

* Refactor into focusItems

* chore: update version num

* fix:Add success call in layoutWithWorker (#3873)

Co-authored-by: Yuran Ou <[email protected]>

Co-authored-by: Fabio Tacchelli <[email protected]>
Co-authored-by: Yuran Ou <[email protected]>
Co-authored-by: Yuran Ou <[email protected]>
  • Loading branch information
4 people authored Aug 23, 2022
1 parent 8289a1e commit 594106e
Show file tree
Hide file tree
Showing 21 changed files with 229 additions and 45 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# ChangeLog

#### 4.7.0

- fix: combo collapsed edge problems, closes: #3839;

#### 4.7.0-beta

- feat: force2 from graphin-force;
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.7.0-beta.2",
"version": "0.7.0",
"description": "A Graph Visualization Framework in JavaScript",
"keywords": [
"antv",
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.7.0-beta.1',
version: '0.7.0',
rootContainerClassName: 'root-container',
nodeContainerClassName: 'node-container',
edgeContainerClassName: 'edge-container',
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/graph/controller/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ export default abstract class LayoutController {
}
}

/**
* execute a preset layout before running layout
*/
public abstract initWithPreset(): boolean;

// 初始化节点到 center 附近
Expand All @@ -308,7 +311,7 @@ export default abstract class LayoutController {
const nodeLength = nodes ? nodes.length : 0;
if (!nodeLength) return;

const hasPreset = this.initWithPreset();
const hasPreset = this.initWithPreset?.();

if (hasPreset) return false;

Expand Down
89 changes: 85 additions & 4 deletions packages/core/src/graph/controller/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ export default class ViewController {
graph.translate(viewCenter.x - groupCenter.x, viewCenter.y - groupCenter.y, animate, animateCfg);
}

private animatedFitView(group: IGroup, startMatrix: number[], animateCfg: GraphAnimateConfig, bbox: BBox, viewCenter: Point, groupCenter: Point, ratio: number): void {
private animatedFitView(group: IGroup, startMatrix: number[], animateCfg: GraphAnimateConfig, bbox: BBox, viewCenter: Point, groupCenter: Point,
ratio: number, zoomToFit: boolean): void {
const { graph } = this;
animateCfg = animateCfg ? animateCfg : { duration: 500, easing: 'easeCubic' };

Expand All @@ -58,6 +59,20 @@ export default class ViewController {
if (isNaN(vx) || isNaN(vy)) return;
const translatedMatrix = transform(matrix, [['t', vx, vy]]);

if (!zoomToFit) {
// If zooming is not needed just animate the current translated matrix and return
const animationConfig = getAnimateCfgWithCallback({
animateCfg,
callback: () => {
graph.emit('viewportchange', { action: 'translate', matrix: translatedMatrix });
}
});
group.animate((ratio: number) => {
return { matrix: lerpArray(startMatrix, translatedMatrix, ratio) };
}, animationConfig);
return;
}

// Zoom
const minZoom: number = graph.get('minZoom');
const maxZoom: number = graph.get('maxZoom');
Expand All @@ -67,7 +82,7 @@ export default class ViewController {
realRatio = minZoom;
console.warn('fitview failed, ratio out of range, ratio: %f', ratio, 'graph minzoom has been used instead');
} else if (maxZoom && ratio > maxZoom) {
realRatio = minZoom;
realRatio = maxZoom;
console.warn('fitview failed, ratio out of range, ratio: %f', ratio, 'graph maxzoom has been used instead');
}
let zoomedMatrix = transform(translatedMatrix, [
Expand Down Expand Up @@ -120,7 +135,7 @@ export default class ViewController {
}

if (animate) {
this.animatedFitView(group, startMatrix, animateCfg, bbox, viewCenter, groupCenter, ratio);
this.animatedFitView(group, startMatrix, animateCfg, bbox, viewCenter, groupCenter, ratio, true);
} else {
const dx = viewCenter.x - groupCenter.x;
const dy = viewCenter.y - groupCenter.y;
Expand Down Expand Up @@ -175,7 +190,7 @@ export default class ViewController {
}

if (animate) {
this.animatedFitView(group, startMatrix, animateCfg, bbox, viewCenter, groupCenter, ratio);
this.animatedFitView(group, startMatrix, animateCfg, bbox, viewCenter, groupCenter, ratio, true);
} else {
const initZoomRatio = graph.getZoom();
let endZoom = initZoomRatio * ratio;
Expand Down Expand Up @@ -316,6 +331,72 @@ export default class ViewController {
}
}

public focusItems(items: Item[], zoomToFit: boolean, animate?: boolean, animateCfg?: GraphAnimateConfig): void {
if (!items.length) {
return;
}

const { graph } = this;
const padding = this.getFormatPadding();
const width: number = graph.get('width');
const height: number = graph.get('height');
const group: IGroup = graph.get('group');
const startMatrix = group.getMatrix() || [1, 0, 0, 0, 1, 0, 0, 0, 1];
group.resetMatrix();

let bbox: BBox = {
x: 0, y: 0,
minX: Number.MAX_SAFE_INTEGER, minY: Number.MAX_SAFE_INTEGER,
maxX: Number.MIN_SAFE_INTEGER, maxY: Number.MIN_SAFE_INTEGER,
width: 0, height: 0
};
for (const item of items) {
const itemBBox = item.getBBox();
if (itemBBox.minX < bbox.minX) {
bbox.minX = itemBBox.minX;
}
if (itemBBox.minY < bbox.minY) {
bbox.minY = itemBBox.minY;
}
if (itemBBox.maxX > bbox.maxX) {
bbox.maxX = itemBBox.maxX;
}
if (itemBBox.maxY > bbox.maxY) {
bbox.maxY = itemBBox.maxY;
}
}
bbox.x = bbox.minX;
bbox.y = bbox.minY;
bbox.width = bbox.maxX - bbox.minX;
bbox.height = bbox.maxY - bbox.minY;

if (bbox.width === 0 || bbox.height === 0) return;
const viewCenter = this.getViewCenter();

const groupCenter: Point = {
x: bbox.x + bbox.width / 2,
y: bbox.y + bbox.height / 2,
};

// Compute ratio
const w = (width - padding[1] - padding[3]) / bbox.width;
const h = (height - padding[0] - padding[2]) / bbox.height;
let ratio = w;
if (w > h) {
ratio = h;
}

if (animate) {
this.animatedFitView(group, startMatrix, animateCfg, bbox, viewCenter, groupCenter, ratio, zoomToFit);
} else {
graph.translate(viewCenter.x - groupCenter.x, viewCenter.y - groupCenter.y);

if (zoomToFit && !graph.zoom(ratio, viewCenter)) {
console.warn('zoom failed, ratio out of range, ratio: %f', ratio);
}
}
}

/**
* 改变 canvas 画布的宽度和高度
* @param width canvas 宽度
Expand Down
16 changes: 14 additions & 2 deletions packages/core/src/graph/graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,18 @@ export default abstract class AbstractGraph extends EventEmitter implements IAbs
this.autoPaint();
}

/**
* Focus on the passed items
* @param {Item[]} items Items you want to focus on
* @param {boolean} zoomToFit Wether to zoom on the passed items
* @param {boolean} animate Wether to animate the transition
* @param {GraphAnimateConfig} animateCfg Animation configuration
*/
public focusItems(items: Item[], zoomToFit?: boolean, animate?: boolean, animateCfg?: GraphAnimateConfig): void {
const viewController: ViewController = this.get('viewController');
viewController.focusItems(items, zoomToFit, animate, animateCfg);
}

/**
* 自动重绘
* @internal 仅供内部更新机制调用,外部根据需求调用 render 或 paint 接口
Expand Down Expand Up @@ -2743,8 +2755,8 @@ export default abstract class AbstractGraph extends EventEmitter implements IAbs
let selfEndModel = selfEnd.getModel();
// find the nearest visible ancestor
while (!selfEnd.isVisible()) {
const { parentId: selfEndPId, comboId: selfEndCId } = otherEndModel;
const selfEndParentId = selfEndPId || selfEndCId;
const { parentId: selfEndPId, comboId: selfEndCId } = selfEndModel;
const selfEndParentId = (selfEndPId || selfEndCId) as string;
selfEnd = this.findById(selfEndParentId) as ICombo;
if (!selfEnd || !selfEndParentId) {
return; // if all the ancestors of the oppsite are all hidden, ignore the edge
Expand Down
9 changes: 9 additions & 0 deletions packages/core/src/interface/graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,15 @@ export interface IAbstractGraph extends EventEmitter {
*/
focusItem: (item: Item | string, animate?: boolean, animateCfg?: GraphAnimateConfig) => void;

/**
* Fits the passed items into the view. If no items are passed it will fit the whole graph
* @param {Item[]} items Items you want to fit into the view
* @param {boolean} zoomToFit Wether to zoom on the passed items
* @param {boolean} animate Wheter to animate the transition
* @param {GraphAnimateConfig} animateCfg Animation configuration
*/
focusItems: (items: Item[], zoomToFit?: boolean, animate?: boolean, animateCfg?: GraphAnimateConfig) => void;

/**
* 调整视口适应视图
* @param {Padding} padding 四周围边距
Expand Down
76 changes: 71 additions & 5 deletions packages/core/tests/unit/graph/controller/view-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,18 +111,83 @@ describe('view', () => {
expect(centerPoint.x - 50 < 0.1).toBe(true);
expect(centerPoint.y - 50 < 0.1).toBe(true);
});
it('focus items', () => {
const data = {
nodes: [
{
id: 'node-1',
x: 100,
y: 100,
size: [150, 100],
type: 'simple-rect',
color: '#333',
style: {
fill: '#666',
},
},
{
id: 'node-2',
x: 200,
y: 200,
size: [150, 100],
type: 'simple-rect',
color: '#333',
style: {
fill: '#666',
},
}
],
};
graph.data(data);
graph.render();

const canvas: AbstractCanvas = graph.get('canvas');

let bbox = canvas.getCanvasBBox();

expect(numberEqual(bbox.x, 50, 1)).toBe(true);
expect(numberEqual(bbox.y, 89, 1)).toBe(true);
expect(numberEqual(bbox.maxX, 450, 1)).toBe(true);
expect(numberEqual(bbox.maxY, 410, 1)).toBe(true);
expect(numberEqual(bbox.width, 400, 1)).toBe(true);
expect(numberEqual(bbox.height, 320, 1)).toBe(true);

const node1 = graph.findById('node-1');
graph.focusItems([node1], true);

bbox = graph.get('canvas').getCanvasBBox();

expect(numberEqual(bbox.x, 50, 1)).toBe(true);
expect(numberEqual(bbox.y, 116, 1)).toBe(true);
expect(numberEqual(bbox.maxX, 714, 1)).toBe(true);
expect(numberEqual(bbox.maxY, 648, 1)).toBe(true);
expect(numberEqual(bbox.width, 664, 1)).toBe(true);
expect(numberEqual(bbox.height, 532, 1)).toBe(true);

const node2 = graph.findById('node-2');
graph.focusItems([node1, node2], true);

bbox = graph.get('canvas').getCanvasBBox();

expect(numberEqual(bbox.x, 50, 1)).toBe(true);
expect(numberEqual(bbox.y, 89, 1)).toBe(true);
expect(numberEqual(bbox.maxX, 450, 1)).toBe(true);
expect(numberEqual(bbox.maxY, 410, 1)).toBe(true);
expect(numberEqual(bbox.width, 400, 1)).toBe(true);
expect(numberEqual(bbox.height, 320, 1)).toBe(true);
});
it('focus edge', () => {
const data = {
nodes: [{id: '1', x: 10, y: 10}, {id: '2', x: 25, y: 40}, {id: '3', x: -50, y: 80}],
edges: [{source: '1', target: '2'}, {source: '1', target: '3'}]
nodes: [{ id: '1', x: 10, y: 10 }, { id: '2', x: 25, y: 40 }, { id: '3', x: -50, y: 80 }],
edges: [{ source: '1', target: '2' }, { source: '1', target: '3' }]
}
const g = new Graph({
container: div,
width: 500,
height: 500,
})
g.read(data);
g.get('canvas').get('el').style.backgroundColor='#ccc';
g.get('canvas').get('el').style.backgroundColor = '#ccc';
g.zoom(2, { x: 10, y: 10 });
g.focusItem(g.getEdges()[0]);
let centerPoint = g.getPointByCanvas(250, 250);
Expand All @@ -137,8 +202,9 @@ describe('view', () => {

it('getPointByCanvas', () => {
const point = graph.getPointByCanvas(250, 250);
expect(numberEqual(point.x, 50, 0.1)).toBe(true);
expect(numberEqual(point.y, 50, 0.1)).toBe(true);
console.log('point', point);
expect(numberEqual(point.x, 150, 0.1)).toBe(true);
expect(numberEqual(point.y, 150, 0.1)).toBe(true);
});
});

Expand Down
4 changes: 2 additions & 2 deletions packages/element/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@antv/g6-element",
"version": "0.7.0-beta.2",
"version": "0.7.0",
"description": "A Graph Visualization Framework in JavaScript",
"keywords": [
"antv",
Expand Down Expand Up @@ -61,7 +61,7 @@
},
"dependencies": {
"@antv/g-base": "^0.5.1",
"@antv/g6-core": "0.7.0-beta.2",
"@antv/g6-core": "0.7.0",
"@antv/util": "~2.0.5"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions packages/g6/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@antv/g6",
"version": "4.7.0-beta.2",
"version": "4.7.0",
"description": "A Graph Visualization Framework in JavaScript",
"keywords": [
"antv",
Expand Down Expand Up @@ -66,7 +66,7 @@
]
},
"dependencies": {
"@antv/g6-pc": "0.7.0-beta.2"
"@antv/g6-pc": "0.7.0"
},
"devDependencies": {
"@babel/core": "^7.7.7",
Expand Down
4 changes: 2 additions & 2 deletions packages/g6/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import G6 from '@antv/g6-pc';

G6.version = '4.7.0-beta.2';
G6.version = '4.7.0';

export * from '@antv/g6-pc';
export default G6;
export const version = '4.7.0-beta.2';
export const version = '4.7.0';
10 changes: 5 additions & 5 deletions packages/pc/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@antv/g6-pc",
"version": "0.7.0-beta.2",
"version": "0.7.0",
"description": "A Graph Visualization Framework in JavaScript",
"keywords": [
"antv",
Expand Down Expand Up @@ -75,11 +75,11 @@
"@antv/g-canvas": "^0.5.2",
"@antv/g-math": "^0.1.1",
"@antv/g-svg": "^0.5.1",
"@antv/g6-core": "0.7.0-beta.2",
"@antv/g6-element": "0.7.0-beta.2",
"@antv/g6-plugin": "0.7.0-beta.2",
"@antv/g6-core": "0.7.0",
"@antv/g6-element": "0.7.0",
"@antv/g6-plugin": "0.7.0",
"@antv/hierarchy": "^0.6.7",
"@antv/layout": "^0.3.0-beta.1",
"@antv/layout": "^0.3.0",
"@antv/matrix-util": "^3.1.0-beta.3",
"@antv/path-util": "^2.0.3",
"@antv/util": "~2.0.5",
Expand Down
2 changes: 1 addition & 1 deletion packages/pc/src/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const textColor = 'rgb(0, 0, 0)';
const colorSet = getColorsWithSubjectColor(subjectColor, backColor);

export default {
version: '0.7.0-beta.2',
version: '0.7.0',
rootContainerClassName: 'root-container',
nodeContainerClassName: 'node-container',
edgeContainerClassName: 'edge-container',
Expand Down
Loading

0 comments on commit 594106e

Please sign in to comment.