2023-08-30 14:21:51 +08:00
|
|
|
|
import { Graph, Extensions, extend } from '@antv/g6';
|
2023-12-04 14:42:33 +08:00
|
|
|
|
import { supportsThreads, initThreads, ForceLayout, FruchtermanLayout, ForceAtlas2Layout } from '@antv/layout-wasm';
|
2023-08-30 14:21:51 +08:00
|
|
|
|
|
2023-12-04 14:42:33 +08:00
|
|
|
|
// WASM layout is not built-in G6 stbLib, you need to extend G6 with it.
|
2023-08-30 14:21:51 +08:00
|
|
|
|
const ExtGraph = extend(Graph, {
|
2023-10-07 17:59:58 +08:00
|
|
|
|
transforms: { 'transform-v4-data': Extensions.TransformV4Data },
|
2023-08-30 14:21:51 +08:00
|
|
|
|
layouts: {
|
|
|
|
|
'force-wasm': ForceLayout,
|
|
|
|
|
'forceAtlas2-wasm': ForceAtlas2Layout,
|
|
|
|
|
'fruchterman-wasm': FruchtermanLayout,
|
|
|
|
|
},
|
2023-10-07 19:05:08 +08:00
|
|
|
|
behaviors: {
|
|
|
|
|
'hover-activate': Extensions.HoverActivate,
|
|
|
|
|
},
|
2023-08-30 14:21:51 +08:00
|
|
|
|
});
|
|
|
|
|
const container = document.getElementById('container');
|
|
|
|
|
const width = container.scrollWidth;
|
|
|
|
|
const height = container.scrollHeight || 500;
|
|
|
|
|
|
|
|
|
|
const descriptionDiv = document.createElement('div');
|
|
|
|
|
container.appendChild(descriptionDiv);
|
|
|
|
|
|
|
|
|
|
let timer;
|
|
|
|
|
const beginTimer = () => {
|
|
|
|
|
const begin = performance.now();
|
|
|
|
|
timer = setInterval(() => {
|
|
|
|
|
descriptionDiv.innerHTML = `节点数量:1589, 边数量:2742 <br /> ⏰ Computing Time: ${Math.floor(
|
|
|
|
|
performance.now() - begin,
|
|
|
|
|
)}ms`;
|
|
|
|
|
}, 10);
|
|
|
|
|
};
|
|
|
|
|
beginTimer();
|
|
|
|
|
|
2023-11-20 09:49:15 +08:00
|
|
|
|
let graph;
|
|
|
|
|
|
2023-08-30 14:21:51 +08:00
|
|
|
|
fetch('https://gw.alipayobjects.com/os/basement_prod/da5a1b47-37d6-44d7-8d10-f3e046dabf82.json') //'https://gw.alipayobjects.com/os/antvdemo/assets/data/relations.json'
|
|
|
|
|
.then((res) => res.json())
|
|
|
|
|
.then(async (data) => {
|
|
|
|
|
const supported = await supportsThreads();
|
|
|
|
|
const threads = await initThreads(supported);
|
|
|
|
|
|
|
|
|
|
const layoutConfigs = {
|
|
|
|
|
'force-wasm': {
|
|
|
|
|
type: 'force-wasm',
|
|
|
|
|
threads,
|
|
|
|
|
dimensions: 2,
|
|
|
|
|
maxIteration: 130,
|
|
|
|
|
minMovement: 0.4,
|
|
|
|
|
distanceThresholdMode: 'mean',
|
|
|
|
|
height,
|
|
|
|
|
width,
|
|
|
|
|
center: [width / 2, height / 2],
|
|
|
|
|
factor: 1,
|
|
|
|
|
gravity: 10,
|
|
|
|
|
linkDistance: 200,
|
|
|
|
|
edgeStrength: 200,
|
|
|
|
|
nodeStrength: 1000,
|
|
|
|
|
coulombDisScale: 0.005,
|
|
|
|
|
damping: 0.9,
|
|
|
|
|
maxSpeed: 1000,
|
|
|
|
|
interval: 0.02,
|
|
|
|
|
},
|
|
|
|
|
'forceAtals2-wasm': {
|
|
|
|
|
type: 'forceAtlas2-wasm',
|
|
|
|
|
threads,
|
|
|
|
|
dimensions: 2,
|
|
|
|
|
maxIteration: 100,
|
|
|
|
|
minMovement: 0.4,
|
|
|
|
|
distanceThresholdMode: 'mean',
|
|
|
|
|
height,
|
|
|
|
|
width,
|
|
|
|
|
center: [width / 2, height / 2],
|
|
|
|
|
kg: 5,
|
|
|
|
|
kr: 10,
|
|
|
|
|
ks: 0.1,
|
|
|
|
|
},
|
|
|
|
|
'fruchterman-wasm': {
|
|
|
|
|
type: 'fruchterman-wasm',
|
|
|
|
|
threads,
|
|
|
|
|
dimensions: 2,
|
|
|
|
|
maxIteration: 1000,
|
|
|
|
|
minMovement: 0.4,
|
|
|
|
|
distanceThresholdMode: 'mean',
|
|
|
|
|
height,
|
|
|
|
|
width,
|
|
|
|
|
gravity: 1,
|
|
|
|
|
speed: 5,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// remove positions in data to avoid the affecting
|
|
|
|
|
data.nodes.forEach((node) => {
|
|
|
|
|
delete node.x;
|
|
|
|
|
delete node.y;
|
|
|
|
|
});
|
|
|
|
|
|
2023-11-20 09:49:15 +08:00
|
|
|
|
graph = new ExtGraph({
|
2023-08-30 14:21:51 +08:00
|
|
|
|
container: 'container',
|
|
|
|
|
width,
|
|
|
|
|
height,
|
2023-08-31 15:21:57 +08:00
|
|
|
|
renderer: 'webgl',
|
2023-11-29 10:59:21 +08:00
|
|
|
|
transforms: [
|
2023-12-04 14:42:33 +08:00
|
|
|
|
{
|
|
|
|
|
type: 'transform-v4-data',
|
|
|
|
|
activeLifecycle: ['read'],
|
|
|
|
|
},
|
|
|
|
|
],
|
2023-08-30 14:21:51 +08:00
|
|
|
|
layout: layoutConfigs['force-wasm'],
|
|
|
|
|
autoFit: 'view',
|
|
|
|
|
modes: {
|
|
|
|
|
default: ['zoom-canvas', 'drag-canvas', 'drag-node', 'brush-select', 'click-select', 'hover-activate'],
|
|
|
|
|
},
|
|
|
|
|
data,
|
|
|
|
|
});
|
|
|
|
|
graph.on('afterlayout', (e) => {
|
|
|
|
|
clearTimeout(timer);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const btnContainer = document.createElement('div');
|
|
|
|
|
btnContainer.style.position = 'absolute';
|
|
|
|
|
container.appendChild(btnContainer);
|
|
|
|
|
const tip = document.createElement('span');
|
|
|
|
|
tip.innerHTML = '👉 Change Layout:';
|
|
|
|
|
btnContainer.appendChild(tip);
|
|
|
|
|
|
|
|
|
|
Object.keys(layoutConfigs).forEach((name, i) => {
|
|
|
|
|
const btn = document.createElement('a');
|
|
|
|
|
btn.innerHTML = name;
|
|
|
|
|
btn.style.backgroundColor = 'rgba(255, 255, 255, 0.8)';
|
|
|
|
|
btn.style.padding = '4px';
|
|
|
|
|
btn.style.marginLeft = i > 0 ? '24px' : '8px';
|
|
|
|
|
btnContainer.appendChild(btn);
|
|
|
|
|
btn.addEventListener('click', () => {
|
|
|
|
|
beginTimer();
|
|
|
|
|
graph.layout(layoutConfigs[name]);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2023-12-04 14:42:33 +08:00
|
|
|
|
window.graph = graph;
|