mirror of
https://gitee.com/antv/g6.git
synced 2024-11-30 02:38:20 +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 { EdgeConfig, IPoint, NodeConfig, SourceTarget, Indexable } from '../types';
|
||||
import Item from './item';
|
||||
@ -212,6 +212,15 @@ export default class Edge extends Item implements IEdge {
|
||||
const oriVisible = model.visible;
|
||||
const cfgVisible = cfg.visible;
|
||||
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);
|
||||
this.updateShape();
|
||||
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 GGEditorNode from './ggeditorNode';
|
||||
import MultiLayout from './forceLayout/multiLayout'
|
||||
import EdgeStatus from './edgeStatus'
|
||||
|
||||
export default { title: 'Issues' };
|
||||
|
||||
@ -20,3 +21,4 @@ storiesOf('Issues', module)
|
||||
.add('forcelayout', () => <ForceLayout />)
|
||||
.add('ggeditor node issue', () => <GGEditorNode />)
|
||||
.add('multi layout', () => <MultiLayout />)
|
||||
.add('edge status', () => <EdgeStatus />)
|
||||
|
@ -576,4 +576,133 @@ describe('graph edge states', () => {
|
||||
graph.emit('edge:mouseleave', { item: edge });
|
||||
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