mirror of
https://gitee.com/antv/g6.git
synced 2024-12-04 04:38:55 +08:00
fix: redo and undo problem when update item after additem, closes #2019
This commit is contained in:
parent
343e7658f0
commit
154cdeae3e
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
#### 3.7.1
|
#### 3.7.1
|
||||||
|
|
||||||
- fix: hide the tooltip plugin when drag node and contextmenu, #1975;
|
- fix: hide the tooltip plugin when drag node and contextmenu, closes #1975;
|
||||||
- fix: processParellelEdges without edge id problem;
|
- fix: processParellelEdges without edge id problem;
|
||||||
- fix: label background with left, right position problem, #1861;
|
- fix: label background with left, right position problem, closes #1861;
|
||||||
- fix: create-edge and redo undo problem, #1976;
|
- fix: create-edge and redo undo problem, #1976;
|
||||||
- fix: tooltip plugin with shouldBegin problem, closes #2006;
|
- fix: tooltip plugin with shouldBegin problem, closes #2006;
|
||||||
- fix: tooltip behavior with shouldBegin problem, closes #2016;
|
- fix: tooltip behavior with shouldBegin problem, closes #2016;
|
||||||
@ -12,7 +12,9 @@
|
|||||||
- fix: fisheye destroy and new problem, closes: #2018;
|
- fix: fisheye destroy and new problem, closes: #2018;
|
||||||
- fix: node event with wrong canvasX and canvasY problem, closes: #2027;
|
- fix: node event with wrong canvasX and canvasY problem, closes: #2027;
|
||||||
- feat: improve the performance on the combos;
|
- feat: improve the performance on the combos;
|
||||||
- feat: hide shapes beside keyShape while zooming.
|
- fix: redo and undo problem when update item after additem, closes #2019;
|
||||||
|
- feat: hide shapes beside keyShape while zooming;
|
||||||
|
- feat: improve the performance on the combos.
|
||||||
|
|
||||||
#### 3.7.0
|
#### 3.7.0
|
||||||
|
|
||||||
|
@ -107,6 +107,11 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.targets.push(item);
|
this.targets.push(item);
|
||||||
}
|
}
|
||||||
|
const beforeDragNodes = [];
|
||||||
|
this.targets.forEach(t => {
|
||||||
|
beforeDragNodes.push(clone(t.getModel()));
|
||||||
|
});
|
||||||
|
this.set('beforeDragNodes', beforeDragNodes);
|
||||||
|
|
||||||
this.origin = {
|
this.origin = {
|
||||||
x: evt.x,
|
x: evt.x,
|
||||||
@ -193,7 +198,15 @@ export default {
|
|||||||
|
|
||||||
// 拖动结束后,入栈
|
// 拖动结束后,入栈
|
||||||
if (graph.get('enabledStack')) {
|
if (graph.get('enabledStack')) {
|
||||||
graph.pushStack('update', clone(graph.save()));
|
const stackData = {
|
||||||
|
before: { nodes: this.get('beforeDragNodes'), edges: [], combos: [] },
|
||||||
|
after: { nodes: [], edges: [], combos: [] }
|
||||||
|
}
|
||||||
|
|
||||||
|
this.targets.forEach(target => {
|
||||||
|
stackData.after.nodes.push(target.getModel());
|
||||||
|
})
|
||||||
|
graph.pushStack('update', clone(stackData));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.point = {};
|
this.point = {};
|
||||||
|
@ -395,7 +395,7 @@ export default class ItemController {
|
|||||||
}
|
}
|
||||||
// 若移除的是节点,需要将与之相连的边一同删除
|
// 若移除的是节点,需要将与之相连的边一同删除
|
||||||
const edges = (item as INode).getEdges();
|
const edges = (item as INode).getEdges();
|
||||||
for (let i = edges.length; i >= 0; i--) {
|
for (let i = edges.length - 1; i >= 0; i--) {
|
||||||
graph.removeItem(edges[i], false);
|
graph.removeItem(edges[i], false);
|
||||||
}
|
}
|
||||||
if (comboId) graph.updateCombo(comboId);
|
if (comboId) graph.updateCombo(comboId);
|
||||||
@ -560,7 +560,7 @@ export default class ItemController {
|
|||||||
* @param {boolean} visible 是否显示
|
* @param {boolean} visible 是否显示
|
||||||
* @memberof ItemController
|
* @memberof ItemController
|
||||||
*/
|
*/
|
||||||
public changeItemVisibility(item: Item | string, visible: boolean): void {
|
public changeItemVisibility(item: Item | string, visible: boolean): Item {
|
||||||
const { graph } = this;
|
const { graph } = this;
|
||||||
|
|
||||||
if (isString(item)) {
|
if (isString(item)) {
|
||||||
@ -620,6 +620,7 @@ export default class ItemController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
graph.emit('afteritemvisibilitychange', { item, visible });
|
graph.emit('afteritemvisibilitychange', { item, visible });
|
||||||
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
|
@ -853,13 +853,29 @@ export default class Graph extends EventEmitter implements IGraph {
|
|||||||
*/
|
*/
|
||||||
public showItem(item: Item | string, stack: boolean = true): void {
|
public showItem(item: Item | string, stack: boolean = true): void {
|
||||||
const itemController: ItemController = this.get('itemController');
|
const itemController: ItemController = this.get('itemController');
|
||||||
itemController.changeItemVisibility(item, true);
|
const object = itemController.changeItemVisibility(item, true);
|
||||||
if (stack && this.get('enabledStack')) {
|
if (stack && this.get('enabledStack')) {
|
||||||
if (isString(item)) {
|
let id = object.getID();
|
||||||
this.pushStack('visible', item);
|
const type = object.getType();
|
||||||
} else {
|
const before: GraphData = {};
|
||||||
this.pushStack('visible', (item as Item).getID());
|
const after: GraphData = {};
|
||||||
|
switch (type) {
|
||||||
|
case 'node':
|
||||||
|
before.nodes = [{ id, visible: false }];
|
||||||
|
after.nodes = [{ id, visible: true }];
|
||||||
|
break;
|
||||||
|
case 'edge':
|
||||||
|
before.nodes = [{ id, visible: false }];
|
||||||
|
after.edges = [{ id, visible: true }];
|
||||||
|
break;
|
||||||
|
case 'combo':
|
||||||
|
before.nodes = [{ id, visible: false }];
|
||||||
|
after.combos = [{ id, visible: true }];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
this.pushStack('visible', { before, after });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -870,13 +886,29 @@ export default class Graph extends EventEmitter implements IGraph {
|
|||||||
*/
|
*/
|
||||||
public hideItem(item: Item | string, stack: boolean = true): void {
|
public hideItem(item: Item | string, stack: boolean = true): void {
|
||||||
const itemController: ItemController = this.get('itemController');
|
const itemController: ItemController = this.get('itemController');
|
||||||
itemController.changeItemVisibility(item, false);
|
const object = itemController.changeItemVisibility(item, false);
|
||||||
if (stack && this.get('enabledStack')) {
|
if (stack && this.get('enabledStack')) {
|
||||||
if (isString(item)) {
|
let id = object.getID();
|
||||||
this.pushStack('visible', item);
|
const type = object.getType();
|
||||||
} else {
|
const before: GraphData = {};
|
||||||
this.pushStack('visible', (item as Item).getID());
|
const after: GraphData = {};
|
||||||
|
switch (type) {
|
||||||
|
case 'node':
|
||||||
|
before.nodes = [{ id, visible: true }];
|
||||||
|
after.nodes = [{ id, visible: false }];
|
||||||
|
break;
|
||||||
|
case 'edge':
|
||||||
|
before.nodes = [{ id, visible: true }];
|
||||||
|
after.edges = [{ id, visible: false }];
|
||||||
|
break;
|
||||||
|
case 'combo':
|
||||||
|
before.nodes = [{ id, visible: true }];
|
||||||
|
after.combos = [{ id, visible: false }];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
this.pushStack('visible', { before, after });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -929,9 +961,34 @@ export default class Graph extends EventEmitter implements IGraph {
|
|||||||
|
|
||||||
// 将删除的元素入栈
|
// 将删除的元素入栈
|
||||||
if (stack && this.get('enabledStack')) {
|
if (stack && this.get('enabledStack')) {
|
||||||
this.pushStack('delete', {
|
const deletedModel = {
|
||||||
...(nodeItem as Item).getModel(),
|
...(nodeItem as Item).getModel(),
|
||||||
type,
|
type,
|
||||||
|
}
|
||||||
|
const before: GraphData = {};
|
||||||
|
switch (type) {
|
||||||
|
case 'node':
|
||||||
|
before.nodes = [deletedModel as NodeConfig];
|
||||||
|
before.edges = [];
|
||||||
|
const edges = (nodeItem as INode).getEdges();
|
||||||
|
for (let i = edges.length - 1; i >= 0; i--) {
|
||||||
|
before.edges.push({
|
||||||
|
...edges[i].getModel(),
|
||||||
|
type: 'edge'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'edge':
|
||||||
|
before.edges = [deletedModel as EdgeConfig];
|
||||||
|
break;
|
||||||
|
case 'combo':
|
||||||
|
before.combos = [deletedModel as ComboConfig];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.pushStack('delete', {
|
||||||
|
before, after: {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1079,9 +1136,26 @@ export default class Graph extends EventEmitter implements IGraph {
|
|||||||
this.autoPaint();
|
this.autoPaint();
|
||||||
|
|
||||||
if (stack && this.get('enabledStack')) {
|
if (stack && this.get('enabledStack')) {
|
||||||
this.pushStack('add', {
|
const addedModel = {
|
||||||
...item.getModel(),
|
...item.getModel(),
|
||||||
type,
|
type
|
||||||
|
}
|
||||||
|
const after: GraphData = {};
|
||||||
|
switch (type) {
|
||||||
|
case 'node':
|
||||||
|
after.nodes = [addedModel];
|
||||||
|
break;
|
||||||
|
case 'edge':
|
||||||
|
after.edges = [addedModel];
|
||||||
|
break;
|
||||||
|
case 'combo':
|
||||||
|
after.combos = [addedModel];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.pushStack('add', {
|
||||||
|
before: {}, after
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1117,6 +1191,8 @@ export default class Graph extends EventEmitter implements IGraph {
|
|||||||
currentItem = item;
|
currentItem = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const UnupdateModel = clone(currentItem.getModel());
|
||||||
|
|
||||||
let type = '';
|
let type = '';
|
||||||
if (currentItem.getType) type = currentItem.getType();
|
if (currentItem.getType) type = currentItem.getType();
|
||||||
const states = [...currentItem.getStates()];
|
const states = [...currentItem.getStates()];
|
||||||
@ -1130,7 +1206,32 @@ export default class Graph extends EventEmitter implements IGraph {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stack && this.get('enabledStack')) {
|
if (stack && this.get('enabledStack')) {
|
||||||
this.pushStack();
|
const before = { nodes: [], edges: [], combos: [] };
|
||||||
|
const after = { nodes: [], edges: [], combos: [] };
|
||||||
|
const afterModel = {
|
||||||
|
id: UnupdateModel.id,
|
||||||
|
...cfg
|
||||||
|
};
|
||||||
|
switch (type) {
|
||||||
|
case 'node':
|
||||||
|
before.nodes.push(UnupdateModel);
|
||||||
|
after.nodes.push(afterModel);
|
||||||
|
break;
|
||||||
|
case 'edge':
|
||||||
|
before.edges.push(UnupdateModel);
|
||||||
|
after.edges.push(afterModel);
|
||||||
|
break;
|
||||||
|
case 'combo':
|
||||||
|
before.combos.push(UnupdateModel);
|
||||||
|
after.combos.push(afterModel);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (type === 'node') {
|
||||||
|
before.nodes.push(UnupdateModel);
|
||||||
|
}
|
||||||
|
this.pushStack('update', { before, after });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1339,13 +1440,16 @@ export default class Graph extends EventEmitter implements IGraph {
|
|||||||
* @return {object} this
|
* @return {object} this
|
||||||
*/
|
*/
|
||||||
public changeData(data?: GraphData | TreeGraphData, stack: boolean = true): Graph {
|
public changeData(data?: GraphData | TreeGraphData, stack: boolean = true): Graph {
|
||||||
if (stack && this.get('enabledStack')) {
|
|
||||||
this.pushStack('update', data);
|
|
||||||
}
|
|
||||||
const self = this;
|
const self = this;
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
if (stack && this.get('enabledStack')) {
|
||||||
|
this.pushStack('changedata', {
|
||||||
|
before: self.save(),
|
||||||
|
after: data
|
||||||
|
});
|
||||||
|
}
|
||||||
this.set('comboSorted', false);
|
this.set('comboSorted', false);
|
||||||
|
|
||||||
// 更改数据源后,取消所有状态
|
// 更改数据源后,取消所有状态
|
||||||
@ -3029,7 +3133,10 @@ export default class Graph extends EventEmitter implements IGraph {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stackData = data ? clone(data) : clone(this.save());
|
const stackData = data ? clone(data) : {
|
||||||
|
before: {},
|
||||||
|
after: clone(this.save())
|
||||||
|
};
|
||||||
|
|
||||||
if (stackType === 'redo') {
|
if (stackType === 'redo') {
|
||||||
this.redoStack.push({
|
this.redoStack.push({
|
||||||
|
@ -189,39 +189,61 @@ export default class ToolBar extends Base {
|
|||||||
|
|
||||||
const currentData = undoStack.pop();
|
const currentData = undoStack.pop();
|
||||||
if (currentData) {
|
if (currentData) {
|
||||||
let { action, data } = currentData;
|
let { action } = currentData;
|
||||||
graph.pushStack(action, clone(data), 'redo');
|
graph.pushStack(action, clone(currentData.data), 'redo');
|
||||||
|
let data = currentData.data.before;
|
||||||
|
|
||||||
if (undoStack.length > 0 && (action === 'render' || action === 'update')) {
|
if (action === 'add') {
|
||||||
const current = undoStack.peek();
|
data = currentData.data.after;
|
||||||
action = current.action;
|
|
||||||
data = current.data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!data) return;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'visible': {
|
case 'visible': {
|
||||||
let item = data;
|
Object.keys(data).forEach(key => {
|
||||||
if (isString(data)) {
|
const array = data[key];
|
||||||
item = graph.findById(data);
|
array && array.forEach(model => {
|
||||||
}
|
const item = graph.findById(model.id);
|
||||||
if (item.get('visible')) {
|
if (model.visible) {
|
||||||
graph.hideItem(item, false);
|
|
||||||
} else {
|
|
||||||
graph.showItem(item, false);
|
graph.showItem(item, false);
|
||||||
|
} else {
|
||||||
|
graph.hideItem(item, false);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'render':
|
case 'render':
|
||||||
case 'update':
|
case 'update':
|
||||||
|
Object.keys(data).forEach(key => {
|
||||||
|
const array = data[key];
|
||||||
|
array && array.forEach(model => {
|
||||||
|
graph.updateItem(model.id, model, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'changedata':
|
||||||
graph.changeData(data, false);
|
graph.changeData(data, false);
|
||||||
break;
|
break;
|
||||||
case 'delete': {
|
case 'delete': {
|
||||||
const { type, ...model } = data;
|
Object.keys(data).forEach(key => {
|
||||||
|
const array = data[key];
|
||||||
|
array && array.forEach(model => {
|
||||||
|
const type = model.type;
|
||||||
|
delete model.type;
|
||||||
graph.addItem(type, model, false);
|
graph.addItem(type, model, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'add':
|
case 'add':
|
||||||
graph.removeItem(data.id, false);
|
Object.keys(data).forEach(key => {
|
||||||
|
const array = data[key];
|
||||||
|
array && array.forEach(model => {
|
||||||
|
graph.removeItem(model.id, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
@ -241,38 +263,62 @@ export default class ToolBar extends Base {
|
|||||||
|
|
||||||
let currentData = redoStack.pop();
|
let currentData = redoStack.pop();
|
||||||
if (currentData) {
|
if (currentData) {
|
||||||
let { action, data } = currentData;
|
let { action } = currentData;
|
||||||
graph.pushStack(action, clone(data));
|
let data = currentData.data.after;
|
||||||
if (action === 'render') {
|
graph.pushStack(action, clone(currentData.data));
|
||||||
currentData = redoStack.pop();
|
if (action === 'delete') {
|
||||||
action = currentData.action;
|
data = currentData.data.before;
|
||||||
data = currentData.data;
|
|
||||||
graph.pushStack(action, clone(data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!data) return;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'visible': {
|
case 'visible': {
|
||||||
let item = data;
|
Object.keys(data).forEach(key => {
|
||||||
if (isString(data)) {
|
const array = data[key];
|
||||||
item = graph.findById(data);
|
array && array.forEach(model => {
|
||||||
}
|
const item = graph.findById(model.id);
|
||||||
if (item.get('visible')) {
|
if (model.visible) {
|
||||||
graph.hideItem(item, false);
|
|
||||||
} else {
|
|
||||||
graph.showItem(item, false);
|
graph.showItem(item, false);
|
||||||
|
} else {
|
||||||
|
graph.hideItem(item, false);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'render':
|
case 'render':
|
||||||
case 'update':
|
case 'update':
|
||||||
|
Object.keys(data).forEach(key => {
|
||||||
|
const array = data[key];
|
||||||
|
array && array.forEach(model => {
|
||||||
|
graph.updateItem(model.id, model, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'changedata':
|
||||||
graph.changeData(data, false);
|
graph.changeData(data, false);
|
||||||
break;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
graph.removeItem(data.id, false);
|
data.edges && data.edges.forEach(model => {
|
||||||
|
graph.removeItem(model.id, false);
|
||||||
|
});
|
||||||
|
data.nodes && data.nodes.forEach(model => {
|
||||||
|
graph.removeItem(model.id, false);
|
||||||
|
});
|
||||||
|
data.combos && data.combos.forEach(model => {
|
||||||
|
graph.removeItem(model.id, false);
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case 'add': {
|
case 'add': {
|
||||||
const { type, ...model } = data;
|
Object.keys(data).forEach(key => {
|
||||||
|
const array = data[key];
|
||||||
|
array && array.forEach(model => {
|
||||||
|
const type = model.type;
|
||||||
|
delete model.type;
|
||||||
graph.addItem(type, model, false);
|
graph.addItem(type, model, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -5,8 +5,31 @@ import { IGraph } from '../../../src/interface/graph';
|
|||||||
let graph: IGraph = null;
|
let graph: IGraph = null;
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
nodes: [],
|
nodes: [{
|
||||||
edges: [],
|
id: '1'
|
||||||
|
}, {
|
||||||
|
id: '2'
|
||||||
|
},],
|
||||||
|
edges: [{
|
||||||
|
source: '1',
|
||||||
|
target: '2'
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
const data2 = {
|
||||||
|
nodes: [{
|
||||||
|
id: 'new1'
|
||||||
|
}, {
|
||||||
|
id: 'new2'
|
||||||
|
}, {
|
||||||
|
id: '1'
|
||||||
|
},],
|
||||||
|
edges: [{
|
||||||
|
source: '1',
|
||||||
|
target: 'new2'
|
||||||
|
}, {
|
||||||
|
source: 'new1',
|
||||||
|
target: 'new2'
|
||||||
|
}],
|
||||||
};
|
};
|
||||||
const ToolBar = () => {
|
const ToolBar = () => {
|
||||||
const container = React.useRef();
|
const container = React.useRef();
|
||||||
@ -21,7 +44,7 @@ const ToolBar = () => {
|
|||||||
// 设置为true,启用 redo & undo 栈功能
|
// 设置为true,启用 redo & undo 栈功能
|
||||||
enabledStack: true,
|
enabledStack: true,
|
||||||
modes: {
|
modes: {
|
||||||
default: ['drag-canvas', 'zoom-canvas', 'drag-node'],
|
default: ['zoom-canvas', 'drag-node', { type: 'brush-select', }],
|
||||||
},
|
},
|
||||||
defaultNode: {
|
defaultNode: {
|
||||||
size: 50
|
size: 50
|
||||||
@ -32,7 +55,7 @@ const ToolBar = () => {
|
|||||||
graph.on('stackchange', e => {
|
graph.on('stackchange', e => {
|
||||||
// console.log(e)
|
// console.log(e)
|
||||||
})
|
})
|
||||||
graph.addItem('node', {
|
const node4 = graph.addItem('node', {
|
||||||
id: '4',
|
id: '4',
|
||||||
label: 'node-4',
|
label: 'node-4',
|
||||||
x: 100,
|
x: 100,
|
||||||
@ -40,11 +63,11 @@ const ToolBar = () => {
|
|||||||
description: 'This is node-4.',
|
description: 'This is node-4.',
|
||||||
subdescription: 'This is subdescription of node-3.',
|
subdescription: 'This is subdescription of node-3.',
|
||||||
})
|
})
|
||||||
graph.addItem('node', {
|
const node5 = graph.addItem('node', {
|
||||||
id: '5',
|
id: '5',
|
||||||
label: 'node-5',
|
label: 'node-5',
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 300,
|
y: 100,
|
||||||
description: 'This is node-5.',
|
description: 'This is node-5.',
|
||||||
subdescription: 'This is subdescription of node-5.',
|
subdescription: 'This is subdescription of node-5.',
|
||||||
})
|
})
|
||||||
@ -54,6 +77,22 @@ const ToolBar = () => {
|
|||||||
target: '5',
|
target: '5',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
graph.updateItem(node4, {
|
||||||
|
x: 100,
|
||||||
|
y: 200
|
||||||
|
})
|
||||||
|
graph.on('canvas:click', e => {
|
||||||
|
graph.removeItem(graph.getNodes()[0])
|
||||||
|
})
|
||||||
|
|
||||||
|
graph.on('node:click', e => {
|
||||||
|
graph.hideItem(e.item);
|
||||||
|
})
|
||||||
|
|
||||||
|
graph.on('canvas:dragstart', e => {
|
||||||
|
graph.changeData(data2);
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1605,7 +1605,7 @@ describe('redo stack & undo stack', () => {
|
|||||||
let redoStack = stackData.redoStack;
|
let redoStack = stackData.redoStack;
|
||||||
expect(undoStack.length).toBe(1);
|
expect(undoStack.length).toBe(1);
|
||||||
expect(undoStack[0].action).toEqual('render');
|
expect(undoStack[0].action).toEqual('render');
|
||||||
expect(undoStack[0].data.nodes.length).toEqual(2);
|
expect(undoStack[0].data.after.nodes.length).toEqual(2);
|
||||||
expect(redoStack.length).toBe(0);
|
expect(redoStack.length).toBe(0);
|
||||||
|
|
||||||
// update 后,undo stack 中有 2 条数据,一条 render,一条 update
|
// update 后,undo stack 中有 2 条数据,一条 render,一条 update
|
||||||
@ -1620,9 +1620,9 @@ describe('redo stack & undo stack', () => {
|
|||||||
|
|
||||||
let firstStackData = undoStack[0];
|
let firstStackData = undoStack[0];
|
||||||
expect(firstStackData.action).toEqual('update');
|
expect(firstStackData.action).toEqual('update');
|
||||||
expect(firstStackData.data.nodes[0].id).toEqual('node1');
|
expect(firstStackData.data.after.nodes[0].id).toEqual('node1');
|
||||||
expect(firstStackData.data.nodes[0].x).toEqual(120);
|
expect(firstStackData.data.after.nodes[0].x).toEqual(120);
|
||||||
expect(firstStackData.data.nodes[0].y).toEqual(200);
|
expect(firstStackData.data.after.nodes[0].y).toEqual(200);
|
||||||
|
|
||||||
// 执行 update 后,undo stack 中有3条数据
|
// 执行 update 后,undo stack 中有3条数据
|
||||||
graph.update('node2', {
|
graph.update('node2', {
|
||||||
@ -1636,9 +1636,9 @@ describe('redo stack & undo stack', () => {
|
|||||||
|
|
||||||
firstStackData = undoStack[0];
|
firstStackData = undoStack[0];
|
||||||
expect(firstStackData.action).toEqual('update');
|
expect(firstStackData.action).toEqual('update');
|
||||||
expect(firstStackData.data.nodes[1].id).toEqual('node2');
|
expect(firstStackData.data.after.nodes[0].id).toEqual('node2');
|
||||||
expect(firstStackData.data.nodes[1].x).toEqual(120);
|
expect(firstStackData.data.after.nodes[0].x).toEqual(120);
|
||||||
expect(firstStackData.data.nodes[1].y).toEqual(350);
|
expect(firstStackData.data.after.nodes[0].y).toEqual(350);
|
||||||
|
|
||||||
// addItem 后,undo 栈中有4条数据,1个render、2个update、1个add
|
// addItem 后,undo 栈中有4条数据,1个render、2个update、1个add
|
||||||
graph.addItem('node', {
|
graph.addItem('node', {
|
||||||
@ -1654,9 +1654,9 @@ describe('redo stack & undo stack', () => {
|
|||||||
|
|
||||||
firstStackData = undoStack[0];
|
firstStackData = undoStack[0];
|
||||||
expect(firstStackData.action).toEqual('add');
|
expect(firstStackData.action).toEqual('add');
|
||||||
expect(firstStackData.data.id).toEqual('node3');
|
expect(firstStackData.data.after.nodes[0].id).toEqual('node3');
|
||||||
expect(firstStackData.data.x).toEqual(150);
|
expect(firstStackData.data.after.nodes[0].x).toEqual(150);
|
||||||
expect(firstStackData.data.y).toEqual(150);
|
expect(firstStackData.data.after.nodes[0].y).toEqual(150);
|
||||||
|
|
||||||
// hideItem 后,undo 栈中有5条数据,1个render、2个update、1个add、1个visible
|
// hideItem 后,undo 栈中有5条数据,1个render、2个update、1个add、1个visible
|
||||||
graph.hideItem('node1');
|
graph.hideItem('node1');
|
||||||
@ -1667,7 +1667,7 @@ describe('redo stack & undo stack', () => {
|
|||||||
|
|
||||||
firstStackData = undoStack[0];
|
firstStackData = undoStack[0];
|
||||||
expect(firstStackData.action).toEqual('visible');
|
expect(firstStackData.action).toEqual('visible');
|
||||||
expect(firstStackData.data).toEqual('node1');
|
expect(firstStackData.data.after.nodes[0].id).toEqual('node1');
|
||||||
|
|
||||||
// remove 后,undo 栈中有6条数据,1个render、2个update、1个add、1个visible、1个delete
|
// remove 后,undo 栈中有6条数据,1个render、2个update、1个add、1个visible、1个delete
|
||||||
graph.remove('node2');
|
graph.remove('node2');
|
||||||
@ -1678,8 +1678,8 @@ describe('redo stack & undo stack', () => {
|
|||||||
|
|
||||||
firstStackData = undoStack[0];
|
firstStackData = undoStack[0];
|
||||||
expect(firstStackData.action).toEqual('delete');
|
expect(firstStackData.action).toEqual('delete');
|
||||||
expect(firstStackData.data.id).toEqual('node2');
|
expect(firstStackData.data.before.nodes[0].id).toEqual('node2');
|
||||||
expect(firstStackData.data.type).toEqual('node');
|
expect(firstStackData.data.before.nodes[0].type).toEqual('node');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('clear stack', () => {
|
it('clear stack', () => {
|
||||||
|
@ -47,7 +47,7 @@ describe('toolbar', () => {
|
|||||||
|
|
||||||
expect(undoStack.length).toBe(1);
|
expect(undoStack.length).toBe(1);
|
||||||
expect(undoStack[0].action).toEqual('render');
|
expect(undoStack[0].action).toEqual('render');
|
||||||
expect(undoStack[0].data.nodes.length).toEqual(2);
|
expect(undoStack[0].data.after.nodes.length).toEqual(2);
|
||||||
expect(redoStack.length).toBe(0);
|
expect(redoStack.length).toBe(0);
|
||||||
|
|
||||||
// update 后,undo stack 中有 2 条数据,一条 render,一条 update
|
// update 后,undo stack 中有 2 条数据,一条 render,一条 update
|
||||||
@ -62,9 +62,9 @@ describe('toolbar', () => {
|
|||||||
|
|
||||||
let firstStackData = undoStack[0];
|
let firstStackData = undoStack[0];
|
||||||
expect(firstStackData.action).toEqual('update');
|
expect(firstStackData.action).toEqual('update');
|
||||||
expect(firstStackData.data.nodes[0].id).toEqual('node1');
|
expect(firstStackData.data.after.nodes[0].id).toEqual('node1');
|
||||||
expect(firstStackData.data.nodes[0].x).toEqual(120);
|
expect(firstStackData.data.after.nodes[0].x).toEqual(120);
|
||||||
expect(firstStackData.data.nodes[0].y).toEqual(200);
|
expect(firstStackData.data.after.nodes[0].y).toEqual(200);
|
||||||
|
|
||||||
// 执行 update 后,undo stack 中有3条数据
|
// 执行 update 后,undo stack 中有3条数据
|
||||||
graph.update('node2', {
|
graph.update('node2', {
|
||||||
@ -78,9 +78,9 @@ describe('toolbar', () => {
|
|||||||
|
|
||||||
firstStackData = undoStack[0];
|
firstStackData = undoStack[0];
|
||||||
expect(firstStackData.action).toEqual('update');
|
expect(firstStackData.action).toEqual('update');
|
||||||
expect(firstStackData.data.nodes[1].id).toEqual('node2');
|
expect(firstStackData.data.after.nodes[0].id).toEqual('node2');
|
||||||
expect(firstStackData.data.nodes[1].x).toEqual(120);
|
expect(firstStackData.data.after.nodes[0].x).toEqual(120);
|
||||||
expect(firstStackData.data.nodes[1].y).toEqual(350);
|
expect(firstStackData.data.after.nodes[0].y).toEqual(350);
|
||||||
|
|
||||||
// addItem 后,undo 栈中有4条数据,1个render、2个update、1个add
|
// addItem 后,undo 栈中有4条数据,1个render、2个update、1个add
|
||||||
graph.addItem('node', {
|
graph.addItem('node', {
|
||||||
@ -96,9 +96,9 @@ describe('toolbar', () => {
|
|||||||
|
|
||||||
firstStackData = undoStack[0];
|
firstStackData = undoStack[0];
|
||||||
expect(firstStackData.action).toEqual('add');
|
expect(firstStackData.action).toEqual('add');
|
||||||
expect(firstStackData.data.id).toEqual('node3');
|
expect(firstStackData.data.after.nodes[0].id).toEqual('node3');
|
||||||
expect(firstStackData.data.x).toEqual(150);
|
expect(firstStackData.data.after.nodes[0].x).toEqual(150);
|
||||||
expect(firstStackData.data.y).toEqual(150);
|
expect(firstStackData.data.after.nodes[0].y).toEqual(150);
|
||||||
|
|
||||||
// hideItem 后,undo 栈中有5条数据,1个render、2个update、1个add、1个visible
|
// hideItem 后,undo 栈中有5条数据,1个render、2个update、1个add、1个visible
|
||||||
graph.hideItem('node1');
|
graph.hideItem('node1');
|
||||||
@ -109,7 +109,7 @@ describe('toolbar', () => {
|
|||||||
|
|
||||||
firstStackData = undoStack[0];
|
firstStackData = undoStack[0];
|
||||||
expect(firstStackData.action).toEqual('visible');
|
expect(firstStackData.action).toEqual('visible');
|
||||||
expect(firstStackData.data).toEqual('node1');
|
expect(firstStackData.data.after.nodes[0].id).toEqual('node1');
|
||||||
|
|
||||||
// remove 后,undo 栈中有6条数据,1个render、2个update、1个add、1个visible、1个delete
|
// remove 后,undo 栈中有6条数据,1个render、2个update、1个add、1个visible、1个delete
|
||||||
graph.remove('node2');
|
graph.remove('node2');
|
||||||
@ -120,8 +120,8 @@ describe('toolbar', () => {
|
|||||||
|
|
||||||
firstStackData = undoStack[0];
|
firstStackData = undoStack[0];
|
||||||
expect(firstStackData.action).toEqual('delete');
|
expect(firstStackData.action).toEqual('delete');
|
||||||
expect(firstStackData.data.id).toEqual('node2');
|
expect(firstStackData.data.before.nodes[0].id).toEqual('node2');
|
||||||
expect(firstStackData.data.type).toEqual('node');
|
expect(firstStackData.data.before.nodes[0].type).toEqual('node');
|
||||||
|
|
||||||
// 第一次 undo 后,撤销 remove node2 操作
|
// 第一次 undo 后,撤销 remove node2 操作
|
||||||
toolbar.undo();
|
toolbar.undo();
|
||||||
@ -134,13 +134,13 @@ describe('toolbar', () => {
|
|||||||
|
|
||||||
firstStackData = redoStack[0];
|
firstStackData = redoStack[0];
|
||||||
expect(firstStackData.action).toEqual('delete');
|
expect(firstStackData.action).toEqual('delete');
|
||||||
expect(firstStackData.data.id).toEqual('node2');
|
expect(firstStackData.data.before.nodes[0].id).toEqual('node2');
|
||||||
expect(firstStackData.data.type).toEqual('node');
|
expect(firstStackData.data.before.nodes[0].type).toEqual('node');
|
||||||
|
|
||||||
// 此时 undo stack 中第一个元素应该是 visible node1 的数据
|
// 此时 undo stack 中第一个元素应该是 visible node1 的数据
|
||||||
firstStackData = undoStack[0];
|
firstStackData = undoStack[0];
|
||||||
expect(firstStackData.action).toEqual('visible');
|
expect(firstStackData.action).toEqual('visible');
|
||||||
expect(firstStackData.data).toEqual('node1');
|
expect(firstStackData.data.after.nodes[0].id).toEqual('node1');
|
||||||
|
|
||||||
// 第二次 undo 后,撤销 hide node1 的操作
|
// 第二次 undo 后,撤销 hide node1 的操作
|
||||||
toolbar.undo();
|
toolbar.undo();
|
||||||
@ -152,7 +152,7 @@ describe('toolbar', () => {
|
|||||||
|
|
||||||
firstStackData = redoStack[0];
|
firstStackData = redoStack[0];
|
||||||
expect(firstStackData.action).toEqual('visible');
|
expect(firstStackData.action).toEqual('visible');
|
||||||
expect(firstStackData.data).toEqual('node1');
|
expect(firstStackData.data.after.nodes[0].id).toEqual('node1');
|
||||||
|
|
||||||
graph.destroy();
|
graph.destroy();
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user