mirror of
https://gitee.com/antv/g6.git
synced 2024-12-02 11:48:29 +08:00
feat: update rdo/undo pause and resume stacking
This commit is contained in:
parent
99bee31f16
commit
9242fd6203
@ -473,7 +473,9 @@ export class ItemController {
|
||||
}
|
||||
const parentItem = this.itemMap[current.parentId];
|
||||
if (current.parentId && parentItem?.model.data.collapsed) {
|
||||
this.graph.hideItem(innerModel.id, false, false);
|
||||
this.graph.executeWithoutStacking(() => {
|
||||
this.graph.hideItem(innerModel.id, false);
|
||||
});
|
||||
}
|
||||
});
|
||||
updateRelates();
|
||||
@ -1097,8 +1099,11 @@ export class ItemController {
|
||||
const succeedIds: ID[] = [];
|
||||
// hide the succeeds
|
||||
graphComboTreeDfs(this.graph, [comboModel], (child) => {
|
||||
if (child.id !== comboModel.id)
|
||||
this.graph.hideItem(child.id, false, false);
|
||||
if (child.id !== comboModel.id) {
|
||||
this.graph.executeWithoutStacking(() => {
|
||||
this.graph.hideItem(child.id, false);
|
||||
});
|
||||
}
|
||||
relatedEdges = relatedEdges.concat(graphCore.getRelatedEdges(child.id));
|
||||
succeedIds.push(child.id);
|
||||
});
|
||||
@ -1133,7 +1138,9 @@ export class ItemController {
|
||||
},
|
||||
});
|
||||
});
|
||||
this.graph.addData('edge', virtualEdges, false);
|
||||
this.graph.executeWithoutStacking(() => {
|
||||
this.graph.addData('edge', virtualEdges);
|
||||
});
|
||||
}
|
||||
|
||||
private expandCombo(graphCore: GraphCore, comboModel: ComboModel) {
|
||||
@ -1154,7 +1161,9 @@ export class ItemController {
|
||||
});
|
||||
if (child.id !== comboModel.id) {
|
||||
if (!graphCore.getNode(child.data.parentId).data.collapsed) {
|
||||
this.graph.showItem(child.id, false, false);
|
||||
this.graph.executeWithoutStacking(() => {
|
||||
this.graph.showItem(child.id, false);
|
||||
});
|
||||
}
|
||||
// re-add collapsed succeeds' virtual edges by calling collapseCombo
|
||||
if (child.data._isCombo && child.data.collapsed) {
|
||||
@ -1163,7 +1172,9 @@ export class ItemController {
|
||||
}
|
||||
});
|
||||
// remove related virtual edges
|
||||
this.graph.removeData('edge', uniq(relatedVirtualEdgeIds), false);
|
||||
this.graph.executeWithoutStacking(() => {
|
||||
this.graph.removeData('edge', uniq(relatedVirtualEdgeIds));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,19 +102,6 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
base: 'light',
|
||||
},
|
||||
enableStack: true,
|
||||
stackCfg: {
|
||||
stackSize: 0,
|
||||
/** ignore* 是全局设置,用于指示是否忽略某种类型的操作 */
|
||||
ignoreStateChange: false,
|
||||
ignoreAdd: false,
|
||||
ignoreRemove: false,
|
||||
ignoreUpdate: false,
|
||||
/** 允许更细粒度的控制,优先与 ignore 选项。
|
||||
* 如果某个 API 在 excludes 中,即使他的操作类型没有被忽略,也不会放入栈
|
||||
*/
|
||||
includes: [],
|
||||
excludes: [],
|
||||
},
|
||||
};
|
||||
|
||||
constructor(spec: Specification<B, T>) {
|
||||
@ -927,7 +914,6 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
* Add one or more node/edge/combo data to the graph.
|
||||
* @param itemType item type
|
||||
* @param model user data
|
||||
* @param stack whether push this operation to stack
|
||||
* @returns whether success
|
||||
* @group Data
|
||||
*/
|
||||
@ -940,7 +926,6 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
| NodeUserModel[]
|
||||
| EdgeUserModel[]
|
||||
| ComboUserModel[],
|
||||
stack?: boolean,
|
||||
):
|
||||
| NodeModel
|
||||
| EdgeModel
|
||||
@ -965,7 +950,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
type: itemType,
|
||||
action: 'add',
|
||||
models,
|
||||
enableStack: this.shouldPushToStack('addData', stack),
|
||||
apiName: 'addData',
|
||||
changes,
|
||||
});
|
||||
});
|
||||
@ -986,11 +971,10 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
/**
|
||||
* Remove one or more node/edge/combo data from the graph.
|
||||
* @param item the item to be removed
|
||||
* @param stack whether push this operation to stack
|
||||
* @returns whether success
|
||||
* @group Data
|
||||
*/
|
||||
public removeData(itemType: ITEM_TYPE, ids: ID | ID[], stack?: boolean) {
|
||||
public removeData(itemType: ITEM_TYPE, ids: ID | ID[]) {
|
||||
const idArr = isArray(ids) ? ids : [ids];
|
||||
const data = { nodes: [], edges: [], combos: [] };
|
||||
const { userGraphCore, graphCore } = this.dataController;
|
||||
@ -1011,7 +995,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
type: itemType,
|
||||
action: 'remove',
|
||||
ids,
|
||||
enableStack: this.shouldPushToStack('removeData', stack),
|
||||
apiName: 'removeData',
|
||||
changes,
|
||||
});
|
||||
});
|
||||
@ -1051,10 +1035,18 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
}
|
||||
});
|
||||
|
||||
if (oldValue.x === undefined || Number.isNaN(oldValue.x))
|
||||
if (
|
||||
(oldValue.x === undefined || Number.isNaN(oldValue.x)) &&
|
||||
!oldValue._isCombo
|
||||
)
|
||||
oldValue.x = 0;
|
||||
if (oldValue.y === undefined || Number.isNaN(oldValue.x))
|
||||
if (
|
||||
(oldValue.y === undefined || Number.isNaN(oldValue.x)) &&
|
||||
!oldValue._isCombo
|
||||
)
|
||||
oldValue.y = 0;
|
||||
if (Number.isNaN(newValue.x)) delete newValue.x;
|
||||
if (Number.isNaN(newValue.y)) delete newValue.y;
|
||||
|
||||
if (isEqual(newValue, oldValue)) return false;
|
||||
|
||||
@ -1070,7 +1062,6 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
* Update one or more node/edge/combo data on the graph.
|
||||
* @param {ITEM_TYPE} itemType 'node' | 'edge' | 'combo'
|
||||
* @param models new configurations for every node/edge/combo, which has id field to indicate the specific item
|
||||
* @param {boolean} stack whether push this operation into graph's stack, true by default
|
||||
* @group Data
|
||||
*/
|
||||
public updateData(
|
||||
@ -1084,7 +1075,6 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
| Partial<EdgeUserModel>[]
|
||||
| Partial<ComboUserModel>[]
|
||||
>,
|
||||
stack?: boolean,
|
||||
):
|
||||
| NodeModel
|
||||
| EdgeModel
|
||||
@ -1110,7 +1100,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
type: itemType,
|
||||
action: 'update',
|
||||
models,
|
||||
enableStack: this.shouldPushToStack('updateData', stack),
|
||||
apiName: 'updateData',
|
||||
changes,
|
||||
});
|
||||
});
|
||||
@ -1130,7 +1120,6 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
* Update one or more nodes' positions,
|
||||
* do not update other styles which leads to better performance than updating positions by updateData.
|
||||
* @param models new configurations with x and y for every node, which has id field to indicate the specific item
|
||||
* @param {boolean} stack whether push this operation into graph's stack, true by default
|
||||
* @group Data
|
||||
*/
|
||||
public updateNodePosition(
|
||||
@ -1140,9 +1129,8 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
ComboUserModel | Partial<NodeUserModel>[] | Partial<ComboUserModel>[]
|
||||
>,
|
||||
upsertAncestors?: boolean,
|
||||
stack?: boolean,
|
||||
) {
|
||||
return this.updatePosition('node', models, upsertAncestors, stack);
|
||||
return this.updatePosition('node', models, upsertAncestors);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1150,7 +1138,6 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
* do not update other styles which leads to better performance than updating positions by updateData.
|
||||
* In fact, it changes the succeed nodes positions to affect the combo's position, but not modify the combo's position directly.
|
||||
* @param models new configurations with x and y for every combo, which has id field to indicate the specific item
|
||||
* @param {boolean} stack whether push this operation into graph's stack, true by default
|
||||
* @group Data
|
||||
*/
|
||||
public updateComboPosition(
|
||||
@ -1160,9 +1147,8 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
ComboUserModel | Partial<NodeUserModel>[] | Partial<ComboUserModel>[]
|
||||
>,
|
||||
upsertAncestors?: boolean,
|
||||
stack?: boolean,
|
||||
) {
|
||||
return this.updatePosition('combo', models, upsertAncestors, stack);
|
||||
return this.updatePosition('combo', models, upsertAncestors);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1178,26 +1164,6 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
return this.pluginController.getPlugin('history') as History;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a given operation should be pushed onto the history stack based on various configurations.
|
||||
* @param {string} apiName name of the API operation.
|
||||
* @param {boolean} stack Optional. whether push this operation into graph's stack.
|
||||
*/
|
||||
private shouldPushToStack(apiName: string, stack?: boolean): boolean {
|
||||
const { enableStack, stackCfg } = this.specification;
|
||||
const { includes: defaultIncludes, excludes: defaultExcludes } =
|
||||
this.defaultSpecification.stackCfg;
|
||||
const { includes = defaultIncludes, excludes = defaultExcludes } = stackCfg;
|
||||
if (!enableStack) return false;
|
||||
if (isBoolean(stack)) return stack;
|
||||
if (includes.includes(apiName)) return true;
|
||||
if (excludes.includes(apiName)) return false;
|
||||
let categoryKey: any = getCategoryByApiName(apiName);
|
||||
if (!categoryKey) return true;
|
||||
categoryKey = 'ignore' + upperFirst(categoryKey);
|
||||
return !stackCfg[categoryKey];
|
||||
}
|
||||
|
||||
private updatePosition(
|
||||
type: 'node' | 'combo',
|
||||
models:
|
||||
@ -1206,7 +1172,6 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
ComboUserModel | Partial<NodeUserModel>[] | Partial<ComboUserModel>[]
|
||||
>,
|
||||
upsertAncestors?: boolean,
|
||||
stack?: boolean,
|
||||
) {
|
||||
const modelArr = isArray(models) ? models : [models];
|
||||
const { graphCore } = this.dataController;
|
||||
@ -1229,7 +1194,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
action: 'updatePosition',
|
||||
upsertAncestors,
|
||||
models,
|
||||
enableStack: this.shouldPushToStack('updatePosition', stack),
|
||||
apiName: 'updatePosition',
|
||||
changes,
|
||||
});
|
||||
});
|
||||
@ -1269,7 +1234,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
* @returns
|
||||
* @group Item
|
||||
*/
|
||||
public showItem(ids: ID | ID[], disableAnimate?: boolean, stack?: boolean) {
|
||||
public showItem(ids: ID | ID[], disableAnimate?: boolean) {
|
||||
const idArr = isArray(ids) ? ids : [ids];
|
||||
if (isEmpty(idArr)) return;
|
||||
const changes = {
|
||||
@ -1287,7 +1252,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
value: true,
|
||||
animate: !disableAnimate,
|
||||
action: 'updateVisibility',
|
||||
enableStack: this.shouldPushToStack('showItem', stack),
|
||||
apiName: 'showItem',
|
||||
changes,
|
||||
});
|
||||
}
|
||||
@ -1297,7 +1262,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
* @returns
|
||||
* @group Item
|
||||
*/
|
||||
public hideItem(ids: ID | ID[], disableAnimate?: boolean, stack?: boolean) {
|
||||
public hideItem(ids: ID | ID[], disableAnimate?: boolean) {
|
||||
const idArr = isArray(ids) ? ids : [ids];
|
||||
if (isEmpty(idArr)) return;
|
||||
const changes = {
|
||||
@ -1315,7 +1280,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
value: false,
|
||||
animate: !disableAnimate,
|
||||
action: 'updateVisibility',
|
||||
enableStack: this.shouldPushToStack('hideItem', stack),
|
||||
apiName: 'hideItem',
|
||||
changes,
|
||||
});
|
||||
}
|
||||
@ -1326,7 +1291,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
* @returns
|
||||
* @group Item
|
||||
*/
|
||||
public frontItem(ids: ID | ID[], stack?: boolean) {
|
||||
public frontItem(ids: ID | ID[]) {
|
||||
const idArr = isArray(ids) ? ids : [ids];
|
||||
this.hooks.itemzindexchange.emit({
|
||||
ids: idArr as ID[],
|
||||
@ -1336,7 +1301,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
this.emit('afteritemzindexchange', {
|
||||
ids: idArr,
|
||||
action: 'front',
|
||||
enableStack: this.shouldPushToStack('frontItem', stack),
|
||||
apiName: 'frontItem',
|
||||
});
|
||||
}
|
||||
/**
|
||||
@ -1345,7 +1310,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
* @returns
|
||||
* @group Item
|
||||
*/
|
||||
public backItem(ids: ID | ID[], stack?: boolean) {
|
||||
public backItem(ids: ID | ID[]) {
|
||||
const idArr = isArray(ids) ? ids : [ids];
|
||||
this.hooks.itemzindexchange.emit({
|
||||
ids: idArr as ID[],
|
||||
@ -1355,7 +1320,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
this.emit('afteritemzindexchange', {
|
||||
ids: idArr,
|
||||
action: 'back',
|
||||
enableStack: this.shouldPushToStack('backItem', stack),
|
||||
apiName: 'backItem',
|
||||
});
|
||||
}
|
||||
|
||||
@ -1388,7 +1353,6 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
ids: ID | ID[],
|
||||
states: string | string[],
|
||||
value: boolean,
|
||||
stack?: boolean,
|
||||
) {
|
||||
const idArr = isArray(ids) ? ids : [ids];
|
||||
const stateArr = isArray(states) ? states : [states];
|
||||
@ -1407,7 +1371,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
states,
|
||||
value,
|
||||
action: 'updateState',
|
||||
enableStack: this.shouldPushToStack('setItemState', stack),
|
||||
apiName: 'setItemState',
|
||||
changes,
|
||||
});
|
||||
}
|
||||
@ -1429,7 +1393,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
* @returns
|
||||
* @group Item
|
||||
*/
|
||||
public clearItemState(ids: ID | ID[], states?: string[], stack?: boolean) {
|
||||
public clearItemState(ids: ID | ID[], states?: string[]) {
|
||||
const idArr = isArray(ids) ? ids : [ids];
|
||||
const stateOptions = { ids: idArr, states, value: false };
|
||||
const changes = {
|
||||
@ -1446,7 +1410,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
states,
|
||||
value: false,
|
||||
action: 'updateState',
|
||||
enableStack: this.shouldPushToStack('clearItemState', stack),
|
||||
apiName: 'clearItemState',
|
||||
changes,
|
||||
});
|
||||
}
|
||||
@ -1482,15 +1446,10 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
* Add a new combo to the graph, and update the structure of the existed child in childrenIds to be the children of the new combo.
|
||||
* Different from addData with combo type, this API update the succeeds' combo tree strucutres in the same time.
|
||||
* @param model combo user data
|
||||
* @param stack whether push this operation to stack
|
||||
* @returns whether success
|
||||
* @group Combo
|
||||
*/
|
||||
public addCombo(
|
||||
model: ComboUserModel,
|
||||
childrenIds: ID[],
|
||||
stack?: boolean,
|
||||
): ComboModel {
|
||||
public addCombo(model: ComboUserModel, childrenIds: ID[]): ComboModel {
|
||||
const { graphCore } = this.dataController;
|
||||
const { specification } = this.themeController;
|
||||
graphCore.once('changed', (event) => {
|
||||
@ -1506,7 +1465,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
type: 'combo',
|
||||
action: 'add',
|
||||
models: [model],
|
||||
enableStack: this.shouldPushToStack('addCombo', stack),
|
||||
apiName: 'addCombo',
|
||||
changes,
|
||||
});
|
||||
});
|
||||
@ -1535,38 +1494,39 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
* @param comboId combo ids
|
||||
* @group Combo
|
||||
*/
|
||||
public collapseCombo(comboIds: ID | ID[], stack?: boolean) {
|
||||
public collapseCombo(comboIds: ID | ID[]) {
|
||||
const ids = isArray(comboIds) ? comboIds : [comboIds];
|
||||
this.updateData(
|
||||
'combo',
|
||||
ids.map((id) => ({ id, data: { collapsed: true } })),
|
||||
false,
|
||||
);
|
||||
this.executeWithoutStacking(() => {
|
||||
this.updateData(
|
||||
'combo',
|
||||
ids.map((id) => ({ id, data: { collapsed: true } })),
|
||||
);
|
||||
});
|
||||
this.emit('aftercollapsecombo', {
|
||||
type: 'combo',
|
||||
action: 'collapseCombo',
|
||||
ids: comboIds,
|
||||
enableStack: this.shouldPushToStack('collapseCombo', stack),
|
||||
apiName: 'collapseCombo',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Expand a combo.
|
||||
* @param combo combo ids
|
||||
*
|
||||
* @group Combo
|
||||
*/
|
||||
public expandCombo(comboIds: ID | ID[], stack?: boolean) {
|
||||
public expandCombo(comboIds: ID | ID[]) {
|
||||
const ids = isArray(comboIds) ? comboIds : [comboIds];
|
||||
this.updateData(
|
||||
'combo',
|
||||
ids.map((id) => ({ id, data: { collapsed: false } })),
|
||||
false,
|
||||
);
|
||||
this.executeWithoutStacking(() => {
|
||||
this.updateData(
|
||||
'combo',
|
||||
ids.map((id) => ({ id, data: { collapsed: false } })),
|
||||
);
|
||||
});
|
||||
this.emit('afterexpandcombo', {
|
||||
type: 'combo',
|
||||
action: 'expandCombo',
|
||||
ids: comboIds,
|
||||
enableStack: this.shouldPushToStack('expandCombo', stack),
|
||||
apiName: 'expandCombo',
|
||||
});
|
||||
}
|
||||
|
||||
@ -1575,7 +1535,6 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
* do not update other styles which leads to better performance than updating positions by updateData.
|
||||
* In fact, it changes the succeed nodes positions to affect the combo's position, but not modify the combo's position directly.
|
||||
* @param models new configurations with x and y for every combo, which has id field to indicate the specific item
|
||||
* @param {boolean} stack whether push this operation into graph's stack, true by default
|
||||
* @group Combo
|
||||
*/
|
||||
public moveCombo(
|
||||
@ -1583,7 +1542,6 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
dx: number,
|
||||
dy: number,
|
||||
upsertAncestors?: boolean,
|
||||
stack?: boolean,
|
||||
): ComboModel[] {
|
||||
const idArr = isArray(ids) ? ids : [ids];
|
||||
const { graphCore } = this.dataController;
|
||||
@ -1606,7 +1564,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
dy,
|
||||
action: 'updatePosition',
|
||||
upsertAncestors,
|
||||
enableStack: this.shouldPushToStack('moveCombo', stack),
|
||||
apiName: 'moveCombo',
|
||||
changes,
|
||||
});
|
||||
});
|
||||
@ -1936,6 +1894,36 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
|
||||
return history.push(cmd, stackType, isNew);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause stacking operation.
|
||||
*/
|
||||
public pauseStacking(): void {
|
||||
const history = this.getHistoryPlugin();
|
||||
return history.pauseStacking();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume stacking operation.
|
||||
*/
|
||||
public resumeStacking(): void {
|
||||
const history = this.getHistoryPlugin();
|
||||
return history.resumeStacking();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback without allowing any stacking operations.
|
||||
* @param callback
|
||||
*/
|
||||
public executeWithoutStacking = (callback: () => void): void => {
|
||||
const history = this.getHistoryPlugin();
|
||||
history.pauseStacking();
|
||||
try {
|
||||
callback();
|
||||
} finally {
|
||||
history.resumeStacking();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve the current redo stack which consists of operations that could be undone
|
||||
*/
|
||||
|
@ -118,20 +118,24 @@ export default class ActivateRelations extends Behavior {
|
||||
edgeIds,
|
||||
);
|
||||
|
||||
/** 节点 */
|
||||
graph.setItemState(activeNodeIds, ACTIVE_STATE, true);
|
||||
graph.setItemState(inactiveNodeIds, ACTIVE_STATE, false);
|
||||
/** 边 */
|
||||
graph.setItemState(activeEdgeIds, ACTIVE_STATE, true);
|
||||
graph.setItemState(inactiveEdgeIds, ACTIVE_STATE, false);
|
||||
graph.batch(() => {
|
||||
/** 节点 */
|
||||
graph.setItemState(activeNodeIds, ACTIVE_STATE, true);
|
||||
graph.setItemState(inactiveNodeIds, ACTIVE_STATE, false);
|
||||
/** 边 */
|
||||
graph.setItemState(activeEdgeIds, ACTIVE_STATE, true);
|
||||
graph.setItemState(inactiveEdgeIds, ACTIVE_STATE, false);
|
||||
});
|
||||
|
||||
this.prevNodeIds = nodeIds;
|
||||
this.prevEdgeIds = edgeIds;
|
||||
}
|
||||
public clearActiveState(e: any) {
|
||||
const { activeState: ACTIVE_STATE } = this.options;
|
||||
this.graph.setItemState(this.prevNodeIds, ACTIVE_STATE, false);
|
||||
this.graph.setItemState(this.prevEdgeIds, ACTIVE_STATE, false);
|
||||
this.graph.batch(() => {
|
||||
this.graph.setItemState(this.prevNodeIds, ACTIVE_STATE, false);
|
||||
this.graph.setItemState(this.prevEdgeIds, ACTIVE_STATE, false);
|
||||
});
|
||||
this.prevNodeIds = [];
|
||||
this.prevEdgeIds = [];
|
||||
}
|
||||
|
@ -136,13 +136,13 @@ export default class ClickSelect extends Behavior {
|
||||
|
||||
// Select/Unselect item.
|
||||
if (this.options.shouldUpdate(event)) {
|
||||
this.graph.startBatch();
|
||||
if (!multiple) {
|
||||
// Not multiple, clear all currently selected items
|
||||
this.graph.setItemState(this.selectedIds, state, false);
|
||||
}
|
||||
this.graph.setItemState(itemId, state, isSelectAction);
|
||||
this.graph.stopBatch();
|
||||
this.graph.batch(() => {
|
||||
if (!multiple) {
|
||||
// Not multiple, clear all currently selected items
|
||||
this.graph.setItemState(this.selectedIds, state, false);
|
||||
}
|
||||
this.graph.setItemState(itemId, state, isSelectAction);
|
||||
});
|
||||
|
||||
if (isSelectAction) {
|
||||
this.selectedIds.push(itemId);
|
||||
|
@ -137,18 +137,20 @@ export default class DragCanvas extends Behavior {
|
||||
.getAllEdgesData()
|
||||
.map((edge) => edge.id)
|
||||
.filter((id) => graph.getItemVisible(id) === true);
|
||||
graph.hideItem(this.hiddenEdgeIds, true, false);
|
||||
this.hiddenNodeIds = graph
|
||||
.getAllNodesData()
|
||||
.map((node) => node.id)
|
||||
.filter((id) => graph.getItemVisible(id) === true);
|
||||
// draw node's keyShapes on transient, and then hidden the real nodes;
|
||||
this.hiddenNodeIds.forEach((id) => {
|
||||
graph.drawTransient('node', id, {
|
||||
onlyDrawKeyShape: true,
|
||||
graph.executeWithoutStacking(() => {
|
||||
graph.hideItem(this.hiddenEdgeIds, true);
|
||||
this.hiddenNodeIds = graph
|
||||
.getAllNodesData()
|
||||
.map((node) => node.id)
|
||||
.filter((id) => graph.getItemVisible(id) === true);
|
||||
// draw node's keyShapes on transient, and then hidden the real nodes;
|
||||
this.hiddenNodeIds.forEach((id) => {
|
||||
graph.drawTransient('node', id, {
|
||||
onlyDrawKeyShape: true,
|
||||
});
|
||||
});
|
||||
graph.hideItem(this.hiddenNodeIds, true);
|
||||
});
|
||||
graph.hideItem(this.hiddenNodeIds, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,15 +243,17 @@ export default class DragCanvas extends Behavior {
|
||||
|
||||
const { graph } = this;
|
||||
if (this.options.enableOptimize) {
|
||||
graph.startBatch();
|
||||
if (this.hiddenEdgeIds) {
|
||||
graph.showItem(this.hiddenEdgeIds, true, false);
|
||||
graph.showItem(this.hiddenEdgeIds, true);
|
||||
}
|
||||
if (this.hiddenNodeIds) {
|
||||
this.hiddenNodeIds.forEach((id) => {
|
||||
this.graph.drawTransient('node', id, { action: 'remove' });
|
||||
});
|
||||
graph.showItem(this.hiddenNodeIds, true, false);
|
||||
graph.showItem(this.hiddenNodeIds, true);
|
||||
}
|
||||
graph.stopBatch();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,16 +247,16 @@ export default class DragCombo extends Behavior {
|
||||
selectedComboIds,
|
||||
this.hiddenComboTreeRoots,
|
||||
);
|
||||
this.graph.hideItem(
|
||||
this.hiddenEdges.map((edge) => edge.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
this.graph.hideItem(
|
||||
this.hiddenComboTreeRoots.map((child) => child.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
this.graph.executeWithoutStacking(() => {
|
||||
this.graph.hideItem(
|
||||
this.hiddenEdges.map((edge) => edge.id),
|
||||
true,
|
||||
);
|
||||
this.graph.hideItem(
|
||||
this.hiddenComboTreeRoots.map((child) => child.id),
|
||||
true,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Draw transient nodes and edges.
|
||||
@ -277,17 +277,19 @@ export default class DragCombo extends Behavior {
|
||||
});
|
||||
|
||||
// Hide original edges and nodes. They will be restored when pointerup.
|
||||
this.graph.hideItem(selectedComboIds, true, false);
|
||||
this.graph.hideItem(
|
||||
this.hiddenEdges.map((edge) => edge.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
this.graph.hideItem(
|
||||
this.hiddenComboTreeRoots.map((child) => child.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
this.graph.executeWithoutStacking(() => {
|
||||
this.graph.hideItem(selectedComboIds, true, false);
|
||||
this.graph.hideItem(
|
||||
this.hiddenEdges.map((edge) => edge.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
this.graph.hideItem(
|
||||
this.hiddenComboTreeRoots.map((child) => child.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
});
|
||||
} else {
|
||||
this.graph.frontItem(selectedComboIds);
|
||||
}
|
||||
@ -423,11 +425,11 @@ export default class DragCombo extends Behavior {
|
||||
}
|
||||
|
||||
public restoreHiddenItems() {
|
||||
this.graph.pauseStacking();
|
||||
if (this.hiddenEdges.length) {
|
||||
this.graph.showItem(
|
||||
this.hiddenEdges.map((edge) => edge.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
this.hiddenEdges = [];
|
||||
}
|
||||
@ -435,7 +437,6 @@ export default class DragCombo extends Behavior {
|
||||
this.graph.showItem(
|
||||
this.hiddenComboTreeRoots.map((model) => model.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
this.hiddenComboTreeRoots = [];
|
||||
}
|
||||
@ -445,9 +446,9 @@ export default class DragCombo extends Behavior {
|
||||
this.graph.showItem(
|
||||
this.originPositions.map((position) => position.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
}
|
||||
this.graph.resumeStacking();
|
||||
}
|
||||
|
||||
public onPointerUp(event: IG6GraphEvent) {
|
||||
@ -514,6 +515,7 @@ export default class DragCombo extends Behavior {
|
||||
|
||||
public onDropCombo(event: IG6GraphEvent) {
|
||||
const newParentId = event.itemId;
|
||||
this.graph.startBatch();
|
||||
this.originPositions.forEach(({ id }) => {
|
||||
const model = this.graph.getComboData(id);
|
||||
if (!model || model.id === newParentId) return;
|
||||
@ -522,10 +524,12 @@ export default class DragCombo extends Behavior {
|
||||
// event.stopPropagation();
|
||||
this.graph.updateData('combo', { id, data: { parentId: newParentId } });
|
||||
});
|
||||
this.graph.stopBatch();
|
||||
this.onPointerUp(event);
|
||||
}
|
||||
|
||||
public onDropCanvas(event: IG6GraphEvent) {
|
||||
this.graph.startBatch();
|
||||
this.originPositions.forEach(({ id }) => {
|
||||
const model = this.graph.getComboData(id);
|
||||
if (!model) return;
|
||||
@ -533,6 +537,7 @@ export default class DragCombo extends Behavior {
|
||||
if (!parentId) return;
|
||||
this.graph.updateData('combo', { id, data: { parentId: undefined } });
|
||||
});
|
||||
this.graph.stopBatch();
|
||||
this.onPointerUp(event);
|
||||
}
|
||||
}
|
||||
|
@ -236,16 +236,16 @@ export default class DragNode extends Behavior {
|
||||
selectedNodeIds,
|
||||
this.hiddenComboTreeItems,
|
||||
);
|
||||
this.graph.hideItem(
|
||||
this.hiddenEdges.map((edge) => edge.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
this.graph.hideItem(
|
||||
this.hiddenComboTreeItems.map((child) => child.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
this.graph.executeWithoutStacking(() => {
|
||||
this.graph.hideItem(
|
||||
this.hiddenEdges.map((edge) => edge.id),
|
||||
true,
|
||||
);
|
||||
this.graph.hideItem(
|
||||
this.hiddenComboTreeItems.map((child) => child.id),
|
||||
true,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Draw transient nodes and edges.
|
||||
@ -268,17 +268,17 @@ export default class DragNode extends Behavior {
|
||||
});
|
||||
|
||||
// Hide original edges and nodes. They will be restored when pointerup.
|
||||
this.graph.hideItem(selectedNodeIds, true, false);
|
||||
this.graph.hideItem(
|
||||
this.hiddenEdges.map((edge) => edge.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
this.graph.hideItem(
|
||||
this.hiddenComboTreeItems.map((combo) => combo.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
this.graph.executeWithoutStacking(() => {
|
||||
this.graph.hideItem(selectedNodeIds, true);
|
||||
this.graph.hideItem(
|
||||
this.hiddenEdges.map((edge) => edge.id),
|
||||
true,
|
||||
);
|
||||
this.graph.hideItem(
|
||||
this.hiddenComboTreeItems.map((combo) => combo.id),
|
||||
true,
|
||||
);
|
||||
});
|
||||
} else {
|
||||
this.graph.frontItem(selectedNodeIds);
|
||||
}
|
||||
@ -413,11 +413,11 @@ export default class DragNode extends Behavior {
|
||||
}
|
||||
|
||||
public restoreHiddenItems() {
|
||||
this.graph.pauseStacking();
|
||||
if (this.hiddenEdges.length) {
|
||||
this.graph.showItem(
|
||||
this.hiddenEdges.map((edge) => edge.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
this.hiddenEdges = [];
|
||||
}
|
||||
@ -425,7 +425,6 @@ export default class DragNode extends Behavior {
|
||||
this.graph.showItem(
|
||||
this.hiddenComboTreeItems.map((edge) => edge.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
this.hiddenComboTreeItems = [];
|
||||
}
|
||||
@ -435,9 +434,9 @@ export default class DragNode extends Behavior {
|
||||
this.graph.showItem(
|
||||
this.originPositions.map((position) => position.id),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
}
|
||||
this.graph.resumeStacking();
|
||||
}
|
||||
|
||||
public clearState() {
|
||||
|
@ -11,14 +11,18 @@ export class ComboCommand implements Command {
|
||||
}
|
||||
|
||||
undo(graph: IGraph) {
|
||||
this.action === 'expandCombo'
|
||||
? graph.collapseCombo(this.ids, false)
|
||||
: graph.expandCombo(this.ids, false);
|
||||
graph.executeWithoutStacking(() => {
|
||||
this.action === 'expandCombo'
|
||||
? graph.collapseCombo(this.ids)
|
||||
: graph.expandCombo(this.ids);
|
||||
});
|
||||
}
|
||||
|
||||
redo(graph: IGraph) {
|
||||
this.action === 'collapseCombo'
|
||||
? graph.collapseCombo(this.ids, false)
|
||||
: graph.expandCombo(this.ids, false);
|
||||
graph.executeWithoutStacking(() => {
|
||||
this.action === 'collapseCombo'
|
||||
? graph.collapseCombo(this.ids)
|
||||
: graph.expandCombo(this.ids);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { IGraph } from 'types';
|
||||
import { each, isEmpty } from '@antv/util';
|
||||
import { deepMix, each, isEmpty, mix, upperFirst } from '@antv/util';
|
||||
import { STACK_TYPE, StackCfg, StackType } from '../../../types/history';
|
||||
import { Plugin as Base, IPluginBaseConfig } from '../../../types/plugin';
|
||||
import CommandFactory, { Command } from './command';
|
||||
@ -81,12 +81,14 @@ export default class History extends Base {
|
||||
protected undoStack: HistoryStack<Command[]>;
|
||||
protected redoStack: HistoryStack<Command[]>;
|
||||
protected stackSize = 0;
|
||||
protected stackActive = true;
|
||||
protected withoutStackingCounter = 0;
|
||||
protected isBatching: boolean;
|
||||
protected batchCommands: Command[];
|
||||
|
||||
constructor(options?: HistoryConfig) {
|
||||
super();
|
||||
const { enableStack, stackCfg } = options;
|
||||
const { enableStack, stackCfg } = deepMix(this.getDefaultCfgs(), options);
|
||||
this.enableStack = enableStack;
|
||||
this.cfg = stackCfg;
|
||||
this.isBatching = false;
|
||||
@ -95,6 +97,24 @@ export default class History extends Base {
|
||||
this.initBatchCommands();
|
||||
}
|
||||
|
||||
public getDefaultCfgs(): HistoryConfig {
|
||||
return {
|
||||
enableStack: true,
|
||||
stackCfg: {
|
||||
stackSize: 0,
|
||||
stackActive: true,
|
||||
includes: [],
|
||||
excludes: ['updateData'],
|
||||
ignoreAdd: false,
|
||||
ignoreRemove: false,
|
||||
ignoreUpdate: false,
|
||||
ignoreStateChange: false,
|
||||
ignoreLayerChange: false,
|
||||
ignoreDisplayChange: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public init(graph: IGraph) {
|
||||
super.init(graph);
|
||||
this.clear();
|
||||
@ -137,18 +157,50 @@ export default class History extends Base {
|
||||
stackType: StackType = STACK_TYPE.undo,
|
||||
isNew = true,
|
||||
) {
|
||||
if (stackType === STACK_TYPE.undo) {
|
||||
if (isNew) {
|
||||
// Clear the redo stack when a new action is performed to maintain state consistency
|
||||
this.clearRedoStack();
|
||||
if (this.stackActive) {
|
||||
if (stackType === STACK_TYPE.undo) {
|
||||
if (isNew) {
|
||||
// Clear the redo stack when a new action is performed to maintain state consistency
|
||||
this.clearRedoStack();
|
||||
}
|
||||
if (isEmpty(cmd)) return;
|
||||
this.undoStack.push(cmd);
|
||||
this.initBatchCommands();
|
||||
} else {
|
||||
this.redoStack.push(cmd);
|
||||
}
|
||||
if (isEmpty(cmd)) return;
|
||||
this.undoStack.push(cmd);
|
||||
this.initBatchCommands();
|
||||
this.graph.emit('history:change', cmd, stackType, isNew);
|
||||
} else {
|
||||
this.redoStack.push(cmd);
|
||||
throw new Error(
|
||||
'Stacking operations are currently paused. Unable to push to the stack.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause stacking operations.
|
||||
*/
|
||||
pauseStacking(): void {
|
||||
this.withoutStackingCounter++;
|
||||
|
||||
if (this.withoutStackingCounter === 1) {
|
||||
// Only disable on the first call
|
||||
this.stackActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume stacking operations.
|
||||
*/
|
||||
resumeStacking(): void {
|
||||
if (this.withoutStackingCounter > 0) {
|
||||
this.withoutStackingCounter--;
|
||||
}
|
||||
|
||||
if (this.withoutStackingCounter === 0) {
|
||||
// Only enable when all pause requests are cleared
|
||||
this.stackActive = true;
|
||||
}
|
||||
this.graph.emit('history:change', cmd, stackType, isNew);
|
||||
}
|
||||
|
||||
public undo() {
|
||||
@ -223,11 +275,8 @@ export default class History extends Base {
|
||||
*/
|
||||
public batch(callback) {
|
||||
this.startBatch();
|
||||
// try {
|
||||
callback();
|
||||
// } finally {
|
||||
this.stopBatch();
|
||||
// }
|
||||
}
|
||||
|
||||
public getEvents() {
|
||||
@ -242,9 +291,9 @@ export default class History extends Base {
|
||||
}
|
||||
|
||||
private handleUpdateHistory(props) {
|
||||
const { enableStack, changes } = props;
|
||||
const { apiName, changes } = props;
|
||||
if (changes && changes.length === 0) return;
|
||||
if (enableStack) {
|
||||
if (this.shouldPushToStack(apiName)) {
|
||||
this.batchCommands = [
|
||||
...this.batchCommands,
|
||||
...CommandFactory.create(props),
|
||||
@ -256,6 +305,22 @@ export default class History extends Base {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a given operation should be pushed onto the history stack based on various configurations.
|
||||
* @param {string} apiName name of the API operation.
|
||||
* @param {boolean} stack Optional. whether push this operation into graph's stack.
|
||||
*/
|
||||
private shouldPushToStack(apiName: string): boolean {
|
||||
const { includes = [], excludes = [] } = this.cfg;
|
||||
if (!this.enableStack || !this.stackActive) return false;
|
||||
if (includes.includes(apiName)) return true;
|
||||
if (excludes.includes(apiName)) return false;
|
||||
let categoryKey: any = getCategoryByApiName(apiName);
|
||||
if (!categoryKey) return true;
|
||||
categoryKey = 'ignore' + upperFirst(categoryKey);
|
||||
return !this.cfg[categoryKey];
|
||||
}
|
||||
|
||||
public notify(graph, eventName, ...data) {
|
||||
graph.emit(eventName, data);
|
||||
}
|
||||
|
@ -26,15 +26,23 @@ export class ItemDataCommand implements Command {
|
||||
|
||||
private removeChangedData(graph) {
|
||||
const ids = this.changes.map((data) => data.value.id);
|
||||
graph.removeData(this.type, ids, false);
|
||||
graph.executeWithoutStacking(() => {
|
||||
graph.removeData(this.type, ids);
|
||||
});
|
||||
}
|
||||
|
||||
private addChangedData(graph) {
|
||||
const models = this.changes.map((data) => data.value);
|
||||
graph.addData(this.type, models, false);
|
||||
graph.executeWithoutStacking(() => {
|
||||
graph.addData(this.type, models);
|
||||
});
|
||||
}
|
||||
|
||||
private updateChangedData(graph, operationType: StackType, onlyMove = false) {
|
||||
private updateChangedData(
|
||||
graph: IGraph,
|
||||
operationType: StackType,
|
||||
onlyMove = false,
|
||||
) {
|
||||
let models;
|
||||
if (this.type === 'combo' && !onlyMove) {
|
||||
models = this.changes.map((data) => ({
|
||||
@ -53,11 +61,13 @@ export class ItemDataCommand implements Command {
|
||||
});
|
||||
}
|
||||
|
||||
graph.pauseStacking();
|
||||
if (onlyMove) {
|
||||
graph.updatePosition(this.type, models, this.upsertAncestors, false);
|
||||
graph.updatePosition(this.type, models, this.upsertAncestors);
|
||||
} else {
|
||||
graph.updateData(this.type, models, false);
|
||||
graph.updateData(this.type, models);
|
||||
}
|
||||
graph.resumeStacking();
|
||||
}
|
||||
|
||||
undo(graph: IGraph) {
|
||||
|
@ -11,14 +11,18 @@ export class LayerUpdatedCommand implements Command {
|
||||
}
|
||||
|
||||
undo(graph: IGraph) {
|
||||
this.action === 'front'
|
||||
? graph.backItem(this.ids, false)
|
||||
: graph.frontItem(this.ids, false);
|
||||
graph.executeWithoutStacking(() => {
|
||||
this.action === 'front'
|
||||
? graph.backItem(this.ids)
|
||||
: graph.frontItem(this.ids);
|
||||
});
|
||||
}
|
||||
|
||||
redo(graph: IGraph) {
|
||||
this.action === 'front'
|
||||
? graph.frontItem(this.ids, false)
|
||||
: graph.backItem(this.ids, false);
|
||||
graph.executeWithoutStacking(() => {
|
||||
this.action === 'front'
|
||||
? graph.frontItem(this.ids)
|
||||
: graph.backItem(this.ids);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,9 @@ export class StateUpdatedCommand implements Command {
|
||||
private updateItemsStates(graph, stateOptions) {
|
||||
stateOptions?.map((option) => {
|
||||
const { ids, states, value } = option;
|
||||
graph.setItemState(ids, states, value, false);
|
||||
graph.executeWithoutStacking(() => {
|
||||
graph.setItemState(ids, states, value);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -19,12 +19,14 @@ export class VisibilityUpdatedCommand implements Command {
|
||||
this.disableAnimate = disableAnimate;
|
||||
}
|
||||
|
||||
private toggleItemsVisible(graph, values) {
|
||||
private toggleItemsVisible(graph: IGraph, values) {
|
||||
graph.pauseStacking();
|
||||
each(values, (value) =>
|
||||
value.visible
|
||||
? graph.showItem(value.ids, this.disableAnimate, false)
|
||||
: graph.hideItem(value.ids, this.disableAnimate, false),
|
||||
? graph.showItem(value.ids, this.disableAnimate)
|
||||
: graph.hideItem(value.ids, this.disableAnimate),
|
||||
);
|
||||
graph.resumeStacking();
|
||||
}
|
||||
|
||||
undo(graph: IGraph) {
|
||||
|
@ -648,7 +648,19 @@ export interface IGraph<
|
||||
* @param stackType undo/redo stack
|
||||
*/
|
||||
pushStack: (cmd: Command[], stackType: StackType) => void;
|
||||
|
||||
/**
|
||||
* Pause stacking operation.
|
||||
*/
|
||||
pauseStacking: () => void;
|
||||
/**
|
||||
* Resume stacking operation.
|
||||
*/
|
||||
resumeStacking: () => void;
|
||||
/**
|
||||
* Execute a callback without allowing any stacking operations.
|
||||
* @param callback
|
||||
*/
|
||||
executeWithoutStacking: (callback: () => void) => void;
|
||||
/**
|
||||
* Retrieve the current redo stack which consists of operations that could be undone
|
||||
*/
|
||||
@ -701,6 +713,13 @@ export interface IGraph<
|
||||
*/
|
||||
stopBatch: () => void;
|
||||
|
||||
/**
|
||||
* Execute a provided function within a batched context
|
||||
* All operations performed inside callback will be treated as a composite operation
|
||||
* more convenient way without manually invoking `startBatch` and `stopBatch`.
|
||||
* @param callback The func containing operations to be batched together.
|
||||
*/
|
||||
batch: (callback: () => void) => void;
|
||||
/**
|
||||
* Execute a provided function within a batched context
|
||||
* All operations performed inside callback will be treated as a composite operation
|
||||
|
@ -1,13 +1,19 @@
|
||||
export type StackCfg = {
|
||||
stackSize?: number;
|
||||
/** Indicate whether the stack is active. If active, operations can be pushed onto the stack; otherwise, cannot. */
|
||||
stackActive?: boolean;
|
||||
/** Allows finer-grained control over the ignore option.
|
||||
* If an API is in excludes, even if its operation type is not ignored, it will not be put on the stack
|
||||
*/
|
||||
excludes?: string[];
|
||||
includes?: string[];
|
||||
/** ignore* is a global setting that indicates whether to ignore a certain type of operation */
|
||||
ignoreAdd?: boolean;
|
||||
ignoreRemove?: boolean;
|
||||
ignoreUpdate?: boolean;
|
||||
ignoreStateChange?: boolean;
|
||||
ignoreLayerChange?: boolean;
|
||||
ignoreDisplayChange?: boolean;
|
||||
includes?: string[];
|
||||
excludes?: string[];
|
||||
};
|
||||
|
||||
export enum STACK_TYPE {
|
||||
|
@ -172,6 +172,14 @@ export default (context) => {
|
||||
type: 'circle-node',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'node3',
|
||||
data: {
|
||||
x: 100,
|
||||
y: 150,
|
||||
type: 'circle-node',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'node4',
|
||||
data: {
|
||||
@ -193,6 +201,14 @@ export default (context) => {
|
||||
type: 'line-edge',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'edge2',
|
||||
source: 'node1',
|
||||
target: 'node3',
|
||||
data: {
|
||||
type: 'line-edge',
|
||||
},
|
||||
},
|
||||
],
|
||||
// combos: [{ id: 'combo1', data: { x: 400, y: 100 } }],
|
||||
};
|
||||
@ -247,10 +263,11 @@ export default (context) => {
|
||||
},
|
||||
edge,
|
||||
// enableStack: false,
|
||||
stackCfg: {
|
||||
stackSize: 0,
|
||||
// ignoreStateChange: true,
|
||||
},
|
||||
// stackCfg: {
|
||||
// stackSize: 0,
|
||||
// stackActive: true,
|
||||
// ignoreStateChange: true,
|
||||
// },
|
||||
});
|
||||
|
||||
const { undoButton, redoButton } = createOperations(graph);
|
||||
|
Loading…
Reference in New Issue
Block a user