mirror of
https://gitee.com/antv/g6.git
synced 2024-11-30 10:48:24 +08:00
feat: darg combo with states
This commit is contained in:
parent
4a8171a104
commit
8c7550956d
@ -37,6 +37,8 @@ export default {
|
||||
return {
|
||||
enableDelegate: false,
|
||||
delegateStyle: {},
|
||||
// 拖动节点过程中是否只改变 Combo 的大小,而不改变其结构
|
||||
onlyChangeComboSize: false,
|
||||
// 拖动过程中目标 combo 状态样式
|
||||
activeState: '',
|
||||
selectedState: 'selected'
|
||||
@ -100,8 +102,6 @@ export default {
|
||||
this.point = {};
|
||||
this.originPoint = {};
|
||||
|
||||
this.itemStates = {}
|
||||
|
||||
this.origin = {
|
||||
x: evt.x,
|
||||
y: evt.y
|
||||
@ -195,7 +195,10 @@ export default {
|
||||
if (this.activeState) {
|
||||
graph.setItemState(item, this.activeState, false)
|
||||
}
|
||||
graph.updateComboTree(combo, targetModel.id)
|
||||
// 将 Combo 放置到某个 Combo 上面时,只有当 onlyChangeComboSize 为 false 时候才更新 Combo 结构
|
||||
if (!this.onlyChangeComboSize) {
|
||||
graph.updateComboTree(combo, targetModel.id)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -242,102 +245,107 @@ export default {
|
||||
|
||||
const model = item.getModel()
|
||||
|
||||
// 拖动结束时计算拖入还是拖出, 需要更新 combo
|
||||
// 1. 是否将当前 combo 拖出了 父 combo;
|
||||
// 2. 是否将当前 combo 拖入了新的 combo
|
||||
const type = item.getType()
|
||||
if (type === 'combo') {
|
||||
const parentId = model.parentId
|
||||
// 拖动 Combo 结束后,如果 onlyChangeComboSize 值为 true 则只更新 Combo 位置,不更新结构
|
||||
if (this.onlyChangeComboSize) {
|
||||
graph.updateCombos()
|
||||
} else {
|
||||
// 拖动结束时计算拖入还是拖出, 需要更新 combo
|
||||
// 1. 是否将当前 combo 拖出了 父 combo;
|
||||
// 2. 是否将当前 combo 拖入了新的 combo
|
||||
const type = item.getType()
|
||||
if (type === 'combo') {
|
||||
const parentId = model.parentId
|
||||
|
||||
let currentBBox = null
|
||||
const parentCombo = this.getParentCombo(parentId)
|
||||
let currentBBox = null
|
||||
const parentCombo = this.getParentCombo(parentId)
|
||||
|
||||
// 当只有存在 parentCombo 时才处理拖出的情况
|
||||
if (parentCombo) {
|
||||
if (this.enableDelegate) {
|
||||
currentBBox = this.delegateShape.getBBox()
|
||||
} else {
|
||||
currentBBox = item.getBBox()
|
||||
}
|
||||
const { x: cx, y: cy, centerX, centerY, width } = currentBBox;
|
||||
|
||||
//判断是否拖出了 combo,需要满足:
|
||||
// 1、有 parent;
|
||||
// 2、拿拖动的对象和它父parent比较
|
||||
|
||||
const parentBBox = parentCombo.getBBox()
|
||||
const { minX, minY, maxX, maxY, centerX: pcx, centerY: pcy, width: w } = parentBBox;
|
||||
|
||||
// 拖出了父 combo
|
||||
// 如果直接拖出到了 父 combo 周边,则不用计算距离圆心距离
|
||||
if (cx <= minX || cx >= maxX || cy <= minY || cy >= maxY) {
|
||||
if (this.activeState) {
|
||||
graph.setItemState(parentCombo, this.activeState, false)
|
||||
// 当只有存在 parentCombo 时才处理拖出的情况
|
||||
if (parentCombo) {
|
||||
if (this.enableDelegate) {
|
||||
currentBBox = this.delegateShape.getBBox()
|
||||
} else {
|
||||
currentBBox = item.getBBox()
|
||||
}
|
||||
isDragOut = true
|
||||
// 表示正在拖出操作
|
||||
graph.updateComboTree(item as ICombo)
|
||||
} else {
|
||||
// 拖动的 combo 和要进入的 combo 之间的距离
|
||||
const disX = centerX - pcx
|
||||
const disY = centerY - pcy
|
||||
// 圆心距离
|
||||
const distance = 2 * Math.sqrt(disX * disX + disY * disY)
|
||||
const { x: cx, y: cy, centerX, centerY, width } = currentBBox;
|
||||
|
||||
// 拖出的还在父 combo 包围盒范围内,但实际上已经拖出去了
|
||||
if ((width + w) - distance < 0.8 * width) {
|
||||
//判断是否拖出了 combo,需要满足:
|
||||
// 1、有 parent;
|
||||
// 2、拿拖动的对象和它父parent比较
|
||||
|
||||
const parentBBox = parentCombo.getBBox()
|
||||
const { minX, minY, maxX, maxY, centerX: pcx, centerY: pcy, width: w } = parentBBox;
|
||||
|
||||
// 拖出了父 combo
|
||||
// 如果直接拖出到了 父 combo 周边,则不用计算距离圆心距离
|
||||
if (cx <= minX || cx >= maxX || cy <= minY || cy >= maxY) {
|
||||
if (this.activeState) {
|
||||
graph.setItemState(parentCombo, this.activeState, false)
|
||||
}
|
||||
isDragOut = true
|
||||
// 表示正在拖出操作
|
||||
graph.updateComboTree(item as ICombo)
|
||||
} else {
|
||||
// 拖动的 combo 和要进入的 combo 之间的距离
|
||||
const disX = centerX - pcx
|
||||
const disY = centerY - pcy
|
||||
// 圆心距离
|
||||
const distance = 2 * Math.sqrt(disX * disX + disY * disY)
|
||||
|
||||
// 拖出的还在父 combo 包围盒范围内,但实际上已经拖出去了
|
||||
if ((width + w) - distance < 0.8 * width) {
|
||||
if (this.activeState) {
|
||||
graph.setItemState(parentCombo, this.activeState, false)
|
||||
}
|
||||
isDragOut = true
|
||||
graph.updateComboTree(item as ICombo)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 拖入
|
||||
if (!this.endComparison && !isDragOut) {
|
||||
// 判断是否拖入了 父 Combo,需要满足:
|
||||
// 1、拖放最终位置是 combo,且不是父 Combo;
|
||||
// 2、拖动 Combo 进入到非父 Combo 超过 50%;
|
||||
const combos = graph.getCombos()
|
||||
const sourceBBox = item.getBBox()
|
||||
// 拖入
|
||||
if (!this.endComparison && !isDragOut) {
|
||||
// 判断是否拖入了 父 Combo,需要满足:
|
||||
// 1、拖放最终位置是 combo,且不是父 Combo;
|
||||
// 2、拖动 Combo 进入到非父 Combo 超过 50%;
|
||||
const combos = graph.getCombos()
|
||||
const sourceBBox = item.getBBox()
|
||||
|
||||
const { centerX, centerY, width } = sourceBBox
|
||||
const { centerX, centerY, width } = sourceBBox
|
||||
|
||||
// 参与计算的 Combo,需要排除掉:
|
||||
// 1、拖动 combo 自己
|
||||
// 2、拖动 combo 的 parent
|
||||
// 3、拖动 Combo 的 children
|
||||
const calcCombos = combos.filter(combo => {
|
||||
const cmodel = combo.getModel() as ComboConfig
|
||||
// 被拖动的是最外层的 Combo,无 parent,排除自身和子元素
|
||||
if (!model.parentId) {
|
||||
// 参与计算的 Combo,需要排除掉:
|
||||
// 1、拖动 combo 自己
|
||||
// 2、拖动 combo 的 parent
|
||||
// 3、拖动 Combo 的 children
|
||||
const calcCombos = combos.filter(combo => {
|
||||
const cmodel = combo.getModel() as ComboConfig
|
||||
// 被拖动的是最外层的 Combo,无 parent,排除自身和子元素
|
||||
if (!model.parentId) {
|
||||
return cmodel.id !== model.id && !this.currentItemChildCombos.includes(cmodel.id)
|
||||
}
|
||||
return cmodel.id !== model.id && !this.currentItemChildCombos.includes(cmodel.id)
|
||||
}
|
||||
return cmodel.id !== model.id && !this.currentItemChildCombos.includes(cmodel.id)
|
||||
})
|
||||
})
|
||||
|
||||
calcCombos.map(combo => {
|
||||
const current = combo.getModel()
|
||||
const { centerX: cx, centerY: cy, width: w } = combo.getBBox()
|
||||
calcCombos.map(combo => {
|
||||
const current = combo.getModel()
|
||||
const { centerX: cx, centerY: cy, width: w } = combo.getBBox()
|
||||
|
||||
// 拖动的 combo 和要进入的 combo 之间的距离
|
||||
const disX = centerX - cx
|
||||
const disY = centerY - cy
|
||||
// 圆心距离
|
||||
const distance = 2 * Math.sqrt(disX * disX + disY * disY)
|
||||
// 拖动的 combo 和要进入的 combo 之间的距离
|
||||
const disX = centerX - cx
|
||||
const disY = centerY - cy
|
||||
// 圆心距离
|
||||
const distance = 2 * Math.sqrt(disX * disX + disY * disY)
|
||||
|
||||
if (this.activeState) {
|
||||
graph.setItemState(combo, this.activeState, false)
|
||||
}
|
||||
if (this.activeState) {
|
||||
graph.setItemState(combo, this.activeState, false)
|
||||
}
|
||||
|
||||
if ((width + w) - distance > 0.8 * width) {
|
||||
graph.updateComboTree(item as ICombo, current.id)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if ((width + w) - distance > 0.8 * width) {
|
||||
graph.updateComboTree(item as ICombo, current.id)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 删除delegate shape
|
||||
@ -347,11 +355,6 @@ export default {
|
||||
this.delegateShape = null
|
||||
}
|
||||
|
||||
for (let itemId in this.itemStates) {
|
||||
const states = this.itemStates[itemId]
|
||||
each(states, state => graph.setItemState(item, state, true))
|
||||
}
|
||||
|
||||
const parentCombo = this.getParentCombo(model.parentId)
|
||||
if (parentCombo && this.activeState) {
|
||||
graph.setItemState(parentCombo, this.activeState, false)
|
||||
@ -362,7 +365,6 @@ export default {
|
||||
this.origin = null
|
||||
this.originPoint = null
|
||||
this.targets.length = 0
|
||||
this.itemStates = {}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -419,12 +421,6 @@ export default {
|
||||
const x: number = evt.x - origin.x + this.point[itemId].x;
|
||||
const y: number = evt.y - origin.y + this.point[itemId].y;
|
||||
|
||||
if (item.getStates().length > 0) {
|
||||
const states = item.getStates()
|
||||
this.itemStates[itemId] = [...states]
|
||||
each(states, state => graph.setItemState(item, state, false))
|
||||
}
|
||||
|
||||
graph.updateItem(item, { x, y });
|
||||
},
|
||||
|
||||
|
@ -19,6 +19,8 @@ export default {
|
||||
delegateStyle: {},
|
||||
// 是否开启delegate
|
||||
enableDelegate: false,
|
||||
// 拖动节点过程中是否只改变 Combo 的大小,而不改变其结构
|
||||
onlyChangeComboSize: false,
|
||||
// 拖动过程中目标 combo 状态样式
|
||||
comboActiveState: '',
|
||||
selectedState: 'selected'
|
||||
@ -126,26 +128,43 @@ export default {
|
||||
this.delegateRect = null;
|
||||
}
|
||||
|
||||
if (this.target) {
|
||||
const delegateShape = this.target.get('delegateShape');
|
||||
if (delegateShape) {
|
||||
delegateShape.remove();
|
||||
this.target.set('delegateShape', null);
|
||||
}
|
||||
// 当开启 delegate 时,拖动结束后需要更新所有已选中节点的位置
|
||||
if (this.get('enableDelegate')) {
|
||||
this.targets.map(node => this.update(node, evt));
|
||||
}
|
||||
|
||||
if (this.targets.length > 0) {
|
||||
// 获取所有已经选中的节点
|
||||
this.targets.forEach(node => this.update(node, evt));
|
||||
} else if (this.target) {
|
||||
this.update(this.target, evt);
|
||||
const graph: IGraph = this.graph
|
||||
|
||||
// 拖动结束后是动态改变 Combo 大小还是将节点从 Combo 中删除
|
||||
if (this.onlyChangeComboSize) {
|
||||
// 拖动节点结束后,动态改变 Combo 的大小
|
||||
graph.updateCombos()
|
||||
} else {
|
||||
// 拖放到了最外面,如果targets中有 combo,则删除掉
|
||||
if (!this.targetCombo) {
|
||||
this.targets.map((node: INode) => {
|
||||
// 拖动的节点有 comboId,即是从其他 combo 中拖出时才处理
|
||||
const model = node.getModel()
|
||||
if (model.comboId) {
|
||||
graph.updateComboTree(node)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const targetComboModel = this.targetCombo.getModel()
|
||||
this.targets.map((node: INode) => {
|
||||
const nodeModel = node.getModel()
|
||||
if (nodeModel.comboId !== targetComboModel.id) {
|
||||
graph.updateComboTree(node, targetComboModel.id)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
this.point = {};
|
||||
this.origin = null;
|
||||
this.originPoint = {};
|
||||
this.targets.length = 0;
|
||||
this.target = null;
|
||||
this.targetCombo = null;
|
||||
},
|
||||
/**
|
||||
* 拖动过程中将节点放置到 combo 上
|
||||
|
@ -944,7 +944,23 @@ export default class Graph extends EventEmitter implements IGraph {
|
||||
*/
|
||||
public updateItem(item: Item | string, cfg: Partial<NodeConfig> | EdgeConfig): void {
|
||||
const itemController: ItemController = this.get('itemController');
|
||||
itemController.updateItem(item, cfg);
|
||||
let currentItem
|
||||
if (isString(item)) {
|
||||
currentItem = this.findById(item)
|
||||
} else {
|
||||
currentItem = item
|
||||
}
|
||||
|
||||
const type = currentItem.getType()
|
||||
const states = [...currentItem.getStates()]
|
||||
if (type === 'combo') {
|
||||
each(states, state => this.setItemState(currentItem, state, false))
|
||||
}
|
||||
itemController.updateItem(currentItem, cfg);
|
||||
|
||||
if (type === 'combo') {
|
||||
each(states, state => this.setItemState(currentItem, state, true))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1368,7 +1384,15 @@ export default class Graph extends EventEmitter implements IGraph {
|
||||
}
|
||||
const childItem = itemMap[child.id];
|
||||
if (childItem && childItem.getType() === 'combo') {
|
||||
// 更新具体的 Combo 之前先清除所有的已有状态,以免将 state 中的样式更新为 Combo 的样式
|
||||
const states = [...childItem.getStates()]
|
||||
each(states, state => this.setItemState(childItem, state, false))
|
||||
|
||||
// 更新具体的 Combo
|
||||
itemController.updateCombo(childItem, child.children);
|
||||
|
||||
// 更新 Combo 后,还原已有的状态
|
||||
each(states, state => this.setItemState(childItem, state, true))
|
||||
}
|
||||
return true;
|
||||
});
|
||||
@ -1413,6 +1437,7 @@ export default class Graph extends EventEmitter implements IGraph {
|
||||
if (parentId) {
|
||||
const parentCombo = this.findById(parentId) as ICombo
|
||||
if (parentCombo) {
|
||||
// 将元素添加到 parentCombo 中
|
||||
parentCombo.addChild(uItem as ICombo | INode)
|
||||
}
|
||||
}
|
||||
@ -1420,6 +1445,7 @@ export default class Graph extends EventEmitter implements IGraph {
|
||||
if (oldParentId) {
|
||||
const parentCombo = this.findById(oldParentId) as ICombo
|
||||
if (parentCombo) {
|
||||
// 将元素从 parentCombo 中移除
|
||||
parentCombo.removeChild(uItem as ICombo | INode)
|
||||
}
|
||||
}
|
||||
|
@ -121,6 +121,7 @@ export interface ModeOption {
|
||||
activeState?: string;
|
||||
comboActiveState?: string;
|
||||
selectedState?: string;
|
||||
onlyChangeComboSize?: boolean;
|
||||
includeEdges?: boolean;
|
||||
direction?: 'x' | 'y';
|
||||
shouldUpdate?: (e: IG6GraphEvent) => boolean;
|
||||
|
@ -320,7 +320,7 @@ describe('drag-combo', () => {
|
||||
// fill: '#f00',
|
||||
// fontSize: 20
|
||||
// },
|
||||
stroke: '#f00'
|
||||
stroke: 'blue'
|
||||
},
|
||||
active: {
|
||||
stroke: 'red'
|
||||
|
Loading…
Reference in New Issue
Block a user