Node Swapping
If you want users to reorganize your chart visually, node swapping with drag and drop is a clean approach.
This example enables drag and drop, then handles three important drop scenarios:
- Swap nodes on the same level.
- Swap parent-child nodes.
- Swap nodes from different levels and rewire children safely.
Core Setup
javascript
let chart = new OrgChart(document.getElementById("tree"), {
mode: 'dark',
enableDragDrop: true,
nodeBinding: {
field_0: "id",
field_1: "pid",
},
orderBy: 'order'
});The key options are:
enableDragDrop: trueto allow dragging.orderBy: 'order'so rendering follows your custom sequence.
Drop Logic
javascript
chart.onDrop((args) => {
let dragData = chart.get(args.dragId);
let dropData = chart.get(args.dropId);
if (dropData != undefined) {
let dragNode = chart.getNode(args.dragId);
let dropNode = chart.getNode(args.dropId);
if (dragNode.level == dropNode.level) {
let temp = dropData.order;
dropData.order = dragData.order;
dragData.order = temp;
temp = dropData.pid;
dropData.pid = dragData.pid;
dragData.pid = temp;
chart.update(dropData).update(dragData).draw();
}
else if (dragData.pid == dropData.id || dragData.id == dropData.pid) {
for (let i = 0; i < chart.config.nodes.length; i++) {
let data = chart.config.nodes[i];
if (data.pid == args.dropId) {
data.pid = args.dragId;
}
else if (data.pid == args.dragId) {
data.pid = args.dropId;
}
}
if (dragData.pid == dropData.id) {
dragData.pid = dropData.pid;
dropData.pid = dragData.id;
}
else if (dragData.id == dropData.pid) {
dropData.pid = dragData.pid;
dragData.pid = dropData.id;
}
let temp = dropData.order;
dropData.order = dragData.order;
dragData.order = temp;
chart.update(dropData).update(dragData).draw();
}
else {
for (let i = 0; i < chart.config.nodes.length; i++) {
let data = chart.config.nodes[i];
if (dragNode.level > dropNode.level && data.pid == args.dropId) {
data.pid = args.dragId;
}
else if (dragNode.level < dropNode.level && data.pid == args.dragId) {
data.pid = args.dropId;
}
chart.update(data)
}
let temp = dragData.pid;
dragData.pid = dropData.pid;
dropData.pid = temp;
temp = dropData.order;
dropData.order = dragData.order;
dragData.order = temp;
chart.update(dropData).update(dragData).draw();
}
}
return false;
})Returning false cancels the default drop behavior, so your custom swapping logic is always used.
Sample Data
javascript
chart.load([
{ id: 1, order: 1 },
{ id: 2, pid: 1, order: 2 },
{ id: 3, pid: 1, order: 3 },
{ id: 4, pid: 2, order: 4 },
{ id: 5, pid: 2, order: 5 },
{ id: 6, pid: 3, order: 6 },
{ id: 7, pid: 3, order: 7 }
]);Important Notes
- Always update both
pidandorderwhen swapping nodes. - Redraw after updates to keep the UI in sync.
- Handle parent-child swaps separately to avoid broken hierarchy.