|
@@ -163,6 +163,234 @@ Draw.loadPlugin(function(ui)
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+ // Adds resource for action
|
|
|
+ mxResources.parse('placeChildren=Place children...');
|
|
|
+
|
|
|
+ // Adds action
|
|
|
+ ui.actions.addAction('placeChildren', function()
|
|
|
+ {
|
|
|
+ var graph = ui.editor.graph;
|
|
|
+ var cells = graph.getSelectionCells().slice();
|
|
|
+
|
|
|
+ if (cells.length > 1)
|
|
|
+ {
|
|
|
+
|
|
|
+ var counter = 0;
|
|
|
+ var delay = parseInt(prompt('Delay (ms)', defaultDelay));
|
|
|
+ var max = parseInt(prompt('Cycles', defaultMax));
|
|
|
+
|
|
|
+
|
|
|
+ function schedule()
|
|
|
+ {
|
|
|
+ var jitter = 1 + 0.3 * (Math.random() - 0.5);
|
|
|
+
|
|
|
+ window.setTimeout(function()
|
|
|
+ {
|
|
|
+ // assuming parent is the first cell selected
|
|
|
+ var parentA = cells[0];
|
|
|
+ var parentB = cells[1];
|
|
|
+
|
|
|
+ var childrenA = parentA.children;
|
|
|
+ var childrenB = parentB.children;
|
|
|
+
|
|
|
+ var numberA = (childrenA != null)? childrenA.length: 0;
|
|
|
+ var numberB = (childrenB != null)? childrenB.length: 0;
|
|
|
+
|
|
|
+ var n = 0;
|
|
|
+
|
|
|
+ if (childrenA != null && childrenA.length > 1 || childrenB != null && childrenB.length > 1)
|
|
|
+ {
|
|
|
+ graph.getModel().beginUpdate();
|
|
|
+ try
|
|
|
+ {
|
|
|
+ // first, remove a few children from each parent
|
|
|
+ childrenA = parentA.children;
|
|
|
+ childrenB = parentB.children;
|
|
|
+ numberA = (childrenA != null)? childrenA.length: 0;
|
|
|
+ numberB = (childrenB != null)? childrenB.length: 0;
|
|
|
+
|
|
|
+ // 1st parent
|
|
|
+ n = Math.floor(Math.random() * 4); // how many to delete? at least 1 should remain
|
|
|
+ n = Math.min(n, Math.max(0, numberA - 2));
|
|
|
+ console.log(counter + " - removing " + n + " children from parent A");
|
|
|
+ for (var i = 0; i < n; i++)
|
|
|
+ {
|
|
|
+ childrenA = parentA.children;
|
|
|
+ numberA = (childrenA != null)? childrenA.length: 0;
|
|
|
+ if (numberA > 0)
|
|
|
+ {
|
|
|
+ var k = Math.floor(Math.random() * numberA);
|
|
|
+ parentA.remove(k);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2nd parent
|
|
|
+ n = Math.floor(Math.random() * 4); // how many to delete? at least 1 should remain
|
|
|
+ n = Math.min(n, Math.max(0, numberB - 2));
|
|
|
+ console.log(counter + " - removing " + n + " children from parent B");
|
|
|
+ for (var i = 0; i < n; i++)
|
|
|
+ {
|
|
|
+ childrenB = parentB.children;
|
|
|
+ numberB = (childrenB != null)? childrenB.length: 0;
|
|
|
+ if (numberB > 0)
|
|
|
+ {
|
|
|
+ var k = Math.floor(Math.random() * numberB);
|
|
|
+ parentB.remove(k);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // second, insert a few children to each parent
|
|
|
+ childrenA = parentA.children;
|
|
|
+ childrenB = parentB.children;
|
|
|
+ numberA = (childrenA != null)? childrenA.length: 0;
|
|
|
+ numberB = (childrenB != null)? childrenB.length: 0;
|
|
|
+
|
|
|
+ // 1st parent
|
|
|
+ n = Math.floor(Math.random() * 4); // how many to insert?
|
|
|
+ console.log(counter + " - inserting " + n + " children into parent A");
|
|
|
+ for (var i = 0; i < n; i++)
|
|
|
+ {
|
|
|
+ childrenA = parentA.children;
|
|
|
+ numberA = (childrenA != null)? childrenA.length: 0;
|
|
|
+ if (numberA > 0)
|
|
|
+ {
|
|
|
+ var k = Math.floor(Math.random() * numberA);
|
|
|
+ var x = Math.floor(Math.random() * 200);
|
|
|
+ var y = Math.floor(Math.random() * 50);
|
|
|
+ var number = Math.floor(Math.random() * 9000 + 1000);
|
|
|
+ var child = graph.insertVertex(parentA, null, number.toString(), x, y, 120, 30);
|
|
|
+ parentA.insert(child, k);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2nd parent
|
|
|
+ n = Math.floor(Math.random() * 4); // how many to insert?
|
|
|
+ console.log(counter + " - inserting " + n + " children into parent B");
|
|
|
+ for (var i = 0; i < n; i++)
|
|
|
+ {
|
|
|
+ childrenB = parentB.children;
|
|
|
+ numberB = (childrenB != null)? childrenB.length: 0;
|
|
|
+ if (numberB > 0)
|
|
|
+ {
|
|
|
+ var k = Math.floor(Math.random() * numberB);
|
|
|
+ var x = Math.floor(Math.random() * 200);
|
|
|
+ var y = Math.floor(Math.random() * 50);
|
|
|
+ var number = Math.floor(Math.random() * 9000 + 1000);
|
|
|
+ var child = graph.insertVertex(parentB, null, number.toString(), x, y, 120, 30);
|
|
|
+ parentB.insert(child, k);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // third, shuffle children in each parent
|
|
|
+ childrenA = parentA.children;
|
|
|
+ childrenB = parentB.children;
|
|
|
+ numberA = (childrenA != null)? childrenA.length: 0;
|
|
|
+ numberB = (childrenB != null)? childrenB.length: 0;
|
|
|
+
|
|
|
+ // 1st parent
|
|
|
+ n = Math.floor(Math.random() * numberA); // how many to shuffle?
|
|
|
+ console.log(counter + " - moving " + n + " children inside parent A");
|
|
|
+ for (var i = 0; i < n; i++)
|
|
|
+ {
|
|
|
+ childrenA = parentA.children;
|
|
|
+ numberA = (childrenA != null)? childrenA.length: 0;
|
|
|
+ if (numberA > 0)
|
|
|
+ {
|
|
|
+ var k = Math.floor(Math.random() * numberA); // from index
|
|
|
+ var l = Math.floor(Math.random() * numberA); // to index
|
|
|
+ var child = parentA.getChildAt(k);
|
|
|
+ parentA.insert(child, l);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2nd parent
|
|
|
+ n = Math.floor(Math.random() * numberB); // how many to shuffle?
|
|
|
+ console.log(counter + " - moving " + n + " children inside parent B");
|
|
|
+ for (var i = 0; i < n; i++)
|
|
|
+ {
|
|
|
+ childrenB = parentB.children;
|
|
|
+ numberB = (childrenB != null)? childrenB.length: 0;
|
|
|
+ if (numberB > 0)
|
|
|
+ {
|
|
|
+ var k = Math.floor(Math.random() * numberB); // from index
|
|
|
+ var l = Math.floor(Math.random() * numberB); // to index
|
|
|
+ var child = parentB.getChildAt(k);
|
|
|
+ parentB.insert(child, l);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // fourth, exchange a few children between both parents
|
|
|
+ childrenA = parentA.children;
|
|
|
+ childrenB = parentB.children;
|
|
|
+ numberA = (childrenA != null)? childrenA.length: 0;
|
|
|
+ numberB = (childrenB != null)? childrenB.length: 0;
|
|
|
+
|
|
|
+ // permute children
|
|
|
+ var passes = Math.floor(Math.random() * numberA) + 1;
|
|
|
+ console.log(counter + " - swapping " + passes + " children from parent A to parent B");
|
|
|
+
|
|
|
+ for (var i = 0; i < passes; i++)
|
|
|
+ {
|
|
|
+ // which child to select from parent A
|
|
|
+ var k = Math.floor(Math.random() * numberA);
|
|
|
+ // where to insert it to parent B
|
|
|
+ var l = Math.floor(Math.random() * (numberB + 1));
|
|
|
+ graph.model.add(parentB, childrenA[k], l);
|
|
|
+
|
|
|
+ numberA -= 1;
|
|
|
+ numberB += 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ var passes = Math.floor(Math.random() * numberB) + 1;
|
|
|
+ console.log(counter + " - swapping " + passes + " children from parent B to parent A");
|
|
|
+
|
|
|
+ for (var i = 0; i < passes; i++)
|
|
|
+ {
|
|
|
+ // which child to select from parent A
|
|
|
+ var k = Math.floor(Math.random() * numberB);
|
|
|
+ // where to insert it to parent B
|
|
|
+ var l = Math.floor(Math.random() * (numberA + 1));
|
|
|
+ graph.model.add(parentA, childrenB[k], l);
|
|
|
+ numberA += 1;
|
|
|
+ numberB -= 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ graph.getModel().endUpdate();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ui.dialog != null)
|
|
|
+ {
|
|
|
+ console.log('swapChildren halted');
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ui.saveFile(null, function()
|
|
|
+ {
|
|
|
+ if (counter++ < max && ui.dialog == null)
|
|
|
+ {
|
|
|
+ console.log('swapChildren', counter);
|
|
|
+ schedule();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ console.log('swapChildren halted');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }, delay * jitter);
|
|
|
+ }
|
|
|
+
|
|
|
+ schedule();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ui.alert(mxResources.get('nothingIsSelected'));
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
// Adds resource for action
|
|
|
mxResources.parse('reorderChildren=Reorder children...');
|
|
|
|
|
@@ -247,6 +475,6 @@ Draw.loadPlugin(function(ui)
|
|
|
{
|
|
|
oldFunct.apply(this, arguments);
|
|
|
|
|
|
- ui.menus.addMenuItems(menu, ['-', 'randomLabel', 'reorderChildren', 'swapChildren'], parent);
|
|
|
+ ui.menus.addMenuItems(menu, ['-', 'randomLabel', 'reorderChildren', 'swapChildren', 'placeChildren'], parent);
|
|
|
};
|
|
|
});
|