orgchart 4.0.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -11
- package/README.zh-cn.md +68 -4
- package/README.zh-tw.md +68 -4
- package/demo/export-chart-with-pictures.html +2 -1
- package/demo/family-tree.html +97 -0
- package/demo/index.html +2 -2
- package/demo/nodes-of-different-widths.html +4 -3
- package/demo/option-createNode.html +3 -3
- package/dist/css/jquery.orgchart.css +113 -44
- package/dist/css/jquery.orgchart.min.css +1 -1
- package/dist/js/jquery.orgchart.js +106 -45
- package/dist/js/jquery.orgchart.min.js +2 -2
- package/dist/js/jquery.orgchart.min.js.map +1 -1
- package/package.json +3 -3
- package/src/css/jquery.orgchart.css +113 -44
- package/src/js/jquery.orgchart.js +106 -45
- package/demo/multiple-layers.html +0 -128
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orgchart",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "Simple and direct organization chart(tree-like hierarchy) plugin based on pure DOM and jQuery.",
|
|
5
5
|
"main": "./dist/js/jquery.orgchart.min.js",
|
|
6
6
|
"style": [
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
"jspdf": "^2.5.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"browser-sync": "^
|
|
47
|
+
"browser-sync": "^3.0.2",
|
|
48
48
|
"chai": "^4.2.0",
|
|
49
49
|
"cypress": "^13.2.0",
|
|
50
50
|
"del": "^3.0.0",
|
|
51
|
-
"gulp": "^
|
|
51
|
+
"gulp": "^5.0.0",
|
|
52
52
|
"gulp-clean-css": "^3.10.0",
|
|
53
53
|
"gulp-csslint": "^1.0.1",
|
|
54
54
|
"gulp-eslint": "^4.0.2",
|
|
@@ -83,6 +83,7 @@
|
|
|
83
83
|
list-style: none;
|
|
84
84
|
padding-left: 0;
|
|
85
85
|
margin: 0;
|
|
86
|
+
justify-content: center;
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
.orgchart .hierarchy {
|
|
@@ -100,6 +101,62 @@
|
|
|
100
101
|
box-sizing: border-box;
|
|
101
102
|
}
|
|
102
103
|
|
|
104
|
+
/* 本姓人与上一层父母的连线,借助伪元素::before实现 */
|
|
105
|
+
/* 处理同一层中特殊的首节点 */
|
|
106
|
+
.orgchart .couple:first-child:not(:only-child)::before {
|
|
107
|
+
width: calc(100% - 69px); /* half width of hierarchy - half width of node - node's padding - node's border width */
|
|
108
|
+
left: 69px;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* 处理同一层中特殊的末节点 */
|
|
112
|
+
.orgchart .couple:last-child:not(:only-child)::before {
|
|
113
|
+
width: calc(50% + 71px);
|
|
114
|
+
left: 0px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.orgchart .hierarchy.couple:only-child::before {
|
|
118
|
+
width: 142px; /* half of node's width + link's width */
|
|
119
|
+
left: calc(50% - 71px); /* half width of node - half of link width */
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* 在family tree中,一个夫妻组合里,本姓人只有一个,外姓人可能有多个 */
|
|
123
|
+
/* 我们通过水平的连线来表示他们存在婚姻关系,借助伪元素::after实现 */
|
|
124
|
+
.orgchart .hierarchy.spouse:not(.couple)::after {
|
|
125
|
+
content: "";
|
|
126
|
+
position: absolute;
|
|
127
|
+
border-top: 2px solid rgba(217, 83, 79, 0.8);
|
|
128
|
+
box-sizing: border-box;
|
|
129
|
+
z-index: 0;
|
|
130
|
+
top: 24px;
|
|
131
|
+
width: var(--ft-width);
|
|
132
|
+
left: var(--ft-left-offset);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* 一夫一妻情况下的连线 */
|
|
136
|
+
.orgchart .couple {
|
|
137
|
+
white-space: nowrap;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.orgchart .couple:has(> .nodes) > .node:first-child::after {
|
|
141
|
+
content: "";
|
|
142
|
+
position: absolute;
|
|
143
|
+
top: 24px;
|
|
144
|
+
left: calc(100% + 1px);
|
|
145
|
+
width: 2px;
|
|
146
|
+
height: 33px;
|
|
147
|
+
background-color: rgba(217, 83, 79, 0.8);
|
|
148
|
+
}
|
|
149
|
+
.orgchart .couple::after {
|
|
150
|
+
content: "";
|
|
151
|
+
position: absolute;
|
|
152
|
+
border-top: 2px solid rgba(217, 83, 79, 0.8);
|
|
153
|
+
box-sizing: border-box;
|
|
154
|
+
z-index: 0;
|
|
155
|
+
top: 24px;
|
|
156
|
+
width: 20px;
|
|
157
|
+
left: calc(50% - 10px); /* half of hierarchy - node's padding width - node's border with */
|
|
158
|
+
}
|
|
159
|
+
|
|
103
160
|
.orgchart .hierarchy:first-child::before,
|
|
104
161
|
.orgchart .hierarchy.isSiblingsCollapsed.left-sibs::before {
|
|
105
162
|
left: calc(50% - 1px);
|
|
@@ -111,7 +168,7 @@
|
|
|
111
168
|
width: calc(50% + 1px);
|
|
112
169
|
}
|
|
113
170
|
|
|
114
|
-
.orgchart .hierarchy:not(.hidden):only-child::before {
|
|
171
|
+
.orgchart .hierarchy:not(.hidden):not(.spouse):only-child::before {
|
|
115
172
|
width: 2px;
|
|
116
173
|
}
|
|
117
174
|
|
|
@@ -122,17 +179,17 @@
|
|
|
122
179
|
.orgchart .isSiblingsCollapsed.left-sibs:last-child:before,
|
|
123
180
|
.orgchart .isCollapsedSibling::before,
|
|
124
181
|
.orgchart .isCollapsedSibling .hierarchy::before,
|
|
125
|
-
.orgchart .isChildrenCollapsed > .node:
|
|
182
|
+
.orgchart .hierarchy.isChildrenCollapsed:not(.couple) > .node:has(+ .nodes)::after,
|
|
126
183
|
.orgchart .isCollapsedDescendant::before,
|
|
127
184
|
.orgchart .isCollapsedDescendant > .node::before,
|
|
128
185
|
.orgchart .isCollapsedDescendant > .node::after,
|
|
129
186
|
.orgchart .isAncestorsCollapsed:only-child::before,
|
|
130
|
-
.orgchart .isAncestorsCollapsed > .node::before {
|
|
187
|
+
.orgchart .isAncestorsCollapsed > .node:not(.outsider)::before {
|
|
131
188
|
content: none;
|
|
132
189
|
}
|
|
133
190
|
|
|
134
191
|
/* excluding leaf node */
|
|
135
|
-
.orgchart .
|
|
192
|
+
.orgchart .hierarchy:not(.couple) > .node:has(+ .nodes)::after {
|
|
136
193
|
content: "";
|
|
137
194
|
position: absolute;
|
|
138
195
|
bottom: -12px; /* -(background square size + node's border width) */
|
|
@@ -155,7 +212,7 @@
|
|
|
155
212
|
background-color: rgba(238, 217, 54, 0.5);
|
|
156
213
|
}
|
|
157
214
|
/* excluding root node */
|
|
158
|
-
.orgchart > ul > li > ul li > .node::before {
|
|
215
|
+
.orgchart > ul > li > ul li > .node:not(.outsider)::before {
|
|
159
216
|
content: "";
|
|
160
217
|
position: absolute;
|
|
161
218
|
top: var(--top, -12px); /* -(fallback value = background square size + border width of node) */
|
|
@@ -165,7 +222,17 @@
|
|
|
165
222
|
background-color: rgba(217, 83, 79, 0.8);
|
|
166
223
|
}
|
|
167
224
|
|
|
168
|
-
.orgchart > ul > li > ul li
|
|
225
|
+
.orgchart > ul > li > ul li > .node.outsider::before {
|
|
226
|
+
content: "";
|
|
227
|
+
position: absolute;
|
|
228
|
+
top: var(--top, -12px);
|
|
229
|
+
left: calc(50% - 1px);
|
|
230
|
+
width: 0;
|
|
231
|
+
height: var(--height, 10px);
|
|
232
|
+
border-right: 2px dotted rgba(217, 83, 79, 0.8);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.orgchart > ul > li > ul .isSiblingsCollapsed > .node::before {
|
|
169
236
|
top: var(--top-cross-point, -12px);
|
|
170
237
|
height: var(--height-cross-point, 10px);
|
|
171
238
|
}
|
|
@@ -179,6 +246,8 @@
|
|
|
179
246
|
padding: 3px;
|
|
180
247
|
border: 2px dashed transparent;
|
|
181
248
|
text-align: center;
|
|
249
|
+
transition: transform 0.3s, opacity 0.3s;
|
|
250
|
+
z-index: 1;
|
|
182
251
|
}
|
|
183
252
|
|
|
184
253
|
.orgchart.l2r .node, .orgchart.r2l .node {
|
|
@@ -190,7 +259,7 @@
|
|
|
190
259
|
background-color: rgba(238, 217, 54, 0.5);
|
|
191
260
|
transition: .5s;
|
|
192
261
|
cursor: default;
|
|
193
|
-
z-index:
|
|
262
|
+
z-index: 2;
|
|
194
263
|
}
|
|
195
264
|
|
|
196
265
|
.orgchart .node.focused {
|
|
@@ -420,10 +489,6 @@
|
|
|
420
489
|
padding: 0.5rem 1rem;
|
|
421
490
|
}
|
|
422
491
|
|
|
423
|
-
.orgchart .node {
|
|
424
|
-
transition: transform 0.3s, opacity 0.3s;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
492
|
.orgchart .slide-down {
|
|
428
493
|
opacity: 0;
|
|
429
494
|
transform: translateY(40px);
|
|
@@ -479,8 +544,8 @@
|
|
|
479
544
|
margin-bottom: 0;
|
|
480
545
|
}
|
|
481
546
|
|
|
482
|
-
.orgchart .nodes.vertical .node::before,
|
|
483
|
-
.orgchart .nodes.vertical .node::after {
|
|
547
|
+
.orgchart .nodes.vertical .hierarchy .node::before,
|
|
548
|
+
.orgchart .nodes.vertical .hierarchy .node::after {
|
|
484
549
|
content: none;
|
|
485
550
|
}
|
|
486
551
|
|
|
@@ -500,6 +565,10 @@
|
|
|
500
565
|
border-width: 0 0 2px 2px;
|
|
501
566
|
}
|
|
502
567
|
|
|
568
|
+
.orgchart .nodes.vertical .hierarchy:only-child::before {
|
|
569
|
+
width: 11px;
|
|
570
|
+
}
|
|
571
|
+
|
|
503
572
|
.orgchart .nodes.vertical .hierarchy::before {
|
|
504
573
|
top: 0px;
|
|
505
574
|
height: 26px; /* node top half's height(25px) + half width of line */
|
|
@@ -535,15 +604,36 @@
|
|
|
535
604
|
}
|
|
536
605
|
|
|
537
606
|
/* styles for compact nodes */
|
|
538
|
-
.orgchart .
|
|
607
|
+
.orgchart .node.compact {
|
|
539
608
|
position: static;
|
|
540
609
|
display: grid;
|
|
541
610
|
width: 140px;
|
|
542
611
|
height: 50px;
|
|
543
|
-
overflow: hidden;
|
|
544
612
|
background-color: #eee;
|
|
545
613
|
}
|
|
546
614
|
|
|
615
|
+
.orgchart .node.compact.looseMode {
|
|
616
|
+
display: grid;
|
|
617
|
+
width: unset;
|
|
618
|
+
height: unset;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
.orgchart .node.compact > .node {
|
|
622
|
+
display: none;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
.orgchart .node.compact.looseMode > .node {
|
|
626
|
+
display: inline-block;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
.orgchart .node.compact > .node.compact {
|
|
630
|
+
position: relative;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
.orgchart .node.compact > .node.compact.looseMode {
|
|
634
|
+
display: grid;
|
|
635
|
+
}
|
|
636
|
+
|
|
547
637
|
.orgchart .node.compact.even,
|
|
548
638
|
.orgchart .node.compact.even:hover {
|
|
549
639
|
background-color: #eee;
|
|
@@ -566,43 +656,22 @@
|
|
|
566
656
|
background-color: #eee;
|
|
567
657
|
}
|
|
568
658
|
|
|
569
|
-
.orgchart .
|
|
570
|
-
display: grid;
|
|
571
|
-
width: unset;
|
|
572
|
-
height: unset;
|
|
573
|
-
overflow: unset;
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
.orgchart .hierarchy > .node.compact::before {
|
|
659
|
+
.orgchart .node.compact::before {
|
|
577
660
|
top: var(--top-cross-point, -10px);
|
|
578
661
|
}
|
|
579
662
|
|
|
580
|
-
.orgchart .node.compact > .
|
|
581
|
-
position: relative;
|
|
582
|
-
display: grid;
|
|
583
|
-
width: 140px;
|
|
584
|
-
height: 50px;
|
|
585
|
-
overflow: hidden;
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
.orgchart .node.compact .node.compact.looseMode {
|
|
589
|
-
width: unset;
|
|
590
|
-
height: unset;
|
|
591
|
-
overflow: unset;
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
.orgchart .hierarchy > .node.compact > .content {
|
|
663
|
+
.orgchart .node.compact > .content {
|
|
595
664
|
position: absolute;
|
|
596
665
|
top: 25px;
|
|
597
666
|
left: 5px;
|
|
598
667
|
}
|
|
599
668
|
|
|
600
|
-
.orgchart .
|
|
669
|
+
.orgchart .node.compact.looseMode > .title {
|
|
601
670
|
margin-top: 5px;
|
|
602
671
|
margin-left: 5px;
|
|
603
672
|
}
|
|
604
673
|
|
|
605
|
-
.orgchart .
|
|
674
|
+
.orgchart .node.compact.looseMode > .content {
|
|
606
675
|
top: 30px;
|
|
607
676
|
left: 10px;
|
|
608
677
|
}
|
|
@@ -627,7 +696,7 @@
|
|
|
627
696
|
margin-bottom: 0;
|
|
628
697
|
}
|
|
629
698
|
|
|
630
|
-
.orgchart .node.compact .node:
|
|
699
|
+
.orgchart .node.compact .node:has(+ .nodes)::after {
|
|
631
700
|
content: unset;
|
|
632
701
|
}
|
|
633
702
|
|
|
@@ -635,13 +704,13 @@
|
|
|
635
704
|
cursor: pointer;
|
|
636
705
|
}
|
|
637
706
|
|
|
638
|
-
.orgchart .
|
|
707
|
+
.orgchart .node.compact > .backToCompactSymbol {
|
|
639
708
|
position: absolute;
|
|
640
709
|
top: 5px;
|
|
641
710
|
left: 5px;
|
|
642
711
|
}
|
|
643
712
|
|
|
644
|
-
.orgchart .
|
|
713
|
+
.orgchart .node.compact.looseMode > .backToCompactSymbol {
|
|
645
714
|
top: 10px;
|
|
646
715
|
left: 10px;
|
|
647
716
|
}
|
|
@@ -657,7 +726,7 @@
|
|
|
657
726
|
left: 3px;
|
|
658
727
|
}
|
|
659
728
|
|
|
660
|
-
.orgchart .
|
|
729
|
+
.orgchart .node.compact > .backToLooseSymbol {
|
|
661
730
|
position: absolute;
|
|
662
731
|
top: 25px;
|
|
663
732
|
right: 5px;
|
|
@@ -75,7 +75,8 @@
|
|
|
75
75
|
if (typeof MutationObserver !== 'undefined') {
|
|
76
76
|
this.triggerInitEvent();
|
|
77
77
|
}
|
|
78
|
-
var $root = $chart.append($('<ul class="nodes"
|
|
78
|
+
var $root = Array.isArray(data) ? $chart.append($('<ul class="nodes"></ul>')).find('.nodes')
|
|
79
|
+
: $chart.append($('<ul class="nodes"><li class="hierarchy"></li></ul>')).find('.hierarchy');
|
|
79
80
|
|
|
80
81
|
if (data instanceof $) { // ul datasource
|
|
81
82
|
this.buildHierarchy($root, this.buildJsonDS(data.children()), 0, this.options);
|
|
@@ -83,7 +84,7 @@
|
|
|
83
84
|
if (data.relationship) {
|
|
84
85
|
this.buildHierarchy($root, data);
|
|
85
86
|
} else {
|
|
86
|
-
this.buildHierarchy($root, this.attachRel(data, '00'));
|
|
87
|
+
this.buildHierarchy($root, Array.isArray(data) ? data : this.attachRel(data, '00'));
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
|
|
@@ -567,6 +568,9 @@
|
|
|
567
568
|
isVisibleNode: function (index, elem) {
|
|
568
569
|
return this.getNodeState($(elem)).visible;
|
|
569
570
|
},
|
|
571
|
+
isCompactDescendant: function (index, elem) {
|
|
572
|
+
return $(elem).parent().is('.node.compact');
|
|
573
|
+
},
|
|
570
574
|
// do some necessary cleanup tasks when hide animation is finished
|
|
571
575
|
hideChildrenEnd: function (event) {
|
|
572
576
|
var $node = event.data.node;
|
|
@@ -581,7 +585,7 @@
|
|
|
581
585
|
$node.closest('.hierarchy').addClass('isChildrenCollapsed');
|
|
582
586
|
var $lowerLevel = $node.siblings('.nodes');
|
|
583
587
|
this.stopAjax($lowerLevel);
|
|
584
|
-
var $animatedNodes = $lowerLevel.find('.node').filter(this.isVisibleNode.bind(this));
|
|
588
|
+
var $animatedNodes = $lowerLevel.find('.node').filter(this.isVisibleNode.bind(this)).not(this.isCompactDescendant.bind(this));
|
|
585
589
|
var isVerticalDesc = $lowerLevel.is('.vertical');
|
|
586
590
|
if (!isVerticalDesc) {
|
|
587
591
|
$animatedNodes.closest('.hierarchy').addClass('isCollapsedDescendant');
|
|
@@ -746,6 +750,7 @@
|
|
|
746
750
|
},
|
|
747
751
|
// whether the cursor is hovering over the node
|
|
748
752
|
isInAction: function ($node) {
|
|
753
|
+
// TODO: 展开/折叠的按钮不止4个箭头,还有toggleBtn
|
|
749
754
|
return [
|
|
750
755
|
this.options.icons.expandToUp,
|
|
751
756
|
this.options.icons.collapseToDown,
|
|
@@ -937,8 +942,11 @@
|
|
|
937
942
|
// show the compact node's children in the compact mode
|
|
938
943
|
backToCompactHandler: function (event) {
|
|
939
944
|
$(event.delegateTarget).removeClass('looseMode')
|
|
945
|
+
.find('.looseMode').removeClass('looseMode')
|
|
940
946
|
.children('.backToCompactSymbol').addClass('hidden').end()
|
|
941
947
|
.children('.backToLooseSymbol').removeClass('hidden');
|
|
948
|
+
$(event.delegateTarget).children('.backToCompactSymbol').addClass('hidden').end()
|
|
949
|
+
.children('.backToLooseSymbol').removeClass('hidden');
|
|
942
950
|
},
|
|
943
951
|
// show the compact node's children in the loose mode
|
|
944
952
|
backToLooseHandler: function (event) {
|
|
@@ -1341,7 +1349,10 @@
|
|
|
1341
1349
|
}
|
|
1342
1350
|
// construct the content of node
|
|
1343
1351
|
var $nodeDiv = $('<div' + (opts.draggable ? ' draggable="true"' : '') + (data[opts.nodeId] ? ' id="' + data[opts.nodeId] + '"' : '') + (data.parentId ? ' data-parent="' + data.parentId + '"' : '') + '>')
|
|
1344
|
-
.addClass('node '
|
|
1352
|
+
.addClass('node '
|
|
1353
|
+
+ (data.className || '')
|
|
1354
|
+
+ (data?.outsider ? 'outsider' : '')
|
|
1355
|
+
+ (level > opts.visibleLevel ? ' slide-up' : ''));
|
|
1345
1356
|
if (opts.nodeTemplate) {
|
|
1346
1357
|
$nodeDiv.append(opts.nodeTemplate(data));
|
|
1347
1358
|
} else {
|
|
@@ -1410,51 +1421,38 @@
|
|
|
1410
1421
|
|
|
1411
1422
|
return $nodeDiv;
|
|
1412
1423
|
},
|
|
1413
|
-
//
|
|
1414
|
-
|
|
1424
|
+
// Construct the inferior nodes within a hierarchy
|
|
1425
|
+
buildInferiorNodes: function ($hierarchy, $nodeDiv, data, level) {
|
|
1415
1426
|
var that = this;
|
|
1416
1427
|
var opts = this.options;
|
|
1417
|
-
var
|
|
1418
|
-
var $
|
|
1419
|
-
if (
|
|
1420
|
-
|
|
1428
|
+
var isHidden = level + 1 > opts.visibleLevel || (data.collapsed !== undefined && data.collapsed);
|
|
1429
|
+
var $nodesLayer;
|
|
1430
|
+
if ((opts.verticalLevel && (level + 1) >= opts.verticalLevel) || data.hybrid) {
|
|
1431
|
+
$nodesLayer = $('<ul class="nodes">');
|
|
1432
|
+
if (isHidden && (opts.verticalLevel && (level + 1) >= opts.verticalLevel)) {
|
|
1433
|
+
$nodesLayer.addClass('hidden');
|
|
1434
|
+
}
|
|
1435
|
+
if (((opts.verticalLevel && level + 1 === opts.verticalLevel) || data.hybrid)
|
|
1436
|
+
&& !$hierarchy.closest('.vertical').length) {
|
|
1437
|
+
$nodesLayer.addClass('vertical');
|
|
1438
|
+
}
|
|
1439
|
+
$hierarchy.append($nodesLayer);
|
|
1440
|
+
} else if (data.compact) {
|
|
1441
|
+
$nodeDiv.addClass('compact');
|
|
1421
1442
|
} else {
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
if (Object.keys(data).length > 2) {
|
|
1426
|
-
$nodeDiv = this.createNode(data);
|
|
1427
|
-
$appendTo.append($nodeDiv);
|
|
1428
|
-
}
|
|
1429
|
-
// Construct the "inferior nodes"
|
|
1430
|
-
if (data.children && data.children.length) {
|
|
1431
|
-
var isHidden = level + 1 > opts.visibleLevel || (data.collapsed !== undefined && data.collapsed);
|
|
1432
|
-
var $nodesLayer;
|
|
1433
|
-
if ((opts.verticalLevel && (level + 1) >= opts.verticalLevel) || data.hybrid) {
|
|
1434
|
-
$nodesLayer = $('<ul class="nodes">');
|
|
1435
|
-
if (isHidden && (opts.verticalLevel && (level + 1) >= opts.verticalLevel)) {
|
|
1436
|
-
$nodesLayer.addClass('hidden');
|
|
1437
|
-
}
|
|
1438
|
-
if (((opts.verticalLevel && level + 1 === opts.verticalLevel) || data.hybrid)
|
|
1439
|
-
&& !$appendTo.closest('.vertical').length) {
|
|
1440
|
-
$appendTo.append($nodesLayer.addClass('vertical'));
|
|
1441
|
-
} else {
|
|
1442
|
-
$appendTo.append($nodesLayer);
|
|
1443
|
-
}
|
|
1444
|
-
} else if (data.compact) {
|
|
1445
|
-
$nodeDiv.addClass('compact');
|
|
1446
|
-
} else {
|
|
1447
|
-
$nodesLayer = $('<ul class="nodes' + (isHidden ? ' hidden' : '') + '">');
|
|
1448
|
-
if (Object.keys(data).length === 2) {
|
|
1449
|
-
$appendTo.append($nodesLayer);
|
|
1450
|
-
} else {
|
|
1451
|
-
if (isHidden) {
|
|
1452
|
-
$appendTo.addClass('isChildrenCollapsed');
|
|
1453
|
-
}
|
|
1454
|
-
$appendTo.append($nodesLayer);
|
|
1455
|
-
}
|
|
1443
|
+
$nodesLayer = $('<ul class="nodes' + (isHidden ? ' hidden' : '') + '">');
|
|
1444
|
+
if (isHidden) {
|
|
1445
|
+
$hierarchy.addClass('isChildrenCollapsed');
|
|
1456
1446
|
}
|
|
1457
|
-
|
|
1447
|
+
$hierarchy.append($nodesLayer);
|
|
1448
|
+
}
|
|
1449
|
+
// recurse through children nodes
|
|
1450
|
+
if (Array.isArray(data.children[0])) {
|
|
1451
|
+
$.each(data.children, function() {
|
|
1452
|
+
this.level = level + 1;
|
|
1453
|
+
});
|
|
1454
|
+
this.buildHierarchy($nodesLayer, data.children); // 构造子一层的夫妻组合(每个组合可能有多妻多夫情况)
|
|
1455
|
+
} else {
|
|
1458
1456
|
$.each(data.children, function () {
|
|
1459
1457
|
this.level = level + 1;
|
|
1460
1458
|
if (data.compact) {
|
|
@@ -1467,6 +1465,69 @@
|
|
|
1467
1465
|
});
|
|
1468
1466
|
}
|
|
1469
1467
|
},
|
|
1468
|
+
// recursively build the tree
|
|
1469
|
+
buildHierarchy: function ($hierarchy, data) {
|
|
1470
|
+
var that = this;
|
|
1471
|
+
var opts = this.options;
|
|
1472
|
+
var level = 0;
|
|
1473
|
+
var $nodeDiv;
|
|
1474
|
+
if (data.level || data[0]?.level) {
|
|
1475
|
+
level = data.level;
|
|
1476
|
+
} else {
|
|
1477
|
+
level = $hierarchy.parentsUntil('.orgchart', '.nodes').length;
|
|
1478
|
+
if (Array.isArray(data) && Array.isArray(data[0])) {
|
|
1479
|
+
$.each(data, function () {
|
|
1480
|
+
$.each(this, function () {
|
|
1481
|
+
this.level = level;
|
|
1482
|
+
});
|
|
1483
|
+
});
|
|
1484
|
+
} else {
|
|
1485
|
+
data.level = level;
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
// Construct the single node in OrgChart or the multiple nodes in family tree
|
|
1489
|
+
if (Array.isArray(data) && Array.isArray(data[0])) { // 处理family tree的情况
|
|
1490
|
+
$.each(data, function () { // 构造一个家庭的hierarchy
|
|
1491
|
+
var _this = this;
|
|
1492
|
+
$.each(this, function (i) { // 构造一个夫/妻节点
|
|
1493
|
+
$nodeDiv = that.createNode(this);
|
|
1494
|
+
// if there are only two persons in a marriage, two single nodes will appear in a hierarchy
|
|
1495
|
+
if (_this.length === 2 && i === 1) {
|
|
1496
|
+
$hierarchy.find(`#${_this[0].id}`).after($nodeDiv);
|
|
1497
|
+
if (this.children && this.children.length && this.children[0].length) {
|
|
1498
|
+
that.buildInferiorNodes($hierarchy.find(`#${_this[0].id}`).parent(), $nodeDiv, this, level);
|
|
1499
|
+
}
|
|
1500
|
+
} else {
|
|
1501
|
+
// if there are more than two persons in a marriage, every node will be included in a single hierarchy
|
|
1502
|
+
var $wrapper = $(`<li class="hierarchy${_this.length > 1 ? ' spouse' : ''}${_this.length === 2 ? ' couple' : ''}${!!this.outsider === false && _this.length > 2 ? ' insider' : ''}"></li>`);
|
|
1503
|
+
|
|
1504
|
+
//在family tree中,一个多妻/多夫组合里,本姓人只有一个,外姓人可能有多个,我们通过水平的连线来表示他们是一家子
|
|
1505
|
+
if (i === 0) {
|
|
1506
|
+
$wrapper.css({'--ft-width': '50%', '--ft-left-offset': '50%'});
|
|
1507
|
+
} else if (i > 0 && i < _this.length - 1) {
|
|
1508
|
+
$wrapper.css({'--ft-width': '100%', '--ft-left-offset': '0px'});
|
|
1509
|
+
} else {
|
|
1510
|
+
$wrapper.css({'--ft-width': '50%', '--ft-left-offset': '0px'});
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
$wrapper.append($nodeDiv);
|
|
1514
|
+
$hierarchy.append($wrapper);
|
|
1515
|
+
if (this.children && this.children.length && this.children[0].length) {
|
|
1516
|
+
that.buildInferiorNodes($wrapper, $nodeDiv, this, level);
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
});
|
|
1520
|
+
});
|
|
1521
|
+
} else {
|
|
1522
|
+
if (Object.keys(data).length > 2) { // TODO: 应该用更好的方式来判断是否是供父一级节点创建的信息
|
|
1523
|
+
$nodeDiv = this.createNode(data);
|
|
1524
|
+
$hierarchy.append($nodeDiv);
|
|
1525
|
+
}
|
|
1526
|
+
if (data.children && data.children.length) {
|
|
1527
|
+
this.buildInferiorNodes($hierarchy, $nodeDiv, data, level);
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
},
|
|
1470
1531
|
// build the child nodes of specific node
|
|
1471
1532
|
buildChildNode: function ($appendTo, data) {
|
|
1472
1533
|
this.buildHierarchy($appendTo, { 'children': data });
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<title>Organization Chart Plugin</title>
|
|
6
|
-
<link rel="icon" href="img/logo.png">
|
|
7
|
-
<link rel="stylesheet" href="css/jquery.orgchart.css">
|
|
8
|
-
<link rel="stylesheet" href="css/style.css">
|
|
9
|
-
<style type="text/css">
|
|
10
|
-
.hidden { display: none; }
|
|
11
|
-
.orgchart .drill-icon {
|
|
12
|
-
transition: opacity .5s;
|
|
13
|
-
opacity: 0;
|
|
14
|
-
right: -8px;
|
|
15
|
-
top: -8px;
|
|
16
|
-
z-index: 2;
|
|
17
|
-
position: absolute;
|
|
18
|
-
}
|
|
19
|
-
.orgchart .drill-icon::before {
|
|
20
|
-
background-color: rgba(68, 157, 68, 0.5);
|
|
21
|
-
}
|
|
22
|
-
.orgchart .drill-icon:hover::before { background-color: #449d44; }
|
|
23
|
-
.orgchart .node:hover .drill-icon { opacity: 1; }
|
|
24
|
-
</style>
|
|
25
|
-
</head>
|
|
26
|
-
<body>
|
|
27
|
-
<div id="chart-container"></div>
|
|
28
|
-
|
|
29
|
-
<script type="text/javascript" src="js/jquery.min.js"></script>
|
|
30
|
-
<script type="text/javascript" src="js/jquery.orgchart.js"></script>
|
|
31
|
-
<script type="text/javascript" src="js/jquery.mockjax.min.js"></script>
|
|
32
|
-
<script type="text/javascript">
|
|
33
|
-
$.mockjax({
|
|
34
|
-
url: '/orgchart/root-node',
|
|
35
|
-
responseTime: 1000,
|
|
36
|
-
contentType: 'application/json',
|
|
37
|
-
responseText: {
|
|
38
|
-
'className': 'root-node',
|
|
39
|
-
'name': 'Lao Lao',
|
|
40
|
-
'dept': 'president office',
|
|
41
|
-
'children': [
|
|
42
|
-
{ 'name': 'Bo Miao', 'dept': 'product dept' },
|
|
43
|
-
{ 'className': 'drill-down asso-rd', 'name': 'Su Miao', 'dept': 'R&D dept' },
|
|
44
|
-
{ 'name': 'Hong Miao', 'dept': 'finance dept' },
|
|
45
|
-
{ 'name': 'Chun Miao', 'dept': 'HR dept' }
|
|
46
|
-
]
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
$.mockjax({
|
|
51
|
-
url: '/orgchart/asso-rd',
|
|
52
|
-
responseTime: 1000,
|
|
53
|
-
contentType: 'application/json',
|
|
54
|
-
responseText: {
|
|
55
|
-
'className': 'asso-rd drill-up',
|
|
56
|
-
'name': 'Su Miao',
|
|
57
|
-
'dept': 'R&D dept',
|
|
58
|
-
'children': [
|
|
59
|
-
{ 'name': 'Tie Hua', 'dept': 'backend group' },
|
|
60
|
-
{ 'className': 'drill-down asso-frontend', 'name': 'Hei Hei', 'dept': 'frontend group' }
|
|
61
|
-
]
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
$.mockjax({
|
|
66
|
-
url: '/orgchart/asso-frontend',
|
|
67
|
-
responseTime: 1000,
|
|
68
|
-
contentType: 'application/json',
|
|
69
|
-
responseText: {
|
|
70
|
-
'className': 'asso-frontend drill-up',
|
|
71
|
-
'name': 'Hei Hei',
|
|
72
|
-
'dept': 'frontend group',
|
|
73
|
-
'children': [
|
|
74
|
-
{ 'name': 'Pang Pang', 'dept': 'frontend group' },
|
|
75
|
-
{ 'name': 'Xiang Xiang', 'dept': 'frontend group',
|
|
76
|
-
'children': [
|
|
77
|
-
{ 'name': 'Xiao Xiao', 'dept': 'frontend group' },
|
|
78
|
-
{ 'name': 'Dan Dan', 'dept': 'frontend group' },
|
|
79
|
-
{ 'name': 'Zai Zai', 'dept': 'frontend group' }
|
|
80
|
-
]
|
|
81
|
-
}
|
|
82
|
-
]
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
function initOrgchart(rootClass) {
|
|
87
|
-
$('#chart-container').orgchart({
|
|
88
|
-
'chartClass': rootClass,
|
|
89
|
-
'data' : '/orgchart/' + rootClass,
|
|
90
|
-
'nodeContent': 'dept',
|
|
91
|
-
'createNode': function($node, data) {
|
|
92
|
-
if ($node.is('.drill-down')) {
|
|
93
|
-
var assoClass = data.className.match(/asso-\w+/)[0];
|
|
94
|
-
var drillDownIcon = $('<i>', {
|
|
95
|
-
'class': 'oci oci-arrow-square-down drill-icon',
|
|
96
|
-
'click': function() {
|
|
97
|
-
$('#chart-container').find('.orgchart:visible').addClass('hidden');
|
|
98
|
-
if (!$('#chart-container').find('.orgchart.' + assoClass).length) {
|
|
99
|
-
initOrgchart(assoClass);
|
|
100
|
-
} else {
|
|
101
|
-
$('#chart-container').find('.orgchart.' + assoClass).removeClass('hidden');
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
$node.append(drillDownIcon);
|
|
106
|
-
} else if ($node.is('.drill-up')) {
|
|
107
|
-
var assoClass = data.className.match(/asso-\w+/)[0];
|
|
108
|
-
var drillUpIcon = $('<i>', {
|
|
109
|
-
'class': 'oci oci-arrow-square-up drill-icon',
|
|
110
|
-
'click': function() {
|
|
111
|
-
$('#chart-container').find('.orgchart:visible').addClass('hidden').end()
|
|
112
|
-
.find('.drill-down.' + assoClass).closest('.orgchart').removeClass('hidden');
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
$node.append(drillUpIcon);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
$(function() {
|
|
122
|
-
|
|
123
|
-
initOrgchart('root-node');
|
|
124
|
-
|
|
125
|
-
});
|
|
126
|
-
</script>
|
|
127
|
-
</body>
|
|
128
|
-
</html>
|