mirror of
https://gitee.com/antv/g6.git
synced 2024-11-30 10:48:24 +08:00
feat: fisheye plugin, support clear, update, show labels.
This commit is contained in:
parent
41abeae5a2
commit
7936523d67
@ -1,5 +1,8 @@
|
||||
# ChangeLog
|
||||
|
||||
#### 3.5
|
||||
- feat: fisheye lens plugin.
|
||||
|
||||
#### 3.5.12
|
||||
- fix: node:click is triggered twice while clicking a node;
|
||||
- fix: update combo edge when drag node out of it problem;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6",
|
||||
"version": "3.5.12",
|
||||
"version": "3.6.0",
|
||||
"description": "A Graph Visualization Framework in JavaScript",
|
||||
"keywords": [
|
||||
"antv",
|
||||
|
@ -1,5 +1,5 @@
|
||||
export default {
|
||||
version: '3.5.12',
|
||||
version: '3.6.0',
|
||||
rootContainerClassName: 'root-container',
|
||||
nodeContainerClassName: 'node-container',
|
||||
edgeContainerClassName: 'edge-container',
|
||||
|
@ -1,6 +1,6 @@
|
||||
import createDOM from '@antv/dom-util/lib/create-dom';
|
||||
import modifyCSS from '@antv/dom-util/lib/modify-css';
|
||||
import { IG6GraphEvent } from '../../types';
|
||||
import { IG6GraphEvent, ShapeStyle } from '../../types';
|
||||
import { IGraph } from '../../interface/graph';
|
||||
import Graph from '../../graph/graph';
|
||||
import Base from '../base';
|
||||
@ -8,7 +8,17 @@ import Base from '../base';
|
||||
interface FisheyeConfig {
|
||||
trigger?: 'mousemove' | 'click',
|
||||
d?: number,
|
||||
r?: number
|
||||
r?: number,
|
||||
delegateStyle?: ShapeStyle,
|
||||
showLabel?: boolean
|
||||
}
|
||||
|
||||
const lensDelegateStyle = {
|
||||
stroke: '#000',
|
||||
strokeOpacity: 0.8,
|
||||
lineWidth: 2,
|
||||
fillOpacity: 0.1,
|
||||
fill: '#ccc'
|
||||
}
|
||||
export default class Fisheye extends Base {
|
||||
constructor(cfg?: FisheyeConfig) {
|
||||
@ -18,7 +28,9 @@ export default class Fisheye extends Base {
|
||||
return {
|
||||
trigger: 'mousemove',
|
||||
d: 1.5,
|
||||
r: 100
|
||||
r: 300,
|
||||
delegateStyle: lensDelegateStyle,
|
||||
showLabel: false
|
||||
};
|
||||
}
|
||||
|
||||
@ -53,12 +65,14 @@ export default class Fisheye extends Base {
|
||||
const graph: Graph = self.get('graph');
|
||||
const cachedMagnifiedModels = self.get('cachedMagnifiedModels');
|
||||
const cachedOriginPositions = self.get('cachedOriginPositions');
|
||||
const showLabel = self.get('showLabel');
|
||||
const r = self.get('r');
|
||||
const r2 = self.get('r2');
|
||||
const d = self.get('d');
|
||||
const nodes = graph.getNodes();
|
||||
const nodeLength = nodes.length;
|
||||
const mCenter = { x: e.x, y: e.y };
|
||||
self.updateDelegate(mCenter, r);
|
||||
for (let i = 0; i < nodeLength; i++) {
|
||||
const model = nodes[i].getModel();
|
||||
const { x, y } = model;
|
||||
@ -73,9 +87,26 @@ export default class Fisheye extends Base {
|
||||
model.x = cos * magnifiedDist + mCenter.x;
|
||||
model.y = sin * magnifiedDist + mCenter.y;
|
||||
if (!cachedOriginPositions[model.id]) {
|
||||
cachedOriginPositions[model.id] = { x, y };
|
||||
cachedOriginPositions[model.id] = { x, y, texts: [] };
|
||||
}
|
||||
cachedMagnifiedModels.push(model);
|
||||
if (showLabel && 2 * dist < r) {
|
||||
const node = nodes[i];
|
||||
const nodeGroup = node.getContainer();
|
||||
const shapes = nodeGroup.getChildren();
|
||||
const shapeLength = shapes.length;
|
||||
for (let j = 0; j < shapeLength; j++) {
|
||||
const shape = shapes[j];
|
||||
if (shape.get('type') === 'text') {
|
||||
cachedOriginPositions[model.id].texts.push({
|
||||
visible: shape.get('visible'),
|
||||
shape
|
||||
});
|
||||
shape.set('visible', true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
graph.refreshPositions();
|
||||
@ -92,8 +123,12 @@ export default class Fisheye extends Base {
|
||||
for (let i = 0; i < cacheLength; i++) {
|
||||
const node = cachedMagnifiedModels[i];
|
||||
const id = node.id;
|
||||
node.x = cachedOriginPositions[id].x;
|
||||
node.y = cachedOriginPositions[id].y;
|
||||
const ori = cachedOriginPositions[id];
|
||||
node.x = ori.x;
|
||||
node.y = ori.y;
|
||||
ori.texts.forEach(text => {
|
||||
text.shape.set('visible', text.visible);
|
||||
});
|
||||
}
|
||||
self.set('cachedMagnifiedModels', []);
|
||||
self.set('cachedOriginPositions', {});
|
||||
@ -114,10 +149,47 @@ export default class Fisheye extends Base {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 放大镜的图形
|
||||
* @param {Point} mCenter
|
||||
* @param {number} r
|
||||
*/
|
||||
private updateDelegate(mCenter, r) {
|
||||
const self = this;
|
||||
const graph = self.get('graph');
|
||||
let lensDelegate = self.get('delegate');
|
||||
if (!lensDelegate || lensDelegate.destroyed) {
|
||||
// 拖动多个
|
||||
const parent = graph.get('group');
|
||||
const attrs = self.get('delegateStyle') || lensDelegateStyle;
|
||||
|
||||
// model上的x, y是相对于图形中心的,delegateShape是g实例,x,y是绝对坐标
|
||||
lensDelegate = parent.addShape('circle', {
|
||||
attrs: {
|
||||
r: r / 1.5,
|
||||
x: mCenter.x,
|
||||
y: mCenter.y,
|
||||
...attrs,
|
||||
},
|
||||
name: 'lens-delegate-shape',
|
||||
});
|
||||
lensDelegate.set('capture', false);
|
||||
} else {
|
||||
lensDelegate.attr({
|
||||
x: mCenter.x,
|
||||
y: mCenter.y,
|
||||
});
|
||||
}
|
||||
self.set('delegate', lensDelegate);
|
||||
}
|
||||
|
||||
public clear() {
|
||||
const graph = this.get('graph');
|
||||
this.restoreCache();
|
||||
graph.refreshPositions();
|
||||
let lensDelegate = this.get('delegate');
|
||||
lensDelegate.destroy();
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -7,20 +7,34 @@ let graph: IGraph = null;
|
||||
const FishEye = () => {
|
||||
const container = React.useRef();
|
||||
const fisheye = new G6.Fisheye({
|
||||
r: 100
|
||||
r: 200,
|
||||
showLabel: true,
|
||||
});
|
||||
const colors = [
|
||||
'#8FE9FF',
|
||||
'#87EAEF',
|
||||
'#FFC9E3',
|
||||
'#A7C2FF',
|
||||
'#FFA1E3',
|
||||
'#FFE269',
|
||||
'#BFCFEE',
|
||||
'#FFA0C5',
|
||||
'#D5FF86',
|
||||
]
|
||||
|
||||
useEffect(() => {
|
||||
if (!graph) {
|
||||
graph = new G6.Graph({
|
||||
container: container.current as string | HTMLElement,
|
||||
width: 500,
|
||||
height: 500,
|
||||
width: 1000,
|
||||
height: 700,
|
||||
plugins: [fisheye],
|
||||
layout: {
|
||||
type: 'force'
|
||||
type: 'force',
|
||||
preventOverlap: true
|
||||
},
|
||||
modes: {
|
||||
default: ['drag-canvas']
|
||||
default: ['drag-canvas', 'zoom-canvas']
|
||||
}
|
||||
});
|
||||
fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/relations.json')
|
||||
@ -28,9 +42,20 @@ const FishEye = () => {
|
||||
.then(data => {
|
||||
data.nodes.forEach(node => {
|
||||
node.label = node.id;
|
||||
node.size = Math.random() * 40 + 20;
|
||||
node.style = {
|
||||
fill: colors[Math.floor(Math.random() * 9)],
|
||||
lineWidth: 0
|
||||
}
|
||||
console.log(node)
|
||||
});
|
||||
graph.data(data);
|
||||
graph.render();
|
||||
graph.getNodes().forEach(node => {
|
||||
node.getContainer().getChildren().forEach(shape => {
|
||||
if (shape.get('type') === 'text') shape.set('visible', false);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user