Переглянути джерело

Stat tree edit - create child permutations

Vijayakrishnan 3 роки тому
батько
коміт
61c9298d87

+ 117 - 0
resources/views/app/stat-tree/stat-trees/sub/edit.blade.php

@@ -698,6 +698,16 @@
                                                                             StatTree.el.jstree(true).delete_node(selected.id);
                                                                             StatTree.setDirty();
                                                                         }
+                                                                    },
+                                                                    separator_after: true,
+                                                                },
+                                                                "permutate_child_tree": {
+                                                                    "label": "<span class='text-sm'>Create Child Permutations</span>",
+                                                                    "action": function (obj) {
+                                                                        let selected = StatTree.selectedNode();
+                                                                        if(selected) {
+                                                                            StatTree.createChildTreePermutations(selected);
+                                                                        }
                                                                     }
                                                                 }
                                                             }
@@ -719,6 +729,113 @@
                                     }, 'json').then(hideMask);
                                 },
 
+                                createChildTreePermutations: function(_node) {
+
+                                    // permute: thanks: https://stackoverflow.com/a/37580979/921204
+                                    function _permute(permutation) {
+                                        var length = permutation.length,
+                                            result = [permutation.slice()],
+                                            c = new Array(length).fill(0),
+                                            i = 1, k, p;
+
+                                        while (i < length) {
+                                            if (c[i] < i) {
+                                                k = i % 2 && c[i];
+                                                p = permutation[i];
+                                                permutation[i] = permutation[k];
+                                                permutation[k] = p;
+                                                ++c[i];
+                                                i = 1;
+                                                result.push(permutation.slice());
+                                            } else {
+                                                c[i] = 0;
+                                                ++i;
+                                            }
+                                        }
+                                        return result;
+                                    }
+
+                                    // ensure 1 child for selected node
+                                    if(_node.children.length !== 1) {
+                                        toastr.error('Line must have exactly one child!');
+                                        return;
+                                    }
+
+                                    // ensure all nodes down the node in the tree have only one child (if any)
+                                    function _hasSingleChild(_id) {
+                                        let node = StatTree.el.jstree(true).get_node(_id);
+                                        if(node.children.length === 0) return true; // no children
+                                        if(node.children.length > 1) return false; // more than 1 child, stop already!
+                                        return _hasSingleChild(node.children[0]);
+                                    }
+                                    if(!_hasSingleChild(_node.id)) {
+                                        toastr.error('Single linear child tree structure needed under selected node!');
+                                        return;
+                                    }
+
+                                    // get an array of line "data" of the child tree
+                                    function _getData(_id, _dataArray, _displayLabelArray) {
+                                        let node = StatTree.el.jstree(true).get_node(_id);
+                                        _dataArray.push(node.data);
+                                        _displayLabelArray.push(node.data.displayLabel);
+                                        if(node.children.length) {
+                                            _getData(node.children[0], _dataArray, _displayLabelArray);
+                                        }
+                                    }
+                                    let dataArray = [], displayLabelArray = [];
+                                    _getData(_node.children[0], dataArray, displayLabelArray);
+                                    let dataMap = {};
+                                    for (let i = 0; i < dataArray.length; i++) {
+                                        dataMap[dataArray[i].displayLabel] = JSON.parse(JSON.stringify(dataArray[i]));
+                                        delete dataMap[dataArray[i].displayLabel].dropPercent;
+                                        delete dataMap[dataArray[i].displayLabel].id;
+                                        delete dataMap[dataArray[i].displayLabel].lastRefreshCount;
+                                        delete dataMap[dataArray[i].displayLabel].treeOrderPositionIndex;
+                                        delete dataMap[dataArray[i].displayLabel].uid;
+                                    }
+
+                                    // get all permutations
+                                    let permutations = _permute(displayLabelArray);
+
+                                    // create child tree for each permutation
+                                    function _childTreeFromArray(_array, _index = 0) {
+                                        let children = [];
+                                        if(_index < _array.length - 1) {
+                                            children.push(_childTreeFromArray(_array, _index + 1));
+                                        }
+                                        return {
+                                            text: '<span class="stat-tree-anchor">' + _array[_index] + '</span><span class="ml-2 text-secondary line-count-label">(…)</span>',
+                                            state: {
+                                                opened: true,
+                                                disabled: false,
+                                                selected: false,
+                                            },
+                                            children: children,
+                                            data: {
+                                                    type: "stat_tree_line",
+                                                    displayLabel: _array[_index],
+                                                    columns: dataMap[_array[_index]].columns,
+                                                    clause: dataMap[_array[_index]].clause
+                                            },
+                                            a_attr: {
+                                                title: dataMap[_array[_index]].clause.clause_text
+                                            }
+                                        };
+                                    }
+
+                                    // clear current children
+                                    this.el.jstree(true).delete_node(_node.children[0]);
+
+                                    // create new child trees
+                                    for (let i = 0; i < permutations.length; i++) {
+                                        let subTree = _childTreeFromArray(permutations[i]);
+                                        this.el.jstree(true).create_node(_node.id, JSON.parse(JSON.stringify(subTree)));
+                                    }
+
+                                    this.setDirty();
+
+                                },
+
                                 pasteColumnsDeep: function(_node, _strColumns) {
                                     _node.data.columns = JSON.parse(_strColumns);
                                     for (let i = 0; i < _node.children.length; i++) {