orgchart 4.0.1 → 6.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/.github/workflows/publish.yml +32 -0
- package/README.md +205 -89
- package/README.zh-cn.md +221 -68
- package/README.zh-tw.md +221 -68
- package/bower.json +6 -9
- package/demo/10000-nodes.html +139 -0
- package/demo/ajax-datasource.html +46 -45
- package/demo/bottom2top.html +12 -9
- package/demo/center-on-selected-node.html +21 -17
- package/demo/color-coded.html +12 -9
- package/demo/css/style.css +28 -0
- package/demo/custom-icons.html +12 -9
- package/demo/custom-template.html +12 -9
- package/demo/data-prop-compact.html +11 -8
- package/demo/data-prop-hybrid.html +79 -50
- package/demo/default-collapsed.html +12 -9
- package/demo/drag-drop-hybrid-chart.html +17 -14
- package/demo/drag-drop.html +21 -16
- package/demo/edit-chart.html +148 -94
- package/demo/edit-hybrid-chart.html +178 -135
- package/demo/expand-to-given-depth.html +30 -22
- package/demo/export-chart-pdf.html +12 -9
- package/demo/export-chart-with-pictures.html +19 -12
- package/demo/export-chart.html +12 -9
- package/demo/family-tree.html +100 -0
- package/demo/familytree-custom-properties.html +108 -0
- package/demo/filter-node.html +104 -57
- package/demo/get-hierarchy.html +17 -12
- package/demo/get-related-nodes.html +27 -17
- package/demo/index.html +7 -4
- package/demo/integrate-map.html +32 -27
- package/demo/left2right.html +12 -9
- package/demo/level-offset.html +16 -15
- package/demo/link-node.html +12 -9
- package/demo/local-datasource.html +11 -8
- package/demo/minimap.html +224 -0
- package/demo/nodes-of-different-widths.html +11 -8
- package/demo/ondemand-loading-data.html +88 -91
- package/demo/option-createNode.html +31 -20
- package/demo/pan-zoom.html +20 -11
- package/demo/reload-data.html +17 -14
- package/demo/report-path.html +59 -29
- package/demo/responsive-design.html +14 -11
- package/demo/right2left.html +12 -9
- package/demo/toggle-sibs-resp.html +12 -9
- package/demo/ul-datasource.html +11 -8
- package/demo/vertical-level.html +12 -9
- package/dist/css/{jquery.orgchart.css → orgchart.css} +210 -78
- package/dist/css/orgchart.min.css +1 -0
- package/dist/js/orgchart.js +4101 -0
- package/dist/js/orgchart.min.js +2 -0
- package/dist/js/orgchart.min.js.map +1 -0
- package/gulpfile.js +37 -26
- package/package.json +32 -32
- package/src/css/{jquery.orgchart.css → orgchart.css} +210 -78
- package/src/js/orgchart.js +4101 -0
- package/test/cypress/e2e/demo-interactions.cy.js +91 -0
- package/test/cypress/e2e/demo-rendering.cy.js +100 -0
- package/test/cypress/e2e/drag-drop-hybrid-chart.cy.js +22 -0
- package/test/cypress/e2e/edit-chart.cy.js +20 -0
- package/test/cypress/e2e/level-offset.cy.js +21 -0
- package/test/cypress/e2e/minimap.cy.js +66 -0
- package/test/cypress/e2e/pan-zoom.cy.js +165 -0
- package/test/cypress/e2e/report-path.cy.js +20 -0
- package/test/cypress/e2e/vertical-vevel.cy.js +5 -3
- package/test/e2e/local-datasource/test.js +1 -1
- package/test/integration/init-tests.js +168 -62
- package/test/integration/tests.js +1034 -56
- package/test/unit/lifecycle-builders-export.tests.js +1426 -0
- package/test/unit/minimap.tests.js +210 -0
- package/test/unit/tests.js +2372 -252
- package/demo/multiple-layers.html +0 -128
- package/dist/css/jquery.orgchart.min.css +0 -1
- package/dist/js/jquery.orgchart.js +0 -1686
- package/dist/js/jquery.orgchart.min.js +0 -5
- package/dist/js/jquery.orgchart.min.js.map +0 -1
- package/src/js/jquery.orgchart.js +0 -1686
|
@@ -2,25 +2,23 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
|
-
<title>
|
|
5
|
+
<title>OrgChart On-Demand Loading Demo</title>
|
|
6
6
|
<link rel="icon" href="img/logo.png">
|
|
7
|
-
<link rel="stylesheet" href="css/
|
|
7
|
+
<link rel="stylesheet" href="css/orgchart.css">
|
|
8
8
|
<link rel="stylesheet" href="css/style.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
|
+
<section class="demo-notes">
|
|
12
|
+
<h1>On-Demand Loading Demo</h1>
|
|
13
|
+
<p>This demo loads ancestors and descendants only when users expand the corresponding branches.</p>
|
|
14
|
+
</section>
|
|
11
15
|
<div id="chart-container"></div>
|
|
12
|
-
|
|
13
|
-
<script type="text/javascript" src="js/jquery.min.js"></script>
|
|
14
|
-
<script type="text/javascript" src="js/jquery.orgchart.js"></script>
|
|
15
|
-
<script type="text/javascript" src="js/jquery.mockjax.min.js"></script>
|
|
16
|
+
<script type="text/javascript" src="js/orgchart.js"></script>
|
|
16
17
|
<script type="text/javascript">
|
|
17
|
-
|
|
18
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
contentType: 'application/json',
|
|
22
|
-
responseTime: 1000,
|
|
23
|
-
responseText: {
|
|
20
|
+
const responseMap = {
|
|
21
|
+
'/orgchart/ancestors/n1': {
|
|
24
22
|
'id': 'n0',
|
|
25
23
|
'name': 'Lao Lao',
|
|
26
24
|
'title': 'general manager', 'relationship': '001',
|
|
@@ -33,23 +31,11 @@
|
|
|
33
31
|
{ 'id': 'n15', 'name': 'Chun Miao', 'title': 'department engineer', 'relationship': '110' },
|
|
34
32
|
{ 'id': 'n16', 'name': 'Yu Tie', 'title': 'department engineer', 'relationship': '110' }
|
|
35
33
|
]
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
$.mockjax({
|
|
40
|
-
url: '/orgchart/descendants/n2',
|
|
41
|
-
contentType: 'application/json',
|
|
42
|
-
responseTime: 1000,
|
|
43
|
-
responseText: [
|
|
34
|
+
},
|
|
35
|
+
'/orgchart/descendants/n2': [
|
|
44
36
|
{ 'id': 'n4', 'name': 'Xiang Xiang', 'title': 'engineer', 'relationship': '110' }
|
|
45
|
-
]
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
$.mockjax({
|
|
49
|
-
url: '/orgchart/descendants/n3',
|
|
50
|
-
contentType: 'application/json',
|
|
51
|
-
responseTime: 1000,
|
|
52
|
-
responseText: [
|
|
37
|
+
],
|
|
38
|
+
'/orgchart/descendants/n3': [
|
|
53
39
|
{ 'id': 'n5', 'name': 'Pang Pang', 'title': 'engineer', 'relationship': '111',
|
|
54
40
|
'children': [
|
|
55
41
|
{ 'id': 'n6', 'name': 'Er Dan', 'title': 'UE engineer', 'relationship': '110'}
|
|
@@ -57,9 +43,13 @@
|
|
|
57
43
|
},
|
|
58
44
|
{ 'id': 'n7', 'name': 'Dan Dan', 'title': 'engineer', 'relationship': '110' }
|
|
59
45
|
]
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const requestJson = (url) => new Promise((resolve) => {
|
|
49
|
+
window.setTimeout(() => resolve(responseMap[url]), 1000);
|
|
60
50
|
});
|
|
61
51
|
|
|
62
|
-
|
|
52
|
+
const datasource = {
|
|
63
53
|
'id': 'n1',
|
|
64
54
|
'name': 'Su Miao',
|
|
65
55
|
'title': 'department manager',
|
|
@@ -70,82 +60,89 @@
|
|
|
70
60
|
]
|
|
71
61
|
};
|
|
72
62
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
'
|
|
76
|
-
'siblings': function(nodeData) {
|
|
77
|
-
return '/orgchart/siblings/' + nodeData.id;
|
|
78
|
-
},
|
|
79
|
-
'families': function(nodeData) {
|
|
80
|
-
return '/orgchart/families/' + nodeData.id;
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
var oc = $('#chart-container').orgchart({
|
|
85
|
-
'data' : datascource,
|
|
63
|
+
const oc = new OrgChart({
|
|
64
|
+
chartContainer: '#chart-container',
|
|
65
|
+
'data' : datasource,
|
|
86
66
|
'nodeContent': 'title',
|
|
87
67
|
'nodeId': 'id'
|
|
88
68
|
});
|
|
89
69
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
})
|
|
106
|
-
.done(function(data, textStatus, jqXHR) {
|
|
107
|
-
oc.addAncestors(data, 'n0');
|
|
108
|
-
})
|
|
109
|
-
.always(function() {
|
|
110
|
-
$topEdge.removeClass('hidden');
|
|
111
|
-
$node.children('.spinner').remove();
|
|
112
|
-
$node.children().removeAttr('style');
|
|
113
|
-
$chart.data('inAjax', false);
|
|
70
|
+
const chartElement = document.getElementById('chart-container');
|
|
71
|
+
const getAjaxFlag = () => oc.chart.dataset.inAjax === 'true';
|
|
72
|
+
const setAjaxFlag = (value) => {
|
|
73
|
+
oc.chart.dataset.inAjax = value ? 'true' : 'false';
|
|
74
|
+
};
|
|
75
|
+
const toggleLoading = (edgeElement, isLoading) => {
|
|
76
|
+
const nodeElement = edgeElement.parentElement;
|
|
77
|
+
const spinner = nodeElement.querySelector('.spinner');
|
|
78
|
+
edgeElement.classList.toggle('hidden', isLoading);
|
|
79
|
+
if (isLoading && !spinner) {
|
|
80
|
+
nodeElement.insertAdjacentHTML('beforeend', '<i class="oci oci-spinner spinner"></i>');
|
|
81
|
+
Array.from(nodeElement.children)
|
|
82
|
+
.filter((child) => !child.classList.contains('spinner'))
|
|
83
|
+
.forEach((child) => {
|
|
84
|
+
child.style.opacity = '0.2';
|
|
114
85
|
});
|
|
86
|
+
setAjaxFlag(true);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (!isLoading) {
|
|
90
|
+
const currentSpinner = nodeElement.querySelector('.spinner');
|
|
91
|
+
if (currentSpinner) {
|
|
92
|
+
currentSpinner.remove();
|
|
93
|
+
}
|
|
94
|
+
Array.from(nodeElement.children).forEach((child) => {
|
|
95
|
+
child.removeAttribute('style');
|
|
96
|
+
});
|
|
97
|
+
setAjaxFlag(false);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
chartElement.addEventListener('click', async (event) => {
|
|
102
|
+
const clickableAncestor = event.target.closest('.topEdge, .horizontalEdge');
|
|
103
|
+
if (!clickableAncestor || !chartElement.contains(clickableAncestor)) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const nodeElement = clickableAncestor.parentElement;
|
|
107
|
+
const parentState = oc.getNodeState(nodeElement, 'parent');
|
|
108
|
+
if (!parentState.exist) {
|
|
109
|
+
if (getAjaxFlag()) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
toggleLoading(clickableAncestor, true);
|
|
113
|
+
try {
|
|
114
|
+
const nodeData = nodeElement ? nodeElement.__ocNodeData || nodeElement.dataset : {};
|
|
115
|
+
const data = await requestJson('/orgchart/ancestors/' + nodeData.id);
|
|
116
|
+
oc.addAncestors(data, 'n0');
|
|
117
|
+
} finally {
|
|
118
|
+
toggleLoading(clickableAncestor, false);
|
|
115
119
|
}
|
|
116
120
|
}
|
|
117
121
|
});
|
|
118
122
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
chartElement.addEventListener('click', async (event) => {
|
|
124
|
+
const bottomEdge = event.target.closest('.bottomEdge');
|
|
125
|
+
if (!bottomEdge || !chartElement.contains(bottomEdge)) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const nodeElement = bottomEdge.parentElement;
|
|
129
|
+
const childrenState = oc.getNodeState(nodeElement, 'children');
|
|
124
130
|
if (!childrenState.exist) {
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
.done(function(data, textStatus, jqXHR) {
|
|
136
|
-
oc.addDescendants(data, $node);
|
|
137
|
-
})
|
|
138
|
-
.always(function() {
|
|
139
|
-
$bottomEdge.removeClass('hidden');
|
|
140
|
-
$node.children('.spinner').remove();
|
|
141
|
-
$node.children().removeAttr('style');
|
|
142
|
-
$chart.data('inAjax', false);
|
|
143
|
-
});
|
|
131
|
+
if (getAjaxFlag()) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
toggleLoading(bottomEdge, true);
|
|
135
|
+
try {
|
|
136
|
+
const nodeData = nodeElement ? nodeElement.__ocNodeData || nodeElement.dataset : {};
|
|
137
|
+
const data = await requestJson('/orgchart/descendants/' + nodeData.id);
|
|
138
|
+
oc.addDescendants(data, nodeElement);
|
|
139
|
+
} finally {
|
|
140
|
+
toggleLoading(bottomEdge, false);
|
|
144
141
|
}
|
|
145
142
|
}
|
|
146
143
|
});
|
|
147
144
|
|
|
148
|
-
|
|
145
|
+
});
|
|
149
146
|
</script>
|
|
150
147
|
</body>
|
|
151
148
|
</html>
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
|
-
<title>
|
|
5
|
+
<title>OrgChart createNode Callback Demo</title>
|
|
6
6
|
<link rel="icon" href="img/logo.png">
|
|
7
|
-
<link rel="stylesheet" href="css/
|
|
7
|
+
<link rel="stylesheet" href="css/orgchart.css">
|
|
8
8
|
<link rel="stylesheet" href="css/style.css">
|
|
9
9
|
<style type="text/css">
|
|
10
10
|
.orgchart .second-menu-icon {
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
.orgchart .node .second-menu {
|
|
22
22
|
display: none;
|
|
23
23
|
position: absolute;
|
|
24
|
-
|
|
25
|
-
right:
|
|
24
|
+
bottom: -35px;
|
|
25
|
+
right: 0;
|
|
26
26
|
border-radius: 35px;
|
|
27
27
|
box-shadow: 0 0 10px 1px #999;
|
|
28
28
|
background-color: #fff;
|
|
29
|
-
z-index:
|
|
29
|
+
z-index: 3;
|
|
30
30
|
}
|
|
31
31
|
.orgchart .node .second-menu .avatar {
|
|
32
32
|
width: 60px;
|
|
@@ -38,14 +38,16 @@
|
|
|
38
38
|
</style>
|
|
39
39
|
</head>
|
|
40
40
|
<body>
|
|
41
|
+
<section class="demo-notes">
|
|
42
|
+
<h1>createNode Callback Demo</h1>
|
|
43
|
+
<p>This demo uses the createNode callback to append custom secondary UI after each node is created.</p>
|
|
44
|
+
</section>
|
|
41
45
|
<div id="chart-container"></div>
|
|
42
|
-
|
|
43
|
-
<script type="text/javascript" src="js/jquery.min.js"></script>
|
|
44
|
-
<script type="text/javascript" src="js/jquery.orgchart.js"></script>
|
|
46
|
+
<script type="text/javascript" src="js/orgchart.js"></script>
|
|
45
47
|
<script type="text/javascript">
|
|
46
|
-
|
|
48
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
const datasource = {
|
|
49
51
|
'id': '1',
|
|
50
52
|
'name': 'Lao Lao',
|
|
51
53
|
'title': 'general manager',
|
|
@@ -71,20 +73,29 @@
|
|
|
71
73
|
]
|
|
72
74
|
};
|
|
73
75
|
|
|
74
|
-
|
|
75
|
-
'
|
|
76
|
+
const oc = new OrgChart({
|
|
77
|
+
chartContainer: '#chart-container',
|
|
78
|
+
'data' : datasource,
|
|
76
79
|
'visibleLevel': 2,
|
|
77
80
|
'nodeContent': 'title',
|
|
78
81
|
'nodeID': 'id',
|
|
79
|
-
'createNode': function(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
'createNode': function(node, data) {
|
|
83
|
+
const secondMenuIcon = document.createElement('i');
|
|
84
|
+
const secondMenu = document.createElement('div');
|
|
85
|
+
const avatar = document.createElement('img');
|
|
86
|
+
|
|
87
|
+
secondMenuIcon.className = 'oci oci-info-circle second-menu-icon';
|
|
88
|
+
secondMenuIcon.addEventListener('click', () => {
|
|
89
|
+
secondMenu.style.display = secondMenu.style.display === 'block' ? 'none' : 'block';
|
|
85
90
|
});
|
|
86
|
-
|
|
87
|
-
|
|
91
|
+
|
|
92
|
+
secondMenu.className = 'second-menu';
|
|
93
|
+
avatar.className = 'avatar';
|
|
94
|
+
avatar.src = 'img/avatar/' + data.id + '.jpg';
|
|
95
|
+
|
|
96
|
+
secondMenu.appendChild(avatar);
|
|
97
|
+
node.appendChild(secondMenuIcon);
|
|
98
|
+
node.appendChild(secondMenu);
|
|
88
99
|
}
|
|
89
100
|
});
|
|
90
101
|
|
package/demo/pan-zoom.html
CHANGED
|
@@ -2,23 +2,31 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
|
-
<title>
|
|
5
|
+
<title>OrgChart Pan and Zoom Demo</title>
|
|
6
6
|
<link rel="icon" href="img/logo.png">
|
|
7
|
-
<link rel="stylesheet" href="css/
|
|
7
|
+
<link rel="stylesheet" href="css/orgchart.css">
|
|
8
8
|
<link rel="stylesheet" href="css/style.css">
|
|
9
9
|
<style type="text/css">
|
|
10
|
+
body {
|
|
11
|
+
padding: 0.5rem;
|
|
12
|
+
}
|
|
10
13
|
.orgchart { background: white; }
|
|
11
14
|
</style>
|
|
12
15
|
</head>
|
|
13
16
|
<body>
|
|
17
|
+
<section class="demo-notes">
|
|
18
|
+
<h1>Pan and Zoom Demo</h1>
|
|
19
|
+
<p>Mouse wheel zoom is anchored to the current mouse position inside the chart container, so the content under the pointer should stay under the pointer while zooming.</p>
|
|
20
|
+
<p>Wheel input is ignored when the pointer is outside the chart container bounds. On touch devices, pinch zoom is anchored to the midpoint between the two fingers.</p>
|
|
21
|
+
<p>Drag the chart to pan. Use mouse wheel or touch pinch to verify the zoom anchor behavior.</p>
|
|
22
|
+
<p>If you want an overview navigator for the same interaction model, open <a href="minimap.html" target="_blank">the minimap demo</a> to move the main chart through the viewport rectangle in the lower-right corner.</p>
|
|
23
|
+
</section>
|
|
14
24
|
<div id="chart-container"></div>
|
|
15
|
-
|
|
16
|
-
<script type="text/javascript" src="js/jquery.min.js"></script>
|
|
17
|
-
<script type="text/javascript" src="js/jquery.orgchart.js"></script>
|
|
25
|
+
<script type="text/javascript" src="js/orgchart.js"></script>
|
|
18
26
|
<script type="text/javascript">
|
|
19
|
-
|
|
27
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
20
28
|
|
|
21
|
-
|
|
29
|
+
const datasource = {
|
|
22
30
|
'name': 'Lao Lao',
|
|
23
31
|
'title': 'general manager',
|
|
24
32
|
'children': [
|
|
@@ -43,16 +51,17 @@
|
|
|
43
51
|
]
|
|
44
52
|
};
|
|
45
53
|
|
|
46
|
-
|
|
47
|
-
'
|
|
54
|
+
const oc = new OrgChart({
|
|
55
|
+
chartContainer: '#chart-container',
|
|
56
|
+
'data' : datasource,
|
|
48
57
|
'nodeContent': 'title',
|
|
49
58
|
'pan': true,
|
|
50
59
|
'zoom': true
|
|
51
60
|
});
|
|
52
61
|
|
|
53
|
-
oc
|
|
62
|
+
oc.chartContainer.addEventListener('touchmove', function(event) {
|
|
54
63
|
event.preventDefault();
|
|
55
|
-
});
|
|
64
|
+
}, { passive: false });
|
|
56
65
|
|
|
57
66
|
});
|
|
58
67
|
</script>
|
package/demo/reload-data.html
CHANGED
|
@@ -2,26 +2,28 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
|
-
<title>
|
|
5
|
+
<title>OrgChart Reload Data Demo</title>
|
|
6
6
|
<link rel="icon" href="img/logo.png">
|
|
7
|
-
<link rel="stylesheet" href="css/
|
|
7
|
+
<link rel="stylesheet" href="css/orgchart.css">
|
|
8
8
|
<link rel="stylesheet" href="css/style.css">
|
|
9
9
|
<style type="text/css">
|
|
10
10
|
button { padding: 0.5rem 1rem; font-size: 1rem; }
|
|
11
11
|
</style>
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
|
+
<section class="demo-notes">
|
|
15
|
+
<h1>Reload Data Demo</h1>
|
|
16
|
+
<p>This demo re-initializes the same chart container with different datasources so you can compare how option changes refresh the chart.</p>
|
|
17
|
+
</section>
|
|
14
18
|
<button style="margin: 10px;" id="btn-chart1">chart 1</button>
|
|
15
19
|
<button style="margin: 10px;" id="btn-chart2">chart 2</button>
|
|
16
20
|
<button style="margin: 10px;" id="btn-chart3">chart 3</button>
|
|
17
21
|
<div id="chart-container"></div>
|
|
18
|
-
|
|
19
|
-
<script type="text/javascript" src="js/jquery.min.js"></script>
|
|
20
|
-
<script type="text/javascript" src="js/jquery.orgchart.js"></script>
|
|
22
|
+
<script type="text/javascript" src="js/orgchart.js"></script>
|
|
21
23
|
<script type="text/javascript">
|
|
22
|
-
|
|
24
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
const datasource = {
|
|
25
27
|
'name': 'Lao Lao',
|
|
26
28
|
'title': 'general manager',
|
|
27
29
|
'children': [
|
|
@@ -36,17 +38,18 @@
|
|
|
36
38
|
]
|
|
37
39
|
};
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
const oc = new OrgChart({
|
|
42
|
+
chartContainer: '#chart-container',
|
|
40
43
|
'data' : datasource,
|
|
41
44
|
'nodeContent': 'title'
|
|
42
45
|
});
|
|
43
46
|
|
|
44
|
-
|
|
47
|
+
document.getElementById('btn-chart1').addEventListener('click', () => {
|
|
45
48
|
oc.init({ 'data': datasource });
|
|
46
49
|
});
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
document.getElementById('btn-chart2').addEventListener('click', () => {
|
|
52
|
+
const data = { 'name': 'Su Miao', 'title': 'department manager',
|
|
50
53
|
'children': [
|
|
51
54
|
{ 'name': 'Tie Hua', 'title': 'senior engineer' },
|
|
52
55
|
{ 'name': 'Hei Hei', 'title': 'senior engineer' }
|
|
@@ -55,8 +58,8 @@
|
|
|
55
58
|
oc.init({ 'data': data });
|
|
56
59
|
});
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
document.getElementById('btn-chart3').addEventListener('click', () => {
|
|
62
|
+
const data = { 'name': 'Hei Hei', 'title': 'senior engineer',
|
|
60
63
|
'children': [
|
|
61
64
|
{ 'name': 'Pang Pang', 'title': 'engineer' },
|
|
62
65
|
{ 'name': 'Dan Zai', 'title': 'UE engineer' },
|
|
@@ -66,7 +69,7 @@
|
|
|
66
69
|
oc.init({ 'data': data });
|
|
67
70
|
});
|
|
68
71
|
|
|
69
|
-
|
|
72
|
+
});
|
|
70
73
|
</script>
|
|
71
74
|
</body>
|
|
72
75
|
</html>
|
package/demo/report-path.html
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
|
-
<title>
|
|
5
|
+
<title>OrgChart Report Path Demo</title>
|
|
6
6
|
<link rel="icon" href="img/logo.png">
|
|
7
|
-
<link rel="stylesheet" href="css/
|
|
7
|
+
<link rel="stylesheet" href="css/orgchart.css">
|
|
8
8
|
<link rel="stylesheet" href="css/style.css">
|
|
9
9
|
<style type="text/css">
|
|
10
10
|
#edit-panel {
|
|
@@ -18,19 +18,26 @@
|
|
|
18
18
|
</style>
|
|
19
19
|
</head>
|
|
20
20
|
<body>
|
|
21
|
+
<section class="demo-notes">
|
|
22
|
+
<h1>Report Path Demo</h1>
|
|
23
|
+
<p>This demo lets you select a node and then draw the reporting path back through its management chain.</p>
|
|
24
|
+
</section>
|
|
21
25
|
<div id="chart-container"></div>
|
|
22
26
|
<div id="edit-panel" class="view-state">
|
|
23
27
|
<input type="text" id="selected-node" placeholder="please select node" readonly="true">
|
|
24
28
|
<button type="button" id="btn-report-path">draw report path</button>
|
|
25
29
|
<button type="button" id="btn-reset">reset</button>
|
|
26
30
|
</div>
|
|
27
|
-
|
|
28
|
-
<script type="text/javascript" src="js/jquery.min.js"></script>
|
|
29
|
-
<script type="text/javascript" src="js/jquery.orgchart.js"></script>
|
|
31
|
+
<script type="text/javascript" src="js/orgchart.js"></script>
|
|
30
32
|
<script type="text/javascript">
|
|
31
|
-
|
|
33
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
34
|
+
|
|
35
|
+
const chartContainer = document.getElementById('chart-container');
|
|
36
|
+
const selectedNodeInput = document.getElementById('selected-node');
|
|
37
|
+
const reportButton = document.getElementById('btn-report-path');
|
|
38
|
+
const resetButton = document.getElementById('btn-reset');
|
|
32
39
|
|
|
33
|
-
|
|
40
|
+
const datasource = {
|
|
34
41
|
'name': 'Lao Lao',
|
|
35
42
|
'title': 'general manager',
|
|
36
43
|
'children': [
|
|
@@ -61,40 +68,63 @@
|
|
|
61
68
|
]
|
|
62
69
|
};
|
|
63
70
|
|
|
64
|
-
|
|
65
|
-
'
|
|
71
|
+
const oc = new OrgChart({
|
|
72
|
+
chartContainer: '#chart-container',
|
|
73
|
+
'data' : datasource,
|
|
66
74
|
'nodeContent': 'title'
|
|
67
75
|
});
|
|
68
76
|
|
|
69
|
-
|
|
70
|
-
|
|
77
|
+
chartContainer.addEventListener('click', (event) => {
|
|
78
|
+
const clickedNode = event.target.closest('.node');
|
|
79
|
+
if (!clickedNode || !chartContainer.contains(clickedNode)) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const titleElement = clickedNode.querySelector('.title');
|
|
83
|
+
selectedNodeInput.value = titleElement ? titleElement.textContent.trim() : '';
|
|
71
84
|
});
|
|
72
85
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
86
|
+
reportButton.addEventListener('click', () => {
|
|
87
|
+
const selected = chartContainer.querySelector('.node.focused');
|
|
88
|
+
const selectedNodeName = selectedNodeInput.value;
|
|
89
|
+
if (selected) {
|
|
90
|
+
let hierarchy = selected.closest('.hierarchy');
|
|
91
|
+
while (hierarchy) {
|
|
92
|
+
const parentNodes = hierarchy.parentElement;
|
|
93
|
+
const parentHierarchy = parentNodes ? parentNodes.closest('.hierarchy') : null;
|
|
94
|
+
if (!parentHierarchy) {
|
|
95
|
+
break;
|
|
79
96
|
}
|
|
97
|
+
const superior = parentHierarchy.querySelector(':scope > .node');
|
|
98
|
+
const horizontalEdge = superior ? superior.querySelector('.horizontalEdge') : null;
|
|
99
|
+
const hasHiddenSibling = Array.from(parentHierarchy.parentElement.children)
|
|
100
|
+
.some((sibling) => sibling !== parentHierarchy && sibling.classList.contains('hidden'));
|
|
101
|
+
if (horizontalEdge && !hasHiddenSibling) {
|
|
102
|
+
horizontalEdge.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
|
103
|
+
}
|
|
104
|
+
hierarchy = parentHierarchy;
|
|
105
|
+
}
|
|
106
|
+
chartContainer.querySelectorAll('.node.focused').forEach((node) => {
|
|
107
|
+
node.classList.remove('focused');
|
|
80
108
|
});
|
|
81
|
-
|
|
109
|
+
selected.classList.add('focused');
|
|
110
|
+
selectedNodeInput.value = selectedNodeName;
|
|
111
|
+
reportButton.disabled = true;
|
|
82
112
|
} else {
|
|
83
113
|
alert('please select the node firstly');
|
|
84
114
|
}
|
|
85
115
|
});
|
|
86
116
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
117
|
+
resetButton.addEventListener('click', () => {
|
|
118
|
+
chartContainer.querySelectorAll('.hidden').forEach((element) => element.classList.remove('hidden'));
|
|
119
|
+
chartContainer.querySelectorAll('.slide-up, .slide-right, .slide-left, .focused').forEach((element) => {
|
|
120
|
+
element.classList.remove('slide-up', 'slide-right', 'slide-left', 'focused');
|
|
121
|
+
});
|
|
122
|
+
chartContainer.querySelectorAll('.isCollapsedSibling, .isChildrenCollapsed, .isSiblingsCollapsed').forEach((element) => {
|
|
123
|
+
element.classList.remove('isCollapsedSibling', 'isChildrenCollapsed', 'isSiblingsCollapsed');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
reportButton.disabled = false;
|
|
127
|
+
selectedNodeInput.value = '';
|
|
98
128
|
});
|
|
99
129
|
|
|
100
130
|
});
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
|
-
<title>
|
|
5
|
+
<title>OrgChart Responsive Design Demo</title>
|
|
6
6
|
<link rel="icon" href="img/logo.png">
|
|
7
|
-
<link rel="stylesheet" href="css/
|
|
7
|
+
<link rel="stylesheet" href="css/orgchart.css">
|
|
8
8
|
<link rel="stylesheet" href="css/style.css">
|
|
9
9
|
<style type="text/css">
|
|
10
10
|
#chart-container { height: 620px; }
|
|
@@ -12,14 +12,16 @@
|
|
|
12
12
|
</style>
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
|
+
<section class="demo-notes">
|
|
16
|
+
<h1>Responsive Design Demo</h1>
|
|
17
|
+
<p>This demo shows how the chart behaves inside a constrained container across different viewport sizes.</p>
|
|
18
|
+
</section>
|
|
15
19
|
<div id="chart-container"></div>
|
|
16
|
-
|
|
17
|
-
<script type="text/javascript" src="js/jquery.min.js"></script>
|
|
18
|
-
<script type="text/javascript" src="js/jquery.orgchart.js"></script>
|
|
20
|
+
<script type="text/javascript" src="js/orgchart.js"></script>
|
|
19
21
|
<script type="text/javascript">
|
|
20
|
-
|
|
22
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
const datasource = {
|
|
23
25
|
'name': 'Lao Lao',
|
|
24
26
|
'title': 'general manager',
|
|
25
27
|
'children': [
|
|
@@ -59,13 +61,14 @@
|
|
|
59
61
|
]
|
|
60
62
|
};
|
|
61
63
|
|
|
62
|
-
|
|
63
|
-
'
|
|
64
|
+
const oc = new OrgChart({
|
|
65
|
+
chartContainer: '#chart-container',
|
|
66
|
+
'data' : datasource,
|
|
64
67
|
'nodeContent': 'title',
|
|
65
68
|
});
|
|
66
69
|
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
window.addEventListener('resize', () => {
|
|
71
|
+
const width = window.innerWidth;
|
|
69
72
|
if(width > 576) {
|
|
70
73
|
oc.init({'verticalLevel': undefined});
|
|
71
74
|
} else {
|