├── .github ├── ISSUE_TEMPLATE │ ├── bug-report.yml │ ├── config.yml │ └── feature-request.yml └── workflows │ ├── commits.yml │ └── maven.yml ├── .gitignore ├── LICENSE.txt ├── README.md ├── assembly ├── MANIFEST.MF └── assembly.xml ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── flowingcode │ │ └── vaadin │ │ └── addons │ │ └── orgchart │ │ ├── OrgChart.java │ │ ├── OrgChartItem.java │ │ ├── client │ │ ├── OrgChartState.java │ │ ├── constants │ │ │ └── ChartConstants.java │ │ └── enums │ │ │ └── ChartDirectionEnum.java │ │ └── extra │ │ └── TemplateLiteralRewriter.java └── resources │ └── META-INF │ ├── VAADIN │ └── package.properties │ ├── frontend │ └── fc-orgchart.js │ ├── native-image │ └── com.flowingcode.addons │ │ └── orgchart │ │ └── reflect-config.json │ └── resources │ └── frontend │ └── fc-orgchart-styles.css └── test ├── java └── com │ └── flowingcode │ └── vaadin │ └── addons │ ├── DemoLayout.java │ └── orgchart │ ├── BottomTopDemo.java │ ├── DemoView.java │ ├── DragAndDropExportDemo.java │ ├── HybridDataPropertyDemo.java │ ├── HybridEnhancedChartDemo.java │ ├── ImageInTitleDemo.java │ └── OrgchartDemoView.java └── resources └── META-INF └── resources ├── frontend └── styles │ └── orgchart │ ├── demo-styles.css │ ├── font-awesome.css │ └── hybrid-demo-styles.css └── images ├── 1.png ├── 10.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.png ├── 9.png ├── user.png └── users.png /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Please report issues related to OrgChart add-on here. 3 | body: 4 | - type: textarea 5 | id: problem-description 6 | attributes: 7 | label: Describe the bug 8 | description: A clear description of the issue you're experiencing. 9 | validations: 10 | required: true 11 | - type: textarea 12 | id: expected-behavior 13 | attributes: 14 | label: Expected behavior 15 | description: A clear and concise description of the expected behavior. 16 | validations: 17 | required: false 18 | - type: textarea 19 | id: minimal-reproduction 20 | attributes: 21 | label: Minimal reproducible example 22 | description: If possible, add a concise code snippet that reproduces the issue and describe the steps needed to follow to reproduce it. 23 | validations: 24 | required: false 25 | - type: input 26 | id: addon-version 27 | attributes: 28 | label: Add-on Version 29 | description: The version of the add-on on which you're experiencing the issue. 30 | validations: 31 | required: true 32 | - type: input 33 | id: vaadin-version 34 | attributes: 35 | label: Vaadin Version 36 | description: The complete Vaadin version (X.Y.Z) on which the issue is reproducible. 37 | validations: 38 | required: true 39 | - type: textarea 40 | id: additional-information 41 | attributes: 42 | label: Additional information 43 | description: "Any other context/information about the issue can be added here (browser, OS, etc.)." 44 | validations: 45 | required: false 46 | 47 | 48 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Please add feature suggestions related to OrgChart add-on here. 3 | body: 4 | - type: textarea 5 | id: feature-proposal 6 | attributes: 7 | label: Feature proposal 8 | description: A concise but detailed description of the feature that you would like to see in the add-on. 9 | validations: 10 | required: true 11 | - type: textarea 12 | id: feature-implementation 13 | attributes: 14 | label: Describe solution expectations 15 | description: Do you have an idea/expectations of how it could be implemented? Did you try a possible solution that you want to share? 16 | validations: 17 | required: false 18 | - type: textarea 19 | id: additional-information 20 | attributes: 21 | label: Additional information 22 | description: Add any extra information you think it might be relevant to the request. 23 | validations: 24 | required: false 25 | -------------------------------------------------------------------------------- /.github/workflows/commits.yml: -------------------------------------------------------------------------------- 1 | name: Check Commits 2 | 3 | on: 4 | pull_request: 5 | 6 | jobs: 7 | check-commits: 8 | uses: FlowingCode/GithubActions/.github/workflows/check-commits.yml@main 9 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Java CI with Maven 10 | 11 | on: 12 | push: 13 | branches: [ "master" ] 14 | pull_request: 15 | branches: [ "master" ] 16 | 17 | jobs: 18 | build-vaadin14: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v4 22 | - name: Set up JDK 23 | uses: actions/setup-java@v3 24 | with: 25 | java-version: '8' 26 | distribution: 'temurin' 27 | cache: maven 28 | - name: Build (Vaadin 14) 29 | run: mvn -B package --file pom.xml 30 | 31 | build-vaadin23: 32 | runs-on: ubuntu-latest 33 | steps: 34 | - uses: actions/checkout@v4 35 | - name: Set up JDK 36 | uses: actions/setup-java@v3 37 | with: 38 | java-version: '11' 39 | distribution: 'temurin' 40 | cache: maven 41 | - name: Build (Vaadin 23) 42 | run: mvn -B package --file pom.xml -Pv23 43 | 44 | build-vaadin24: 45 | runs-on: ubuntu-latest 46 | steps: 47 | - uses: actions/checkout@v4 48 | - name: Set up JDK 49 | uses: actions/setup-java@v3 50 | with: 51 | java-version: '17' 52 | distribution: 'temurin' 53 | cache: maven 54 | - name: Build (Vaadin 24) 55 | run: mvn -B package --file pom.xml -Pv24 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /orgchart-addon/.project 2 | /orgchart-addon/.settings 3 | /orgchart-addon/target 4 | /orgchart-addon/.classpath 5 | /orgchart-addon-demo/.project 6 | /orgchart-addon-demo/.settings 7 | /orgchart-addon-demo/target 8 | /orgchart-addon-demo/.classpath 9 | /.project 10 | /.settings 11 | /target 12 | /package.json 13 | /webpack.config.js 14 | /webpack.generated.js 15 | /node_modules 16 | /package-lock.json 17 | /.classpath 18 | /node 19 | tsconfig.json 20 | types.d.ts -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Published on Vaadin Directory](https://img.shields.io/badge/Vaadin%20Directory-published-00b4f0.svg)](https://vaadin.com/directory/component/orgchart-add-on) 2 | [![Stars on vaadin.com/directory](https://img.shields.io/vaadin-directory/star/orgchart-add-on.svg)](https://vaadin.com/directory/component/orgchart-add-on) 3 | [![Build Status](https://jenkins.flowingcode.com/job/OrgChart-14-addon/badge/icon)](https://jenkins.flowingcode.com/job/OrgChart-14-addon/) 4 | [![Javadoc](https://img.shields.io/badge/javadoc-00b4f0)](https://javadoc.flowingcode.com/artifact/com.flowingcode.vaadin.addons/orgchart-addon) 5 | 6 | # OrgChart Add-On 7 | 8 | OrgChart Add-On is a Vaadin 14+ NPM mode integration of the library [OrgChart](https://github.com/dabeng/OrgChart). 9 | 10 | ## Features 11 | 12 | - Supported library features: 13 | - data, 14 | - pan, 15 | - zoom, 16 | - zoominLimit, 17 | - zoomoutLimit, 18 | - direction, 19 | - verticalDepth, 20 | - depth, 21 | - toggleSiblingsResp, 22 | - nodeTitle, 23 | - nodeContent, 24 | - nodeTemplate 25 | - exportButton, 26 | - exportFilename, 27 | - exportFileextension (png & pdf) 28 | - Enable/disable expand/collapse feature 29 | - Add a chart title 30 | - Drag and Drop 31 | 32 | ## Online demo 33 | 34 | Try the add-on demo at http://addonsv14.flowingcode.com/orgchart 35 | 36 | ## Download release 37 | 38 | Official releases at Vaadin Directory https://vaadin.com/directory/component/orgchart-add-on 39 | 40 | ### Maven install 41 | 42 | Add the following dependencies in your pom.xml file: 43 | 44 | ```xml 45 | 46 | com.flowingcode.vaadin.addons 47 | orgchart-addon 48 | X.Y.Z 49 | 50 | ``` 51 | 52 | 53 | ```xml 54 | 55 | vaadin-addons 56 | https://maven.vaadin.com/vaadin-addons 57 | 58 | ``` 59 | 60 | For SNAPSHOT versions see [here](https://maven.flowingcode.com/snapshots/). 61 | 62 | 63 | ## Building and running demo 64 | 65 | - git clone repository 66 | - mvn clean install 67 | - cd demo 68 | - mvn jetty:run 69 | 70 | To see the demo, navigate to http://localhost:8080/ 71 | 72 | ## Release notes 73 | 74 | ### Version 2.0.0 75 | - Initial Version. This version allows to visualize an organizational chart and exported as a png or a pdf file. 76 | ### Version 2.0.1 77 | - Drag and Drop Version. This version allows to Drag and Drop OrgChart nodes. 78 | ### Version 2.0.2 79 | - Add support for node styling (e.g. change node colors) 80 | ### Version 2.0.3 81 | - Add support for [node templates](https://rawgit.com/dabeng/OrgChart/master/demo/custom-template.html) 82 | - Fix options chartDepth and chartVerticalDepth 83 | - Fix export support in IE 84 | - Update OrgChart library to version [2.1.3](https://github.com/dabeng/OrgChart/releases/tag/v2.1.3) 85 | - Update jackson-databind dependency because of security vulnerabilities [(#7)](https://github.com/FlowingCode/OrgChartAddon/issues/7) 86 | ### Version 2.0.4 87 | - Add support for click events [(#4)](https://github.com/FlowingCode/OrgChartAddon/issues/4) and tooltips in orgchart nodes [(#9)](https://github.com/FlowingCode/OrgChartAddon/issues/9) 88 | ### Version 4.0.0 89 | - Initial release for Vaadin 14+ (npm mode) 90 | 91 | ## Roadmap 92 | 93 | This component is developed as a hobby with no public roadmap or any guarantees of upcoming releases. That said, the following features are planned for upcoming releases: 94 | 95 | - Edition of the organization chart 96 | 97 | ## Issue tracking 98 | 99 | The issues for this add-on are tracked on its github.com page. All bug reports and feature requests are appreciated. 100 | 101 | ## Contributions 102 | 103 | Contributions are welcome, but there are no guarantees that they are accepted as such. 104 | 105 | As first step, please refer to our [Development Conventions](https://github.com/FlowingCode/DevelopmentConventions) page to find information about Conventional Commits & Code Style requeriments. 106 | 107 | Then, follow these steps for creating a contribution: 108 | 109 | - Fork this project. 110 | - Create an issue to this project about the contribution (bug or feature) if there is no such issue about it already. Try to keep the scope minimal. 111 | - Develop and test the fix or functionality carefully. Only include minimum amount of code needed to fix the issue. 112 | - For commit message, use [Conventional Commits](https://github.com/FlowingCode/DevelopmentConventions/blob/main/conventional-commits.md) to describe your change. 113 | - Send a pull request for the original project. 114 | - Comment on the original issue that you have implemented a fix for it. 115 | 116 | ## License & Author 117 | 118 | This add-on is distributed under Apache License 2.0. For license terms, see LICENSE.txt. 119 | 120 | OrgChart Add-On is written by Flowing Code S.A. 121 | 122 | Hybrid Demo uses [People icons created by Creartive - Flaticon](https://www.flaticon.com/free-icons/people) 123 | 124 | # Developer Guide 125 | 126 | ## Getting started 127 | 128 | Here is a simple example on how to try out the add-on component: 129 | 130 | ```java 131 | OrgChartItem item1 = new OrgChartItem(1, "Root item", "Root Level"); 132 | OrgChartItem item2 = new OrgChartItem(2, "Item 2", "Level 1"); 133 | OrgChartItem item3 = new OrgChartItem(3, "Item 3", "Level 1"); 134 | item1.setChildren(Arrays.asList(item2, item3)); 135 | 136 | OrgChart orgChart = new OrgChart(item1); 137 | orgChart.setChartTitle("A Title"); 138 | orgChart.setChartNodeContent("title"); 139 | orgChart.setChartExportButton(true); 140 | orgChart.setZoom(true); 141 | orgChart.setChartDraggable(true); 142 | 143 | // add to a layout 144 | VerticalLayout layout = new VerticalLayout(); 145 | layout.addComponent(orgChart); 146 | ``` 147 | 148 | ## Special configuration when using Spring 149 | 150 | By default, Vaadin Flow only includes ```com/vaadin/flow/component``` to be always scanned for UI components and views. For this reason, the addon might need to be whitelisted in order to display correctly. 151 | 152 | To do so, just add ```com.flowingcode``` to the ```vaadin.whitelisted-packages``` property in ```src/main/resources/application.properties```, like: 153 | 154 | ```vaadin.whitelisted-packages = com.vaadin,org.vaadin,com.flowingcode``` 155 | 156 | More information on Spring whitelisted configuration [here](https://vaadin.com/docs/latest/integrations/spring/configuration/#configure-the-scanning-of-packages). 157 | 158 | -------------------------------------------------------------------------------- /assembly/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Vaadin-Package-Version: 1 3 | Vaadin-Addon: ${project.build.finalName}.${project.packaging} 4 | Implementation-Vendor: ${organization.name} 5 | Implementation-Title: ${project.name} 6 | Implementation-Version: ${project.version} 7 | -------------------------------------------------------------------------------- /assembly/assembly.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | game-card 7 | 8 | 9 | zip 10 | 11 | 12 | 13 | false 14 | 15 | 16 | 17 | . 18 | 19 | LICENSE 20 | README.md 21 | 22 | 23 | 24 | target 25 | 26 | 27 | *.jar 28 | *.pdf 29 | 30 | 31 | *-demo.jar 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | assembly/MANIFEST.MF 41 | META-INF 42 | true 43 | 44 | 45 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | com.flowingcode.vaadin.addons 4 | orgchart-addon 5 | 5.2.1-SNAPSHOT 6 | OrgChart Add-on 7 | 8 | 9 | 14.9.8 10 | 11 | 1.8 12 | 1.8 13 | UTF-8 14 | UTF-8 15 | 16 | ${project.basedir}/drivers 17 | 18 | 9.4.36.v20210114 19 | 20 | 21 | Flowing Code S.A. 22 | https://www.flowingcode.com 23 | 24 | 25 | 26 | git://github.com/FlowingCode/orgchart-addon.git 27 | scm:git://github.com/FlowingCode/orgchart-addon.git 28 | scm:git:ssh://git@github.com:/FlowingCode/orgchart-addon.git 29 | OrgChart add-on for Vaadin 14+ 30 | 31 | 32 | 33 | 34 | flowingcode 35 | Flowing Code 36 | https://www.flowingcode.com 37 | 38 | 39 | 40 | 41 | 42 | Apache 2 43 | http://www.apache.org/licenses/LICENSE-2.0.txt 44 | repo 45 | 46 | 47 | 2017 48 | 49 | 50 | 51 | 52 | com.vaadin 53 | vaadin-bom 54 | pom 55 | import 56 | ${vaadin.version} 57 | 58 | 59 | 60 | 61 | 62 | 63 | central 64 | https://repo.maven.apache.org/maven2 65 | 66 | false 67 | 68 | 69 | 70 | Vaadin Directory 71 | https://maven.vaadin.com/vaadin-addons 72 | 73 | 74 | 75 | Vaadin prereleases 76 | https://maven.vaadin.com/vaadin-prereleases 77 | 78 | 79 | 80 | vaadin-snapshots 81 | https://oss.sonatype.org/content/repositories/vaadin-snapshots/ 82 | 83 | 84 | FlowingCode Releases 85 | https://maven.flowingcode.com/releases 86 | 87 | 88 | FlowingCode Snapshots 89 | https://maven.flowingcode.com/snapshots 90 | 91 | true 92 | 93 | 94 | false 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | Vaadin prereleases 103 | https://maven.vaadin.com/vaadin-prereleases 104 | 105 | 106 | vaadin-snapshots 107 | https://oss.sonatype.org/content/repositories/vaadin-snapshots/ 108 | false 109 | 110 | 111 | 112 | 113 | 114 | com.vaadin 115 | vaadin-core 116 | true 117 | 118 | 121 | 122 | com.vaadin.webjar 123 | * 124 | 125 | 126 | org.webjars.bowergithub.insites 127 | * 128 | 129 | 130 | org.webjars.bowergithub.polymer 131 | * 132 | 133 | 134 | org.webjars.bowergithub.polymerelements 135 | * 136 | 137 | 138 | org.webjars.bowergithub.vaadin 139 | * 140 | 141 | 142 | org.webjars.bowergithub.webcomponents 143 | * 144 | 145 | 146 | 147 | 148 | org.slf4j 149 | slf4j-simple 150 | test 151 | 152 | 153 | com.vaadin 154 | vaadin-testbench 155 | test 156 | 157 | 158 | org.webjars 159 | font-awesome 160 | 4.7.0 161 | test 162 | 163 | 164 | com.fasterxml.jackson.core 165 | jackson-databind 166 | 2.13.4.2 167 | 168 | 169 | com.flowingcode.vaadin.addons.demo 170 | commons-demo 171 | 3.6.0 172 | test 173 | 174 | 175 | 176 | 177 | jetty:run 178 | 179 | 180 | 181 | org.apache.maven.plugins 182 | maven-release-plugin 183 | 2.5.3 184 | 185 | 186 | org.apache.maven.plugins 187 | maven-deploy-plugin 188 | 2.8.2 189 | 190 | 191 | org.apache.maven.plugins 192 | maven-surefire-plugin 193 | 2.22.1 194 | 195 | false 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | org.codehaus.mojo 205 | license-maven-plugin 206 | 1.14 207 | 208 | apache_v2 209 | false 210 | 211 | **/font-awesome.css 212 | 213 | 214 | 215 | 216 | 217 | org.apache.maven.plugins 218 | maven-jar-plugin 219 | 3.1.2 220 | 221 | 222 | true 223 | 224 | false 225 | true 226 | 227 | 228 | 1 229 | 230 | 231 | 232 | 233 | 234 | com.vaadin 235 | vaadin-maven-plugin 236 | ${vaadin.version} 237 | 238 | 239 | 240 | prepare-frontend 241 | 242 | 243 | 244 | 245 | 246 | org.eclipse.jetty 247 | jetty-maven-plugin 248 | ${jetty.version} 249 | 250 | 3 251 | 253 | true 254 | 255 | jar 256 | 257 | 258 | 259 | src/main/resources/META-INF/resources 260 | src/test/resources/META-INF/resources 261 | 262 | 263 | 264 | 265 | src/main/resources/META-INF/resources 266 | src/test/resources/META-INF/resources 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | directory 277 | 278 | 279 | 280 | org.apache.maven.plugins 281 | maven-assembly-plugin 282 | 3.3.0 283 | 284 | false 285 | 286 | assembly/assembly.xml 287 | 288 | 289 | 290 | 291 | 292 | single 293 | 294 | install 295 | 296 | 297 | 298 | 299 | org.apache.maven.plugins 300 | maven-source-plugin 301 | 3.0.1 302 | 303 | 304 | attach-sources 305 | verify 306 | 307 | jar-no-fork 308 | 309 | 310 | 311 | 312 | 313 | 314 | org.apache.maven.plugins 315 | maven-javadoc-plugin 316 | 3.11.1 317 | 318 | 319 | attach-javadocs 320 | package 321 | 322 | jar 323 | 324 | 325 | 326 | 327 | true 328 | none 329 | true 330 | 331 | https://javadoc.io/doc/com.vaadin/vaadin-platform-javadoc/${vaadin.version} 332 | 333 | 334 | 335 | 336 | org.apache.maven.plugins 337 | maven-jar-plugin 338 | 3.1.2 339 | 340 | 341 | 342 | META-INF/VAADIN/config/flow-build-info.json 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | production 353 | 354 | true 355 | 356 | 357 | 358 | com.vaadin 359 | flow-server-production-mode 360 | 361 | 362 | 363 | 364 | 365 | 366 | com.vaadin 367 | vaadin-maven-plugin 368 | 369 | 370 | 371 | build-frontend 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | integration-tests 382 | 383 | 384 | 385 | org.eclipse.jetty 386 | jetty-maven-plugin 387 | ${jetty.version} 388 | 389 | 0 390 | 391 | jar 392 | 393 | ${project.artifactId} 394 | 8081 395 | 396 | 397 | 398 | start-jetty 399 | pre-integration-test 400 | 401 | start 402 | 403 | 404 | 405 | stop-jetty 406 | post-integration-test 407 | 408 | stop 409 | 410 | 411 | 412 | 413 | 414 | 415 | com.lazerycode.selenium 416 | driver-binary-downloader-maven-plugin 417 | 418 | 1.0.17 419 | 420 | 421 | true 422 | 423 | 424 | ${drivers.dir}/driver 425 | 426 | 427 | ${drivers.dir}/driver_zips 428 | 429 | 430 | ${project.basedir}/drivers.xml 431 | 432 | 433 | 434 | 435 | 436 | selenium 437 | 438 | 439 | 440 | 441 | 442 | 443 | org.apache.maven.plugins 444 | maven-failsafe-plugin 445 | 2.22.2 446 | 447 | 448 | 449 | integration-test 450 | verify 451 | 452 | 453 | 454 | 455 | false 456 | true 457 | 458 | 459 | 460 | ${webdriver.chrome.driver} 461 | 462 | 463 | 464 | 465 | 466 | maven-resources-plugin 467 | 3.1.0 468 | 469 | 470 | 473 | copy-test-to-classes 474 | process-test-classes 475 | 476 | copy-resources 477 | 478 | 479 | ${project.build.outputDirectory} 480 | 481 | 482 | ${project.build.testOutputDirectory} 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | demo-jar 495 | 496 | 497 | 498 | org.apache.maven.plugins 499 | maven-jar-plugin 500 | 501 | 502 | 503 | test-jar 504 | 505 | 506 | demo 507 | 508 | META-INF/resources/frontend/styles/shared-styles.css 509 | **/test/* 510 | **/integration/* 511 | **/DemoView.class 512 | **/DemoLayout.class 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | v23 524 | 525 | 23.3.5 526 | 11 527 | 11 528 | 529 | 530 | 531 | 532 | v24 533 | 534 | 24.3.20 535 | 17 536 | 17 537 | 11.0.12 538 | 539 | 540 | 541 | 542 | -------------------------------------------------------------------------------- /src/main/java/com/flowingcode/vaadin/addons/orgchart/OrgChart.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * #%L 3 | * OrgChart Add-on 4 | * %% 5 | * Copyright (C) 2017 - 2025 Flowing Code S.A. 6 | * %% 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * #L% 19 | */ 20 | package com.flowingcode.vaadin.addons.orgchart; 21 | 22 | 23 | import com.fasterxml.jackson.core.JsonProcessingException; 24 | import com.fasterxml.jackson.databind.ObjectMapper; 25 | import com.flowingcode.vaadin.addons.orgchart.client.OrgChartState; 26 | import com.vaadin.flow.component.AttachEvent; 27 | import com.vaadin.flow.component.ClientCallable; 28 | import com.vaadin.flow.component.ComponentEvent; 29 | import com.vaadin.flow.component.ComponentEventListener; 30 | import com.vaadin.flow.component.Tag; 31 | import com.vaadin.flow.component.dependency.CssImport; 32 | import com.vaadin.flow.component.dependency.JsModule; 33 | import com.vaadin.flow.component.dependency.NpmPackage; 34 | import com.vaadin.flow.component.html.Div; 35 | import com.vaadin.flow.shared.Registration; 36 | import java.util.List; 37 | import java.util.stream.Collectors; 38 | 39 | /** 40 | * OrgChart component definition.
41 | * Uses JQuery library OrgChart to show an organization chart.
42 | * More information about this library at https://github.com/dabeng/OrgChart 44 | * 45 | * @author pbartolo 46 | */ 47 | @SuppressWarnings("serial") 48 | @NpmPackage(value = "orgchart", version = "3.7.0") 49 | @NpmPackage(value = "html2canvas", version = "1.4.1") 50 | @NpmPackage(value = "jquery", version = "3.6.2") 51 | @JsModule("jquery/dist/jquery.js") 52 | @JsModule("orgchart/dist/js/jquery.orgchart.js") 53 | @CssImport("orgchart/dist/css/jquery.orgchart.min.css") 54 | @Tag("fc-orgchart") 55 | @JsModule("./fc-orgchart.js") 56 | @CssImport("./fc-orgchart-styles.css") 57 | @NpmPackage(value = "json-digger", version = "2.0.2") 58 | public class OrgChart extends Div { 59 | 60 | private OrgChartItem orgChartItem; 61 | 62 | private OrgChartState state = new OrgChartState(); 63 | 64 | public OrgChart(OrgChartItem orgChartItem) { 65 | super(); 66 | this.orgChartItem = orgChartItem; 67 | this.setValue(orgChartItem); 68 | String identifier = "orgchart" + this.hashCode(); 69 | this.setId(identifier); 70 | } 71 | 72 | @Override 73 | protected void onAttach(AttachEvent attachEvent) { 74 | super.onAttach(attachEvent); 75 | this.getElement() 76 | .executeJs( 77 | "this.initializeOrgChart($0,$1,$2)", 78 | convertToJsonObj(state), 79 | state.value, 80 | this.getId().get()); 81 | } 82 | 83 | /** 84 | * @deprecated This method is no longer needed. Initialization is done in {@link 85 | * #onAttach(AttachEvent)}. 86 | */ 87 | @Deprecated 88 | public void initializeChart() {} 89 | 90 | public void setValue(OrgChartItem orgChartItem) { 91 | String value = convertToJsonObj(orgChartItem); 92 | getState().value = value; 93 | } 94 | 95 | protected OrgChartState getState() { 96 | return this.state; 97 | } 98 | 99 | private String convertToJsonObj(Object orgChartItem) { 100 | String result = null; 101 | ObjectMapper mapper = new ObjectMapper(); 102 | try { 103 | result = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(orgChartItem); 104 | } catch (JsonProcessingException e) { 105 | e.printStackTrace(); 106 | } 107 | return result; 108 | } 109 | 110 | public void setChartNodeTitle(String chartNodeTitle) { 111 | getState().chartNodeTitle = chartNodeTitle; 112 | } 113 | 114 | public void setChartNodeContent(String chartNodeContent) { 115 | getState().chartNodeContent = chartNodeContent; 116 | } 117 | 118 | public void setChartDirection(String chartDirection) { 119 | getState().chartDirection = chartDirection; 120 | } 121 | 122 | public void setChartTitle(String chartTitle) { 123 | getState().chartTitle = chartTitle; 124 | } 125 | 126 | public void setChartZoom(Boolean chartZoom) { 127 | getState().chartZoom = chartZoom; 128 | } 129 | 130 | public void setChartExportButton(Boolean chartExportButton) { 131 | getState().chartExportButton = chartExportButton; 132 | } 133 | 134 | public void setChartExportFileName(String chartExportFileName) { 135 | getState().chartExportFileName = chartExportFileName; 136 | } 137 | 138 | public void setChartExportFileExtension(String chartExportFileExtension) { 139 | getState().chartExportFileExtension = chartExportFileExtension; 140 | } 141 | 142 | public void setChartPan(Boolean chartPan) { 143 | getState().chartPan = chartPan; 144 | } 145 | 146 | public void setChartZoominLimit(Double chartZoominLimit) { 147 | getState().chartZoominLimit = chartZoominLimit; 148 | } 149 | 150 | public void setChartZoomoutLimit(Double chartZoomoutLimit) { 151 | getState().chartZoomoutLimit = chartZoomoutLimit; 152 | } 153 | 154 | /** orgchart visibleLevel option */ 155 | public void setChartDepth(Integer chartDepth) { 156 | getState().chartDepth = chartDepth; 157 | } 158 | 159 | /** orgchart verticalLevel option */ 160 | public void setChartVerticalDepth(Integer chartVerticalDepth) { 161 | getState().chartVerticalDepth = chartVerticalDepth; 162 | } 163 | 164 | public void setChartToggleSiblingsResp(Boolean chartToggleSiblingsResp) { 165 | getState().chartToggleSiblingsResp = chartToggleSiblingsResp; 166 | } 167 | 168 | public void setChartExpandCollapse(Boolean chartExpandCollapse) { 169 | getState().chartExpandCollapse = chartExpandCollapse; 170 | } 171 | 172 | public void setChartDraggable(Boolean chartDraggable) { 173 | getState().chartDraggable = chartDraggable; 174 | } 175 | 176 | /** Returns latest value of the orgchart element. */ 177 | public OrgChartItem getOrgChartItem() { 178 | return orgChartItem; 179 | } 180 | 181 | /** 182 | * Fires event on node click. 183 | * 184 | * @param nodeId 185 | */ 186 | @ClientCallable 187 | public void onClick(String nodeId) { 188 | Integer clickedNodeId = Integer.valueOf(nodeId); 189 | OrgChartItem clickedItem = getById(clickedNodeId, orgChartItem); 190 | 191 | fireNodeClickEvent(clickedItem, true); 192 | } 193 | 194 | /** 195 | * Updates chart after drag and drop event. 196 | * 197 | * @param draggedNode 198 | * @param dragZone 199 | * @param dropZone 200 | */ 201 | @ClientCallable 202 | public void updateDraggedNode(String draggedNode, String dragZone, String dropZone) { 203 | 204 | Integer draggedNodeId = Integer.valueOf(draggedNode); 205 | 206 | OrgChartItem draggedItem = getById(draggedNodeId, orgChartItem); 207 | OrgChartItem oldParentItem = getById(Integer.valueOf(dragZone), orgChartItem); 208 | OrgChartItem newParentItem = getById(Integer.valueOf(dropZone), orgChartItem); 209 | 210 | // update old parent (remove item) 211 | List oldParentUpdated = 212 | oldParentItem.getChildren().stream() 213 | .filter(i -> !draggedNodeId.equals(i.getId())) 214 | .collect(Collectors.toList()); 215 | oldParentItem.setChildren(oldParentUpdated); 216 | 217 | // update new parent (add item) 218 | newParentItem.addChildren(draggedItem); 219 | 220 | fireDragAndDropEvent(draggedItem, true); 221 | } 222 | 223 | private OrgChartItem getById(Integer id, OrgChartItem item) { 224 | if (id.equals(item.getId())) { 225 | return item; 226 | } else { 227 | return getChildItemById(id, item.getChildren()); 228 | } 229 | } 230 | 231 | private OrgChartItem getChildItemById(Integer id, List children) { 232 | OrgChartItem result = null; 233 | for (int i = 0; i < children.size() && result == null; i++) { 234 | result = getById(id, children.get(i)); 235 | } 236 | return result; 237 | } 238 | 239 | /** 240 | * Sets the template generation function used to customize the internal structure of nodes. {@code 241 | * functionBody} is the body of a javascript function that recieves one parameter (the JSON 242 | * datasoure representing a node) and returns an HTML snippet. The name of this parameter is given 243 | * by {@code parameterName}. 244 | * 245 | *

Example: 246 | * setNodeTemplate("item","return ''+item.name+'';") 247 | * configures the following JS function as node template: 248 | * function(item) { return ''+item.name+''; } 249 | * {@linkplain OrgChartItem#setData(String, String) custom properties} are accessible 250 | * through {@code item.data}
251 | * 252 | * @param parameterName the name of the parameter of a javascript function 253 | * @param functionBody the body of a javascript function 254 | */ 255 | public void setNodeTemplate(String parameterName, String functionBody) { 256 | getState().nodeTemplateParam = parameterName; 257 | getState().nodeTemplate = functionBody; 258 | } 259 | 260 | /** 261 | * Adds a {@link DragAndDropEvent} listener to the component. 262 | * 263 | * @param listener the listener to be added. 264 | */ 265 | public void addDragAndDropListener(ComponentEventListener listener) { 266 | addListener(DragAndDropEvent.class, listener); 267 | } 268 | 269 | /** 270 | * Fires a {@link DragAndDropEvent}. 271 | * 272 | * @param draggedItem the item being dragged. 273 | */ 274 | protected void fireDragAndDropEvent(OrgChartItem draggedItem, boolean fromClient) { 275 | fireEvent(new DragAndDropEvent(this, draggedItem, fromClient)); 276 | } 277 | 278 | /** Event thrown when a node is dragged and dropped. */ 279 | public static class DragAndDropEvent extends ComponentEvent { 280 | 281 | private final OrgChartItem draggedItem; 282 | 283 | public DragAndDropEvent(OrgChart source, OrgChartItem draggedItem, boolean fromClient) { 284 | super(source, fromClient); 285 | this.draggedItem = draggedItem; 286 | } 287 | 288 | public OrgChartItem getDraggedItem() { 289 | return draggedItem; 290 | } 291 | 292 | public OrgChart getOrgChart() { 293 | return (OrgChart) source; 294 | } 295 | } 296 | 297 | public Registration addOnNodeClickListener(ComponentEventListener listener) { 298 | return addListener(NodeClickEvent.class, listener); 299 | } 300 | 301 | /** 302 | * Fires a {@link NodeClickEvent}. 303 | * 304 | * @param clickedItem the item being clicked. 305 | */ 306 | protected void fireNodeClickEvent(OrgChartItem clickedItem, boolean fromClient) { 307 | fireEvent(new NodeClickEvent(this, clickedItem, fromClient)); 308 | } 309 | 310 | /** Event thrown when a node is clicked. */ 311 | public static class NodeClickEvent extends ComponentEvent { 312 | 313 | private final OrgChartItem clickedItem; 314 | 315 | public NodeClickEvent(OrgChart source, OrgChartItem clickedItem, boolean fromClient) { 316 | super(source, fromClient); 317 | this.clickedItem = clickedItem; 318 | } 319 | 320 | public OrgChartItem getClickedItem() { 321 | return clickedItem; 322 | } 323 | 324 | public OrgChart getOrgChart() { 325 | return (OrgChart) source; 326 | } 327 | } 328 | 329 | /** Collapses all nodes except the root */ 330 | public void setCollapsedNodes() { 331 | setChartDepth(1); 332 | } 333 | } 334 | -------------------------------------------------------------------------------- /src/main/java/com/flowingcode/vaadin/addons/orgchart/OrgChartItem.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * #%L 3 | * OrgChart Add-on 4 | * %% 5 | * Copyright (C) 2017 - 2025 Flowing Code S.A. 6 | * %% 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * #L% 19 | */ 20 | package com.flowingcode.vaadin.addons.orgchart; 21 | 22 | 23 | import java.io.Serializable; 24 | import java.util.ArrayList; 25 | import java.util.Collections; 26 | import java.util.HashMap; 27 | import java.util.List; 28 | import java.util.Map; 29 | import java.util.Optional; 30 | 31 | import com.fasterxml.jackson.annotation.JsonProperty; 32 | 33 | /** @author pbartolo */ 34 | @SuppressWarnings("serial") 35 | public class OrgChartItem implements Serializable { 36 | 37 | private String name; 38 | 39 | private String title; 40 | 41 | private String className; 42 | 43 | private Integer id; 44 | 45 | private List children = new ArrayList<>(); 46 | 47 | private Map data; 48 | 49 | private boolean hybrid; 50 | 51 | public OrgChartItem(Integer id, String name, String title) { 52 | super(); 53 | this.id = id; 54 | this.name = name; 55 | this.title = title; 56 | } 57 | 58 | public OrgChartItem(OrgChartItem original) { 59 | OrgChartItem orgChartCopy = 60 | new OrgChartItem(original.getId(), original.getName(), original.getTitle()); 61 | for (OrgChartItem child : original.getChildren()) { 62 | orgChartCopy.addChildren(new OrgChartItem(child)); 63 | } 64 | } 65 | 66 | /** Return the map of {@linkplain #setData(String, String) custom properties}. */ 67 | public Map getData() { 68 | return Optional.ofNullable(data) 69 | .map(Collections::unmodifiableMap) 70 | .orElse(Collections.emptyMap()); 71 | } 72 | 73 | /** 74 | * Add or remove a custom property. 75 | * 76 | * @param name the name of the custom property 77 | * @param value the value of the custom property 78 | */ 79 | public void setData(String name, String value) { 80 | if (data == null) { 81 | data = new HashMap<>(); 82 | } 83 | if (value != null) { 84 | data.put(name, value); 85 | } else { 86 | data.remove(name); 87 | } 88 | } 89 | 90 | public String getName() { 91 | return name; 92 | } 93 | 94 | public void setName(String name) { 95 | this.name = name; 96 | } 97 | 98 | public Integer getId() { 99 | return id; 100 | } 101 | 102 | public void setId(Integer id) { 103 | this.id = id; 104 | } 105 | 106 | public String getTitle() { 107 | return title; 108 | } 109 | 110 | public void setTitle(String title) { 111 | this.title = title; 112 | } 113 | 114 | public String getClassName() { 115 | return className; 116 | } 117 | 118 | public void setClassName(String className) { 119 | this.className = className; 120 | } 121 | 122 | public List getChildren() { 123 | return children; 124 | } 125 | 126 | public void setChildren(List children) { 127 | if (this.children != children) { 128 | this.children = new ArrayList<>(children); 129 | } 130 | } 131 | 132 | public void addChildren(OrgChartItem item) { 133 | this.children.add(item); 134 | } 135 | 136 | /** 137 | * Indicates whether this item is a hybrid node. 138 | * A hybrid node arranges its descendant children vertically instead of 139 | * horizontally. 140 | * 141 | * @return {@code true} if this item is hybrid; {@code false} otherwise 142 | */ 143 | public boolean isHybrid() { 144 | return this.hybrid; 145 | } 146 | 147 | /** 148 | * Sets whether this item is a hybrid node. 149 | * When {@code true}, the item's descendant children will be arranged 150 | * vertically. 151 | * 152 | * @param hybrid {@code true} to mark this node as hybrid; {@code false} 153 | * otherwise 154 | */ 155 | @JsonProperty("isHybrid") 156 | public void setHybrid(boolean hybrid) { 157 | this.hybrid = hybrid; 158 | } 159 | 160 | @Override 161 | public int hashCode() { 162 | final int prime = 31; 163 | int result = 1; 164 | result = prime * result + ((id == null) ? 0 : id.hashCode()); 165 | return result; 166 | } 167 | 168 | @Override 169 | public boolean equals(Object obj) { 170 | if (this == obj) return true; 171 | if (obj == null) return false; 172 | if (getClass() != obj.getClass()) return false; 173 | OrgChartItem other = (OrgChartItem) obj; 174 | if (id == null) { 175 | if (other.id != null) return false; 176 | } else if (!id.equals(other.id)) return false; 177 | return true; 178 | } 179 | 180 | @Override 181 | public String toString() { 182 | StringBuilder sb = new StringBuilder(); 183 | printChildren(this, sb, 0); 184 | return sb.toString(); 185 | } 186 | 187 | private void printChildren(OrgChartItem item, StringBuilder sb, int count) { 188 | String tabs = count > 0 ? String.format("%-" + count + "s", "").replace(' ', '\t') : ""; 189 | sb.append(tabs + item.getName() + "\n"); 190 | count++; 191 | for (int i = 0; i < item.getChildren().size(); i++) { 192 | printChildren(item.getChildren().get(i), sb, count); 193 | } 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /src/main/java/com/flowingcode/vaadin/addons/orgchart/client/OrgChartState.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * #%L 3 | * OrgChart Add-on 4 | * %% 5 | * Copyright (C) 2017 - 2025 Flowing Code S.A. 6 | * %% 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * #L% 19 | */ 20 | package com.flowingcode.vaadin.addons.orgchart.client; 21 | 22 | 23 | import com.flowingcode.vaadin.addons.orgchart.client.constants.ChartConstants; 24 | import com.flowingcode.vaadin.addons.orgchart.client.enums.ChartDirectionEnum; 25 | import java.io.Serializable; 26 | 27 | /** @author pbartolo */ 28 | @SuppressWarnings("serial") 29 | public class OrgChartState implements Serializable { 30 | 31 | public String value; 32 | 33 | public String chartTitle; 34 | 35 | public String chartNodeContent; 36 | 37 | public String chartNodeTitle = ChartConstants.CHART_NODE_TITLE_DEFAULT; 38 | 39 | public String chartDirection = 40 | ChartDirectionEnum.TOP_TO_BOTTOM.getAbreviation(); // default value in the library 41 | 42 | public Boolean chartZoom = false; 43 | 44 | public Boolean chartPan = false; 45 | 46 | public Double chartZoominLimit = ChartConstants.CHART_ZOOM_IN_LIMIT_DEFAULT; 47 | 48 | public Double chartZoomoutLimit = ChartConstants.CHART_ZOOM_OUT_LIMIT_DEFAULT; 49 | 50 | public Boolean chartExportButton = false; 51 | 52 | public String chartExportFileName = ChartConstants.DEFAULT_CHART_EXPORT_FILENAME; 53 | 54 | public String chartExportFileExtension = 55 | ChartConstants.CHART_EXPORT_EXTENSION_PNG; // default value in the library 56 | 57 | public Boolean chartToggleSiblingsResp = false; 58 | 59 | public Integer chartDepth = ChartConstants.CHART_DEPTH_DEFAULT; // orgchart visibleLevel option 60 | 61 | public Integer chartVerticalDepth; // orgchart verticalLevel options 62 | 63 | public Boolean chartExpandCollapse = false; 64 | 65 | public Boolean chartDraggable = 66 | false; // Note from library: this feature doesn't work on IE due to its poor support for HTML5 67 | // drag & drop 68 | 69 | public String chartNodeId = ChartConstants.CHART_NODE_ID_DEFAULT; 70 | 71 | public String nodeTemplate; 72 | 73 | public String nodeTemplateParam = "item"; 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/flowingcode/vaadin/addons/orgchart/client/constants/ChartConstants.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * #%L 3 | * OrgChart Add-on 4 | * %% 5 | * Copyright (C) 2017 - 2025 Flowing Code S.A. 6 | * %% 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * #L% 19 | */ 20 | package com.flowingcode.vaadin.addons.orgchart.client.constants; 21 | 22 | 23 | public interface ChartConstants { 24 | 25 | public static String DEFAULT_CHART_EXPORT_FILENAME = "OrgChart"; 26 | 27 | public static String CHART_EXPORT_EXTENSION_PNG = "png"; // default value in the library 28 | 29 | public static String CHART_EXPORT_EXTENSION_PDF = "pdf"; 30 | 31 | public static Double CHART_ZOOM_IN_LIMIT_DEFAULT = 7.0; 32 | 33 | public static Double CHART_ZOOM_OUT_LIMIT_DEFAULT = 0.5; 34 | 35 | public static Integer CHART_DEPTH_DEFAULT = 999; 36 | 37 | public static String CHART_NODE_TITLE_DEFAULT = "name"; 38 | 39 | public static String CHART_NODE_ID_DEFAULT = "id"; 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/flowingcode/vaadin/addons/orgchart/client/enums/ChartDirectionEnum.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * #%L 3 | * OrgChart Add-on 4 | * %% 5 | * Copyright (C) 2017 - 2025 Flowing Code S.A. 6 | * %% 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * #L% 19 | */ 20 | package com.flowingcode.vaadin.addons.orgchart.client.enums; 21 | 22 | 23 | /** 24 | * Enumeration of the directions that the organization chart can have.
25 | * Default one is "t2b = Top to Bottom". 26 | * 27 | * @author pbartolo 28 | */ 29 | public enum ChartDirectionEnum { 30 | TOP_TO_BOTTOM("t2b"), 31 | BOTTOM_TO_TOP("b2t"), 32 | LEFT_TO_RIGHT("l2r"), 33 | RIGHT_TO_LEFT("r2l"); 34 | 35 | private String abreviation; 36 | 37 | ChartDirectionEnum(String abreviation) { 38 | this.abreviation = abreviation; 39 | } 40 | 41 | public String getAbreviation() { 42 | return abreviation; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/flowingcode/vaadin/addons/orgchart/extra/TemplateLiteralRewriter.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * #%L 3 | * OrgChart Add-on 4 | * %% 5 | * Copyright (C) 2017 - 2025 Flowing Code S.A. 6 | * %% 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * #L% 19 | */ 20 | 21 | package com.flowingcode.vaadin.addons.orgchart.extra; 22 | 23 | /** 24 | * ES6 template literal parser that rewrites the literal as an ES5 expression. This class is 25 | * experimental and subject to change, with no guarantee of completeness (but it should work for 26 | * simple expressions). 27 | * 28 | * @author Javier Godoy / Flowing Code 29 | */ 30 | public class TemplateLiteralRewriter { 31 | 32 | // https://www.ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components 33 | 34 | public static String rewriteFunction(String s) { 35 | return "return " + rewrite(s) + ";"; 36 | } 37 | 38 | // rewrites an ES6 template literal as an ES5 expression 39 | public static String rewrite(String s) { 40 | StringBuilder sb = new StringBuilder(); 41 | sb.ensureCapacity(s.length() + 1); 42 | rewriteTemplate(s, 0, sb, true); 43 | return sb.toString(); 44 | } 45 | 46 | /** 47 | * Parse a Template literal in {@code s} starting at index {@code i} and rewrite it into {@code 48 | * sb}. 49 | * 50 | * @param s The ES6 template literal 51 | * @param i The index into {@code s} where the expression begins. 52 | * @param sb The result buffer 53 | * @throws IllegalArgumentException if the template literal is not closed with a backtick 54 | * @return the index of the closing backtick that ends the Template literal 55 | */ 56 | private static int rewriteTemplate(String s, int i, StringBuilder sb, boolean implicit) { 57 | int begin = i; 58 | sb.append('"'); 59 | // https://www.ecma-international.org/ecma-262/6.0/#sec-static-semantics-templatestrings 60 | outer: 61 | for (; i < s.length(); i++) { 62 | char c = s.charAt(i); 63 | switch (c) { 64 | case '"': 65 | // escape quotes in TemplateCharacters since we are using them for the string literals 66 | sb.append('\\').append('"'); 67 | break; 68 | case '\r': 69 | // The TV of TemplateCharacter :: LineTerminatorSequence is the TRV of 70 | // LineTerminatorSequence. 71 | // The TRV of LineTerminatorSequence :: is the sequence consisting of the code 72 | // unit value 0x000A. 73 | // The TRV of LineTerminatorSequence :: is the code unit value 0x000A. 74 | if (i < s.length() - 1 && s.charAt(i + 1) == '\n') { 75 | ++i; 76 | } 77 | // fallthrough 78 | case '\n': 79 | // The TRV of LineTerminatorSequence :: is the code unit value 0x000A. 80 | sb.append("\\n"); 81 | continue; 82 | case '\u2028': 83 | // The TRV of LineTerminatorSequence :: is the code unit value 0x2028. 84 | sb.append("\\u2028"); 85 | continue; 86 | case '\u2029': 87 | // The TRV of LineTerminatorSequence :: is the code unit value 0x2029. 88 | sb.append("\\u2029"); 89 | continue; 90 | case '\\': 91 | if (++i == s.length()) { 92 | throw new IllegalArgumentException("Unterminated escape sequence at index " + i); 93 | } 94 | c = s.charAt(i); 95 | if (c == '\r' || c == '\n' || c == '\u2028' || c == '\u2029') { 96 | if (i < s.length() - 1 && s.charAt(i + 1) == '\n') { 97 | ++i; 98 | } 99 | // LineTerminator :: | | | 100 | // The TV of LineContinuation :: \ LineTerminatorSequence is the empty code unit 101 | // sequence. 102 | continue; 103 | } else { 104 | // EscapeSequence 105 | sb.append('\\').append(c); 106 | continue; 107 | } 108 | case '$': 109 | { 110 | if (i == s.length() - 1 || s.charAt(i + 1) != '{') { 111 | // this was a dangling dollar sign 112 | sb.append(c); 113 | continue; 114 | } 115 | 116 | sb.append("\"+("); 117 | // expression substitution 118 | i = rewriteExpression(s, i + 2, sb); 119 | sb.append(")+\""); 120 | continue; 121 | } 122 | case '`': 123 | { 124 | if (implicit) { 125 | throw new IllegalArgumentException("Unexpected backtick at index " + i); 126 | } else { 127 | break outer; 128 | } 129 | } 130 | default: 131 | sb.append(c); 132 | } 133 | } 134 | 135 | if (!implicit && i >= s.length()) { 136 | throw new IllegalArgumentException("Unterminated template at index " + begin); 137 | } 138 | 139 | // end of Template 140 | sb.append('"'); 141 | return i; 142 | } 143 | 144 | /** 145 | * Parse a Expression in {@code s} starting at index {@code i} and rewrite it into {@code sb}. 146 | * 147 | * @param s The ES6 template literal 148 | * @param i The index into {@code s} where the expression begins. 149 | * @param sb The result buffer 150 | * @return the index where the corresponding TemplateSubstitutionTail starts. 151 | */ 152 | private static int rewriteExpression(String s, int i, StringBuilder sb) { 153 | int begin = i; 154 | 155 | if (begin == s.length()) { 156 | throw new IllegalArgumentException("Expected expression at index " + begin); 157 | } 158 | if (s.charAt(begin) == '}') { 159 | throw new IllegalArgumentException("Unexpected token } at index " + begin); 160 | } 161 | 162 | for (; i < s.length(); i++) { 163 | char c = s.charAt(i); 164 | switch (c) { 165 | case '}': 166 | // TemplateSubstitutionTail 167 | return i; 168 | case '`': 169 | // nested template literal 170 | sb.append("("); 171 | i = rewriteTemplate(s, i + 1, sb, false); 172 | sb.append(")"); 173 | continue; 174 | case '"': 175 | // fallthrough 176 | case '\'': 177 | int end = s.indexOf(c, i + 1); 178 | if (end < 0) 179 | throw new IllegalArgumentException("Unterminated string literal at index " + i); 180 | sb.append(s.substring(i, end)).append(c); 181 | i = end; 182 | continue; 183 | default: 184 | sb.append(c); 185 | } 186 | } 187 | 188 | throw new IllegalArgumentException("Expected TemplateSubstitutionTail at index " + begin); 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/VAADIN/package.properties: -------------------------------------------------------------------------------- 1 | vaadin.allowed-packages=com.flowingcode 2 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/frontend/fc-orgchart.js: -------------------------------------------------------------------------------- 1 | /*- 2 | * #%L 3 | * OrgChart Add-on 4 | * %% 5 | * Copyright (C) 2017 - 2025 Flowing Code S.A. 6 | * %% 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * #L% 19 | */ 20 | 21 | import {html, PolymerElement} from '@polymer/polymer/polymer-element.js'; 22 | import jQuery from "jquery"; 23 | import html2canvas from 'html2canvas'; 24 | import JSONDigger from "json-digger/dist/json-digger.js"; 25 | 26 | /** 27 | * `fc-orgchart` 28 | * 29 | * OrgChart element. 30 | * 31 | * @customElement 32 | * @polymer 33 | */ 34 | class FCOrgChart extends PolymerElement { 35 | 36 | initializeOrgChart(statestring,data,identifier) { 37 | var $ = window.jQuery || jQuery; 38 | var state = $.parseJSON(statestring); 39 | 40 | let exportChart = state.chartExportButton; 41 | let exportExt = state.chartExportFileExtension; 42 | if(exportChart & exportExt == "pdf"){ 43 | var src = "https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.debug.js"; 44 | var jsfile = $("