mirror of
https://gitee.com/antv/g6.git
synced 2024-12-02 11:48:29 +08:00
fix: update edge state with updateItem
This commit is contained in:
parent
518021657b
commit
3a7dd04ed1
@ -1,4 +1,4 @@
|
|||||||
import { isString, isPlainObject, isNil } from '@antv/util';
|
import { isString, isPlainObject, isNil, mix } from '@antv/util';
|
||||||
import { IEdge, INode, ICombo } from '../interface/item';
|
import { IEdge, INode, ICombo } from '../interface/item';
|
||||||
import { EdgeConfig, IPoint, NodeConfig, SourceTarget, Indexable } from '../types';
|
import { EdgeConfig, IPoint, NodeConfig, SourceTarget, Indexable } from '../types';
|
||||||
import Item from './item';
|
import Item from './item';
|
||||||
@ -212,6 +212,15 @@ export default class Edge extends Item implements IEdge {
|
|||||||
const oriVisible = model.visible;
|
const oriVisible = model.visible;
|
||||||
const cfgVisible = cfg.visible;
|
const cfgVisible = cfg.visible;
|
||||||
if (oriVisible !== cfgVisible && cfgVisible !== undefined) this.changeVisibility(cfgVisible);
|
if (oriVisible !== cfgVisible && cfgVisible !== undefined) this.changeVisibility(cfgVisible);
|
||||||
|
|
||||||
|
const styles = this.get('styles');
|
||||||
|
if (cfg.stateStyles) {
|
||||||
|
// 更新 item 时更新 this.get('styles') 中的值
|
||||||
|
const { stateStyles } = cfg;
|
||||||
|
mix(styles, stateStyles);
|
||||||
|
delete cfg.stateStyles;
|
||||||
|
}
|
||||||
|
|
||||||
Object.assign(model, cfg);
|
Object.assign(model, cfg);
|
||||||
this.updateShape();
|
this.updateShape();
|
||||||
this.afterUpdate();
|
this.afterUpdate();
|
||||||
|
196
stories/Issues/edgeStatus/index.tsx
Normal file
196
stories/Issues/edgeStatus/index.tsx
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
import React, { useRef, useEffect } from 'react';
|
||||||
|
import G6 from '../../../src';
|
||||||
|
import isArray from '@antv/util/lib/is-array';
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
// 点集
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
id: 'node1', // String,该节点存在则必须,节点的唯一标识
|
||||||
|
x: 100, // Number,可选,节点位置的 x 值
|
||||||
|
y: 200, // Number,可选,节点位置的 y 值
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node2', // String,该节点存在则必须,节点的唯一标识
|
||||||
|
x: 300, // Number,可选,节点位置的 x 值
|
||||||
|
y: 200, // Number,可选,节点位置的 y 值
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// 边集
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
source: 'node1', // String,必须,起始点 id
|
||||||
|
target: 'node2', // String,必须,目标点 id
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// import "./styles.css";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【问题】!!!
|
||||||
|
* 当我点击“隐藏节点”后,节点正常隐藏
|
||||||
|
* 但是点击“改变数据”调用changeData方法后,节点能隐藏,但是边又显示出来了。
|
||||||
|
*/
|
||||||
|
export default () => {
|
||||||
|
const graphContainer = useRef(null);
|
||||||
|
let graph = null// useRef(null);
|
||||||
|
|
||||||
|
// 图初始化
|
||||||
|
useEffect(() => {
|
||||||
|
if (!graph) {
|
||||||
|
graph = new G6.Graph({
|
||||||
|
container: graphContainer.current, // String | HTMLElement,必须,在 Step 1 中创建的容器 id 或容器本身
|
||||||
|
width: 800, // Number,必须,图的宽度
|
||||||
|
height: 500, // Number,必须,图的高度
|
||||||
|
modes: {
|
||||||
|
default: [
|
||||||
|
"drag-canvas",
|
||||||
|
"zoom-canvas",
|
||||||
|
"drag-node",
|
||||||
|
{
|
||||||
|
type: "brush-select",
|
||||||
|
trigger: "ctrl",
|
||||||
|
includeEdges: false,
|
||||||
|
selectedState: "click"
|
||||||
|
}
|
||||||
|
] // 允许拖拽画布、放缩画布、拖拽节点
|
||||||
|
// default: ["drag-canvas", "zoom-canvas"] // 允许拖拽画布、放缩画布
|
||||||
|
},
|
||||||
|
defaultNode: {
|
||||||
|
size: 50, // 节点大小
|
||||||
|
style: {
|
||||||
|
opacity: 0.8,
|
||||||
|
lineWidth: 1,
|
||||||
|
stroke: "#999"
|
||||||
|
},
|
||||||
|
labelCfg: {
|
||||||
|
style: {
|
||||||
|
fill: "#fff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaultEdge: {
|
||||||
|
labelCfg: {
|
||||||
|
autoRotate: true,
|
||||||
|
style: {
|
||||||
|
fontSize: 14,
|
||||||
|
fill: "#333"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
stroke: "#808080",
|
||||||
|
lineWidth: 1,
|
||||||
|
endArrow: true,
|
||||||
|
lineAppendWidth: 10,
|
||||||
|
// opacity: 0.6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 节点不同状态下的样式集合
|
||||||
|
nodeStateStyles: {
|
||||||
|
// 鼠标 hover 上节点,即 hover 状态为 true 时的样式
|
||||||
|
hover: {
|
||||||
|
fill: "lightsteelblue"
|
||||||
|
},
|
||||||
|
// 鼠标点击节点,即 click 状态为 true 时的样式
|
||||||
|
click: {
|
||||||
|
shadowColor: "#808080",
|
||||||
|
shadowBlur: 10,
|
||||||
|
lineWidth: 2,
|
||||||
|
fill: 'yellow'
|
||||||
|
// fill: "lightsteelblue"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 边不同状态下的样式集合
|
||||||
|
edgeStateStyles: {
|
||||||
|
// 鼠标点击边,即 click 状态为 true 时的样式
|
||||||
|
click: {
|
||||||
|
stroke: "red",
|
||||||
|
lineWidth: 2
|
||||||
|
// shadowColor: "#000",
|
||||||
|
// shadowBlur: 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
graph && graph.data(data);
|
||||||
|
graph && graph.render();
|
||||||
|
|
||||||
|
graph.on("edge:click", e => {
|
||||||
|
// 先将所有当前是 click 状态的边置为非 click 状态
|
||||||
|
const edgeItem = e.item; // 获取被点击的边元素对象
|
||||||
|
graph.setItemState(edgeItem, "click", true); // 设置当前边的 click 状态为 true
|
||||||
|
// this.options.edgeClickCallback();
|
||||||
|
});
|
||||||
|
graph.on("node:click", e => {
|
||||||
|
// 先将所有当前是 click 状态的节点置为非 click 状态
|
||||||
|
const nodeItem = e.item; // 获取被点击的节点元素对象
|
||||||
|
graph.setItemState(nodeItem, "click", true); // 设置当前节点的 click 状态为 true
|
||||||
|
});
|
||||||
|
// 鼠标进入节点
|
||||||
|
graph.on("node:mouseenter", e => {
|
||||||
|
const nodeItem = e.item; // 获取鼠标进入的节点元素对象
|
||||||
|
graph.setItemState(nodeItem, "hover", true); // 设置当前节点的 hover 状态为 true
|
||||||
|
});
|
||||||
|
graph.on("node:mouseleave", e => {
|
||||||
|
const nodeItem = e.item; // 获取鼠标离开的节点元素对象
|
||||||
|
graph.setItemState(nodeItem, "hover", false); // 设置当前节点的 hover 状态为 false
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const toggleEdge = () => {
|
||||||
|
const clickEdges = graph.findAllByState("edge", "click");
|
||||||
|
clickEdges.forEach(clickEdge => {
|
||||||
|
const model = {
|
||||||
|
style: {
|
||||||
|
stroke: "#808080",
|
||||||
|
lineWidth: 1,
|
||||||
|
endArrow: true,
|
||||||
|
lineAppendWidth: 10,
|
||||||
|
},
|
||||||
|
stateStyles: {
|
||||||
|
click: {
|
||||||
|
stroke: "#333",
|
||||||
|
lineWidth: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
graph.updateItem(clickEdge, model);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模拟折叠node2节点
|
||||||
|
*/
|
||||||
|
const toggleNode = () => {
|
||||||
|
const clickNodes = graph.findAllByState("node", "click");
|
||||||
|
// console.log(clickNodes);
|
||||||
|
clickNodes.forEach(clickNode => {
|
||||||
|
// let model = clickNode.getModel();
|
||||||
|
// console.log(model);
|
||||||
|
const model = {
|
||||||
|
style: {
|
||||||
|
opacity: 0.8,
|
||||||
|
lineWidth: 1,
|
||||||
|
stroke: "green"
|
||||||
|
},
|
||||||
|
stateStyles: {
|
||||||
|
// 修改 hover 状态下的样式
|
||||||
|
click: {
|
||||||
|
stroke: 'blue'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
graph.updateItem(clickNode, model);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button onClick={toggleNode}>切换节点</button>
|
||||||
|
<button onClick={toggleEdge}>切换边</button>
|
||||||
|
<div ref={graphContainer} className={'graph-container'} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -8,6 +8,7 @@ import DomClick from './component/dom-click';
|
|||||||
import ForceLayout from './forceLayout';
|
import ForceLayout from './forceLayout';
|
||||||
import GGEditorNode from './ggeditorNode';
|
import GGEditorNode from './ggeditorNode';
|
||||||
import MultiLayout from './forceLayout/multiLayout'
|
import MultiLayout from './forceLayout/multiLayout'
|
||||||
|
import EdgeStatus from './edgeStatus'
|
||||||
|
|
||||||
export default { title: 'Issues' };
|
export default { title: 'Issues' };
|
||||||
|
|
||||||
@ -20,3 +21,4 @@ storiesOf('Issues', module)
|
|||||||
.add('forcelayout', () => <ForceLayout />)
|
.add('forcelayout', () => <ForceLayout />)
|
||||||
.add('ggeditor node issue', () => <GGEditorNode />)
|
.add('ggeditor node issue', () => <GGEditorNode />)
|
||||||
.add('multi layout', () => <MultiLayout />)
|
.add('multi layout', () => <MultiLayout />)
|
||||||
|
.add('edge status', () => <EdgeStatus />)
|
||||||
|
@ -576,4 +576,133 @@ describe('graph edge states', () => {
|
|||||||
graph.emit('edge:mouseleave', { item: edge });
|
graph.emit('edge:mouseleave', { item: edge });
|
||||||
graph.destroy();
|
graph.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('update edge states with updateItem', () => {
|
||||||
|
const data = {
|
||||||
|
// 点集
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
id: 'node1', // String,该节点存在则必须,节点的唯一标识
|
||||||
|
x: 100, // Number,可选,节点位置的 x 值
|
||||||
|
y: 200, // Number,可选,节点位置的 y 值
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node2', // String,该节点存在则必须,节点的唯一标识
|
||||||
|
x: 300, // Number,可选,节点位置的 x 值
|
||||||
|
y: 200, // Number,可选,节点位置的 y 值
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// 边集
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
id: 'node1-node2',
|
||||||
|
source: 'node1', // String,必须,起始点 id
|
||||||
|
target: 'node2', // String,必须,目标点 id
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const graph = new G6.Graph({
|
||||||
|
container: div, // String | HTMLElement,必须,在 Step 1 中创建的容器 id 或容器本身
|
||||||
|
width: 800, // Number,必须,图的宽度
|
||||||
|
height: 500, // Number,必须,图的高度
|
||||||
|
modes: {
|
||||||
|
default: [
|
||||||
|
"drag-canvas",
|
||||||
|
"zoom-canvas",
|
||||||
|
"drag-node",
|
||||||
|
{
|
||||||
|
type: "brush-select",
|
||||||
|
trigger: "ctrl",
|
||||||
|
includeEdges: false,
|
||||||
|
selectedState: "click"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
defaultNode: {
|
||||||
|
size: 50, // 节点大小
|
||||||
|
style: {
|
||||||
|
opacity: 0.8,
|
||||||
|
lineWidth: 1,
|
||||||
|
stroke: "#999"
|
||||||
|
},
|
||||||
|
labelCfg: {
|
||||||
|
style: {
|
||||||
|
fill: "#fff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaultEdge: {
|
||||||
|
labelCfg: {
|
||||||
|
autoRotate: true,
|
||||||
|
style: {
|
||||||
|
fontSize: 14,
|
||||||
|
fill: "#333"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
stroke: "#808080",
|
||||||
|
lineWidth: 1,
|
||||||
|
endArrow: true,
|
||||||
|
lineAppendWidth: 10,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 边不同状态下的样式集合
|
||||||
|
edgeStateStyles: {
|
||||||
|
// 鼠标点击边,即 click 状态为 true 时的样式
|
||||||
|
click: {
|
||||||
|
stroke: "red",
|
||||||
|
lineWidth: 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
graph.data(data)
|
||||||
|
graph.render()
|
||||||
|
|
||||||
|
// 验证 edge 的初始样式
|
||||||
|
const currentEdge = graph.findById('node1-node2')
|
||||||
|
let states = currentEdge.getStates()
|
||||||
|
expect(states.length).toBe(0)
|
||||||
|
|
||||||
|
let keyShape = currentEdge.getKeyShape()
|
||||||
|
expect(keyShape.attr('stroke')).toEqual('#808080')
|
||||||
|
|
||||||
|
// 先设置 edge click states
|
||||||
|
graph.setItemState(currentEdge, 'click', true)
|
||||||
|
states = currentEdge.getStates()
|
||||||
|
expect(states.length).toBe(1)
|
||||||
|
|
||||||
|
let stateStyle = currentEdge.getStateStyle('click')
|
||||||
|
expect(stateStyle).toEqual({"lineWidth": 2, "stroke": "red"})
|
||||||
|
|
||||||
|
keyShape = currentEdge.getKeyShape()
|
||||||
|
expect(keyShape.attr('stroke')).toEqual('red')
|
||||||
|
|
||||||
|
// 验证此时 edge 的样式状态
|
||||||
|
|
||||||
|
// 再使用 updateItem 更新 click states
|
||||||
|
const model = {
|
||||||
|
style: {
|
||||||
|
stroke: "#808080",
|
||||||
|
lineWidth: 1,
|
||||||
|
endArrow: true,
|
||||||
|
lineAppendWidth: 10,
|
||||||
|
},
|
||||||
|
stateStyles: {
|
||||||
|
click: {
|
||||||
|
stroke: "#333",
|
||||||
|
lineWidth: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
graph.updateItem('node1-node2', model);
|
||||||
|
|
||||||
|
// updateItem 以后,edge click states 的值以及变化了
|
||||||
|
stateStyle = currentEdge.getStateStyle('click')
|
||||||
|
expect(stateStyle).toEqual({"lineWidth": 2, "stroke": "#333"})
|
||||||
|
|
||||||
|
graph.destroy()
|
||||||
|
expect(graph.destroyed).toBe(true)
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user