<\/div>';return dendrogram.sprint(input,label,column,value,'type=disabled');default:return dendrogram.sprint(dendrogram.form.formContentTemplate.input,label,column,value,attribute);}}},addForm:function(){dendrogram.form.conserve_action='add';document.getElementById('dendrogram-form-theme').innerText='增添节点';var delete_buttun=document.getElementsByClassName('dendrogram-form-delete');if(delete_buttun[0]instanceof HTMLElement){delete_buttun[0].setAttribute('style','display:none;');}dendrogram.form.initFormContent(this.parentNode.getAttribute('data-v'),true);dendrogram.form.nodeElement=this.parentNode;dendrogram.form.mongolia(true);},upForm:function(){dendrogram.form.conserve_action='update';document.getElementById('dendrogram-form-theme').innerText='修改节点';var delete_buttun=document.getElementsByClassName('dendrogram-form-delete');if(delete_buttun[0]instanceof HTMLElement){delete_buttun[0].setAttribute('style','display:inline-block;');}dendrogram.form.initFormContent(this.parentNode.getAttribute('data-v'));dendrogram.form.nodeElement=this.parentNode;dendrogram.form.mongolia(true);},conserve:function(){if(dendrogram.form.conserve_action==='add'){var data={'p_id':dendrogram.form.id};}else{var data={'id':dendrogram.form.id};}data=insert_input_data(document.getElementsByClassName('dendrogram-input'),data);data=insert_input_data(document.getElementsByClassName('dendrogram-textarea'),data);data=insert_select_data(document.getElementsByClassName('dendrogram-radio'),data);data=insert_select_data(document.getElementsByClassName('dendrogram-checkbox'),data);dendrogram.requestEvent(dendrogram.form.form_action,data);function insert_input_data(elements,data){for(var element in elements){if(elements[element]instanceof HTMLElement){var name=elements[element].name;var val=elements[element].value;data[name]=val;}}return data;}function insert_select_data(elements,data){for(var element in elements){if(elements[element]instanceof HTMLElement){var name=elements[element].name;var options=document.getElementsByName(name);if(elements[element].className=='dendrogram-radio'){for(var k in options){if(options[k].checked){data[name]=options[k].value;break;}}continue;}var check_box=[];for(var k in options){if(options[k].checked){check_box.push(options[k].value);}}data[name]=check_box;}}return data;}},delete:function(){dendrogram.form.conserve_action='delete';dendrogram.requestEvent(dendrogram.form.form_action,{id:dendrogram.form.id})},}};if(typeof define==='function'&&define.amd){define(dendrogram);}else{window.dendrogram=dendrogram;}})(window);
2 |
--------------------------------------------------------------------------------
/src/Static/dendrogramUnlimitedSelect.css:
--------------------------------------------------------------------------------
1 | #dendrogram-unlimited-select{position:relative;display:flex;align-items:flex-start;flex-wrap:nowrap}.dendrogram-select-button{background-color:transparent;color:#222;border:1px solid #e5e5e5;margin:0;font:inherit;text-transform:none;-webkit-appearance:none;border-radius:0;display:inline-block;box-sizing:border-box;padding:0 30px 0 15px;vertical-align:middle;font-size:14px;line-height:38px;text-align:center;text-decoration:none;transition:.1s ease-in-out;transition-property:color,background-color,border-color;width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;position:relative;cursor:pointer}.dendrogram-select-button:hover,.dendrogram-select-button:focus{background-color:transparent;color:#222;border-color:#b2b2b2}.dendrogram-select-button:active{background-color:transparent;color:#222;border-color:#999}.dendrogram-select-dropdown{display:none;position:absolute;z-index:1020;box-sizing:border-box;padding:12px;background:#fff;color:#666;box-shadow:0 5px 12px rgba(0,0,0,.15);width:150px;animation-name:dendrogram-fade-show-select;animation-duration:.2s;animation-direction:reverse;animation-timing-function:ease-in}.dendrogram-select-dropdown ul{white-space:nowrap;margin:0;padding:0;list-style:none}.dendrogram-select-dropdown ul>li{font-size:13px;color:#999;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:center;margin-top:10px;cursor:pointer}.dendrogram-select-dropdown ul>li:first-child{margin-top:0}.dendrogram-select-dropdown ul>li:hover{color:#666}.dendrogram-select-dropdown ul>li:active{color:#333}.dendrogram-select-dropdown ul>li:after{content:" ";display:block;margin-top:7px;border-bottom:1px solid #efefef;transition:.3s ease-in-out}.dendrogram-select-dropdown ul>li:hover:after{content:" ";display:block;margin-top:7px;border-bottom:1px solid #d2d0d0;transition:.3s ease-in-out}.dendrogram-select-dropdown ul>li:last-child:after{display:none}@keyframes dendrogram-fade-show-select{0%{opacity:1;transform:translateY(0)}100%{opacity:0;transform:translateY(-10px)}}
2 |
--------------------------------------------------------------------------------
/src/Static/dendrogramUnlimitedSelect.js:
--------------------------------------------------------------------------------
1 | !function(e){"use strict";var t={label:"%s",value:"%s",tag:'
',default:JSON.parse("%s"),storage:function(){for(var e=document.getElementById("dendrogram-unlimited-select"),t=[],n=0;n
"+e.children[0][t.label]+"<\/span>"+t.tag,l.setAttribute("data-value",e.children[0][t.value]);var d=0;t.default.length>0&&e.children.forEach(function(e,n){var a=t.default.indexOf(e.id);if(-1!==a)return l.innerHTML=""+e[t.label]+"<\/span>"+t.tag,l.setAttribute("data-value",e[t.value]),t.default.splice(a,1),void(d=n)}),i.appendChild(l);var r=document.createElement("div");r.className="dendrogram-select-dropdown",r.appendChild(a),i.addEventListener("click",function(){r.style.setProperty("display","block")}),i.addEventListener("mouseleave",function(){r.style.setProperty("display","none")}),i.appendChild(r),n.appendChild(i),e.children[d].children.length>0&&t.create(e.children[d])}}},makeDropDown:function(e){if(e.length<=0)return!1;var n=document.createElement("ul");return e.forEach(function(e){var a=document.createElement("li");a.innerText=e[t.label],a.setAttribute("data-option",e[t.value]),e.children.length<=0?a.addEventListener("click",function(){i(this),t.callback()}):a.addEventListener("click",function(){i(this),t.create(e),t.callback()});var i=function(n){var i=n.getAttribute("data-option"),l=a.parentNode.parentNode.parentNode.firstChild;l.firstChild.textContent=e[t.label],l.valueOf().setAttribute("data-value",i);do{var d=l.parentNode.nextSibling;if(!d)break;var r=d.nextSibling;l.parentNode.parentNode.removeChild(l.parentNode.nextSibling)}while(r)};n.appendChild(a)}),n}};"function"==typeof define&&define.amd?define(t):e.dendrogramUS=t}(window);
2 |
--------------------------------------------------------------------------------
/src/ViewModel/AdjacencyListHorizontalViewModel.php:
--------------------------------------------------------------------------------
1 | %s
18 | EOF;
19 |
20 | private $branch = <<%s
22 | EOF;
23 |
24 | private $leaf = <<
26 |
37 | %s
38 |
39 | EOF;
40 |
41 | private $leaf_apex = <<
43 |
54 | %s
55 |
56 | EOF;
57 |
58 | public function __construct($column)
59 | {
60 | parent::__construct($column);
61 | }
62 |
63 | public function index($data)
64 | {
65 | if($this->sign){
66 | $this->branch = Func::firstSprintf($this->branch,'block');
67 | }else{
68 | $this->branch = Func::firstSprintf($this->branch,'none');
69 | }
70 | $this->makeTree($data, $tree);
71 | $this->tree_view.=$this->form;
72 | return $this->tree_view;
73 | }
74 |
75 | /**
76 | * @param array $array
77 | * @param $tree
78 | */
79 | private function makeTree(&$array, &$tree)
80 | {
81 | if (empty($array)) {
82 | return;
83 | }
84 |
85 | $left_button = $this->sign ? $this->icon['shrink'] : $this->icon['expand'];
86 |
87 | if (empty($tree)) {
88 | $item = array_shift($array);
89 | $tree[$item['id']] = [];
90 | if (empty($array)) {
91 | //无子节点
92 | $this->tree_view = sprintf($this->root, sprintf($this->leaf_apex, json_encode($item),$this->icon['ban'], $this->makeColumn($item),$this->icon['grow'], ''));
93 | return;
94 | } else {
95 | $this->tree_view = sprintf($this->root, sprintf($this->leaf, json_encode($item),(int)$this->sign,$left_button, $this->makeColumn($item),$this->icon['grow'], $this->branch));
96 | }
97 | }
98 |
99 | foreach ($tree as $branch => &$leaves) {
100 | $shoot = [];
101 | foreach ($array as $key => $value) {
102 | if ($value['p_id'] == $branch) {
103 | $leaves[$value['id']] = [];
104 | unset($array[$key]);
105 | if (Func::quadraticArrayGetIndex($array, ['p_id' => $value['id']]) === false) {
106 | //无子节点
107 | $shoot[] = $this->makeBranch($value, false);
108 | } else {
109 | $shoot[] = $this->makeBranch($value);
110 | }
111 | }
112 | }
113 |
114 | if (!empty($leaves) && $array) {
115 | $this->tree_view = Func::firstSprintf($this->tree_view, join('', $shoot));
116 | $this->makeTree($array, $leaves);
117 | } elseif (!empty($leaves)) {
118 | $this->tree_view = Func::firstSprintf($this->tree_view, join('', $shoot));
119 | }
120 | }
121 | }
122 |
123 | private function makeColumn($data)
124 | {
125 | $text = '%s
';
126 | $html = '';
127 | foreach ($this->column as $column){
128 | $html.=sprintf($text,isset($data[$column])?$data[$column]:'');
129 | }
130 |
131 | return $html;
132 | }
133 |
134 | /**
135 | * 枝
136 | * @param $data
137 | * @param bool $node
138 | * @return string
139 | */
140 | private function makeBranch($data, $node = true)
141 | {
142 | if ($node) {
143 | $left_button = $this->sign ? $this->icon['shrink'] : $this->icon['expand'];
144 | return sprintf($this->leaf, json_encode($data),$this->sign,$left_button, $this->makeColumn($data),$this->icon['grow'], $this->branch);
145 | }
146 | return sprintf($this->leaf_apex, json_encode($data),$this->icon['ban'], $this->makeColumn($data),$this->icon['grow'], '');
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/src/ViewModel/AdjacencyListVerticalViewModel.php:
--------------------------------------------------------------------------------
1 | %s
18 | EOF;
19 |
20 | private $branch = <<%s
22 | EOF;
23 |
24 | private $leaf = <<
26 |
37 | %s
38 |
39 | EOF;
40 |
41 | private $leaf_apex = <<
43 |
54 |
55 | EOF;
56 |
57 | public function __construct($column)
58 | {
59 | parent::__construct($column);
60 | }
61 |
62 | public function index($data)
63 | {
64 | if($this->sign){
65 | $this->branch = Func::firstSprintf($this->branch,'block');
66 | }else{
67 | $this->branch = Func::firstSprintf($this->branch,'none');
68 | }
69 | $this->makeTree($data,$tree);
70 | $this->tree_view.=$this->form;
71 | return $this->tree_view;
72 | }
73 |
74 | /**
75 | * @param $array
76 | * @param array $tree
77 | */
78 | private function makeTree(&$array, &$tree = [])
79 | {
80 | if(empty($array)){
81 | return;
82 | }
83 |
84 | if (empty($tree)) {
85 | $item = array_shift($array);
86 | $tree[$item['id']] = [];
87 | if (empty($array)) {
88 | //no children
89 | $this->tree_view = sprintf($this->root,
90 | sprintf($this->leaf_apex,json_encode($item),$this->icon['ban'],$this->makeColumn($item),$this->icon['grow'],''));
91 | return;
92 | } else {
93 | $this->tree_view = sprintf($this->root,
94 | sprintf($this->leaf,json_encode($item),(int)$this->sign,$this->icon['shrink'],$this->makeColumn($item),$this->icon['grow'],$this->branch));
95 | }
96 | }
97 |
98 | foreach ($tree as $branch => &$leaves) {
99 | $shoot = [];
100 | foreach ($array as $key => $value) {
101 | if ($value['p_id'] == $branch) {
102 | $leaves[$value['id']] = [];
103 | unset($array[$key]);
104 | if (Func::quadraticArrayGetIndex($array, ['p_id' => $value['id']]) === false) {
105 | //无子节点
106 | $shoot[] = $this->makeBranch($value, false);
107 | } else {
108 | $shoot[] = $this->makeBranch($value);
109 | }
110 | }
111 | }
112 |
113 | if (!empty($leaves) && $array) {
114 | $this->tree_view = Func::firstSprintf($this->tree_view, join('', $shoot));
115 | $this->makeTree($array, $leaves);
116 | } elseif (!empty($leaves)) {
117 | $this->tree_view = Func::firstSprintf($this->tree_view, join('', $shoot));
118 | }
119 | }
120 | }
121 |
122 | private function makeColumn($data)
123 | {
124 | $text = '%s
';
125 | $html = '';
126 | foreach ($this->column as $column){
127 | $html.=sprintf($text,isset($data[$column])?$data[$column]:'');
128 | }
129 | return $html;
130 | }
131 |
132 | /**
133 | * 枝
134 | * @param $data
135 | * @param bool $node
136 | * @return string
137 | */
138 | private function makeBranch($data, $node = true)
139 | {
140 | if ($node) {
141 | $left_button = $this->sign ? $this->icon['shrink'] : $this->icon['expand'];
142 | return sprintf($this->leaf, json_encode($data),$this->sign,$left_button, $this->makeColumn($data),$this->icon['grow'], $this->branch);
143 | }
144 | return sprintf($this->leaf_apex, json_encode($data),$this->icon['ban'], $this->makeColumn($data),$this->icon['grow'], '');
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/src/ViewModel/NestedSetHorizontalViewModel.php:
--------------------------------------------------------------------------------
1 | %s
18 | EOF;
19 |
20 | private $branch = <<%s
22 | EOF;
23 |
24 | private $leaf = <<
26 |
37 | %s
38 |
39 | EOF;
40 |
41 | private $leaf_apex = <<
43 |
54 | %s
55 |
56 | EOF;
57 |
58 | public function __construct($column)
59 | {
60 | parent::__construct($column);
61 | }
62 |
63 | public function index($data)
64 | {
65 | if($this->sign){
66 | $this->branch = Func::firstSprintf($this->branch,'block');
67 | }else{
68 | $this->branch = Func::firstSprintf($this->branch,'none');
69 | }
70 | $this->makeTree($data, $tree);
71 | $this->tree_view.=$this->form;
72 | return $this->tree_view;
73 | }
74 |
75 | /**
76 | * @param array $array
77 | * @param $tree
78 | */
79 | private function makeTree(&$array, &$tree)
80 | {
81 | if (empty($array)) {
82 | return;
83 | }
84 |
85 | $left_button = $this->sign ? $this->icon['shrink'] : $this->icon['expand'];
86 |
87 | if (empty($tree)) {
88 | $item = array_shift($array);
89 | $item['children'] = [];
90 | $tree[] = $item;
91 | if (empty($array)) {
92 | //无子节点
93 | $this->tree_view = sprintf($this->root, sprintf($this->leaf_apex, json_encode($item),$this->icon['ban'], $this->makeColumn($item),$this->icon['grow'], ''));
94 | return;
95 | } else {
96 | $this->tree_view = sprintf($this->root, sprintf($this->leaf, json_encode($item),(int)$this->sign,$left_button, $this->makeColumn($item),$this->icon['grow'], $this->branch));
97 | }
98 | }
99 |
100 | foreach ($tree as &$branch) {
101 | $shoot = [];
102 | foreach ($array as $key => $value) {
103 | if (($branch['layer'] + 1) == $value['layer'] && $branch['left'] < $value['left'] && $branch['right'] > $value['left']) {
104 | $value['children'] = [];
105 | $branch['children'][] = $value;
106 | unset($array[$key]);
107 | if (!$this->hasChildren($value,$array)) {
108 | //无子节点
109 | $shoot[] = $this->makeBranch($value, false);
110 | } else {
111 | $shoot[] = $this->makeBranch($value);
112 | }
113 | }
114 | }
115 |
116 | if (!empty($branch['children']) && $array) {
117 | $this->tree_view = Func::firstSprintf($this->tree_view, join('', $shoot));
118 | $this->makeTree($array, $branch['children']);
119 | } elseif (!empty($branch['children'])) {
120 | $this->tree_view = Func::firstSprintf($this->tree_view, join('', $shoot));
121 | }
122 | }
123 | }
124 |
125 | private function hasChildren($item,$data)
126 | {
127 | foreach ($data as $key => $value) {
128 | if(($item['layer'] + 1) == $value['layer'] && $item['left'] < $value['left'] && $item['right'] > $value['right']){
129 | return true;
130 | }
131 | }
132 | return false;
133 | }
134 |
135 | private function makeColumn($data)
136 | {
137 | $text = '%s
';
138 | $html = '';
139 | foreach ($this->column as $column){
140 | $html.=sprintf($text,isset($data[$column])?$data[$column]:'');
141 | }
142 |
143 | return $html;
144 | }
145 |
146 | /**
147 | * 枝
148 | * @param $data
149 | * @param bool $node
150 | * @return string
151 | */
152 | private function makeBranch($data, $node = true)
153 | {
154 | if ($node) {
155 | $left_button = $this->sign ? $this->icon['shrink'] : $this->icon['expand'];
156 | return sprintf($this->leaf, json_encode($data),$this->sign,$left_button, $this->makeColumn($data),$this->icon['grow'], $this->branch);
157 | }
158 | return sprintf($this->leaf_apex, json_encode($data),$this->icon['ban'], $this->makeColumn($data),$this->icon['grow'], '');
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/src/ViewModel/NestedSetVerticalViewModel.php:
--------------------------------------------------------------------------------
1 | %s
17 | EOF;
18 |
19 | private $branch = <<%s
21 | EOF;
22 |
23 | private $leaf = <<
25 |
36 | %s
37 |
38 | EOF;
39 |
40 | private $leaf_apex = <<
42 |
53 |
54 | EOF;
55 |
56 | public function __construct($column)
57 | {
58 | parent::__construct($column);
59 | }
60 |
61 | public function index($data)
62 | {
63 | if($this->sign){
64 | $this->branch = Func::firstSprintf($this->branch,'block');
65 | }else{
66 | $this->branch = Func::firstSprintf($this->branch,'none');
67 | }
68 | $this->makeTree($data,$tree);
69 | $this->tree_view.=$this->form;
70 | return $this->tree_view;
71 | }
72 |
73 | /**
74 | * @param $array
75 | * @param array $tree
76 | */
77 | private function makeTree(&$array, &$tree = [])
78 | {
79 | if(empty($array)){
80 | return;
81 | }
82 |
83 | if (empty($tree)) {
84 | $item = array_shift($array);
85 | $item['children'] = [];
86 | $tree[] = $item;
87 | if (empty($array)) {
88 | //no children
89 | $this->tree_view = sprintf($this->root,
90 | sprintf($this->leaf_apex,json_encode($item),$this->icon['ban'],$this->makeColumn($item),$this->icon['grow'],''));
91 | return;
92 | } else {
93 | $left_button = $this->sign ? $this->icon['shrink'] : $this->icon['expand'];
94 | $this->tree_view = sprintf($this->root,
95 | sprintf($this->leaf,json_encode($item),(int)$this->sign,$left_button,$this->makeColumn($item),$this->icon['grow'],$this->branch));
96 | }
97 | }
98 |
99 | foreach ($tree as &$branch) {
100 | $shoot = [];
101 | foreach ($array as $key => $value) {
102 | if (($branch['layer'] + 1) == $value['layer'] && $branch['left'] < $value['left'] && $branch['right'] > $value['left']) {
103 | $value['children'] = [];
104 | $branch['children'][] = $value;
105 | unset($array[$key]);
106 | if (!$this->hasChildren($value,$array)) {
107 | //无子节点
108 | $shoot[] = $this->makeBranch($value, false);
109 | } else {
110 | $shoot[] = $this->makeBranch($value);
111 | }
112 | }
113 | }
114 |
115 | if (!empty($branch['children']) && $array) {
116 | $this->tree_view = Func::firstSprintf($this->tree_view, join('', $shoot));
117 | $this->makeTree($array, $branch['children']);
118 | } elseif (!empty($branch['children'])) {
119 | $this->tree_view = Func::firstSprintf($this->tree_view, join('', $shoot));
120 | }
121 | }
122 | }
123 |
124 | private function hasChildren($item,$data)
125 | {
126 | foreach ($data as $key => $value) {
127 | if(($item['layer'] + 1) == $value['layer'] && $item['left'] < $value['left'] && $item['right'] > $value['right']){
128 | return true;
129 | }
130 | }
131 | return false;
132 | }
133 |
134 | private function makeColumn($data)
135 | {
136 | $text = '%s
';
137 | $html = '';
138 | foreach ($this->column as $column){
139 | $html.=sprintf($text,isset($data[$column])?$data[$column]:'');
140 | }
141 | return $html;
142 | }
143 |
144 | /**
145 | * 枝
146 | * @param $data
147 | * @param bool $node
148 | * @return string
149 | */
150 | private function makeBranch($data, $node = true)
151 | {
152 | if ($node) {
153 | $left_button = $this->sign ? $this->icon['shrink'] : $this->icon['expand'];
154 | return sprintf($this->leaf, json_encode($data),$this->sign,$left_button, $this->makeColumn($data),$this->icon['grow'], $this->branch);
155 | }
156 | return sprintf($this->leaf_apex, json_encode($data),$this->icon['ban'], $this->makeColumn($data),$this->icon['grow'], '');
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/ViewModel/ViewModel.php:
--------------------------------------------------------------------------------
1 |
20 |
23 |
26 |
27 |
28 |
32 |
33 | EOF;
34 |
35 | protected $icon = [
36 | 'expand'=>'