├── .gitignore ├── .prettierignore ├── .prettierrc.json ├── LICENSE ├── README.md ├── app ├── assets │ ├── info_icon.svg │ ├── logo-yFiles-about.svg │ ├── logo-yFiles.svg │ └── yworks-logo.svg ├── copy-license.js ├── favicon.ico ├── index.html ├── package.json ├── src │ ├── app.ts │ ├── knwl.ts │ ├── lodlabelstyle.ts │ └── popup.ts ├── style.css └── vite-env.d.ts ├── data ├── DBPedia.ttl └── loadData.js ├── doc └── screenshot.png ├── package.json ├── sample-database ├── package.json ├── src │ ├── index.js │ ├── ontology.js │ └── store.js ├── test │ ├── elements.test.js │ ├── knowledge.test.js │ ├── schema.test.js │ └── store.test.js └── vite.config.js ├── server ├── api.js ├── package.json └── service.js ├── tsconfig.json └── vite.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### JetBrains template 3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 4 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 5 | 6 | # User-specific stuff 7 | .idea/**/workspace.xml 8 | .idea/**/tasks.xml 9 | .idea/**/usage.statistics.xml 10 | .idea/**/dictionaries 11 | .idea/**/shelf 12 | 13 | # Generated files 14 | .idea/**/contentModel.xml 15 | 16 | # Sensitive or high-churn files 17 | .idea/**/dataSources/ 18 | .idea/**/dataSources.ids 19 | .idea/**/dataSources.local.xml 20 | .idea/**/sqlDataSources.xml 21 | .idea/**/dynamic.xml 22 | .idea/**/uiDesigner.xml 23 | .idea/**/dbnavigator.xml 24 | 25 | # Gradle 26 | .idea/**/gradle.xml 27 | .idea/**/libraries 28 | 29 | # Gradle and Maven with auto-import 30 | # When using Gradle or Maven with auto-import, you should exclude module files, 31 | # since they will be recreated, and may cause churn. Uncomment if using 32 | # auto-import. 33 | # .idea/modules.xml 34 | # .idea/*.iml 35 | # .idea/modules 36 | # *.iml 37 | # *.ipr 38 | 39 | # CMake 40 | cmake-build-*/ 41 | 42 | # Mongo Explorer plugin 43 | .idea/**/mongoSettings.xml 44 | 45 | # File-based project format 46 | *.iws 47 | 48 | # IntelliJ 49 | out/ 50 | 51 | # mpeltonen/sbt-idea plugin 52 | .idea_modules/ 53 | 54 | # JIRA plugin 55 | atlassian-ide-plugin.xml 56 | 57 | # Cursive Clojure plugin 58 | .idea/replstate.xml 59 | 60 | # Crashlytics plugin (for Android Studio and IntelliJ) 61 | com_crashlytics_export_strings.xml 62 | crashlytics.properties 63 | crashlytics-build.properties 64 | fabric.properties 65 | 66 | # Editor-based Rest Client 67 | .idea/httpRequests 68 | 69 | # Android studio 3.1+ serialized cache file 70 | .idea/caches/build_file_checksums.ser 71 | 72 | ### Node template 73 | # Logs 74 | logs 75 | *.log 76 | npm-debug.log* 77 | yarn-debug.log* 78 | yarn-error.log* 79 | lerna-debug.log* 80 | 81 | # Diagnostic reports (https://nodejs.org/api/report.html) 82 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 83 | 84 | # Runtime data 85 | pids 86 | *.pid 87 | *.seed 88 | *.pid.lock 89 | 90 | # Directory for instrumented libs generated by jscoverage/JSCover 91 | lib-cov 92 | 93 | # Coverage directory used by tools like istanbul 94 | coverage 95 | *.lcov 96 | 97 | # nyc test coverage 98 | .nyc_output 99 | 100 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 101 | .grunt 102 | 103 | # Bower dependency directory (https://bower.io/) 104 | bower_components 105 | 106 | # node-waf configuration 107 | .lock-wscript 108 | 109 | # Compiled binary addons (https://nodejs.org/api/addons.html) 110 | build/Release 111 | 112 | # Dependency directories 113 | node_modules/ 114 | jspm_packages/ 115 | 116 | # TypeScript v1 declaration files 117 | typings/ 118 | 119 | # TypeScript cache 120 | *.tsbuildinfo 121 | 122 | # Optional npm cache directory 123 | .npm 124 | 125 | # Optional eslint cache 126 | .eslintcache 127 | 128 | # Optional REPL history 129 | .node_repl_history 130 | 131 | # Output of 'npm pack' 132 | *.tgz 133 | 134 | # Yarn Integrity file 135 | .yarn-integrity 136 | 137 | # dotenv environment variables file 138 | .env 139 | .env.test 140 | 141 | # parcel-bundler cache (https://parceljs.org/) 142 | .cache 143 | 144 | # next.js build output 145 | .next 146 | 147 | # nuxt.js build output 148 | .nuxt 149 | 150 | # vuepress build output 151 | .vuepress/dist 152 | 153 | # Serverless directories 154 | .serverless/ 155 | 156 | # FuseBox cache 157 | .fusebox/ 158 | 159 | # DynamoDB Local files 160 | .dynamodb/ 161 | 162 | # Temporary merge files from mercurial 163 | *.orig 164 | 165 | # package lock files 166 | package-lock.json 167 | yarn.lock 168 | 169 | app/app/dist/ 170 | app/yfiles/ 171 | license.json 172 | live/ 173 | /app/database 174 | /dist/ 175 | app/assets/yfiles/ 176 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | *.html 2 | **/node_modules/ 3 | app/yfiles/** 4 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": false, 6 | "singleQuote": true, 7 | "endOfLine": "auto" 8 | } 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) yWorks GmbH 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ontology Visualizer 2 | 3 |  4 | 5 | This repository contains the sample application for the yFiles use case about 6 | an [Ontology Visualizer](https://www.yworks.com/use-case/visualizing-an-ontology). 7 | The app displays a sample ontology diagram that you can explore. 8 | 9 | ## See also 10 | 11 | - [Watch the introductory video](https://player.vimeo.com/video/389490579) of this app 12 | - [Read the article](https://www.yworks.com/use-case/visualizing-an-ontology) about an _Ontology Visualizer_ 13 | - [Learn more about yFiles](https://www.yworks.com/products/yfiles), the software library for visualizing, editing, and analyzing graphs 14 | 15 | If you have any questions or suggestions, email us at [consulting@yworks.com](mailto:consulting@yworks.com) 16 | or call [+49 7071 9709050](tel:+4970719709050). 17 | 18 | ## How to run this app 19 | 20 | You need a copy of the [yFiles for HTML](https://www.yworks.com/products/yfiles-for-html) diagramming library in order 21 | to run this application. You can download a free test version of yFiles in the 22 | [yWorks Customer Center](https://my.yworks.com/signup?product=YFILES_HTML_EVAL). 23 | 24 | Checkout this project, then extract the yFiles for HTML package to a directory next to it, e.g.: 25 | 26 | ``` 27 | documents 28 | |-- ontology-visualizer 29 | |-- yFiles-for-HTML-Complete-3.0-Evaluation 30 | ``` 31 | 32 | Afterward, enter the `ontology-visualizer` directory and run the usual commands 33 | 34 | ``` 35 | npm install 36 | ``` 37 | 38 | followed by 39 | 40 | ``` 41 | npm run load-data 42 | npm run start-server 43 | npm run dev 44 | ``` 45 | 46 | ## About 47 | 48 | This application is powered by [yFiles for HTML](https://www.yworks.com/products/yfiles-for-html), the powerful 49 | diagramming library. 50 | 51 | Turn your data into clear diagrams with the help of unequaled automatic diagram layout, use rich visualizations for your 52 | diagram elements, and give your users an intuitive interface for smooth interaction. 53 | 54 | You can learn more about the many features that come with yFiles 55 | on the [yFiles Features Overview](https://www.yworks.com/products/yfiles/features). 56 | 57 | If you want to try it for yourself, obtain a free test version of yFiles in the 58 | [yWorks Customer Center](https://my.yworks.com/signup?product=YFILES_HTML_EVAL). 59 | 60 | ## Contact 61 | 62 | If you have any questions or suggestions, email us at [consulting@yworks.com](mailto:consulting@yworks.com) 63 | or call [+49 7071 9709050](tel:+4970719709050). 64 | 65 | ## Data 66 | 67 | The app shows data from [DBpedia](http://dbpedia.org/ontology/) 68 | 69 | ## License 70 | 71 | The MIT License (MIT) 72 | 73 | Copyright (c) yWorks GmbH 74 | 75 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 76 | 77 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 78 | 79 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 80 | -------------------------------------------------------------------------------- /app/assets/info_icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/logo-yFiles-about.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/logo-yFiles.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/yworks-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 48 | -------------------------------------------------------------------------------- /app/copy-license.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copies the license.json file from the 'yfiles' dependency of the 'demos/package.json' file to the 'demos' directory. 3 | */ 4 | 5 | import * as fs from 'node:fs' 6 | import * as path from 'node:path' 7 | import { dirname } from 'node:path' 8 | import { fileURLToPath } from 'node:url' 9 | 10 | const __dirname = dirname(fileURLToPath(import.meta.url)) 11 | 12 | const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '/package.json'), 'utf8')) 13 | const yFilesTarFile = packageJson?.dependencies?.['@yfiles/yfiles'] 14 | const destDir = path.resolve(__dirname) 15 | 16 | if (!yFilesTarFile) { 17 | console.log( 18 | `\nyFiles license was NOT copied because the 'yfiles' dependency was not detected.` + 19 | `\nPlease add your own yFiles license to the demo.`, 20 | ) 21 | process.exit(1) 22 | } 23 | 24 | const licenseFile = path.join(__dirname, path.dirname(yFilesTarFile), 'license.json') 25 | if (!fs.existsSync(licenseFile)) { 26 | console.log( 27 | `\nyFiles license was NOT copied from '${licenseFile}' because the file does not exist.` + 28 | `\nPlease add your own yFiles license to the demo.`, 29 | ) 30 | process.exit(1) 31 | } 32 | 33 | if (!fs.existsSync(destDir)) { 34 | fs.mkdirSync(destDir) 35 | } 36 | 37 | fs.copyFile(licenseFile, path.join(destDir, 'license.json'), (err) => { 38 | if (err) { 39 | console.log( 40 | `\nyFiles license was NOT copied from '${licenseFile}'.` + 41 | `\nPlease add your own yFiles license to the demo.`, 42 | ) 43 | } else { 44 | console.log(`\nyFiles license was copied from '${licenseFile}'.`) 45 | } 46 | }) 47 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yWorks/ontology-visualizer/42d8c7844502de4e1a4d5977443eee9cc9711ea2/app/favicon.ico -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |null
to hide the pop-ups
206 | inputMode.keyboardInputMode.addKeyBinding('Escape', ModifierKeys.NONE, () => {
207 | this.graphComponent.currentItem = null
208 | })
209 | }
210 |
211 | updateNodePopupContent(nodePopup: HTMLPopupSupport, node: INode) {
212 | // get business data from node tag
213 | const id = node.tag
214 | this.knwl.getClass(id).then((data: any) => {
215 | // get all divs in the pop-up
216 | const divs = nodePopup.div.getElementsByTagName('div')
217 | for (let i = 0; i < divs.length; i++) {
218 | const div = divs.item(i)!
219 | if (div.hasAttribute('data-id')) {
220 | // if div has a 'data-id' attribute, get content from the business data
221 | const id = div.getAttribute('data-id')!
222 | const link = div.children[1] as HTMLLinkElement
223 | if (id === 'id') {
224 | //make a rather than text
225 | const short = this.toShortForm(data[id])
226 | link.href = `http://dbpedia.org/ontology/${short}`
227 | link.textContent = `dbpedia:${short}`
228 | } else {
229 | link.textContent = data[id]
230 | }
231 | }
232 | }
233 | })
234 | }
235 |
236 | updateEdgePopupContent(edgePopup: HTMLPopupSupport, edge: IEdge) {
237 | // get business data from node tags
238 | const edgeData = edge.tag
239 | const sourceData = edge.sourcePort.owner.tag
240 | const targetData = edge.targetPort.owner.tag
241 |
242 | const font = new Font(defaultFontFamily, 12)
243 | const size = new Size(200, 20)
244 | const wrapping = TextWrapping.WRAP_CHARACTER_ELLIPSIS
245 |
246 | const sourceText = edgePopup.div.querySelector('*[data-id="sourceName"]') as SVGTextElement
247 | TextRenderSupport.addText(sourceText, this.toShortForm(sourceData), font, size, wrapping)
248 | sourceText.setAttribute('title', this.toShortForm(sourceData))
249 |
250 | const linkText = edgePopup.div.querySelector('*[data-id="linkName"]') as SVGGElement
251 | const linkSize = new Size(170, 20)
252 | const linkFont = new Font(defaultFontFamily, 12, 'normal', 'bold')
253 | const linkShort = this.toShortForm(edgeData.uri)
254 | TextRenderSupport.addText(linkText, linkShort, linkFont, linkSize, wrapping)
255 | const linkAnchor = linkText.parentElement!
256 | linkAnchor.setAttribute('href', `http://dbpedia.org/ontology/${linkShort}`)
257 | linkText.setAttribute('title', linkShort)
258 |
259 | const targetText = edgePopup.div.querySelector('*[data-id="targetName"]') as SVGTextElement
260 | TextRenderSupport.addText(targetText, this.toShortForm(targetData), font, size, wrapping)
261 | targetText.setAttribute('title', this.toShortForm(targetData))
262 | }
263 |
264 | /**
265 | * Shortens the Uri to something one can display.
266 | */
267 | toShortForm(uri: any | Array