mirror of
https://gitee.com/antv/g6.git
synced 2024-11-30 18:58:34 +08:00
fix: force layout with addItem and relayout. closes: #1275.
This commit is contained in:
parent
5b1ab44280
commit
5b6f5491a6
@ -6,6 +6,7 @@
|
||||
- feat: Floyd Warshall shortest path algorithm;
|
||||
- feat: built-in arrows;
|
||||
- feat: built-in markers;
|
||||
- fix: force layout with addItem and relayout.
|
||||
|
||||
#### 3.5.7
|
||||
- feat: shouldBegin for click-select behavior;
|
||||
|
@ -236,12 +236,10 @@ export default class EventController {
|
||||
const canvas: Canvas = graph.get('canvas');
|
||||
|
||||
each(EVENTS, event => {
|
||||
console.log(' event', event);
|
||||
canvas.off(event, canvasHandler);
|
||||
});
|
||||
|
||||
each(extendEvents, event => {
|
||||
console.log('extend event', event);
|
||||
event.remove();
|
||||
});
|
||||
|
||||
|
@ -419,7 +419,7 @@ export default class LayoutController {
|
||||
layoutMethod.forceSimulation.stop();
|
||||
}
|
||||
graph.emit('beforelayout');
|
||||
layoutMethod.execute();
|
||||
layoutMethod.execute(reloadData);
|
||||
if (this.layoutType !== 'force' && !layoutMethod.enableTick) {
|
||||
graph.emit('afterlayout');
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ export default class ForceLayout<Cfg = any> extends BaseLayout {
|
||||
|
||||
/** 是否正在布局 */
|
||||
private ticking: boolean | undefined = undefined;
|
||||
private edgeForce: any;
|
||||
|
||||
public getDefaultCfg() {
|
||||
return {
|
||||
@ -104,7 +105,7 @@ export default class ForceLayout<Cfg = any> extends BaseLayout {
|
||||
/**
|
||||
* 执行布局
|
||||
*/
|
||||
public execute() {
|
||||
public execute(reloadData?: boolean) {
|
||||
const self = this;
|
||||
const nodes = self.nodes;
|
||||
const edges = self.edges;
|
||||
@ -147,6 +148,7 @@ export default class ForceLayout<Cfg = any> extends BaseLayout {
|
||||
if (self.linkDistance) {
|
||||
edgeForce.distance(self.linkDistance);
|
||||
}
|
||||
self.edgeForce = edgeForce;
|
||||
simulation.force('link', edgeForce);
|
||||
}
|
||||
if (self.workerEnabled && !isInWorker()) {
|
||||
@ -188,6 +190,10 @@ export default class ForceLayout<Cfg = any> extends BaseLayout {
|
||||
console.warn(e);
|
||||
}
|
||||
} else {
|
||||
if (reloadData) {
|
||||
simulation.nodes(nodes);
|
||||
self.edgeForce.links(edges);
|
||||
}
|
||||
if (self.preventOverlap) {
|
||||
self.overlapProcess(simulation);
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ export interface ModeOption {
|
||||
onlyChangeComboSize?: boolean;
|
||||
includeEdges?: boolean;
|
||||
direction?: 'x' | 'y';
|
||||
offset: number;
|
||||
offset?: number;
|
||||
shouldUpdate?: (e: IG6GraphEvent) => boolean;
|
||||
shouldBegin?: (e: IG6GraphEvent) => boolean;
|
||||
shouldEnd?: (e: IG6GraphEvent) => boolean;
|
||||
|
87
stories/Layout/component/force-layout.tsx
Normal file
87
stories/Layout/component/force-layout.tsx
Normal file
@ -0,0 +1,87 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import G6 from '../../../src';
|
||||
import { IGraph } from '../../../src/interface/graph';
|
||||
|
||||
let graph: IGraph = null;
|
||||
|
||||
const ForceLayout = () => {
|
||||
const container = React.useRef();
|
||||
useEffect(() => {
|
||||
if (!graph) {
|
||||
|
||||
const graph = new G6.Graph({
|
||||
container: container.current as string | HTMLElement,
|
||||
width: 500,
|
||||
height: 500,
|
||||
layout: {
|
||||
type: 'force',
|
||||
},
|
||||
defaultNode: {
|
||||
size: 15,
|
||||
color: '#5B8FF9',
|
||||
style: {
|
||||
lineWidth: 2,
|
||||
fill: '#C6E5FF',
|
||||
},
|
||||
},
|
||||
defaultEdge: {
|
||||
size: 1,
|
||||
color: '#e2e2e2',
|
||||
},
|
||||
modes: {
|
||||
default: ['drag-canvas']
|
||||
}
|
||||
});
|
||||
fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/relations.json')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
graph.data({
|
||||
nodes: data.nodes,
|
||||
edges: data.edges.map(function (edge, i) {
|
||||
edge.id = 'edge' + i;
|
||||
return Object.assign({}, edge);
|
||||
}),
|
||||
});
|
||||
|
||||
graph.render();
|
||||
|
||||
const forceLayout = graph.get('layoutController').layoutMethod;
|
||||
graph.on('node:dragstart', function (e) {
|
||||
graph.layout()
|
||||
refreshDragedNodePosition(e);
|
||||
});
|
||||
graph.on('node:drag', function (e) {
|
||||
forceLayout.execute();
|
||||
refreshDragedNodePosition(e);
|
||||
});
|
||||
graph.on('node:dragend', function (e) {
|
||||
e.item.get('model').fx = null;
|
||||
e.item.get('model').fy = null;
|
||||
});
|
||||
|
||||
graph.on('canvas:click', e => {
|
||||
graph.addItem('node', {
|
||||
id: 'newnode',
|
||||
label: 'xx',
|
||||
x: 0,
|
||||
y: 0
|
||||
})
|
||||
graph.addItem('edge', {
|
||||
source: 'newnode',
|
||||
target: 'Myriel'
|
||||
})
|
||||
graph.layout()
|
||||
});
|
||||
});
|
||||
|
||||
const refreshDragedNodePosition = (e) => {
|
||||
const model = e.item.get('model');
|
||||
model.fx = e.x;
|
||||
model.fy = e.y;
|
||||
}
|
||||
}
|
||||
});
|
||||
return <div ref={container}></div>;
|
||||
};
|
||||
|
||||
export default ForceLayout;
|
@ -7,6 +7,7 @@ import FruchtermanWorker from './component/fruchterman-worker-layout';
|
||||
import AddNodeLayout from './component/addNodeLayout'
|
||||
import ChangeData from './component/changeData'
|
||||
import ComboForceLayout from './component/combo-force-layout';
|
||||
import ForceLayout from './component/force-layout';
|
||||
|
||||
export default { title: 'Layout' };
|
||||
|
||||
@ -17,4 +18,5 @@ storiesOf('Layout', module)
|
||||
.add('add node and layout', () => <AddNodeLayout />)
|
||||
.add('change data', () => <ChangeData />)
|
||||
.add('combo force layout', () => <ComboForceLayout />)
|
||||
.add('Fruchterman worker layout', () => <FruchtermanWorker />);
|
||||
.add('Fruchterman worker layout', () => <FruchtermanWorker />)
|
||||
.add('force layout', () => <ForceLayout />);
|
||||
|
Loading…
Reference in New Issue
Block a user