Интерактивное дерево

Один из режимов компонента Таблица, позволяющих сделать навигацию по большому иерархическому дереву. 

Демо-стенд компонента

Настройка Дерева

Для вывода данных необходимо следующим образом настроить таблицу. 

1. В SELECT 1 вернуть таблицу следующего вида: 

declare   @result TABLE (id int, parentID int, name nvarchar(256), data nvarchar(max))

data - дополнительные данные по объекту, передающиеся в виде JSON строки (кавычки для параметров обязательны). Если не используется - передаем пустую строку.

parentID - ссылка на родителя элемента. По этому полю строится иерархия элементов (на стороне браузера). 

2. В SELECT 3 указываем ViewMode='dynamicTree' и настройки плагина.

select 'dynamicTree' ViewType,
    	'{ "levelDistance": 100, "setCurrentAsRoot": false, "orientation": "top",
        "contHeight":"400px",
        "itemFormCode": "tst-dynTreeItem",
        "itemFormContainer": ".itemFormDetails"
        }' dynamicTreeOptions 

 в dynamicTreeOptions передаются как системные настройки плагина jit, так и дополнительные настройки: 

  • setCurrentAsRoot - если true, то при клике на элемент диаграмма будет преобразовываться (корневым элементом становится текущий выбранный). 
  • orientation - left, right, top, bottom - "куда" будет расти дерево. 
  • contHeight - можно установить высоту контейнера. По умолчанию контейнер имеет высоту 500px (при ширине 100%). 
  • itemFormCode, itemFormContaiter - если эти параметры установлены, то при клике на элемент, в контейнер с селектором itemFormContaiter будет добавляться форма с кодом itemFormCode, которой в качестве data-itemID будет передаваться id текущего элемента. 

По умолчанию системные настройки плагина (которые можно подменить на свои в dynamicTreeOptions) выглядят следующим образом: 

var defaultOptions = {
                //id of viz container element
                injectInto: contID,
                //set duration for the animation
                duration: 800,
                //SET THE TREE TO VERTICAL
                orientation: "left",
                //set animation transition type
                transition: $jit.Trans.Quart.easeInOut,
                //set distance between node and its children
                levelDistance: 50,
                //enable panning
                Navigation: {
                    enable: true,
                    panning: true
                },
                //set node and edge styles
                //set overridable=true for styling individual
                //nodes or edges
                Node: {
                    height: 25,
                    width: 60,
                    type: 'rectangle',
                    color: '#aaa',
                    overridable: true
                },

                Edge: {
                    type: 'bezier',
                    overridable: true
                },

                onBeforeCompute: function (node) {
                    as.vis.log("loading " + node.name);
                },

                onAfterCompute: function () {
                    as.vis.log("done");
                },

                //This method is called on DOM label creation.
                //Use this method to add event handlers and styles to
                //your node.
                onCreateLabel: function (label, node) {
                    label.id = node.id;
                    label.innerHTML = node.name;
                    label.onclick = function () {
                        if (options.setCurrentAsRoot) {
                            st.setRoot(node.id, 'animate');
                        } else {
                            st.onClick(node.id);
                        }
                        if (options.itemFormCode && options.itemFormContainer) {
                            var cont = $(options.itemFormContainer);
                            if (cont.length) {
                                var s = "
";
                                cont.html(s);
                                as.initControls(cont);
                            }
                        }

                    };
                    //set label styles
                    var style = label.style;
                    style.width = 60 + 'px';
                    style.height = 17 + 'px';
                    style.cursor = 'pointer';
                    style.color = '#333';
                    style.fontSize = '0.8em';
                    style.textAlign = 'center';
                    style.paddingTop = '3px';
                },

                //This method is called right before plotting
                //a node. It's useful for changing an individual node
                //style properties before plotting it.
                //The data properties prefixed with a dollar
                //sign will override the global node style properties.
                onBeforePlotNode: function (node) {
                    //add some color to the nodes in the path between the
                    //root node and the selected node.
                    if (node.selected) {
                        node.data.$color = "#ff7";
                    }
                    else {
                        delete node.data.$color;
                        //if the node belongs to the last plotted level
                        if (!node.anySubnode("exist")) {
                            //count children number
                            var count = 0;
                            node.eachSubnode(function (n) { count++; });
                            //assign a node color based on
                            //how many children it has
                            node.data.$color = ['#aaa', '#baa', '#caa', '#daa', '#eaa', '#faa'][count];
                        }
                    }
                },

                //This method is called right before plotting
                //an edge. It's useful for changing an individual edge
                //style properties before plotting it.
                //Edge data proprties prefixed with a dollar sign will
                //override the Edge global style properties.
                onBeforePlotLine: function (adj) {
                    if (adj.nodeFrom.selected && adj.nodeTo.selected) {
                        adj.data.$color = "#eed";
                        adj.data.$lineWidth = 3;
                    }
                    else {
                        delete adj.data.$color;
                        delete adj.data.$lineWidth;
                    }
                }
            };

Вопросы по Дереву

Как сделать добавление элемента?

Через отдельную форму, после которой сделать refreshContainer с нашим деревом. 

Как удалить элемент? 

Можно реализовать дополнительную кнопку в itemForm для удаления данного элемента с последующим обновлением дерева через refreshContainer.

Примечание