orgchart 5.0.0 → 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 +172 -93
- package/README.zh-cn.md +163 -74
- package/README.zh-tw.md +163 -74
- 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 +14 -11
- 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 +5 -2
- 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 +28 -17
- 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} +143 -80
- 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} +143 -80
- 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/dist/css/jquery.orgchart.min.css +0 -1
- package/dist/js/jquery.orgchart.js +0 -1741
- 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 -1741
package/demo/edit-chart.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 Edit Chart 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: 500px; }
|
|
@@ -33,6 +33,10 @@
|
|
|
33
33
|
</style>
|
|
34
34
|
</head>
|
|
35
35
|
<body>
|
|
36
|
+
<section class="demo-notes">
|
|
37
|
+
<h1>Edit Chart Demo</h1>
|
|
38
|
+
<p>This demo uses the edit panel to add parent, child, and sibling nodes, delete nodes, and reset the chart state.</p>
|
|
39
|
+
</section>
|
|
36
40
|
<div id="chart-container"></div>
|
|
37
41
|
<div id="edit-panel">
|
|
38
42
|
<span id="chart-state-panel" class="radio-panel">
|
|
@@ -56,13 +60,19 @@
|
|
|
56
60
|
<button type="button" id="btn-delete-nodes">Delete</button>
|
|
57
61
|
<button type="button" id="btn-reset">Reset</button>
|
|
58
62
|
</div>
|
|
59
|
-
<script type="text/javascript" src="js/jquery.min.js"></script>
|
|
60
63
|
<script type="text/javascript" src="js/html2canvas.min.js"></script>
|
|
61
|
-
<script type="text/javascript" src="js/
|
|
64
|
+
<script type="text/javascript" src="js/orgchart.js"></script>
|
|
62
65
|
<script type="text/javascript">
|
|
63
|
-
|
|
66
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
64
67
|
|
|
65
|
-
|
|
68
|
+
const chartContainer = document.getElementById('chart-container');
|
|
69
|
+
const selectedNodeInput = document.getElementById('selected-node');
|
|
70
|
+
const editPanel = document.getElementById('edit-panel');
|
|
71
|
+
const newNodeList = document.getElementById('new-nodelist');
|
|
72
|
+
const nodeTypePanel = document.getElementById('node-type-panel');
|
|
73
|
+
let selectedNode = null;
|
|
74
|
+
|
|
75
|
+
const datasource = {
|
|
66
76
|
'name': 'Ball game',
|
|
67
77
|
'children': [
|
|
68
78
|
{ 'name': 'Football' },
|
|
@@ -71,146 +81,190 @@
|
|
|
71
81
|
]
|
|
72
82
|
};
|
|
73
83
|
|
|
74
|
-
|
|
75
|
-
|
|
84
|
+
const getId = () => (Date.now() * 1000) + Math.floor(Math.random() * 1001);
|
|
85
|
+
const getRootNode = () => chartContainer.querySelector('.orgchart .node');
|
|
86
|
+
const getCheckedNodeType = () => document.querySelector('input[name="node-type"]:checked');
|
|
87
|
+
const getCheckedChartState = () => document.querySelector('input[name="chart-state"]:checked');
|
|
88
|
+
const getNewNodeValues = () => Array.from(newNodeList.querySelectorAll('.new-node'))
|
|
89
|
+
.map((input) => input.value.trim())
|
|
90
|
+
.filter(Boolean);
|
|
91
|
+
const clearSelection = () => {
|
|
92
|
+
selectedNode = null;
|
|
93
|
+
selectedNodeInput.value = '';
|
|
76
94
|
};
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
'
|
|
80
|
-
|
|
81
|
-
|
|
95
|
+
const syncChartEditState = () => {
|
|
96
|
+
const isEditMode = getCheckedChartState()?.value === 'edit';
|
|
97
|
+
const chartElement = chartContainer.querySelector('.orgchart');
|
|
98
|
+
if (!chartElement) {
|
|
99
|
+
return;
|
|
82
100
|
}
|
|
83
|
-
|
|
101
|
+
chartElement.classList.toggle('edit-state', isEditMode);
|
|
102
|
+
};
|
|
84
103
|
|
|
85
|
-
oc
|
|
86
|
-
|
|
87
|
-
|
|
104
|
+
let oc = new OrgChart({
|
|
105
|
+
chartContainer: '#chart-container',
|
|
106
|
+
'data' : datasource,
|
|
107
|
+
'createNode': function(node) {
|
|
108
|
+
node.id = getId();
|
|
109
|
+
}
|
|
88
110
|
});
|
|
89
111
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
112
|
+
chartContainer.addEventListener('click', (event) => {
|
|
113
|
+
const clickedNode = event.target.closest('.node');
|
|
114
|
+
if (clickedNode && chartContainer.contains(clickedNode)) {
|
|
115
|
+
selectedNode = clickedNode;
|
|
116
|
+
const titleElement = clickedNode.querySelector('.title');
|
|
117
|
+
selectedNodeInput.value = titleElement ? titleElement.textContent.trim() : '';
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (event.target.closest('.orgchart')) {
|
|
121
|
+
clearSelection();
|
|
93
122
|
}
|
|
94
123
|
});
|
|
95
124
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
125
|
+
document.querySelectorAll('input[name="chart-state"]').forEach((radio) => {
|
|
126
|
+
radio.addEventListener('click', () => {
|
|
127
|
+
const isEditMode = radio.value === 'edit';
|
|
128
|
+
const chartElement = chartContainer.querySelector('.orgchart');
|
|
129
|
+
if (chartElement) {
|
|
130
|
+
chartElement.classList.toggle('edit-state', isEditMode);
|
|
131
|
+
}
|
|
132
|
+
editPanel.classList.toggle('edit-state', !isEditMode);
|
|
133
|
+
if (isEditMode) {
|
|
134
|
+
const orgchart = chartContainer.querySelector('.orgchart');
|
|
135
|
+
if (orgchart) {
|
|
136
|
+
orgchart.querySelectorAll('.hidden').forEach((element) => element.classList.remove('hidden'));
|
|
137
|
+
orgchart.querySelectorAll('.hierarchy').forEach((element) => {
|
|
138
|
+
element.classList.remove('isCollapsedDescendant', 'isChildrenCollapsed', 'isSiblingsCollapsed', 'isCollapsedSibling');
|
|
139
|
+
});
|
|
140
|
+
orgchart.querySelectorAll('.node').forEach((element) => {
|
|
141
|
+
element.classList.remove('slide-up', 'slide-down', 'slide-right', 'slide-left');
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
document.getElementById('btn-reset').click();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
106
148
|
});
|
|
107
149
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
150
|
+
document.querySelectorAll('input[name="node-type"]').forEach((radio) => {
|
|
151
|
+
radio.addEventListener('click', () => {
|
|
152
|
+
if (radio.value === 'parent') {
|
|
153
|
+
editPanel.classList.add('edit-parent-node');
|
|
154
|
+
Array.from(newNodeList.children).slice(1).forEach((item) => item.remove());
|
|
155
|
+
} else {
|
|
156
|
+
editPanel.classList.remove('edit-parent-node');
|
|
157
|
+
}
|
|
158
|
+
});
|
|
116
159
|
});
|
|
117
160
|
|
|
118
|
-
|
|
119
|
-
|
|
161
|
+
document.getElementById('btn-add-input').addEventListener('click', () => {
|
|
162
|
+
const item = document.createElement('li');
|
|
163
|
+
item.innerHTML = '<input type="text" class="new-node">';
|
|
164
|
+
newNodeList.appendChild(item);
|
|
120
165
|
});
|
|
121
166
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
inputs.last().remove();
|
|
167
|
+
document.getElementById('btn-remove-input').addEventListener('click', () => {
|
|
168
|
+
if (newNodeList.children.length > 1) {
|
|
169
|
+
newNodeList.lastElementChild.remove();
|
|
126
170
|
}
|
|
127
171
|
});
|
|
128
172
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
var validVal = item.value.trim();
|
|
134
|
-
if (validVal.length) {
|
|
135
|
-
nodeVals.push(validVal);
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
var $node = $('#selected-node').data('node');
|
|
173
|
+
document.getElementById('btn-add-nodes').addEventListener('click', () => {
|
|
174
|
+
const nodeVals = getNewNodeValues();
|
|
175
|
+
const nodeType = getCheckedNodeType();
|
|
176
|
+
const rootNode = getRootNode();
|
|
139
177
|
if (!nodeVals.length) {
|
|
140
178
|
alert('Please input value for new node');
|
|
141
179
|
return;
|
|
142
180
|
}
|
|
143
|
-
|
|
144
|
-
if (!nodeType.length) {
|
|
181
|
+
if (!nodeType) {
|
|
145
182
|
alert('Please select a node type');
|
|
146
183
|
return;
|
|
147
184
|
}
|
|
148
|
-
if (nodeType.
|
|
185
|
+
if (nodeType.value !== 'parent' && !chartContainer.querySelector('.orgchart')) {
|
|
149
186
|
alert('Please creat the root node firstly when you want to build up the orgchart from the scratch');
|
|
150
187
|
return;
|
|
151
188
|
}
|
|
152
|
-
if (nodeType.
|
|
189
|
+
if (nodeType.value !== 'parent' && !selectedNode) {
|
|
153
190
|
alert('Please select one node in orgchart');
|
|
154
191
|
return;
|
|
155
192
|
}
|
|
156
|
-
if (nodeType.
|
|
157
|
-
if (
|
|
158
|
-
oc =
|
|
193
|
+
if (nodeType.value === 'parent') {
|
|
194
|
+
if (!chartContainer.querySelector('.orgchart')) {
|
|
195
|
+
oc = new OrgChart({
|
|
196
|
+
chartContainer: '#chart-container',
|
|
159
197
|
'data' : { 'name': nodeVals[0] },
|
|
160
198
|
'chartClass': 'edit-state',
|
|
161
199
|
'exportButton': true,
|
|
162
200
|
'exportFilename': 'SportsChart',
|
|
163
|
-
'createNode': function(
|
|
164
|
-
|
|
201
|
+
'createNode': function(node) {
|
|
202
|
+
node.id = getId();
|
|
165
203
|
}
|
|
166
204
|
});
|
|
205
|
+
syncChartEditState();
|
|
167
206
|
} else {
|
|
168
|
-
oc.addParent(
|
|
207
|
+
oc.addParent(selectedNode || rootNode, { 'name': nodeVals[0], 'id': getId() });
|
|
169
208
|
}
|
|
170
|
-
|
|
171
|
-
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
if (nodeType.value === 'siblings') {
|
|
212
|
+
if (selectedNode.id === rootNode.id) {
|
|
172
213
|
alert('You are not allowed to directly add sibling nodes to root node');
|
|
173
214
|
return;
|
|
174
215
|
}
|
|
175
|
-
oc.addSiblings(
|
|
176
|
-
|
|
177
|
-
|
|
216
|
+
oc.addSiblings(selectedNode, nodeVals.map((item) => ({
|
|
217
|
+
'name': item,
|
|
218
|
+
'relationship': '110',
|
|
219
|
+
'id': getId()
|
|
220
|
+
})));
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const childLevel = selectedNode.nextElementSibling;
|
|
225
|
+
if (!childLevel || !childLevel.classList.contains('nodes')) {
|
|
226
|
+
const relationship = nodeVals.length > 1 ? '110' : '100';
|
|
227
|
+
oc.addChildren(selectedNode, nodeVals.map((item) => ({
|
|
228
|
+
'name': item,
|
|
229
|
+
'relationship': relationship,
|
|
230
|
+
'id': getId()
|
|
231
|
+
})));
|
|
178
232
|
} else {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
} else {
|
|
185
|
-
oc.addSiblings($node.siblings('.nodes').find('.node:first'), nodeVals.map(function (item) {
|
|
186
|
-
return { 'name': item, 'relationship': '110', 'id': getId() };
|
|
187
|
-
}));
|
|
188
|
-
}
|
|
233
|
+
oc.addSiblings(childLevel.querySelector('.node'), nodeVals.map((item) => ({
|
|
234
|
+
'name': item,
|
|
235
|
+
'relationship': '110',
|
|
236
|
+
'id': getId()
|
|
237
|
+
})));
|
|
189
238
|
}
|
|
190
239
|
});
|
|
191
240
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (
|
|
241
|
+
document.getElementById('btn-delete-nodes').addEventListener('click', () => {
|
|
242
|
+
const rootNode = getRootNode();
|
|
243
|
+
if (!selectedNode) {
|
|
195
244
|
alert('Please select one node in orgchart');
|
|
196
245
|
return;
|
|
197
|
-
} else if ($node[0] === $('.orgchart').find('.node:first')[0]) {
|
|
198
|
-
if (!window.confirm('Are you sure you want to delete the whole chart?')) {
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
246
|
}
|
|
202
|
-
|
|
203
|
-
|
|
247
|
+
if (rootNode && selectedNode === rootNode && !window.confirm('Are you sure you want to delete the whole chart?')) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
oc.removeNodes(selectedNode);
|
|
251
|
+
clearSelection();
|
|
204
252
|
});
|
|
205
253
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
254
|
+
document.getElementById('btn-reset').addEventListener('click', () => {
|
|
255
|
+
chartContainer.querySelectorAll('.focused').forEach((element) => element.classList.remove('focused'));
|
|
256
|
+
clearSelection();
|
|
257
|
+
const inputs = newNodeList.querySelectorAll('input');
|
|
258
|
+
if (inputs.length) {
|
|
259
|
+
inputs[0].value = '';
|
|
260
|
+
}
|
|
261
|
+
Array.from(newNodeList.children).slice(1).forEach((item) => item.remove());
|
|
262
|
+
nodeTypePanel.querySelectorAll('input').forEach((input) => {
|
|
263
|
+
input.checked = false;
|
|
264
|
+
});
|
|
211
265
|
});
|
|
212
266
|
|
|
213
|
-
|
|
267
|
+
});
|
|
214
268
|
</script>
|
|
215
269
|
</body>
|
|
216
270
|
</html>
|