orgchart 5.0.0 → 7.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 +35 -0
- package/README.md +214 -123
- package/README.zh-cn.md +232 -100
- package/README.zh-tw.md +232 -100
- 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 +144 -94
- package/demo/edit-hybrid-chart.html +177 -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 +10 -3
- 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 +166 -112
- package/demo/option-createNode.html +28 -17
- package/demo/options-compact-drag.html +82 -0
- package/demo/options-export-navigation.html +76 -0
- package/demo/options-horizontal-template.html +80 -0
- package/demo/options-hybrid-navigation.html +71 -0
- 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} +154 -80
- package/dist/css/orgchart.min.css +1 -0
- package/dist/js/orgchart.js +4474 -0
- package/dist/js/orgchart.min.js +2 -0
- package/dist/js/orgchart.min.js.map +1 -0
- package/gulpfile.js +42 -27
- package/package.json +33 -32
- package/src/css/{jquery.orgchart.css → orgchart.css} +154 -80
- package/src/js/orgchart.js +4474 -0
- package/test/compatibility/README.md +123 -0
- package/test/compatibility/browser.tests.js +1279 -0
- package/test/compatibility/options.tests.js +628 -0
- package/test/cypress/e2e/demo-interactions.cy.js +91 -0
- package/test/cypress/e2e/demo-rendering.cy.js +161 -0
- package/test/cypress/e2e/drag-drop-hybrid-chart.cy.js +23 -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/local-datasource.cy.js +16 -16
- package/test/cypress/e2e/minimap.cy.js +66 -0
- package/test/cypress/e2e/ondemand-loading-data.cy.js +34 -10
- package/test/cypress/e2e/pan-zoom.cy.js +165 -0
- package/test/cypress/e2e/report-path.cy.js +20 -0
- package/test/cypress/e2e/toggle-sibs-resp.cy.js +4 -4
- package/test/cypress/e2e/vertical-vevel.cy.js +7 -5
- package/test/e2e/local-datasource/test.js +1 -1
- package/test/integration/init-tests.js +192 -99
- package/test/integration/tests.js +1043 -57
- package/test/unit/lifecycle-builders-export.tests.js +1487 -0
- package/test/unit/minimap.tests.js +210 -0
- package/test/unit/tests.js +2372 -253
- 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
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
describe('Demo Interactions', () => {
|
|
2
|
+
|
|
3
|
+
it('loads the ajax datasource after showing its loading state', () => {
|
|
4
|
+
cy.visit('demo/ajax-datasource.html');
|
|
5
|
+
cy.get('#chart-container .spinner').should('exist');
|
|
6
|
+
cy.get('#chart-container .node .title', { timeout: 6000 }).should('contain.text', 'Lao Lao');
|
|
7
|
+
cy.get('#chart-container .spinner').should('not.exist');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('centers the selected node', () => {
|
|
11
|
+
cy.visit('demo/center-on-selected-node.html');
|
|
12
|
+
cy.get('#chart-container .orgchart').invoke('css', 'transform').then((beforeTransform) => {
|
|
13
|
+
cy.contains('#chart-container .node .title', 'Su Miao').closest('.node').click();
|
|
14
|
+
cy.get('#chart-container .orgchart').should('not.have.css', 'transform', beforeTransform);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('starts configured branches collapsed and expands them', () => {
|
|
19
|
+
cy.visit('demo/default-collapsed.html');
|
|
20
|
+
cy.contains('#chart-container .node .title', 'Hei Hei').closest('.node').then(($node) => {
|
|
21
|
+
expect($node[0].nextElementSibling).to.have.class('hidden');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
cy.contains('#chart-container .node .title', 'Hei Hei').closest('.node').trigger('mouseenter').find('.bottomEdge').click();
|
|
25
|
+
cy.contains('#chart-container .node .title', 'Dan Dan').should('be.visible');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('adds a sibling in the editable hybrid chart', () => {
|
|
29
|
+
cy.visit('demo/edit-hybrid-chart.html');
|
|
30
|
+
cy.contains('#chart-container .node .title', 'Football').closest('.node').click();
|
|
31
|
+
cy.get('#new-nodelist .new-node').type('Futsal');
|
|
32
|
+
cy.get('#rd-sibling').click();
|
|
33
|
+
cy.get('#btn-add-nodes').click();
|
|
34
|
+
cy.contains('#chart-container .node .title', 'Futsal').should('exist');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('expands a selected branch to the configured depth', () => {
|
|
38
|
+
cy.visit('demo/expand-to-given-depth.html');
|
|
39
|
+
cy.contains('#chart-container .node .title', 'Su Miao').closest('.node').trigger('mouseenter').find('.bottomEdge').click();
|
|
40
|
+
cy.contains('#chart-container .node .title', 'Dan Zai').should('be.visible');
|
|
41
|
+
cy.contains('#chart-container .node .title', 'Er Dan Zai').should('not.be.visible');
|
|
42
|
+
cy.contains('#chart-container .node .title', 'AAA').should('not.be.visible');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('filters matching nodes and clears the filter result', () => {
|
|
46
|
+
cy.visit('demo/filter-node.html');
|
|
47
|
+
cy.get('#key-word').type('dan');
|
|
48
|
+
cy.get('#btn-filter-node').click();
|
|
49
|
+
cy.get('#chart-container .node.matched').should('have.length.at.least', 1);
|
|
50
|
+
cy.get('#chart-container .orgchart').should('have.class', 'noncollapsable');
|
|
51
|
+
cy.get('#btn-cancel').click();
|
|
52
|
+
cy.get('#chart-container .node.matched').should('not.exist');
|
|
53
|
+
cy.get('#chart-container .orgchart').should('not.have.class', 'noncollapsable');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('exports the current unordered-list hierarchy as JSON', () => {
|
|
57
|
+
cy.visit('demo/get-hierarchy.html');
|
|
58
|
+
cy.get('#btn-export-hier').click();
|
|
59
|
+
cy.get('pre').should('contain.text', 'n1').and('contain.text', 'n7');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('highlights and clears related nodes on hover', () => {
|
|
63
|
+
cy.visit('demo/get-related-nodes.html');
|
|
64
|
+
cy.contains('#chart-container .node .title', 'Hei Hei').closest('.node').trigger('mouseenter');
|
|
65
|
+
cy.get('#chart-container .highlight-parent').should('exist');
|
|
66
|
+
cy.get('#chart-container .highlight-siblings').should('exist');
|
|
67
|
+
cy.get('#chart-container .highlight-children').should('exist');
|
|
68
|
+
cy.contains('#chart-container .node .title', 'Hei Hei').closest('.node').trigger('mouseleave');
|
|
69
|
+
cy.get('#chart-container .highlight-parent, #chart-container .highlight-siblings, #chart-container .highlight-children').should('not.exist');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('toggles the custom secondary menu created for each node', () => {
|
|
73
|
+
cy.visit('demo/option-createNode.html');
|
|
74
|
+
cy.contains('#chart-container .node .title', 'Lao Lao').closest('.node').find('.second-menu-icon').click({ force: true });
|
|
75
|
+
cy.contains('#chart-container .node .title', 'Lao Lao').closest('.node').find('.second-menu').should('have.css', 'display', 'block');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('switches to a hybrid layout on a narrow viewport', () => {
|
|
79
|
+
cy.viewport(500, 720);
|
|
80
|
+
cy.visit('demo/responsive-design.html');
|
|
81
|
+
cy.window().trigger('resize');
|
|
82
|
+
cy.get('#chart-container .nodes.vertical').should('exist');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('renders all 10,000 generated nodes', () => {
|
|
86
|
+
cy.visit('demo/10000-nodes.html');
|
|
87
|
+
cy.get('#status', { timeout: 30000 }).should('contain.text', 'Initialization completed');
|
|
88
|
+
cy.get('#chart-container .node').should('have.length', 10000);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
});
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
describe('Demo Rendering and Configuration', () => {
|
|
2
|
+
|
|
3
|
+
const visitChartDemo = (page) => {
|
|
4
|
+
cy.visit('demo/' + page);
|
|
5
|
+
cy.get('#chart-container .orgchart').should('exist');
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
it('renders the bottom-to-top chart', () => {
|
|
9
|
+
visitChartDemo('bottom2top.html', 'Bottom to Top Demo');
|
|
10
|
+
cy.get('#chart-container .orgchart').should('have.class', 'b2t');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('renders color-coded node levels', () => {
|
|
14
|
+
visitChartDemo('color-coded.html', 'Color Coded Demo');
|
|
15
|
+
cy.get('#chart-container .node').filter('.middle-level, .product-dept, .rd-dept').should('exist');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('renders custom control icons', () => {
|
|
19
|
+
visitChartDemo('custom-icons.html', 'Custom Icons Demo');
|
|
20
|
+
cy.get('#chart-container .nodes.vertical .node').filter(':has(.parentNodeSymbol)').first().trigger('mouseenter');
|
|
21
|
+
cy.get('#chart-container .node .toggleBtn').should('have.class', 'fa-solid');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('renders the custom node template', () => {
|
|
25
|
+
visitChartDemo('custom-template.html', 'Custom Template Demo');
|
|
26
|
+
cy.get('#chart-container .node .office').should('exist');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('renders compact nodes from node data', () => {
|
|
30
|
+
visitChartDemo('data-prop-compact.html', 'Compact Nodes Demo');
|
|
31
|
+
cy.get('#chart-container .node.compact').should('exist');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('renders hybrid nodes from node data', () => {
|
|
35
|
+
visitChartDemo('data-prop-hybrid.html', 'Hybrid Nodes Demo');
|
|
36
|
+
cy.get('#chart-container .nodes.vertical').should('exist');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('renders the PNG export control', () => {
|
|
40
|
+
visitChartDemo('export-chart.html', 'Export Chart Demo');
|
|
41
|
+
cy.get('.oc-export-btn').should('be.visible');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('renders the PDF export control', () => {
|
|
45
|
+
visitChartDemo('export-chart-pdf.html', 'Export PDF Demo');
|
|
46
|
+
cy.get('.oc-export-btn').should('be.visible');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('renders the picture export control and avatars', () => {
|
|
50
|
+
visitChartDemo('export-chart-with-pictures.html', 'Export Chart with Pictures Demo');
|
|
51
|
+
cy.get('.oc-export-btn').should('be.visible');
|
|
52
|
+
cy.get('#chart-container .avatar').should('exist');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('renders the family-tree relationship layout', () => {
|
|
56
|
+
visitChartDemo('family-tree.html', 'Family Tree Demo');
|
|
57
|
+
cy.get('#chart-container .node').should('have.length.at.least', 3);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('renders family-tree custom properties', () => {
|
|
61
|
+
visitChartDemo('familytree-custom-properties.html', 'Family Tree Custom Properties Demo');
|
|
62
|
+
cy.get('#chart-container .node').should('have.length.at.least', 3);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('renders the left-to-right chart', () => {
|
|
66
|
+
visitChartDemo('left2right.html', 'Left to Right Demo');
|
|
67
|
+
cy.get('#chart-container .orgchart').should('have.class', 'l2r');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('renders link nodes', () => {
|
|
71
|
+
visitChartDemo('link-node.html', 'Link Nodes Demo');
|
|
72
|
+
cy.get('#chart-container .node').should('have.length.at.least', 2);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('renders nodes with different widths', () => {
|
|
76
|
+
visitChartDemo('nodes-of-different-widths.html', 'Nodes of Different Widths Demo');
|
|
77
|
+
cy.get('#chart-container .node').then(($nodes) => {
|
|
78
|
+
const widths = Array.from($nodes, (node) => node.getBoundingClientRect().width);
|
|
79
|
+
|
|
80
|
+
expect(new Set(widths).size).to.be.greaterThan(1);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('renders the right-to-left chart', () => {
|
|
85
|
+
visitChartDemo('right2left.html', 'Right to Left Demo');
|
|
86
|
+
cy.get('#chart-container .orgchart').should('have.class', 'r2l');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('combines hybrid layout, initial depth and minimap navigation', () => {
|
|
90
|
+
visitChartDemo('options-hybrid-navigation.html');
|
|
91
|
+
cy.get('#chart-container .node').should('have.length', 14);
|
|
92
|
+
cy.get('#chart-container .nodes.vertical').should('exist');
|
|
93
|
+
cy.get('#api').should('not.be.visible');
|
|
94
|
+
cy.get('#chart-container .orgchart-minimap-node').should('have.length.at.least', 1);
|
|
95
|
+
cy.get('#services').trigger('mouseenter');
|
|
96
|
+
cy.get('#services .toggleBtn').click({ force: true });
|
|
97
|
+
cy.get('#api').should('be.visible');
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('combines compact layout with constrained team assignments', () => {
|
|
101
|
+
visitChartDemo('options-compact-drag.html');
|
|
102
|
+
cy.get('#chart-container .node.compact').should('exist');
|
|
103
|
+
cy.get('#studio').trigger('mouseenter');
|
|
104
|
+
cy.get('#studio > .backToLooseSymbol').click();
|
|
105
|
+
cy.get('#engineering-team').trigger('mouseenter');
|
|
106
|
+
cy.get('#engineering-team > .backToLooseSymbol').click();
|
|
107
|
+
cy.get('#member-tie').should('have.attr', 'draggable', 'true');
|
|
108
|
+
cy.window().then((win) => {
|
|
109
|
+
const dataTransfer = new win.DataTransfer();
|
|
110
|
+
cy.get('#member-tie').then(($node) => {
|
|
111
|
+
$node[0].dispatchEvent(new win.DragEvent('dragstart', { bubbles: true, dataTransfer }));
|
|
112
|
+
});
|
|
113
|
+
cy.get('#product-team').should('have.class', 'allowedDrop');
|
|
114
|
+
cy.get('#member-bo').should('not.have.class', 'allowedDrop');
|
|
115
|
+
cy.get('#studio').should('not.have.class', 'allowedDrop');
|
|
116
|
+
cy.get('#product-team').then(($node) => {
|
|
117
|
+
$node[0].dispatchEvent(new win.DragEvent('drop', { bubbles: true, dataTransfer }));
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
cy.get('#product-team #member-tie').should('exist');
|
|
121
|
+
cy.get('#engineering-team #member-tie').should('not.exist');
|
|
122
|
+
cy.get('#assignment-status').should('have.text', 'Tie Hua / Product');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('combines horizontal layout, custom fields, avatars and icons', () => {
|
|
126
|
+
visitChartDemo('options-horizontal-template.html');
|
|
127
|
+
cy.get('#chart-container .orgchart').should('have.class', 'l2r');
|
|
128
|
+
cy.get('#design-director').should('have.attr', 'data-office', 'Shanghai');
|
|
129
|
+
cy.get('#design-director .title').should('contain.text', 'Lao Lao');
|
|
130
|
+
cy.get('#design-director .content').should('have.text', 'Design director');
|
|
131
|
+
cy.get('#chart-container .avatar').should('have.length', 7);
|
|
132
|
+
cy.get('#experience-lead').trigger('mouseenter');
|
|
133
|
+
cy.get('#experience-lead > .edge').should('have.class', 'fa-solid');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('combines bottom-to-top layout, custom fields and PDF export', () => {
|
|
137
|
+
visitChartDemo('options-export-navigation.html');
|
|
138
|
+
cy.get('#chart-container .orgchart').should('have.class', 'b2t').and('have.class', 'delivery-chart');
|
|
139
|
+
cy.get('#delivery-director .title').should('have.text', 'Lao Lao');
|
|
140
|
+
cy.get('#west-manager').should('have.attr', 'data-region', 'west');
|
|
141
|
+
cy.get('#east-manager').should('have.attr', 'data-region', 'east');
|
|
142
|
+
cy.get('.oc-export-btn').should('be.visible').and('have.text', 'Export PDF');
|
|
143
|
+
cy.window().then((win) => {
|
|
144
|
+
expect(win.html2canvas).to.be.a('function');
|
|
145
|
+
expect(win.jspdf.jsPDF).to.be.a('function');
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('parses the unordered-list datasource', () => {
|
|
150
|
+
visitChartDemo('ul-datasource.html', 'UL Datasource Demo');
|
|
151
|
+
cy.contains('#chart-container .node .title', 'Lao Lao').should('exist');
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('renders the map integration page shell without requiring map tiles', () => {
|
|
155
|
+
cy.visit('demo/integrate-map.html');
|
|
156
|
+
cy.contains('h1', 'Map Integration Demo').should('be.visible');
|
|
157
|
+
cy.get('#map').should('exist');
|
|
158
|
+
cy.get('#chart-container').should('exist');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
describe('Hybrid Drag and Drop Chart', () => {
|
|
2
|
+
|
|
3
|
+
const sanDan = '.node:contains("San Dan")';
|
|
4
|
+
const sanYue = '.node:contains("San Yue")';
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
cy.visit('demo/drag-drop-hybrid-chart.html');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('recomputes vertical relationships after moving a nested branch', () => {
|
|
11
|
+
const dataTransfer = new DataTransfer();
|
|
12
|
+
|
|
13
|
+
cy.get(sanDan).trigger('dragstart', { dataTransfer, force: true });
|
|
14
|
+
cy.get(sanYue).trigger('drop', { dataTransfer, force: true });
|
|
15
|
+
|
|
16
|
+
cy.get(sanYue).should(($node) => {
|
|
17
|
+
expect($node.siblings('.nodes').find('.node:contains("San Dan")')).to.exist;
|
|
18
|
+
});
|
|
19
|
+
cy.get(sanYue).find('.toggleBtn').should('not.exist');
|
|
20
|
+
cy.get(sanYue).trigger('mouseenter').find('.toggleBtn').should('exist');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
});
|
|
@@ -31,6 +31,26 @@ describe('Edit Chart', () => {
|
|
|
31
31
|
});
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
+
it('add parent to a non-root node without changing its branch', () => {
|
|
35
|
+
cy.get(football).click();
|
|
36
|
+
cy.get(newNodes).eq(0).type('Indoor sports');
|
|
37
|
+
cy.get(parentRel).click();
|
|
38
|
+
cy.get(addBtn).click();
|
|
39
|
+
|
|
40
|
+
cy.get(ballgame).should(($root) => {
|
|
41
|
+
const rootChildNodes = $root[0].nextElementSibling;
|
|
42
|
+
const rootChildren = Array.from(rootChildNodes.children);
|
|
43
|
+
const localParentHierarchy = rootChildren.find((hierarchy) =>
|
|
44
|
+
hierarchy.querySelector(':scope > .node > .title').textContent === 'Indoor sports'
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
expect(rootChildren).to.have.length(3);
|
|
48
|
+
expect(localParentHierarchy.querySelector(':scope > .nodes > .hierarchy > .node > .title').textContent).to.equal('Football');
|
|
49
|
+
expect(rootChildren.map((hierarchy) => hierarchy.querySelector(':scope > .node > .title').textContent))
|
|
50
|
+
.to.include.members(['Indoor sports', 'Basketball', 'Volleyball']);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
34
54
|
it('add child nodes -- Futsal and Beach football', () => {
|
|
35
55
|
cy.get(football).click();
|
|
36
56
|
cy.get(newNodes).eq(0).type('Futsal');
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
describe('Level Offset', () => {
|
|
2
|
+
|
|
3
|
+
beforeEach(() => {
|
|
4
|
+
cy.visit('demo/level-offset.html');
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
it('applies the configured offset to the node and connector variables', () => {
|
|
8
|
+
cy.contains('.node .title', 'Hong Miao')
|
|
9
|
+
.closest('.node')
|
|
10
|
+
.should('have.css', 'margin-top', '140px')
|
|
11
|
+
.then(($node) => {
|
|
12
|
+
const nodeStyle = $node[0].style;
|
|
13
|
+
|
|
14
|
+
expect(nodeStyle.getPropertyValue('--top')).to.equal('-151px');
|
|
15
|
+
expect(nodeStyle.getPropertyValue('--height')).to.equal('149px');
|
|
16
|
+
expect(nodeStyle.getPropertyValue('--top-cross-point')).to.equal('-153px');
|
|
17
|
+
expect(nodeStyle.getPropertyValue('--height-cross-point')).to.equal('151px');
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
});
|
|
@@ -14,67 +14,67 @@ describe('Local Datasource', () => {
|
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
it('bottomEdge of root node works well', () => {
|
|
17
|
-
cy.get(laolao).find('.bottomEdge').click();
|
|
17
|
+
cy.get(laolao).trigger('mouseenter').find('.bottomEdge').click();
|
|
18
18
|
cy.get(bomiao).get(sumiao).get(hongmiao).should('not.be.visible');
|
|
19
19
|
|
|
20
|
-
cy.get(laolao).find('.bottomEdge').click();
|
|
20
|
+
cy.get(laolao).trigger('mouseenter').find('.bottomEdge').click();
|
|
21
21
|
cy.get(bomiao).get(sumiao).get(hongmiao).should('be.visible');
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
it('topEdge of sumiao node works well', () => {
|
|
25
|
-
cy.get(sumiao).find('.topEdge').click();
|
|
25
|
+
cy.get(sumiao).trigger('mouseenter').find('.topEdge').click();
|
|
26
26
|
cy.get(laolao).get(bomiao).get(hongmiao).should('not.be.visible');
|
|
27
27
|
|
|
28
|
-
cy.get(sumiao).find('.topEdge').click();
|
|
28
|
+
cy.get(sumiao).trigger('mouseenter').find('.topEdge').click();
|
|
29
29
|
cy.get(laolao).should('be.visible');
|
|
30
30
|
cy.get(bomiao).get(hongmiao).should('not.be.visible');
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
it('leftEdge of sumiao node works well', () => {
|
|
34
|
-
cy.get(sumiao).find('.leftEdge').click();
|
|
34
|
+
cy.get(sumiao).trigger('mouseenter').find('.leftEdge').click();
|
|
35
35
|
cy.get(bomiao).get(hongmiao).should('not.be.visible');
|
|
36
36
|
|
|
37
|
-
cy.get(sumiao).find('.leftEdge').click();
|
|
37
|
+
cy.get(sumiao).trigger('mouseenter').find('.leftEdge').click();
|
|
38
38
|
cy.get(bomiao).get(hongmiao).should('be.visible');
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
it('rightEdge of sumiao node works well', () => {
|
|
42
|
-
cy.get(sumiao).find('.rightEdge').click();
|
|
42
|
+
cy.get(sumiao).trigger('mouseenter').find('.rightEdge').click();
|
|
43
43
|
cy.get(bomiao).get(hongmiao).should('not.be.visible');
|
|
44
44
|
|
|
45
|
-
cy.get(sumiao).find('.rightEdge').click();
|
|
45
|
+
cy.get(sumiao).trigger('mouseenter').find('.rightEdge').click();
|
|
46
46
|
cy.get(bomiao).get(hongmiao).should('be.visible');
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
it('bottomEdge of sumiao node works well', () => {
|
|
50
|
-
cy.get(sumiao).find('.bottomEdge').click();
|
|
50
|
+
cy.get(sumiao).trigger('mouseenter').find('.bottomEdge').click();
|
|
51
51
|
cy.get(tiehua).get(heihei).get(pangpang).get(dandan).should('not.be.visible');
|
|
52
52
|
|
|
53
|
-
cy.get(sumiao).find('.bottomEdge').click();
|
|
53
|
+
cy.get(sumiao).trigger('mouseenter').find('.bottomEdge').click();
|
|
54
54
|
cy.get(tiehua).get(heihei).get(pangpang).should('be.visible');
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
it('topEdge of heihei node works well', () => {
|
|
58
|
-
cy.get(heihei).find('.topEdge').click();
|
|
58
|
+
cy.get(heihei).trigger('mouseenter').find('.topEdge').click();
|
|
59
59
|
cy.get(laolao).get(bomiao).get(sumiao).get(hongmiao).get(tiehua).get(pangpang).should('not.be.visible');
|
|
60
60
|
|
|
61
|
-
cy.get(heihei).find('.topEdge').click();
|
|
61
|
+
cy.get(heihei).trigger('mouseenter').find('.topEdge').click();
|
|
62
62
|
cy.get(sumiao).should('be.visible');
|
|
63
63
|
cy.get(laolao).should('not.be.visible');
|
|
64
64
|
});
|
|
65
65
|
|
|
66
66
|
it('horizontalEdge of heihei node works well', () => {
|
|
67
|
-
cy.get(heihei).find('.topEdge').click();
|
|
68
|
-
cy.get(heihei).find('.leftEdge').click();
|
|
67
|
+
cy.get(heihei).trigger('mouseenter').find('.topEdge').click();
|
|
68
|
+
cy.get(heihei).trigger('mouseenter').find('.leftEdge').click();
|
|
69
69
|
cy.get(sumiao).get(tiehua).get(pangpang).should('be.visible');
|
|
70
70
|
cy.get(laolao).should('not.be.visible');
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
it('horizontalEdge of pangpang node works well', () => {
|
|
74
|
-
cy.get(pangpang).find('.leftEdge').click();
|
|
74
|
+
cy.get(pangpang).trigger('mouseenter').find('.leftEdge').click();
|
|
75
75
|
cy.get(tiehua).get(heihei).get(dandan).should('not.be.visible');
|
|
76
76
|
|
|
77
|
-
cy.get(pangpang).find('.leftEdge').click();
|
|
77
|
+
cy.get(pangpang).trigger('mouseenter').find('.leftEdge').click();
|
|
78
78
|
cy.get(tiehua).get(heihei).should('be.visible');
|
|
79
79
|
});
|
|
80
80
|
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
describe('Minimap', () => {
|
|
2
|
+
|
|
3
|
+
const chart = '.orgchart';
|
|
4
|
+
const minimap = '.orgchart-minimap';
|
|
5
|
+
const minimapViewport = '.orgchart-minimap-viewport';
|
|
6
|
+
const parseMatrixScale = (transformValue) => {
|
|
7
|
+
const matrixMatch = /matrix\(([^)]+)\)/.exec(transformValue || '');
|
|
8
|
+
|
|
9
|
+
return matrixMatch ? Number.parseFloat(matrixMatch[1].split(',')[0]) : 1;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
cy.visit('demo/minimap.html');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('renders an overview and moves the chart when its viewport is dragged', () => {
|
|
17
|
+
cy.get(minimap).should('be.visible');
|
|
18
|
+
cy.get('.orgchart-minimap-node').should('have.length.at.least', 30);
|
|
19
|
+
cy.get(minimapViewport).should('be.visible');
|
|
20
|
+
|
|
21
|
+
cy.get(chart).invoke('css', 'transform').then((beforeTransform) => {
|
|
22
|
+
cy.get(minimapViewport).then(($viewport) => {
|
|
23
|
+
const viewport = $viewport[0];
|
|
24
|
+
const rect = viewport.getBoundingClientRect();
|
|
25
|
+
const startX = rect.left + (rect.width / 2);
|
|
26
|
+
const startY = rect.top + (rect.height / 2);
|
|
27
|
+
const win = viewport.ownerDocument.defaultView;
|
|
28
|
+
|
|
29
|
+
viewport.dispatchEvent(new win.MouseEvent('mousedown', {
|
|
30
|
+
bubbles: true,
|
|
31
|
+
cancelable: true,
|
|
32
|
+
clientX: startX,
|
|
33
|
+
clientY: startY
|
|
34
|
+
}));
|
|
35
|
+
viewport.ownerDocument.dispatchEvent(new win.MouseEvent('mousemove', {
|
|
36
|
+
bubbles: true,
|
|
37
|
+
clientX: startX + 20,
|
|
38
|
+
clientY: startY + 20
|
|
39
|
+
}));
|
|
40
|
+
viewport.ownerDocument.dispatchEvent(new win.MouseEvent('mouseup', { bubbles: true }));
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
cy.get(chart).should('not.have.css', 'transform', beforeTransform);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('zooms the main chart from the minimap wheel control', () => {
|
|
48
|
+
cy.get(chart).invoke('css', 'transform').then((beforeTransform) => {
|
|
49
|
+
cy.get(minimap).then(($minimap) => {
|
|
50
|
+
const minimapElement = $minimap[0];
|
|
51
|
+
const win = minimapElement.ownerDocument.defaultView;
|
|
52
|
+
|
|
53
|
+
minimapElement.dispatchEvent(new win.WheelEvent('wheel', {
|
|
54
|
+
bubbles: true,
|
|
55
|
+
cancelable: true,
|
|
56
|
+
deltaY: -1
|
|
57
|
+
}));
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
cy.get(chart).invoke('css', 'transform').then((afterTransform) => {
|
|
61
|
+
expect(parseMatrixScale(afterTransform)).to.be.greaterThan(parseMatrixScale(beforeTransform));
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
});
|
|
@@ -1,35 +1,59 @@
|
|
|
1
1
|
describe('Load data on-demand', () => {
|
|
2
2
|
|
|
3
|
-
const sumiao = '
|
|
4
|
-
const heihei = '
|
|
3
|
+
const sumiao = '#n1';
|
|
4
|
+
const heihei = '#n3';
|
|
5
5
|
|
|
6
6
|
beforeEach(() => {
|
|
7
7
|
cy.visit('demo/ondemand-loading-data.html');
|
|
8
8
|
});
|
|
9
9
|
|
|
10
10
|
it('load the descendants of hehei', () => {
|
|
11
|
-
cy.get(heihei).find('.bottomEdge').
|
|
11
|
+
cy.get(heihei).find('.bottomEdge, .request-control').should('not.exist');
|
|
12
|
+
cy.get(heihei).trigger('mouseenter').find('.request-children').click();
|
|
13
|
+
cy.get('#n5').should('exist');
|
|
14
|
+
cy.get(heihei).find('.request-control').should('not.exist');
|
|
12
15
|
cy.get(heihei).should(($node) => {
|
|
13
16
|
expect($node.siblings('.nodes').children('.hierarchy').length).to.equal(2);
|
|
14
17
|
expect($node.siblings('.nodes').children('.hierarchy').eq(0).find('.node:contains("Er Dan")')).to.exist;
|
|
15
18
|
});
|
|
19
|
+
cy.get(heihei).trigger('mouseenter').find('.bottomEdge').click();
|
|
20
|
+
cy.get('#n5').should('not.be.visible');
|
|
21
|
+
cy.get(heihei).find('.bottomEdge').click();
|
|
22
|
+
cy.get('#n5').should('be.visible');
|
|
16
23
|
});
|
|
17
24
|
|
|
18
25
|
it('load the ancestors of sumiao by expanding vertically', () => {
|
|
19
|
-
cy.get(sumiao).find('.
|
|
26
|
+
cy.get(sumiao).trigger('mouseenter').find('.request-parent').click();
|
|
27
|
+
cy.get('#n0').should('exist');
|
|
20
28
|
cy.get(sumiao).should(($node) => {
|
|
21
29
|
expect($node.closest('.nodes').siblings('.node:contains("Lao Lao")')).to.exist;
|
|
22
30
|
expect($node.closest('.hierarchy').siblings().length).to.equal(7);
|
|
23
31
|
});
|
|
24
32
|
});
|
|
25
33
|
|
|
26
|
-
it('
|
|
27
|
-
cy.get(sumiao).find('.
|
|
28
|
-
cy.get(sumiao).
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
it('shows both sibling loading buttons on hover without duplicating them', () => {
|
|
35
|
+
cy.get(sumiao).find('.request-siblings').should('not.exist');
|
|
36
|
+
cy.get(sumiao).trigger('mouseenter').trigger('mouseenter');
|
|
37
|
+
cy.get(sumiao).find('.request-siblings').should('have.length', 2);
|
|
38
|
+
cy.get(sumiao).find('.request-siblings-left .oci-chevron-left').should('be.visible');
|
|
39
|
+
cy.get(sumiao).find('.request-siblings-right .oci-chevron-right').should('be.visible');
|
|
40
|
+
cy.get(sumiao).trigger('mouseleave').find('.request-siblings').should('not.exist');
|
|
41
|
+
cy.get(sumiao).trigger('mouseenter').find('.request-siblings').should('have.length', 2);
|
|
42
|
+
});
|
|
32
43
|
|
|
44
|
+
['left', 'right'].forEach((side) => {
|
|
45
|
+
it('load the ancestors of sumiao by expanding horizontally from the ' + side, () => {
|
|
46
|
+
cy.clock();
|
|
47
|
+
cy.get(sumiao).trigger('mouseenter').find('.request-siblings-' + side).click();
|
|
48
|
+
cy.get(sumiao).find('.request-siblings').should('have.length', 2).and('be.disabled');
|
|
49
|
+
cy.tick(1000);
|
|
50
|
+
cy.get('#n0').should('exist');
|
|
51
|
+
cy.get(sumiao).find('.request-control').should('not.exist');
|
|
52
|
+
cy.get(sumiao).should(($node) => {
|
|
53
|
+
expect($node.closest('.nodes').siblings('.node:contains("Lao Lao")')).to.exist;
|
|
54
|
+
expect($node.closest('.hierarchy').siblings().length).to.equal(7);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
33
57
|
});
|
|
34
58
|
|
|
35
59
|
});
|