diff --git a/.jshintignore b/.jshintignore new file mode 100644 index 0000000000000000000000000000000000000000..cc2c713b191d0192f1e49267415e4e82f4f86b07 --- /dev/null +++ b/.jshintignore @@ -0,0 +1,7 @@ +webpack.config.js +deploy/** +Gruntfile.js +node_modules/** +src/webvowl/js/entry.js +src/app/js/entry.js +src/app/js/browserWarning.js diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000000000000000000000000000000000000..cecbcc9e433c1b78469f48f2978ea2f29fda56b8 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,20 @@ +{ + "globals": { + "d3": false, + "webvowl": false, + "module": false, + "require": false + }, + + "bitwise" : true, + "eqeqeq" : true, + "forin" : true, + "latedef" : "nofunc", + "noarg" : true, + "nonew" : true, + "undef" : true, + + "browser" : true, + "jasmine" : true, + "devel" : true +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..94c018971997256ab0c5e0fe8123370b1495b7b0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,60 @@ +########### +# WebVOWL # +########### + +# Stage 1: Build OWL2VOWL converter from source +FROM docker.io/maven:3-openjdk-8-slim AS owl2vowl-builder + +WORKDIR /owl2vowl + +# Clone and build OWL2VOWL WAR +RUN apt-get update && \ + apt-get install -y git && \ + git clone https://github.com/VisualDataWeb/OWL2VOWL.git . && \ + mvn clean package -P war-release -DskipTests + +# Stage 2: Build WebVOWL from source +FROM docker.io/node:12-alpine AS webvowl-builder + +WORKDIR /build + +# Copy package files +COPY package.json ./ +COPY Gruntfile.js ./ +COPY webpack.config.js ./ + +# Copy source code and configuration +COPY src ./src +COPY util ./util +COPY .jshintrc ./.jshintrc +COPY .jshintignore ./.jshintignore + +# Install dependencies and build +RUN npm install && \ + npm run release + +# Stage 3: Runtime - Deploy both to Tomcat +FROM docker.io/tomcat:9-jdk8-openjdk-slim + +# Remove default webapps +RUN rm -rf /usr/local/tomcat/webapps/* + +# First, deploy OWL2VOWL WAR as ROOT (this provides the servlets) +RUN mkdir -p /usr/local/tomcat/webapps/ROOT +COPY --from=owl2vowl-builder /owl2vowl/target/*.war /tmp/owl2vowl.war +RUN cd /usr/local/tomcat/webapps/ROOT && \ + jar -xf /tmp/owl2vowl.war && \ + rm /tmp/owl2vowl.war + +# Then, copy WebVOWL static files into the same ROOT context +# This merges the static frontend with the backend servlets +COPY --from=webvowl-builder /build/deploy /usr/local/tomcat/webapps/ROOT/ + +# Expose port 7860 (Hugging Face Spaces standard port) +EXPOSE 7860 + +# Configure Tomcat to listen on port 7860 instead of default 8080 +RUN sed -i 's/port="8080"/port="7860"/g' /usr/local/tomcat/conf/server.xml + +# Run Tomcat +CMD ["catalina.sh", "run"] \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000000000000000000000000000000000000..c5cbbef5a99627b026f4bea7398f94d4c51fbb27 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,179 @@ +"use strict"; + +module.exports = function (grunt) { + + require("load-grunt-tasks")(grunt); + var webpack = require("webpack"); + var webpackConfig = require("./webpack.config.js"); + + var deployPath = "deploy/"; + + // Project configuration. + grunt.initConfig({ + pkg: grunt.file.readJSON("package.json"), + bump: { + options: { + files: ["package.json"], + updateConfigs: ["pkg"], + commit: true, + commitMessage: "Bump version to %VERSION%", + commitFiles: ["package.json"], + createTag: false, + prereleaseName: "RC", + push: false + } + }, + clean: { + deploy: deployPath, + zip: "webvowl-*.zip", + testOntology: deployPath + "data/benchmark.json" + }, + compress: { + deploy: { + options: { + archive: function() { + var branchInfo = grunt.config("gitinfo.local.branch.current"); + return "webvowl-" + branchInfo.name + "-" + branchInfo.shortSHA + ".zip"; + }, + level: 9, + pretty: true + }, + files: [ + {expand: true, cwd: "deploy/", src: ["**"], dest: "webvowl/"} + ] + } + }, + connect: { + devserver: { + options: { + protocol: "http", + hostname: "localhost", + port: 8000, + base: deployPath, + directory: deployPath, + livereload: true, + open: "http://localhost:8000/", + middleware: function (connect, options, middlewares) { + return middlewares.concat([ + require("serve-favicon")("deploy/favicon.ico"), + require("serve-static")(options.base[0]) + ]); + } + } + } + }, + copy: { + dependencies: { + files: [ + {expand: true, cwd: "node_modules/d3/", src: ["d3.min.js"], dest: deployPath + "/js/"} + ] + }, + static: { + files: [ + {expand: true, cwd: "src/", src: ["favicon.ico"], dest: deployPath}, + {expand: true, src: ["license.txt"], dest: deployPath} + ] + } + }, + htmlbuild: { + options: { + beautify: true, + relative: true, + data: { + // Data to pass to templates + version: "<%= pkg.version %>" + } + }, + dev: { + src: "src/index.html", + dest: deployPath + }, + release: { + // required for removing the benchmark ontology from the selection menu + src: "src/index.html", + dest: deployPath + } + }, + jshint: { + options: { + jshintrc: true + }, + source: ["src/**/*.js"], + tests: ["test/*/**/*.js"] + }, + karma: { + options: { + configFile: "test/karma.conf.js" + }, + dev: {}, + continuous: { + singleRun: true + } + }, + replace: { + options: { + patterns: [ + { + match: "WEBVOWL_VERSION", + replacement: "<%= pkg.version %>" + } + ] + }, + dist: { + files: [ + {expand: true, cwd: "deploy/js/", src: "webvowl*.js", dest: "deploy/js/"} + ] + } + }, + webpack: { + options: webpackConfig, + build: { + plugins: webpackConfig.plugins.concat( + // minimize the deployed code + //new webpack.optimize.UglifyJsPlugin(), + new webpack.optimize.DedupePlugin() + + ) + }, + "build-dev": { + devtool: "sourcemap", + debug: true + } + }, + watch: { + configs: { + files: ["Gruntfile.js"], + options: { + reload: true + } + }, + js: { + files: ["src/app/**/*", "src/webvowl/**/*"], + tasks: ["webpack:build-dev", "post-js"], + options: { + livereload: true, + spawn: false + } + }, + html: { + files: ["src/**/*.html"], + tasks: ["htmlbuild:dev"], + options: { + livereload: true, + spawn: false + } + } + } + }); + + + grunt.registerTask("default", ["release"]); + grunt.registerTask("pre-js", ["clean:deploy", "clean:zip", "copy"]); + grunt.registerTask("post-js", ["replace"]); + grunt.registerTask("package", ["pre-js", "webpack:build-dev", "post-js", "htmlbuild:dev"]); + grunt.registerTask("release", ["pre-js", "webpack:build", "post-js", "htmlbuild:release", "clean:testOntology"]); + grunt.registerTask("zip", ["gitinfo", "release", "compress"]); + grunt.registerTask("webserver", ["package", "connect:devserver", "watch"]); + grunt.registerTask("test", ["karma:dev"]); + grunt.registerTask("test-ci", ["karma:continuous"]); +}; diff --git a/README.md b/README.md index 080f003154c5e739c3e8cd799e423a78af910c7f..10f6f221bf8667410bbb7fb60467e4913c7e5a32 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,59 @@ ---- -title: Webvowl -emoji: 😻 -colorFrom: yellow -colorTo: gray -sdk: docker -pinned: false ---- - -Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference +WebVOWL [![Build Status](https://travis-ci.org/VisualDataWeb/WebVOWL.svg?branch=master)](https://travis-ci.org/VisualDataWeb/WebVOWL) +======= + +> [!CAUTION] +> The URL https://visualdataweb.org/ is not owned bei VisualDataWeb anymore! Not related to WebVOWL anymore. + +This repository was ported from an internal SVN repository to Github after the release of WebVOWL 0.4.0. Due to cleanups with `git filter-branch`, the commit history might show some strange effects. + +Run Using Docker +------------ +Make sure you are inside `WebVOWL` directory and you have docker installed. Run the following command to build the docker image: + +`docker build . -t webvowl:v1` + +Run the following command to run WebVOWL at port 8080. + +`docker-compose up -d` + +Visit [http://localhost:8080](http://localhost:8080) to use WebVOWL. + +Requirements +------------ + +Node.js for installing the development tools and dependencies. + + +Development setup +----------------- + +### Simple ### +1. Download and install Node.js from http://nodejs.org/download/ +2. Open the terminal in the root directory +3. Run `npm install` to install the dependencies and build the project +4. Edit the code +5. Run `npm run-script release` to (re-)build all necessary files into the deploy directory +6. Run `serve deploy/` to run the server locally, by installing serve by using `npm install serve -g`. + +Visit [http://localhost:3000](http://localhost:3000) to use WebVOWL. + +### Advanced ### +Instead of the last step of the simple setup, install the npm package `grunt-cli` globally with +`npm install grunt-cli -g`. Now you can execute a few more advanced commands in the terminal: + +* `grunt` or `grunt release` builds the release files into the deploy directory +* `grunt package` builds the development version +* `grunt webserver` starts a local live-updating webserver with the current development version +* `grunt test` starts the test runner +* `grunt zip` builds the project and puts it into a zip file + + +Additional information +---------------------- + +To export the VOWL visualization to an SVG image, all css styles have to be included into the SVG code. +This means that if you change the CSS code in the `vowl.css` file, you also have to update the code that +inlines the styles - otherwise the exported SVG will not look the same as the displayed graph. + +The tool which creates the code that inlines the styles can be found in the util directory. Please +follow the instructions in its [README](util/VowlCssToD3RuleConverter/README.md) file. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..e2ddc71de7a5d2313fb796b111276840399e3184 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,9 @@ +version: '3' + +services: + + server: + build: . + command: catalina.sh run + ports: + - 8080:8080 \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000000000000000000000000000000000000..f01b936d8dc7a38a1f87b87f8b78a3a866843e1c --- /dev/null +++ b/package.json @@ -0,0 +1,51 @@ +{ + "name": "webvowl", + "version": "1.1.7", + "dependencies": { + "d3": "^3.5.6", + "grunt-cli": "^1.3.2", + "lodash": "^4.1.0" + }, + "devDependencies": { + "connect-livereload": "^0.6.0", + "copy-webpack-plugin": "^4.0.1", + "css-loader": "^0.26.0", + "extract-text-webpack-plugin": "^1.0.1", + "grunt": "^1.0.1", + "grunt-bump": "^0.8.0", + "grunt-contrib-clean": "^1.0.0", + "grunt-contrib-compress": "^1.2.0", + "grunt-contrib-connect": "^1.0.1", + "grunt-contrib-copy": "^1.0.0", + "grunt-contrib-jshint": "^1.0.0", + "grunt-contrib-watch": "^1.0.0", + "grunt-gitinfo": "^0.1.8", + "grunt-html-build": "^0.6.0", + "grunt-karma": "^2.0.0", + "grunt-replace": "^1.0.1", + "grunt-webpack": "^1.0.11", + "jasmine-core": "^2.2.0", + "karma": "^1.3.0", + "karma-commonjs": "^1.0.0", + "karma-jasmine": "^1.0.2", + "karma-phantomjs-launcher": "^1.0.0", + "karma-spec-reporter": "0.0.26", + "karma-webpack": "^1.7.0", + "load-grunt-tasks": "^3.2.0", + "phantomjs-prebuilt": "^2.1.4", + "serve-favicon": "^2.3.0", + "serve-static": "^1.10.0", + "style-loader": "^0.13.0", + "webpack": "^1.12.0", + "webpack-dev-server": "^1.12.0" + }, + "scripts": { + "postinstall": "grunt release", + "package": "grunt package", + "release": "grunt release", + "test": "grunt test-ci", + "webserver": "grunt webserver" + }, + "license": "MIT", + "private": true +} diff --git a/src/app/css/toolstyle.css b/src/app/css/toolstyle.css new file mode 100644 index 0000000000000000000000000000000000000000..9caec37a20fad8d62c43cf02b37dc2e68eee1e3d --- /dev/null +++ b/src/app/css/toolstyle.css @@ -0,0 +1,2479 @@ +@import url(http://fonts.googleapis.com/css?family=Open+Sans); + +/*---------------------------------------------- + WebVOWL page +----------------------------------------------*/ +html { + -ms-content-zooming: none; +} + + + +#loading-progress { + width: 50%; + margin: 10px 0; +} + +#drag_dropOverlay{ + width: 100%; + height:100%; + position:absolute; + top:0; + opacity: 0.5; + background-color: #3071a9; + pointer-events: none; + +} + +#dragDropContainer{ + width: 100%; + height:100%; + position:absolute; + top:0; + pointer-events: none; +} +#drag_icon_group{ + + +} + +#drag_msg{ + width: 50%; + background-color: #fefefe; + height: 50%; + border: black 2px solid; + border-radius: 20px; + left: 25%; + position: absolute; + top: 25%; + vertical-align: middle; + line-height: 10px; + text-align: center; + pointer-events: none; + padding: 10px; + font-size: 1.5em; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + + +#layoutLoadingProgressBarContainer { + height: 50px; + text-align: left; + line-height: 1.5; +} + +#FPS_Statistics { + /*position : absolute;*/ + /*top : 10px;*/ + /*right: 50px;*/ + padding-left: 60px; + padding-top: 60px; +} + +#reloadCachedOntology { + /*position : absolute;*/ + /*top : 10px;*/ + /*right: 50px;*/ +} + +#additionalInformationContainer { + position: absolute; + top: 10px; + right: 50px; +} + +#modeOfOperationString { + /*position: absolute;*/ + /*right: 50px;*/ + /*top : 60px;*/ + padding-left: 34px; +} + +#direct-text-input { + border: 1px solid #34495e; + width: 100%; + margin-top: 5px; + cursor: pointer; +} + +#directUploadBtn, #close_directUploadBtn { + border: 1px solid #34495e; + width: 100%; + margin-top: 5px; + cursor: pointer +} + +#di_controls { + +} + +#di_controls > ul { + list-style: none; + margin: 0; + padding: 5px 0 0 5px; + +} + +#progressBarContext { + border-radius: 10px; + background-color: #bdc3c7; + height: 25px; + border: solid 1px black; + + margin: auto; + +} + +#progressBarValue { + border-radius: 9px; + width: 0%; + background-color: #2980b9; + height: 25px; + line-height: 1.5; + text-align: center; +} + +/** adding searching Styles **/ +.dbEntry { + background-color: #ffffff; + color: #2980b9; + padding: 10px; + font-size: 14px; + border: none; + cursor: pointer; +} + +.debugOption { + +} + +.dbEntrySelected { + background-color: #bdc3c7; + color: #2980b9; + padding: 10px; + font-size: 14px; + border: none; + cursor: pointer; +} + +.dbEntry:hover, .dbEntry:focus { + background-color: #bdc3c7; +} + +.searchMenuEntry { + background-color: #ffffff; + bottom: 0; + font-size: 14px; + min-width: 50px; + margin: 0; + padding: 0; + z-index: 99; + border-radius: 4px 4px 0 0; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-sizing: border-box; + border-bottom: none; + display: none; + position: absolute; + list-style: none; +} + +.searchInputText { + background-color: #ffffff; + color: black; + border: black; + text-decoration: none; + max-width: 150px; + overflow: hidden; + text-overflow: ellipsis; + /*height: 20px;*/ + margin: 0; +} + +img, iframe { + border: none; +} + +.hidden { + display: none !important; +} + +.clear { + clear: both; +} + +a { + color: #69c; + text-decoration: none; +} + +a:hover { + color: #3498db; +} + +#optionsArea a { + color: #2980b9; +} + +#optionsArea a.highlighted { + background-color: #d90; +} + +.toolTipMenu li.highlighted { + background-color: #feb; +} + +#browserCheck { + /* checking for IE where WebVOWL is not working */ + background-color: #f00; + padding: 5px 0; + position: absolute; + text-align: center; + width: 100%; +} + +#browserCheck a { + color: #fff; +} + +#browserCheck a:hover { + text-decoration: underline; +} + +/*---------------------------------------------- + SideBar Animation Class; +----------------------------------------------- */ +@-webkit-keyframes sbExpandAnimation { + 0% { + width: 78%; + } + 100% { + width: 100%; + } +} + +@-moz-keyframes sbExpandAnimation { + 0% { + width: 78%; + } + 100% { + width: 100%; + } +} + +@-o-keyframes sbExpandAnimation { + 0% { + width: 78%; + } + 100% { + width: 100%; + } +} + +@keyframes sbExpandAnimation { + 0% { + width: 78%; + } + 100% { + width: 100%; + } +} + +/*Collapse Animation*/ +@-webkit-keyframes sbCollapseAnimation { + 0% { + width: 100%; + } + 100% { + width: 78%; + } +} + +@-moz-keyframes sbCollapseAnimation { + 0% { + width: 100%; + } + 100% { + width: 78%; + } +} + +@-o-keyframes sbCollapseAnimation { + 0% { + width: 100%; + } + 100% { + width: 78%; + } +} + +@keyframes sbCollapseAnimation { + 0% { + width: 100%; + } + 100% { + width: 78%; + } +} + +/*---------------------------------------------- + SideBar Animation Class; +----------------------------------------------- */ +@-webkit-keyframes l_sbExpandAnimation { + 0% { + width: 0px; + } + 100% { + width: 200px; + } +} + +@-moz-keyframes l_sbExpandAnimation { + 0% { + width: 0px; + } + 100% { + width: 200px; + } +} + +@-o-keyframes l_sbExpandAnimation { + 0% { + width: 0px; + } + 100% { + width: 200px; + } +} + +@keyframes l_sbExpandAnimation { + 0% { + width: 0px; + } + 100% { + width: 200px; + } +} + +/*Collapse Animation*/ +@-webkit-keyframes l_sbCollapseAnimation { + 0% { + width: 200px; + } + 100% { + width: 0px; + } +} + +@-moz-keyframes l_sbCollapseAnimation { + 0% { + width: 200px; + } + 100% { + width: 0px; + } +} + +@-o-keyframes l_sbCollapseAnimation { + 0% { + width: 200px; + } + 100% { + width: 0px; + } +} + +@keyframes l_sbCollapseAnimation { + 0% { + width: 200px; + } + 100% { + width: 0px; + } +} + +/*----------------- WARNING ANIMATIONS-------------*/ + +/*---------------------------------------------- + SideBar Animation Class; +----------------------------------------------- */ +@-webkit-keyframes warn_ExpandAnimation { + 0% { + top: -500px; + } + 100% { + top: 0; + } +} + +@-moz-keyframes warn_ExpandAnimation { + 0% { + top: -500px; + } + 100% { + top: 0; + } +} + +@-o-keyframes warn_ExpandAnimation { + 0% { + top: -500px; + } + 100% { + top: 0; + } +} + +@keyframes warn_ExpandAnimation { + 0% { + top: -500px; + } + 100% { + top: 0; + } +} + +/*Collapse Animation*/ +@-webkit-keyframes warn_CollapseAnimation { + 0% { + top: 0; + } + 100% { + top: -400px; + } +} + +@-moz-keyframes warn_CollapseAnimation { + 0% { + top: 0; + } + 100% { + top: -400px; + } +} + +@-o-keyframes warn_CollapseAnimation { + 0% { + top: 0; + } + 100% { + top: -400px; + } +} + +@keyframes warn_CollapseAnimation { + 0% { + top: 0; + } + 100% { + top: -400px; + } +} + +@keyframes msg_CollapseAnimation { + 0% { + top: 0; + } + 100% { + top: -400px; + } +} + +/*// add expand and collaps width for the warn module*/ +@-webkit-keyframes warn_ExpandLeftBarAnimation { + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +@-moz-keyframes warn_ExpandLeftBarAnimation { + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +@-o-keyframes warn_ExpandLeftBarAnimation { + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +@keyframes warn_ExpandLeftBarAnimation { + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +/*Collapse Animation*/ +@-webkit-keyframes warn_CollapseLeftBarAnimation { + 0% { + left: 100px; + } + 100% { + left: 0; + } +} + +@-moz-keyframes warn_CollapseLeftBarAnimation { + 0% { + left: 100px; + } + 100% { + left: 0; + } +} + +@-o-keyframes warn_CollapseLeftBarAnimation { + 0% { + left: 100px; + } + 100% { + left: 0; + } +} + +@keyframes warn_CollapseLeftBarAnimation { + 0% { + left: 100px; + } + 100% { + left: 0; + } +} + +/*// same for the right side expansion*/ + +/*// add expand and collaps width for the warn module*/ +@-webkit-keyframes warn_ExpandRightBarAnimation { + 0% { + width: 100%; + } + 100% { + width: 78%; + } +} + +@-moz-keyframes warn_ExpandRightBarAnimation { + 0% { + width: 100%; + } + 100% { + width: 78%; + } +} + +@-o-keyframes warn_ExpandRightBarAnimation { + 0% { + width: 100%; + } + 100% { + width: 78%; + } +} + +@keyframes warn_ExpandRightBarAnimation { + 0% { + width: 100%; + } + 100% { + width: 78%; + } + +} + +/*Collapse Animation*/ +@-webkit-keyframes warn_CollapseRightBarAnimation { + 0% { + width: 78%; + } + 100% { + width: 100%; + } +} + +@-moz-keyframes warn_CollapseRightBarAnimation { + 0% { + width: 78%; + } + 100% { + width: 100%; + } +} + +@-o-keyframes warn_CollapseRightBarAnimation { + 0% { + width: 78%; + } + 100% { + width: 100%; + } +} + +@keyframes warn_CollapseRightBarAnimation { + 0% { + width: 78%; + } + 100% { + width: 100%; + } +} + +/*---------------------------------------------- + LAYOUT +----------------------------------------------*/ +body { + background: rgb(24, 32, 42); + height: 100%; + font-size: 14px; + font-family: 'Open Sans', Helvetica, Arial, sans-serif; + line-height: 1; + margin: 0; + overflow: hidden; + padding: 0; + position: fixed; + width: 100%; +} + +main { + height: 100%; + margin: 0; + padding: 0; + position: relative; + width: 100%; +} + +#canvasArea { + position: relative; + margin: 0; + padding: 0; + width: 78%; +} + +#canvasArea #graph { + box-sizing: border-box; + margin: 0 0 2px 0; + background-color: #ecf0f1; + overflow: hidden; + padding: 0; + width: 100%; +} + +#canvasArea svg { + box-sizing: border-box; + margin: 0; + overflow: hidden; + padding: 0; +} + +#logo { + position: fixed; + /*padding: 10px;*/ + pointer-events: none; + /*border: solid 1px red;*/ +} + +#logo h2 { + color: #3498db; + margin: 0; + line-height: 0.7; + text-align: center; + font-size: 24px; +} + +#logo h2 span { + color: #34495E; + /*font-size: min(2vmin, 24px);*/ + font-size: 16px; +} + +@media screen and (max-device-height: 800px) { + #logo h2 { + font-size: calc(8px + 1.0vmin); + } + + #logo h2 span { + font-size: calc(3px + 1.0vmin); + } +} + +@media screen and (max-height: 800px) { + #logo h2 { + font-size: calc(8px + 1.0vmin); + } + + #logo h2 span { + font-size: calc(3px + 1.0vmin); + } +} + +@media screen and (max-device-width: 1200px) { + #logo h2 { + font-size: calc(8px + 1.0vmin); + } + + #logo h2 span { + font-size: calc(3px + 1.0vmin); + } +} + +@media screen and (max-width: 1200px) { + #logo h2 { + font-size: calc(8px + 1.0vmin); + } + + #logo h2 span { + font-size: calc(3px + 1.0vmin); + } +} + +.checkboxContainer input, .checkboxContainer label { + vertical-align: middle; +} + +.selected-ontology { + background-color: #eee; +} + +#credits { + border-top: solid 1px #bdc3c7; + font-size: 0.9em; +} + +.slideOption { + position: relative; + padding: 8px 5px; + outline: none; +} + +.slideOption .value { + float: right; + outline: none; +} + +.slideOption input[type="range"] { + box-sizing: border-box; + margin: 0; + outline: none; + -webkit-appearance: none; + -moz-appearance: none; + border-radius: 3px; + height: 12px; + width: 100%; + box-shadow: none; + left: 0; + position: relative; + transition: all 0.5s ease; + background-color: #eee; +} + +/*TRACK*/ +.slideOption input[type=range]::-webkit-slider-runnable-track { + -webkit-appearance: none; + background-color: #3071a9; + height: 3px; +} + +.slideOption input[type=range]::-moz-range-track { + -webkit-appearance: none; + background-color: #3071a9; + height: 3px; +} + +.slideOption input[type="range"]:hover { + outline: none; +} + +/*THUMB*/ +.slideOption input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + background-color: white; + border-radius: 3px; + border: solid 1px black; + transition: all 0.5s ease; + height: 10px; + width: 30px; + outline: none; + margin-top: -3px; +} + +.slideOption input[type="range"]::-moz-range-thumb { + -webkit-appearance: none; + background-color: white; + border-radius: 3px; + border: solid 1px black; + transition: all 0.5s ease; + height: 10px; + width: 30px; + outline: none; +} + +.slideOption input[type="range"]::-moz-range-thumb:hover { + background-color: #d90; + outline: none; +} + +.slideOption input[type="range"]::-webkit-slider-thumb:hover { + background-color: #d90; + /*color: #d90;*/ + outline: none; +} + +/*focus : remove border*/ +.slideOption input[type="range"]:focus { + outline: none; +} + +.slideOption input[type="range"]:active { + outline: none; +} + +.slideOption input[type="range"]::-moz-range-thumb:focus { + outline: none; +} + +.slideOption input[type="range"]::-moz-range-thumb:active { + outline: none; +} + +.slideOption input[type="range"]::-webkit-slider-thumb:focus { + outline: none; +} + +.slideOption input[type="range"]::-webkit-slider-thumb:active { + outline: none; +} + +.slideOption input[type="range"]:disabled { + box-sizing: border-box; + margin: 0; + outline: none; + -webkit-appearance: none; + -moz-appearance: none; + border-radius: 3px; + height: 12px; + width: 100%; + box-shadow: none; + left: 0; + position: relative; + transition: all 0.5s ease; + background-color: #787878; +} + +/*TRACK*/ +.slideOption input[type=range]:disabled::-webkit-slider-runnable-track { + -webkit-appearance: none; + background-color: #373737; + height: 3px; +} + +.slideOption input[type=range]:disabled::-moz-range-track { + -webkit-appearance: none; + background-color: #373737; + height: 3px; +} + +.slideOption input[type="range"]:disabled { + outline: none; +} + +/*THUMB*/ +.slideOption input[type="range"]:disabled::-webkit-slider-thumb { + -webkit-appearance: none; + background-color: #363636; + border-radius: 3px; + border: solid 1px #aaaaaa; + transition: all 0.5s ease; + height: 10px; + width: 30px; + outline: none; + margin-top: -3px; +} + +.slideOption input[type="range"]:disabled::-moz-range-thumb { + -webkit-appearance: none; + background-color: #aaaaaa; + border-radius: 3px; + border: solid 1px black; + transition: all 0.5s ease; + height: 10px; + width: 30px; + outline: none; +} + +.slideOption input[type="range"]:disabled::-moz-range-thumb { + background-color: #aaaaaa; + outline: none; +} + +.slideOption input[type="range"]:disabled::-webkit-slider-thumb { + background-color: #aaaaaa; + /*color: #d90;*/ + outline: none; +} + +.slideOption input[type="range"]:disabled:hover::-moz-range-thumb { + background-color: #404040; + outline: none; +} + +.slideOption input[type="range"]:disabled:hover::-webkit-slider-thumb { + background-color: #404040; + /*color: #d90;*/ + outline: none; +} + +#detailsArea { + top: 0; + right: 0; + bottom: 0; + color: #bdc3c7; + height: 100%; + width: 22%; + overflow-y: auto; + overflow-x: hidden; + position: fixed; + border-left: 1px solid #34495E; +} + +#detailsArea h1 { + border-bottom: solid 1px #34495e; + color: #ecf0f1; + display: block; + font-weight: 100; + font-size: 1.5em; + margin: 0; + padding: 10px 0; + text-align: center; +} + +#generalDetails { + width: auto; + box-sizing: border-box; + height: 100%; +} + +#generalDetails span #about { + border-bottom: solid 1px #34495e; + display: block; + padding: 10px; + text-align: center; + word-wrap: break-word; + color: #69c; +} + +#generalDetails h4 { + background: rgb(27, 37, 46); + color: #ecf0f1; + display: block; + font-size: 1.1em; + font-weight: 100; + margin: 0; + padding: 10px 0; + text-align: center; +} + +#detailsArea #generalDetails h5 { + border-bottom: solid 1px #34495e; + font-size: 0.9em; + font-weight: 100; + margin: 0; + padding: 5px; + text-align: center; +} + +#description { + text-align: justify; +} + +.accordion-container p { + font-size: 0.9em; + line-height: 1.3; + margin: 5px 10px; +} + +.statisticDetails span { + font-weight: 100; + font-style: italic; + margin: 10px 0; + padding: 10px; +} + +.statisticDetails div { + font-weight: 100; + font-style: italic; + margin: 10px 0; + padding: 0 10px; + display: inline; +} + +#selection-details .propDetails a { + color: #69c; +} + +#selection-details .propDetails > span { + font-weight: 100; + font-style: italic; + padding: 0 10px; +} + +#selection-details #classEquivUri span, #selection-details #disjointNodes span { + padding: 0; +} + +#selection-details .propDetails div { + font-weight: 100; + font-style: italic; + margin: 10px 0; + padding: 0 10px; + display: inline; +} + +#selection-details .propDetails div span { + padding: 0; +} + +/* give subclass property the same background color as the canvas */ +.subclass { + fill: #ecf0f1; +} + +.accordion-trigger { + background: #24323e; + cursor: pointer; + padding: .5em; +} + +.accordion-trigger.accordion-trigger-active:before { + padding-right: 4px; + content: "\25BC" +} + +.accordion-trigger:not(.accordion-trigger-active):before { + padding-right: 4px; + content: "\25BA" +} + +.accordion-container.scrollable { + max-height: 40%; + overflow: auto; +} + +.small-whitespace-separator { + height: 3px; +} + +#language { + background: transparent; + border: 1px solid #34495E; + color: #ecf0f1; +} + +#language option { + background-color: #24323e; +} + +.converter-form:not(:first-child) { + margin-top: 5px; +} + +.converter-form label { + display: inline-block; + line-height: normal; +} + +.converter-form input { + box-sizing: border-box; + height: 20px; + width: 74%; + border: 1px solid #34495E; +} + +.converter-form button { + cursor: pointer; + float: right; + height: 20px; + padding: 0; + width: 25%; + border: 1px solid #34495E; + background-color: #ecf0f1; +} + +#file-converter-label { + border: 1px solid #34495E; + box-sizing: border-box; + cursor: pointer; + height: 20px; + width: 74%; +} + +#killWarning { + cursor: pointer; + color: #ffffff; + font-weight: bold; +} + +/*#copyBt{*/ +/*box-sizing: border-box;*/ +/*color: #000000;*/ +/*float:right;*/ +/*position:absolute;*/ +/*right:2px;*/ +/*padding: 2px 7px 3px 7px;*/ +/*border: 1px solid #000000;*/ +/*background-color: #ecf0f1;*/ +/*cursor: pointer;*/ +/*}*/ + +#copyBt { + box-sizing: border-box; + height: 20px; + width: 31%; + border: 1px solid #34495E; +} + +#sidebarExpandButton { + height: 24px; + width: 24px; + /*background-color: white;*/ + /*box-shadow: 0px 1px 1px grey;*/ + box-sizing: border-box; + top: 10px; + color: #000000; + float: right; + position: absolute; + right: 0; + border: 1px solid #000000; + + text-align: center; + font-size: 1.5em; + cursor: pointer; +} + +.dropdownMenuClass { + height: 20px; + /*width: 69%;*/ + float: right; + border: 1px solid #34495E; + background-color: #34495E; + color: white; + /*border-bottom: 1px solid #d90;*/ + text-align: left; + width: auto; +} + +#typeEditForm_datatype { + padding-top: 5px; +} + +#typeEditor { + width: 165px; +} + +#typeEditor_datatype { + width: 165px; +} + +#leftSideBarCollapseButton { + box-sizing: border-box; + top: 50px; + /*padding:5px;*/ + color: #000000; + position: absolute; + left: 200px; + border: 1px solid #000000; + /*background-color: #ecf0f1;*/ + cursor: pointer; + width: 24px; + height: 24px; + font-size: 1.5em; + text-align: center; +} + +#leftSideBarCollapseButton:hover { + background-color: #d90; +} + +#sidebarExpandButton:hover { + background-color: #d90; +} + +.spanForCharSelection { + padding-left: 25px; +} + +.nodeEditSpan { + color: #000; + background-color: #fff; + text-align: center; + /*overflow: auto;*/ + border: none; + padding-top: 6px; +} + +.nodeEditSpan:focus { + outline: none; + border: none; +} + +.foreignelements { + /*width: 80px;*/ + /*height: 3px;*/ + border: none; +} + +.foreignelements:focus { + outline: none; + border: none; +} + +#leftSideBarContent { + color: #000000; + float: left; + position: absolute; + left: 0; + /*border: 1px solid #000000;*/ + background-color: rgb(24, 32, 42); + width: 100%; + height: 100%; +} + +#leftSideBarContent > h3 { + color: #ecf0f1; + display: block; + font-size: 1.1em; + font-weight: 100; + margin: 0 0 5px 0; + padding: 10px 0; + text-align: left; +} + +#generalDetailsEdit { + /*color: #ecf0f1;*/ + color: #ecf0f1; +} + +#generalDetailsEdit > div { + padding: 5px; +} + +#generalDetailsEdit > h3 { + color: #ecf0f1; + display: block; + font-size: 1.1em; + font-weight: 100; + margin: 0 0 5px 0; + padding: 10px 0; + text-align: left; +} + +.subAccordion { + color: #ecf0f1; + display: block; + font-size: 0.8em; + font-weight: 100; + margin: 0; + padding: 5px; + text-align: left; +} + +.subAccordionDescription { + padding: 0 5px; +} + +.boxed { + padding: 0 5px; +} + +.separatorLineRight { + border-right: 1px solid #f00; +} + +.editPrefixButton:hover { + color: #ff972d; + cursor: pointer; +} + +.editPrefixIcon:hover { + stroke: #ff972d; + stroke-width: 1px; + cursor: pointer; +} + +.editPrefixIcon { + stroke: #fffff; + stroke-width: 1px; + cursor: pointer; +} + +.deletePrefixButton:hover { + color: #ff972d; + cursor: pointer; +} + +.deletePrefixButton { + color: #ff0000; + cursor: pointer; +} + +.invisiblePrefixButton { + cursor: default; + color: rgb(24, 32, 42); +} + +#containerForAddPrefixButton { + width: 100%; + margin-top: 5px; +} + +.roundedButton { + border: 1px solid #000000; + border-radius: 20px; + padding: 0 5px; + background: #fff; + cursor: pointer; + color: black; + outline: none; +} + +.roundedButton:hover { + background: #318638; + cursor: pointer; + color: #fff; + outline: none; +} + +#prefixURL_Description { + padding: 5px 0 0 0; +} + +.prefixIRIElements { + display: inline-block; + padding: 3px; + border-bottom: 1px solid #34495E; + width: 100% +} + +.prefixInput { + width: 30px; + display: inline-block; + margin-right: 5px; +} + +.prefixURL { + width: 100px; + display: inline-block; + paddig-left: 5px; +} + +.selectedDefaultElement { + text-align: left; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: inline-block; + max-width: 200px; +} + +#editHeader { + color: #ecf0f1; + background-color: #394f5a; + display: block; + font-size: 1.1em; + font-weight: 100; + text-align: center; +} + +#leftHeader { + color: #ecf0f1; + background-color: #394f5a; + display: block; + font-size: 1.1em; + font-weight: 100; + text-align: center; + padding: 10px 0; + margin: 0; +} + +.containerForDefaultSelection { + color: #ecf0f1; + display: block; + font-size: 1.1em; + font-weight: 100; + margin: 0; + padding: 10px 20px; + text-align: left; +} + +.defaultSelected { + color: #a15d05; + background-color: #283943; +} + +.containerForDefaultSelection:hover { + color: #f19505; + background-color: #394f5a; + display: block; + cursor: pointer; +} + +#containerForLeftSideBar { + top: 50px; + float: left; + position: absolute; + background-color: #1b252e; + left: 0; + width: 200px; + height: 200px; + overflow-y: auto; + overflow-x: hidden; +} + +#leftSideBar { + width: 100%; + background-color: rgb(24, 32, 42); +} + +#loading-info { + box-sizing: border-box; + position: absolute; + text-align: center; + + width: 100%; + height: 80%; + top: 0; +} + +#loading-info > div { + display: inline-block; + color: #ffffff; + background-color: #18202A; + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; +} + +#loading-info > * > * { + padding: 5px; +} + +#loading-info { + pointer-events: none; +} + +#loading-progress { + pointer-events: auto; + min-width: 220px; + border-radius: 10px; +} + +#show-loadingInfo-button { + font-size: 12px; + color: #fff; + cursor: pointer; + text-align: center; +} + +#loadingIndicator_closeButton:hover { + color: #ff972d; + cursor: pointer; + +} + +#loadingIndicator_closeButton { + color: #ffe30f; + cursor: pointer; + padding-bottom: 5px; + float: right; +} + +.busyProgressBar { + background-color: #000; + height: 25px; + position: relative; + animation: busy 2s linear infinite; +} + +@-webkit-keyframes busy { + 0% { + left: 0%; + } + 50% { + left: 80%; + } + 100% { + left: 0%; + } +} + +#bulletPoint_container { + padding-left: 15px; + margin-top: 0px; + margin-bottom: 0px; +} + +#bulletPoint_container > div { + margin-left: -15px; +} + +#loadingInfo-container { + box-sizing: border-box; + text-align: left; + line-height: 1.2; + padding-top: 5px; + overflow: auto; + /*white-space: nowrap;*/ + /*min-width: 250px;*/ + height: 120px; + min-height: 40px; + background-color: #3c3c3c; + +} + +#error-description-button { + margin: 5px 0 0 0; + font-size: 12px; + color: #69c; + cursor: pointer; + text-align: center; +} + +#error-description-container { + box-sizing: border-box; + text-align: left; +} + +#error-description-container pre { + background-color: #34495E; + padding: 2px; + margin: 0; + white-space: pre-wrap; + max-height: calc(100vh - 125px); + max-width: 75vw; + overflow: auto; +} + +.spin { + display: inline-block; + -webkit-animation: spin 2s infinite linear; + animation: spin 2s infinite linear; +} + +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} + +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} + +.truncate { + max-width: 250px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.color-mode-switch { + float: right; + width: 90px; + cursor: pointer; + height: 20px; + padding: 0; + border: 0; + color: #555; + background-color: #ECEEEF; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2), inset 0 0 3px rgba(0, 0, 0, 0.1); +} + +.color-mode-switch:focus { + outline-width: 0; +} + +.color-mode-switch.active { + color: #FFF; + background-color: #32CD32; + box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.2), inset 0 0 3px rgba(0, 0, 0, 0.1); +} + +/* adding button pulse animation*/ +.filterMenuButtonHighlight { + background-color: #d90; +} + +@-webkit-keyframes buttonAnimation { + 0% { + background-color: unset; + } + 100% { + background-color: #d90; + } +} + +@-moz-keyframes buttonAnimation { + 0% { + background-color: unset; + } + 100% { + background-color: #d90; + } +} + +@-o-keyframes buttonAnimation { + 0% { + background-color: unset; + } + 100% { + background-color: #d90; + } +} + +@keyframes buttonAnimation { + 0% { + background-color: unset; + } + 100% { + background-color: #d90; + } +} + +.buttonPulse { + -webkit-animation-name: buttonAnimation; + -moz-animation-name: buttonAnimation; + -o-animation-name: buttonAnimation; + animation-name: buttonAnimation; + + -webkit-animation-duration: 0.5s; + -moz-animation-duration: 0.5s; + -o-animation-duration: 0.5s; + animation-duration: 0.5s; + + -webkit-animation-iteration-count: 3; + -moz-animation-iteration-count: 3; + -o-animation-iteration-count: 3; + animation-iteration-count: 3; + + -webkit-animation-timing-function: linear; + -moz-animation-timing-function: linear; + -o-animation-timing-function: linear; + animation-timing-function: linear; + + +} + +/*swipe bar definition*/ + +/*Overwriting individual menu widths*/ +#m_about { + max-width: 200px; + width: 200px; + position: absolute; + +} + +#m_modes { + max-width: 160px; + width: 160px; + position: absolute; +} + +#m_filter { + max-width: 170px; + width: 170px; + position: absolute; +} + +#m_gravity { + max-width: 180px; + width: 180px; + position: absolute; +} + +#m_export { + max-width: 160px; + width: 160px; + position: absolute; + +} + +#exportedUrl { + width: 100px; +} + +#m_select { + max-width: 300px; + width: 300px; + position: absolute; +} + +#m_config { + max-width: 240px; + width: 240px; + position: absolute; +} + +#m_search { + max-width: 250px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/***************** REWRITING MENU ELEMENT CONTAINERS ***********************/ +/*Container which holds the swipeBar*/ +#swipeBarContainer { + position: fixed; + width: 77.8%; + height: 40px; + margin: 0; + padding: 0; + bottom: 0; +} + +/*Scroll-able container for the menu entries */ +#menuElementContainer { + margin: 0; + padding: 0; + overflow-x: auto; + overflow-y: hidden; + white-space: nowrap; + text-align: right; + list-style-type: none; +} + +/*Style for the individual menu entries*/ +#menuElementContainer > li { + display: inline-block; + box-sizing: border-box; + text-align: left; + position: relative; + height: 40px; + font-size: 14px; + color: #ffffff; + padding: 12px 0 0; + margin-left: -4px; +} + +/*Font-color Style for menu entries */ +#menuElementContainer > li > a { + color: #fff; + padding: 9px 12px 12px 30px; +} + +.menuElementSvgElement { + height: 20px; + width: 20px; + display: block; + position: absolute; + top: 10px; + left: 8px; +} + +.btn_shadowed { + background-color: #fefefe; + box-shadow: 1px 1px 1px gray; +} + +.reloadCachedOntologyIcon { + height: 20px; + width: 108px; + display: block; + position: absolute; + top: 20px; + left: 3px; + /*background: #ecf0f1;;*/ + border: solid 1px black; + border-radius: 10px; + cursor: pointer; +} + +.reloadCachedOntologyIcon:disabled { + background: #f4f4f4; + cursor: auto; + border: solid 1px darkgray; + +} + +.reloadCachedOntologyIcon:hover { + background: #d90; + cursor: pointer; +} + +.disabledReloadElement { + cursor: auto; + background: #F4F4F4; + pointer-events: auto; + border: solid 1px darkgray; + color: #bbbbbb; +} + +.disabledReloadElement:hover { + cursor: auto; + background: #EEEEEE; + pointer-events: auto; +} + +#menuElementContainer > li > input { + color: #000; + /*padding : 0 0.3em 0 1.5em;*/ + padding: 0.1em .3em 0.1em 1.5em; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + width: 120px; +} + +/*Hovered behavior for the menu entries*/ +#menuElementContainer > li > a:hover { + box-sizing: border-box; + background: #1B252E; + /*background : #d90;*/ + color: #bdc3c7; + +} + +#empty:hover { + box-sizing: border-box; + background: #e1e1e1; + /*background : #d90;*/ + color: #2980b9; +} + +#empty.disabled { + pointer-events: none; + cursor: default; + color: #979797; +} + +.disabled { + pointer-events: none; + cursor: default; + color: #979797; +} + +/*ToolTip Menu Definition*/ +.toolTipMenu { + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-sizing: border-box; + background-color: #ffffff; + border: 1px solid rgba(0, 0, 0, 0.15); + border-bottom: none; + border-radius: 4px 4px 0 0; + bottom: 0; + display: none; + font-size: 14px; + list-style: none; + /*max-width: 300px;*/ + margin: 0; + padding: 0; + white-space: normal; + position: absolute; + z-index: 99; +} + +.toolTipMenu > li:first-of-type { + border: none; +} + +.toolTipMenu a { + color: #2980b9; +} + +.toolTipMenu > li { + border-top: solid 1px #bdc3c7; +} + +.toolTipMenu li { + color: #2980b9; + display: block; +} + +/*MenuElement hovering enables the toolTip of the corresponding menu*/ +#menuElementContainer > li:hover .toolTipMenu { + display: block; +} + +#menuElementContainer li > ul.toolTipMenu li a:hover { + background: #e1e1e1; +} + +/****************************************************************************/ +/*ScrollButton behavior*/ +#scrollLeftButton { + height: 30px; + width: 30px; + padding: 5px 0 5px 10px; + color: #fff; + cursor: pointer; + position: absolute; + margin-top: -2px; + font-size: 2em; + background-color: #24323e; + left: 0; +} + +#scrollLeftButton:focus { + outline: none; +} + +#scrollLeftButton:before { + content: "<"; +} + +/*Right Scroll Button*/ +#scrollRightButton { + height: 30px; + width: 30px; + padding: 5px 0 5px 10px; + color: #fff; + cursor: pointer; + position: absolute; + margin-top: -2px; + font-size: 2em; + background-color: #24323e; + right: 0; +} + +#scrollRightButton:focus { + outline: none; +} + +#scrollRightButton:hover { + color: #bdc3c7; +} + +#scrollLeftButton:hover { + color: #bdc3c7; +} + +#scrollRightButton:before { + content: ">"; +} + +#centerGraphButton, #zoomInButton, #zoomOutButton { + border: 1px solid #000000; + text-align: center; + margin: -1px 0 0 0; + font-size: 1.5em; + padding: 0; + height: 28px; +} + +.noselect { + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Safari */ + -khtml-user-select: none; /* Konqueror HTML */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; + /* Non-prefixed version, currently + supported by Chrome and Opera */ +} + +#zoomOutButton { + line-height: 22px; +} + +#centerGraphButton { + line-height: 25px; +} + +#zoomInButton { + line-height: 25px; +} + +#zoomSlider > p:hover { + background-color: #d90; +} + +#zoomSliderParagraph { + color: #000000; + padding-top: 5px; + margin: -1px 0 0 0; + border: 1px solid #000000; + /*background-color: #ecf0f1;*/ + /*width: 28px;*/ + height: 150px; +} + +p#zoomSliderParagraph:hover { + background-color: #fff; +} + +/*todo put this in a proper position*/ +#zoomSlider { + width: 28px; + margin-top: -2px; + padding: 0; + font-size: 1.5em; + cursor: pointer; + position: absolute; + right: 20px; + bottom: 20px; + color: #000; + /*background-color: #ecf0f1;*/ + box-sizing: border-box; +} + +/****************************************************************************/ +/*Definition for the Icons before*/ +#menuElementContainer > li > a::before { + font-size: 1em; + margin: 0; + padding: 0 6px 0 0; +} + +#menuElementContainer a.highlighted { + background-color: #d90; +} + +/*#search-input-text.searchInputText {*/ +/*!*padding: 0 0.2em;*!*/ +/*color: black;*/ +/*}*/ + +.inner-addon { + position: relative; +} + +.searchIcon { + position: absolute; + /*padding: 0.15em 0;*/ + width: 17px; + height: 17px; + + pointer-events: none; +} + +.gearIcon { + position: absolute; + width: 17px; + height: 17px; + pointer-events: none; + left: -5px; +} + +/*#search-input-text::before {*/ +/*!*padding: 0 0.2em;*!*/ +/*!*color: black;*!*/ +/*font-size: 1.4em; !* todo : test this *!*/ +/*!*content: "\2315";*!*/ +/*content: "⚲";*/ +/*color: white;*/ +/*padding: 0;*/ +/*-webkit-transform: rotate(-45deg);*/ +/*!*content: "\2315" or "\1F50D"*!;*/ +/*display: inline-block;*/ +/*position: relative;*/ +/*top: 2px;*/ +/*left:-5px;*/ +/*}*/ + +li#c_search { + padding: 0 5px; + margin-left: 5px; + height: 20px; +} + +/*Menu icons before the links selection */ +/*#c_select > a::before { content: "\2263"; }*/ +/*#c_export > a::before { content: "\21E4"; }*/ +/*#c_gravity > a::before { content: "\2299"; }*/ +/*#c_filter > a::before { content: "\25BD"; }*/ +/*#c_modes > a::before { content: "\2606"; }*/ +/*#c_reset > a::before { content: "\21BB"; }*/ +/*#c_about > a::before { content: "\00A9"; }*/ + +li#c_locate { + padding: 0; +} + +#c_locate > a { + font-size: 2em; + padding: 0; +} + +a#pause-button { + padding: 12px 12px; +} + +/*Pause Button has a different behavior*/ +a#pause-button.paused::before { + content: "►"; +} + +a#pause-button.paused:hover { + background-color: #d90; + color: #fff; +} + +a#pause-button:not(.paused)::before { + content: "II"; +} + +.toolTipMenu li:hover { + background-color: #e1e1e1; +} + +#emptyLiHover { + background-color: #FFFFFF; +} + +#emptyLiHover:hover { + background-color: #FFFFFF; +} + +.toggleOption li:hover { + background-color: #e1e1e1; +} + +.toggleOption { + padding: 8px 5px; +} + +#converter-option:hover { + background-color: #ffffff; +} + +.toolTipMenu li a:only-child, .option { + display: block; + float: none; + padding: 8px 5px; +} + +.customLocate { + padding: 0; + background-color: #32CD32; +} + +a#locateSearchResult { + padding-bottom: 0; + padding-top: 50px; + position: relative; + top: 5px; +} + +/*#sliderRange{*/ +/*padding: 0;*/ +/*margin: 7px 0 0 0;*/ +/*width:100%;*/ +/*height:5px;*/ +/*-webkit-appearance: none;*/ +/*outline: none;*/ +/*}*/ + +#zoomSliderElement { + color: #000; + position: relative; + padding-top: 0; + width: 155px; + height: 24px; + background-color: transparent; + -webkit-transform-origin-x: 73px; + -webkit-transform-origin-y: 73px; + -webkit-transform: rotate(-90deg); + -moz-transform-origin: 73px 73px; + transform: rotate(-90deg); + transform-origin: 73px 73px; + -webkit-appearance: none; + outline: none; + margin: 4px 0; +} + +/* ------------------ Zoom Slider styles --------------------------*/ +#zoomSliderElement::-webkit-scrollbar { + height: 0; +} + +#zoomSliderElement:hover { + cursor: crosshair; +} + +/*TRACK*/ +#zoomSliderElement::-webkit-slider-runnable-track { + width: 100%; + height: 5px; + cursor: pointer; + background: #3071a9; +} + +#zoomSliderElement::-moz-range-track { + width: 100%; + height: 5px; + cursor: pointer; + background: #3071a9; +} + +/*Thumb*/ +#zoomSliderElement::-webkit-slider-thumb { + -webkit-appearance: none; + border: 1px solid #000000; + height: 10px; + width: 30px; + margin-right: 50px; + border-radius: 3px; + background: #fff; + cursor: pointer; + outline: none; + margin-top: -3px; +} + +#zoomSliderElement::-ms-thumb { + -webkit-appearance: none; + border: 1px solid #000000; + height: 10px; + width: 30px; + margin-right: 50px; + border-radius: 3px; + background: #fff; + cursor: pointer; + outline: none; + margin-top: -3px; +} + +#zoomSliderElement::-ms-thumb:hover { + -webkit-appearance: none; + border: 1px solid #000000; + height: 10px; + width: 30px; + margin-right: 50px; + border-radius: 3px; + background: #d90; + cursor: pointer; + outline: none; + margin-top: -3px; +} + +#zoomSliderElement::-webkit-slider-thumb:hover { + -webkit-appearance: none; + border: 1px solid #000000; + height: 10px; + width: 30px; + margin-right: 50px; + border-radius: 3px; + background: #d90; + cursor: pointer; + outline: none; + margin-top: -3px; +} + +#zoomSliderElement::-moz-range-thumb { + border: 1px solid #000000; + height: 10px; + width: 30px; + border-radius: 3px; + /*background: #ffffff;*/ + cursor: pointer; + outline: none; +} + +#zoomSliderElement::-moz-range-thumb:hover { + border: 1px solid #000000; + height: 10px; + width: 30px; + border-radius: 3px; + background: #d90; + cursor: pointer; + outline: none; +} + +#zoomSliderElement::-moz-focus-outer { + border: 0; +} + +#locateSearchResult:focus { + outline: none; + +} + +a#locateSearchResult.highlighted:hover { + background-color: #d90; + color: red; +} + +a#locateSearchResult { + outline: none; + padding-bottom: 0; + padding-top: 0; + position: relative; + top: 5px; +} + +/*Editor hints*/ +#editorHint { + padding: 5px 5px; + position: absolute; + text-align: center; + width: 100%; + pointer-events: none; +} + +#editorHint label { + pointer-events: auto; + float: right; + padding: 5px 5px; + color: #ffdd00; +} + +#editorHint label:hover { + text-decoration: underline; + cursor: pointer; +} + +#editorHint > div { + pointer-events: auto; + text-align: left; + display: inline-block; + color: #ffffff; + font-size: 0.8em; + background-color: #18202A; + padding: 5px 5px; + border-radius: 5px; + +} + +#WarningErrorMessagesContainer { + position: absolute; + text-align: center; + top: 0; + pointer-events: none; +} + +/*Editor hints*/ +#WarningErrorMessages { + position: relative; + /*text-align: center;*/ + width: 50%; + pointer-events: auto; + margin: 10px 0; + padding-right: 12px; + overflow-y: auto; + overflow-x: hidden; +} + +#WarningErrorMessages label { + pointer-events: auto; + float: right; + padding: 5px 5px; + color: #ffdd00; +} + +#WarningErrorMessages span { + pointer-events: auto; + float: right; + padding: 5px 5px; +} + +#WarningErrorMessages label:hover { + text-decoration: underline; + cursor: pointer; +} + +#WarningErrorMessages > div { + pointer-events: auto; + text-align: left; + display: inline-block; + color: #ffffff; + font-size: 0.8em; + background-color: #18202A; + padding: 5px 5px; + border-radius: 10px; + border: solid 1px #ecf0f1; + width: 70%; + +} + +#WarningErrorMessagesContent > ul { + -webkit-padding-start: 20px; + padding: 0 16px; + +} + +#WarningErrorMessagesContent > ul > li { + padding: 5px; +} + +.converter-form-Editor { + /*display: inline-block;*/ +} + +.textLineEditWithLabel { + display: inline-block; + width: 100%; + border-bottom: 1px solid #34495E; + padding: 2px 0; + +} + +.converter-form-Editor label { + /*//display: inline-block;*/ + line-height: normal; +} + +.descriptionTextClass { + background-color: #34495E; + color: white; +} + +.prefixIRIElements input { + border: 1px solid #34495E; + background-color: #34495E; + color: white; +} + +.prefixIRIElements input:disabled { + background-color: rgb(24, 32, 42); + border: 1px solid rgb(24, 32, 42); + color: white; +} + +.converter-form-Editor input { + /*box-sizing: border-box;*/ + /*height: 18px;*/ + /*width: 69%;*/ + float: right; + border: 1px solid #34495E; + background-color: #34495E; + color: white; + /*border-bottom: 1px solid #d90;*/ + /*text-align: center;*/ + /*display: inline-block;*/ +} + +.converter-form-Editor input:disabled { + background-color: #545350; + border: 1px solid #34495E; + color: #939798; +} + +.disabledLabelForSlider { + color: #808080; +} diff --git a/src/app/data/benchmark.json b/src/app/data/benchmark.json new file mode 100644 index 0000000000000000000000000000000000000000..765e16782ec3ff7d5a5217a7285b995d2f83dc12 --- /dev/null +++ b/src/app/data/benchmark.json @@ -0,0 +1,1917 @@ +{ + "namespace": [ + { + "name": "owl", + "iri": "http://www.w3.org/2002/07/owl#" + }, + { + "name": "rdf", + "iri": "http://www.w3.org/1999/02/22-rdf-syntax-ns#" + }, + { + "name": "rdfs", + "iri": "http://www.w3.org/2000/01/rdf-schema#" + } + ], + "header": { + "title": { + "iriBased": "Benchmark Graph", + "en": "Benchmark Graph", + "de": "Benchmark Graph (DE)", + "undefined": "Benchmark Graph (UNDEFINED)" + }, + "iri": "#", + "version": "0.1", + "author": [ + "Vincent Link", + "Eduard Marbach" + ], + "description": { + "iriBased": "The benchmark graph contains all visual elements of VOWL to test WebVOWL conformance with the specification and special cases.", + "en": "The benchmark graph contains all visual elements of VOWL to test WebVOWL conformance with the specification and special cases.", + "de": "Deutsche Beschreibung" + }, + "languages": [ + "en", + "de", + "unset", + "iriBased" + ] + }, + "class": [ + { + "id": "MultiLink2", + "type": "owl:Class", + "label": "MultiLink2" + }, + { + "id": "MultiLink3", + "type": "owl:Class", + "label": "MultiLink3" + }, + { + "id": "MultiLink4", + "type": "owl:Class", + "label": "MultiLink4" + }, + { + "id": "MultiLink5", + "type": "owl:Class", + "label": "MultiLink5" + }, + { + "id": "MultiLinkEnd", + "type": "owl:Class", + "label": "MultiLinkEnd" + }, + { + "id": "DisjointTest0", + "type": "owl:Class", + "label": "DisjointTest0" + }, + { + "id": "DisjointTestUri", + "type": "owl:Class", + "label": "DisjointTestUri" + }, + { + "id": "DisjointTest2", + "type": "owl:Class", + "label": "DisjointTest2" + }, + { + "id": "SetOperatorTest", + "type": "owl:Class", + "intersection": [ + "IntersectionTest" + ], + "union": [ + "UnionTest" + ], + "disjointUnion": [ + "DisjointUnionTest" + ], + "complement": [ + "ComplementTest" + ], + "label": "SetOperatorTest" + }, + { + "id": "IntersectionTest", + "type": "owl:intersectionOf", + "label": "Intersection", + "individuals": [ + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + } + ] + }, + { + "id": "UnionTest", + "type": "owl:unionOf", + "label": "Union", + "individuals": [ + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + } + ] + }, + { + "id": "DisjointUnionTest", + "type": "owl:disjointUnionOf", + "label": "DisjointUnion" + }, + { + "id": "ComplementTest", + "type": "owl:complementOf", + "label": "Complement" + }, + { + "id": "NodeTest", + "type": "owl:Class", + "label": { + "de": "KnotenTest", + "en": "NodeTest", + "unset": "NodeTest", + "iriBased": "NodeTest" + } + }, + { + "id": "ExternalClass", + "type": "ExternalClass", + "label": "ExternalClass" + }, + { + "id": "OwlClass", + "type": "owl:Class", + "label": "OwlClass" + }, + { + "id": "OwlEquivalentClass", + "type": "owl:equivalentClass", + "equivalent": [ + "EquivalentClassA", + "EquivalentClassB" + ], + "label": "EquivalentClass" + }, + { + "id": "EquivalentClassA", + "type": "owl:Class", + "label": "EC A" + }, + { + "id": "EquivalentClassB", + "type": "owl:Class", + "label": "EC B" + }, + { + "id": "OwlThing", + "type": "owl:Thing", + "label": "OwlThing" + }, + { + "id": "OwlNothing", + "type": "owl:Nothing", + "label": "OwlNothing" + }, + { + "id": "RdfsResource", + "type": "rdfs:Resource", + "label": "RdfsResource" + }, + { + "id": "RdfsClass", + "type": "rdfs:Class", + "label": "RdfsClass" + }, + { + "id": "OwlDeprecatedClass", + "type": "owl:DeprecatedClass", + "label": "OwlDeprecatedClass" + }, + { + "id": "PropertyTest", + "type": "owl:Class", + "label": "PropertyTest" + }, + { + "id": "ExternalPropertyTest", + "type": "owl:Class", + "label": "ExternalProperty" + }, + { + "id": "DatatypePropertyTest", + "type": "owl:Class", + "label": "DatatypeProperty" + }, + { + "id": "RdfPropertyTest", + "type": "owl:Class", + "label": "RdfProperty" + }, + { + "id": "ObjectPropertyTest", + "type": "owl:Class", + "label": "ObjectProperty" + }, + { + "id": "InverseObjectPropertyTest", + "type": "owl:Class", + "label": "InverseObjectProperty" + }, + { + "id": "DeprecatedPropertyTest", + "type": "owl:Class", + "label": "DeprecatedProperty" + }, + { + "id": "SubClassOfPropertyTest", + "type": "owl:Class", + "label": "SubClassOfProperty" + }, + { + "id": "SomeValuesFromPropertyTest", + "type": "owl:Class", + "label": "SomeValuesFromProperty" + }, + { + "id": "AllValuesFromPropertyTest", + "type": "owl:Class", + "label": "AllValuesFromProperty" + }, + { + "id": "HoverTest1", + "type": "owl:Class", + "label": "HoverTest1" + }, + { + "id": "HoverTest2", + "type": "owl:Class", + "label": "HoverTest2" + }, + { + "id": "EightSymmetric", + "type": "owl:Class" + }, + { + "id": "FiveSymmetric", + "type": "owl:Class" + }, + { + "id": "UriPropertyTest1", + "type": "owl:Class" + }, + { + "id": "UriPropertyTest2", + "type": "owl:Class" + }, + { + "id": "DatatypeTest", + "type": "owl:Class" + }, + { + "id": "IndicationTest1", + "type": "owl:Class" + }, + { + "id": "IndicationTest2", + "type": "owl:Class" + }, + { + "id": "ClassFeatureTest", + "type": "owl:Class" + }, + { + "id": "cardinalityTest1", + "type": "owl:Class" + }, + { + "id": "cardinalityTest2", + "type": "owl:Class" + }, + { + "id": "cardinalityTest3", + "type": "owl:Class" + }, + { + "id": "equivalentPropertyTest", + "type": "owl:Class" + }, + { + "id": "AnonymousClass", + "type": "owl:Class" + } + ], + "classAttribute": [ + { + "id": "ClassFeatureTest", + "label": "Class Feature Test", + "individuals": [ + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + } + ], + "comment": "Class Feature Test comment" + }, + { + "id": "UriPropertyTest1", + "iri": "http://vowl.visualdataweb.org/v2/", + "label": "VOWL-Spec URL" + }, + { + "id": "equivalentPropertyTest", + "label": "VISIBLE OR NOT?" + }, + { + "id": "AnonymousClass", + "label": "Anonymous Class", + "attributes": [ + "anonymous" + ] + } + ], + "datatype": [ + { + "id": "DatatypeDatatype", + "type": "rdfs:Datatype", + "label": "e.g. String" + }, + { + "id": "LiteralDatatype", + "type": "rdfs:Literal" + }, + { + "id": "DatatypeFeatureTest", + "type": "rdfs:Datatype" + } + ], + "datatypeAttribute": [ + { + "id": "DatatypeFeatureTest", + "label": "Datatype Feature Test", + "individuals": [ + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + }, + { + "a": "b" + } + ], + "comment": "Datatype Feature Test comment" + } + ], + "property": [ + { + "id": "21to" + }, + { + "id": "21from" + }, + { + "id": "22to" + }, + { + "id": "22from" + }, + { + "id": "31to" + }, + { + "id": "31from" + }, + { + "id": "32to" + }, + { + "id": "32from" + }, + { + "id": "33to" + }, + { + "id": "33from" + }, + { + "id": "41to" + }, + { + "id": "41from" + }, + { + "id": "42to" + }, + { + "id": "42from" + }, + { + "id": "43to" + }, + { + "id": "43from" + }, + { + "id": "44to" + }, + { + "id": "44from" + }, + { + "id": "51to" + }, + { + "id": "51from" + }, + { + "id": "52to" + }, + { + "id": "52from" + }, + { + "id": "53to" + }, + { + "id": "53from" + }, + { + "id": "54to" + }, + { + "id": "54from" + }, + { + "id": "55to" + }, + { + "id": "55from" + }, + { + "id": "disjoint0Uri" + }, + { + "id": "disjoint02" + }, + { + "id": "disjointBridge1" + }, + { + "id": "disjointBridge2" + }, + { + "id": "testOwlClass" + }, + { + "id": "testOwlEquivalentClass" + }, + { + "id": "testOwlThing" + }, + { + "id": "testOwlNothing" + }, + { + "id": "testRdfsResource" + }, + { + "id": "testOwlDeprecatedClass" + }, + { + "id": "testRdfsClass" + }, + { + "id": "testExternalClass" + }, + { + "id": "testObjectProperty", + "attributes": [ + "object" + ] + }, + { + "id": "testInverseObjectProperty", + "attributes": [ + "object" + ] + }, + { + "id": "testInverseObjectPropertyInverse", + "attributes": [ + "object" + ] + }, + { + "id": "testExternalProperty", + "attributes": [ + "external" + ] + }, + { + "id": "testDatatypeProperty", + "attributes": [ + "datatype" + ] + }, + { + "id": "testRdfProperty" + }, + { + "id": "testDeprecatedProperty", + "attributes": [ + "deprecated" + ] + }, + { + "id": "testSubClassOfProperty" + }, + { + "id": "testSomeValuesFromProperty" + }, + { + "id": "testAllValuesFromProperty" + }, + { + "id": "hoverMeProperty", + "subproperty": [ + "highlightedProperty" + ] + }, + { + "id": "highlightedProperty" + }, + { + "id": "SymmetricFiveEight" + }, + { + "id": "EightSymmetric1" + }, + { + "id": "EightSymmetric2" + }, + { + "id": "EightSymmetric3" + }, + { + "id": "EightSymmetric4" + }, + { + "id": "EightSymmetric5" + }, + { + "id": "EightSymmetric6" + }, + { + "id": "EightSymmetric7" + }, + { + "id": "EightSymmetric8" + }, + { + "id": "FiveSymmetric1" + }, + { + "id": "FiveSymmetric2" + }, + { + "id": "FiveSymmetric3" + }, + { + "id": "FiveSymmetric4" + }, + { + "id": "FiveSymmetric5" + }, + { + "id": "UriProperty" + }, + { + "id": "DatatypeTestProperty" + }, + { + "id": "LiteralTestProperty" + }, + { + "id": "FunctionalProperty" + }, + { + "id": "InverseFunctionalProperty" + }, + { + "id": "KeyProperty" + }, + { + "id": "TransitiveProperty" + }, + { + "id": "SymmetricProperty" + }, + { + "id": "EquivalentBaseProperty" + }, + { + "id": "EquivalentProperty" + }, + { + "id": "PropertyFeatureTest", + "attributes": [ + "object", + "datatype", + "deprecated", + "rdf" + ] + }, + { + "id": "cardinalityLink1", + "label": "card1", + "minCardinality": "1", + "maxCardinality": "5" + }, + { + "id": "cardinalityLink2", + "label": "card2", + "cardinality": "8888" + }, + { + "id": "cardinalityLink3", + "label": "card3", + "minCardinality": "77" + }, + { + "id": "cardinalityLink4", + "label": "card4", + "maxCardinality": "13" + }, + { + "id": "anonymousClassProperty", + "domain": "NodeTest", + "range": "AnonymousClass", + "type": "owl:ObjectProperty" + } + ], + "propertyAttribute": [ + { + "id": "21to", + "domain": "MultiLink2", + "range": "MultiLink3", + "inverse": "21from", + "type": "owl:ObjectProperty", + "label": "21to" + }, + { + "id": "21from", + "type": "owl:ObjectProperty", + "label": "21from" + }, + { + "id": "22to", + "domain": "MultiLink2", + "range": "MultiLink3", + "inverse": "22from", + "type": "owl:ObjectProperty", + "label": "22to" + }, + { + "id": "22from", + "type": "owl:ObjectProperty", + "label": "22from" + }, + { + "id": "31to", + "domain": "MultiLink3", + "range": "MultiLink4", + "inverse": "31from", + "type": "owl:ObjectProperty", + "label": "31to" + }, + { + "id": "31from", + "type": "owl:ObjectProperty", + "label": "31from" + }, + { + "id": "32to", + "domain": "MultiLink3", + "range": "MultiLink4", + "inverse": "32from", + "type": "owl:ObjectProperty", + "label": "32to" + }, + { + "id": "32from", + "type": "owl:ObjectProperty", + "label": "32from" + }, + { + "id": "33to", + "domain": "MultiLink3", + "range": "MultiLink4", + "inverse": "33from", + "type": "owl:ObjectProperty", + "label": "33to" + }, + { + "id": "33from", + "type": "owl:ObjectProperty", + "label": "33from" + }, + { + "id": "41to", + "domain": "MultiLink4", + "range": "MultiLink5", + "inverse": "41from", + "type": "owl:ObjectProperty", + "label": "41to" + }, + { + "id": "41from", + "type": "owl:ObjectProperty", + "label": "41from" + }, + { + "id": "42to", + "domain": "MultiLink4", + "range": "MultiLink5", + "inverse": "42from", + "type": "owl:ObjectProperty", + "label": "42to" + }, + { + "id": "42from", + "type": "owl:ObjectProperty", + "label": "42from" + }, + { + "id": "43to", + "domain": "MultiLink4", + "range": "MultiLink5", + "inverse": "43from", + "type": "owl:ObjectProperty", + "label": "43to" + }, + { + "id": "43from", + "type": "owl:ObjectProperty", + "label": "43from" + }, + { + "id": "44to", + "domain": "MultiLink4", + "range": "MultiLink5", + "inverse": "44from", + "type": "owl:ObjectProperty", + "label": "44to" + }, + { + "id": "44from", + "type": "owl:ObjectProperty", + "label": "44from" + }, + { + "id": "51to", + "domain": "MultiLink5", + "range": "MultiLinkEnd", + "inverse": "51from", + "type": "owl:ObjectProperty", + "label": "51to" + }, + { + "id": "51from", + "type": "owl:ObjectProperty", + "label": "51from" + }, + { + "id": "52to", + "domain": "MultiLink5", + "range": "MultiLinkEnd", + "inverse": "52from", + "type": "owl:ObjectProperty", + "label": "52to" + }, + { + "id": "52from", + "type": "owl:ObjectProperty", + "label": "52from" + }, + { + "id": "53to", + "domain": "MultiLink5", + "range": "MultiLinkEnd", + "inverse": "53from", + "type": "owl:ObjectProperty", + "label": "53to" + }, + { + "id": "53from", + "type": "owl:ObjectProperty", + "label": "53from" + }, + { + "id": "54to", + "domain": "MultiLink5", + "range": "MultiLinkEnd", + "inverse": "54from", + "type": "owl:ObjectProperty", + "label": "54to" + }, + { + "id": "54from", + "type": "owl:ObjectProperty", + "label": "54from" + }, + { + "id": "55to", + "domain": "MultiLink5", + "range": "MultiLinkEnd", + "inverse": "55from", + "type": "owl:ObjectProperty", + "label": "55to" + }, + { + "id": "55from", + "type": "owl:ObjectProperty", + "label": "55from" + }, + { + "id": "disjoint0Uri", + "domain": "DisjointTest0", + "range": "DisjointTestUri", + "type": "owl:disjointWith" + }, + { + "id": "disjoint02", + "domain": "DisjointTest0", + "range": "DisjointTest2", + "type": "owl:disjointWith" + }, + { + "id": "disjointBridge1", + "domain": "DisjointTest0", + "range": "DisjointTestUri", + "type": "owl:ObjectProperty" + }, + { + "id": "disjointBridge2", + "domain": "DisjointTestUri", + "range": "DisjointTest2", + "type": "owl:ObjectProperty" + }, + { + "id": "testOwlClass", + "domain": "NodeTest", + "range": "OwlClass", + "type": "owl:ObjectProperty" + }, + { + "id": "testOwlEquivalentClass", + "domain": "NodeTest", + "range": "OwlEquivalentClass", + "type": "owl:ObjectProperty" + }, + { + "id": "testOwlThing", + "domain": "NodeTest", + "range": "OwlThing", + "type": "owl:ObjectProperty" + }, + { + "id": "testOwlNothing", + "domain": "NodeTest", + "range": "OwlNothing", + "type": "owl:ObjectProperty" + }, + { + "id": "testRdfsResource", + "domain": "NodeTest", + "range": "RdfsResource", + "type": "owl:ObjectProperty" + }, + { + "id": "testOwlDeprecatedClass", + "domain": "NodeTest", + "range": "OwlDeprecatedClass", + "type": "owl:ObjectProperty" + }, + { + "id": "testRdfsClass", + "domain": "NodeTest", + "range": "RdfsClass", + "type": "owl:ObjectProperty" + }, + { + "id": "testExternalClass", + "domain": "NodeTest", + "range": "ExternalClass", + "type": "owl:ObjectProperty" + }, + { + "id": "testObjectProperty", + "domain": "PropertyTest", + "range": "ObjectPropertyTest", + "type": "owl:ObjectProperty", + "label": "Object" + }, + { + "id": "testInverseObjectProperty", + "inverse": "testInverseObjectPropertyInverse", + "domain": "PropertyTest", + "range": "InverseObjectPropertyTest", + "type": "owl:ObjectProperty", + "label": "Object to" + }, + { + "id": "testInverseObjectPropertyInverse", + "type": "owl:ObjectProperty", + "label": "Object from" + }, + { + "id": "testExternalProperty", + "domain": "PropertyTest", + "range": "ExternalPropertyTest", + "type": "owl:ObjectProperty", + "label": "External" + }, + { + "id": "testDatatypeProperty", + "domain": "PropertyTest", + "range": "DatatypePropertyTest", + "type": "owl:DatatypeProperty", + "label": "Datatype" + }, + { + "id": "testRdfProperty", + "domain": "PropertyTest", + "range": "RdfPropertyTest", + "type": "rdf:Property", + "label": "Rdf" + }, + { + "id": "testDeprecatedProperty", + "domain": "PropertyTest", + "range": "DeprecatedPropertyTest", + "type": "owl:ObjectProperty", + "label": "Deprecated" + }, + { + "id": "testSubClassOfProperty", + "domain": "SubClassOfPropertyTest", + "range": "PropertyTest", + "type": "rdfs:SubClassOf", + "label": "SubClassOf" + }, + { + "id": "testSomeValuesFromProperty", + "domain": "PropertyTest", + "range": "SomeValuesFromPropertyTest", + "type": "owl:someValuesFrom", + "label": "someValuesFrom", + "attributes": [ + "datatype" + ] + }, + { + "id": "testAllValuesFromProperty", + "domain": "PropertyTest", + "range": "AllValuesFromPropertyTest", + "type": "owl:allValuesFrom", + "label": "allValuesFrom" + }, + { + "id": "hoverMeProperty", + "domain": "HoverTest1", + "range": "HoverTest2", + "type": "owl:ObjectProperty", + "label": "Hover me" + }, + { + "id": "highlightedProperty", + "domain": "HoverTest2", + "range": "HoverTest1", + "type": "owl:ObjectProperty", + "label": "Highlighted" + }, + { + "id": "SymmetricFiveEight", + "type": "owl:ObjectProperty", + "domain": "EightSymmetric", + "range": "FiveSymmetric" + }, + { + "id": "EightSymmetric1", + "domain": "EightSymmetric", + "range": "EightSymmetric", + "type": "owl:ObjectProperty", + "label": "1" + }, + { + "id": "EightSymmetric2", + "domain": "EightSymmetric", + "range": "EightSymmetric", + "type": "owl:ObjectProperty", + "label": "2" + }, + { + "id": "EightSymmetric3", + "domain": "EightSymmetric", + "range": "EightSymmetric", + "type": "owl:ObjectProperty", + "label": "3" + }, + { + "id": "EightSymmetric4", + "domain": "EightSymmetric", + "range": "EightSymmetric", + "type": "owl:ObjectProperty", + "label": "4" + }, + { + "id": "EightSymmetric5", + "domain": "EightSymmetric", + "range": "EightSymmetric", + "type": "owl:ObjectProperty", + "label": "5" + }, + { + "id": "EightSymmetric6", + "domain": "EightSymmetric", + "range": "EightSymmetric", + "type": "owl:ObjectProperty", + "label": "6" + }, + { + "id": "EightSymmetric7", + "domain": "EightSymmetric", + "range": "EightSymmetric", + "type": "owl:ObjectProperty", + "label": "7" + }, + { + "id": "EightSymmetric8", + "domain": "EightSymmetric", + "range": "EightSymmetric", + "type": "owl:ObjectProperty", + "label": "8" + }, + { + "id": "FiveSymmetric1", + "domain": "FiveSymmetric", + "range": "FiveSymmetric", + "type": "owl:ObjectProperty", + "label": "1" + }, + { + "id": "FiveSymmetric2", + "domain": "FiveSymmetric", + "range": "FiveSymmetric", + "type": "owl:ObjectProperty", + "label": "2" + }, + { + "id": "FiveSymmetric3", + "domain": "FiveSymmetric", + "range": "FiveSymmetric", + "type": "owl:ObjectProperty", + "label": "3" + }, + { + "id": "FiveSymmetric4", + "domain": "FiveSymmetric", + "range": "FiveSymmetric", + "type": "owl:ObjectProperty", + "label": "4" + }, + { + "id": "FiveSymmetric5", + "domain": "FiveSymmetric", + "range": "FiveSymmetric", + "type": "owl:ObjectProperty", + "label": "5" + }, + { + "id": "UriProperty", + "domain": "UriPropertyTest1", + "range": "UriPropertyTest2", + "type": "owl:ObjectProperty", + "label": "Uri Property", + "iri": "rdf:Group" + }, + { + "id": "DatatypeTestProperty", + "domain": "DatatypeTest", + "range": "DatatypeDatatype", + "type": "owl:ObjectProperty" + }, + { + "id": "LiteralTestProperty", + "domain": "DatatypeTest", + "range": "LiteralDatatype", + "type": "owl:ObjectProperty" + }, + { + "id": "FunctionalProperty", + "type": "owl:FunctionalProperty", + "domain": "IndicationTest1", + "range": "IndicationTest2", + "label": "Functional" + }, + { + "id": "InverseFunctionalProperty", + "type": "owl:InverseFunctionalProperty", + "domain": "IndicationTest1", + "range": "IndicationTest2", + "label": "InverseFunctional" + }, + { + "id": "KeyProperty", + "type": "owl:ObjectProperty", + "domain": "IndicationTest1", + "range": "IndicationTest2", + "label": "hasKey", + "attributes": [ + "key" + ] + }, + { + "id": "TransitiveProperty", + "type": "owl:TransitiveProperty", + "domain": "IndicationTest1", + "range": "IndicationTest2", + "label": "Transitive" + }, + { + "id": "SymmetricProperty", + "type": "owl:SymmetricProperty", + "domain": "IndicationTest1", + "range": "IndicationTest1", + "label": "Symmetric" + }, + { + "id": "EquivalentBaseProperty", + "type": "owl:equivalentProperty", + "equivalent": [ + "EquivalentProperty" + ], + "domain": "IndicationTest1", + "range": "IndicationTest2", + "label": "EquivalentBase" + }, + { + "id": "EquivalentProperty", + "type": "owl:equivalentProperty", + "domain": "IndicationTest1", + "range": "equivalentPropertyTest", + "label": "AnEquivalentProperty" + }, + { + "id": "PropertyFeatureTest", + "type": "owl:ObjectProperty", + "domain": "ClassFeatureTest", + "range": "DatatypeFeatureTest", + "label": "Property Feature Test", + "comment": "Property Feature Test comment" + }, + { + "id": "cardinalityLink1", + "domain": "cardinalityTest1", + "range": "cardinalityTest2", + "inverse": "cardinalityLink2", + "type": "owl:ObjectProperty" + }, + { + "id": "cardinalityLink2", + "domain": "cardinalityTest2", + "range": "cardinalityTest1", + "inverse": "cardinalityLink1", + "type": "owl:ObjectProperty" + }, + { + "id": "cardinalityLink3", + "domain": "cardinalityTest1", + "range": "cardinalityTest3", + "type": "owl:ObjectProperty" + }, + { + "id": "cardinalityLink4", + "domain": "cardinalityTest3", + "range": "cardinalityTest1", + "inverse": "cardinalityLink3", + "type": "owl:ObjectProperty" + } + ] +} diff --git a/src/app/data/foaf.json b/src/app/data/foaf.json new file mode 100644 index 0000000000000000000000000000000000000000..e011b2ef204e9ba4c73457325d53180fdcda489a --- /dev/null +++ b/src/app/data/foaf.json @@ -0,0 +1,3723 @@ +{ + "_comment": "Created with OWL2VOWL (version 0.3.6), http://vowl.visualdataweb.org", + "header": { + "languages": [ + "undefined" + ], + "baseIris": [ + "http://schema.org", + "http://www.w3.org/2000/01/rdf-schema", + "http://www.w3.org/2003/01/geo/wgs84_pos", + "http://purl.org/dc/terms", + "http://www.w3.org/2001/XMLSchema", + "http://xmlns.com/foaf/0.1", + "http://www.w3.org/2000/10/swap/pim/contact", + "http://www.w3.org/2004/02/skos/core" + ], + "prefixList": { + "owl": "http://www.w3.org/2002/07/owl#", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "wot": "http://xmlns.com/wot/0.1/", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "dc": "http://purl.org/dc/elements/1.1/", + "xml": "http://www.w3.org/XML/1998/namespace", + "vs": "http://www.w3.org/2003/06/sw-vocab-status/ns#", + "foaf": "http://xmlns.com/foaf/0.1/", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#" + }, + "title": { + "undefined": "Friend of a Friend (FOAF) vocabulary" + }, + "iri": "http://xmlns.com/foaf/0.1/", + "description": { + "undefined": "The Friend of a Friend (FOAF) RDF vocabulary, described using W3C RDF Schema and the Web Ontology Language." + }, + "other": { + "title": [ + { + "identifier": "title", + "language": "undefined", + "value": "Friend of a Friend (FOAF) vocabulary", + "type": "label" + } + ] + } + }, + "namespace": [], + "class": [ + { + "id": "3", + "type": "owl:Thing" + }, + { + "id": "9", + "type": "owl:Class" + }, + { + "id": "1", + "type": "owl:equivalentClass" + }, + { + "id": "18", + "type": "owl:Thing" + }, + { + "id": "19", + "type": "owl:Thing" + }, + { + "id": "5", + "type": "owl:Thing" + }, + { + "id": "20", + "type": "rdfs:Literal" + }, + { + "id": "8", + "type": "rdfs:Literal" + }, + { + "id": "11", + "type": "owl:Class" + }, + { + "id": "21", + "type": "owl:Thing" + }, + { + "id": "22", + "type": "rdfs:Literal" + }, + { + "id": "24", + "type": "rdfs:Literal" + }, + { + "id": "26", + "type": "rdfs:Literal" + }, + { + "id": "27", + "type": "rdfs:Literal" + }, + { + "id": "37", + "type": "owl:equivalentClass" + }, + { + "id": "45", + "type": "rdfs:Literal" + }, + { + "id": "46", + "type": "rdfs:Literal" + }, + { + "id": "53", + "type": "rdfs:Literal" + }, + { + "id": "56", + "type": "rdfs:Literal" + }, + { + "id": "59", + "type": "rdfs:Literal" + }, + { + "id": "60", + "type": "owl:Class" + }, + { + "id": "61", + "type": "rdfs:Literal" + }, + { + "id": "6", + "type": "rdfs:Literal" + }, + { + "id": "62", + "type": "rdfs:Literal" + }, + { + "id": "12", + "type": "owl:equivalentClass" + }, + { + "id": "55", + "type": "rdfs:Literal" + }, + { + "id": "69", + "type": "rdfs:Literal" + }, + { + "id": "71", + "type": "owl:Class" + }, + { + "id": "36", + "type": "owl:Class" + }, + { + "id": "86", + "type": "owl:Class" + }, + { + "id": "83", + "type": "owl:Class" + }, + { + "id": "94", + "type": "owl:Class" + }, + { + "id": "73", + "type": "rdfs:Literal" + }, + { + "id": "68", + "type": "rdfs:Literal" + }, + { + "id": "93", + "type": "rdfs:Literal" + }, + { + "id": "33", + "type": "owl:Thing" + }, + { + "id": "49", + "type": "rdfs:Literal" + }, + { + "id": "29", + "type": "owl:Thing" + }, + { + "id": "101", + "type": "rdfs:Literal" + }, + { + "id": "39", + "type": "owl:Thing" + }, + { + "id": "63", + "type": "owl:equivalentClass" + }, + { + "id": "64", + "type": "owl:equivalentClass" + }, + { + "id": "102", + "type": "owl:equivalentClass" + }, + { + "id": "78", + "type": "owl:Class" + }, + { + "id": "77", + "type": "owl:Class" + }, + { + "id": "13", + "type": "owl:equivalentClass" + }, + { + "id": "58", + "type": "rdfs:Literal" + }, + { + "id": "100", + "type": "rdfs:Literal" + }, + { + "id": "106", + "type": "rdfs:Literal" + }, + { + "id": "52", + "type": "rdfs:Literal" + }, + { + "id": "88", + "type": "rdfs:Literal" + }, + { + "id": "118", + "type": "rdfs:Literal" + }, + { + "id": "126", + "type": "owl:Class" + }, + { + "id": "2", + "type": "owl:equivalentClass" + }, + { + "id": "32", + "type": "owl:equivalentClass" + }, + { + "id": "10", + "type": "owl:Class" + } + ], + "classAttribute": [ + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "3", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2004/02/skos/core#Concept", + "baseIri": "http://www.w3.org/2004/02/skos/core", + "instances": 0, + "label": { + "IRI-based": "Concept", + "undefined": "Concept" + }, + "attributes": [ + "external" + ], + "id": "9" + }, + { + "iri": "http://xmlns.com/foaf/0.1/Agent", + "equivalent": [ + "13" + ], + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "annotations": { + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "Agent", + "undefined": "Agent" + }, + "subClasses": [ + "10", + "11", + "12" + ], + "comment": { + "undefined": "An agent (eg. person, group, software or physical artifact)." + }, + "attributes": [ + "equivalent" + ], + "id": "1" + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "18", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "19", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "5", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "20", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "8", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://xmlns.com/foaf/0.1/Organization", + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "Organization", + "undefined": "Organization" + }, + "comment": { + "undefined": "An organization." + }, + "id": "11", + "superClasses": [ + "1" + ] + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "21", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "22", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "24", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "26", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "27", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://schema.org/CreativeWork", + "baseIri": "http://schema.org", + "instances": 0, + "label": { + "IRI-based": "CreativeWork" + }, + "attributes": [ + "equivalent", + "external" + ], + "id": "37" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "45", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "46", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "53", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "56", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "59", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://xmlns.com/foaf/0.1/Project", + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "Project", + "undefined": "Project" + }, + "comment": { + "undefined": "A project (a collective endeavour of some kind)." + }, + "id": "60" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "61", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "6", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "62", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://xmlns.com/foaf/0.1/Person", + "equivalent": [ + "63", + "64" + ], + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "Person", + "undefined": "Person" + }, + "comment": { + "undefined": "A person." + }, + "attributes": [ + "equivalent" + ], + "id": "12", + "superClasses": [ + "1", + "36" + ] + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "55", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "69", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://xmlns.com/foaf/0.1/PersonalProfileDocument", + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "annotations": { + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "PersonalProfileDocument", + "undefined": "PersonalProfileDocument" + }, + "comment": { + "undefined": "A personal profile RDF document." + }, + "id": "71", + "superClasses": [ + "2" + ] + }, + { + "iri": "http://www.w3.org/2003/01/geo/wgs84_pos#SpatialThing", + "baseIri": "http://www.w3.org/2003/01/geo/wgs84_pos", + "instances": 0, + "label": { + "IRI-based": "SpatialThing", + "undefined": "Spatial Thing" + }, + "subClasses": [ + "12" + ], + "attributes": [ + "external" + ], + "id": "36" + }, + { + "iri": "http://xmlns.com/foaf/0.1/OnlineChatAccount", + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "unstable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "OnlineChatAccount", + "undefined": "Online Chat Account" + }, + "comment": { + "undefined": "An online chat account." + }, + "id": "86", + "superClasses": [ + "78" + ] + }, + { + "iri": "http://xmlns.com/foaf/0.1/OnlineGamingAccount", + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "unstable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "OnlineGamingAccount", + "undefined": "Online Gaming Account" + }, + "comment": { + "undefined": "An online gaming account." + }, + "id": "83", + "superClasses": [ + "78" + ] + }, + { + "iri": "http://xmlns.com/foaf/0.1/LabelProperty", + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "unstable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "LabelProperty", + "undefined": "Label Property" + }, + "comment": { + "undefined": "A foaf:LabelProperty is any RDF property with texual values that serve as labels." + }, + "id": "94" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "73", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "68", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "93", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "33", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "49", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "29", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "101", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "39", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2000/10/swap/pim/contact#Person", + "baseIri": "http://www.w3.org/2000/10/swap/pim/contact", + "instances": 0, + "label": { + "IRI-based": "Person" + }, + "attributes": [ + "equivalent", + "external" + ], + "id": "63" + }, + { + "iri": "http://schema.org/Person", + "baseIri": "http://schema.org", + "instances": 0, + "label": { + "IRI-based": "Person" + }, + "attributes": [ + "equivalent", + "external" + ], + "id": "64" + }, + { + "iri": "http://schema.org/ImageObject", + "baseIri": "http://schema.org", + "instances": 0, + "label": { + "IRI-based": "ImageObject" + }, + "attributes": [ + "equivalent", + "external" + ], + "id": "102" + }, + { + "iri": "http://xmlns.com/foaf/0.1/OnlineAccount", + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "OnlineAccount", + "undefined": "Online Account" + }, + "subClasses": [ + "77", + "86", + "83" + ], + "comment": { + "undefined": "An online account." + }, + "id": "78" + }, + { + "iri": "http://xmlns.com/foaf/0.1/OnlineEcommerceAccount", + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "unstable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "OnlineEcommerceAccount", + "undefined": "Online E-commerce Account" + }, + "comment": { + "undefined": "An online e-commerce account." + }, + "id": "77", + "superClasses": [ + "78" + ] + }, + { + "iri": "http://purl.org/dc/terms/Agent", + "baseIri": "http://purl.org/dc/terms", + "instances": 0, + "label": { + "IRI-based": "Agent" + }, + "attributes": [ + "equivalent", + "external" + ], + "id": "13" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "58", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "100", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "106", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "52", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "88", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "118", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Class", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "instances": 0, + "label": { + "IRI-based": "Class" + }, + "attributes": [ + "external" + ], + "id": "126" + }, + { + "iri": "http://xmlns.com/foaf/0.1/Document", + "equivalent": [ + "37" + ], + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "Document", + "undefined": "Document" + }, + "subClasses": [ + "71", + "32" + ], + "comment": { + "undefined": "A document." + }, + "attributes": [ + "equivalent" + ], + "id": "2" + }, + { + "iri": "http://xmlns.com/foaf/0.1/Image", + "equivalent": [ + "102" + ], + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "Image", + "undefined": "Image" + }, + "comment": { + "undefined": "An image." + }, + "attributes": [ + "equivalent" + ], + "id": "32", + "superClasses": [ + "2" + ] + }, + { + "iri": "http://xmlns.com/foaf/0.1/Group", + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "annotations": { + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "Group", + "undefined": "Group" + }, + "comment": { + "undefined": "A class of Agents." + }, + "id": "10", + "superClasses": [ + "1" + ] + } + ], + "property": [ + { + "id": "0", + "type": "owl:objectProperty" + }, + { + "id": "4", + "type": "owl:datatypeProperty" + }, + { + "id": "7", + "type": "owl:datatypeProperty" + }, + { + "id": "14", + "type": "owl:objectProperty" + }, + { + "id": "16", + "type": "owl:objectProperty" + }, + { + "id": "17", + "type": "owl:objectProperty" + }, + { + "id": "23", + "type": "owl:objectProperty" + }, + { + "id": "25", + "type": "owl:objectProperty" + }, + { + "id": "28", + "type": "owl:objectProperty" + }, + { + "id": "30", + "type": "owl:objectProperty" + }, + { + "id": "31", + "type": "owl:objectProperty" + }, + { + "id": "35", + "type": "owl:objectProperty" + }, + { + "id": "38", + "type": "owl:objectProperty" + }, + { + "id": "44", + "type": "owl:datatypeProperty" + }, + { + "id": "47", + "type": "owl:objectProperty" + }, + { + "id": "48", + "type": "owl:datatypeProperty" + }, + { + "id": "50", + "type": "owl:objectProperty" + }, + { + "id": "51", + "type": "owl:datatypeProperty" + }, + { + "id": "54", + "type": "owl:datatypeProperty" + }, + { + "id": "57", + "type": "owl:datatypeProperty" + }, + { + "id": "65", + "type": "owl:datatypeProperty" + }, + { + "id": "66", + "type": "owl:datatypeProperty" + }, + { + "id": "67", + "type": "owl:datatypeProperty" + }, + { + "id": "70", + "type": "owl:datatypeProperty" + }, + { + "id": "72", + "type": "owl:datatypeProperty" + }, + { + "id": "15", + "type": "owl:objectProperty" + }, + { + "id": "74", + "type": "rdfs:SubClassOf" + }, + { + "id": "75", + "type": "rdfs:SubClassOf" + }, + { + "id": "76", + "type": "rdfs:SubClassOf" + }, + { + "id": "79", + "type": "rdfs:SubClassOf" + }, + { + "id": "80", + "type": "owl:objectProperty" + }, + { + "id": "81", + "type": "owl:objectProperty" + }, + { + "id": "82", + "type": "rdfs:SubClassOf" + }, + { + "id": "34", + "type": "owl:objectProperty" + }, + { + "id": "85", + "type": "rdfs:SubClassOf" + }, + { + "id": "87", + "type": "owl:datatypeProperty" + }, + { + "id": "89", + "type": "rdfs:SubClassOf" + }, + { + "id": "90", + "type": "rdfs:SubClassOf" + }, + { + "id": "91", + "type": "owl:objectProperty" + }, + { + "id": "92", + "type": "owl:datatypeProperty" + }, + { + "id": "95", + "type": "owl:datatypeProperty" + }, + { + "id": "96", + "type": "owl:objectProperty" + }, + { + "id": "97", + "type": "owl:datatypeProperty" + }, + { + "id": "98", + "type": "rdfs:SubClassOf" + }, + { + "id": "99", + "type": "owl:datatypeProperty" + }, + { + "id": "43", + "type": "owl:objectProperty" + }, + { + "id": "42", + "type": "owl:objectProperty" + }, + { + "id": "103", + "type": "owl:datatypeProperty" + }, + { + "id": "104", + "type": "owl:objectProperty" + }, + { + "id": "105", + "type": "owl:datatypeProperty" + }, + { + "id": "107", + "type": "owl:objectProperty" + }, + { + "id": "108", + "type": "owl:datatypeProperty" + }, + { + "id": "109", + "type": "owl:objectProperty" + }, + { + "id": "110", + "type": "owl:objectProperty" + }, + { + "id": "40", + "type": "owl:objectProperty" + }, + { + "id": "41", + "type": "owl:objectProperty" + }, + { + "id": "84", + "type": "owl:objectProperty" + }, + { + "id": "111", + "type": "owl:datatypeProperty" + }, + { + "id": "112", + "type": "owl:datatypeProperty" + }, + { + "id": "113", + "type": "owl:datatypeProperty" + }, + { + "id": "114", + "type": "owl:objectProperty" + }, + { + "id": "116", + "type": "owl:disjointWith" + }, + { + "id": "117", + "type": "owl:disjointWith" + }, + { + "id": "119", + "type": "owl:datatypeProperty" + }, + { + "id": "120", + "type": "owl:disjointWith" + }, + { + "id": "121", + "type": "owl:disjointWith" + }, + { + "id": "122", + "type": "owl:objectProperty" + }, + { + "id": "123", + "type": "owl:datatypeProperty" + }, + { + "id": "124", + "type": "owl:objectProperty" + }, + { + "id": "125", + "type": "owl:datatypeProperty" + }, + { + "id": "127", + "type": "owl:datatypeProperty" + }, + { + "id": "115", + "type": "owl:objectProperty" + }, + { + "id": "128", + "type": "owl:objectProperty" + }, + { + "id": "129", + "type": "owl:objectProperty" + } + ], + "propertyAttribute": [ + { + "iri": "http://xmlns.com/foaf/0.1/interest", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "interest", + "undefined": "interest" + }, + "domain": "1", + "comment": { + "undefined": "A page about a topic of interest to this person." + }, + "attributes": [ + "object" + ], + "id": "0" + }, + { + "iri": "http://xmlns.com/foaf/0.1/mbox_sha1sum", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "6", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "mbox_sha1sum", + "undefined": "sha1sum of a personal mailbox URI name" + }, + "domain": "5", + "comment": { + "undefined": "The sha1sum of the URI of an Internet mailbox associated with exactly one owner, the first owner of the mailbox." + }, + "attributes": [ + "datatype" + ], + "id": "4" + }, + { + "iri": "http://xmlns.com/foaf/0.1/nick", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "8", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "nick", + "undefined": "nickname" + }, + "domain": "5", + "comment": { + "undefined": "A short informal nickname characterising an agent (includes login identifiers, IRC and other chat nicknames)." + }, + "attributes": [ + "datatype" + ], + "id": "7" + }, + { + "iri": "http://xmlns.com/foaf/0.1/openid", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "openid", + "undefined": "openid" + }, + "superproperty": [ + "15" + ], + "domain": "1", + "comment": { + "undefined": "An OpenID for an Agent." + }, + "attributes": [ + "object", + "inverse functional" + ], + "id": "14" + }, + { + "iri": "http://xmlns.com/foaf/0.1/workInfoHomepage", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "workInfoHomepage", + "undefined": "work info homepage" + }, + "domain": "12", + "comment": { + "undefined": "A work info homepage of some person; a page about their work for some organization." + }, + "attributes": [ + "object" + ], + "id": "16" + }, + { + "iri": "http://xmlns.com/foaf/0.1/pastProject", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "3", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "pastProject", + "undefined": "past project" + }, + "domain": "12", + "comment": { + "undefined": "A project this person has previously worked on." + }, + "attributes": [ + "object" + ], + "id": "17" + }, + { + "iri": "http://xmlns.com/foaf/0.1/theme", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "19", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "archaic", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "theme", + "undefined": "theme" + }, + "domain": "19", + "comment": { + "undefined": "A theme." + }, + "attributes": [ + "object" + ], + "id": "23" + }, + { + "iri": "http://xmlns.com/foaf/0.1/knows", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "12", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "knows", + "undefined": "knows" + }, + "domain": "12", + "comment": { + "undefined": "A person known by this person (indicating some level of reciprocated interaction between the parties)." + }, + "attributes": [ + "object" + ], + "id": "25" + }, + { + "iri": "http://xmlns.com/foaf/0.1/focus", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "29", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "focus", + "undefined": "focus" + }, + "domain": "9", + "comment": { + "undefined": "The underlying or 'focal' entity associated with some SKOS-described concept." + }, + "attributes": [ + "object" + ], + "id": "28" + }, + { + "iri": "http://xmlns.com/foaf/0.1/phone", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "19", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "phone", + "undefined": "phone" + }, + "domain": "19", + "comment": { + "undefined": "A phone, specified using fully qualified tel: URI scheme (refs: http://www.w3.org/Addressing/schemes.html#tel)." + }, + "attributes": [ + "object" + ], + "id": "30" + }, + { + "iri": "http://xmlns.com/foaf/0.1/depicts", + "inverse": "34", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "33", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "depicts", + "undefined": "depicts" + }, + "domain": "32", + "comment": { + "undefined": "A thing depicted in this representation." + }, + "attributes": [ + "object" + ], + "id": "31" + }, + { + "iri": "http://xmlns.com/foaf/0.1/based_near", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "36", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "based_near", + "undefined": "based near" + }, + "domain": "36", + "comment": { + "undefined": "A location that something is based near, for some broadly human notion of near." + }, + "attributes": [ + "object" + ], + "id": "35" + }, + { + "iri": "http://xmlns.com/foaf/0.1/page", + "inverse": "40", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "page", + "undefined": "page" + }, + "domain": "39", + "subproperty": [ + "15", + "41", + "42", + "43" + ], + "comment": { + "undefined": "A page or document about this thing." + }, + "attributes": [ + "object" + ], + "id": "38" + }, + { + "iri": "http://xmlns.com/foaf/0.1/geekcode", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "26", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "archaic", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "geekcode", + "undefined": "geekcode" + }, + "domain": "12", + "comment": { + "undefined": "A textual geekcode for this person, see http://www.geekcode.com/geek.html" + }, + "attributes": [ + "datatype" + ], + "id": "44" + }, + { + "iri": "http://xmlns.com/foaf/0.1/primaryTopic", + "inverse": "15", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "39", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "primaryTopic", + "undefined": "primary topic" + }, + "domain": "2", + "comment": { + "undefined": "The primary topic of some page or document." + }, + "attributes": [ + "functional", + "object" + ], + "id": "47" + }, + { + "iri": "http://xmlns.com/foaf/0.1/givenName", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "49", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "givenName", + "undefined": "Given name" + }, + "domain": "19", + "comment": { + "undefined": "The given name of some person." + }, + "attributes": [ + "datatype" + ], + "id": "48" + }, + { + "iri": "http://xmlns.com/foaf/0.1/schoolHomepage", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "schoolHomepage", + "undefined": "schoolHomepage" + }, + "domain": "12", + "comment": { + "undefined": "A homepage of a school attended by the person." + }, + "attributes": [ + "object" + ], + "id": "50" + }, + { + "iri": "http://xmlns.com/foaf/0.1/gender", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "52", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "gender", + "undefined": "gender" + }, + "domain": "1", + "comment": { + "undefined": "The gender of this Agent (typically but not necessarily 'male' or 'female')." + }, + "attributes": [ + "datatype", + "functional" + ], + "id": "51" + }, + { + "iri": "http://xmlns.com/foaf/0.1/dnaChecksum", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "55", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "archaic", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "dnaChecksum", + "undefined": "DNA checksum" + }, + "domain": "19", + "comment": { + "undefined": "A checksum for the DNA of some thing. Joke." + }, + "attributes": [ + "datatype" + ], + "id": "54" + }, + { + "iri": "http://xmlns.com/foaf/0.1/lastName", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "58", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "lastName", + "undefined": "lastName" + }, + "domain": "12", + "comment": { + "undefined": "The last name of a person." + }, + "attributes": [ + "datatype" + ], + "id": "57" + }, + { + "iri": "http://xmlns.com/foaf/0.1/status", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "45", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "unstable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "status", + "undefined": "status" + }, + "domain": "1", + "comment": { + "undefined": "A string expressing what the user is happy for the general public (normally) to know about their current activity." + }, + "attributes": [ + "datatype" + ], + "id": "65" + }, + { + "iri": "http://xmlns.com/foaf/0.1/yahooChatID", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "46", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "yahooChatID", + "undefined": "Yahoo chat ID" + }, + "domain": "19", + "comment": { + "undefined": "A Yahoo chat ID" + }, + "attributes": [ + "datatype" + ], + "id": "66" + }, + { + "iri": "http://xmlns.com/foaf/0.1/name", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "68", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "name", + "undefined": "name" + }, + "domain": "19", + "comment": { + "undefined": "A name for some thing." + }, + "attributes": [ + "datatype" + ], + "id": "67" + }, + { + "iri": "http://xmlns.com/foaf/0.1/icqChatID", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "53", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "icqChatID", + "undefined": "ICQ chat ID" + }, + "domain": "19", + "comment": { + "undefined": "An ICQ chat ID" + }, + "attributes": [ + "datatype" + ], + "id": "70" + }, + { + "iri": "http://xmlns.com/foaf/0.1/givenname", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "73", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "archaic", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "givenname", + "undefined": "Given name" + }, + "domain": "19", + "comment": { + "undefined": "The given name of some person." + }, + "attributes": [ + "datatype" + ], + "id": "72" + }, + { + "iri": "http://xmlns.com/foaf/0.1/isPrimaryTopicOf", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "isPrimaryTopicOf", + "undefined": "is primary topic of" + }, + "superproperty": [ + "38" + ], + "domain": "39", + "subproperty": [ + "14", + "43" + ], + "comment": { + "undefined": "A document that this thing is the primary topic of." + }, + "attributes": [ + "object", + "inverse functional" + ], + "id": "15" + }, + { + "range": "2", + "domain": "32", + "attributes": [ + "anonymous", + "object" + ], + "id": "74" + }, + { + "range": "2", + "domain": "71", + "attributes": [ + "anonymous", + "object" + ], + "id": "75" + }, + { + "range": "78", + "domain": "77", + "attributes": [ + "anonymous", + "object" + ], + "id": "76" + }, + { + "range": "36", + "domain": "12", + "attributes": [ + "anonymous", + "object" + ], + "id": "79" + }, + { + "iri": "http://xmlns.com/foaf/0.1/accountServiceHomepage", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "accountServiceHomepage", + "undefined": "account service homepage" + }, + "domain": "78", + "comment": { + "undefined": "Indicates a homepage of the service provide for this online account." + }, + "attributes": [ + "object" + ], + "id": "80" + }, + { + "iri": "http://xmlns.com/foaf/0.1/logo", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "19", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "logo", + "undefined": "logo" + }, + "domain": "19", + "comment": { + "undefined": "A logo representing some thing." + }, + "attributes": [ + "object", + "inverse functional" + ], + "id": "81" + }, + { + "range": "78", + "domain": "83", + "attributes": [ + "anonymous", + "object" + ], + "id": "82" + }, + { + "iri": "http://xmlns.com/foaf/0.1/depiction", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "32", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "depiction", + "undefined": "depiction" + }, + "domain": "33", + "subproperty": [ + "84" + ], + "comment": { + "undefined": "A depiction of some thing." + }, + "attributes": [ + "object" + ], + "id": "34" + }, + { + "range": "78", + "domain": "86", + "attributes": [ + "anonymous", + "object" + ], + "id": "85" + }, + { + "iri": "http://xmlns.com/foaf/0.1/family_name", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "88", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "archaic", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "family_name", + "undefined": "family_name" + }, + "domain": "12", + "comment": { + "undefined": "The family name of some person." + }, + "attributes": [ + "datatype" + ], + "id": "87" + }, + { + "range": "1", + "domain": "12", + "attributes": [ + "anonymous", + "object" + ], + "id": "89" + }, + { + "range": "1", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "90" + }, + { + "iri": "http://xmlns.com/foaf/0.1/fundedBy", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "19", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "archaic", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "fundedBy", + "undefined": "funded by" + }, + "domain": "19", + "comment": { + "undefined": "An organization funding a project or person." + }, + "attributes": [ + "object" + ], + "id": "91" + }, + { + "iri": "http://xmlns.com/foaf/0.1/title", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "93", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "title", + "undefined": "title" + }, + "domain": "19", + "comment": { + "undefined": "Title (Mr, Mrs, Ms, Dr. etc)" + }, + "attributes": [ + "datatype" + ], + "id": "92" + }, + { + "iri": "http://xmlns.com/foaf/0.1/accountName", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "59", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "accountName", + "undefined": "account name" + }, + "domain": "78", + "comment": { + "undefined": "Indicates the name (identifier) associated with this online account." + }, + "attributes": [ + "datatype" + ], + "id": "95" + }, + { + "iri": "http://xmlns.com/foaf/0.1/account", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "78", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "account", + "undefined": "account" + }, + "domain": "1", + "comment": { + "undefined": "Indicates an account held by this agent." + }, + "attributes": [ + "object" + ], + "id": "96" + }, + { + "iri": "http://xmlns.com/foaf/0.1/jabberID", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "69", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "jabberID", + "undefined": "jabber ID" + }, + "domain": "19", + "comment": { + "undefined": "A jabber ID for something." + }, + "attributes": [ + "datatype" + ], + "id": "97" + }, + { + "range": "1", + "domain": "10", + "attributes": [ + "anonymous", + "object" + ], + "id": "98" + }, + { + "iri": "http://xmlns.com/foaf/0.1/age", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "100", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "unstable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "age", + "undefined": "age" + }, + "domain": "1", + "comment": { + "undefined": "The age in years of some agent." + }, + "attributes": [ + "datatype", + "functional" + ], + "id": "99" + }, + { + "iri": "http://xmlns.com/foaf/0.1/homepage", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "homepage", + "undefined": "homepage" + }, + "superproperty": [ + "15", + "38" + ], + "domain": "39", + "comment": { + "undefined": "A homepage for some thing." + }, + "attributes": [ + "object", + "inverse functional" + ], + "id": "43" + }, + { + "iri": "http://xmlns.com/foaf/0.1/tipjar", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "tipjar", + "undefined": "tipjar" + }, + "superproperty": [ + "38" + ], + "domain": "1", + "comment": { + "undefined": "A tipjar document for this agent, describing means for payment and reward." + }, + "attributes": [ + "object" + ], + "id": "42" + }, + { + "iri": "http://xmlns.com/foaf/0.1/msnChatID", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "61", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "msnChatID", + "undefined": "MSN chat ID" + }, + "domain": "5", + "comment": { + "undefined": "An MSN chat ID" + }, + "attributes": [ + "datatype" + ], + "id": "103" + }, + { + "iri": "http://xmlns.com/foaf/0.1/topic_interest", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "18", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "topic_interest", + "undefined": "topic_interest" + }, + "domain": "1", + "comment": { + "undefined": "A thing of interest to this person." + }, + "attributes": [ + "object" + ], + "id": "104" + }, + { + "iri": "http://xmlns.com/foaf/0.1/aimChatID", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "106", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "aimChatID", + "undefined": "AIM chat ID" + }, + "domain": "19", + "comment": { + "undefined": "An AIM chat ID" + }, + "attributes": [ + "datatype" + ], + "id": "105" + }, + { + "iri": "http://xmlns.com/foaf/0.1/currentProject", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "3", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "currentProject", + "undefined": "current project" + }, + "domain": "12", + "comment": { + "undefined": "A current project this person works on." + }, + "attributes": [ + "object" + ], + "id": "107" + }, + { + "iri": "http://xmlns.com/foaf/0.1/skypeID", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "20", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "skypeID", + "undefined": "Skype ID" + }, + "domain": "1", + "comment": { + "undefined": "A Skype ID" + }, + "attributes": [ + "datatype" + ], + "id": "108" + }, + { + "iri": "http://xmlns.com/foaf/0.1/holdsAccount", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "78", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "archaic", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "holdsAccount", + "undefined": "account" + }, + "domain": "1", + "comment": { + "undefined": "Indicates an account held by this agent." + }, + "attributes": [ + "object" + ], + "id": "109" + }, + { + "iri": "http://xmlns.com/foaf/0.1/thumbnail", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "32", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "thumbnail", + "undefined": "thumbnail" + }, + "domain": "32", + "comment": { + "undefined": "A derived thumbnail image." + }, + "attributes": [ + "object" + ], + "id": "110" + }, + { + "iri": "http://xmlns.com/foaf/0.1/topic", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "39", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "topic", + "undefined": "topic" + }, + "domain": "2", + "comment": { + "undefined": "A topic of some page or document." + }, + "attributes": [ + "object" + ], + "id": "40" + }, + { + "iri": "http://xmlns.com/foaf/0.1/weblog", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "weblog", + "undefined": "weblog" + }, + "superproperty": [ + "38" + ], + "domain": "1", + "comment": { + "undefined": "A weblog of some thing (whether person, group, company etc.)." + }, + "attributes": [ + "object", + "inverse functional" + ], + "id": "41" + }, + { + "iri": "http://xmlns.com/foaf/0.1/img", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "32", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "img", + "undefined": "image" + }, + "superproperty": [ + "34" + ], + "domain": "12", + "comment": { + "undefined": "An image that can be used to represent some thing (ie. those depictions which are particularly representative of something, eg. one's photo on a homepage)." + }, + "attributes": [ + "object" + ], + "id": "84" + }, + { + "iri": "http://xmlns.com/foaf/0.1/birthday", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "56", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "unstable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "birthday", + "undefined": "birthday" + }, + "domain": "1", + "comment": { + "undefined": "The birthday of this Agent, represented in mm-dd string form, eg. '12-31'." + }, + "attributes": [ + "datatype", + "functional" + ], + "id": "111" + }, + { + "iri": "http://xmlns.com/foaf/0.1/sha1", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "101", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "unstable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "sha1", + "undefined": "sha1sum (hex)" + }, + "domain": "2", + "comment": { + "undefined": "A sha1sum hash, in hex." + }, + "attributes": [ + "datatype" + ], + "id": "112" + }, + { + "iri": "http://xmlns.com/foaf/0.1/firstName", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "24", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "firstName", + "undefined": "firstName" + }, + "domain": "12", + "comment": { + "undefined": "The first name of a person." + }, + "attributes": [ + "datatype" + ], + "id": "113" + }, + { + "iri": "http://xmlns.com/foaf/0.1/made", + "inverse": "115", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "18", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "made", + "undefined": "made" + }, + "domain": "1", + "comment": { + "undefined": "Something that was made by this agent." + }, + "attributes": [ + "object" + ], + "id": "114" + }, + { + "range": "60", + "domain": "2", + "attributes": [ + "anonymous", + "object" + ], + "id": "116" + }, + { + "range": "12", + "domain": "60", + "attributes": [ + "anonymous", + "object" + ], + "id": "117" + }, + { + "iri": "http://xmlns.com/foaf/0.1/familyName", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "62", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "familyName", + "undefined": "familyName" + }, + "domain": "12", + "comment": { + "undefined": "The family name of some person." + }, + "attributes": [ + "datatype" + ], + "id": "119" + }, + { + "range": "2", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "120" + }, + { + "range": "12", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "121" + }, + { + "iri": "http://xmlns.com/foaf/0.1/member", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "member", + "undefined": "member" + }, + "domain": "10", + "comment": { + "undefined": "Indicates a member of a Group" + }, + "attributes": [ + "object" + ], + "id": "122" + }, + { + "iri": "http://xmlns.com/foaf/0.1/plan", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "27", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "plan", + "undefined": "plan" + }, + "domain": "12", + "comment": { + "undefined": "A .plan comment, in the tradition of finger and '.plan' files." + }, + "attributes": [ + "datatype" + ], + "id": "123" + }, + { + "iri": "http://xmlns.com/foaf/0.1/mbox", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "18", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "mbox", + "undefined": "personal mailbox" + }, + "domain": "1", + "comment": { + "undefined": "A personal mailbox, ie. an Internet mailbox associated with exactly one owner, the first owner of this mailbox. This is a 'static inverse functional property', in that there is (across time and change) at most one individual that ever has any particular value for foaf:mbox." + }, + "attributes": [ + "object", + "inverse functional" + ], + "id": "124" + }, + { + "iri": "http://xmlns.com/foaf/0.1/surname", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "118", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "archaic", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "surname", + "undefined": "Surname" + }, + "domain": "12", + "comment": { + "undefined": "The surname of some person." + }, + "attributes": [ + "datatype" + ], + "id": "125" + }, + { + "iri": "http://xmlns.com/foaf/0.1/myersBriggs", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "22", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "myersBriggs", + "undefined": "myersBriggs" + }, + "domain": "12", + "comment": { + "undefined": "A Myers Briggs (MBTI) personality classification." + }, + "attributes": [ + "datatype" + ], + "id": "127" + }, + { + "iri": "http://xmlns.com/foaf/0.1/maker", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "stable", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "maker", + "undefined": "maker" + }, + "domain": "18", + "comment": { + "undefined": "An agent that made this thing." + }, + "attributes": [ + "object" + ], + "id": "115" + }, + { + "iri": "http://xmlns.com/foaf/0.1/publications", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "publications", + "undefined": "publications" + }, + "domain": "12", + "comment": { + "undefined": "A link to the publications of this person." + }, + "attributes": [ + "object" + ], + "id": "128" + }, + { + "iri": "http://xmlns.com/foaf/0.1/workplaceHomepage", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://xmlns.com/foaf/0.1/", + "type": "iri" + } + ], + "term_status": [ + { + "identifier": "term_status", + "language": "undefined", + "value": "testing", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "workplaceHomepage", + "undefined": "workplace homepage" + }, + "domain": "12", + "comment": { + "undefined": "A workplace homepage of some person; the homepage of an organization they work for." + }, + "attributes": [ + "object" + ], + "id": "129" + } + ] +} \ No newline at end of file diff --git a/src/app/data/goodrelations.json b/src/app/data/goodrelations.json new file mode 100644 index 0000000000000000000000000000000000000000..6bac4d6fe099e04f33342b5707a83893fdf689ca --- /dev/null +++ b/src/app/data/goodrelations.json @@ -0,0 +1,8961 @@ +{ + "_comment": "Created with OWL2VOWL (version 0.3.4), http://vowl.visualdataweb.org", + "header": { + "languages": [ + "en", + "undefined" + ], + "baseIris": [ + "http://www.w3.org/1999/02/22-rdf-syntax-ns", + "http://schema.org", + "http://purl.org/goodrelations/v1", + "http://www.w3.org/2000/01/rdf-schema", + "http://www.w3.org/2001/XMLSchema", + "http://xmlns.com/foaf/0.1" + ], + "title": { + "en": "The GoodRelations Vocabulary for Semantic Web-based E-Commerce" + }, + "iri": "http://purl.org/goodrelations/v1", + "version": "V 1.0, Release 2011-10-01", + "author": [ + "Martin Hepp" + ], + "labels": { + "en": "GoodRelations Ontology" + }, + "comments": { + "en": "The GoodRelations ontology provides the vocabulary for annotating e-commerce offerings (1) to sell, lease, repair, dispose, or maintain commodity products and (2) to provide commodity services.\n\nGoodRelations allows describing the relationship between (1) Web resources, (2) offerings made by those Web resources, (3) legal entities, (4) prices, (5) terms and conditions, and the aforementioned ontologies for products and services (6).\n \nFor more information, see http://purl.org/goodrelations/\n\nNote: The base URI of GoodRelations is http://purl.org/goodrelations/v1. Please make sure you are only using element identifiers in this namespace, e.g. http://purl.org/goodrelations/v1#BusinessEntity. There may be copies of the ontology file on the Web which can be retrieved from other locations, BUT THOSE LOCATIONS MUST NOT BE USED AS THE BASIS OF IDENTIFIERS.\n\nIf you use GoodRelations for scientific purposes, please cite our paper:\n\nHepp, Martin: GoodRelations: An Ontology for Describing Products and Services Offers on the Web, Proceedings of the 16th International Conference on Knowledge Engineering and Knowledge Management (EKAW2008), September 29 - October 3, 2008, Acitrezza, Italy, Springer LNCS, Vol. 5268, pp. 332-347.\n\nPDF at http://www.heppnetz.de/publications/" + }, + "other": { + "license": [ + { + "identifier": "license", + "language": "undefined", + "value": "http://creativecommons.org/licenses/by/3.0/", + "type": "iri" + } + ], + "creator": [ + { + "identifier": "creator", + "language": "en", + "value": "Martin Hepp", + "type": "label" + } + ], + "contributor": [ + { + "identifier": "contributor", + "language": "en", + "value": "Work on the GoodRelations ontology and related research and development has been partly supported by the Austrian BMVIT/FFG under the FIT-IT Semantic Systems project myOntology (grant no. 812515/9284), by a Young Researcher's Grant (Nachwuchsfoerderung 2005-2006) from the Leopold-Franzens-Universitaet Innsbruck, by the European Commission under the project SUPER (FP6-026850), and by the German Federal Ministry of Research (BMBF) by a grant under the KMU Innovativ program as part of the Intelligent Match project (FKZ 01IS10022B). The", + "type": "label" + } + ], + "subject": [ + { + "identifier": "subject", + "language": "en", + "value": "E-Commerce, E-Business, GoodRelations, Microdata, Ontology, Semantic SEO, RDFa, Linked Data, RDF, Semantic Web, Recommender Systems", + "type": "label" + } + ], + "rights": [ + { + "identifier": "rights", + "language": "en", + "value": "The GoodRelations ontology is available under the Creative Commons Attribution 3.0 Unported license; see http://creativecommons.org/licenses/by/3.0/. In a nutshell, you are free to copy, distribute and transmit the work; to remix/adapt the work (e.g. to import the ontology and create specializations of its elements), as long as you attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work). Proper Attribution: Simply include the statement \"This work is based on the GoodRelations ontology, developed by Martin Hepp\" and link back to http://purl.org/goodrelations/", + "type": "label" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "en", + "value": "V 1.0, Release 2011-10-01", + "type": "label" + } + ], + "title": [ + { + "identifier": "title", + "language": "en", + "value": "The GoodRelations Vocabulary for Semantic Web-based E-Commerce", + "type": "label" + } + ], + "homepage": [ + { + "identifier": "homepage", + "language": "undefined", + "value": "http://purl.org/goodrelations/", + "type": "iri" + } + ] + } + }, + "namespace": [], + "metrics": { + "classCount": 38, + "objectPropertyCount": 53, + "datatypePropertyCount": 49, + "individualCount": 46 + }, + "class": [ + { + "id": "3", + "type": "owl:unionOf" + }, + { + "id": "9", + "type": "rdfs:Datatype" + }, + { + "id": "12", + "type": "owl:Thing" + }, + { + "id": "15", + "type": "rdfs:Literal" + }, + { + "id": "17", + "type": "rdfs:Literal" + }, + { + "id": "19", + "type": "rdfs:Literal" + }, + { + "id": "32", + "type": "owl:unionOf" + }, + { + "id": "37", + "type": "rdfs:Datatype" + }, + { + "id": "39", + "type": "rdfs:Datatype" + }, + { + "id": "31", + "type": "rdfs:Datatype" + }, + { + "id": "43", + "type": "rdfs:Datatype" + }, + { + "id": "45", + "type": "owl:unionOf" + }, + { + "id": "51", + "type": "rdfs:Datatype" + }, + { + "id": "55", + "type": "owl:unionOf" + }, + { + "id": "57", + "type": "rdfs:Datatype" + }, + { + "id": "60", + "type": "owl:unionOf" + }, + { + "id": "62", + "type": "rdfs:Datatype" + }, + { + "id": "72", + "type": "owl:unionOf" + }, + { + "id": "84", + "type": "rdfs:Literal" + }, + { + "id": "85", + "type": "rdfs:Datatype" + }, + { + "id": "86", + "type": "owl:unionOf" + }, + { + "id": "87", + "type": "rdfs:Datatype" + }, + { + "id": "88", + "type": "rdfs:Literal" + }, + { + "id": "89", + "type": "rdfs:Datatype" + }, + { + "id": "8", + "type": "owl:Class" + }, + { + "id": "66", + "type": "rdfs:Datatype" + }, + { + "id": "90", + "type": "rdfs:Datatype" + }, + { + "id": "92", + "type": "owl:unionOf" + }, + { + "id": "93", + "type": "rdfs:Literal" + }, + { + "id": "14", + "type": "owl:equivalentClass" + }, + { + "id": "98", + "type": "owl:unionOf" + }, + { + "id": "99", + "type": "rdfs:Datatype" + }, + { + "id": "100", + "type": "rdfs:Literal" + }, + { + "id": "101", + "type": "rdfs:Datatype" + }, + { + "id": "103", + "type": "rdfs:Datatype" + }, + { + "id": "104", + "type": "rdfs:Datatype" + }, + { + "id": "105", + "type": "rdfs:Literal" + }, + { + "id": "108", + "type": "rdfs:Datatype" + }, + { + "id": "28", + "type": "owl:Class" + }, + { + "id": "109", + "type": "rdfs:Datatype" + }, + { + "id": "110", + "type": "owl:unionOf" + }, + { + "id": "111", + "type": "rdfs:Datatype" + }, + { + "id": "80", + "type": "owl:Class" + }, + { + "id": "68", + "type": "owl:Class" + }, + { + "id": "117", + "type": "owl:unionOf" + }, + { + "id": "118", + "type": "owl:unionOf" + }, + { + "id": "119", + "type": "owl:unionOf" + }, + { + "id": "120", + "type": "owl:unionOf" + }, + { + "id": "41", + "type": "owl:Class" + }, + { + "id": "125", + "type": "owl:unionOf" + }, + { + "id": "126", + "type": "owl:unionOf" + }, + { + "id": "129", + "type": "owl:unionOf" + }, + { + "id": "130", + "type": "owl:unionOf" + }, + { + "id": "131", + "type": "owl:unionOf" + }, + { + "id": "113", + "type": "owl:unionOf" + }, + { + "id": "132", + "type": "owl:unionOf" + }, + { + "id": "135", + "type": "owl:unionOf" + }, + { + "id": "136", + "type": "owl:unionOf" + }, + { + "id": "137", + "type": "owl:unionOf" + }, + { + "id": "138", + "type": "owl:unionOf" + }, + { + "id": "1", + "type": "owl:Class" + }, + { + "id": "144", + "type": "owl:unionOf" + }, + { + "id": "145", + "type": "owl:unionOf" + }, + { + "id": "107", + "type": "owl:unionOf" + }, + { + "id": "146", + "type": "owl:unionOf" + }, + { + "id": "147", + "type": "owl:unionOf" + }, + { + "id": "148", + "type": "owl:unionOf" + }, + { + "id": "25", + "type": "owl:unionOf" + }, + { + "id": "122", + "type": "owl:unionOf" + }, + { + "id": "152", + "type": "owl:unionOf" + }, + { + "id": "153", + "type": "owl:unionOf" + }, + { + "id": "154", + "type": "owl:unionOf" + }, + { + "id": "115", + "type": "owl:unionOf" + }, + { + "id": "157", + "type": "owl:unionOf" + }, + { + "id": "124", + "type": "owl:unionOf" + }, + { + "id": "165", + "type": "owl:unionOf" + }, + { + "id": "180", + "type": "owl:unionOf" + }, + { + "id": "82", + "type": "owl:Class" + }, + { + "id": "5", + "type": "owl:unionOf" + }, + { + "id": "197", + "type": "owl:Class" + }, + { + "id": "74", + "type": "owl:Class" + }, + { + "id": "34", + "type": "owl:Class" + }, + { + "id": "94", + "type": "owl:equivalentClass" + }, + { + "id": "46", + "type": "owl:equivalentClass" + }, + { + "id": "78", + "type": "owl:Class" + }, + { + "id": "6", + "type": "owl:Class" + }, + { + "id": "75", + "type": "owl:Class" + }, + { + "id": "76", + "type": "owl:Class" + }, + { + "id": "95", + "type": "owl:equivalentClass" + }, + { + "id": "21", + "type": "owl:Class" + }, + { + "id": "331", + "type": "owl:equivalentClass" + }, + { + "id": "47", + "type": "owl:equivalentClass" + }, + { + "id": "133", + "type": "owl:equivalentClass" + }, + { + "id": "11", + "type": "owl:Class" + }, + { + "id": "50", + "type": "owl:Class" + }, + { + "id": "23", + "type": "owl:equivalentClass" + }, + { + "id": "65", + "type": "owl:Class" + }, + { + "id": "4", + "type": "owl:Class" + }, + { + "id": "81", + "type": "owl:Class" + }, + { + "id": "30", + "type": "owl:Class" + }, + { + "id": "2", + "type": "owl:Class" + }, + { + "id": "33", + "type": "owl:Class" + }, + { + "id": "183", + "type": "owl:unionOf" + }, + { + "id": "184", + "type": "rdfs:Datatype" + }, + { + "id": "140", + "type": "owl:unionOf" + }, + { + "id": "73", + "type": "owl:Class" + }, + { + "id": "141", + "type": "rdfs:Datatype" + }, + { + "id": "264", + "type": "owl:unionOf" + }, + { + "id": "265", + "type": "rdfs:Datatype" + }, + { + "id": "348", + "type": "owl:unionOf" + }, + { + "id": "350", + "type": "rdfs:Datatype" + }, + { + "id": "317", + "type": "owl:unionOf" + }, + { + "id": "318", + "type": "rdfs:Datatype" + }, + { + "id": "322", + "type": "rdfs:Datatype" + }, + { + "id": "79", + "type": "owl:Class" + }, + { + "id": "359", + "type": "rdfs:Literal" + }, + { + "id": "128", + "type": "rdfs:Datatype" + }, + { + "id": "356", + "type": "owl:unionOf" + }, + { + "id": "357", + "type": "rdfs:Datatype" + }, + { + "id": "343", + "type": "rdfs:Datatype" + }, + { + "id": "216", + "type": "rdfs:Datatype" + }, + { + "id": "353", + "type": "owl:unionOf" + }, + { + "id": "354", + "type": "rdfs:Datatype" + }, + { + "id": "321", + "type": "owl:unionOf" + }, + { + "id": "314", + "type": "rdfs:Literal" + }, + { + "id": "361", + "type": "owl:unionOf" + }, + { + "id": "49", + "type": "owl:Class" + }, + { + "id": "200", + "type": "owl:unionOf" + }, + { + "id": "201", + "type": "rdfs:Literal" + }, + { + "id": "338", + "type": "rdfs:Datatype" + }, + { + "id": "364", + "type": "owl:unionOf" + }, + { + "id": "365", + "type": "rdfs:Literal" + }, + { + "id": "366", + "type": "owl:unionOf" + }, + { + "id": "367", + "type": "rdfs:Literal" + }, + { + "id": "313", + "type": "owl:unionOf" + }, + { + "id": "368", + "type": "owl:unionOf" + }, + { + "id": "371", + "type": "rdfs:Datatype" + }, + { + "id": "220", + "type": "rdfs:Datatype" + }, + { + "id": "377", + "type": "owl:unionOf" + }, + { + "id": "378", + "type": "owl:unionOf" + }, + { + "id": "303", + "type": "owl:unionOf" + }, + { + "id": "311", + "type": "owl:unionOf" + }, + { + "id": "71", + "type": "rdfs:Datatype" + }, + { + "id": "328", + "type": "owl:unionOf" + }, + { + "id": "329", + "type": "rdfs:Datatype" + }, + { + "id": "77", + "type": "owl:equivalentClass" + }, + { + "id": "35", + "type": "owl:Class" + } + ], + "classAttribute": [ + { + "instances": 0, + "union": [ + "4", + "5", + "6" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "3" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "9", + "label": { + "IRI-based": "string" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "12", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "15", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "17", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "19", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "instances": 0, + "union": [ + "33", + "30", + "34", + "35", + "2" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "32" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#dateTime", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "37", + "label": { + "IRI-based": "dateTime" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#boolean", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "39", + "label": { + "IRI-based": "boolean" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#time", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "31", + "label": { + "IRI-based": "time" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "43", + "label": { + "IRI-based": "string" + } + }, + { + "instances": 0, + "union": [ + "46", + "33", + "47" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "45" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "51", + "label": { + "IRI-based": "string" + } + }, + { + "instances": 0, + "union": [ + "4", + "5", + "6" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "55" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "57", + "label": { + "IRI-based": "string" + } + }, + { + "instances": 0, + "union": [ + "33", + "30", + "34", + "35", + "2" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "60" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#dateTime", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "62", + "label": { + "IRI-based": "dateTime" + } + }, + { + "instances": 0, + "union": [ + "41", + "8", + "49", + "5", + "14", + "50", + "23", + "33", + "30", + "73", + "74", + "65", + "21", + "75", + "76", + "77", + "47", + "78", + "28", + "1", + "79", + "80", + "2", + "81", + "11", + "68", + "82" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "72" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "84", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "85", + "label": { + "IRI-based": "string" + } + }, + { + "instances": 0, + "union": [ + "8", + "1", + "49" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "86" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "87", + "label": { + "IRI-based": "string" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "88", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#float", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "89", + "label": { + "IRI-based": "float" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#TypeAndQuantityNode", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "TypeAndQuantityNode", + "en": "Type and quantity node" + }, + "comment": { + "en": "This class collates all the information about a gr:ProductOrService included in a bundle. If a gr:Offering contains just one item, you can directly link from the gr:Offering to the gr:ProductOrService using gr:includes. If the offering contains multiple items, use an instance of this class for each component to indicate the quantity, unit of measurement, and type of product, and link from the gr:Offering via gr:includesObject.\n\nExample: An offering may include of 100g of Butter and 1 kg of potatoes, or 1 cell phone and 2 headsets." + }, + "id": "8" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#int", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "66", + "label": { + "IRI-based": "int" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#boolean", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "90", + "label": { + "IRI-based": "boolean" + } + }, + { + "instances": 0, + "union": [ + "4", + "5" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "92" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "93", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#ProductOrService", + "equivalent": [ + "46" + ], + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "ProductOrService", + "en": "Product or service" + }, + "subClasses": [ + "23", + "47", + "28", + "94", + "95" + ], + "comment": { + "en": "The superclass of all classes describing products or services types, either by nature or purpose. Examples for such subclasses are \"TV set\", \"vacuum cleaner\", etc. An instance of this class can be either an actual product or service (gr:Individual), a placeholder instance for unknown instances of a mass-produced commodity (gr:SomeItems), or a model / prototype specification (gr:ProductOrServiceModel). When in doubt, use gr:SomeItems.\n\nExamples: \na) MyCellphone123, i.e. my personal, tangible cell phone (gr:Individual)\nb) Siemens1234, i.e. the Siemens cell phone make and model 1234 (gr:ProductOrServiceModel)\nc) dummyCellPhone123 as a placeholder for actual instances of a certain kind of cell phones (gr:SomeItems)\n\t\nNote: Your first choice for specializations of gr:ProductOrService should be http://www.productontology.org.\n\nCompatibility with schema.org: This class is (approximately) equivalent to http://schema.org/Product." + }, + "attributes": [ + "equivalent" + ], + "id": "14" + }, + { + "instances": 0, + "union": [ + "46", + "33", + "34", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "98" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#float", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "99", + "label": { + "IRI-based": "float" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "100", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#float", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "101", + "label": { + "IRI-based": "float" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#int", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "103", + "label": { + "IRI-based": "int" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#float", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "104", + "label": { + "IRI-based": "float" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "105", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#float", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "108", + "label": { + "IRI-based": "float" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#ProductOrServiceModel", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "ProductOrServiceModel", + "en": "Product or service model" + }, + "comment": { + "en": "A product or service model is a intangible entity that specifies some characteristics of a group of similar, usually mass-produced products, in the sense of a prototype. In case of mass-produced products, there exists a relation gr:hasMakeAndModel between the actual product or service (gr:Individual or gr:SomeItems) and the prototype (gr:ProductOrServiceModel). GoodRelations treats product or service models as \"prototypes\" instead of a completely separate kind of entities, because this allows using the same domain-specific properties (e.g. gr:weight) for describing makes and models and for describing actual products.\n\nExamples: Ford T, Volkswagen Golf, Sony Ericsson W123 cell phone\n\nNote: An actual product or service (gr:Individual) by default shares the features of its model (e.g. the weight). However, this requires non-standard reasoning. See http://wiki.goodrelations-vocabulary.org/Axioms for respective rule sets.\n\t\nCompatibility with schema.org: This class is (approximately) a subclass of http://schema.org/Product." + }, + "id": "28", + "superClasses": [ + "46", + "14" + ] + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#int", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "109", + "label": { + "IRI-based": "int" + } + }, + { + "instances": 0, + "union": [ + "4", + "5" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "110" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#int", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "111", + "label": { + "IRI-based": "int" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#DayOfWeek", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "DayOfWeek", + "en": "Day of week" + }, + "individuals": [ + { + "iri": "http://purl.org/goodrelations/v1#Thursday", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ], + "displayPosition": [ + { + "identifier": "displayPosition", + "language": "undefined", + "value": "4", + "type": "label" + } + ] + }, + "comment": { + "en": "Thursday as a day of the week." + }, + "labels": { + "IRI-based": "Thursday", + "en": "Thursday (day of week)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Sunday", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ], + "displayPosition": [ + { + "identifier": "displayPosition", + "language": "undefined", + "value": "7", + "type": "label" + } + ] + }, + "comment": { + "en": "Sunday as a day of the week." + }, + "labels": { + "IRI-based": "Sunday", + "en": "Sunday (day of week)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Monday", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ], + "displayPosition": [ + { + "identifier": "displayPosition", + "language": "undefined", + "value": "1", + "type": "label" + } + ] + }, + "comment": { + "en": "Monday as a day of the week." + }, + "labels": { + "IRI-based": "Monday", + "en": "Monday (day of week)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Tuesday", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ], + "displayPosition": [ + { + "identifier": "displayPosition", + "language": "undefined", + "value": "2", + "type": "label" + } + ] + }, + "comment": { + "en": "Tuesday as a day of the week." + }, + "labels": { + "IRI-based": "Tuesday", + "en": "Tuesday (day of week)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Friday", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ], + "displayPosition": [ + { + "identifier": "displayPosition", + "language": "undefined", + "value": "5", + "type": "label" + } + ] + }, + "comment": { + "en": "Friday as a day of the week." + }, + "labels": { + "IRI-based": "Friday", + "en": "Friday (day of week)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#PublicHolidays", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ], + "displayPosition": [ + { + "identifier": "displayPosition", + "language": "undefined", + "value": "8", + "type": "label" + } + ] + }, + "comment": { + "en": "A placeholder for all official public holidays at the gr:Location. This allows specifying the opening hours on public holidays. If a given day is a public holiday, this specification supersedes the opening hours for the respective day of the week." + }, + "labels": { + "IRI-based": "PublicHolidays", + "en": "Public holidays (day of week)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Saturday", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ], + "displayPosition": [ + { + "identifier": "displayPosition", + "language": "undefined", + "value": "6", + "type": "label" + } + ] + }, + "comment": { + "en": "Saturday as a day of the week." + }, + "labels": { + "IRI-based": "Saturday", + "en": "Saturday (day of week)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Wednesday", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ], + "displayPosition": [ + { + "identifier": "displayPosition", + "language": "undefined", + "value": "3", + "type": "label" + } + ] + }, + "comment": { + "en": "Wednesday as a day of the week." + }, + "labels": { + "IRI-based": "Wednesday", + "en": "Wednesday (day of week)" + } + } + ], + "comment": { + "en": "The day of the week, used to specify to which day the opening hours of a gr:OpeningHoursSpecification refer.\n\nExamples: Monday, Tuesday, Wednesday,..." + }, + "id": "80" + }, + { + "iri": "http://purl.org/goodrelations/v1#QualitativeValue", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "QualitativeValue", + "en": "Qualitative value" + }, + "comment": { + "en": "A qualitative value is a predefined value for a product characteristic. \n\t\nExamples: the color \"green\" or the power cord plug type \"US\"; the garment sizes \"S\", \"M\", \"L\", and \"XL\".\n\t\nNote: Value sets are supported by creating subclasses of this class. Ordinal relations between values (gr:greater, gr:lesser, ...) are provided directly by GoodRelations.\n\nCompatibility with schema.org: This class is equivalent to http://schema.org/Enumeration." + }, + "id": "68" + }, + { + "instances": 0, + "union": [ + "46", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "117" + }, + { + "instances": 0, + "union": [ + "46", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "118" + }, + { + "instances": 0, + "union": [ + "4", + "5", + "6" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "119" + }, + { + "instances": 0, + "union": [ + "23", + "47" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "120" + }, + { + "iri": "http://purl.org/goodrelations/v1#PaymentMethod", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "PaymentMethod", + "en": "Payment method" + }, + "individuals": [ + { + "iri": "http://purl.org/goodrelations/v1#CheckInAdvance", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Payment by sending a check in advance, i.e., the offering gr:BusinessEntity will deliver the goods upon receipt of a check over the due amount. There are variations in handling payment by check - sometimes, shipment will be upon receipt of the check as a document, sometimes the shipment will take place only upon successful crediting of the check." + }, + "labels": { + "IRI-based": "CheckInAdvance", + "en": "Check in advance (payment method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#PayPal", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Payment via the PayPal payment service." + }, + "labels": { + "IRI-based": "PayPal", + "en": "PayPal (payment method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Cash", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Payment by cash upon delivery or pickup." + }, + "labels": { + "IRI-based": "Cash", + "en": "Cash (payment method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#COD", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Collect on delivery / Cash on delivery - A payment method where the recipient of goods pays at the time of delivery. Usually, the amount of money is collected by the transportation company handling the goods." + }, + "labels": { + "IRI-based": "COD", + "en": "COD (payment method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#ByInvoice", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Payment by bank transfer after delivery, i.e., the offering gr:BusinessEntity will deliver first, inform the buying party about the due amount and their bank account details, and expect payment shortly after delivery." + }, + "labels": { + "IRI-based": "ByInvoice", + "en": "By invoice (payment method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#GoogleCheckout", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Payment via the Google Checkout payment service." + }, + "labels": { + "IRI-based": "GoogleCheckout", + "en": "Google Checkout (payment method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#ByBankTransferInAdvance", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Payment by bank transfer in advance, i.e., the offering gr:BusinessEntity will inform the buying party about their bank account details and will deliver the goods upon receipt of the due amount.\nThis is equivalent to payment by wire transfer." + }, + "labels": { + "IRI-based": "ByBankTransferInAdvance", + "en": "By bank transfer in advance (payment method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#PaySwarm", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Payment via the PaySwarm distributed micropayment service." + }, + "labels": { + "IRI-based": "PaySwarm", + "en": "PaySwarm (payment method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#DirectDebit", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Payment by direct debit, i.e., the buying party will inform the offering gr:BusinessEntity about its bank account details and authorizes the gr:BusinessEntity to collect the agreed amount directly from that account." + }, + "labels": { + "IRI-based": "DirectDebit", + "en": "Direct debit (payment method)" + } + } + ], + "subClasses": [ + "82" + ], + "comment": { + "en": "A payment method is a standardized procedure for transferring the monetary amount for a purchase. Payment methods are characterized by the legal and technical structures used, and by the organization or group carrying out the transaction. This element is mostly used for specifying the types of payment accepted by a gr:BusinessEntity.\n\nExamples: VISA, MasterCard, Diners, cash, or bank transfer in advance." + }, + "id": "41" + }, + { + "instances": 0, + "union": [ + "33", + "34" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "125" + }, + { + "instances": 0, + "union": [ + "46", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "126" + }, + { + "instances": 0, + "union": [ + "46", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "129" + }, + { + "instances": 0, + "union": [ + "46", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "130" + }, + { + "instances": 0, + "union": [ + "4", + "5" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "131" + }, + { + "instances": 0, + "union": [ + "4", + "5", + "6" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "113" + }, + { + "instances": 0, + "union": [ + "77", + "133" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "132" + }, + { + "instances": 0, + "union": [ + "4", + "5" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "135" + }, + { + "instances": 0, + "union": [ + "33", + "34" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "136" + }, + { + "instances": 0, + "union": [ + "33", + "34" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "137" + }, + { + "instances": 0, + "union": [ + "46", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "138" + }, + { + "iri": "http://purl.org/goodrelations/v1#QuantitativeValue", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "QuantitativeValue", + "en": "Quantitative value" + }, + "subClasses": [ + "76", + "65" + ], + "comment": { + "en": "A quantitative value is a numerical interval that represents the range of a certain gr:quantitativeProductOrServiceProperty in terms of the lower and upper bounds for a particular gr:ProductOrService. It is to be interpreted in combination with the respective unit of measurement. Most quantitative values are intervals even if they are in practice often treated as a single point value.\n\t\nExample: a weight between 10 and 25 kilogramms, a length between 10 and 15 milimeters.\n\nCompatibility with schema.org: This class is equivalent to http://schema.org/Quantity." + }, + "id": "1" + }, + { + "instances": 0, + "union": [ + "33", + "8", + "34" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "144" + }, + { + "instances": 0, + "union": [ + "33", + "34", + "2" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "145" + }, + { + "instances": 0, + "union": [ + "23", + "33", + "34" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "107" + }, + { + "instances": 0, + "union": [ + "46", + "23", + "47" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "146" + }, + { + "instances": 0, + "union": [ + "46", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "147" + }, + { + "instances": 0, + "union": [ + "33", + "34" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "148" + }, + { + "instances": 0, + "union": [ + "46", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "25" + }, + { + "instances": 0, + "union": [ + "33", + "34" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "122" + }, + { + "instances": 0, + "union": [ + "33", + "34", + "35" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "152" + }, + { + "instances": 0, + "union": [ + "33", + "34", + "2" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "153" + }, + { + "instances": 0, + "union": [ + "46", + "4", + "5", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "154" + }, + { + "instances": 0, + "union": [ + "33", + "34" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "115" + }, + { + "instances": 0, + "union": [ + "33", + "34" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "157" + }, + { + "instances": 0, + "union": [ + "33", + "34" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "124" + }, + { + "instances": 0, + "union": [ + "33", + "34" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "165" + }, + { + "instances": 0, + "union": [ + "33", + "34" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "180" + }, + { + "iri": "http://purl.org/goodrelations/v1#PaymentMethodCreditCard", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "PaymentMethodCreditCard", + "en": "Payment method credit card" + }, + "individuals": [ + { + "iri": "http://purl.org/goodrelations/v1#DinersClub", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Payment by credit or debit cards issued by the Diner's Club network." + }, + "labels": { + "IRI-based": "DinersClub", + "en": "Diners Club (payment method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#MasterCard", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Payment by credit or debit cards issued by the MasterCard network." + }, + "labels": { + "IRI-based": "MasterCard", + "en": "MasterCard (payment method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#AmericanExpress", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Payment by credit or debit cards issued by the American Express network." + }, + "labels": { + "IRI-based": "AmericanExpress", + "en": "American Express (payment method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#VISA", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Payment by credit or debit cards issued by the VISA network." + }, + "labels": { + "IRI-based": "VISA", + "en": "VISA (payment method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#JCB", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Payment by credit or debit cards issued by the JCB network." + }, + "labels": { + "IRI-based": "JCB", + "en": "JCB (payment method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Discover", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Payment by credit or debit cards issued by the Discover network." + }, + "labels": { + "IRI-based": "Discover", + "en": "Discover (payment method)" + } + } + ], + "comment": { + "en": "The subclass of gr:PaymentMethod represents all variants and brands of credit or debit cards as a standardized procedure for transferring the monetary amount for a purchase. It is mostly used for specifying the types of payment accepted by a gr:Business Entity.\n\nExamples: VISA, MasterCard, or American Express." + }, + "id": "82", + "superClasses": [ + "41" + ] + }, + { + "iri": "http://purl.org/goodrelations/v1#BusinessEntity", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "BusinessEntity", + "en": "Business entity" + }, + "union": [ + "4", + "6" + ], + "subClasses": [ + "4", + "6" + ], + "comment": { + "en": "An instance of this class represents the legal agent making (or seeking) a particular offering. This can be a legal body or a person. A business entity has at least a primary mailing address and contact details. For this, typical address standards (vCard) and location data (geo, WGS84) can be attached. Note that the location of the business entity is not necessarily the location from which the product or service is being available (e.g. the branch or store). Use gr:Location for stores and branches.\n\t\t\nExample: Siemens Austria AG, Volkswagen Ltd., Peter Miller's Cell phone Shop LLC\n\nCompatibility with schema.org: This class is equivalent to the union of http://schema.org/Person and http://schema.org/Organization.\t\t\n" + }, + "attributes": [ + "union" + ], + "id": "5" + }, + { + "iri": "http://purl.org/goodrelations/v1#N-Ary-Relations", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "N-Ary-Relations", + "en": "N-ary relations (DEPRECATED)" + }, + "comment": { + "en": "This is the superclass for all classes that are placeholders for n-ary relations, which OWL cannot represent.\nDEPRECATED. Do not use this class in data or queries." + }, + "attributes": [ + "deprecated" + ], + "id": "197" + }, + { + "iri": "http://purl.org/goodrelations/v1#DeliveryChargeSpecification", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "DeliveryChargeSpecification", + "en": "Delivery charge specification" + }, + "comment": { + "en": "A delivery charge specification is a conceptual entity that specifies the additional costs asked for the delivery of a given gr:Offering using a particular gr:DeliveryMethod by the respective gr:BusinessEntity. A delivery charge specification is characterized by (1) a monetary amount per order, specified as a literal value of type float in combination with a currency, (2) the delivery method, (3) the target country or region, and (4) whether this charge includes local sales taxes, namely VAT.\nA gr:Offering may be linked to multiple gr:DeliveryChargeSpecification nodes that specify alternative charges for disjoint combinations of target countries or regions, and delivery methods.\n\nExamples: Delivery by direct download is free of charge worldwide, delivery by UPS to Germany is 10 Euros per order, delivery by mail within the US is 5 Euros per order.\n\nThe total amount of this charge is specified as a float value of the gr:hasCurrencyValue property. The currency is specified via the gr:hasCurrency datatype property. Whether the price includes VAT or not is indicated by the gr:valueAddedTaxIncluded property. The gr:DeliveryMethod to which this charge applies is specified using the gr:appliesToDeliveryMethod object property. The region or regions to which this charge applies is specified using the gr:eligibleRegions property, which uses ISO 3166-1 and ISO 3166-2 codes.\n\nIf the price can only be given as a range, use gr:hasMaxCurrencyValue and gr:hasMinCurrencyValue for the upper and lower bounds.\n\nImportant: When querying for the price, always use gr:hasMaxCurrencyValue and gr:hasMinCurrencyValue." + }, + "id": "74", + "superClasses": [ + "2" + ] + }, + { + "iri": "http://schema.org/Offer", + "baseIri": "http://schema.org", + "instances": 0, + "label": { + "IRI-based": "Offer" + }, + "attributes": [ + "external" + ], + "id": "34", + "superClasses": [ + "33" + ] + }, + { + "iri": "http://purl.org/goodrelations/v1#ProductOrServicesSomeInstancesPlaceholder", + "equivalent": [ + "23" + ], + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "ProductOrServicesSomeInstancesPlaceholder", + "en": "Product or services some instances placeholder (DEPRECATED)" + }, + "comment": { + "en": "DEPRECATED - This class is superseded by gr:SomeItems. Replace all occurrences of gr:ProductOrServicesSomeInstancesPlaceholder by gr:SomeItems, if possible." + }, + "attributes": [ + "equivalent", + "deprecated" + ], + "id": "94", + "superClasses": [ + "14" + ] + }, + { + "iri": "http://schema.org/Product", + "baseIri": "http://schema.org", + "instances": 0, + "label": { + "IRI-based": "Product" + }, + "subClasses": [ + "23", + "47", + "28" + ], + "attributes": [ + "external", + "equivalent" + ], + "id": "46" + }, + { + "iri": "http://purl.org/goodrelations/v1#DeliveryModeParcelService", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "DeliveryModeParcelService", + "en": "Delivery mode parcel service" + }, + "individuals": [ + { + "iri": "http://purl.org/goodrelations/v1#UPS", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Delivery via the parcel service UPS." + }, + "labels": { + "IRI-based": "UPS", + "en": "UPS (delivery method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#DHL", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Delivery via the parcel service DHL." + }, + "labels": { + "IRI-based": "DHL", + "en": "DHL (delivery method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#FederalExpress", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Delivery via the parcel service Federal Express." + }, + "labels": { + "IRI-based": "FederalExpress", + "en": "Federal Express (delivery method)" + } + } + ], + "comment": { + "en": "A private parcel service as the delivery mode available for a certain offering.\n\nExamples: UPS, DHL" + }, + "id": "78", + "superClasses": [ + "81" + ] + }, + { + "iri": "http://schema.org/Person", + "baseIri": "http://schema.org", + "instances": 0, + "label": { + "IRI-based": "Person" + }, + "attributes": [ + "external" + ], + "id": "6", + "superClasses": [ + "5" + ] + }, + { + "iri": "http://purl.org/goodrelations/v1#Brand", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Brand", + "en": "Brand" + }, + "comment": { + "en": "A brand is the identity of a specific product, service, or business. Use foaf:logo for attaching a brand logo and gr:name or rdfs:label for attaching the brand name.\t\n\n(Source: Wikipedia, the free encyclopedia, see http://en.wikipedia.org/wiki/Brand)" + }, + "id": "75" + }, + { + "iri": "http://purl.org/goodrelations/v1#QuantitativeValueFloat", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "QuantitativeValueFloat", + "en": "Quantitative value float" + }, + "comment": { + "en": "An instance of this class is an actual float value for a quantitative property of a product. This instance is usually characterized by a minimal value, a maximal value, and a unit of measurement.\n\nExamples: The intervals \"between 10.0 and 25.4 kilogramms\" or \"10.2 and 15.5 milimeters\".\n\nCompatibility with schema.org: This class is a subclass of http://schema.org/Quantity." + }, + "id": "76", + "superClasses": [ + "1" + ] + }, + { + "iri": "http://purl.org/goodrelations/v1#ActualProductOrServiceInstance", + "equivalent": [ + "47" + ], + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "ActualProductOrServiceInstance", + "en": "Actual product or service instance (DEPRECATED)" + }, + "comment": { + "en": "DEPRECATED - This class is superseded by gr:Individual. Replace all occurrences of gr:ActualProductOrServiceInstance by gr:Individual, if possible." + }, + "attributes": [ + "equivalent", + "deprecated" + ], + "id": "95", + "superClasses": [ + "14" + ] + }, + { + "iri": "http://purl.org/goodrelations/v1#WarrantyScope", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "WarrantyScope", + "en": "Warranty scope" + }, + "individuals": [ + { + "iri": "http://purl.org/goodrelations/v1#PartsAndLabor-PickUp", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "In case of a defect or malfunction, the buying party has the right to request from the selling gr:Business Entity to pick-up the good from its current location to a suitable service location, where the functionality of the good will be restored. All transportation, labor, parts, and materials needed to fix the problem will be covered by the selling business entity or one of its partnering business entities.\n \nNote: This is just a rough classification for filtering offers. It is up to the buying party to check the exact scope and terms and conditions of the gr:WarrantyPromise." + }, + "labels": { + "IRI-based": "PartsAndLabor-PickUp", + "en": "Parts and labor / pick up (warranty scope)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#PartsAndLabor-BringIn", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "In case of a defect or malfunction, the buying party has the right to transport the good to a service location determined by the the selling gr:BusinessEntity and will not be be charged for labor, parts, and materials needed to fix the problem. All those costs will be covered by the selling business entity or one of its partnering business entities.\n\nNote: This is just a rough classification for filtering offers. It is up to the buying party to check the exact scope and terms and conditions of the gr:WarrantyPromise." + }, + "labels": { + "IRI-based": "PartsAndLabor-BringIn", + "en": "Parts and labor / bring-in (warranty scope)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Labor-BringIn", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "In case of a defect or malfunction, the buying party has the right to transport the good to a service location determined by the the selling gr:BusinessEntity and will be charged only for parts and materials needed to fix the problem. Labor will be covered by the selling business entity or one of its partnering business entities.\n\nNote: This is just a rough classification for filtering offers. It is up to the buying party to check the exact scope and terms and conditions of the gr:WarrantyPromise." + }, + "labels": { + "IRI-based": "Labor-BringIn", + "en": "Labor / bring-in (warranty scope)" + } + } + ], + "comment": { + "en": "The warranty scope represents types of services that will be provided free of charge by the vendor or manufacturer in the case of a defect (e.g. labor and parts, just parts), as part of the warranty included in an gr:Offering. The actual services may be provided by the gr:BusinessEntity making the offering, by the manufacturer of the product, or by a third party. \n\nExamples: Parts and Labor, Parts" + }, + "id": "21" + }, + { + "iri": "http://purl.org/goodrelations/v1#LocationOfSalesOrServiceProvisioning", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "LocationOfSalesOrServiceProvisioning", + "en": "Location of sales or service provisioning (DEPRECATED)" + }, + "comment": { + "en": "DEPRECATED - This class is superseded by gr:Location. Replace all occurrences of gr:LocationOfSalesOrServiceProvisioning by gr:Location, if possible." + }, + "attributes": [ + "equivalent", + "deprecated" + ], + "id": "331" + }, + { + "iri": "http://purl.org/goodrelations/v1#Individual", + "equivalent": [ + "95" + ], + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Individual", + "en": "Individual" + }, + "comment": { + "en": "A gr:Individual is an actual product or service instance, i.e., a single identifiable object or action that creates some increase in utility (in the economic sense) for the individual possessing or using this very object (product) or for the individual in whose favor this very action is being taken (service). Products or services are types of goods in the economic sense. For an overview of goods and commodities in economics, see Milgate (1987).\n\nExamples: MyThinkpad T60, the pint of beer standing in front of me, my Volkswagen Golf, the haircut that I received or will be receiving at a given date and time.\n\nNote 1: In many cases, product or service instances are not explicitly exposed on the Web but only claimed to exist (i.e. existentially quantified). In this case, use gr:SomeItems.\nNote 2: This class is the new, shorter form of the former gr:ActualProductOrServiceInstance.\n\nCompatibility with schema.org: This class is a subclass of http://schema.org/Product." + }, + "attributes": [ + "equivalent" + ], + "id": "47", + "superClasses": [ + "46", + "14" + ] + }, + { + "iri": "http://schema.org/Place", + "baseIri": "http://schema.org", + "instances": 0, + "label": { + "IRI-based": "Place" + }, + "attributes": [ + "external", + "equivalent" + ], + "id": "133" + }, + { + "iri": "http://purl.org/goodrelations/v1#WarrantyPromise", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "WarrantyPromise", + "en": "Warranty promise" + }, + "comment": { + "en": "This is a conceptual entity that holds together all aspects of the n-ary relation gr:hasWarrantyPromise.\n\nA Warranty promise is an entity representing the duration and scope of services that will be provided to a customer free of charge in case of a defect or malfunction of the gr:ProductOrService. A warranty promise is characterized by its temporal duration (usually starting with the date of purchase) and its gr:WarrantyScope. The warranty scope represents the types of services provided (e.g. labor and parts, just parts) of the warranty included in an gr:Offering. The actual services may be provided by the gr:BusinessEntity making the offering, by the manufacturer of the product, or by a third party. There may be multiple warranty promises associated with a particular offering, which differ in duration and scope (e.g. pick-up service during the first 12 months, just parts and labor for 36 months).\n\nExamples: 12 months parts and labor, 36 months parts" + }, + "id": "11" + }, + { + "iri": "http://purl.org/goodrelations/v1#PaymentChargeSpecification", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "PaymentChargeSpecification", + "en": "Payment charge specification" + }, + "comment": { + "en": "A payment charge specification is a conceptual entity that specifies the additional costs asked for settling the payment after accepting a given gr:Offering using a particular gr:PaymentMethod. A payment charge specification is characterized by (1) a monetary amount per order specified as a literal value of type float in combination with a Currency, (2) the payment method, and (3) a whether this charge includes local sales taxes, namely VAT.\nA gr:Offering may be linked to multiple payment charge specifications that specify alternative charges for various payment methods.\n\nExamples: Payment by VISA or Mastercard costs a fee of 3 Euros including VAT, payment by bank transfer in advance is free of charge.\n\nThe total amount of this surcharge is specified as a float value of the gr:hasCurrencyValue property. The currency is specified via the gr:hasCurrency datatype property. Whether the price includes VAT or not is indicated by the gr:valueAddedTaxIncluded datatype property. The gr:PaymentMethod to which this charge applies is specified using the gr:appliesToPaymentMethod object property.\n\nIf the price can only be given as a range, use gr:hasMaxCurrencyValue and gr:hasMinCurrencyValue for the upper and lower bounds.\n\nImportant: When querying for the price, always use gr:hasMaxCurrencyValue and gr:hasMinCurrencyValue." + }, + "id": "50", + "superClasses": [ + "2" + ] + }, + { + "iri": "http://purl.org/goodrelations/v1#SomeItems", + "equivalent": [ + "94" + ], + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "SomeItems", + "en": "Some items" + }, + "comment": { + "en": "A placeholder instance for unknown instances of a mass-produced commodity. This is used as a computationally cheap work-around for such instances that are not individually exposed on the Web but just stated to exist (i.e., which are existentially quantified).\n\nExample: An instance of this class can represent an anonymous set of green Siemens1234 phones. It is different from the gr:ProductOrServiceModel Siemens1234, since this refers to the make and model, and it is different from a particular instance of this make and model (e.g. my individual phone) since the latter can be sold only once.\n\nNote: This class is the new, shorter form of the former gr:ProductOrServicesSomeInstancesPlaceholder.\n\t\t\nCompatibility with schema.org: This class is (approximately) a subclass of http://schema.org/Product." + }, + "attributes": [ + "equivalent" + ], + "id": "23", + "superClasses": [ + "46", + "14" + ] + }, + { + "iri": "http://purl.org/goodrelations/v1#QuantitativeValueInteger", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "QuantitativeValueInteger", + "en": "Quantitative value integer" + }, + "comment": { + "en": "An instance of this class is an actual integer value for a quantitative property of a product. This instance is usually characterized by a minimal value, a maximal value, and a unit of measurement. \n\nExample: A seating capacity between 1 and 8 persons.\n\nNote: Users must keep in mind that ranges in here mean that ALL possible values in this interval are covered. (Sometimes, the actual commitment may be less than that: \"We sell cars from 2 - 12 seats\" does often not really mean that they have cars with 2,3,4,...12 seats.). Someone renting out two types of rowing boats, one that fits for 1 or 2 people, and another that must be operated by 4 people cannot claim to rent boats with a seating capacity between 1 and 4 people. He or she is offering two boat types for 1-2 and 4 persons.\n\t\t\nCompatibility with schema.org: This class is a subclass of http://schema.org/Quantity." + }, + "id": "65", + "superClasses": [ + "1" + ] + }, + { + "iri": "http://schema.org/Organization", + "baseIri": "http://schema.org", + "instances": 0, + "label": { + "IRI-based": "Organization" + }, + "attributes": [ + "external" + ], + "id": "4", + "superClasses": [ + "5" + ] + }, + { + "iri": "http://purl.org/goodrelations/v1#DeliveryMethod", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "DeliveryMethod", + "en": "Delivery method" + }, + "individuals": [ + { + "iri": "http://purl.org/goodrelations/v1#DeliveryModePickUp", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Delivery of the goods by picking them up at one of the stores etc. (gr:Location) during the opening hours as specified by respective instances of gr:OpeningHoursSpecification." + }, + "labels": { + "IRI-based": "DeliveryModePickUp", + "en": "Delivery mode pick up (delivery method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#DeliveryModeDirectDownload", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Delivery of the goods via direct download from the Internet, i.e., the offering gr:BusinessEntity provides the buying party with details on how to retrieve the goods online. Connection fees and other costs of using the infrastructure are to be carried by the buying party." + }, + "labels": { + "IRI-based": "DeliveryModeDirectDownload", + "en": "Delivery mode direct download (delivery method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#DeliveryModeOwnFleet", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Delivery of the goods by using a fleet of vehicles either owned and operated or subcontracted by the gr:BusinessEntity." + }, + "labels": { + "IRI-based": "DeliveryModeOwnFleet", + "en": "Delivery mode own fleet (delivery method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#DeliveryModeFreight", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Delivery by an unspecified air, sea, or ground freight carrier or cargo company." + }, + "labels": { + "IRI-based": "DeliveryModeFreight", + "en": "Delivery mode freight (delivery method)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#DeliveryModeMail", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "Delivery via regular mail service (private or public postal services)." + }, + "labels": { + "IRI-based": "DeliveryModeMail", + "en": "Delivery mode mail (delivery method)" + } + } + ], + "subClasses": [ + "78" + ], + "comment": { + "en": "A delivery method is a standardized procedure for transferring the product or service to the destination of fulfilment chosen by the customer. Delivery methods are characterized by the means of transportation used, and by the organization or group that is the contracting party for the sending gr:BusinessEntity (this is important, since the contracted party may subcontract the fulfilment to smaller, regional businesses).\n\nExamples: Delivery by mail, delivery by direct download, delivery by UPS" + }, + "id": "81" + }, + { + "iri": "http://purl.org/goodrelations/v1#OpeningHoursSpecification", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "OpeningHoursSpecification", + "en": "Opening hours specification" + }, + "comment": { + "en": "This is a conceptual entity that holds together all information about the opening hours on a given day (gr:DayOfWeek)." + }, + "id": "30" + }, + { + "iri": "http://purl.org/goodrelations/v1#PriceSpecification", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "PriceSpecification", + "en": "Price specification" + }, + "subClasses": [ + "49", + "74", + "50" + ], + "comment": { + "en": "The superclass of all price specifications." + }, + "id": "2" + }, + { + "iri": "http://purl.org/goodrelations/v1#Offering", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Offering", + "en": "Offering" + }, + "subClasses": [ + "34" + ], + "comment": { + "en": "An offering represents the public, not necessarily binding, not necessarily exclusive, announcement by a gr:BusinessEntity to provide (or seek) a certain gr:BusinessFunction for a certain gr:ProductOrService to a specified target audience. An offering is specified by the type of product or service or bundle it refers to, what business function is being offered (sales, rental, ...), and a set of commercial properties. It can either refer to \n(1) a clearly specified instance (gr:Individual),\n(2) to a set of anonymous instances of a given type (gr:SomeItems),\n(3) a product model specification (gr:ProductOrServiceModel), see also section 3.3.3 of the GoodRelations Technical Report. \n\nAn offering may be constrained in terms of the eligible type of business partner, countries, quantities, and other commercial properties. The definition of the commercial properties, the type of product offered, and the business function are explained in other parts of this vocabulary in more detail.\n\nExample: Peter Miller offers to repair TV sets made by Siemens, Volkswagen Innsbruck sells a particular instance of a Volkswagen Golf at $10,000.\n\nCompatibility with schema.org: This class is a superclass to http://schema.org/Offer, since gr:Offering can also represent demand." + }, + "id": "33" + }, + { + "instances": 0, + "union": [ + "46", + "33", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "183" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "184", + "label": { + "IRI-based": "string" + } + }, + { + "instances": 0, + "union": [ + "46", + "33", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "140" + }, + { + "iri": "http://purl.org/goodrelations/v1#BusinessEntityType", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "BusinessEntityType", + "en": "Business entity type" + }, + "individuals": [ + { + "iri": "http://purl.org/goodrelations/v1#Reseller", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "The gr:BusinessEntityType representing such agents that are purchasing the scope of products included in the gr:Offering for resale on the market. Resellers are also businesses, i.e., they are officially registered with the public administration and strive for profits by their activities." + }, + "labels": { + "IRI-based": "Reseller", + "en": "Reseller (business entity type)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#PublicInstitution", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "The gr:BusinessEntityType representing such agents that are part of the adminstration or owned by the public." + }, + "labels": { + "IRI-based": "PublicInstitution", + "en": "Public institution (business entity type)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Enduser", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "The gr:BusinessEntityType representing such agents that are purchasing the good or service for private consumption, in particular not for resale or for usage within an industrial enterprise. By default, a Business Entity is an Enduser." + }, + "labels": { + "IRI-based": "Enduser", + "en": "Enduser (business entity type)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Business", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "The gr:BusinessEntityType representing such agents that are themselves offering commercial services or products on the market. Usually, businesses are characterized by the fact that they are officially registered with the public administration and strive for profits by their activities." + }, + "labels": { + "IRI-based": "Business", + "en": "Business (business entity type)" + } + } + ], + "comment": { + "en": "A business entity type is a conceptual entity representing the legal form, the size, the main line of business, the position in the value chain, or any combination thereof, of a gr:BusinessEntity. From the ontological point of view, business entity types are mostly roles that a business entity has in the market. Business entity types are important for specifying eligible customers, since a gr:Offering is often valid only for business entities of a certain size, legal structure, or role in the value chain. \n\nExamples: Consumers, Retailers, Wholesalers, or Public Institutions" + }, + "id": "73" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "141", + "label": { + "IRI-based": "string" + } + }, + { + "instances": 0, + "union": [ + "77", + "133", + "4", + "5" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "264" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "265", + "label": { + "IRI-based": "string" + } + }, + { + "instances": 0, + "union": [ + "77", + "133", + "4", + "5" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "348" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#int", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "350", + "label": { + "IRI-based": "int" + } + }, + { + "instances": 0, + "union": [ + "46", + "33", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "317" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "318", + "label": { + "IRI-based": "string" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "322", + "label": { + "IRI-based": "string" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#BusinessFunction", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "BusinessFunction", + "en": "Business function" + }, + "individuals": [ + { + "iri": "http://purl.org/goodrelations/v1#ProvideService", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "This gr:BusinessFunction indicates that the gr:BusinessEntity offers (or seeks) the respective type of service.\n\nNote: Maintain and Repair are also types of Services. However, products and services ontologies often provide classes for tangible products as well as for types of services. The business function gr:ProvideService is to be used with such goods that are services, while gr:Maintain and gr:Repair can be used with goods for which only the class of product exists in the ontology, but not the respective type of service.\n\nExample: Car maintenance could be expressed both as \"provide the service car maintenance\" or \"maintain cars\"." + }, + "labels": { + "IRI-based": "ProvideService", + "en": "Provide service (business function)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#ConstructionInstallation", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "This gr:BusinessFunction indicates that the gr:BusinessEntity offers (or seeks) the construction and/or installation of the specified gr:ProductOrService at the customer's location." + }, + "labels": { + "IRI-based": "ConstructionInstallation", + "en": "Construction / installation (business function)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Repair", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "This gr:BusinessFunction indicates that the gr:BusinessEntity offers (or seeks) the evaluation of the chances for repairing, and, if positive, repair of the specified gr:ProductOrService. Repairing means actions that restore the originally intended function of a product that suffers from outage or malfunction." + }, + "labels": { + "IRI-based": "Repair", + "en": "Repair (business function)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Sell", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "This gr:BusinessFunction indicates that the gr:BusinessEntity offers to permanently transfer all property rights on the specified gr:ProductOrService." + }, + "labels": { + "IRI-based": "Sell", + "en": "Sell (business function)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Maintain", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "This gr:BusinessFunction indicates that the gr:BusinessEntity offers (or seeks) typical maintenance tasks for the specified gr:ProductOrService. Maintenance tasks are actions that undo or compensate for wear or other deterioriation caused by regular usage, in order to restore the originally intended function of the product, or to prevent outage or malfunction." + }, + "labels": { + "IRI-based": "Maintain", + "en": "Maintain (business function)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Buy", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "This gr:BusinessFunction indicates that the gr:BusinessEntity is in general interested in purchasing the specified gr:ProductOrService.\nDEPRECATED. Use gr:seeks instead." + }, + "labels": { + "IRI-based": "Buy", + "en": "Buy (business function, DEPRECATED)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Dispose", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "This gr:BusinessFunction indicates that the gr:BusinessEntity offers (or seeks) the acceptance of the specified gr:ProductOrService for proper disposal, recycling, or any other kind of allowed usages, freeing the current owner from all rights and obligations of ownership." + }, + "labels": { + "IRI-based": "Dispose", + "en": "Dispose (business function)" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#LeaseOut", + "baseIri": "http://purl.org/goodrelations/v1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "comment": { + "en": "This gr:BusinessFunction indicates that the gr:BusinessEntity offers (or seeks) the temporary right to use the specified gr:ProductOrService." + }, + "labels": { + "IRI-based": "LeaseOut", + "en": "Lease Out (business function)" + } + } + ], + "subClasses": [ + "35" + ], + "comment": { + "en": "The business function specifies the type of activity or access (i.e., the bundle of rights) offered by the gr:BusinessEntity on the gr:ProductOrService through the gr:Offering. Typical are sell, rental or lease, maintenance or repair, manufacture / produce, recycle / dispose, engineering / construction, or installation.\n\nLicenses and other proprietary specifications of access rights are also instances of this class.\n\nExamples: A particular offering made by Miller Rentals Ltd. says that they (1) sell Volkswagen Golf convertibles, (2) lease out a particular Ford pick-up truck, and (3) dispose car wrecks of any make and model." + }, + "id": "79" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "359", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#int", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "128", + "label": { + "IRI-based": "int" + } + }, + { + "instances": 0, + "union": [ + "33", + "74", + "34", + "35" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "356" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "357", + "label": { + "IRI-based": "string" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "343", + "label": { + "IRI-based": "string" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#float", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "216", + "label": { + "IRI-based": "float" + } + }, + { + "instances": 0, + "union": [ + "4", + "5" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "353" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "354", + "label": { + "IRI-based": "string" + } + }, + { + "instances": 0, + "union": [ + "46", + "33", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "321" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "314", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "instances": 0, + "union": [ + "41", + "8", + "49", + "5", + "14", + "50", + "23", + "33", + "30", + "73", + "74", + "65", + "21", + "75", + "76", + "77", + "47", + "78", + "28", + "1", + "79", + "80", + "2", + "81", + "11", + "68", + "82" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "361" + }, + { + "iri": "http://purl.org/goodrelations/v1#UnitPriceSpecification", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "UnitPriceSpecification", + "en": "Unit price specification" + }, + "comment": { + "en": "A unit price specification is a conceptual entity that specifies the price asked for a given gr:Offering by the respective gr:Business Entity. An offering may be linked to multiple unit price specifications that specify alternative prices for non-overlapping sets of conditions (e.g. quantities or sales regions) or with differing validity periods. \n\nA unit price specification is characterized by (1) the lower and upper limits and the unit of measurement of the eligible quantity, (2) by a monetary amount per unit of the product or service, and (3) whether this prices includes local sales taxes, namely VAT.\n\t\nExample: The price, including VAT, for 1 kg of a given material is 5 Euros per kg for 0 - 5 kg and 4 Euros for quantities above 5 kg.\n\nThe eligible quantity interval for a given price is specified using the object property gr:hasEligibleQuantity, which points to an instance of gr:QuantitativeValue. The currency is specified using the gr:hasCurrency property, which points to an ISO 4217 currency code. The unit of measurement for the eligible quantity is specified using the gr:hasUnitOfMeasurement datatype property, which points to an UN/CEFACT Common Code (3 characters).\n\t\nIn most cases, the appropriate unit of measurement is the UN/CEFACT Common Code \"C62\" for \"Unit or piece\", since a gr:Offering is defined by the quantity and unit of measurement of all items included (e.g. \"1 kg of bananas plus a 2 kg of apples\"). As long at the offering consists of only one item, it is also possible to use an unit of measurement of choice for specifying the price per unit. For bundles, however, only \"C62\" for \"Unit or piece\" is a valid unit of measurement.\n\nYou can assume that the price is given per unit or piece if there is no gr:hasUnitOfMeasurement property attached to the price.\n\t\nWhether VAT and sales taxes are included in this price is specified using the property gr:valueAddedTaxIncluded (xsd:boolean).\n\t\nThe price per unit of measurement is specified as a float value of the gr:hasCurrencyValue property. The currency is specified via the gr:hasCurrency datatype property. Whether the price includes VAT or not is indicated by the gr:valueAddedTaxIncluded datatype property.\n\nThe property priceType can be used to indicate that the price is a retail price recommendation only (i.e. a list price). \n\nIf the price can only be given as a range, use gr:hasMaxCurrencyValue and gr:hasMinCurrencyValue for the upper and lower bounds.\n\nImportant: When querying for the price, always use gr:hasMaxCurrencyValue and gr:hasMinCurrencyValue.\n\nNote 1: Due to the complexity of pricing scenarios in various industries, it may be necessary to create extensions of this fundamental model of price specifications. Such can be done easily by importing and refining the GoodRelations ontology.\n\nNote 2: For Google, attaching a gr:validThrough statement to a gr:UnitPriceSpecification is mandatory. \n" + }, + "id": "49", + "superClasses": [ + "2" + ] + }, + { + "instances": 0, + "union": [ + "46", + "77", + "33", + "133", + "4", + "5", + "34", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "200" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "201", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#time", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "338", + "label": { + "IRI-based": "time" + } + }, + { + "instances": 0, + "union": [ + "46", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "364" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "365", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "instances": 0, + "union": [ + "46", + "33", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "366" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "367", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "instances": 0, + "union": [ + "46", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "313" + }, + { + "instances": 0, + "union": [ + "33", + "34" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "368" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#dateTime", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "371", + "label": { + "IRI-based": "dateTime" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#float", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "220", + "label": { + "IRI-based": "float" + } + }, + { + "instances": 0, + "union": [ + "1", + "68" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "377" + }, + { + "instances": 0, + "union": [ + "1", + "68" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "378" + }, + { + "instances": 0, + "union": [ + "46", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "303" + }, + { + "instances": 0, + "union": [ + "46", + "14" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "311" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#float", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "71", + "label": { + "IRI-based": "float" + } + }, + { + "instances": 0, + "union": [ + "33", + "34" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "328" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#dateTime", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "329", + "label": { + "IRI-based": "dateTime" + } + }, + { + "iri": "http://purl.org/goodrelations/v1#Location", + "equivalent": [ + "133", + "331" + ], + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Location", + "en": "Location" + }, + "comment": { + "en": "A location is a point or area of interest from which a particular product or service is available, e.g. a store, a bus stop, a gas station, or a ticket booth. The difference to gr:BusinessEntity is that the gr:BusinessEntity is the legal entity (e.g. a person or corporation) making the offer, while gr:Location is the store, office, or place. A chain restaurant will e.g. have one legal entity but multiple restaurant locations. Locations are characterized by an address or geographical position and a set of opening hour specifications for various days of the week.\n\t\t\nExample: A rental car company may offer the Business Function Lease Out of cars from two locations, one in Fort Myers, Florida, and one in Boston, Massachussetts. Both stations are open 7:00 - 23:00 Mondays through Saturdays.\n\nNote: Typical address standards (vcard) and location data (geo, WGC84) should be attached to a gr:Location node. Since there already exist established vocabularies for this, the GoodRelations ontology does not provide respective attributes. Instead, the use of respective vocabularies is recommended. However, the gr:hasGlobalLocationNumber property is provided for linking to public identifiers for business locations.\n\t\t\nCompatibility with schema.org: This class is equivalent to http://schema.org/Place." + }, + "attributes": [ + "equivalent" + ], + "id": "77" + }, + { + "iri": "http://purl.org/goodrelations/v1#License", + "baseIri": "http://purl.org/goodrelations/v1", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "License", + "en": "License" + }, + "comment": { + "en": "A license is the specification of a bundle of rights that determines the type of activity or access offered by the gr:BusinessEntity on the gr:ProductOrService through the gr:Offering.\n\t\nLicenses can be standardized (e.g. LPGL, Creative Commons, ...), vendor-specific, or individually defined for a single offer or product. Whether there is a fee for obtaining the license is specified using the gr:UnitPriceSpecification attached to the gr:Offering. Use foaf:page for linking to a document containing the license, e.g. in PDF or HTML." + }, + "id": "35", + "superClasses": [ + "79" + ] + } + ], + "property": [ + { + "id": "0", + "type": "owl:disjointWith" + }, + { + "id": "7", + "type": "owl:disjointWith" + }, + { + "id": "10", + "type": "owl:disjointWith" + }, + { + "id": "13", + "type": "owl:disjointWith" + }, + { + "id": "16", + "type": "owl:disjointWith" + }, + { + "id": "18", + "type": "owl:disjointWith" + }, + { + "id": "20", + "type": "owl:disjointWith" + }, + { + "id": "22", + "type": "rdfs:SubClassOf" + }, + { + "id": "24", + "type": "owl:objectProperty" + }, + { + "id": "27", + "type": "owl:disjointWith" + }, + { + "id": "29", + "type": "owl:datatypeProperty" + }, + { + "id": "36", + "type": "owl:disjointWith" + }, + { + "id": "38", + "type": "owl:disjointWith" + }, + { + "id": "40", + "type": "owl:disjointWith" + }, + { + "id": "42", + "type": "owl:disjointWith" + }, + { + "id": "44", + "type": "owl:disjointWith" + }, + { + "id": "48", + "type": "owl:disjointWith" + }, + { + "id": "52", + "type": "owl:objectProperty" + }, + { + "id": "54", + "type": "owl:disjointWith" + }, + { + "id": "56", + "type": "owl:disjointWith" + }, + { + "id": "58", + "type": "owl:datatypeProperty" + }, + { + "id": "59", + "type": "owl:disjointWith" + }, + { + "id": "61", + "type": "owl:disjointWith" + }, + { + "id": "63", + "type": "owl:disjointWith" + }, + { + "id": "64", + "type": "owl:datatypeProperty" + }, + { + "id": "67", + "type": "owl:objectProperty" + }, + { + "id": "70", + "type": "owl:datatypeProperty" + }, + { + "id": "83", + "type": "owl:disjointWith" + }, + { + "id": "91", + "type": "owl:datatypeProperty" + }, + { + "id": "96", + "type": "owl:objectProperty" + }, + { + "id": "102", + "type": "owl:objectProperty" + }, + { + "id": "106", + "type": "owl:objectProperty" + }, + { + "id": "53", + "type": "owl:objectProperty" + }, + { + "id": "112", + "type": "owl:objectProperty" + }, + { + "id": "114", + "type": "owl:objectProperty" + }, + { + "id": "116", + "type": "owl:objectProperty" + }, + { + "id": "121", + "type": "owl:objectProperty" + }, + { + "id": "123", + "type": "owl:objectProperty" + }, + { + "id": "127", + "type": "owl:datatypeProperty" + }, + { + "id": "134", + "type": "owl:objectProperty" + }, + { + "id": "139", + "type": "owl:datatypeProperty" + }, + { + "id": "142", + "type": "owl:datatypeProperty" + }, + { + "id": "143", + "type": "owl:datatypeProperty" + }, + { + "id": "149", + "type": "rdfs:SubClassOf" + }, + { + "id": "150", + "type": "rdfs:SubClassOf" + }, + { + "id": "151", + "type": "rdfs:SubClassOf" + }, + { + "id": "155", + "type": "owl:objectProperty" + }, + { + "id": "156", + "type": "owl:objectProperty" + }, + { + "id": "158", + "type": "owl:objectProperty" + }, + { + "id": "159", + "type": "owl:objectProperty" + }, + { + "id": "160", + "type": "rdfs:SubClassOf" + }, + { + "id": "161", + "type": "rdfs:SubClassOf" + }, + { + "id": "162", + "type": "rdfs:SubClassOf" + }, + { + "id": "163", + "type": "owl:datatypeProperty" + }, + { + "id": "164", + "type": "rdfs:SubClassOf" + }, + { + "id": "166", + "type": "rdfs:SubClassOf" + }, + { + "id": "167", + "type": "owl:disjointWith" + }, + { + "id": "168", + "type": "rdfs:SubClassOf" + }, + { + "id": "169", + "type": "owl:disjointWith" + }, + { + "id": "170", + "type": "rdfs:SubClassOf" + }, + { + "id": "171", + "type": "owl:objectProperty" + }, + { + "id": "172", + "type": "owl:disjointWith" + }, + { + "id": "173", + "type": "rdfs:SubClassOf" + }, + { + "id": "174", + "type": "owl:disjointWith" + }, + { + "id": "175", + "type": "rdfs:SubClassOf" + }, + { + "id": "176", + "type": "owl:disjointWith" + }, + { + "id": "177", + "type": "rdfs:SubClassOf" + }, + { + "id": "178", + "type": "owl:disjointWith" + }, + { + "id": "179", + "type": "rdfs:SubClassOf" + }, + { + "id": "181", + "type": "owl:objectProperty" + }, + { + "id": "182", + "type": "owl:datatypeProperty" + }, + { + "id": "185", + "type": "owl:objectProperty" + }, + { + "id": "186", + "type": "owl:objectProperty" + }, + { + "id": "187", + "type": "rdfs:SubClassOf" + }, + { + "id": "188", + "type": "owl:disjointWith" + }, + { + "id": "189", + "type": "rdfs:SubClassOf" + }, + { + "id": "190", + "type": "owl:disjointWith" + }, + { + "id": "191", + "type": "rdfs:SubClassOf" + }, + { + "id": "192", + "type": "owl:disjointWith" + }, + { + "id": "193", + "type": "rdfs:SubClassOf" + }, + { + "id": "194", + "type": "owl:disjointWith" + }, + { + "id": "195", + "type": "owl:objectProperty" + }, + { + "id": "196", + "type": "owl:datatypeProperty" + }, + { + "id": "198", + "type": "owl:objectProperty" + }, + { + "id": "199", + "type": "owl:datatypeProperty" + }, + { + "id": "202", + "type": "owl:disjointWith" + }, + { + "id": "203", + "type": "owl:disjointWith" + }, + { + "id": "204", + "type": "owl:datatypeProperty" + }, + { + "id": "205", + "type": "owl:disjointWith" + }, + { + "id": "206", + "type": "owl:disjointWith" + }, + { + "id": "207", + "type": "owl:disjointWith" + }, + { + "id": "208", + "type": "owl:disjointWith" + }, + { + "id": "209", + "type": "owl:objectProperty" + }, + { + "id": "211", + "type": "owl:disjointWith" + }, + { + "id": "212", + "type": "owl:disjointWith" + }, + { + "id": "213", + "type": "owl:disjointWith" + }, + { + "id": "214", + "type": "owl:disjointWith" + }, + { + "id": "215", + "type": "owl:datatypeProperty" + }, + { + "id": "217", + "type": "owl:datatypeProperty" + }, + { + "id": "218", + "type": "owl:datatypeProperty" + }, + { + "id": "219", + "type": "owl:datatypeProperty" + }, + { + "id": "221", + "type": "owl:disjointWith" + }, + { + "id": "222", + "type": "owl:disjointWith" + }, + { + "id": "223", + "type": "owl:datatypeProperty" + }, + { + "id": "224", + "type": "owl:disjointWith" + }, + { + "id": "225", + "type": "owl:disjointWith" + }, + { + "id": "226", + "type": "owl:disjointWith" + }, + { + "id": "227", + "type": "owl:disjointWith" + }, + { + "id": "228", + "type": "owl:objectProperty" + }, + { + "id": "229", + "type": "owl:disjointWith" + }, + { + "id": "230", + "type": "owl:objectProperty" + }, + { + "id": "231", + "type": "owl:disjointWith" + }, + { + "id": "232", + "type": "owl:disjointWith" + }, + { + "id": "233", + "type": "owl:disjointWith" + }, + { + "id": "234", + "type": "owl:disjointWith" + }, + { + "id": "235", + "type": "owl:disjointWith" + }, + { + "id": "236", + "type": "owl:disjointWith" + }, + { + "id": "237", + "type": "owl:disjointWith" + }, + { + "id": "238", + "type": "owl:disjointWith" + }, + { + "id": "239", + "type": "owl:disjointWith" + }, + { + "id": "240", + "type": "owl:disjointWith" + }, + { + "id": "241", + "type": "owl:disjointWith" + }, + { + "id": "242", + "type": "owl:datatypeProperty" + }, + { + "id": "243", + "type": "owl:disjointWith" + }, + { + "id": "244", + "type": "owl:disjointWith" + }, + { + "id": "245", + "type": "owl:disjointWith" + }, + { + "id": "246", + "type": "owl:disjointWith" + }, + { + "id": "247", + "type": "owl:disjointWith" + }, + { + "id": "248", + "type": "owl:disjointWith" + }, + { + "id": "249", + "type": "owl:disjointWith" + }, + { + "id": "250", + "type": "owl:disjointWith" + }, + { + "id": "251", + "type": "owl:disjointWith" + }, + { + "id": "252", + "type": "owl:objectProperty" + }, + { + "id": "253", + "type": "owl:disjointWith" + }, + { + "id": "254", + "type": "owl:disjointWith" + }, + { + "id": "255", + "type": "owl:disjointWith" + }, + { + "id": "256", + "type": "owl:disjointWith" + }, + { + "id": "257", + "type": "owl:disjointWith" + }, + { + "id": "258", + "type": "owl:disjointWith" + }, + { + "id": "259", + "type": "owl:disjointWith" + }, + { + "id": "260", + "type": "owl:disjointWith" + }, + { + "id": "261", + "type": "owl:disjointWith" + }, + { + "id": "262", + "type": "owl:disjointWith" + }, + { + "id": "263", + "type": "owl:datatypeProperty" + }, + { + "id": "266", + "type": "owl:disjointWith" + }, + { + "id": "267", + "type": "owl:disjointWith" + }, + { + "id": "268", + "type": "owl:objectProperty" + }, + { + "id": "210", + "type": "owl:objectProperty" + }, + { + "id": "269", + "type": "owl:disjointWith" + }, + { + "id": "270", + "type": "owl:disjointWith" + }, + { + "id": "271", + "type": "owl:disjointWith" + }, + { + "id": "272", + "type": "owl:disjointWith" + }, + { + "id": "273", + "type": "owl:disjointWith" + }, + { + "id": "274", + "type": "owl:disjointWith" + }, + { + "id": "275", + "type": "owl:disjointWith" + }, + { + "id": "276", + "type": "owl:disjointWith" + }, + { + "id": "277", + "type": "owl:disjointWith" + }, + { + "id": "278", + "type": "owl:disjointWith" + }, + { + "id": "279", + "type": "owl:disjointWith" + }, + { + "id": "280", + "type": "owl:disjointWith" + }, + { + "id": "281", + "type": "owl:disjointWith" + }, + { + "id": "282", + "type": "owl:disjointWith" + }, + { + "id": "283", + "type": "owl:disjointWith" + }, + { + "id": "284", + "type": "owl:disjointWith" + }, + { + "id": "285", + "type": "owl:disjointWith" + }, + { + "id": "286", + "type": "owl:disjointWith" + }, + { + "id": "287", + "type": "owl:disjointWith" + }, + { + "id": "288", + "type": "owl:disjointWith" + }, + { + "id": "289", + "type": "owl:disjointWith" + }, + { + "id": "290", + "type": "owl:disjointWith" + }, + { + "id": "291", + "type": "owl:objectProperty" + }, + { + "id": "292", + "type": "owl:disjointWith" + }, + { + "id": "293", + "type": "owl:disjointWith" + }, + { + "id": "294", + "type": "owl:disjointWith" + }, + { + "id": "295", + "type": "owl:disjointWith" + }, + { + "id": "296", + "type": "owl:disjointWith" + }, + { + "id": "297", + "type": "owl:disjointWith" + }, + { + "id": "298", + "type": "owl:disjointWith" + }, + { + "id": "299", + "type": "owl:disjointWith" + }, + { + "id": "300", + "type": "owl:disjointWith" + }, + { + "id": "301", + "type": "owl:disjointWith" + }, + { + "id": "302", + "type": "owl:objectProperty" + }, + { + "id": "304", + "type": "owl:disjointWith" + }, + { + "id": "305", + "type": "owl:disjointWith" + }, + { + "id": "306", + "type": "owl:disjointWith" + }, + { + "id": "307", + "type": "owl:datatypeProperty" + }, + { + "id": "308", + "type": "owl:disjointWith" + }, + { + "id": "309", + "type": "owl:disjointWith" + }, + { + "id": "310", + "type": "owl:objectProperty" + }, + { + "id": "312", + "type": "owl:datatypeProperty" + }, + { + "id": "315", + "type": "owl:objectProperty" + }, + { + "id": "316", + "type": "owl:datatypeProperty" + }, + { + "id": "319", + "type": "owl:disjointWith" + }, + { + "id": "320", + "type": "owl:datatypeProperty" + }, + { + "id": "323", + "type": "owl:disjointWith" + }, + { + "id": "324", + "type": "owl:disjointWith" + }, + { + "id": "325", + "type": "owl:datatypeProperty" + }, + { + "id": "326", + "type": "owl:datatypeProperty" + }, + { + "id": "327", + "type": "owl:datatypeProperty" + }, + { + "id": "330", + "type": "owl:datatypeProperty" + }, + { + "id": "332", + "type": "owl:datatypeProperty" + }, + { + "id": "333", + "type": "owl:datatypeProperty" + }, + { + "id": "334", + "type": "owl:objectProperty" + }, + { + "id": "335", + "type": "owl:objectProperty" + }, + { + "id": "336", + "type": "owl:objectProperty" + }, + { + "id": "337", + "type": "owl:datatypeProperty" + }, + { + "id": "339", + "type": "owl:objectProperty" + }, + { + "id": "340", + "type": "owl:datatypeProperty" + }, + { + "id": "69", + "type": "owl:objectProperty" + }, + { + "id": "341", + "type": "owl:objectProperty" + }, + { + "id": "342", + "type": "owl:datatypeProperty" + }, + { + "id": "344", + "type": "owl:objectProperty" + }, + { + "id": "345", + "type": "owl:objectProperty" + }, + { + "id": "346", + "type": "owl:datatypeProperty" + }, + { + "id": "347", + "type": "owl:datatypeProperty" + }, + { + "id": "349", + "type": "owl:objectProperty" + }, + { + "id": "351", + "type": "owl:datatypeProperty" + }, + { + "id": "352", + "type": "owl:datatypeProperty" + }, + { + "id": "26", + "type": "owl:objectProperty" + }, + { + "id": "355", + "type": "owl:datatypeProperty" + }, + { + "id": "358", + "type": "owl:datatypeProperty" + }, + { + "id": "360", + "type": "owl:objectProperty" + }, + { + "id": "97", + "type": "owl:objectProperty" + }, + { + "id": "362", + "type": "owl:objectProperty" + }, + { + "id": "363", + "type": "owl:datatypeProperty" + }, + { + "id": "369", + "type": "owl:objectProperty" + }, + { + "id": "370", + "type": "owl:datatypeProperty" + }, + { + "id": "372", + "type": "owl:datatypeProperty" + }, + { + "id": "373", + "type": "owl:datatypeProperty" + }, + { + "id": "374", + "type": "owl:objectProperty" + }, + { + "id": "375", + "type": "owl:datatypeProperty" + }, + { + "id": "376", + "type": "owl:objectProperty" + }, + { + "id": "379", + "type": "owl:objectProperty" + }, + { + "id": "380", + "type": "owl:datatypeProperty" + }, + { + "id": "381", + "type": "owl:datatypeProperty" + }, + { + "id": "382", + "type": "owl:disjointWith" + }, + { + "id": "383", + "type": "owl:disjointWith" + }, + { + "id": "384", + "type": "owl:datatypeProperty" + }, + { + "id": "385", + "type": "owl:datatypeProperty" + }, + { + "id": "386", + "type": "owl:disjointWith" + }, + { + "id": "387", + "type": "owl:disjointWith" + }, + { + "id": "388", + "type": "owl:disjointWith" + }, + { + "id": "389", + "type": "owl:disjointWith" + }, + { + "id": "390", + "type": "owl:disjointWith" + }, + { + "id": "391", + "type": "owl:disjointWith" + }, + { + "id": "392", + "type": "owl:objectProperty" + }, + { + "id": "393", + "type": "owl:disjointWith" + }, + { + "id": "394", + "type": "owl:disjointWith" + }, + { + "id": "395", + "type": "owl:objectProperty" + }, + { + "id": "396", + "type": "owl:objectProperty" + } + ], + "propertyAttribute": [ + { + "range": "2", + "domain": "1", + "attributes": [ + "anonymous", + "object" + ], + "id": "0" + }, + { + "range": "2", + "domain": "8", + "attributes": [ + "anonymous", + "object" + ], + "id": "7" + }, + { + "range": "2", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "10" + }, + { + "range": "14", + "domain": "1", + "attributes": [ + "anonymous", + "object" + ], + "id": "13" + }, + { + "range": "14", + "domain": "8", + "attributes": [ + "anonymous", + "object" + ], + "id": "16" + }, + { + "range": "14", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "18" + }, + { + "range": "21", + "domain": "14", + "attributes": [ + "anonymous", + "object" + ], + "id": "20" + }, + { + "range": "14", + "domain": "23", + "attributes": [ + "anonymous", + "object" + ], + "id": "22" + }, + { + "iri": "http://purl.org/goodrelations/v1#depth", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "depth", + "en": "depth (0..1)" + }, + "superproperty": [ + "26" + ], + "domain": "25", + "comment": { + "en": "The depth of the product.\nTypical unit code(s): CMT for centimeters, INH for inches" + }, + "attributes": [ + "object" + ], + "id": "24" + }, + { + "range": "23", + "domain": "28", + "attributes": [ + "anonymous", + "object" + ], + "id": "27" + }, + { + "iri": "http://purl.org/goodrelations/v1#opens", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "31", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "opens", + "en": "opens (1..1)" + }, + "domain": "30", + "comment": { + "en": "The opening hour of the gr:Location on the given gr:DayOfWeek.\nIf no time-zone suffix is included, the time is given in the local time valid at the gr:Location.\n\nFor a time in GMT/UTC, simply add a \"Z\" following the time:\n\n09:30:10Z.\n\nAlternatively, you can specify an offset from the UTC time by adding a positive or negative time following the time:\n\n09:30:10-09:00\n\nor\n\n09:30:10+09:00.\n\nNote 1: Use 00:00:00 for the first second of the respective day and 23:59:59 for the last second of that day.\nNote 2: If a store opens at 17:00 on Saturdays and closes at 03:00:00 a.m. next morning, use 17:00:00 - 23:59:59 for Saturday and 00:00:00 - 03:00:00 for Sunday.\nNote 3: If the shop re-opens on the same day of the week or set of days of the week, you must create a second instance of gr:OpeningHoursSpecification." + }, + "attributes": [ + "datatype" + ], + "id": "29" + }, + { + "range": "14", + "domain": "2", + "attributes": [ + "anonymous", + "object" + ], + "id": "36" + }, + { + "range": "21", + "domain": "2", + "attributes": [ + "anonymous", + "object" + ], + "id": "38" + }, + { + "range": "30", + "domain": "41", + "attributes": [ + "anonymous", + "object" + ], + "id": "40" + }, + { + "range": "30", + "domain": "14", + "attributes": [ + "anonymous", + "object" + ], + "id": "42" + }, + { + "range": "30", + "domain": "8", + "attributes": [ + "anonymous", + "object" + ], + "id": "44" + }, + { + "range": "50", + "domain": "49", + "attributes": [ + "anonymous", + "object" + ], + "id": "48" + }, + { + "iri": "http://purl.org/goodrelations/v1#successorOf", + "inverse": "53", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "28", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "successorOf", + "en": "successor of (0..*)" + }, + "domain": "28", + "comment": { + "en": "This property indicates that the subject is a newer, often updated or improved variant of the gr:ProductOrServiceModel used as the object.\n\nExample: Golf III successorOf Golf II\n\nThis relation is transitive." + }, + "attributes": [ + "object", + "transitive" + ], + "id": "52" + }, + { + "range": "41", + "domain": "1", + "attributes": [ + "anonymous", + "object" + ], + "id": "54" + }, + { + "range": "2", + "domain": "41", + "attributes": [ + "anonymous", + "object" + ], + "id": "56" + }, + { + "iri": "http://schema.org/description", + "baseIri": "http://schema.org", + "range": "15", + "label": { + "IRI-based": "description" + }, + "domain": "12", + "attributes": [ + "external", + "datatype" + ], + "id": "58" + }, + { + "range": "41", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "59" + }, + { + "range": "21", + "domain": "41", + "attributes": [ + "anonymous", + "object" + ], + "id": "61" + }, + { + "range": "8", + "domain": "41", + "attributes": [ + "anonymous", + "object" + ], + "id": "63" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasValueInteger", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "66", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasValueInteger", + "en": "has value integer (0..1)" + }, + "domain": "65", + "comment": { + "en": "This subproperty specifies that the upper and lower limit of the given gr:QuantitativeValueInteger are identical and have the respective integer value. It is a shortcut for such cases where a quantitative property is (at least practically) a single point value and not an interval." + }, + "attributes": [ + "datatype" + ], + "id": "64" + }, + { + "iri": "http://purl.org/goodrelations/v1#lesserOrEqual", + "inverse": "69", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "68", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "lesserOrEqual", + "en": "lesser or equal (0..*)" + }, + "domain": "68", + "comment": { + "en": "This ordering relation for gr:QualitativeValue pairs indicates that the subject is lesser than or equal to the object." + }, + "attributes": [ + "object", + "transitive" + ], + "id": "67" + }, + { + "iri": "http://purl.org/goodrelations/v1#amountOfThisGood", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "71", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "amountOfThisGood", + "en": "amount of this good (1..1)" + }, + "domain": "8", + "comment": { + "en": "This property specifies the quantity of the goods included in the gr:Offering via this gr:TypeAndQuantityNode. The quantity is given in the unit of measurement attached to the gr:TypeAndQuantityNode." + }, + "attributes": [ + "datatype" + ], + "id": "70" + }, + { + "range": "30", + "domain": "1", + "attributes": [ + "anonymous", + "object" + ], + "id": "83" + }, + { + "iri": "http://purl.org/goodrelations/v1#isListPrice", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "90", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "isListPrice", + "en": "is list price (DEPRECATED)" + }, + "domain": "49", + "comment": { + "en": "This boolean attribute indicates whether a gr:UnitPriceSpecification is a list price (usually a vendor recommendation) or not. \"true\" indicates it is a list price, \"false\" indicates it is not.\nDEPRECATED. Use the gr:priceType property instead." + }, + "attributes": [ + "deprecated", + "datatype" + ], + "id": "91" + }, + { + "iri": "http://xmlns.com/foaf/0.1/depiction", + "equivalent": [ + "97" + ], + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "12", + "label": { + "IRI-based": "depiction" + }, + "domain": "12", + "attributes": [ + "external", + "object" + ], + "id": "96" + }, + { + "iri": "http://purl.org/goodrelations/v1#equal", + "inverse": "102", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "68", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "equal", + "en": "equal (0..*)" + }, + "domain": "68", + "comment": { + "en": "This ordering relation for qualitative values indicates that the subject is equal to the object." + }, + "attributes": [ + "object", + "transitive", + "symmetric" + ], + "id": "102" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasInventoryLevel", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "76", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasInventoryLevel", + "en": "has inventory level (0..1)" + }, + "domain": "107", + "comment": { + "en": "This property specifies the current approximate inventory level for gr:SomeItems. The unit of measurement and the point value or interval are indicated using the attached gr:QuantitativeValueFloat instance.\n\nThis property can also be attached to a gr:Offering in cases where the included products are not modeled in more detail." + }, + "attributes": [ + "object" + ], + "id": "106" + }, + { + "iri": "http://purl.org/goodrelations/v1#predecessorOf", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "28", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "predecessorOf", + "en": "predecessor of (0..*)" + }, + "domain": "28", + "comment": { + "en": "This property indicates that the subject is a previous, often discontinued variant of the gr:ProductOrServiceModel used as the object.\n\nExample: Golf III predecessorOf Golf IV\n\nThis relation is transitive." + }, + "attributes": [ + "object", + "transitive" + ], + "id": "53" + }, + { + "iri": "http://purl.org/goodrelations/v1#owns", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "47", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "owns", + "en": "owns (0..*)" + }, + "domain": "113", + "comment": { + "en": "This property indicates that a particular person or business owns a particular product. It can be used to expose the products in one's posession in order to empower recommender systems to suggest matching offers.\n\nNote that the product must be an instance of the class gr:Individual.\n\nThis property can also be safely applied to foaf:Agent instances." + }, + "attributes": [ + "object" + ], + "id": "112" + }, + { + "iri": "http://purl.org/goodrelations/v1#addOn", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "33", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "addOn", + "en": "add-on (0..*)" + }, + "domain": "115", + "comment": { + "en": "This property points from a gr:Offering to additional offerings that can only be obtained in combination with the first offering. This can be used to model supplements and extensions that are available for a surcharge. Any gr:PriceSpecification attached to the secondary offering is to be understood as an additional charge." + }, + "attributes": [ + "object" + ], + "id": "114" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasWarrantyScope", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "21", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasWarrantyScope", + "en": "has warranty scope (0..1)" + }, + "domain": "11", + "comment": { + "en": "This states the gr:WarrantyScope of a given gr:WarrantyPromise." + }, + "attributes": [ + "object" + ], + "id": "116" + }, + { + "iri": "http://purl.org/goodrelations/v1#eligibleCustomerTypes", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "73", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "eligibleCustomerTypes", + "en": "eligible customer types (0..*)" + }, + "domain": "122", + "comment": { + "en": "The types of customers (gr:BusinessEntityType) for which the given gr:Offering is valid." + }, + "attributes": [ + "object" + ], + "id": "121" + }, + { + "iri": "http://purl.org/goodrelations/v1#availableAtOrFrom", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "77", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "availableAtOrFrom", + "en": "available at or from (0..*)" + }, + "domain": "124", + "comment": { + "en": "This states that a particular gr:Offering is available at or from the given gr:Location (e.g. shop or branch)." + }, + "attributes": [ + "object" + ], + "id": "123" + }, + { + "iri": "http://purl.org/goodrelations/v1#durationOfWarrantyInMonths", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "128", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "durationOfWarrantyInMonths", + "en": "duration of warranty in months (0..1)" + }, + "domain": "11", + "comment": { + "en": "This property specifies the duration of the gr:WarrantyPromise in months." + }, + "attributes": [ + "datatype" + ], + "id": "127" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasOpeningHoursDayOfWeek", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "80", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasOpeningHoursDayOfWeek", + "en": "has opening hours day of week (1..*)" + }, + "domain": "30", + "comment": { + "en": "This specifies the gr:DayOfWeek to which the gr:OpeningHoursSpecification is related.\n\nNote: Use multiple instances of gr:OpeningHoursSpecification for specifying the opening hours for multiple days if the opening hours differ." + }, + "attributes": [ + "object" + ], + "id": "134" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasGTIN-8", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "141", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasGTIN-8", + "en": "has GTIN-8 (0..*)" + }, + "domain": "140", + "comment": { + "en": "The 8-digit Global Trade Item Number (GTIN-8) of the given gr:ProductOrService or gr:Offering, also known as EAN/UCC-8 (8-digit EAN)." + }, + "attributes": [ + "datatype" + ], + "id": "139" + }, + { + "iri": "http://schema.org/name", + "baseIri": "http://schema.org", + "range": "19", + "label": { + "IRI-based": "name" + }, + "domain": "12", + "attributes": [ + "external", + "datatype" + ], + "id": "142" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasMaxCurrencyValue", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "99", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasMaxCurrencyValue", + "en": "has max currency value (1..1)" + }, + "domain": "2", + "comment": { + "en": "This property specifies the UPPER BOUND of the amount of money for a price RANGE per unit, shipping charges, or payment charges. The currency and other relevant details are attached to the respective gr:PriceSpecification etc.\nFor a gr:UnitPriceSpecification, this is the UPPER BOUND for the price for one unit or bundle (as specified in the unit of measurement of the unit price specification) of the respective gr:ProductOrService. For a gr:DeliveryChargeSpecification or a gr:PaymentChargeSpecification, it is the UPPER BOUND of the price per delivery or payment.\n\nUsing gr:hasCurrencyValue sets the upper and lower bounds to the same given value, i.e., x gr:hasCurrencyValue y implies x gr:hasMinCurrencyValue y, x gr:hasMaxCurrencyValue y." + }, + "attributes": [ + "datatype" + ], + "id": "143" + }, + { + "range": "2", + "domain": "50", + "attributes": [ + "anonymous", + "object" + ], + "id": "149" + }, + { + "range": "33", + "domain": "34", + "attributes": [ + "anonymous", + "object" + ], + "id": "150" + }, + { + "range": "79", + "domain": "35", + "attributes": [ + "anonymous", + "object" + ], + "id": "151" + }, + { + "iri": "http://purl.org/goodrelations/v1#eligibleTransactionVolume", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "eligibleTransactionVolume", + "en": "eligible transaction volume (0..1)" + }, + "domain": "153", + "comment": { + "en": "This property can be used to indicate the transaction volume, in a monetary unit, for which the gr:Offering or gr:PriceSpecification is valid. This is mostly used to specify a minimal purchasing volume, to express free shipping above a certain order volume, or to limit the acceptance of credit cards to purchases above a certain amount.\n\nThe object is a gr:PriceSpecification that uses the properties gr:hasMaxCurrencyValue and gr:hasMinCurrencyValue to indicate the lower and upper boundaries and gr:hasCurrency to indicate the currency using the ISO 4217 standard (3 characters)." + }, + "attributes": [ + "object" + ], + "id": "155" + }, + { + "iri": "http://purl.org/goodrelations/v1#advanceBookingRequirement", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "65", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "advanceBookingRequirement", + "en": "advance booking requirement (0..1)" + }, + "domain": "157", + "comment": { + "en": "The minimal and maximal amount of time that is required between accepting the gr:Offering and the actual usage of the resource or service. This is mostly relevant for offers regarding hotel rooms, the rental of objects, or the provisioning of services. The duration is specified relatively to the beginning of the usage of the contracted object. It is represented by attaching an instance of the class gr:QuantitativeValueInteger. The lower and upper boundaries are specified using the properties gr:hasMinValueInteger and gr:hasMaxValueInteger to that instance. The unit of measurement is specified using the property gr:hasUnitOfMeasurement with a string holding a UN/CEFACT code suitable for durations, e.g. MON (months), DAY (days), HUR (hours), or MIN (minutes).\n\nThe difference to the gr:validFrom and gr:validThrough properties is that those specify the interval during which the gr:Offering is valid, while gr:advanceBookingRequirement specifies the acceptable relative amount of time between accepting the offer and the fulfilment or usage." + }, + "attributes": [ + "object" + ], + "id": "156" + }, + { + "iri": "http://purl.org/goodrelations/v1#isVariantOf", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "28", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "isVariantOf", + "en": "is variant of (0..1)" + }, + "domain": "28", + "comment": { + "en": "This states that a particular gr:ProductOrServiceModel is a variant of another product or service model. It is pretty safe to infer that the variant inherits all gr:quantitativeProductOrServiceProperty, gr:qualitativeProductOrServiceProperty, and gr:datatypeProductOrServiceProperty values that are defined for the first gr:ProductOrServiceModel.\n\nExample:\nfoo:Red_Ford_T_Model gr:isVariantOf foo:Ford_T_Model" + }, + "attributes": [ + "object" + ], + "id": "158" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasWarrantyPromise", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "11", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasWarrantyPromise", + "en": "has warranty promise (0..*)" + }, + "domain": "137", + "comment": { + "en": "This specifies the gr:WarrantyPromise made by the gr:BusinessEntity for the given gr:Offering." + }, + "attributes": [ + "object" + ], + "id": "159" + }, + { + "range": "46", + "domain": "47", + "attributes": [ + "anonymous", + "object" + ], + "id": "160" + }, + { + "range": "46", + "domain": "28", + "attributes": [ + "anonymous", + "object" + ], + "id": "161" + }, + { + "range": "81", + "domain": "78", + "attributes": [ + "anonymous", + "object" + ], + "id": "162" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasMinValue", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "105", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasMinValue", + "en": "has min value (0..1)" + }, + "domain": "1", + "comment": { + "en": "This property captures the lower limit of a gr:QuantitativeValue instance." + }, + "attributes": [ + "datatype" + ], + "id": "163" + }, + { + "range": "2", + "domain": "49", + "attributes": [ + "anonymous", + "object" + ], + "id": "164" + }, + { + "range": "2", + "domain": "74", + "attributes": [ + "anonymous", + "object" + ], + "id": "166" + }, + { + "range": "8", + "domain": "1", + "attributes": [ + "anonymous", + "object" + ], + "id": "167" + }, + { + "range": "41", + "domain": "82", + "attributes": [ + "anonymous", + "object" + ], + "id": "168" + }, + { + "range": "1", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "169" + }, + { + "range": "1", + "domain": "76", + "attributes": [ + "anonymous", + "object" + ], + "id": "170" + }, + { + "iri": "http://purl.org/goodrelations/v1#height", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "height", + "en": "height (0..1)" + }, + "superproperty": [ + "26" + ], + "domain": "138", + "comment": { + "en": "The height of the product.\nTypical unit code(s): CMT for centimeters, INH for inches" + }, + "attributes": [ + "object" + ], + "id": "171" + }, + { + "range": "65", + "domain": "76", + "attributes": [ + "anonymous", + "object" + ], + "id": "172" + }, + { + "range": "1", + "domain": "65", + "attributes": [ + "anonymous", + "object" + ], + "id": "173" + }, + { + "range": "8", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "174" + }, + { + "range": "5", + "domain": "4", + "attributes": [ + "anonymous", + "object" + ], + "id": "175" + }, + { + "range": "21", + "domain": "8", + "attributes": [ + "anonymous", + "object" + ], + "id": "176" + }, + { + "range": "5", + "domain": "6", + "attributes": [ + "anonymous", + "object" + ], + "id": "177" + }, + { + "range": "21", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "178" + }, + { + "range": "46", + "domain": "23", + "attributes": [ + "anonymous", + "object" + ], + "id": "179" + }, + { + "iri": "http://purl.org/goodrelations/v1#isConsumableFor", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "14", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "isConsumableFor", + "en": "is consumable for (0..*)" + }, + "domain": "129", + "comment": { + "en": "This states that a particular gr:ProductOrService is a consumable for another product or service." + }, + "attributes": [ + "object" + ], + "id": "181" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasGTIN-14", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "184", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasGTIN-14", + "en": "has GTIN-14 (0..*)" + }, + "domain": "183", + "comment": { + "en": "The Global Trade Item Number (GTIN-14) of the given gr:ProductOrService or gr:Offering." + }, + "attributes": [ + "datatype" + ], + "id": "182" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasPriceSpecification", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasPriceSpecification", + "en": "has price specification (0..*)" + }, + "domain": "136", + "comment": { + "en": "This links a gr:Offering to a gr:PriceSpecification or specifications. There can be unit price specifications, payment charge specifications, and delivery charge specifications. For each type, multiple specifications for the same gr:Offering are possible, e.g. for different quantity ranges or for different currencies, or for different combinations of gr:DeliveryMethod and target destinations.\n\nRecommended retail prices etc. can be marked by the gr:priceType property of the gr:UnitPriceSpecification." + }, + "attributes": [ + "object" + ], + "id": "185" + }, + { + "iri": "http://purl.org/goodrelations/v1#includesObject", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "8", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "includesObject", + "en": "includes object (0..*)" + }, + "domain": "125", + "comment": { + "en": "This object property links a gr:Offering to one or multiple gr:TypeAndQuantityNode or nodes that specify the components that are included in the respective offer." + }, + "attributes": [ + "object" + ], + "id": "186" + }, + { + "range": "14", + "domain": "47", + "attributes": [ + "anonymous", + "object" + ], + "id": "187" + }, + { + "range": "68", + "domain": "8", + "attributes": [ + "anonymous", + "object" + ], + "id": "188" + }, + { + "range": "14", + "domain": "28", + "attributes": [ + "anonymous", + "object" + ], + "id": "189" + }, + { + "range": "68", + "domain": "1", + "attributes": [ + "anonymous", + "object" + ], + "id": "190" + }, + { + "range": "14", + "domain": "94", + "attributes": [ + "anonymous", + "object" + ], + "id": "191" + }, + { + "range": "21", + "domain": "1", + "attributes": [ + "anonymous", + "object" + ], + "id": "192" + }, + { + "range": "14", + "domain": "95", + "attributes": [ + "anonymous", + "object" + ], + "id": "193" + }, + { + "range": "81", + "domain": "73", + "attributes": [ + "anonymous", + "object" + ], + "id": "194" + }, + { + "iri": "http://purl.org/goodrelations/v1#isSimilarTo", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "14", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "isSimilarTo", + "en": "is similar to (0..*)" + }, + "domain": "130", + "comment": { + "en": "This states that a given gr:ProductOrService is similar to another product or service. Of course, this is a subjective statement; when interpreting it, the trust in the origin of the statement should be taken into account." + }, + "attributes": [ + "object" + ], + "id": "195" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasMinValueFloat", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "108", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasMinValueFloat", + "en": "has min value float (1..1)" + }, + "domain": "76", + "comment": { + "en": "This property captures the lower limit of a gr:QuantitativeValueFloat instance." + }, + "attributes": [ + "datatype" + ], + "id": "196" + }, + { + "iri": "http://purl.org/goodrelations/v1#nonEqual", + "inverse": "198", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "68", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "nonEqual", + "en": "non equal (0..*)" + }, + "domain": "68", + "comment": { + "en": "This ordering relation for gr:QualitativeValue pairs indicates that the subject is not equal to the object." + }, + "attributes": [ + "object", + "symmetric" + ], + "id": "198" + }, + { + "iri": "http://purl.org/goodrelations/v1#category", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "201", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "category", + "en": "category (0..*)" + }, + "domain": "200", + "comment": { + "en": "The name of a category to which this gr:ProductOrService, gr:Offering, gr:BusinessEntity, or gr:Location belongs.\n\t\nNote 1: For products, it is better to add an rdf:type statement referring to a GoodRelations-compliant ontology for vertical industries instead, but if you just have a short text label, gr:category is simpler.\nNote 2: You can use greater signs or slashes to informally indicate a category hierarchy, e.g. \"restaurants/asian_restaurants\" or \"cables > usb_cables\"\n" + }, + "attributes": [ + "datatype" + ], + "id": "199" + }, + { + "range": "5", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "202" + }, + { + "range": "2", + "domain": "5", + "attributes": [ + "anonymous", + "object" + ], + "id": "203" + }, + { + "iri": "http://purl.org/goodrelations/v1#validThrough", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "37", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "validThrough", + "en": "valid through (0..1)" + }, + "domain": "32", + "comment": { + "en": "This property specifies the end of the validity of the gr:Offering, gr:PriceSpecification, gr:License, or gr:OpeningHoursSpecification.\nA time-zone should be specified. For a time in GMT/UTC, simply add a \"Z\" following the time:\n\n2008-05-30T09:30:10Z.\n\nAlternatively, you can specify an offset from the UTC time by adding a positive or negative time following the time:\n\n2008-05-30T09:30:10-09:00\n\nor\n2008-05-30T09:30:10+09:00.\n\nNote 1: If multiple contradicting instances of a gr:Offering, gr:PriceSpecification, or gr:OpeningHoursSpecification exist, it is a good heuristics to assume that\n1. Information with validity information for the respective period of time ranks higher than information without validity information.\n2. Among conflicting nodes both having validity information, the one with the shorter validity span ranks higher.\nNote 2: For Google, attaching a gr:validThrough statement to a gr:UnitPriceSpecification is mandatory. \n" + }, + "attributes": [ + "datatype" + ], + "id": "204" + }, + { + "range": "5", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "205" + }, + { + "range": "30", + "domain": "5", + "attributes": [ + "anonymous", + "object" + ], + "id": "206" + }, + { + "range": "5", + "domain": "8", + "attributes": [ + "anonymous", + "object" + ], + "id": "207" + }, + { + "range": "79", + "domain": "5", + "attributes": [ + "anonymous", + "object" + ], + "id": "208" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasManufacturer", + "equivalent": [ + "210" + ], + "baseIri": "http://purl.org/goodrelations/v1", + "range": "5", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasManufacturer", + "en": "has manufacturer (0..1)" + }, + "domain": "147", + "comment": { + "en": "This object property links a gr:ProductOrService to the gr:BusinessEntity that produces it. Mostly used with gr:ProductOrServiceModel." + }, + "attributes": [ + "object" + ], + "id": "209" + }, + { + "range": "73", + "domain": "5", + "attributes": [ + "anonymous", + "object" + ], + "id": "211" + }, + { + "range": "5", + "domain": "77", + "attributes": [ + "anonymous", + "object" + ], + "id": "212" + }, + { + "range": "81", + "domain": "5", + "attributes": [ + "anonymous", + "object" + ], + "id": "213" + }, + { + "range": "21", + "domain": "5", + "attributes": [ + "anonymous", + "object" + ], + "id": "214" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasCurrencyValue", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "216", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasCurrencyValue", + "en": "has currency value (0..1)" + }, + "domain": "2", + "comment": { + "en": "This property specifies the amount of money for a price per unit, shipping charges, or payment charges. The currency and other relevant details are attached to the respective gr:PriceSpecification etc.\n\nFor a gr:UnitPriceSpecification, this is the price for one unit or bundle (as specified in the unit of measurement of the unit price specification) of the respective gr:ProductOrService. For a gr:DeliveryChargeSpecification or a gr:PaymentChargeSpecification, it is the price per delivery or payment.\n\nGoodRelations also supports giving price information as intervals only. If this is needed, use gr:hasMaxCurrencyValue for the upper bound and gr:hasMinCurrencyValue for the lower bound. \n\nUsing gr:hasCurrencyValue sets the upper and lower bounds to the same given value, i.e., x gr:hasCurrencyValue y implies x gr:hasMinCurrencyValue y, x gr:hasMaxCurrencyValue y." + }, + "attributes": [ + "datatype" + ], + "id": "215" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasValueFloat", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "89", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasValueFloat", + "en": "has value float (0..1)" + }, + "domain": "76", + "comment": { + "en": "This subproperty specifies that the upper and lower limit of the given gr:QuantitativeValueFloat are identical and have the respective float value. It is a shortcut for such cases where a quantitative property is (at least practically) a single point value and not an interval." + }, + "attributes": [ + "datatype" + ], + "id": "217" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasMaxValueInteger", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "103", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasMaxValueInteger", + "en": "has max value integer (1..1)" + }, + "domain": "65", + "comment": { + "en": "This property captures the upper limit of a gr:QuantitativeValueInteger instance." + }, + "attributes": [ + "datatype" + ], + "id": "218" + }, + { + "iri": "http://purl.org/goodrelations/v1#billingIncrement", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "220", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "billingIncrement", + "en": "billing increment (0..1)" + }, + "domain": "49", + "comment": { + "en": "This property specifies the minimal quantity and rounding increment that will be the basis for the billing. \nThe unit of measurement is specified by the UN/CEFACT code attached to the gr:UnitPriceSpecification via the gr:hasUnitOfMeasurement property.\n\nExamples: \n- The price for gasoline is 4 USD per gallon at the pump, but you will be charged in units of 0.1 gallons.\n- The price for legal consulting is 100 USD per hour, but you will be charged in units of 15 minutes.\n\nThis property makes sense only for instances of gr:Offering that include not more than one type of good or service." + }, + "attributes": [ + "datatype" + ], + "id": "219" + }, + { + "range": "5", + "domain": "41", + "attributes": [ + "anonymous", + "object" + ], + "id": "221" + }, + { + "range": "5", + "domain": "1", + "attributes": [ + "anonymous", + "object" + ], + "id": "222" + }, + { + "iri": "http://purl.org/goodrelations/v1#validFrom", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "62", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "validFrom", + "en": "valid from (0..1)" + }, + "domain": "60", + "comment": { + "en": "This property specifies the beginning of the validity of the gr:Offering, gr:PriceSpecification, gr:License, or gr:OpeningHoursSpecification.\nA time-zone should be specified. For a time in GMT/UTC, simply add a \"Z\" following the time:\n\n2008-05-30T09:30:10Z.\n\nAlternatively, you can specify an offset from the UTC time by adding a positive or negative time following the time:\n\n2008-05-30T09:30:10-09:00\n\nor\n\n2008-05-30T09:30:10+09:00.\n\nNote: If multiple contradicting instances of a gr:Offering, gr:PriceSpecification, or gr:OpeningHoursSpecification exist, it is a good heuristics to assume that\n1. Information with validity information for the respective period of time ranks higher than information without validity information.\n2. Among conflicting nodes both having validity information, the one with the shorter validity span ranks higher." + }, + "attributes": [ + "datatype" + ], + "id": "223" + }, + { + "range": "80", + "domain": "5", + "attributes": [ + "anonymous", + "object" + ], + "id": "224" + }, + { + "range": "75", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "225" + }, + { + "range": "75", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "226" + }, + { + "range": "5", + "domain": "28", + "attributes": [ + "anonymous", + "object" + ], + "id": "227" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasOpeningHoursSpecification", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "30", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasOpeningHoursSpecification", + "en": "has opening hours specification (0..*)" + }, + "domain": "132", + "comment": { + "en": "This property links a gr:Location to a gr:OpeningHoursSpecification." + }, + "attributes": [ + "object" + ], + "id": "228" + }, + { + "range": "75", + "domain": "5", + "attributes": [ + "anonymous", + "object" + ], + "id": "229" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasPrevious", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "80", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasPrevious", + "en": "has previous (0..1)" + }, + "domain": "80", + "comment": { + "en": "This ordering relation for gr:DayOfWeek indicates that the subject is directly preceeded by the object.\n\nExample: Tuesday hasPrevious Monday\n\nSince days of the week are a cycle, this property is not transitive." + }, + "attributes": [ + "object" + ], + "id": "230" + }, + { + "range": "75", + "domain": "8", + "attributes": [ + "anonymous", + "object" + ], + "id": "231" + }, + { + "range": "30", + "domain": "75", + "attributes": [ + "anonymous", + "object" + ], + "id": "232" + }, + { + "range": "75", + "domain": "2", + "attributes": [ + "anonymous", + "object" + ], + "id": "233" + }, + { + "range": "79", + "domain": "1", + "attributes": [ + "anonymous", + "object" + ], + "id": "234" + }, + { + "range": "21", + "domain": "79", + "attributes": [ + "anonymous", + "object" + ], + "id": "235" + }, + { + "range": "79", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "236" + }, + { + "range": "79", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "237" + }, + { + "range": "79", + "domain": "8", + "attributes": [ + "anonymous", + "object" + ], + "id": "238" + }, + { + "range": "81", + "domain": "79", + "attributes": [ + "anonymous", + "object" + ], + "id": "239" + }, + { + "range": "30", + "domain": "79", + "attributes": [ + "anonymous", + "object" + ], + "id": "240" + }, + { + "range": "79", + "domain": "14", + "attributes": [ + "anonymous", + "object" + ], + "id": "241" + }, + { + "iri": "http://purl.org/goodrelations/v1#name", + "equivalent": [ + "142" + ], + "baseIri": "http://purl.org/goodrelations/v1", + "range": "84", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "name", + "en": "name (0..1)" + }, + "domain": "72", + "comment": { + "en": "A short text describing the respective resource.\n\nThis property is semantically equivalent to dcterms:title and rdfs:label and just meant as a handy shortcut for marking up data." + }, + "attributes": [ + "datatype" + ], + "id": "242" + }, + { + "range": "2", + "domain": "73", + "attributes": [ + "anonymous", + "object" + ], + "id": "243" + }, + { + "range": "79", + "domain": "77", + "attributes": [ + "anonymous", + "object" + ], + "id": "244" + }, + { + "range": "79", + "domain": "2", + "attributes": [ + "anonymous", + "object" + ], + "id": "245" + }, + { + "range": "73", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "246" + }, + { + "range": "73", + "domain": "8", + "attributes": [ + "anonymous", + "object" + ], + "id": "247" + }, + { + "range": "79", + "domain": "73", + "attributes": [ + "anonymous", + "object" + ], + "id": "248" + }, + { + "range": "73", + "domain": "77", + "attributes": [ + "anonymous", + "object" + ], + "id": "249" + }, + { + "range": "21", + "domain": "73", + "attributes": [ + "anonymous", + "object" + ], + "id": "250" + }, + { + "range": "73", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "251" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasBrand", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "75", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasBrand", + "en": "has brand (0..*)" + }, + "domain": "154", + "comment": { + "en": "This specifies the brand or brands (gr:Brand) associated with a gr:ProductOrService, or the brand or brands maintained by a gr:BusinessEntity." + }, + "attributes": [ + "object" + ], + "id": "252" + }, + { + "range": "30", + "domain": "73", + "attributes": [ + "anonymous", + "object" + ], + "id": "253" + }, + { + "range": "80", + "domain": "73", + "attributes": [ + "anonymous", + "object" + ], + "id": "254" + }, + { + "range": "73", + "domain": "1", + "attributes": [ + "anonymous", + "object" + ], + "id": "255" + }, + { + "range": "14", + "domain": "73", + "attributes": [ + "anonymous", + "object" + ], + "id": "256" + }, + { + "range": "73", + "domain": "41", + "attributes": [ + "anonymous", + "object" + ], + "id": "257" + }, + { + "range": "81", + "domain": "8", + "attributes": [ + "anonymous", + "object" + ], + "id": "258" + }, + { + "range": "81", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "259" + }, + { + "range": "81", + "domain": "2", + "attributes": [ + "anonymous", + "object" + ], + "id": "260" + }, + { + "range": "81", + "domain": "21", + "attributes": [ + "anonymous", + "object" + ], + "id": "261" + }, + { + "range": "81", + "domain": "30", + "attributes": [ + "anonymous", + "object" + ], + "id": "262" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasGlobalLocationNumber", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "265", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasGlobalLocationNumber", + "en": "has Global Location Number (0..1)" + }, + "domain": "264", + "comment": { + "en": "The Global Location Number (GLN, sometimes also referred to as International Location Number or ILN) of the respective gr:BusinessEntity or gr:Location.\nThe Global Location Number is a thirteen-digit number used to identify parties and physical locations." + }, + "attributes": [ + "datatype" + ], + "id": "263" + }, + { + "range": "81", + "domain": "14", + "attributes": [ + "anonymous", + "object" + ], + "id": "266" + }, + { + "range": "81", + "domain": "77", + "attributes": [ + "anonymous", + "object" + ], + "id": "267" + }, + { + "iri": "http://purl.org/goodrelations/v1#seeks", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "33", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "seeks", + "en": "seeks (0..*)" + }, + "domain": "119", + "comment": { + "en": "This links a gr:BusinessEntity to gr:Offering nodes that describe what the business entity is interested in (i.e., the buy side). If you want to express interest in offering something, use gr:offers instead. Note that this substitutes the former gr:BusinessFunction gr:Buy, which is now deprecated." + }, + "attributes": [ + "object" + ], + "id": "268" + }, + { + "iri": "http://schema.org/manufacturer", + "baseIri": "http://schema.org", + "range": "12", + "label": { + "IRI-based": "manufacturer" + }, + "domain": "12", + "attributes": [ + "external", + "object" + ], + "id": "210" + }, + { + "range": "80", + "domain": "2", + "attributes": [ + "anonymous", + "object" + ], + "id": "269" + }, + { + "range": "80", + "domain": "1", + "attributes": [ + "anonymous", + "object" + ], + "id": "270" + }, + { + "range": "49", + "domain": "74", + "attributes": [ + "anonymous", + "object" + ], + "id": "271" + }, + { + "range": "50", + "domain": "74", + "attributes": [ + "anonymous", + "object" + ], + "id": "272" + }, + { + "range": "81", + "domain": "80", + "attributes": [ + "anonymous", + "object" + ], + "id": "273" + }, + { + "range": "80", + "domain": "77", + "attributes": [ + "anonymous", + "object" + ], + "id": "274" + }, + { + "range": "80", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "275" + }, + { + "range": "80", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "276" + }, + { + "range": "30", + "domain": "80", + "attributes": [ + "anonymous", + "object" + ], + "id": "277" + }, + { + "range": "80", + "domain": "8", + "attributes": [ + "anonymous", + "object" + ], + "id": "278" + }, + { + "range": "80", + "domain": "41", + "attributes": [ + "anonymous", + "object" + ], + "id": "279" + }, + { + "range": "79", + "domain": "41", + "attributes": [ + "anonymous", + "object" + ], + "id": "280" + }, + { + "range": "80", + "domain": "79", + "attributes": [ + "anonymous", + "object" + ], + "id": "281" + }, + { + "range": "80", + "domain": "14", + "attributes": [ + "anonymous", + "object" + ], + "id": "282" + }, + { + "range": "21", + "domain": "80", + "attributes": [ + "anonymous", + "object" + ], + "id": "283" + }, + { + "range": "11", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "284" + }, + { + "range": "68", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "285" + }, + { + "range": "41", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "286" + }, + { + "range": "21", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "287" + }, + { + "range": "8", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "288" + }, + { + "range": "2", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "289" + }, + { + "range": "1", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "290" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasEligibleQuantity", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasEligibleQuantity", + "en": "has eligible quantity (0..1)" + }, + "domain": "145", + "comment": { + "en": "This specifies the interval and unit of measurement of ordering quantities for which the gr:Offering or gr:PriceSpecification is valid. This allows e.g. specifying that a certain freight charge is valid only for a certain quantity.\nNote that if an offering is a bundle, i.e. it consists of more than one unit of a single type of good, or if the unit of measurement for the good is different from unit (Common Code C62), then gr:hasEligibleQuantity refers to units of this bundle. In other words, \"C62\" for \"Units or pieces\" is usually the appropriate unit of measurement." + }, + "attributes": [ + "object" + ], + "id": "291" + }, + { + "range": "8", + "domain": "77", + "attributes": [ + "anonymous", + "object" + ], + "id": "292" + }, + { + "range": "30", + "domain": "77", + "attributes": [ + "anonymous", + "object" + ], + "id": "293" + }, + { + "range": "30", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "294" + }, + { + "range": "14", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "295" + }, + { + "range": "11", + "domain": "77", + "attributes": [ + "anonymous", + "object" + ], + "id": "296" + }, + { + "range": "2", + "domain": "77", + "attributes": [ + "anonymous", + "object" + ], + "id": "297" + }, + { + "range": "41", + "domain": "77", + "attributes": [ + "anonymous", + "object" + ], + "id": "298" + }, + { + "range": "21", + "domain": "77", + "attributes": [ + "anonymous", + "object" + ], + "id": "299" + }, + { + "range": "1", + "domain": "77", + "attributes": [ + "anonymous", + "object" + ], + "id": "300" + }, + { + "range": "77", + "domain": "33", + "attributes": [ + "anonymous", + "object" + ], + "id": "301" + }, + { + "iri": "http://purl.org/goodrelations/v1#weight", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "weight", + "en": "weight (0..1)" + }, + "superproperty": [ + "26" + ], + "domain": "303", + "comment": { + "en": "The weight of the gr:ProductOrService.\nTypical unit code(s): GRM for gram, KGM for kilogram, LBR for pound" + }, + "attributes": [ + "object" + ], + "id": "302" + }, + { + "range": "23", + "domain": "47", + "attributes": [ + "anonymous", + "object" + ], + "id": "304" + }, + { + "range": "81", + "domain": "1", + "attributes": [ + "anonymous", + "object" + ], + "id": "305" + }, + { + "range": "81", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "306" + }, + { + "iri": "http://purl.org/goodrelations/v1#serialNumber", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "51", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "serialNumber", + "en": "serial number (0..*)" + }, + "domain": "45", + "comment": { + "en": "The serial number or any alphanumeric identifier of a particular product. Note that serial number are unique only for the same brand or the same model, so you cannot infer from two occurrences of the same serial number that the objects to which they are attached are identical.\n\nThis property can also be attached to a gr:Offering in cases where the included products are not modeled in more detail." + }, + "attributes": [ + "datatype" + ], + "id": "307" + }, + { + "range": "28", + "domain": "47", + "attributes": [ + "anonymous", + "object" + ], + "id": "308" + }, + { + "range": "81", + "domain": "41", + "attributes": [ + "anonymous", + "object" + ], + "id": "309" + }, + { + "iri": "http://purl.org/goodrelations/v1#width", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "width", + "en": "width (0..1)" + }, + "superproperty": [ + "26" + ], + "domain": "311", + "comment": { + "en": "The width of the gr:ProductOrService.\nTypical unit code(s): CMT for centimeters, INH for inches" + }, + "attributes": [ + "object" + ], + "id": "310" + }, + { + "iri": "http://purl.org/goodrelations/v1#datatypeProductOrServiceProperty", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "314", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "datatypeProductOrServiceProperty", + "en": "datatype product or service property (0..*)" + }, + "domain": "313", + "comment": { + "en": "This property is the super property for all pure datatype properties that can be used to describe a gr:ProductOrService.\n\nIn products and services ontologies, only such properties that are no quantitative properties and that have no predefined gr:QualitativeValue instances are subproperties of this property. In practice, this refers to a few integer properties for which the integer value represents qualitative aspects, for string datatypes (as long as no predefined values exist), for boolean datatype properties, and for dates and times." + }, + "attributes": [ + "datatype" + ], + "id": "312" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasNext", + "inverse": "230", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "80", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasNext", + "en": "has next (0..1)" + }, + "domain": "80", + "comment": { + "en": "This ordering relation for gr:DayOfWeek indicates that the subject is directly followed by the object.\n\nExample: Monday hasNext Tuesday\n\nSince days of the week are a cycle, this property is not transitive." + }, + "attributes": [ + "object" + ], + "id": "315" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasMPN", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "318", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasMPN", + "en": "has MPN (0..*)" + }, + "domain": "317", + "comment": { + "en": "The Manufacturer Part Number or MPN is a unique identifier for a product, service, or bundle from the perspective of a particular manufacturer. MPNs can be assigned to products or product datasheets, or bundles. Accordingly, the domain of this property is the union of gr:ProductOrService (the common superclass of goods and datasheets), and gr:Offering.\n\nImportant: Be careful when assuming two products or services instances or offering instances to be identical based on the MPN. Since MPNs are unique only for the same gr:BusinessEntity, this holds only when the two MPN values refer to the same gr:BusinessEntity. Such can be done by taking into account the provenance of the data. \n\nUsually, the properties gr:hasEAN_UCC-13 and gr:hasGTIN-14 are much more reliable identifiers, because they are globally unique.\n\nSee also http://en.wikipedia.org/wiki/Part_number" + }, + "attributes": [ + "datatype" + ], + "id": "316" + }, + { + "range": "30", + "domain": "2", + "attributes": [ + "anonymous", + "object" + ], + "id": "319" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasEAN_UCC-13", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "322", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasEAN_UCC-13", + "en": "has EAN/UCC-13 (0..*)" + }, + "domain": "321", + "comment": { + "en": "The EAN·UCC-13 code of the given gr:ProductOrService or gr:Offering. This code is now officially called GTIN-13 (Global Trade Identifier Number) or EAN·UCC-13. Former 12-digit UPC codes can be converted into EAN·UCC-13 code by simply adding a preceeding zero.\n\nNote 1: When using this property for searching by 12-digit UPC codes, you must add a preceeding zero digit.\nNote 2: As of January 1, 2007, the former ISBN numbers for books etc. have been integrated into the EAN·UCC-13 code. For each old ISBN-10 code, there exists a proper translation into EAN·UCC-13 by adding \"978\" or \"979\" as prefix. Since the old ISBN-10 is now deprecated, GoodRelations does not provide a property for ISBNs." + }, + "attributes": [ + "datatype" + ], + "id": "320" + }, + { + "range": "30", + "domain": "11", + "attributes": [ + "anonymous", + "object" + ], + "id": "323" + }, + { + "range": "21", + "domain": "30", + "attributes": [ + "anonymous", + "object" + ], + "id": "324" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasMaxValueFloat", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "101", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasMaxValueFloat", + "en": "has max value float (1..1)" + }, + "domain": "76", + "comment": { + "en": "This property captures the upper limit of a gr:QuantitativeValueFloat instance." + }, + "attributes": [ + "datatype" + ], + "id": "325" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasUnitOfMeasurement", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "87", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasUnitOfMeasurement", + "en": "has unit of measurement (1..1)" + }, + "domain": "86", + "comment": { + "en": "The unit of measurement for a gr:QuantitativeValue, a gr:UnitPriceSpecification, or a gr:TypeAndQuantityNode given using the UN/CEFACT Common Code (3 characters)." + }, + "attributes": [ + "datatype" + ], + "id": "326" + }, + { + "iri": "http://purl.org/goodrelations/v1#availabilityEnds", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "329", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "availabilityEnds", + "en": "availability ends (0..1)" + }, + "domain": "328", + "comment": { + "en": "This property specifies the end of the availability of the gr:ProductOrService included in the gr:Offering.\nThe difference to the properties gr:validFrom and gr:validThrough is that those specify the period of time during which the offer is valid and can be accepted.\n\nExample: I offer to lease my boat for the period of August 1 - August 31, 2010, but you must accept by offer no later than July 15.\n\nA time-zone should be specified. For a time in GMT/UTC, simply add a \"Z\" following the time:\n\n2008-05-30T09:30:10Z.\n\nAlternatively, you can specify an offset from the UTC time by adding a positive or negative time following the time:\n\n2008-05-30T09:30:10-09:00\n\nor\n\n2008-05-30T09:30:10+09:00.\n\nNote: There is another property gr:availableAtOrFrom, which is used to indicate the gr:Location (e.g. store or shop) from which the goods would be available." + }, + "attributes": [ + "datatype" + ], + "id": "327" + }, + { + "iri": "http://purl.org/goodrelations/v1#vatID", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "9", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "vatID", + "en": "VAT ID (0..1)" + }, + "domain": "3", + "comment": { + "en": "The Value-added Tax ID of the gr:BusinessEntity. See http://en.wikipedia.org/wiki/Value_added_tax_identification_number for details." + }, + "attributes": [ + "datatype" + ], + "id": "330" + }, + { + "iri": "http://schema.org/productID", + "baseIri": "http://schema.org", + "range": "17", + "label": { + "IRI-based": "productID" + }, + "domain": "12", + "attributes": [ + "external", + "datatype" + ], + "id": "332" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasValue", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "88", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasValue", + "en": "has value (0..1)" + }, + "domain": "1", + "comment": { + "en": "This subproperty specifies that the upper and lower limit of the given gr:QuantitativeValue are identical and have the respective value. It is a shortcut for such cases where a quantitative property is (at least practically) a single point value and not an interval." + }, + "attributes": [ + "datatype" + ], + "id": "333" + }, + { + "iri": "http://purl.org/goodrelations/v1#greater", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "68", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "greater", + "en": "greater (0..*)" + }, + "domain": "68", + "comment": { + "en": "This ordering relation for qualitative values indicates that the subject is greater than the object." + }, + "attributes": [ + "object", + "transitive" + ], + "id": "334" + }, + { + "iri": "http://purl.org/goodrelations/v1#typeOfGood", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "120", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "typeOfGood", + "en": "type of good (1..1)" + }, + "domain": "8", + "comment": { + "en": "This specifies the gr:ProductOrService that the gr:TypeAndQuantityNode is referring to." + }, + "attributes": [ + "object" + ], + "id": "335" + }, + { + "iri": "http://purl.org/goodrelations/v1#deliveryLeadTime", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "65", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "deliveryLeadTime", + "en": "delivery lead time (0..1)" + }, + "domain": "148", + "comment": { + "en": "This property can be used to indicate the promised delay between the receipt of the order and the goods leaving the warehouse.\n\nThe duration is specified by attaching an instance of gr:QuantitativeValueInteger. The lower and upper boundaries are specified using the properties gr:hasMinValueInteger and gr:hasMaxValueInteger to that instance. A point value can be modeled with the gr:hasValueInteger property. The unit of measurement is specified using the property gr:hasUnitOfMeasurement with a string holding a UN/CEFACT code suitable for durations, e.g. MON (months), DAY (days), HUR (hours), or MIN (minutes)." + }, + "attributes": [ + "object" + ], + "id": "336" + }, + { + "iri": "http://purl.org/goodrelations/v1#closes", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "338", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "closes", + "en": "closes (1..1)" + }, + "domain": "30", + "comment": { + "en": "The closing hour of the gr:Location on the given gr:DayOfWeek.\nIf no time-zone suffix is included, the time is given in the local time valid at the gr:Location.\n\nFor a time in GMT/UTC, simply add a \"Z\" following the time:\n\n09:30:10Z.\n\nAlternatively, you can specify an offset from the UTC time by adding a positive or negative time following the time:\n\n09:30:10-09:00\n\n09:30:10+09:00.\n\nNote 1: Use 00:00:00 for the first second of the respective day and 23:59:59 for the last second of that day.\nNote 2: If a store opens at 17:00 on Saturdays and closes at 03:00:00 a.m. next morning, use two instances of this class, one with 17:00:00 - 23:59:59 for Saturday and another one with 00:00:00 - 03:00:00 for Sunday.\nNote 3: If the shop re-opens on the same day of the week or set of days of the week, you must create a second instance of gr:OpeningHoursSpecification." + }, + "attributes": [ + "datatype" + ], + "id": "337" + }, + { + "iri": "http://purl.org/goodrelations/v1#includes", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "14", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "includes", + "en": "includes (0..1)" + }, + "domain": "33", + "comment": { + "en": "This object property is a shortcut for the original gr:includesObject property for the common case of having exactly one single gr:ProductOrService instance included in an Offering. \n\nWhen linking to an instance of gr:SomeItems or gr:Individual, it is equivalent to using a gr:TypeAndQuantityNode with gr:hasUnitOfMeasurement=\"C62\"^^xsd:string and gr:amountOfThisGood=\"1.0\"^^xsd:float for that good.\n\nWhen linking to a gr:ProductOrServiceModel, it is equivalent to \n1. defining an blank node for a gr:SomeItems\n2. linking that blank node via gr:hasMakeAndModel to the gr:ProductOrServiceModel, and\n3. linking from the gr:Offering to that blank node using another blank node of type gr:TypeAndQuantityNode with gr:hasUnitOfMeasurement=\"C62\"^^xsd:string and gr:amountOfThisGood=\"1.0\"^^xsd:float for that good." + }, + "attributes": [ + "object" + ], + "id": "339" + }, + { + "iri": "http://purl.org/goodrelations/v1#taxID", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "57", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "taxID", + "en": "Tax ID (0..1)" + }, + "domain": "55", + "comment": { + "en": "The Tax / Fiscal ID of the gr:BusinessEntity, e.g. the TIN in the US or the CIF/NIF in Spain. It is usually assigned by the country of residence" + }, + "attributes": [ + "datatype" + ], + "id": "340" + }, + { + "iri": "http://purl.org/goodrelations/v1#greaterOrEqual", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "68", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "greaterOrEqual", + "en": "greater or equal (0..*)" + }, + "domain": "68", + "comment": { + "en": "This ordering relation for qualitative values indicates that the subject is greater than or equal to the object." + }, + "attributes": [ + "object", + "transitive" + ], + "id": "69" + }, + { + "iri": "http://purl.org/goodrelations/v1#appliesToPaymentMethod", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "41", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "appliesToPaymentMethod", + "en": "applies to payment method (1..*)" + }, + "domain": "50", + "comment": { + "en": "This property specifies the gr:PaymentMethod to which the gr:PaymentChargeSpecification applies." + }, + "attributes": [ + "object" + ], + "id": "341" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasCurrency", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "343", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasCurrency", + "en": "has currency (1..1)" + }, + "domain": "2", + "comment": { + "en": "The currency for all prices in the gr:PriceSpecification given using the ISO 4217 standard (3 characters)." + }, + "attributes": [ + "datatype" + ], + "id": "342" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasPOS", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "77", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasPOS", + "en": "has POS (0..*)" + }, + "domain": "135", + "comment": { + "en": "This property states that the respective gr:Location is a point of sale for the respective gr:BusinessEntity. It allows linking those two types of entities without the need for a particular gr:Offering." + }, + "attributes": [ + "object" + ], + "id": "344" + }, + { + "iri": "http://purl.org/goodrelations/v1#qualitativeProductOrServiceProperty", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "68", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "qualitativeProductOrServiceProperty", + "en": "qualitative product or service property (0..*)" + }, + "domain": "117", + "comment": { + "en": "This is the super property of all qualitative properties for products and services. All properties in product or service ontologies for which gr:QualitativeValue instances are specified are subproperties of this property." + }, + "attributes": [ + "object" + ], + "id": "345" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasMaxValue", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "100", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasMaxValue", + "en": "has max value (0..1)" + }, + "domain": "1", + "comment": { + "en": "This property captures the upper limit of a gr:QuantitativeValue instance." + }, + "attributes": [ + "datatype" + ], + "id": "346" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasStockKeepingUnit", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "85", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasStockKeepingUnit", + "en": "has Stock Keeping Unit (0..*)" + }, + "domain": "98", + "comment": { + "en": "The Stock Keeping Unit, or SKU is a unique identifier for a product, service, or bundle from the perspective of a particular supplier, i.e. SKUs are mostly assigned and serialized at the merchant level. \nExamples of SKUs are the ordering or parts numbers used by a particular Web shop or catalog.\n\nConsequently, the domain of gr:hasStockKeepingUnit is the union of the classes gr:Offering and gr:ProductOrService. \nIf attached to a gr:Offering, the SKU will usually reflect a merchant-specific identifier, i.e. one valid only for that particular retailer or shop. \nIf attached to a gr:ProductOrServiceModel, the SKU can reflect either the identifier used by the merchant or the part number used by the official manufacturer of that part. For the latter, gr:hasMPN is a better choice.\n\nImportant: Be careful when assuming two products or services instances or offering instances to be identical based on the SKU. Since SKUs are unique only for the same gr:BusinessEntity, this can be assumed only when you are sure that the two SKU values refer to the same business entity. Such can be done by taking into account the provenance of the data. As long as instances of gr:Offering are concerned, you can also check that the offerings are being offered by the same gr:Business Entity.\n\nUsually, the properties gr:hasEAN_UCC-13 and gr:hasGTIN-14 are much more reliable identifiers, because they are globally unique.\n\nSee also http://en.wikipedia.org/wiki/Stock_Keeping_Unit." + }, + "attributes": [ + "datatype" + ], + "id": "347" + }, + { + "iri": "http://purl.org/goodrelations/v1#availableDeliveryMethods", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "81", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "availableDeliveryMethods", + "en": "available delivery methods (0..*)" + }, + "domain": "165", + "comment": { + "en": "This specifies the gr:DeliveryMethod or methods available for a given gr:Offering." + }, + "attributes": [ + "object" + ], + "id": "349" + }, + { + "iri": "http://purl.org/goodrelations/v1#valueAddedTaxIncluded", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "39", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "valueAddedTaxIncluded", + "en": "value added tax included (0..1)" + }, + "domain": "2", + "comment": { + "en": "This property specifies whether the applicable value-added tax (VAT) is included in the price of the gr:PriceSpecification or not.\n\nNote: This is a simple representation which may not properly reflect all details of local taxation." + }, + "attributes": [ + "datatype" + ], + "id": "351" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasDUNS", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "354", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasDUNS", + "en": "has DUNS (0..1)" + }, + "domain": "353", + "comment": { + "en": "The Dun & Bradstreet DUNS number for identifying a gr:BusinessEntity. The Dun & Bradstreet DUNS is a nine-digit number used to identify legal entities (but usually not branches or locations of logistical importance only)." + }, + "attributes": [ + "datatype" + ], + "id": "352" + }, + { + "iri": "http://purl.org/goodrelations/v1#quantitativeProductOrServiceProperty", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "quantitativeProductOrServiceProperty", + "en": "quantitative product or service property (0..*)" + }, + "domain": "118", + "subproperty": [ + "171", + "24", + "310", + "302" + ], + "comment": { + "en": "This is the super property of all quantitative properties for products and services. All properties in product or service ontologies that specify quantitative characteristics, for which an interval is at least theoretically an appropriate value, are subproperties of this property." + }, + "attributes": [ + "object" + ], + "id": "26" + }, + { + "iri": "http://purl.org/goodrelations/v1#eligibleRegions", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "357", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "eligibleRegions", + "en": "eligible regions (0..*)" + }, + "domain": "356", + "comment": { + "en": "This property specifies the geo-political region or regions for which the gr:Offering, gr:License, or gr:DeliveryChargeSpecification is valid using the two-character version of ISO 3166-1 (ISO 3166-1 alpha-2) for regions or ISO 3166-2 , which breaks down the countries from ISO 3166-1 into administrative subdivisions.\n\nImportant: Do NOT use 3-letter ISO 3166-1 codes!" + }, + "attributes": [ + "datatype" + ], + "id": "355" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasMinCurrencyValue", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "104", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasMinCurrencyValue", + "en": "has min currency value (1..1)" + }, + "domain": "2", + "comment": { + "en": "This property specifies the LOWER BOUND of the amount of money for a price RANGE per unit, shipping charges, or payment charges. The currency and other relevant details are attached to the respective gr:PriceSpecification etc.\nFor a gr:UnitPriceSpecification, this is the LOWER BOUND for the price for one unit or bundle (as specified in the unit of measurement of the unit price specification) of the respective gr:ProductOrService. For a gr:DeliveryChargeSpecification or a gr:PaymentChargeSpecification, it is the LOWER BOUND of the price per delivery or payment.\n\nUsing gr:hasCurrencyValue sets the upper and lower bounds to the same given value, i.e., x gr:hasCurrencyValue y implies x gr:hasMinCurrencyValue y, x gr:hasMaxCurrencyValue y." + }, + "attributes": [ + "datatype" + ], + "id": "358" + }, + { + "iri": "http://purl.org/goodrelations/v1#lesser", + "inverse": "334", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "68", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "lesser", + "en": "lesser (0..*)" + }, + "domain": "68", + "comment": { + "en": "This ordering relation for gr:QualitativeValue pairs indicates that the subject is lesser than the object." + }, + "attributes": [ + "object", + "transitive" + ], + "id": "360" + }, + { + "iri": "http://schema.org/image", + "equivalent": [ + "96" + ], + "baseIri": "http://schema.org", + "range": "12", + "label": { + "IRI-based": "image" + }, + "domain": "12", + "attributes": [ + "external", + "object" + ], + "id": "97" + }, + { + "iri": "http://purl.org/goodrelations/v1#appliesToDeliveryMethod", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "81", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "appliesToDeliveryMethod", + "en": "applies to delivery method (0..*)" + }, + "domain": "74", + "comment": { + "en": "This property specifies the gr:DeliveryMethod to which the gr:DeliveryChargeSpecification applies." + }, + "attributes": [ + "object" + ], + "id": "362" + }, + { + "iri": "http://purl.org/goodrelations/v1#color", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "365", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "color", + "en": "color (0..1)" + }, + "domain": "364", + "comment": { + "en": "The color of the product." + }, + "attributes": [ + "datatype" + ], + "id": "363" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasBusinessFunction", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "79", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasBusinessFunction", + "en": "has business function (1..*)" + }, + "domain": "144", + "comment": { + "en": "This specifies the business function of the gr:Offering, i.e. whether the gr:BusinessEntity is offering to sell, to lease, or to repair the particular type of product. In the case of bundles, it is also possible to attach individual business functions to each gr:TypeAndQuantityNode. The business function of the main gr:Offering determines the business function for all included objects or services, unless a business function attached to a gr:TypeAndQuantityNode overrides it.\n\t\nNote: While it is possible that an entity is offering multiple types of business functions for the same set of objects (e.g. rental and sales), this should usually not be stated by attaching multiple business functions to the same gr:Offering, since the gr:UnitPriceSpecification for the varying business functions will typically be very different." + }, + "attributes": [ + "object" + ], + "id": "369" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasNAICS", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "111", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasNAICS", + "en": "has NAICS (0..*)" + }, + "domain": "110", + "comment": { + "en": "The North American Industry Classification System (NAICS) code for a particular gr:BusinessEntity.\nSee http://www.census.gov/eos/www/naics/ for more details.\n\nNote: While NAICS codes are sometimes misused for classifying products or services, they are designed and suited only for classifying business establishments." + }, + "attributes": [ + "datatype" + ], + "id": "370" + }, + { + "iri": "http://purl.org/goodrelations/v1#legalName", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "93", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "legalName", + "en": "legal name (0..1)" + }, + "domain": "92", + "comment": { + "en": "The legal name of the gr:BusinessEntity." + }, + "attributes": [ + "datatype" + ], + "id": "372" + }, + { + "iri": "http://purl.org/goodrelations/v1#condition", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "367", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "condition", + "en": "condition (0..1)" + }, + "domain": "366", + "comment": { + "en": "A textual description of the condition of the product or service, or the products or services included in the offer (when attached to a gr:Offering)" + }, + "attributes": [ + "datatype" + ], + "id": "373" + }, + { + "iri": "http://purl.org/goodrelations/v1#offers", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "33", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "offers", + "en": "offers (0..*)" + }, + "domain": "131", + "comment": { + "en": "This links a gr:BusinessEntity to the offers (gr:Offering) it makes. If you want to express interest in receiving offers, use gr:seeks instead." + }, + "attributes": [ + "object" + ], + "id": "374" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasMinValueInteger", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "109", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasMinValueInteger", + "en": "has min value integer (1..1)" + }, + "domain": "65", + "comment": { + "en": "This property captures the lower limit of a gr:QuantitativeValueInteger instance." + }, + "attributes": [ + "datatype" + ], + "id": "375" + }, + { + "iri": "http://purl.org/goodrelations/v1#acceptedPaymentMethods", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "41", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "acceptedPaymentMethods", + "en": "accepted payment methods (0..*)" + }, + "domain": "180", + "comment": { + "en": "The gr:PaymentMethod or methods accepted by the gr:BusinessEntity for the given gr:Offering." + }, + "attributes": [ + "object" + ], + "id": "376" + }, + { + "iri": "http://purl.org/goodrelations/v1#eligibleDuration", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "eligibleDuration", + "en": "eligible duration (0..1)" + }, + "domain": "152", + "comment": { + "en": "The minimal and maximal duration for which the given gr:Offering or gr:License is valid. This is mostly used for offers regarding accommodation, the rental of objects, or software licenses. The duration is specified by attaching an instance of gr:QuantitativeValue. The lower and upper boundaries are specified using the properties gr:hasMinValue and gr:hasMaxValue to that instance. If they are the same, use the gr:hasValue property. The unit of measurement is specified using the property gr:hasUnitOfMeasurement with a string holding a UN/CEFACT code suitable for durations, e.g. MON (months), DAY (days), HUR (hours), or MIN (minutes).\n\nThe difference to the gr:validFrom and gr:validThrough properties is that those specify the absiolute interval during which the gr:Offering or gr:License is valid, while gr:eligibleDuration specifies the acceptable duration of the contract or usage." + }, + "attributes": [ + "object" + ], + "id": "379" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasISICv4", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "350", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasISICv4", + "en": "has ISIC v4 (0..*)" + }, + "domain": "348", + "comment": { + "en": "The International Standard of Industrial Classification of All Economic Activities (ISIC), Revision 4 code for a particular gr:BusinessEntity or gr:Location. See http://unstats.un.org/unsd/cr/registry/isic-4.asp for more information.\n\nNote: While ISIC codes are sometimes misused for classifying products or services, they are designed and suited only for classifying business establishments." + }, + "attributes": [ + "datatype" + ], + "id": "380" + }, + { + "iri": "http://purl.org/goodrelations/v1#availabilityStarts", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "371", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "availabilityStarts", + "en": "availability starts (0..1)" + }, + "domain": "368", + "comment": { + "en": "This property specifies the beginning of the availability of the gr:ProductOrService included in the gr:Offering.\nThe difference to the properties gr:validFrom and gr:validThrough is that those specify the period of time during which the offer is valid and can be accepted.\n\nExample: I offer to lease my boat for the period of August 1 - August 31, 2010, but you must accept by offer no later than July 15.\n\nA time-zone should be specified. For a time in GMT/UTC, simply add a \"Z\" following the time:\n\n2008-05-30T09:30:10Z.\n\nAlternatively, you can specify an offset from the UTC time by adding a positive or negative time following the time:\n\n2008-05-30T09:30:10-09:00\n\nor\n\n2008-05-30T09:30:10+09:00.\n\nNote: There is another property gr:availableAtOrFrom, which is used to indicate the gr:Location (e.g. store or shop) from which the goods would be available." + }, + "attributes": [ + "datatype" + ], + "id": "381" + }, + { + "range": "75", + "domain": "79", + "attributes": [ + "anonymous", + "object" + ], + "id": "382" + }, + { + "range": "75", + "domain": "73", + "attributes": [ + "anonymous", + "object" + ], + "id": "383" + }, + { + "iri": "http://purl.org/goodrelations/v1#description", + "equivalent": [ + "58" + ], + "baseIri": "http://purl.org/goodrelations/v1", + "range": "359", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "description", + "en": "description (0..1)" + }, + "domain": "361", + "comment": { + "en": "A short textual description of the resource. \n\nThis property is semantically equivalent to rdfs:comment and just meant as a handy shortcut for marking up data." + }, + "attributes": [ + "datatype" + ], + "id": "384" + }, + { + "iri": "http://purl.org/goodrelations/v1#priceType", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "43", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "priceType", + "en": "price type (0..1)" + }, + "domain": "49", + "comment": { + "en": "This attribute can be used to distinguish multiple different price specifications for the same gr:Offering. It supersedes the former gr:isListPrice property. The following values are recommended:\n\nThe absence of this property marks the actual sales price.\n\nSRP: \"suggested retail price\" - applicable for all sorts of a non-binding retail price recommendations, e.g. such published by the manufacturer or the distributor. This value replaces the former gr:isListPrice property.\n\nINVOICE: The invoice price, mostly used in the car industry - this is the price a dealer pays to the manufacturer, excluding rebates and charges." + }, + "attributes": [ + "datatype" + ], + "id": "385" + }, + { + "range": "75", + "domain": "28", + "attributes": [ + "anonymous", + "object" + ], + "id": "386" + }, + { + "range": "75", + "domain": "41", + "attributes": [ + "anonymous", + "object" + ], + "id": "387" + }, + { + "range": "75", + "domain": "14", + "attributes": [ + "anonymous", + "object" + ], + "id": "388" + }, + { + "range": "75", + "domain": "77", + "attributes": [ + "anonymous", + "object" + ], + "id": "389" + }, + { + "range": "21", + "domain": "75", + "attributes": [ + "anonymous", + "object" + ], + "id": "390" + }, + { + "range": "75", + "domain": "1", + "attributes": [ + "anonymous", + "object" + ], + "id": "391" + }, + { + "iri": "http://purl.org/goodrelations/v1#valueReference", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "378", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "valueReference", + "en": "value reference (0..*)" + }, + "domain": "377", + "comment": { + "en": "The superclass of properties that link a gr:QuantitativeValue or a gr:QualitativeValue to a second gr:QuantitativeValue or a gr:QualitativeValue that provides additional information on the original value. A good modeling practice is to define specializations of this property (e.g. foo:referenceTemperature) for your particular domain." + }, + "attributes": [ + "object" + ], + "id": "392" + }, + { + "range": "81", + "domain": "75", + "attributes": [ + "anonymous", + "object" + ], + "id": "393" + }, + { + "range": "80", + "domain": "75", + "attributes": [ + "anonymous", + "object" + ], + "id": "394" + }, + { + "iri": "http://purl.org/goodrelations/v1#isAccessoryOrSparePartFor", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "14", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "isAccessoryOrSparePartFor", + "en": "is accessory or spare part for (0..*)" + }, + "domain": "126", + "comment": { + "en": "This states that a particular gr:ProductOrService is an accessory or spare part for another product or service." + }, + "attributes": [ + "object" + ], + "id": "395" + }, + { + "iri": "http://purl.org/goodrelations/v1#hasMakeAndModel", + "baseIri": "http://purl.org/goodrelations/v1", + "range": "28", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/goodrelations/v1", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasMakeAndModel", + "en": "has make and model (0..1)" + }, + "domain": "146", + "comment": { + "en": "This states that an actual product instance (gr:Individual) or a placeholder instance for multiple, unidentified such instances (gr:SomeItems) is one occurence of a particular gr:ProductOrServiceModel.\n\nExample: myFordT hasMakeAndModel FordT." + }, + "attributes": [ + "object" + ], + "id": "396" + } + ] +} \ No newline at end of file diff --git a/src/app/data/muto.json b/src/app/data/muto.json new file mode 100644 index 0000000000000000000000000000000000000000..83898b08a9a37c7c32c94b670d442dcfcdfea6b7 --- /dev/null +++ b/src/app/data/muto.json @@ -0,0 +1,1171 @@ +{ + "_comment": "Created with OWL2VOWL (version 0.3.4), http://vowl.visualdataweb.org", + "header": { + "languages": [ + "en", + "undefined" + ], + "baseIris": [ + "http://purl.org/muto/core", + "http://www.w3.org/1999/02/22-rdf-syntax-ns", + "http://www.w3.org/2000/01/rdf-schema", + "http://purl.org/dc/terms", + "http://www.w3.org/2001/XMLSchema", + "http://rdfs.org/sioc/ns", + "http://www.w3.org/2004/02/skos/core" + ], + "title": { + "undefined": "Modular Unified Tagging Ontology (MUTO)" + }, + "iri": "http://purl.org/muto/core", + "version": "Version 1.0 - Global changes (compared to earlier versions): Some properties have been renamed; cardinality constraints in class descriptions (owl:Restriction) have been replaced by global cardinality constraints (owl:FunctionalProperty).", + "author": [ + "Steffen Lohmann" + ], + "description": { + "undefined": "The Modular and Unified Tagging Ontology (MUTO) is an ontology for tagging and folksonomies. It is based on a thorough review of earlier tagging ontologies and unifies core concepts in one consistent schema. It supports different forms of tagging, such as common, semantic, group, private, and automatic tagging, and is easily extensible." + }, + "labels": { + "en": "MUTO Core Ontology" + }, + "other": { + "licence": [ + { + "identifier": "licence", + "language": "undefined", + "value": "http://creativecommons.org/licenses/by/3.0/", + "type": "label" + } + ], + "creator": [ + { + "identifier": "creator", + "language": "undefined", + "value": "Steffen Lohmann", + "type": "label" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "Version 1.0 - Global changes (compared to earlier versions): Some properties have been renamed; cardinality constraints in class descriptions (owl:Restriction) have been replaced by global cardinality constraints (owl:FunctionalProperty).", + "type": "label" + } + ], + "title": [ + { + "identifier": "title", + "language": "undefined", + "value": "Modular Unified Tagging Ontology (MUTO)", + "type": "label" + } + ], + "issued": [ + { + "identifier": "issued", + "language": "undefined", + "value": "2011-11-16", + "type": "label" + } + ], + "seeAlso": [ + { + "identifier": "seeAlso", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "label" + } + ], + "homepage": [ + { + "identifier": "homepage", + "language": "undefined", + "value": "http://purl.org/muto", + "type": "label" + } + ], + "depiction": [ + { + "identifier": "depiction", + "language": "undefined", + "value": "http://purl.org/muto/core/muto-UML.png", + "type": "label" + }, + { + "identifier": "depiction", + "language": "undefined", + "value": "http://purl.org/muto/core/muto-compact.png", + "type": "label" + } + ] + } + }, + "namespace": [], + "metrics": { + "classCount": 7, + "objectPropertyCount": 16, + "datatypePropertyCount": 6, + "individualCount": 0 + }, + "class": [ + { + "id": "4", + "type": "owl:Class" + }, + { + "id": "5", + "type": "owl:Class" + }, + { + "id": "7", + "type": "rdfs:Datatype" + }, + { + "id": "15", + "type": "rdfs:Datatype" + }, + { + "id": "2", + "type": "owl:Thing" + }, + { + "id": "9", + "type": "owl:Thing" + }, + { + "id": "10", + "type": "rdfs:Literal" + }, + { + "id": "18", + "type": "owl:Thing" + }, + { + "id": "19", + "type": "rdfs:Literal" + }, + { + "id": "21", + "type": "owl:Class" + }, + { + "id": "24", + "type": "rdfs:Datatype" + }, + { + "id": "25", + "type": "rdfs:Literal" + }, + { + "id": "6", + "type": "owl:Class" + }, + { + "id": "32", + "type": "owl:Class" + }, + { + "id": "12", + "type": "owl:Class" + }, + { + "id": "1", + "type": "owl:Class" + } + ], + "classAttribute": [ + { + "iri": "http://purl.org/muto/core#Tag", + "baseIri": "http://purl.org/muto/core", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "Version 1.0: The owl:disjointWith statement was removed to make MUTO conform to OWL Lite (the statement is not essential in this case).", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "Tag", + "en": "Tag" + }, + "subClasses": [ + "6" + ], + "comment": { + "en": "A Tag consists of an arbitrary text label. Note that tags with the same label are NOT merged in the ontology." + }, + "id": "4", + "superClasses": [ + "5" + ] + }, + { + "iri": "http://www.w3.org/2004/02/skos/core#Concept", + "baseIri": "http://www.w3.org/2004/02/skos/core", + "instances": 0, + "label": { + "IRI-based": "Concept" + }, + "subClasses": [ + "4" + ], + "attributes": [ + "external" + ], + "id": "5" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#dateTime", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "7", + "label": { + "IRI-based": "dateTime" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#dateTime", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "15", + "label": { + "IRI-based": "dateTime" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "2", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "9", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "10", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "18", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "19", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://purl.org/muto/core#PrivateTagging", + "baseIri": "http://purl.org/muto/core", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "PrivateTagging", + "en": "Private Tagging" + }, + "comment": { + "en": "A private tagging is a tagging that is only visible to its creator (unless the creator has not granted access to others via muto:grantAccess). Every tagging that is not an instance of muto:PrivateTagging is public by default." + }, + "id": "21", + "superClasses": [ + "1" + ] + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#dateTime", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "24", + "label": { + "IRI-based": "dateTime" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "25", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://purl.org/muto/core#AutoTag", + "baseIri": "http://purl.org/muto/core", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "Version 1.0: muto:AutoTag was a subclass of muto:Tagging (called muto:autoTagging) in earlier versions. Defining it as a subclass of muto:Tag is more appropriate and allows for taggings that contain a combination of manually and automatically created tags.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "AutoTag", + "en": "Automatic Tag" + }, + "comment": { + "en": "An automatic tag is a tag that is automatically associated with a resource (e.g. by a tagging system), i.e. it is not entered by a human being." + }, + "id": "6", + "superClasses": [ + "4" + ] + }, + { + "iri": "http://rdfs.org/sioc/ns#Item", + "baseIri": "http://rdfs.org/sioc/ns", + "instances": 0, + "label": { + "IRI-based": "Item" + }, + "subClasses": [ + "1" + ], + "attributes": [ + "external" + ], + "id": "32" + }, + { + "iri": "http://rdfs.org/sioc/ns#UserAccount", + "baseIri": "http://rdfs.org/sioc/ns", + "instances": 0, + "label": { + "IRI-based": "UserAccount" + }, + "attributes": [ + "external" + ], + "id": "12" + }, + { + "iri": "http://purl.org/muto/core#Tagging", + "baseIri": "http://purl.org/muto/core", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Tagging", + "en": "Tagging" + }, + "subClasses": [ + "21" + ], + "comment": { + "en": "A tagging links a resource to a user account and one or more tags." + }, + "id": "1", + "superClasses": [ + "32" + ] + } + ], + "property": [ + { + "id": "0", + "type": "owl:objectProperty" + }, + { + "id": "8", + "type": "owl:datatypeProperty" + }, + { + "id": "11", + "type": "owl:objectProperty" + }, + { + "id": "16", + "type": "owl:objectProperty" + }, + { + "id": "20", + "type": "rdfs:SubClassOf" + }, + { + "id": "22", + "type": "owl:objectProperty" + }, + { + "id": "26", + "type": "owl:objectProperty" + }, + { + "id": "27", + "type": "owl:objectProperty" + }, + { + "id": "13", + "type": "owl:objectProperty" + }, + { + "id": "28", + "type": "owl:objectProperty" + }, + { + "id": "17", + "type": "owl:objectProperty" + }, + { + "id": "29", + "type": "owl:objectProperty" + }, + { + "id": "31", + "type": "owl:datatypeProperty" + }, + { + "id": "14", + "type": "owl:objectProperty" + }, + { + "id": "23", + "type": "owl:objectProperty" + }, + { + "id": "34", + "type": "owl:datatypeProperty" + }, + { + "id": "33", + "type": "owl:objectProperty" + }, + { + "id": "3", + "type": "owl:objectProperty" + }, + { + "id": "30", + "type": "owl:objectProperty" + }, + { + "id": "35", + "type": "owl:datatypeProperty" + }, + { + "id": "36", + "type": "owl:datatypeProperty" + }, + { + "id": "37", + "type": "rdfs:SubClassOf" + }, + { + "id": "38", + "type": "owl:objectProperty" + }, + { + "id": "39", + "type": "owl:datatypeProperty" + }, + { + "id": "40", + "type": "rdfs:SubClassOf" + }, + { + "id": "41", + "type": "rdfs:SubClassOf" + } + ], + "propertyAttribute": [ + { + "iri": "http://purl.org/muto/core#taggedResource", + "baseIri": "http://purl.org/muto/core", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "taggedResource", + "en": "tagged resource" + }, + "superproperty": [ + "3" + ], + "domain": "1", + "comment": { + "en": "Every tagging is linked to exactly one resource. This can be any kind of resource (i.e. all subclasses of rdfs:Resource), including tags and taggings." + }, + "attributes": [ + "functional", + "object" + ], + "id": "0" + }, + { + "iri": "http://purl.org/dc/terms/modified", + "baseIri": "http://purl.org/dc/terms", + "range": "10", + "label": { + "IRI-based": "modified" + }, + "domain": "9", + "attributes": [ + "datatype", + "external" + ], + "id": "8" + }, + { + "iri": "http://purl.org/muto/core#creatorOf", + "inverse": "13", + "baseIri": "http://purl.org/muto/core", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "creatorOf", + "en": "creator of" + }, + "superproperty": [ + "14" + ], + "domain": "12", + "comment": { + "en": "A user account can have a (theoretically unlimited) number of taggings. Use sioc:member_of to define groups for group tagging or link to foaf:Agent, foaf:Person, or foaf:Group via sioc:account_of." + }, + "attributes": [ + "object" + ], + "id": "11" + }, + { + "iri": "http://purl.org/muto/core#hasAccess", + "inverse": "17", + "baseIri": "http://purl.org/muto/core", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "Version 1.0: see muto:grantAccess", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "hasAccess", + "en": "has access" + }, + "domain": "2", + "comment": { + "en": "A user account or user group can have access to a private tagging from another user if the access is explicitly permitted by the creator of the tagging. This property can also be used in public tagging to link a user account or user group to a tagging (e.g. if the creator of a tagging has suggested the tagging to another user)." + }, + "attributes": [ + "object" + ], + "id": "16" + }, + { + "range": "4", + "domain": "6", + "attributes": [ + "anonymous", + "object" + ], + "id": "20" + }, + { + "iri": "http://purl.org/muto/core#meaningOf", + "inverse": "23", + "baseIri": "http://purl.org/muto/core", + "range": "4", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "meaningOf", + "en": "meaning of" + }, + "domain": "18", + "comment": { + "en": "The number of tags that can be linked to one and the same meaning is theoretically unlimited." + }, + "attributes": [ + "object" + ], + "id": "22" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_creator", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "9", + "label": { + "IRI-based": "has_creator" + }, + "domain": "9", + "subproperty": [ + "13" + ], + "attributes": [ + "external", + "object" + ], + "id": "26" + }, + { + "iri": "http://purl.org/muto/core#tagOf", + "inverse": "28", + "baseIri": "http://purl.org/muto/core", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "tagOf", + "en": "tag of" + }, + "domain": "4", + "comment": { + "en": "Every tag is linked to exactly one tagging. This results from the fact that tags with same labels are NOT merged in the ontology." + }, + "attributes": [ + "functional", + "object" + ], + "id": "27" + }, + { + "iri": "http://purl.org/muto/core#hasCreator", + "baseIri": "http://purl.org/muto/core", + "range": "12", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasCreator", + "en": "has creator" + }, + "superproperty": [ + "26" + ], + "domain": "1", + "comment": { + "en": "Every tagging is linked to at most one user account. This property can be omitted for automatic taggings. In contrast to its superproperty sioc:has_creator, it is functional and with an explicit domain. Use sioc:member_of to define groups for group tagging or link to foaf:Agent, foaf:Person, or foaf:Group via sioc:account_of." + }, + "attributes": [ + "functional", + "object" + ], + "id": "13" + }, + { + "iri": "http://purl.org/muto/core#hasTag", + "baseIri": "http://purl.org/muto/core", + "range": "4", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "hasTag", + "en": "has tag" + }, + "domain": "1", + "comment": { + "en": "A tagging consists of a (theoretically unlimited) number of tags. A tagging may also consist of no tags, e.g. if the system allows its users to mark a resource first and add tags later." + }, + "attributes": [ + "object" + ], + "id": "28" + }, + { + "iri": "http://purl.org/muto/core#grantAccess", + "baseIri": "http://purl.org/muto/core", + "range": "2", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "Version 1.0: The range information has been removed for greater flexibility and OWL Lite conformance (no longer owl:unionOf). Classes from different vocabularies can now be used here - such as sioc:UserAccount, sioc:Usergroup, foaf:OnlineAccount, foaf:Group, or dcterms:Agent -, though we recommend the use of sioc:UserAccount or sioc:Usergroup to remain in the SIOC namespace.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "grantAccess", + "en": "grant access" + }, + "domain": "1", + "comment": { + "en": "A (usually private) tagging can be linked to one or more user accounts or user groups that should have access to it (apart from the creator). This property can also be used in public tagging to link a user account or user group to a tagging (e.g. if the creator of a tagging wants to suggest the tagging to another user)." + }, + "attributes": [ + "object" + ], + "id": "17" + }, + { + "iri": "http://purl.org/muto/core#previousTag", + "inverse": "30", + "baseIri": "http://purl.org/muto/core", + "range": "4", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "Version 1.0: see muto:nextTag", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "previousTag", + "en": "previous tag" + }, + "domain": "4", + "comment": { + "en": "This property indicates the tag that is preceding in the list of tags. It can be used to describe the order in which the tags have been entered by the user." + }, + "attributes": [ + "functional", + "object" + ], + "id": "29" + }, + { + "iri": "http://purl.org/muto/core#tagLabel", + "baseIri": "http://purl.org/muto/core", + "range": "25", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "Version 1.0: The subproperty relation to rdfs:label has been removed for OWL DL conformance (rdfs:label is an annotation property and one cannot define subproperties for annotation properties in OWL DL).", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "tagLabel", + "en": "tag label" + }, + "domain": "4", + "comment": { + "en": "Every tag has exactly one label (usually the one given by the user) - otherwise it is not a tag. Additional labels can be defined in the resource that is linked via muto:tagMeaning." + }, + "attributes": [ + "functional", + "datatype" + ], + "id": "31" + }, + { + "iri": "http://rdfs.org/sioc/ns#creator_of", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "9", + "label": { + "IRI-based": "creator_of" + }, + "domain": "9", + "subproperty": [ + "11" + ], + "attributes": [ + "external", + "object" + ], + "id": "14" + }, + { + "iri": "http://purl.org/muto/core#tagMeaning", + "baseIri": "http://purl.org/muto/core", + "range": "18", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "tagMeaning", + "en": "tag meaning" + }, + "domain": "4", + "subproperty": [ + "33" + ], + "comment": { + "en": "The meaning of a tag can be expressed by a link to a well-defined resource. This can be any resource that clarifies the meaning of the tag (e.g. some DBpedia resource)." + }, + "attributes": [ + "object" + ], + "id": "23" + }, + { + "iri": "http://purl.org/muto/core#taggingModified", + "baseIri": "http://purl.org/muto/core", + "range": "15", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "taggingModified", + "en": "tagging modified" + }, + "domain": "1", + "comment": { + "en": "A tagging can have multiple modification dates, as the number of times a tagging can be edited (e.g. to add or remove tags) is theoretically unlimited. The datatype of this property is xsd:dateTime (in contrast to it superproperty dcterms:created which has range rdfs:Literal)." + }, + "attributes": [ + "datatype" + ], + "id": "34" + }, + { + "iri": "http://purl.org/muto/core#autoMeaning", + "baseIri": "http://purl.org/muto/core", + "range": "18", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "autoMeaning", + "en": "automatic tag meaning" + }, + "superproperty": [ + "23" + ], + "domain": "4", + "comment": { + "en": "This subproperty indicates that the meaning of a tag has been automatically defined (e.g. by a tagging system), i.e. it has not been defined by a human being. The default case is disambiguation by users via muto:tagMeaning." + }, + "attributes": [ + "object" + ], + "id": "33" + }, + { + "iri": "http://rdfs.org/sioc/ns#about", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "9", + "label": { + "IRI-based": "about" + }, + "domain": "9", + "subproperty": [ + "0" + ], + "attributes": [ + "external", + "object" + ], + "id": "3" + }, + { + "iri": "http://purl.org/muto/core#nextTag", + "baseIri": "http://purl.org/muto/core", + "range": "4", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "Version 1.0: Earlier versions of MUTO defined a datatype property muto:tagPosition with integer values which has some drawbacks compared to this solution.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "nextTag", + "en": "next tag" + }, + "domain": "4", + "comment": { + "en": "This property indicates the tag that follows next in the list of tags. It can be used to describe the order in which the tags have been entered by the user." + }, + "attributes": [ + "functional", + "object" + ], + "id": "30" + }, + { + "iri": "http://purl.org/muto/core#taggingCreated", + "baseIri": "http://purl.org/muto/core", + "range": "7", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "taggingCreated", + "en": "tagging created" + }, + "domain": "1", + "comment": { + "en": "Every tagging has exactly one creation date and time. The datatype of this property is xsd:dateTime (in contrast to its superproperty dcterms:created which has range rdfs:Literal)." + }, + "attributes": [ + "functional", + "datatype" + ], + "id": "35" + }, + { + "iri": "http://purl.org/dc/terms/created", + "baseIri": "http://purl.org/dc/terms", + "range": "19", + "label": { + "IRI-based": "created" + }, + "domain": "9", + "attributes": [ + "datatype", + "external" + ], + "id": "36" + }, + { + "range": "5", + "domain": "4", + "attributes": [ + "anonymous", + "object" + ], + "id": "37" + }, + { + "iri": "http://purl.org/muto/core#taggedWith", + "inverse": "0", + "baseIri": "http://purl.org/muto/core", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "taggedWith", + "en": "tagged with" + }, + "domain": "2", + "comment": { + "en": "A resource can have several taggings from different users. Tags are never directly linked to resources but can be inferred from the taggings." + }, + "attributes": [ + "object" + ], + "id": "38" + }, + { + "iri": "http://purl.org/muto/core#tagCreated", + "baseIri": "http://purl.org/muto/core", + "range": "24", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://purl.org/muto/core#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "tagCreated", + "en": "tag created" + }, + "domain": "4", + "comment": { + "en": "The creation date and time of a tag. This property can be omitted if muto:taggingCreated = muto:tagCreated (i.e. in the common case that a tag has been created along with a tagging, not in a later edit of the tagging). The datatype of this property is xsd:dateTime (in contrast to it superproperty dcterms:created which has range rdfs:Literal)." + }, + "attributes": [ + "functional", + "datatype" + ], + "id": "39" + }, + { + "range": "1", + "domain": "21", + "attributes": [ + "anonymous", + "object" + ], + "id": "40" + }, + { + "range": "32", + "domain": "1", + "attributes": [ + "anonymous", + "object" + ], + "id": "41" + } + ] +} \ No newline at end of file diff --git a/src/app/data/new_ontology.json b/src/app/data/new_ontology.json new file mode 100644 index 0000000000000000000000000000000000000000..f1cb0dfb86326c953866d5314f5b5d33e4e46bee --- /dev/null +++ b/src/app/data/new_ontology.json @@ -0,0 +1,28 @@ +{ + "_comment": "Empty ontology for WebVOWL Editor", + "header": { + "languages": [ + "en" + ], + "baseIris": [ + "http://www.w3.org/2000/01/rdf-schema" + ], + "iri": "http://visualdataweb.org/newOntology/", + "title": { + "en": "New ontology" + }, + "description": { + "en": "New ontology description" + } + }, + "namespace": [], + "metrics": { + "classCount": 0, + "datatypeCount": 0, + "objectPropertyCount": 0, + "datatypePropertyCount": 0, + "propertyCount": 0, + "nodeCount": 0, + "individualCount": 0 + } +} diff --git a/src/app/data/ontovibe.json b/src/app/data/ontovibe.json new file mode 100644 index 0000000000000000000000000000000000000000..1474c4de19e485913544e0dc08d4dfc695bf79fd --- /dev/null +++ b/src/app/data/ontovibe.json @@ -0,0 +1,2013 @@ +{ + "_comment": "Created with OWL2VOWL (version 0.3.4), http://vowl.visualdataweb.org", + "header": { + "languages": [ + "de", + "zh-hans", + "en", + "fr", + "es", + "undefined" + ], + "baseIris": [ + "http://www.w3.org/1999/02/22-rdf-syntax-ns", + "http://ontovibe.visualdataweb.org", + "http://www.w3.org/2002/07/owl", + "http://www.w3.org/2000/01/rdf-schema", + "http://ontovibe.visualdataweb.org/imported", + "http://www.w3.org/2001/XMLSchema" + ], + "title": { + "undefined": "Ontology Visualization Benchmark (OntoViBe)" + }, + "iri": "http://ontovibe.visualdataweb.org", + "version": "2.2", + "author": [ + "Florian Haag", + "Steffen Lohmann" + ], + "description": { + "undefined": "OntoViBe is a benchmark for testing ontology visualizations. It incorporates a comprehensive set of OWL 2 language constructs and systematic combinations thereof." + }, + "labels": { + "undefined": "Ontology Visualization Benchmark (OntoViBe)" + }, + "comments": { + "undefined": "OntoViBe is a benchmark for testing ontology visualizations. It incorporates a comprehensive set of OWL 2 language constructs and systematic combinations thereof." + }, + "other": { + "date": [ + { + "identifier": "date", + "language": "undefined", + "value": "2015-08-27", + "type": "label" + } + ], + "priorVersion": [ + { + "identifier": "priorVersion", + "language": "undefined", + "value": "http://ontovibe.visualdataweb.org/2.1", + "type": "iri" + } + ], + "creator": [ + { + "identifier": "creator", + "language": "undefined", + "value": "Steffen Lohmann", + "type": "label" + }, + { + "identifier": "creator", + "language": "undefined", + "value": "Florian Haag", + "type": "label" + } + ], + "contributor": [ + { + "identifier": "contributor", + "language": "undefined", + "value": "Stefan Negru", + "type": "label" + } + ], + "incompatibleWith": [ + { + "identifier": "incompatibleWith", + "language": "undefined", + "value": "http://ontovibe.visualdataweb.org/minimal", + "type": "iri" + } + ], + "rights": [ + { + "identifier": "rights", + "language": "undefined", + "value": "http://creativecommons.org/licenses/by/4.0/", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "2.2", + "type": "label" + } + ], + "title": [ + { + "identifier": "title", + "language": "undefined", + "value": "Ontology Visualization Benchmark (OntoViBe)", + "type": "label" + } + ], + "backwardCompatibleWith": [ + { + "identifier": "backwardCompatibleWith", + "language": "undefined", + "value": "http://ontovibe.visualdataweb.org/2.1", + "type": "iri" + } + ] + } + }, + "namespace": [], + "metrics": { + "classCount": 35, + "objectPropertyCount": 22, + "datatypePropertyCount": 13, + "individualCount": 8 + }, + "class": [ + { + "id": "8", + "type": "owl:complementOf" + }, + { + "id": "14", + "type": "owl:Class" + }, + { + "id": "19", + "type": "rdfs:Literal" + }, + { + "id": "20", + "type": "owl:Thing" + }, + { + "id": "21", + "type": "owl:Thing" + }, + { + "id": "22", + "type": "rdfs:Literal" + }, + { + "id": "23", + "type": "owl:unionOf" + }, + { + "id": "13", + "type": "rdfs:Literal" + }, + { + "id": "27", + "type": "owl:equivalentClass" + }, + { + "id": "28", + "type": "rdfs:Datatype" + }, + { + "id": "7", + "type": "owl:Thing" + }, + { + "id": "31", + "type": "owl:Class" + }, + { + "id": "32", + "type": "owl:Class" + }, + { + "id": "34", + "type": "owl:equivalentClass" + }, + { + "id": "35", + "type": "owl:disjointUnionOf" + }, + { + "id": "37", + "type": "owl:Class" + }, + { + "id": "39", + "type": "rdfs:Datatype" + }, + { + "id": "40", + "type": "rdfs:Datatype" + }, + { + "id": "24", + "type": "owl:unionOf" + }, + { + "id": "42", + "type": "rdfs:Datatype" + }, + { + "id": "44", + "type": "rdfs:Datatype" + }, + { + "id": "18", + "type": "rdfs:Datatype" + }, + { + "id": "47", + "type": "owl:Class" + }, + { + "id": "48", + "type": "rdfs:Datatype" + }, + { + "id": "49", + "type": "rdfs:Datatype" + }, + { + "id": "4", + "type": "owl:Class" + }, + { + "id": "50", + "type": "rdfs:Datatype" + }, + { + "id": "46", + "type": "rdfs:Datatype" + }, + { + "id": "52", + "type": "rdfs:Datatype" + }, + { + "id": "54", + "type": "owl:Class" + }, + { + "id": "57", + "type": "owl:equivalentClass" + }, + { + "id": "26", + "type": "owl:Class" + }, + { + "id": "58", + "type": "owl:equivalentClass" + }, + { + "id": "1", + "type": "owl:equivalentClass" + }, + { + "id": "60", + "type": "owl:Class" + }, + { + "id": "30", + "type": "owl:Class" + }, + { + "id": "6", + "type": "owl:Class" + }, + { + "id": "63", + "type": "owl:intersectionOf" + }, + { + "id": "71", + "type": "owl:Class" + }, + { + "id": "73", + "type": "owl:equivalentClass" + }, + { + "id": "70", + "type": "owl:Class" + }, + { + "id": "16", + "type": "owl:Class" + }, + { + "id": "84", + "type": "owl:intersectionOf" + }, + { + "id": "87", + "type": "owl:equivalentClass" + }, + { + "id": "41", + "type": "owl:Class" + }, + { + "id": "91", + "type": "owl:Class" + }, + { + "id": "68", + "type": "owl:complementOf" + }, + { + "id": "79", + "type": "owl:Class" + }, + { + "id": "90", + "type": "owl:unionOf" + }, + { + "id": "77", + "type": "rdfs:Datatype" + }, + { + "id": "88", + "type": "owl:equivalentClass" + }, + { + "id": "3", + "type": "owl:equivalentClass" + }, + { + "id": "59", + "type": "owl:equivalentClass" + }, + { + "id": "9", + "type": "owl:Class" + }, + { + "id": "105", + "type": "owl:disjointUnionOf" + } + ], + "classAttribute": [ + { + "iri": "http://ontovibe.visualdataweb.org#ComplementClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "ComplementClass" + }, + "attributes": [ + "complement" + ], + "id": "8", + "complement": [ + "9" + ] + }, + { + "iri": "http://ontovibe.visualdataweb.org#HasSelfClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "HasSelfClass" + }, + "id": "14" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "19", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "20", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "21", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "22", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#LargeUnionClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "LargeUnionClass" + }, + "union": [ + "6", + "24", + "1" + ], + "attributes": [ + "union" + ], + "id": "23" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "13", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#EquivalentToPropertyOwner", + "equivalent": [ + "1" + ], + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "EquivalentToPropertyOwner" + }, + "attributes": [ + "equivalent" + ], + "id": "27" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#integer", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "28", + "label": { + "IRI-based": "integer" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "7", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#FunctionalAnchor", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "FunctionalAnchor" + }, + "id": "31" + }, + { + "iri": "http://ontovibe.visualdataweb.org#HasValueClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "HasValueClass" + }, + "id": "32" + }, + { + "iri": "http://ontovibe.visualdataweb.org#EquivalentDeprecatedClassInLargeGroup", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "EquivalentDeprecatedClassInLargeGroup" + }, + "attributes": [ + "equivalent", + "deprecated" + ], + "id": "34" + }, + { + "iri": "http://ontovibe.visualdataweb.org#DisjointUnionClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "disjointUnion": [ + "24", + "9" + ], + "label": { + "IRI-based": "DisjointUnionClass" + }, + "attributes": [ + "disjointUnion" + ], + "id": "35" + }, + { + "iri": "http://ontovibe.visualdataweb.org#AnonymousClassAnchor", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "AnonymousClassAnchor" + }, + "id": "37" + }, + { + "iri": "http://ontovibe.visualdataweb.org#UnionDatatype", + "baseIri": "http://ontovibe.visualdataweb.org", + "id": "39", + "label": { + "IRI-based": "UnionDatatype" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#integer", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "40", + "label": { + "IRI-based": "integer" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#UnionClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "UnionClass" + }, + "union": [ + "9", + "41" + ], + "comment": { + "en": "This is an English comment on a class expression." + }, + "attributes": [ + "union" + ], + "id": "24" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#date", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "42", + "label": { + "IRI-based": "date" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#IntersectionDatatype", + "baseIri": "http://ontovibe.visualdataweb.org", + "id": "44", + "label": { + "IRI-based": "IntersectionDatatype" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org/imported#DivisibleByThreeEnumeration", + "baseIri": "http://ontovibe.visualdataweb.org/imported", + "id": "18", + "label": { + "IRI-based": "DivisibleByThreeEnumeration" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#PlainClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "PlainClass" + }, + "id": "47" + }, + { + "iri": "http://www.w3.org/2002/07/owl#real", + "baseIri": "http://www.w3.org/2002/07/owl", + "id": "48", + "label": { + "IRI-based": "real" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#rational", + "baseIri": "http://www.w3.org/2002/07/owl", + "id": "49", + "label": { + "IRI-based": "rational" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#DisjointClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "de": "disjunkte Klasse", + "IRI-based": "DisjointClass", + "en": "disjoint class" + }, + "subClasses": [ + "16", + "3" + ], + "id": "4" + }, + { + "iri": "http://ontovibe.visualdataweb.org#DivisibleByFiveEnumeration", + "baseIri": "http://ontovibe.visualdataweb.org", + "id": "50", + "label": { + "IRI-based": "DivisibleByFiveEnumeration" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#hexBinary", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "46", + "label": { + "IRI-based": "hexBinary" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#date", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "52", + "label": { + "IRI-based": "date" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#EnumerationClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "EnumerationClass" + }, + "individuals": [ + { + "iri": "http://ontovibe.visualdataweb.org#MultiSubclassIndividual3", + "baseIri": "http://ontovibe.visualdataweb.org", + "description": { + "undefined": "This is a description without a language on an individual." + }, + "labels": { + "IRI-based": "MultiSubclassIndividual3" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#MultiSubclassIndividual2", + "baseIri": "http://ontovibe.visualdataweb.org", + "labels": { + "IRI-based": "MultiSubclassIndividual2" + } + } + ], + "id": "54" + }, + { + "iri": "http://ontovibe.visualdataweb.org#EquivalentToSubclass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "EquivalentToSubclass" + }, + "attributes": [ + "equivalent" + ], + "id": "57" + }, + { + "iri": "http://ontovibe.visualdataweb.org#PropertyOwnerType", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 2, + "label": { + "IRI-based": "PropertyOwnerType" + }, + "id": "26" + }, + { + "iri": "http://ontovibe.visualdataweb.org#EquivalentToDeprecatedClass", + "equivalent": [ + "59" + ], + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "EquivalentToDeprecatedClass" + }, + "attributes": [ + "equivalent" + ], + "id": "58" + }, + { + "iri": "http://ontovibe.visualdataweb.org#PropertyOwner", + "equivalent": [ + "27" + ], + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "PropertyOwner" + }, + "attributes": [ + "equivalent" + ], + "id": "1" + }, + { + "iri": "http://ontovibe.visualdataweb.org#SomeValuesFromClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "SomeValuesFromClass" + }, + "id": "60" + }, + { + "iri": "http://ontovibe.visualdataweb.org#MultiPropertyOwner", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "MultiPropertyOwner", + "undefined": "multi-property owner" + }, + "comment": { + "undefined": "This is a comment without a language-tag on a class that also has a label." + }, + "id": "30" + }, + { + "iri": "http://ontovibe.visualdataweb.org/imported#ImportedClass", + "baseIri": "http://ontovibe.visualdataweb.org/imported", + "instances": 0, + "label": { + "IRI-based": "ImportedClass" + }, + "attributes": [ + "external" + ], + "id": "6" + }, + { + "iri": "http://ontovibe.visualdataweb.org#IntersectionClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "IntersectionClass" + }, + "intersection": [ + "9", + "41" + ], + "attributes": [ + "intersection" + ], + "id": "63" + }, + { + "iri": "http://ontovibe.visualdataweb.org#LargeEnumerationClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "LargeEnumerationClass" + }, + "individuals": [ + { + "iri": "http://ontovibe.visualdataweb.org#MultiSubclassIndividual3", + "baseIri": "http://ontovibe.visualdataweb.org", + "description": { + "undefined": "This is a description without a language on an individual." + }, + "labels": { + "IRI-based": "MultiSubclassIndividual3" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#AnotherIndividual", + "baseIri": "http://ontovibe.visualdataweb.org", + "description": { + "en": "This is an English description on an individual that also has a comment." + }, + "comment": { + "en": "This is an English comment on an individual that also has a description." + }, + "labels": { + "IRI-based": "AnotherIndividual" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#MultiSubclassIndividual2", + "baseIri": "http://ontovibe.visualdataweb.org", + "labels": { + "IRI-based": "MultiSubclassIndividual2" + } + } + ], + "id": "71" + }, + { + "iri": "http://ontovibe.visualdataweb.org#AlsoEquivalentToSubclass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "AlsoEquivalentToSubclass" + }, + "attributes": [ + "equivalent" + ], + "id": "73" + }, + { + "iri": "http://ontovibe.visualdataweb.org/imported#DeprecatedImportedClass", + "baseIri": "http://ontovibe.visualdataweb.org/imported", + "instances": 0, + "label": { + "IRI-based": "DeprecatedImportedClass" + }, + "subClasses": [ + "16" + ], + "attributes": [ + "external", + "deprecated" + ], + "id": "70" + }, + { + "iri": "http://ontovibe.visualdataweb.org#MultiSubclass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "description": { + "en": "This is an English description on a class that also has a comment." + }, + "label": { + "IRI-based": "MultiSubclass" + }, + "individuals": [ + { + "iri": "http://ontovibe.visualdataweb.org#MultiSubclassIndividual3", + "baseIri": "http://ontovibe.visualdataweb.org", + "description": { + "undefined": "This is a description without a language on an individual." + }, + "labels": { + "IRI-based": "MultiSubclassIndividual3" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#SameAsMultiSubclassIndividual2", + "baseIri": "http://ontovibe.visualdataweb.org", + "labels": { + "IRI-based": "SameAsMultiSubclassIndividual2" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#MultiSubclassIndividual2", + "baseIri": "http://ontovibe.visualdataweb.org", + "labels": { + "IRI-based": "MultiSubclassIndividual2" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#MultiSubclassIndividual1", + "baseIri": "http://ontovibe.visualdataweb.org", + "comment": { + "en": "This ia an English comment on an individual." + }, + "labels": { + "IRI-based": "MultiSubclassIndividual1" + } + } + ], + "comment": { + "en": "This is an English comment on a class that also has a description." + }, + "id": "16", + "superClasses": [ + "70", + "4" + ] + }, + { + "iri": "http://ontovibe.visualdataweb.org#LargeIntersectionClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "LargeIntersectionClass" + }, + "intersection": [ + "6", + "24", + "1" + ], + "attributes": [ + "intersection" + ], + "id": "84" + }, + { + "iri": "http://ontovibe.visualdataweb.org#EquivalentClassInLargeGroup", + "equivalent": [ + "88", + "34" + ], + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "EquivalentClassInLargeGroup" + }, + "attributes": [ + "equivalent" + ], + "id": "87" + }, + { + "iri": "http://ontovibe.visualdataweb.org#DeprecatedClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "DeprecatedClass" + }, + "individuals": [ + { + "iri": "http://ontovibe.visualdataweb.org#AnotherIndividual", + "baseIri": "http://ontovibe.visualdataweb.org", + "description": { + "en": "This is an English description on an individual that also has a comment." + }, + "comment": { + "en": "This is an English comment on an individual that also has a description." + }, + "labels": { + "IRI-based": "AnotherIndividual" + } + } + ], + "attributes": [ + "deprecated" + ], + "id": "41" + }, + { + "iri": "http://ontovibe.visualdataweb.org#AllValuesFromClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "AllValuesFromClass" + }, + "id": "91" + }, + { + "instances": 0, + "attributes": [ + "complement", + "anonymous" + ], + "id": "68", + "complement": [ + "41" + ] + }, + { + "instances": 0, + "individuals": [ + { + "iri": "http://ontovibe.visualdataweb.org#MultiSubclassIndividual3", + "baseIri": "http://ontovibe.visualdataweb.org", + "description": { + "undefined": "This is a description without a language on an individual." + }, + "labels": { + "IRI-based": "MultiSubclassIndividual3" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#AnotherIndividual", + "baseIri": "http://ontovibe.visualdataweb.org", + "description": { + "en": "This is an English description on an individual that also has a comment." + }, + "comment": { + "en": "This is an English comment on an individual that also has a description." + }, + "labels": { + "IRI-based": "AnotherIndividual" + } + } + ], + "attributes": [ + "anonymous" + ], + "id": "79" + }, + { + "instances": 0, + "union": [ + "9", + "41" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "90" + }, + { + "iri": "http://ontovibe.visualdataweb.org#ComplementDatatype", + "baseIri": "http://ontovibe.visualdataweb.org", + "id": "77", + "label": { + "IRI-based": "ComplementDatatype" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org/imported#EquivalentImportedClassInLargeGroup", + "baseIri": "http://ontovibe.visualdataweb.org/imported", + "instances": 0, + "label": { + "IRI-based": "EquivalentImportedClassInLargeGroup" + }, + "attributes": [ + "equivalent", + "external" + ], + "id": "88" + }, + { + "iri": "http://ontovibe.visualdataweb.org#Subclass", + "equivalent": [ + "73", + "57" + ], + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "Subclass" + }, + "attributes": [ + "equivalent" + ], + "id": "3", + "superClasses": [ + "4" + ] + }, + { + "iri": "http://ontovibe.visualdataweb.org#EquivalentDeprecatedClass", + "equivalent": [ + "58" + ], + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "description": { + "en": "This is an English description in a class that is part of an equivalent class group." + }, + "label": { + "IRI-based": "EquivalentDeprecatedClass" + }, + "attributes": [ + "equivalent", + "deprecated" + ], + "id": "59" + }, + { + "iri": "http://ontovibe.visualdataweb.org#Class1", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "label": { + "IRI-based": "Class1" + }, + "individuals": [ + { + "iri": "http://ontovibe.visualdataweb.org#Class1Individual", + "baseIri": "http://ontovibe.visualdataweb.org", + "labels": { + "IRI-based": "Class1Individual" + } + } + ], + "id": "9" + }, + { + "iri": "http://ontovibe.visualdataweb.org#LargeDisjointUnionClass", + "baseIri": "http://ontovibe.visualdataweb.org", + "instances": 0, + "disjointUnion": [ + "70", + "63", + "8" + ], + "label": { + "IRI-based": "LargeDisjointUnionClass" + }, + "attributes": [ + "disjointUnion" + ], + "id": "105" + } + ], + "property": [ + { + "id": "0", + "type": "owl:objectProperty" + }, + { + "id": "2", + "type": "rdfs:SubClassOf" + }, + { + "id": "5", + "type": "owl:objectProperty" + }, + { + "id": "10", + "type": "owl:objectProperty" + }, + { + "id": "12", + "type": "owl:datatypeProperty" + }, + { + "id": "15", + "type": "rdfs:SubClassOf" + }, + { + "id": "17", + "type": "owl:datatypeProperty" + }, + { + "id": "25", + "type": "rdf:Property" + }, + { + "id": "29", + "type": "rdf:Property" + }, + { + "id": "33", + "type": "owl:objectProperty" + }, + { + "id": "36", + "type": "owl:objectProperty" + }, + { + "id": "38", + "type": "owl:objectProperty" + }, + { + "id": "43", + "type": "owl:objectProperty" + }, + { + "id": "45", + "type": "owl:datatypeProperty" + }, + { + "id": "51", + "type": "owl:datatypeProperty" + }, + { + "id": "53", + "type": "owl:objectProperty" + }, + { + "id": "55", + "type": "owl:objectProperty" + }, + { + "id": "56", + "type": "owl:objectProperty" + }, + { + "id": "61", + "type": "owl:objectProperty" + }, + { + "id": "64", + "type": "owl:objectProperty" + }, + { + "id": "65", + "type": "owl:objectProperty" + }, + { + "id": "66", + "type": "owl:datatypeProperty" + }, + { + "id": "11", + "type": "owl:objectProperty" + }, + { + "id": "67", + "type": "owl:objectProperty" + }, + { + "id": "69", + "type": "rdfs:SubClassOf" + }, + { + "id": "72", + "type": "owl:datatypeProperty" + }, + { + "id": "74", + "type": "owl:objectProperty" + }, + { + "id": "75", + "type": "owl:objectProperty" + }, + { + "id": "76", + "type": "owl:datatypeProperty" + }, + { + "id": "78", + "type": "owl:objectProperty" + }, + { + "id": "80", + "type": "owl:objectProperty" + }, + { + "id": "81", + "type": "owl:datatypeProperty" + }, + { + "id": "82", + "type": "owl:datatypeProperty" + }, + { + "id": "83", + "type": "owl:datatypeProperty" + }, + { + "id": "85", + "type": "owl:datatypeProperty" + }, + { + "id": "86", + "type": "owl:datatypeProperty" + }, + { + "id": "89", + "type": "owl:objectProperty" + }, + { + "id": "92", + "type": "owl:disjointWith" + }, + { + "id": "93", + "type": "owl:disjointWith" + }, + { + "id": "94", + "type": "owl:objectProperty" + }, + { + "id": "96", + "type": "owl:disjointWith" + }, + { + "id": "97", + "type": "owl:someValuesFrom" + }, + { + "id": "98", + "type": "owl:objectProperty" + }, + { + "id": "95", + "type": "owl:objectProperty" + }, + { + "id": "99", + "type": "owl:allValuesFrom" + }, + { + "id": "100", + "type": "owl:disjointWith" + }, + { + "id": "62", + "type": "owl:objectProperty" + }, + { + "id": "101", + "type": "owl:datatypeProperty" + }, + { + "id": "102", + "type": "owl:datatypeProperty" + }, + { + "id": "103", + "type": "owl:datatypeProperty" + }, + { + "id": "104", + "type": "owl:objectProperty" + } + ], + "propertyAttribute": [ + { + "iri": "http://ontovibe.visualdataweb.org#cyclicProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "1", + "label": { + "IRI-based": "cyclicProperty" + }, + "domain": "1", + "attributes": [ + "object" + ], + "id": "0" + }, + { + "range": "4", + "domain": "3", + "attributes": [ + "object", + "anonymous" + ], + "id": "2" + }, + { + "iri": "http://ontovibe.visualdataweb.org/imported#importedObjectPropertyWithDomain", + "baseIri": "http://ontovibe.visualdataweb.org/imported", + "range": "7", + "label": { + "IRI-based": "importedObjectPropertyWithDomain" + }, + "domain": "6", + "attributes": [ + "transitive", + "object", + "external" + ], + "id": "5" + }, + { + "iri": "http://ontovibe.visualdataweb.org#dummyProperty", + "equivalent": [ + "11" + ], + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "4", + "label": { + "IRI-based": "dummyProperty" + }, + "domain": "1", + "attributes": [ + "object" + ], + "id": "10" + }, + { + "iri": "http://ontovibe.visualdataweb.org#untypedDatatypeProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "13", + "label": { + "IRI-based": "untypedDatatypeProperty" + }, + "domain": "1", + "attributes": [ + "datatype" + ], + "id": "12" + }, + { + "range": "4", + "domain": "16", + "attributes": [ + "object", + "anonymous" + ], + "id": "15" + }, + { + "iri": "http://ontovibe.visualdataweb.org#importedTypeDatatypeProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "18", + "label": { + "IRI-based": "importedTypeDatatypeProperty", + "zh-hans": "一种导入类型的数据类型性质", + "en": "imported type datatype property", + "fr": "propriété d'un type de données importé" + }, + "domain": "1", + "attributes": [ + "datatype" + ], + "id": "17" + }, + { + "domain": "26", + "range": "1", + "id": "25", + "label": { + "IRI-based": "21", + "undefined": "is a" + } + }, + { + "domain": "26", + "range": "30", + "id": "29", + "label": { + "IRI-based": "22", + "undefined": "is a" + } + }, + { + "iri": "http://ontovibe.visualdataweb.org#cyclicProperty3", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "30", + "label": { + "IRI-based": "cyclicProperty3" + }, + "domain": "30", + "attributes": [ + "object" + ], + "id": "33" + }, + { + "iri": "http://ontovibe.visualdataweb.org#cyclicProperty2", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "30", + "description": { + "de": "Dies ist eine deutsche Beschreibung einer Eigenschaft, die auch einen nicht in Deutsch verfassten Kommentar enthält." + }, + "label": { + "IRI-based": "cyclicProperty2" + }, + "domain": "30", + "comment": { + "en": "This is an English comment on a property that also has a non-English description." + }, + "attributes": [ + "object", + "reflexive" + ], + "id": "36" + }, + { + "iri": "http://ontovibe.visualdataweb.org#cyclicProperty1", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "30", + "label": { + "IRI-based": "cyclicProperty1" + }, + "domain": "30", + "attributes": [ + "object" + ], + "id": "38" + }, + { + "iri": "http://ontovibe.visualdataweb.org#oppositeDummyProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "1", + "label": { + "IRI-based": "oppositeDummyProperty" + }, + "maxCardinality": "15", + "minCardinality": "5", + "domain": "4", + "attributes": [ + "object" + ], + "id": "43" + }, + { + "iri": "http://ontovibe.visualdataweb.org#functionalDatatypeProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "46", + "label": { + "IRI-based": "functionalDatatypeProperty" + }, + "domain": "31", + "attributes": [ + "functional", + "datatype" + ], + "id": "45" + }, + { + "iri": "http://ontovibe.visualdataweb.org#anotherEquivalentDataProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "19", + "label": { + "IRI-based": "anotherEquivalentDataProperty" + }, + "domain": "20", + "attributes": [ + "datatype" + ], + "id": "51" + }, + { + "iri": "http://ontovibe.visualdataweb.org#disjointProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "31", + "label": { + "IRI-based": "disjointProperty" + }, + "domain": "1", + "attributes": [ + "object" + ], + "id": "53" + }, + { + "iri": "http://ontovibe.visualdataweb.org#classToClassProperty2", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "30", + "label": { + "IRI-based": "classToClassProperty2" + }, + "domain": "1", + "attributes": [ + "irreflexive", + "object" + ], + "id": "55" + }, + { + "iri": "http://ontovibe.visualdataweb.org#classToClassProperty1", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "30", + "label": { + "IRI-based": "classToClassProperty1" + }, + "domain": "1", + "attributes": [ + "object" + ], + "id": "56" + }, + { + "iri": "http://ontovibe.visualdataweb.org#functionalPropertyAsInverse", + "inverse": "62", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "31", + "label": { + "IRI-based": "functionalPropertyAsInverse" + }, + "domain": "1", + "attributes": [ + "functional", + "object" + ], + "id": "61" + }, + { + "iri": "http://ontovibe.visualdataweb.org#anonymousIntersectionClassProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "63", + "label": { + "IRI-based": "anonymousIntersectionClassProperty" + }, + "domain": "37", + "attributes": [ + "object" + ], + "id": "64" + }, + { + "iri": "http://ontovibe.visualdataweb.org/imported#deprecatedImportedObjectProperty", + "baseIri": "http://ontovibe.visualdataweb.org/imported", + "range": "6", + "label": { + "IRI-based": "deprecatedImportedObjectProperty" + }, + "domain": "7", + "attributes": [ + "object", + "external", + "deprecated" + ], + "id": "65" + }, + { + "iri": "http://ontovibe.visualdataweb.org#standardTypeDatatypeProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "40", + "label": { + "IRI-based": "standardTypeDatatypeProperty" + }, + "domain": "1", + "attributes": [ + "datatype" + ], + "id": "66" + }, + { + "iri": "http://ontovibe.visualdataweb.org#equivalentObjectProperty", + "equivalent": [ + "10" + ], + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "20", + "label": { + "IRI-based": "equivalentObjectProperty" + }, + "domain": "20", + "attributes": [ + "object" + ], + "id": "11" + }, + { + "iri": "http://ontovibe.visualdataweb.org#anonymousComplementClassProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "68", + "label": { + "IRI-based": "anonymousComplementClassProperty" + }, + "domain": "37", + "attributes": [ + "object" + ], + "id": "67" + }, + { + "range": "70", + "domain": "16", + "attributes": [ + "object", + "anonymous" + ], + "id": "69" + }, + { + "iri": "http://ontovibe.visualdataweb.org/imported#importedDatatypeProperty", + "baseIri": "http://ontovibe.visualdataweb.org/imported", + "range": "28", + "label": { + "IRI-based": "importedDatatypeProperty" + }, + "domain": "6", + "attributes": [ + "datatype", + "external" + ], + "id": "72" + }, + { + "iri": "http://ontovibe.visualdataweb.org#classToClassProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "9", + "description": { + "en": "This is an English description of a property with descriptions in several languages.", + "es": "Esto es una descripción en español de una propiedad con descripciones en varias lenguas." + }, + "label": { + "IRI-based": "classToClassProperty" + }, + "cardinality": "3", + "domain": "1", + "attributes": [ + "object" + ], + "id": "74" + }, + { + "iri": "http://ontovibe.visualdataweb.org#untypedClassToClassProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "1", + "label": { + "IRI-based": "untypedClassToClassProperty" + }, + "domain": "21", + "attributes": [ + "asymmetric", + "object" + ], + "id": "75" + }, + { + "iri": "http://ontovibe.visualdataweb.org#complementTypeDatatypeProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "77", + "label": { + "IRI-based": "complementTypeDatatypeProperty", + "undefined": "complement-type datatype property" + }, + "domain": "1", + "attributes": [ + "datatype" + ], + "id": "76" + }, + { + "iri": "http://ontovibe.visualdataweb.org#anonymousEnumerationClassProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "79", + "label": { + "IRI-based": "anonymousEnumerationClassProperty" + }, + "domain": "37", + "attributes": [ + "object" + ], + "id": "78" + }, + { + "iri": "http://ontovibe.visualdataweb.org/imported#importedObjectPropertyWithRange", + "baseIri": "http://ontovibe.visualdataweb.org/imported", + "range": "6", + "label": { + "IRI-based": "importedObjectPropertyWithRange" + }, + "domain": "7", + "attributes": [ + "object", + "external" + ], + "id": "80" + }, + { + "iri": "http://ontovibe.visualdataweb.org#intersectionTypeDatatypeProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "44", + "label": { + "IRI-based": "intersectionTypeDatatypeProperty" + }, + "domain": "1", + "attributes": [ + "datatype" + ], + "id": "81" + }, + { + "iri": "http://ontovibe.visualdataweb.org#rationalProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "49", + "label": { + "IRI-based": "rationalProperty" + }, + "domain": "1", + "attributes": [ + "datatype" + ], + "id": "82" + }, + { + "iri": "http://ontovibe.visualdataweb.org#deprecatedDatatypeProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "52", + "label": { + "IRI-based": "deprecatedDatatypeProperty" + }, + "domain": "1", + "attributes": [ + "datatype", + "deprecated" + ], + "id": "83" + }, + { + "iri": "http://ontovibe.visualdataweb.org#customTypeDatatypeProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "50", + "label": { + "IRI-based": "customTypeDatatypeProperty" + }, + "cardinality": "2", + "domain": "1", + "attributes": [ + "datatype" + ], + "id": "85" + }, + { + "iri": "http://ontovibe.visualdataweb.org/imported#deprecatedImportedDatatypeProperty", + "baseIri": "http://ontovibe.visualdataweb.org/imported", + "range": "42", + "label": { + "IRI-based": "deprecatedImportedDatatypeProperty" + }, + "domain": "20", + "attributes": [ + "datatype", + "external", + "deprecated" + ], + "id": "86" + }, + { + "iri": "http://ontovibe.visualdataweb.org#anonymousUnionClassProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "90", + "label": { + "IRI-based": "anonymousUnionClassProperty" + }, + "domain": "37", + "attributes": [ + "object" + ], + "id": "89" + }, + { + "range": "30", + "domain": "9", + "attributes": [ + "object", + "anonymous" + ], + "id": "92" + }, + { + "range": "30", + "domain": "23", + "attributes": [ + "object", + "anonymous" + ], + "id": "93" + }, + { + "iri": "http://ontovibe.visualdataweb.org#deprecatedObjectProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "21", + "label": { + "IRI-based": "deprecatedObjectProperty" + }, + "domain": "1", + "subproperty": [ + "95" + ], + "attributes": [ + "object", + "deprecated" + ], + "id": "94" + }, + { + "range": "23", + "domain": "4", + "attributes": [ + "object", + "anonymous" + ], + "id": "96" + }, + { + "iri": "http://ontovibe.visualdataweb.org#classToClassProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "41", + "description": { + "en": "This is an English description of a property with descriptions in several languages.", + "es": "Esto es una descripción en español de una propiedad con descripciones en varias lenguas." + }, + "label": { + "IRI-based": "classToClassProperty" + }, + "domain": "60", + "attributes": [ + "someValues", + "object" + ], + "id": "97" + }, + { + "iri": "http://ontovibe.visualdataweb.org#functionalProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "31", + "label": { + "IRI-based": "functionalProperty" + }, + "domain": "1", + "attributes": [ + "functional", + "object" + ], + "id": "98" + }, + { + "iri": "http://ontovibe.visualdataweb.org#subproperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "20", + "label": { + "IRI-based": "subproperty" + }, + "superproperty": [ + "94" + ], + "domain": "20", + "attributes": [ + "object" + ], + "id": "95" + }, + { + "iri": "http://ontovibe.visualdataweb.org#classToClassProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "41", + "description": { + "en": "This is an English description of a property with descriptions in several languages.", + "es": "Esto es una descripción en español de una propiedad con descripciones en varias lenguas." + }, + "label": { + "IRI-based": "classToClassProperty" + }, + "domain": "91", + "attributes": [ + "allValues", + "object" + ], + "id": "99" + }, + { + "range": "23", + "domain": "9", + "attributes": [ + "object", + "anonymous" + ], + "id": "100" + }, + { + "iri": "http://ontovibe.visualdataweb.org#inverseFunctionalProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "1", + "label": { + "IRI-based": "inverseFunctionalProperty" + }, + "domain": "31", + "attributes": [ + "object", + "inverse functional" + ], + "id": "62" + }, + { + "iri": "http://ontovibe.visualdataweb.org#realProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "48", + "label": { + "IRI-based": "realProperty" + }, + "domain": "1", + "attributes": [ + "datatype" + ], + "id": "101" + }, + { + "iri": "http://ontovibe.visualdataweb.org#equivalentDataProperty", + "equivalent": [ + "101", + "51" + ], + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "22", + "label": { + "IRI-based": "equivalentDataProperty" + }, + "domain": "20", + "attributes": [ + "datatype" + ], + "id": "102" + }, + { + "iri": "http://ontovibe.visualdataweb.org#unionTypeDatatypeProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "39", + "label": { + "IRI-based": "unionTypeDatatypeProperty" + }, + "domain": "1", + "comment": { + "en": "This is an English comment on a property." + }, + "attributes": [ + "datatype" + ], + "id": "103" + }, + { + "iri": "http://ontovibe.visualdataweb.org#classToUntypedClassProperty", + "baseIri": "http://ontovibe.visualdataweb.org", + "range": "21", + "label": { + "IRI-based": "classToUntypedClassProperty" + }, + "domain": "1", + "attributes": [ + "object", + "symmetric" + ], + "id": "104" + } + ] +} \ No newline at end of file diff --git a/src/app/data/personasonto.json b/src/app/data/personasonto.json new file mode 100644 index 0000000000000000000000000000000000000000..9ddf16752ba2a98aa957b2a28caeaa170f2f2213 --- /dev/null +++ b/src/app/data/personasonto.json @@ -0,0 +1,5246 @@ +{ + "_comment": "Created with OWL2VOWL (version 0.3.4), http://vowl.visualdataweb.org", + "header": { + "languages": [ + "en", + "undefined" + ], + "baseIris": [ + "http://www.w3.org/1999/02/22-rdf-syntax-ns", + "http://blankdots.com/open/personasonto.owl", + "http://www.w3.org/2000/01/rdf-schema", + "http://www.w3.org/2001/XMLSchema" + ], + "title": { + "en": "PersonasOnto" + }, + "iri": "http://blankdots.com/open/personasonto.owl", + "version": "1.5", + "author": [ + "Stefan Negru" + ], + "description": { + "en": "The PersonasOnto is depicts the personas domain along with relating concept and properties. A persona is regarded as a user archetype which can be used to \"help guide decisions about product features, navigation, interactions, and even visual design\" (Goodwin, 2005).\n\nThis ontology wants to address some of the issues regarding this methodology like how personas are reconciled with other information and who is responsible for interpreting and validating them." + }, + "comments": { + "en": "PersonasOnto ontology incorporates concepts and properties used to model personas." + }, + "other": { + "date": [ + { + "identifier": "date", + "language": "undefined", + "value": "2014-02-28", + "type": "label" + } + ], + "creator": [ + { + "identifier": "creator", + "language": "undefined", + "value": "Stefan Negru", + "type": "label" + } + ], + "contributor": [ + { + "identifier": "contributor", + "language": "undefined", + "value": "Sabin Buraga", + "type": "label" + } + ], + "rights": [ + { + "identifier": "rights", + "language": "undefined", + "value": "This ontology is distributed under Attribution-ShareAlike 3.0 Unported - http://creativecommons.org/licenses/by-sa/3.0/", + "type": "label" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "1.5", + "type": "label" + } + ], + "title": [ + { + "identifier": "title", + "language": "en", + "value": "PersonasOnto", + "type": "label" + } + ], + "seeAlso": [ + { + "identifier": "seeAlso", + "language": "undefined", + "value": "http://blankdots.com/open/schema", + "type": "label" + } + ] + } + }, + "namespace": [], + "metrics": { + "classCount": 53, + "objectPropertyCount": 36, + "datatypePropertyCount": 30, + "individualCount": 0 + }, + "class": [ + { + "id": "8", + "type": "owl:Class" + }, + { + "id": "13", + "type": "owl:Class" + }, + { + "id": "23", + "type": "owl:Class" + }, + { + "id": "25", + "type": "owl:Class" + }, + { + "id": "29", + "type": "owl:Class" + }, + { + "id": "54", + "type": "owl:Class" + }, + { + "id": "55", + "type": "owl:Class" + }, + { + "id": "46", + "type": "owl:Class" + }, + { + "id": "88", + "type": "owl:Class" + }, + { + "id": "89", + "type": "owl:Class" + }, + { + "id": "33", + "type": "owl:Class" + }, + { + "id": "42", + "type": "rdfs:Literal" + }, + { + "id": "30", + "type": "owl:Class" + }, + { + "id": "108", + "type": "rdfs:Literal" + }, + { + "id": "66", + "type": "rdfs:Literal" + }, + { + "id": "109", + "type": "rdfs:Literal" + }, + { + "id": "106", + "type": "rdfs:Datatype" + }, + { + "id": "117", + "type": "rdfs:Literal" + }, + { + "id": "100", + "type": "rdfs:Literal" + }, + { + "id": "118", + "type": "rdfs:Datatype" + }, + { + "id": "79", + "type": "owl:Class" + }, + { + "id": "119", + "type": "rdfs:Literal" + }, + { + "id": "120", + "type": "rdfs:Literal" + }, + { + "id": "121", + "type": "rdfs:Datatype" + }, + { + "id": "111", + "type": "rdfs:Datatype" + }, + { + "id": "122", + "type": "rdfs:Datatype" + }, + { + "id": "22", + "type": "rdfs:Datatype" + }, + { + "id": "123", + "type": "rdfs:Datatype" + }, + { + "id": "9", + "type": "owl:Class" + }, + { + "id": "126", + "type": "owl:Class" + }, + { + "id": "131", + "type": "rdfs:Literal" + }, + { + "id": "75", + "type": "rdfs:Datatype" + }, + { + "id": "41", + "type": "owl:Class" + }, + { + "id": "68", + "type": "rdfs:Datatype" + }, + { + "id": "134", + "type": "rdfs:Datatype" + }, + { + "id": "103", + "type": "rdfs:Datatype" + }, + { + "id": "125", + "type": "owl:Class" + }, + { + "id": "130", + "type": "rdfs:Datatype" + }, + { + "id": "142", + "type": "rdfs:Literal" + }, + { + "id": "1", + "type": "owl:Class" + }, + { + "id": "143", + "type": "rdfs:Literal" + }, + { + "id": "71", + "type": "owl:Class" + }, + { + "id": "147", + "type": "rdfs:Datatype" + }, + { + "id": "86", + "type": "owl:unionOf" + }, + { + "id": "87", + "type": "rdfs:Datatype" + }, + { + "id": "148", + "type": "owl:Class" + }, + { + "id": "139", + "type": "owl:Class" + }, + { + "id": "146", + "type": "owl:Class" + }, + { + "id": "155", + "type": "rdfs:Datatype" + }, + { + "id": "156", + "type": "owl:Class" + }, + { + "id": "157", + "type": "rdfs:Literal" + }, + { + "id": "153", + "type": "rdfs:Literal" + }, + { + "id": "113", + "type": "rdfs:Datatype" + }, + { + "id": "158", + "type": "owl:unionOf" + }, + { + "id": "128", + "type": "owl:unionOf" + }, + { + "id": "161", + "type": "owl:unionOf" + }, + { + "id": "163", + "type": "owl:unionOf" + }, + { + "id": "165", + "type": "owl:unionOf" + }, + { + "id": "18", + "type": "owl:Class" + }, + { + "id": "166", + "type": "owl:unionOf" + }, + { + "id": "167", + "type": "rdfs:Datatype" + }, + { + "id": "45", + "type": "owl:Class" + }, + { + "id": "170", + "type": "owl:unionOf" + }, + { + "id": "37", + "type": "owl:Class" + }, + { + "id": "144", + "type": "owl:Class" + }, + { + "id": "4", + "type": "owl:Class" + }, + { + "id": "60", + "type": "owl:Class" + }, + { + "id": "190", + "type": "owl:Class" + }, + { + "id": "27", + "type": "owl:Class" + }, + { + "id": "136", + "type": "owl:Class" + }, + { + "id": "137", + "type": "owl:Class" + }, + { + "id": "164", + "type": "owl:Class" + }, + { + "id": "24", + "type": "owl:Class" + }, + { + "id": "132", + "type": "owl:Class" + }, + { + "id": "7", + "type": "owl:Class" + }, + { + "id": "83", + "type": "owl:Class" + }, + { + "id": "6", + "type": "owl:Class" + }, + { + "id": "97", + "type": "owl:Thing" + }, + { + "id": "116", + "type": "owl:Thing" + }, + { + "id": "151", + "type": "owl:Thing" + }, + { + "id": "138", + "type": "owl:Class" + }, + { + "id": "98", + "type": "owl:Class" + }, + { + "id": "17", + "type": "owl:Thing" + }, + { + "id": "36", + "type": "owl:Thing" + }, + { + "id": "57", + "type": "owl:Thing" + }, + { + "id": "221", + "type": "owl:Thing" + }, + { + "id": "73", + "type": "owl:Thing" + }, + { + "id": "93", + "type": "owl:Thing" + }, + { + "id": "252", + "type": "owl:Thing" + }, + { + "id": "133", + "type": "owl:Class" + }, + { + "id": "140", + "type": "owl:Class" + }, + { + "id": "2", + "type": "owl:Class" + }, + { + "id": "49", + "type": "owl:Class" + }, + { + "id": "135", + "type": "owl:Class" + }, + { + "id": "21", + "type": "owl:Class" + }, + { + "id": "141", + "type": "owl:Class" + }, + { + "id": "70", + "type": "owl:Class" + }, + { + "id": "62", + "type": "owl:Class" + }, + { + "id": "145", + "type": "owl:Class" + }, + { + "id": "81", + "type": "owl:Class" + } + ], + "classAttribute": [ + { + "iri": "http://blankdots.com/open/personasonto.owl#Document", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A paper or digital document (web-page, text document etc.)." + }, + "label": { + "IRI-based": "Document" + }, + "id": "8", + "superClasses": [ + "9" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Product", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A physical product or a digital product (Software Application)." + }, + "label": { + "IRI-based": "Product" + }, + "id": "13", + "superClasses": [ + "9" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#SupplementalType", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Needs are completely satisfied by one of the primary interfaces yet they are part of the set or personas to ensure comprehensive representation." + }, + "label": { + "IRI-based": "SupplementalType" + }, + "id": "23", + "superClasses": [ + "24" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#UsabilityTest", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A usability test evaluates the usability of a certain Product in a Scenario." + }, + "label": { + "IRI-based": "UsabilityTest" + }, + "id": "25" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#TechnicalGoals", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Technical goals reflect technical aspects regarding an application/product for example: run in a variety of browser, data privacy\netc." + }, + "label": { + "IRI-based": "TechnicalGoals" + }, + "id": "29", + "superClasses": [ + "30" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Participant", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A person that participates in the usability test. Usualy a participant has a diresct correspondent to a Persona type." + }, + "label": { + "IRI-based": "Participant" + }, + "id": "54", + "superClasses": [ + "27" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#LifeGoals", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Life goals represent personal aspirations of the user that typically go beyond the context of the product being designed." + }, + "label": { + "IRI-based": "LifeGoals" + }, + "id": "55", + "superClasses": [ + "30" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Scenario", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A series of tasks the user performs in a certain context." + }, + "label": { + "IRI-based": "Scenario" + }, + "id": "46" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Tangible", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A context might be described by an Tangible enviroment - real world." + }, + "label": { + "IRI-based": "Tangible" + }, + "id": "88", + "superClasses": [ + "45" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#EndGoals", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "End goals represent the user’s motivation for performing the tasks associated with using a specific product." + }, + "label": { + "IRI-based": "EndGoals" + }, + "id": "89", + "superClasses": [ + "30" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#DevelopmentDisability", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Any disability that related to growth and development problems." + }, + "label": { + "IRI-based": "DevelopmentDisability" + }, + "id": "33", + "superClasses": [ + "83" + ] + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "42", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Goals", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "The goals of a Persona. The goals are divided accordingly, depending on each persona type." + }, + "label": { + "IRI-based": "Goals" + }, + "subClasses": [ + "18", + "89", + "98", + "55", + "29" + ], + "id": "30" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "108", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "66", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "109", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#positiveInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "106", + "label": { + "IRI-based": "positiveInteger" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "117", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "100", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#double", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "118", + "label": { + "IRI-based": "double" + } + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#PrimaryType", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "\"The goal is to find a single persona from the set whose needs and goals can be completely and happily satisfied by a single interface without disenfranchising any of the other personas\", About Face 2.0, Cooper, pg. 71. This is the Primary Persona Type" + }, + "label": { + "IRI-based": "PrimaryType" + }, + "id": "79", + "superClasses": [ + "24" + ] + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "119", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "120", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#positiveInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "121", + "label": { + "IRI-based": "positiveInteger" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#positiveInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "111", + "label": { + "IRI-based": "positiveInteger" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#positiveInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "122", + "label": { + "IRI-based": "positiveInteger" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#positiveInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "22", + "label": { + "IRI-based": "positiveInteger" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#positiveInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "123", + "label": { + "IRI-based": "positiveInteger" + } + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Resource", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Type of resources available, physical or digital." + }, + "label": { + "IRI-based": "Resource" + }, + "subClasses": [ + "8", + "37", + "13" + ], + "id": "9" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#MediumBusiness", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A particular medium sized business or branch of an organization. ( restaurant, medical practice etc.)" + }, + "label": { + "IRI-based": "MediumBusiness" + }, + "id": "126", + "superClasses": [ + "125" + ] + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "131", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#positiveInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "75", + "label": { + "IRI-based": "positiveInteger" + } + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Task", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Tasks performed by a Person in a Scenario." + }, + "label": { + "IRI-based": "Task" + }, + "subClasses": [ + "132", + "133" + ], + "id": "41" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#positiveInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "68", + "label": { + "IRI-based": "positiveInteger" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#positiveInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "134", + "label": { + "IRI-based": "positiveInteger" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#positiveInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "103", + "label": { + "IRI-based": "positiveInteger" + } + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Organization", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "The type of Organization a Person belongs to." + }, + "label": { + "IRI-based": "Organization" + }, + "subClasses": [ + "135", + "136", + "137", + "138", + "139", + "140", + "126", + "141" + ], + "id": "125" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "130", + "label": { + "IRI-based": "string" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "142", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#HearingImpairment", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Conditions in which persons are fully or partially unable to detect or perceive at least some frequencies of sound." + }, + "label": { + "IRI-based": "HearingImpairment" + }, + "id": "1", + "superClasses": [ + "83" + ] + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "143", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#AffectiveState", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "The affective state of a person at a certain moment and in a certain Context." + }, + "label": { + "IRI-based": "AffectiveState" + }, + "subClasses": [ + "144", + "145", + "146" + ], + "id": "71" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#positiveInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "147", + "label": { + "IRI-based": "positiveInteger" + } + }, + { + "instances": 0, + "union": [ + "125", + "148" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "86" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "87", + "label": { + "IRI-based": "string" + } + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Place", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "The appropriate Place which describes the Context. " + }, + "label": { + "IRI-based": "Place" + }, + "comment": { + "undefined": "A Context might only be described by a certain Place." + }, + "id": "148", + "superClasses": [ + "45" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#NGO", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A Non-Governamental Organization." + }, + "label": { + "IRI-based": "NGO" + }, + "id": "139", + "superClasses": [ + "125" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Feeling", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Feelings relate more to a property associated to and object or being, than to a person’s state of mind." + }, + "label": { + "IRI-based": "Feeling" + }, + "id": "146", + "superClasses": [ + "71" + ] + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#dateTime", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "155", + "label": { + "IRI-based": "dateTime" + } + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Intangible", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A context might be described by an Intangible enviroment (Operating System, Application etc. -- virtual world)." + }, + "label": { + "IRI-based": "Intangible" + }, + "id": "156", + "superClasses": [ + "45" + ] + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "157", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "153", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#string", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "113", + "label": { + "IRI-based": "string" + } + }, + { + "instances": 0, + "union": [ + "54", + "27" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "158" + }, + { + "instances": 0, + "union": [ + "9", + "25", + "46" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "128" + }, + { + "instances": 0, + "union": [ + "88", + "156" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "161" + }, + { + "instances": 0, + "union": [ + "164", + "148" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "163" + }, + { + "instances": 0, + "union": [ + "25", + "46" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "165" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#BusinessGoals", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Business goals represent the goals of the organization the persons works for." + }, + "label": { + "IRI-based": "BusinessGoals" + }, + "id": "18", + "superClasses": [ + "30" + ] + }, + { + "instances": 0, + "union": [ + "54", + "41", + "46" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "166" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#float", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "167", + "label": { + "IRI-based": "float" + } + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Context", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "The Context in which a scenario takes place." + }, + "label": { + "IRI-based": "Context" + }, + "subClasses": [ + "88", + "164", + "156", + "148" + ], + "id": "45" + }, + { + "instances": 0, + "union": [ + "71", + "70" + ], + "attributes": [ + "anonymous", + "union" + ], + "id": "170" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Image", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "An image, which might be used to describe a product or person." + }, + "label": { + "IRI-based": "Image" + }, + "id": "37", + "superClasses": [ + "9" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Mood", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Are not directed at any object in particular and are experienced as more diffuse, global, and general state." + }, + "label": { + "IRI-based": "Mood" + }, + "id": "144", + "superClasses": [ + "71" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#VisualImpairment", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Visual impairment refers to vision loss to such a degree as a person needs an additional support to get through its surroundings." + }, + "label": { + "IRI-based": "VisualImpairment" + }, + "id": "4", + "superClasses": [ + "83" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#ServedType", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Do not directly use the product you are designing but they are somehow affected by the system." + }, + "label": { + "IRI-based": "ServedType" + }, + "id": "60", + "superClasses": [ + "24" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#CustomerType", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Are not the end user but the customer of the product, but might be the person making, buying decisions." + }, + "label": { + "IRI-based": "CustomerType" + }, + "id": "190", + "superClasses": [ + "24" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Person", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A person represents an individual, most likely a human." + }, + "label": { + "IRI-based": "Person" + }, + "subClasses": [ + "21", + "54" + ], + "id": "27" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#EducationalOrganization", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "An educational organization. " + }, + "label": { + "IRI-based": "EducationalOrganization" + }, + "id": "136", + "superClasses": [ + "125" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#SportsTeam", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A sports team (football, basketball, bowling etc.)." + }, + "label": { + "IRI-based": "SportsTeam" + }, + "id": "137", + "superClasses": [ + "125" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Time", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "The appropriate Time which describes the Context. " + }, + "label": { + "IRI-based": "Time" + }, + "comment": { + "undefined": "A Context might only be described at a certain Time." + }, + "id": "164", + "superClasses": [ + "45" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#PersonaType", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Each Persona is classified by a PersonaType and a Person might fit into several PersonaTypes." + }, + "label": { + "IRI-based": "PersonaType" + }, + "subClasses": [ + "190", + "62", + "60", + "23", + "79", + "81" + ], + "id": "24", + "superClasses": [ + "21" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#NonInteractiveTask", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "NonInteractiveTask could be a machine response to that action." + }, + "label": { + "IRI-based": "NonInteractiveTask" + }, + "id": "132", + "superClasses": [ + "41" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#MentalEmotionalDisorder", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Any mental disorder/illness described as a psychological or behavioral pattern associated with distress or disability that occurs in an person." + }, + "label": { + "IRI-based": "MentalEmotionalDisorder" + }, + "id": "7", + "superClasses": [ + "83" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Disability", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A person’s disabilities mental and/or physical." + }, + "label": { + "IRI-based": "Disability" + }, + "subClasses": [ + "2", + "4", + "1", + "7", + "6", + "49", + "33" + ], + "id": "83" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#IntellectualImpairment", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "This type of impairment ranges from mental retardation to cognitive deficits too mild or too specific." + }, + "label": { + "IRI-based": "IntellectualImpairment" + }, + "id": "6", + "superClasses": [ + "83" + ] + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "97", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "116", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "151", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#GovermentOrganization", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A governmental organization or agency. " + }, + "label": { + "IRI-based": "GovermentOrganization" + }, + "id": "138", + "superClasses": [ + "125" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#ExperienceGoals", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Experience goals are simple, universal, and personal." + }, + "label": { + "IRI-based": "ExperienceGoals" + }, + "id": "98", + "superClasses": [ + "30" + ] + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "17", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "36", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "57", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "221", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "73", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "93", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "252", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#InteractiveTask", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "InteractiveTask could be certain action performed by a person (not too often by a machine)." + }, + "label": { + "IRI-based": "InteractiveTask" + }, + "id": "133", + "superClasses": [ + "41" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#SmallBusiness", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A particular small business like a local shop or market (usually under 5 employees)." + }, + "label": { + "IRI-based": "SmallBusiness" + }, + "id": "140", + "superClasses": [ + "125" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#SomatosensoryImpairment", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Insensitivity to stimuli such as touch, heat, cold, and pain." + }, + "label": { + "IRI-based": "SomatosensoryImpairment" + }, + "id": "2", + "superClasses": [ + "83" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#GustatoryImpairment", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Impairment of the sense of smell and taste." + }, + "label": { + "IRI-based": "GustatoryImpairment" + }, + "id": "49", + "superClasses": [ + "83" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Group", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Any kind of (small or large) group a person might be part of (book club)." + }, + "label": { + "IRI-based": "Group" + }, + "id": "135", + "superClasses": [ + "125" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Persona", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "As a subclass of Person, the Persona class could be regarded of being a separate identity of a person, although it has the same usage." + }, + "label": { + "IRI-based": "Persona" + }, + "subClasses": [ + "24" + ], + "id": "21", + "superClasses": [ + "27" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Corporation", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "A business corporation. " + }, + "label": { + "IRI-based": "Corporation" + }, + "id": "141", + "superClasses": [ + "125" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Personality", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "The MyersBriggs personality of a person." + }, + "label": { + "IRI-based": "Personality" + }, + "id": "70" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#SecondaryType", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "The secondary persona's goals and needs can mostly be met by focusing on the primary persona. Still, there are a few goals specific to them that are not a priority for the primary persona." + }, + "label": { + "IRI-based": "SecondaryType" + }, + "id": "62", + "superClasses": [ + "24" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#Emotion", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Emotion encompasses physiological, affective, behavioral, andcognitive components." + }, + "label": { + "IRI-based": "Emotion" + }, + "id": "145", + "superClasses": [ + "71" + ] + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#NegativeType", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "instances": 0, + "description": { + "undefined": "Are used to remind and communicate, who is NOT the target of the design." + }, + "label": { + "IRI-based": "NegativeType" + }, + "id": "81", + "superClasses": [ + "24" + ] + } + ], + "property": [ + { + "id": "0", + "type": "owl:disjointWith" + }, + { + "id": "3", + "type": "owl:disjointWith" + }, + { + "id": "5", + "type": "owl:disjointWith" + }, + { + "id": "10", + "type": "owl:disjointWith" + }, + { + "id": "11", + "type": "owl:disjointWith" + }, + { + "id": "12", + "type": "owl:disjointWith" + }, + { + "id": "14", + "type": "owl:disjointWith" + }, + { + "id": "15", + "type": "owl:disjointWith" + }, + { + "id": "16", + "type": "owl:objectProperty" + }, + { + "id": "20", + "type": "owl:datatypeProperty" + }, + { + "id": "26", + "type": "owl:objectProperty" + }, + { + "id": "28", + "type": "owl:disjointWith" + }, + { + "id": "31", + "type": "owl:disjointWith" + }, + { + "id": "32", + "type": "owl:disjointWith" + }, + { + "id": "34", + "type": "owl:disjointWith" + }, + { + "id": "35", + "type": "owl:objectProperty" + }, + { + "id": "39", + "type": "owl:disjointWith" + }, + { + "id": "40", + "type": "owl:datatypeProperty" + }, + { + "id": "43", + "type": "owl:disjointWith" + }, + { + "id": "44", + "type": "owl:objectProperty" + }, + { + "id": "48", + "type": "owl:disjointWith" + }, + { + "id": "50", + "type": "owl:disjointWith" + }, + { + "id": "51", + "type": "owl:disjointWith" + }, + { + "id": "52", + "type": "owl:disjointWith" + }, + { + "id": "53", + "type": "owl:disjointWith" + }, + { + "id": "56", + "type": "owl:objectProperty" + }, + { + "id": "58", + "type": "owl:objectProperty" + }, + { + "id": "59", + "type": "owl:disjointWith" + }, + { + "id": "61", + "type": "owl:disjointWith" + }, + { + "id": "63", + "type": "owl:disjointWith" + }, + { + "id": "64", + "type": "owl:disjointWith" + }, + { + "id": "65", + "type": "owl:datatypeProperty" + }, + { + "id": "67", + "type": "owl:datatypeProperty" + }, + { + "id": "69", + "type": "owl:objectProperty" + }, + { + "id": "72", + "type": "owl:objectProperty" + }, + { + "id": "74", + "type": "owl:datatypeProperty" + }, + { + "id": "76", + "type": "rdfs:SubClassOf" + }, + { + "id": "77", + "type": "rdfs:SubClassOf" + }, + { + "id": "78", + "type": "rdfs:SubClassOf" + }, + { + "id": "80", + "type": "rdfs:SubClassOf" + }, + { + "id": "82", + "type": "rdfs:SubClassOf" + }, + { + "id": "84", + "type": "rdfs:SubClassOf" + }, + { + "id": "85", + "type": "owl:datatypeProperty" + }, + { + "id": "90", + "type": "rdfs:SubClassOf" + }, + { + "id": "91", + "type": "rdfs:SubClassOf" + }, + { + "id": "92", + "type": "rdfs:SubClassOf" + }, + { + "id": "38", + "type": "owl:objectProperty" + }, + { + "id": "94", + "type": "rdfs:SubClassOf" + }, + { + "id": "95", + "type": "rdfs:SubClassOf" + }, + { + "id": "96", + "type": "owl:objectProperty" + }, + { + "id": "99", + "type": "owl:datatypeProperty" + }, + { + "id": "101", + "type": "owl:objectProperty" + }, + { + "id": "102", + "type": "owl:datatypeProperty" + }, + { + "id": "104", + "type": "owl:objectProperty" + }, + { + "id": "105", + "type": "owl:datatypeProperty" + }, + { + "id": "107", + "type": "owl:objectProperty" + }, + { + "id": "110", + "type": "owl:datatypeProperty" + }, + { + "id": "112", + "type": "owl:datatypeProperty" + }, + { + "id": "114", + "type": "owl:objectProperty" + }, + { + "id": "115", + "type": "owl:objectProperty" + }, + { + "id": "124", + "type": "owl:objectProperty" + }, + { + "id": "127", + "type": "owl:objectProperty" + }, + { + "id": "129", + "type": "owl:datatypeProperty" + }, + { + "id": "149", + "type": "owl:datatypeProperty" + }, + { + "id": "150", + "type": "owl:objectProperty" + }, + { + "id": "152", + "type": "owl:datatypeProperty" + }, + { + "id": "154", + "type": "owl:datatypeProperty" + }, + { + "id": "159", + "type": "owl:objectProperty" + }, + { + "id": "160", + "type": "owl:objectProperty" + }, + { + "id": "162", + "type": "owl:datatypeProperty" + }, + { + "id": "47", + "type": "owl:objectProperty" + }, + { + "id": "168", + "type": "owl:disjointWith" + }, + { + "id": "169", + "type": "owl:someValuesFrom" + }, + { + "id": "171", + "type": "owl:disjointWith" + }, + { + "id": "172", + "type": "owl:datatypeProperty" + }, + { + "id": "173", + "type": "owl:datatypeProperty" + }, + { + "id": "174", + "type": "owl:disjointWith" + }, + { + "id": "175", + "type": "owl:disjointWith" + }, + { + "id": "176", + "type": "rdfs:SubClassOf" + }, + { + "id": "177", + "type": "rdfs:SubClassOf" + }, + { + "id": "178", + "type": "owl:disjointWith" + }, + { + "id": "179", + "type": "rdfs:SubClassOf" + }, + { + "id": "180", + "type": "owl:disjointWith" + }, + { + "id": "181", + "type": "rdfs:SubClassOf" + }, + { + "id": "182", + "type": "owl:disjointWith" + }, + { + "id": "183", + "type": "rdfs:SubClassOf" + }, + { + "id": "184", + "type": "owl:disjointWith" + }, + { + "id": "185", + "type": "rdfs:SubClassOf" + }, + { + "id": "186", + "type": "owl:disjointWith" + }, + { + "id": "187", + "type": "rdfs:SubClassOf" + }, + { + "id": "188", + "type": "owl:disjointWith" + }, + { + "id": "189", + "type": "rdfs:SubClassOf" + }, + { + "id": "191", + "type": "owl:disjointWith" + }, + { + "id": "192", + "type": "rdfs:SubClassOf" + }, + { + "id": "193", + "type": "owl:disjointWith" + }, + { + "id": "194", + "type": "rdfs:SubClassOf" + }, + { + "id": "195", + "type": "rdfs:SubClassOf" + }, + { + "id": "196", + "type": "owl:datatypeProperty" + }, + { + "id": "197", + "type": "owl:objectProperty" + }, + { + "id": "198", + "type": "owl:datatypeProperty" + }, + { + "id": "199", + "type": "owl:disjointWith" + }, + { + "id": "200", + "type": "owl:datatypeProperty" + }, + { + "id": "201", + "type": "owl:disjointWith" + }, + { + "id": "202", + "type": "owl:disjointWith" + }, + { + "id": "203", + "type": "rdfs:SubClassOf" + }, + { + "id": "204", + "type": "owl:disjointWith" + }, + { + "id": "205", + "type": "rdfs:SubClassOf" + }, + { + "id": "206", + "type": "owl:disjointWith" + }, + { + "id": "207", + "type": "rdfs:SubClassOf" + }, + { + "id": "208", + "type": "owl:disjointWith" + }, + { + "id": "209", + "type": "rdfs:SubClassOf" + }, + { + "id": "210", + "type": "owl:disjointWith" + }, + { + "id": "211", + "type": "rdfs:SubClassOf" + }, + { + "id": "212", + "type": "owl:objectProperty" + }, + { + "id": "213", + "type": "owl:disjointWith" + }, + { + "id": "214", + "type": "rdfs:SubClassOf" + }, + { + "id": "215", + "type": "rdfs:SubClassOf" + }, + { + "id": "216", + "type": "owl:disjointWith" + }, + { + "id": "217", + "type": "rdfs:SubClassOf" + }, + { + "id": "218", + "type": "owl:disjointWith" + }, + { + "id": "219", + "type": "rdfs:SubClassOf" + }, + { + "id": "220", + "type": "owl:objectProperty" + }, + { + "id": "222", + "type": "owl:disjointWith" + }, + { + "id": "223", + "type": "rdfs:SubClassOf" + }, + { + "id": "224", + "type": "owl:objectProperty" + }, + { + "id": "225", + "type": "rdfs:SubClassOf" + }, + { + "id": "226", + "type": "owl:disjointWith" + }, + { + "id": "227", + "type": "owl:datatypeProperty" + }, + { + "id": "228", + "type": "owl:disjointWith" + }, + { + "id": "229", + "type": "owl:objectProperty" + }, + { + "id": "230", + "type": "owl:datatypeProperty" + }, + { + "id": "231", + "type": "owl:datatypeProperty" + }, + { + "id": "232", + "type": "owl:disjointWith" + }, + { + "id": "233", + "type": "rdfs:SubClassOf" + }, + { + "id": "234", + "type": "owl:disjointWith" + }, + { + "id": "235", + "type": "rdfs:SubClassOf" + }, + { + "id": "236", + "type": "owl:disjointWith" + }, + { + "id": "237", + "type": "rdfs:SubClassOf" + }, + { + "id": "238", + "type": "owl:objectProperty" + }, + { + "id": "239", + "type": "owl:disjointWith" + }, + { + "id": "240", + "type": "rdfs:SubClassOf" + }, + { + "id": "241", + "type": "owl:disjointWith" + }, + { + "id": "242", + "type": "rdfs:SubClassOf" + }, + { + "id": "243", + "type": "owl:disjointWith" + }, + { + "id": "244", + "type": "rdfs:SubClassOf" + }, + { + "id": "245", + "type": "owl:disjointWith" + }, + { + "id": "246", + "type": "rdfs:SubClassOf" + }, + { + "id": "247", + "type": "owl:disjointWith" + }, + { + "id": "248", + "type": "rdfs:SubClassOf" + }, + { + "id": "249", + "type": "owl:disjointWith" + }, + { + "id": "250", + "type": "owl:disjointWith" + }, + { + "id": "251", + "type": "owl:datatypeProperty" + }, + { + "id": "253", + "type": "owl:disjointWith" + }, + { + "id": "254", + "type": "owl:disjointWith" + }, + { + "id": "255", + "type": "owl:disjointWith" + }, + { + "id": "256", + "type": "owl:disjointWith" + }, + { + "id": "257", + "type": "owl:disjointWith" + }, + { + "id": "258", + "type": "owl:disjointWith" + }, + { + "id": "259", + "type": "owl:disjointWith" + }, + { + "id": "260", + "type": "owl:objectProperty" + }, + { + "id": "261", + "type": "owl:disjointWith" + }, + { + "id": "262", + "type": "owl:disjointWith" + }, + { + "id": "263", + "type": "owl:disjointWith" + }, + { + "id": "264", + "type": "owl:disjointWith" + }, + { + "id": "265", + "type": "owl:disjointWith" + }, + { + "id": "266", + "type": "owl:disjointWith" + }, + { + "id": "267", + "type": "owl:objectProperty" + }, + { + "id": "268", + "type": "owl:datatypeProperty" + }, + { + "id": "269", + "type": "owl:disjointWith" + }, + { + "id": "270", + "type": "owl:datatypeProperty" + }, + { + "id": "271", + "type": "owl:disjointWith" + }, + { + "id": "272", + "type": "owl:objectProperty" + }, + { + "id": "273", + "type": "owl:disjointWith" + }, + { + "id": "274", + "type": "owl:disjointWith" + }, + { + "id": "275", + "type": "owl:disjointWith" + }, + { + "id": "276", + "type": "owl:disjointWith" + }, + { + "id": "277", + "type": "owl:disjointWith" + }, + { + "id": "278", + "type": "owl:disjointWith" + }, + { + "id": "279", + "type": "owl:disjointWith" + }, + { + "id": "280", + "type": "owl:disjointWith" + }, + { + "id": "281", + "type": "owl:objectProperty" + }, + { + "id": "282", + "type": "owl:disjointWith" + }, + { + "id": "283", + "type": "owl:datatypeProperty" + }, + { + "id": "284", + "type": "owl:objectProperty" + }, + { + "id": "285", + "type": "owl:objectProperty" + }, + { + "id": "286", + "type": "owl:disjointWith" + }, + { + "id": "287", + "type": "owl:disjointWith" + }, + { + "id": "19", + "type": "owl:objectProperty" + }, + { + "id": "288", + "type": "owl:objectProperty" + }, + { + "id": "289", + "type": "owl:disjointWith" + }, + { + "id": "290", + "type": "owl:disjointWith" + }, + { + "id": "291", + "type": "owl:disjointWith" + }, + { + "id": "292", + "type": "owl:disjointWith" + }, + { + "id": "293", + "type": "owl:disjointWith" + }, + { + "id": "294", + "type": "owl:disjointWith" + }, + { + "id": "295", + "type": "owl:disjointWith" + }, + { + "id": "296", + "type": "owl:disjointWith" + }, + { + "id": "297", + "type": "owl:disjointWith" + }, + { + "id": "298", + "type": "owl:disjointWith" + }, + { + "id": "299", + "type": "owl:disjointWith" + }, + { + "id": "300", + "type": "owl:disjointWith" + }, + { + "id": "301", + "type": "owl:disjointWith" + }, + { + "id": "302", + "type": "owl:disjointWith" + }, + { + "id": "303", + "type": "owl:disjointWith" + }, + { + "id": "304", + "type": "owl:disjointWith" + }, + { + "id": "305", + "type": "owl:disjointWith" + }, + { + "id": "306", + "type": "owl:disjointWith" + }, + { + "id": "307", + "type": "owl:disjointWith" + }, + { + "id": "308", + "type": "owl:disjointWith" + }, + { + "id": "309", + "type": "owl:someValuesFrom" + }, + { + "id": "310", + "type": "owl:disjointWith" + }, + { + "id": "311", + "type": "owl:disjointWith" + }, + { + "id": "312", + "type": "owl:disjointWith" + }, + { + "id": "313", + "type": "owl:disjointWith" + }, + { + "id": "314", + "type": "owl:disjointWith" + }, + { + "id": "315", + "type": "owl:disjointWith" + }, + { + "id": "316", + "type": "owl:disjointWith" + }, + { + "id": "317", + "type": "owl:datatypeProperty" + }, + { + "id": "318", + "type": "owl:disjointWith" + }, + { + "id": "319", + "type": "owl:objectProperty" + }, + { + "id": "320", + "type": "owl:disjointWith" + }, + { + "id": "321", + "type": "owl:disjointWith" + }, + { + "id": "322", + "type": "owl:disjointWith" + }, + { + "id": "323", + "type": "owl:disjointWith" + }, + { + "id": "324", + "type": "owl:disjointWith" + }, + { + "id": "325", + "type": "owl:disjointWith" + }, + { + "id": "326", + "type": "owl:disjointWith" + }, + { + "id": "327", + "type": "owl:datatypeProperty" + }, + { + "id": "328", + "type": "owl:disjointWith" + } + ], + "propertyAttribute": [ + { + "range": "2", + "domain": "1", + "attributes": [ + "object", + "anonymous" + ], + "id": "0" + }, + { + "range": "1", + "domain": "4", + "attributes": [ + "object", + "anonymous" + ], + "id": "3" + }, + { + "range": "7", + "domain": "6", + "attributes": [ + "object", + "anonymous" + ], + "id": "5" + }, + { + "range": "2", + "domain": "6", + "attributes": [ + "object", + "anonymous" + ], + "id": "10" + }, + { + "range": "4", + "domain": "6", + "attributes": [ + "object", + "anonymous" + ], + "id": "11" + }, + { + "range": "2", + "domain": "7", + "attributes": [ + "object", + "anonymous" + ], + "id": "12" + }, + { + "range": "4", + "domain": "7", + "attributes": [ + "object", + "anonymous" + ], + "id": "14" + }, + { + "range": "2", + "domain": "4", + "attributes": [ + "object", + "anonymous" + ], + "id": "15" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasBusinessGoal", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "18", + "label": { + "IRI-based": "hasBusinessGoal" + }, + "superproperty": [ + "19" + ], + "domain": "17", + "attributes": [ + "object" + ], + "id": "16" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#minHeight", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "22", + "description": { + "undefined": "Minimum Height." + }, + "label": { + "IRI-based": "minHeight" + }, + "domain": "21", + "attributes": [ + "functional", + "datatype" + ], + "id": "20" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasTopicOfInterest", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "9", + "description": { + "undefined": "A person might have a certain topic of interest which is correspondent to a cetain resource." + }, + "label": { + "IRI-based": "hasTopicOfInterest" + }, + "domain": "27", + "attributes": [ + "object" + ], + "id": "26" + }, + { + "range": "1", + "domain": "6", + "attributes": [ + "object", + "anonymous" + ], + "id": "28" + }, + { + "range": "1", + "domain": "7", + "attributes": [ + "object", + "anonymous" + ], + "id": "31" + }, + { + "range": "33", + "domain": "6", + "attributes": [ + "object", + "anonymous" + ], + "id": "32" + }, + { + "range": "33", + "domain": "7", + "attributes": [ + "object", + "anonymous" + ], + "id": "34" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#depictsImage", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "37", + "label": { + "IRI-based": "depictsImage" + }, + "superproperty": [ + "38" + ], + "domain": "36", + "attributes": [ + "object" + ], + "id": "35" + }, + { + "range": "2", + "domain": "33", + "attributes": [ + "object", + "anonymous" + ], + "id": "39" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#taskName", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "42", + "description": { + "undefined": "A generic (short) name for a task." + }, + "label": { + "IRI-based": "taskName" + }, + "domain": "41", + "attributes": [ + "datatype" + ], + "id": "40" + }, + { + "range": "33", + "domain": "4", + "attributes": [ + "object", + "anonymous" + ], + "id": "43" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#isContextOf", + "inverse": "47", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "46", + "description": { + "undefined": "Inverse property of hasContext, isContextof represents the context belonging to a scenario." + }, + "label": { + "IRI-based": "isContextOf" + }, + "domain": "45", + "attributes": [ + "object" + ], + "id": "44" + }, + { + "range": "1", + "domain": "49", + "attributes": [ + "object", + "anonymous" + ], + "id": "48" + }, + { + "range": "49", + "domain": "6", + "attributes": [ + "object", + "anonymous" + ], + "id": "50" + }, + { + "range": "49", + "domain": "7", + "attributes": [ + "object", + "anonymous" + ], + "id": "51" + }, + { + "range": "2", + "domain": "49", + "attributes": [ + "object", + "anonymous" + ], + "id": "52" + }, + { + "range": "49", + "domain": "4", + "attributes": [ + "object", + "anonymous" + ], + "id": "53" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#depictsProduct", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "13", + "label": { + "IRI-based": "depictsProduct" + }, + "superproperty": [ + "38" + ], + "domain": "57", + "attributes": [ + "object" + ], + "id": "56" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#isGoalOf", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "27", + "description": { + "undefined": "Inverse property of hasGoal, isGoalof represents the goal belonging to a person." + }, + "label": { + "IRI-based": "isGoalOf" + }, + "domain": "30", + "attributes": [ + "object" + ], + "id": "58" + }, + { + "range": "23", + "domain": "60", + "attributes": [ + "object", + "anonymous" + ], + "id": "59" + }, + { + "range": "23", + "domain": "62", + "attributes": [ + "object", + "anonymous" + ], + "id": "61" + }, + { + "range": "33", + "domain": "49", + "attributes": [ + "object", + "anonymous" + ], + "id": "63" + }, + { + "range": "1", + "domain": "33", + "attributes": [ + "object", + "anonymous" + ], + "id": "64" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#title", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "66", + "description": { + "undefined": "Academic, professional or military prefix/suffix for a person. " + }, + "label": { + "IRI-based": "title" + }, + "domain": "27", + "attributes": [ + "datatype" + ], + "id": "65" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#maxFeetSize", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "68", + "description": { + "undefined": "Maximum Feet Size." + }, + "label": { + "IRI-based": "maxFeetSize" + }, + "domain": "21", + "attributes": [ + "functional", + "datatype" + ], + "id": "67" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#influences", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "71", + "description": { + "undefined": "The personality influences the affective state o a person." + }, + "label": { + "IRI-based": "influences" + }, + "domain": "70", + "attributes": [ + "object" + ], + "id": "69" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#depictsDocument", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "8", + "label": { + "IRI-based": "depictsDocument" + }, + "superproperty": [ + "38" + ], + "domain": "73", + "attributes": [ + "object" + ], + "id": "72" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#maxBustSize", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "75", + "description": { + "undefined": "Maximum Bust Size." + }, + "label": { + "IRI-based": "maxBustSize" + }, + "domain": "21", + "attributes": [ + "functional", + "datatype" + ], + "id": "74" + }, + { + "range": "21", + "domain": "24", + "attributes": [ + "object", + "anonymous" + ], + "id": "76" + }, + { + "range": "24", + "domain": "23", + "attributes": [ + "object", + "anonymous" + ], + "id": "77" + }, + { + "range": "24", + "domain": "79", + "attributes": [ + "object", + "anonymous" + ], + "id": "78" + }, + { + "range": "24", + "domain": "81", + "attributes": [ + "object", + "anonymous" + ], + "id": "80" + }, + { + "range": "83", + "domain": "2", + "attributes": [ + "object", + "anonymous" + ], + "id": "82" + }, + { + "range": "83", + "domain": "4", + "attributes": [ + "object", + "anonymous" + ], + "id": "84" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#location", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "87", + "description": { + "undefined": "Geographic location (City/Country)." + }, + "label": { + "IRI-based": "location" + }, + "domain": "86", + "attributes": [ + "datatype" + ], + "id": "85" + }, + { + "range": "83", + "domain": "1", + "attributes": [ + "object", + "anonymous" + ], + "id": "90" + }, + { + "range": "83", + "domain": "7", + "attributes": [ + "object", + "anonymous" + ], + "id": "91" + }, + { + "range": "83", + "domain": "6", + "attributes": [ + "object", + "anonymous" + ], + "id": "92" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#depiction", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "9", + "description": { + "undefined": "A certain resource might depict a/any thing." + }, + "label": { + "IRI-based": "depiction" + }, + "domain": "93", + "subproperty": [ + "35", + "56", + "72" + ], + "attributes": [ + "object" + ], + "id": "38" + }, + { + "range": "83", + "domain": "49", + "attributes": [ + "object", + "anonymous" + ], + "id": "94" + }, + { + "range": "83", + "domain": "33", + "attributes": [ + "object", + "anonymous" + ], + "id": "95" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasExperienceGoal", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "98", + "label": { + "IRI-based": "hasExperienceGoal" + }, + "superproperty": [ + "19" + ], + "domain": "97", + "attributes": [ + "object" + ], + "id": "96" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#scenarioName", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "100", + "description": { + "undefined": "The name of each scenario." + }, + "label": { + "IRI-based": "scenarioName" + }, + "domain": "46", + "attributes": [ + "functional", + "datatype" + ], + "id": "99" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#influencedBy", + "inverse": "69", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "70", + "description": { + "undefined": "The affective state of a person is influenced by the personality of that person. (inverse property influences)" + }, + "label": { + "IRI-based": "influencedBy" + }, + "domain": "71", + "attributes": [ + "object" + ], + "id": "101" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#maxWaistSize", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "103", + "description": { + "undefined": "Maximum Waist Size." + }, + "label": { + "IRI-based": "maxWaistSize" + }, + "domain": "21", + "attributes": [ + "functional", + "datatype" + ], + "id": "102" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#uses", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "9", + "description": { + "undefined": "A person makes use of a resource (document, image, product)." + }, + "label": { + "IRI-based": "uses" + }, + "domain": "27", + "attributes": [ + "object" + ], + "id": "104" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#minWeight", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "106", + "description": { + "undefined": "Minimum Weight." + }, + "label": { + "IRI-based": "minWeight" + }, + "domain": "21", + "attributes": [ + "functional", + "datatype" + ], + "id": "105" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasAffectiveState", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "71", + "description": { + "undefined": "A person might have a certain affective state on a given moment or in a given context." + }, + "label": { + "IRI-based": "hasAffectiveState" + }, + "domain": "27", + "attributes": [ + "object" + ], + "id": "107" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#minBustSize", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "111", + "description": { + "undefined": "Minimum Bust Size." + }, + "label": { + "IRI-based": "minBustSize" + }, + "domain": "21", + "attributes": [ + "functional", + "datatype" + ], + "id": "110" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#familyName", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "113", + "description": { + "undefined": "Family or Last name of a person." + }, + "label": { + "IRI-based": "familyName" + }, + "domain": "27", + "attributes": [ + "functional", + "datatype" + ], + "id": "112" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasInterest", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "9", + "description": { + "undefined": "A person might be interested in a certain resource (product, application, document)." + }, + "label": { + "IRI-based": "hasInterest" + }, + "domain": "27", + "attributes": [ + "object" + ], + "id": "114" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasLifeGoal", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "55", + "label": { + "IRI-based": "hasLifeGoal" + }, + "superproperty": [ + "19" + ], + "domain": "116", + "attributes": [ + "object" + ], + "id": "115" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#isMemberOf", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "125", + "description": { + "undefined": "A person might be memeber of an organization." + }, + "label": { + "IRI-based": "isMemberOf" + }, + "domain": "27", + "attributes": [ + "object" + ], + "id": "124" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasReview", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "8", + "description": { + "undefined": "A resource, scenario or usability test is described, reviewed via a document." + }, + "label": { + "IRI-based": "hasReview" + }, + "domain": "128", + "attributes": [ + "object" + ], + "id": "127" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#firstName", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "130", + "description": { + "undefined": "First or Given name of a person." + }, + "label": { + "IRI-based": "firstName" + }, + "domain": "27", + "attributes": [ + "functional", + "datatype" + ], + "id": "129" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#frustrationPoint", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "142", + "description": { + "undefined": "Elements of a UI/UX or certain characteristics that frustrate the user or (s)he sees as pain points." + }, + "label": { + "IRI-based": "frustrationPoint" + }, + "domain": "27", + "attributes": [ + "datatype" + ], + "id": "149" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasTechnicalGoal", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "29", + "label": { + "IRI-based": "hasTechnicalGoal" + }, + "superproperty": [ + "19" + ], + "domain": "151", + "attributes": [ + "object" + ], + "id": "150" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#experienceLevel", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "153", + "description": { + "undefined": "Reflects the experience level of a persona with the application\nor product; proposed levels: Beginner, Intermediate, Advanced." + }, + "label": { + "IRI-based": "experienceLevel" + }, + "domain": "27", + "comment": { + "undefined": "It is different from technical level, because a person might be experienced in some product or application but does not have technical skills." + }, + "attributes": [ + "functional", + "datatype" + ], + "id": "152" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#maxHeight", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "134", + "description": { + "undefined": "Maximum Height." + }, + "label": { + "IRI-based": "maxHeight" + }, + "domain": "21", + "attributes": [ + "functional", + "datatype" + ], + "id": "154" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasDisability", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "83", + "description": { + "undefined": "A person might have a disability." + }, + "label": { + "IRI-based": "hasDisability" + }, + "domain": "27", + "attributes": [ + "object" + ], + "id": "159" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#dependsOn", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "41", + "description": { + "undefined": "The completion of a Task might depend on another Task, as several Tasks are part of a Scenario." + }, + "label": { + "IRI-based": "dependsOn" + }, + "domain": "41", + "attributes": [ + "object" + ], + "id": "160" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#mainPoint", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "131", + "description": { + "undefined": "Main points are specific elements to each persona category." + }, + "label": { + "IRI-based": "mainPoint" + }, + "domain": "27", + "attributes": [ + "datatype" + ], + "id": "162" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasContext", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "45", + "description": { + "undefined": "A scenario is characterized by a certain context." + }, + "label": { + "IRI-based": "hasContext" + }, + "domain": "46", + "attributes": [ + "object" + ], + "id": "47" + }, + { + "range": "133", + "domain": "132", + "attributes": [ + "object", + "anonymous" + ], + "id": "168" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#influences", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "71", + "description": { + "undefined": "The personality influences the affective state o a person." + }, + "label": { + "IRI-based": "influences" + }, + "domain": "70", + "attributes": [ + "object", + "someValues" + ], + "id": "169" + }, + { + "range": "30", + "domain": "70", + "attributes": [ + "object", + "anonymous" + ], + "id": "171" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#age", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "167", + "description": { + "undefined": "Age of a person." + }, + "label": { + "IRI-based": "age" + }, + "domain": "27", + "attributes": [ + "functional", + "datatype" + ], + "id": "172" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#minFeetSize", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "122", + "description": { + "undefined": "Minimum Feet Size." + }, + "label": { + "IRI-based": "minFeetSize" + }, + "domain": "21", + "attributes": [ + "functional", + "datatype" + ], + "id": "173" + }, + { + "range": "27", + "domain": "30", + "attributes": [ + "object", + "anonymous" + ], + "id": "174" + }, + { + "range": "30", + "domain": "125", + "attributes": [ + "object", + "anonymous" + ], + "id": "175" + }, + { + "range": "71", + "domain": "146", + "attributes": [ + "object", + "anonymous" + ], + "id": "176" + }, + { + "range": "45", + "domain": "88", + "attributes": [ + "object", + "anonymous" + ], + "id": "177" + }, + { + "range": "83", + "domain": "46", + "attributes": [ + "object", + "anonymous" + ], + "id": "178" + }, + { + "range": "45", + "domain": "164", + "attributes": [ + "object", + "anonymous" + ], + "id": "179" + }, + { + "range": "9", + "domain": "83", + "attributes": [ + "object", + "anonymous" + ], + "id": "180" + }, + { + "range": "45", + "domain": "156", + "attributes": [ + "object", + "anonymous" + ], + "id": "181" + }, + { + "range": "25", + "domain": "83", + "attributes": [ + "object", + "anonymous" + ], + "id": "182" + }, + { + "range": "45", + "domain": "148", + "attributes": [ + "object", + "anonymous" + ], + "id": "183" + }, + { + "range": "41", + "domain": "83", + "attributes": [ + "object", + "anonymous" + ], + "id": "184" + }, + { + "range": "27", + "domain": "21", + "attributes": [ + "object", + "anonymous" + ], + "id": "185" + }, + { + "range": "83", + "domain": "125", + "attributes": [ + "object", + "anonymous" + ], + "id": "186" + }, + { + "range": "27", + "domain": "54", + "attributes": [ + "object", + "anonymous" + ], + "id": "187" + }, + { + "range": "30", + "domain": "83", + "attributes": [ + "object", + "anonymous" + ], + "id": "188" + }, + { + "range": "24", + "domain": "190", + "attributes": [ + "object", + "anonymous" + ], + "id": "189" + }, + { + "range": "70", + "domain": "83", + "attributes": [ + "object", + "anonymous" + ], + "id": "191" + }, + { + "range": "24", + "domain": "62", + "attributes": [ + "object", + "anonymous" + ], + "id": "192" + }, + { + "range": "27", + "domain": "83", + "attributes": [ + "object", + "anonymous" + ], + "id": "193" + }, + { + "range": "24", + "domain": "60", + "attributes": [ + "object", + "anonymous" + ], + "id": "194" + }, + { + "range": "71", + "domain": "145", + "attributes": [ + "object", + "anonymous" + ], + "id": "195" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#status", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "119", + "description": { + "undefined": "Marital status or a person." + }, + "label": { + "IRI-based": "status" + }, + "domain": "71", + "attributes": [ + "functional", + "datatype" + ], + "id": "196" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#knows", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "27", + "description": { + "undefined": "A person knows another person (similar to FOAF ontology)." + }, + "label": { + "IRI-based": "knows" + }, + "domain": "27", + "attributes": [ + "object" + ], + "id": "197" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#interactionCount", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "147", + "description": { + "undefined": "A count of specific user actions (comments, facebook likes, tweets, etc.)." + }, + "label": { + "IRI-based": "interactionCount" + }, + "domain": "133", + "attributes": [ + "datatype" + ], + "id": "198" + }, + { + "range": "45", + "domain": "41", + "attributes": [ + "object", + "anonymous" + ], + "id": "199" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#tagline", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "120", + "description": { + "undefined": "A tagline specific to a persona." + }, + "label": { + "IRI-based": "tagline" + }, + "domain": "21", + "attributes": [ + "functional", + "datatype" + ], + "id": "200" + }, + { + "range": "45", + "domain": "46", + "attributes": [ + "object", + "anonymous" + ], + "id": "201" + }, + { + "range": "45", + "domain": "25", + "attributes": [ + "object", + "anonymous" + ], + "id": "202" + }, + { + "range": "125", + "domain": "135", + "attributes": [ + "object", + "anonymous" + ], + "id": "203" + }, + { + "range": "27", + "domain": "45", + "attributes": [ + "object", + "anonymous" + ], + "id": "204" + }, + { + "range": "125", + "domain": "136", + "attributes": [ + "object", + "anonymous" + ], + "id": "205" + }, + { + "range": "45", + "domain": "125", + "attributes": [ + "object", + "anonymous" + ], + "id": "206" + }, + { + "range": "125", + "domain": "137", + "attributes": [ + "object", + "anonymous" + ], + "id": "207" + }, + { + "range": "45", + "domain": "9", + "attributes": [ + "object", + "anonymous" + ], + "id": "208" + }, + { + "range": "125", + "domain": "138", + "attributes": [ + "object", + "anonymous" + ], + "id": "209" + }, + { + "range": "45", + "domain": "70", + "attributes": [ + "object", + "anonymous" + ], + "id": "210" + }, + { + "range": "125", + "domain": "139", + "attributes": [ + "object", + "anonymous" + ], + "id": "211" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#isPartOfTest", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "25", + "description": { + "undefined": "Usability tests have participants (observers and users), tasks and a scenario." + }, + "label": { + "IRI-based": "isPartOfTest" + }, + "domain": "166", + "attributes": [ + "object" + ], + "id": "212" + }, + { + "range": "25", + "domain": "71", + "attributes": [ + "object", + "anonymous" + ], + "id": "213" + }, + { + "range": "125", + "domain": "140", + "attributes": [ + "object", + "anonymous" + ], + "id": "214" + }, + { + "range": "125", + "domain": "126", + "attributes": [ + "object", + "anonymous" + ], + "id": "215" + }, + { + "range": "30", + "domain": "45", + "attributes": [ + "object", + "anonymous" + ], + "id": "216" + }, + { + "range": "125", + "domain": "141", + "attributes": [ + "object", + "anonymous" + ], + "id": "217" + }, + { + "range": "45", + "domain": "83", + "attributes": [ + "object", + "anonymous" + ], + "id": "218" + }, + { + "range": "71", + "domain": "144", + "attributes": [ + "object", + "anonymous" + ], + "id": "219" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasEndGoal", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "89", + "label": { + "IRI-based": "hasEndGoal" + }, + "superproperty": [ + "19" + ], + "domain": "221", + "attributes": [ + "object" + ], + "id": "220" + }, + { + "range": "9", + "domain": "46", + "attributes": [ + "object", + "anonymous" + ], + "id": "222" + }, + { + "range": "41", + "domain": "132", + "attributes": [ + "object", + "anonymous" + ], + "id": "223" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasPersonality", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "70", + "description": { + "undefined": "A person has a certain personality corresponding to Myers Briggs personality classification." + }, + "label": { + "IRI-based": "hasPersonality" + }, + "domain": "27", + "attributes": [ + "object" + ], + "id": "224" + }, + { + "range": "41", + "domain": "133", + "attributes": [ + "object", + "anonymous" + ], + "id": "225" + }, + { + "range": "25", + "domain": "9", + "attributes": [ + "object", + "anonymous" + ], + "id": "226" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#birthday", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "155", + "description": { + "undefined": "Date of birth of a person." + }, + "label": { + "IRI-based": "birthday" + }, + "domain": "27", + "attributes": [ + "datatype" + ], + "id": "227" + }, + { + "range": "41", + "domain": "9", + "attributes": [ + "object", + "anonymous" + ], + "id": "228" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasInfluence", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "170", + "description": { + "undefined": "The disability of a person migh have an effect on the affective state or personality on the person." + }, + "label": { + "IRI-based": "hasInfluence" + }, + "domain": "83", + "attributes": [ + "object" + ], + "id": "229" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#gender", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "143", + "description": { + "undefined": "Gender of a person." + }, + "label": { + "IRI-based": "gender" + }, + "domain": "27", + "attributes": [ + "functional", + "datatype" + ], + "id": "230" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#userRole", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "109", + "description": { + "undefined": "The role of the user in the application/product." + }, + "label": { + "IRI-based": "userRole" + }, + "domain": "54", + "attributes": [ + "datatype" + ], + "id": "231" + }, + { + "range": "70", + "domain": "46", + "attributes": [ + "object", + "anonymous" + ], + "id": "232" + }, + { + "range": "30", + "domain": "18", + "attributes": [ + "object", + "anonymous" + ], + "id": "233" + }, + { + "range": "70", + "domain": "9", + "attributes": [ + "object", + "anonymous" + ], + "id": "234" + }, + { + "range": "30", + "domain": "89", + "attributes": [ + "object", + "anonymous" + ], + "id": "235" + }, + { + "range": "25", + "domain": "70", + "attributes": [ + "object", + "anonymous" + ], + "id": "236" + }, + { + "range": "30", + "domain": "98", + "attributes": [ + "object", + "anonymous" + ], + "id": "237" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#involvedIn", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "165", + "description": { + "undefined": "A participant (a certain user or observer) is involvedIn a scenario or Usability Test." + }, + "label": { + "IRI-based": "involvedIn" + }, + "domain": "54", + "attributes": [ + "object" + ], + "id": "238" + }, + { + "range": "41", + "domain": "70", + "attributes": [ + "object", + "anonymous" + ], + "id": "239" + }, + { + "range": "30", + "domain": "55", + "attributes": [ + "object", + "anonymous" + ], + "id": "240" + }, + { + "range": "27", + "domain": "46", + "attributes": [ + "object", + "anonymous" + ], + "id": "241" + }, + { + "range": "30", + "domain": "29", + "attributes": [ + "object", + "anonymous" + ], + "id": "242" + }, + { + "range": "27", + "domain": "9", + "attributes": [ + "object", + "anonymous" + ], + "id": "243" + }, + { + "range": "9", + "domain": "8", + "attributes": [ + "object", + "anonymous" + ], + "id": "244" + }, + { + "range": "27", + "domain": "25", + "attributes": [ + "object", + "anonymous" + ], + "id": "245" + }, + { + "range": "9", + "domain": "37", + "attributes": [ + "object", + "anonymous" + ], + "id": "246" + }, + { + "range": "27", + "domain": "41", + "attributes": [ + "object", + "anonymous" + ], + "id": "247" + }, + { + "range": "9", + "domain": "13", + "attributes": [ + "object", + "anonymous" + ], + "id": "248" + }, + { + "range": "27", + "domain": "70", + "attributes": [ + "object", + "anonymous" + ], + "id": "249" + }, + { + "range": "25", + "domain": "125", + "attributes": [ + "object", + "anonymous" + ], + "id": "250" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#details", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "157", + "description": { + "undefined": "Any kind of details." + }, + "label": { + "IRI-based": "details" + }, + "domain": "252", + "attributes": [ + "functional", + "datatype" + ], + "id": "251" + }, + { + "range": "41", + "domain": "125", + "attributes": [ + "object", + "anonymous" + ], + "id": "253" + }, + { + "range": "70", + "domain": "125", + "attributes": [ + "object", + "anonymous" + ], + "id": "254" + }, + { + "range": "27", + "domain": "125", + "attributes": [ + "object", + "anonymous" + ], + "id": "255" + }, + { + "range": "46", + "domain": "125", + "attributes": [ + "object", + "anonymous" + ], + "id": "256" + }, + { + "range": "9", + "domain": "125", + "attributes": [ + "object", + "anonymous" + ], + "id": "257" + }, + { + "range": "30", + "domain": "46", + "attributes": [ + "object", + "anonymous" + ], + "id": "258" + }, + { + "range": "30", + "domain": "9", + "attributes": [ + "object", + "anonymous" + ], + "id": "259" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasPublications", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "8", + "description": { + "undefined": "A person (of academic, journalistic profession) has published several documents." + }, + "label": { + "IRI-based": "hasPublications" + }, + "domain": "27", + "attributes": [ + "object" + ], + "id": "260" + }, + { + "range": "30", + "domain": "25", + "attributes": [ + "object", + "anonymous" + ], + "id": "261" + }, + { + "range": "30", + "domain": "41", + "attributes": [ + "object", + "anonymous" + ], + "id": "262" + }, + { + "range": "140", + "domain": "138", + "attributes": [ + "object", + "anonymous" + ], + "id": "263" + }, + { + "range": "139", + "domain": "138", + "attributes": [ + "object", + "anonymous" + ], + "id": "264" + }, + { + "range": "126", + "domain": "135", + "attributes": [ + "object", + "anonymous" + ], + "id": "265" + }, + { + "range": "137", + "domain": "138", + "attributes": [ + "object", + "anonymous" + ], + "id": "266" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#performs", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "41", + "description": { + "undefined": "A person performs a task in the usability test or when using a product/application." + }, + "label": { + "IRI-based": "performs" + }, + "domain": "27", + "attributes": [ + "object" + ], + "id": "267" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#myerBriggs", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "117", + "description": { + "undefined": "Inspired by FOAF Myers Briggs personality classification which includes 16 4-letter textual codes." + }, + "label": { + "IRI-based": "myerBriggs" + }, + "domain": "70", + "attributes": [ + "functional", + "datatype" + ], + "id": "268" + }, + { + "range": "126", + "domain": "138", + "attributes": [ + "object", + "anonymous" + ], + "id": "269" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#sensorData", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "118", + "description": { + "undefined": "Data recieved from a sensor (could be a number, temperature, etc.)." + }, + "label": { + "IRI-based": "sensorData" + }, + "domain": "45", + "attributes": [ + "datatype" + ], + "id": "270" + }, + { + "range": "138", + "domain": "135", + "attributes": [ + "object", + "anonymous" + ], + "id": "271" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#includes", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "163", + "description": { + "undefined": "In order to describe context we consider the medium of interaction Tangible or Intangible which is included in a Place and/or Time." + }, + "label": { + "IRI-based": "includes" + }, + "domain": "161", + "attributes": [ + "object" + ], + "id": "272" + }, + { + "range": "136", + "domain": "137", + "attributes": [ + "object", + "anonymous" + ], + "id": "273" + }, + { + "range": "136", + "domain": "126", + "attributes": [ + "object", + "anonymous" + ], + "id": "274" + }, + { + "range": "136", + "domain": "135", + "attributes": [ + "object", + "anonymous" + ], + "id": "275" + }, + { + "range": "136", + "domain": "140", + "attributes": [ + "object", + "anonymous" + ], + "id": "276" + }, + { + "range": "136", + "domain": "139", + "attributes": [ + "object", + "anonymous" + ], + "id": "277" + }, + { + "range": "140", + "domain": "141", + "attributes": [ + "object", + "anonymous" + ], + "id": "278" + }, + { + "range": "139", + "domain": "141", + "attributes": [ + "object", + "anonymous" + ], + "id": "279" + }, + { + "range": "136", + "domain": "138", + "attributes": [ + "object", + "anonymous" + ], + "id": "280" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasPersonaType", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "24", + "description": { + "undefined": "The type of Persona: Primary, Secondary, Negative, Supplemental, Served or Customer." + }, + "label": { + "IRI-based": "hasPersonaType" + }, + "domain": "158", + "attributes": [ + "object" + ], + "id": "281" + }, + { + "range": "137", + "domain": "141", + "attributes": [ + "object", + "anonymous" + ], + "id": "282" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#minWaistSize", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "123", + "description": { + "undefined": "Minimum Waist Size." + }, + "label": { + "IRI-based": "minWaistSize" + }, + "domain": "21", + "attributes": [ + "functional", + "datatype" + ], + "id": "283" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasTask", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "41", + "description": { + "undefined": "A scenario has a set of tasks (or just one). (inverseproperty isTaskfor)" + }, + "label": { + "IRI-based": "hasTask" + }, + "domain": "46", + "attributes": [ + "object" + ], + "id": "284" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasAffiliation", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "125", + "description": { + "undefined": "A person might have a certain type of affiliation to an organization and might not be member of it." + }, + "label": { + "IRI-based": "hasAffiliation" + }, + "domain": "27", + "attributes": [ + "object" + ], + "id": "285" + }, + { + "range": "141", + "domain": "135", + "attributes": [ + "object", + "anonymous" + ], + "id": "286" + }, + { + "range": "141", + "domain": "138", + "attributes": [ + "object", + "anonymous" + ], + "id": "287" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasGoal", + "inverse": "58", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "30", + "description": { + "undefined": "A person might have one or more (short/long term) goals depending on the context." + }, + "label": { + "IRI-based": "hasGoal" + }, + "domain": "27", + "subproperty": [ + "220", + "16", + "115", + "96", + "150" + ], + "attributes": [ + "object" + ], + "id": "19" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#isTaskFor", + "inverse": "284", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "46", + "description": { + "undefined": "A certain task (or a series of tasks) is (are) part of a scenario." + }, + "label": { + "IRI-based": "isTaskFor" + }, + "domain": "41", + "attributes": [ + "object" + ], + "id": "288" + }, + { + "range": "126", + "domain": "141", + "attributes": [ + "object", + "anonymous" + ], + "id": "289" + }, + { + "range": "25", + "domain": "46", + "attributes": [ + "object", + "anonymous" + ], + "id": "290" + }, + { + "range": "41", + "domain": "46", + "attributes": [ + "object", + "anonymous" + ], + "id": "291" + }, + { + "range": "136", + "domain": "141", + "attributes": [ + "object", + "anonymous" + ], + "id": "292" + }, + { + "range": "41", + "domain": "25", + "attributes": [ + "object", + "anonymous" + ], + "id": "293" + }, + { + "range": "79", + "domain": "60", + "attributes": [ + "object", + "anonymous" + ], + "id": "294" + }, + { + "range": "79", + "domain": "62", + "attributes": [ + "object", + "anonymous" + ], + "id": "295" + }, + { + "range": "60", + "domain": "62", + "attributes": [ + "object", + "anonymous" + ], + "id": "296" + }, + { + "range": "23", + "domain": "79", + "attributes": [ + "object", + "anonymous" + ], + "id": "297" + }, + { + "range": "81", + "domain": "62", + "attributes": [ + "object", + "anonymous" + ], + "id": "298" + }, + { + "range": "81", + "domain": "23", + "attributes": [ + "object", + "anonymous" + ], + "id": "299" + }, + { + "range": "81", + "domain": "60", + "attributes": [ + "object", + "anonymous" + ], + "id": "300" + }, + { + "range": "83", + "domain": "71", + "attributes": [ + "object", + "anonymous" + ], + "id": "301" + }, + { + "range": "30", + "domain": "71", + "attributes": [ + "object", + "anonymous" + ], + "id": "302" + }, + { + "range": "125", + "domain": "71", + "attributes": [ + "object", + "anonymous" + ], + "id": "303" + }, + { + "range": "27", + "domain": "71", + "attributes": [ + "object", + "anonymous" + ], + "id": "304" + }, + { + "range": "70", + "domain": "71", + "attributes": [ + "object", + "anonymous" + ], + "id": "305" + }, + { + "range": "9", + "domain": "71", + "attributes": [ + "object", + "anonymous" + ], + "id": "306" + }, + { + "range": "46", + "domain": "71", + "attributes": [ + "object", + "anonymous" + ], + "id": "307" + }, + { + "range": "41", + "domain": "71", + "attributes": [ + "object", + "anonymous" + ], + "id": "308" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#influencedBy", + "inverse": "69", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "70", + "description": { + "undefined": "The affective state of a person is influenced by the personality of that person. (inverse property influences)" + }, + "label": { + "IRI-based": "influencedBy" + }, + "domain": "71", + "attributes": [ + "object", + "someValues" + ], + "id": "309" + }, + { + "range": "45", + "domain": "71", + "attributes": [ + "object", + "anonymous" + ], + "id": "310" + }, + { + "range": "190", + "domain": "60", + "attributes": [ + "object", + "anonymous" + ], + "id": "311" + }, + { + "range": "190", + "domain": "62", + "attributes": [ + "object", + "anonymous" + ], + "id": "312" + }, + { + "range": "81", + "domain": "79", + "attributes": [ + "object", + "anonymous" + ], + "id": "313" + }, + { + "range": "190", + "domain": "23", + "attributes": [ + "object", + "anonymous" + ], + "id": "314" + }, + { + "range": "140", + "domain": "137", + "attributes": [ + "object", + "anonymous" + ], + "id": "315" + }, + { + "range": "137", + "domain": "139", + "attributes": [ + "object", + "anonymous" + ], + "id": "316" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#maxWeight", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "121", + "description": { + "undefined": "Maximum Weight." + }, + "label": { + "IRI-based": "maxWeight" + }, + "domain": "21", + "attributes": [ + "functional", + "datatype" + ], + "id": "317" + }, + { + "range": "190", + "domain": "79", + "attributes": [ + "object", + "anonymous" + ], + "id": "318" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#hasAward", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "9", + "description": { + "undefined": "A person might have been awarded with some sort of distinction (depicted usually by a trophy or document)." + }, + "label": { + "IRI-based": "hasAward" + }, + "domain": "27", + "attributes": [ + "object" + ], + "id": "319" + }, + { + "range": "190", + "domain": "81", + "attributes": [ + "object", + "anonymous" + ], + "id": "320" + }, + { + "range": "140", + "domain": "139", + "attributes": [ + "object", + "anonymous" + ], + "id": "321" + }, + { + "range": "126", + "domain": "137", + "attributes": [ + "object", + "anonymous" + ], + "id": "322" + }, + { + "range": "126", + "domain": "140", + "attributes": [ + "object", + "anonymous" + ], + "id": "323" + }, + { + "range": "140", + "domain": "135", + "attributes": [ + "object", + "anonymous" + ], + "id": "324" + }, + { + "range": "139", + "domain": "135", + "attributes": [ + "object", + "anonymous" + ], + "id": "325" + }, + { + "range": "126", + "domain": "139", + "attributes": [ + "object", + "anonymous" + ], + "id": "326" + }, + { + "iri": "http://blankdots.com/open/personasonto.owl#technicalLevel", + "baseIri": "http://blankdots.com/open/personasonto.owl", + "range": "108", + "description": { + "undefined": "Reflects the technical level of a person." + }, + "label": { + "IRI-based": "technicalLevel" + }, + "domain": "27", + "comment": { + "undefined": "If a person has technical or programming skills it's relevant." + }, + "attributes": [ + "functional", + "datatype" + ], + "id": "327" + }, + { + "range": "137", + "domain": "135", + "attributes": [ + "object", + "anonymous" + ], + "id": "328" + } + ] +} \ No newline at end of file diff --git a/src/app/data/sioc.json b/src/app/data/sioc.json new file mode 100644 index 0000000000000000000000000000000000000000..04b9a7b217c84b12c7fe62f181ed1addfe7116e8 --- /dev/null +++ b/src/app/data/sioc.json @@ -0,0 +1,4373 @@ +{ + "_comment": "Created with OWL2VOWL (version 0.3.4), http://vowl.visualdataweb.org", + "header": { + "languages": [ + "en", + "undefined" + ], + "baseIris": [ + "http://www.w3.org/1999/02/22-rdf-syntax-ns", + "http://www.w3.org/2000/01/rdf-schema", + "http://purl.org/dc/terms", + "http://www.w3.org/2001/XMLSchema", + "http://www.w3.org/2004/03/trix/rdfg-1", + "http://xmlns.com/foaf/0.1", + "http://rdfs.org/sioc/ns" + ], + "iri": "http://rdfs.org/sioc/ns#", + "version": "Revision: 1.36", + "other": { + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "Revision: 1.36", + "type": "label" + } + ], + "seeAlso": [ + { + "identifier": "seeAlso", + "language": "undefined", + "value": "http://rdfs.org/sioc/spec", + "type": "iri" + } + ] + } + }, + "namespace": [], + "metrics": { + "classCount": 17, + "objectPropertyCount": 71, + "datatypePropertyCount": 27, + "individualCount": 1 + }, + "class": [ + { + "id": "6", + "type": "rdfs:Literal" + }, + { + "id": "7", + "type": "owl:Class" + }, + { + "id": "9", + "type": "owl:Class" + }, + { + "id": "26", + "type": "rdfs:Literal" + }, + { + "id": "27", + "type": "rdfs:Literal" + }, + { + "id": "28", + "type": "owl:Class" + }, + { + "id": "32", + "type": "rdfs:Literal" + }, + { + "id": "33", + "type": "rdfs:Literal" + }, + { + "id": "34", + "type": "rdfs:Literal" + }, + { + "id": "37", + "type": "rdfs:Literal" + }, + { + "id": "46", + "type": "rdfs:Literal" + }, + { + "id": "49", + "type": "rdfs:Literal" + }, + { + "id": "78", + "type": "owl:Thing" + }, + { + "id": "79", + "type": "owl:Thing" + }, + { + "id": "80", + "type": "rdfs:Literal" + }, + { + "id": "48", + "type": "owl:equivalentClass" + }, + { + "id": "25", + "type": "rdfs:Literal" + }, + { + "id": "19", + "type": "owl:Thing" + }, + { + "id": "57", + "type": "owl:Thing" + }, + { + "id": "54", + "type": "owl:Thing" + }, + { + "id": "93", + "type": "rdfs:Literal" + }, + { + "id": "94", + "type": "rdfs:Datatype" + }, + { + "id": "95", + "type": "rdfs:Literal" + }, + { + "id": "96", + "type": "rdfs:Literal" + }, + { + "id": "104", + "type": "rdfs:Datatype" + }, + { + "id": "106", + "type": "rdfs:Datatype" + }, + { + "id": "1", + "type": "owl:Class" + }, + { + "id": "103", + "type": "rdfs:Datatype" + }, + { + "id": "111", + "type": "rdfs:Literal" + }, + { + "id": "112", + "type": "rdfs:Literal" + }, + { + "id": "113", + "type": "rdfs:Datatype" + }, + { + "id": "91", + "type": "rdfs:Literal" + }, + { + "id": "82", + "type": "rdfs:Literal" + }, + { + "id": "100", + "type": "rdfs:Literal" + }, + { + "id": "108", + "type": "rdfs:Literal" + }, + { + "id": "116", + "type": "rdfs:Literal" + }, + { + "id": "8", + "type": "owl:Class" + }, + { + "id": "66", + "type": "owl:Class" + }, + { + "id": "85", + "type": "owl:Class" + }, + { + "id": "39", + "type": "owl:Class" + }, + { + "id": "130", + "type": "owl:Class" + }, + { + "id": "42", + "type": "owl:equivalentClass" + }, + { + "id": "63", + "type": "owl:Class" + }, + { + "id": "67", + "type": "owl:Class" + }, + { + "id": "11", + "type": "owl:Thing" + }, + { + "id": "147", + "type": "rdfs:Literal" + }, + { + "id": "12", + "type": "owl:Class" + }, + { + "id": "45", + "type": "owl:Class" + }, + { + "id": "127", + "type": "owl:Class" + } + ], + "classAttribute": [ + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "6", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://rdfs.org/sioc/ns#Forum", + "baseIri": "http://rdfs.org/sioc/ns", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Forum", + "en": "Forum" + }, + "comment": { + "en": "A discussion area on which Posts or entries are made." + }, + "id": "7", + "superClasses": [ + "8" + ] + }, + { + "iri": "http://xmlns.com/foaf/0.1/Agent", + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "label": { + "IRI-based": "Agent" + }, + "attributes": [ + "external" + ], + "id": "9" + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "26", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "27", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://rdfs.org/sioc/ns#Thread", + "baseIri": "http://rdfs.org/sioc/ns", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Thread", + "en": "Thread" + }, + "comment": { + "en": "A container for a series of threaded discussion Posts or Items." + }, + "id": "28", + "superClasses": [ + "8" + ] + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "32", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "33", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "34", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "37", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "46", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "49", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "78", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "79", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "80", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://rdfs.org/sioc/ns#User", + "equivalent": [ + "42" + ], + "baseIri": "http://rdfs.org/sioc/ns", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "This class is deprecated. Use sioc:UserAccount from the SIOC ontology instead.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "User", + "en": "User" + }, + "comment": { + "en": "UserAccount is now preferred. This is a deprecated class for a User in an online community site." + }, + "attributes": [ + "equivalent", + "deprecated" + ], + "id": "48", + "superClasses": [ + "85" + ] + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "25", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "19", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "57", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "54", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "93", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#nonNegativeInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "94", + "label": { + "IRI-based": "nonNegativeInteger" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "95", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "96", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#nonNegativeInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "104", + "label": { + "IRI-based": "nonNegativeInteger" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#nonNegativeInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "106", + "label": { + "IRI-based": "nonNegativeInteger" + } + }, + { + "iri": "http://rdfs.org/sioc/ns#Item", + "baseIri": "http://rdfs.org/sioc/ns", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Item", + "en": "Item" + }, + "subClasses": [ + "45" + ], + "comment": { + "en": "An Item is something which can be in a Container." + }, + "id": "1" + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#nonNegativeInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "103", + "label": { + "IRI-based": "nonNegativeInteger" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "111", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "112", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2001/XMLSchema#nonNegativeInteger", + "baseIri": "http://www.w3.org/2001/XMLSchema", + "id": "113", + "label": { + "IRI-based": "nonNegativeInteger" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "91", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "82", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "100", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "108", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "baseIri": "http://www.w3.org/2000/01/rdf-schema", + "id": "116", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://rdfs.org/sioc/ns#Container", + "baseIri": "http://rdfs.org/sioc/ns", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Container", + "en": "Container" + }, + "subClasses": [ + "7", + "28" + ], + "comment": { + "en": "An area in which content Items are contained." + }, + "id": "8" + }, + { + "iri": "http://rdfs.org/sioc/ns#Role", + "baseIri": "http://rdfs.org/sioc/ns", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Role", + "en": "Role" + }, + "comment": { + "en": "A Role is a function of a UserAccount within a scope of a particular Forum, Site, etc." + }, + "id": "66" + }, + { + "iri": "http://xmlns.com/foaf/0.1/OnlineAccount", + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "label": { + "IRI-based": "OnlineAccount" + }, + "subClasses": [ + "42", + "48" + ], + "attributes": [ + "external" + ], + "id": "85" + }, + { + "iri": "http://rdfs.org/sioc/ns#Usergroup", + "baseIri": "http://rdfs.org/sioc/ns", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Usergroup", + "en": "Usergroup" + }, + "comment": { + "en": "A set of UserAccounts whose owners have a common purpose or interest. Can be used for access control purposes." + }, + "id": "39" + }, + { + "iri": "http://rdfs.org/sioc/ns#Community", + "baseIri": "http://rdfs.org/sioc/ns", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Community", + "en": "Community" + }, + "comment": { + "en": "Community is a high-level concept that defines an online community and what it consists of." + }, + "id": "130" + }, + { + "iri": "http://rdfs.org/sioc/ns#UserAccount", + "equivalent": [ + "48" + ], + "baseIri": "http://rdfs.org/sioc/ns", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "UserAccount", + "en": "User Account" + }, + "comment": { + "en": "A user account in an online community site." + }, + "attributes": [ + "equivalent" + ], + "id": "42", + "superClasses": [ + "85" + ] + }, + { + "iri": "http://www.w3.org/2004/03/trix/rdfg-1/Graph", + "baseIri": "http://www.w3.org/2004/03/trix/rdfg-1", + "instances": 0, + "label": { + "IRI-based": "Graph" + }, + "attributes": [ + "external" + ], + "id": "63" + }, + { + "iri": "http://rdfs.org/sioc/ns#Site", + "baseIri": "http://rdfs.org/sioc/ns", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Site", + "en": "Site" + }, + "comment": { + "en": "A Site can be the location of an online community or set of communities, with UserAccounts and Usergroups creating Items in a set of Containers. It can be thought of as a web-accessible data Space." + }, + "id": "67", + "superClasses": [ + "12" + ] + }, + { + "iri": "http://www.w3.org/2002/07/owl#Thing", + "baseIri": "http://owl2vowl.de", + "id": "11", + "label": { + "undefined": "Thing" + } + }, + { + "iri": "http://www.w3.org/2000/01/rdf-schema#Literal", + "id": "147", + "label": { + "IRI-based": "Literal", + "undefined": "Literal" + } + }, + { + "iri": "http://rdfs.org/sioc/ns#Space", + "baseIri": "http://rdfs.org/sioc/ns", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Space", + "en": "Space" + }, + "subClasses": [ + "67" + ], + "comment": { + "en": "A Space is a place where data resides, e.g. on a website, desktop, fileshare, etc." + }, + "id": "12" + }, + { + "iri": "http://rdfs.org/sioc/ns#Post", + "baseIri": "http://rdfs.org/sioc/ns", + "instances": 0, + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "Post", + "en": "Post" + }, + "comment": { + "en": "An article or message that can be posted to a Forum." + }, + "id": "45", + "superClasses": [ + "127", + "1" + ] + }, + { + "iri": "http://xmlns.com/foaf/0.1/Document", + "baseIri": "http://xmlns.com/foaf/0.1", + "instances": 0, + "label": { + "IRI-based": "Document" + }, + "subClasses": [ + "45" + ], + "attributes": [ + "external" + ], + "id": "127" + } + ], + "property": [ + { + "id": "0", + "type": "owl:objectProperty" + }, + { + "id": "3", + "type": "owl:objectProperty" + }, + { + "id": "10", + "type": "owl:objectProperty" + }, + { + "id": "16", + "type": "owl:objectProperty" + }, + { + "id": "18", + "type": "owl:objectProperty" + }, + { + "id": "21", + "type": "owl:objectProperty" + }, + { + "id": "24", + "type": "owl:datatypeProperty" + }, + { + "id": "22", + "type": "owl:objectProperty" + }, + { + "id": "14", + "type": "owl:objectProperty" + }, + { + "id": "30", + "type": "owl:objectProperty" + }, + { + "id": "35", + "type": "owl:objectProperty" + }, + { + "id": "38", + "type": "owl:objectProperty" + }, + { + "id": "41", + "type": "owl:disjointWith" + }, + { + "id": "29", + "type": "owl:objectProperty" + }, + { + "id": "44", + "type": "owl:datatypeProperty" + }, + { + "id": "47", + "type": "owl:disjointWith" + }, + { + "id": "40", + "type": "owl:objectProperty" + }, + { + "id": "50", + "type": "owl:objectProperty" + }, + { + "id": "52", + "type": "owl:datatypeProperty" + }, + { + "id": "53", + "type": "owl:objectProperty" + }, + { + "id": "56", + "type": "owl:objectProperty" + }, + { + "id": "58", + "type": "owl:disjointWith" + }, + { + "id": "59", + "type": "owl:objectProperty" + }, + { + "id": "60", + "type": "owl:disjointWith" + }, + { + "id": "5", + "type": "owl:objectProperty" + }, + { + "id": "62", + "type": "owl:objectProperty" + }, + { + "id": "64", + "type": "owl:disjointWith" + }, + { + "id": "65", + "type": "owl:disjointWith" + }, + { + "id": "15", + "type": "owl:objectProperty" + }, + { + "id": "69", + "type": "owl:disjointWith" + }, + { + "id": "70", + "type": "owl:disjointWith" + }, + { + "id": "4", + "type": "owl:objectProperty" + }, + { + "id": "71", + "type": "owl:disjointWith" + }, + { + "id": "72", + "type": "owl:disjointWith" + }, + { + "id": "73", + "type": "owl:objectProperty" + }, + { + "id": "75", + "type": "owl:disjointWith" + }, + { + "id": "76", + "type": "owl:disjointWith" + }, + { + "id": "77", + "type": "owl:objectProperty" + }, + { + "id": "81", + "type": "owl:datatypeProperty" + }, + { + "id": "83", + "type": "owl:objectProperty" + }, + { + "id": "84", + "type": "owl:objectProperty" + }, + { + "id": "86", + "type": "owl:datatypeProperty" + }, + { + "id": "87", + "type": "owl:objectProperty" + }, + { + "id": "88", + "type": "owl:objectProperty" + }, + { + "id": "89", + "type": "owl:datatypeProperty" + }, + { + "id": "90", + "type": "owl:datatypeProperty" + }, + { + "id": "92", + "type": "owl:datatypeProperty" + }, + { + "id": "55", + "type": "owl:objectProperty" + }, + { + "id": "97", + "type": "owl:objectProperty" + }, + { + "id": "99", + "type": "owl:datatypeProperty" + }, + { + "id": "101", + "type": "owl:objectProperty" + }, + { + "id": "102", + "type": "owl:datatypeProperty" + }, + { + "id": "105", + "type": "owl:objectProperty" + }, + { + "id": "107", + "type": "owl:datatypeProperty" + }, + { + "id": "109", + "type": "owl:objectProperty" + }, + { + "id": "110", + "type": "owl:objectProperty" + }, + { + "id": "98", + "type": "owl:objectProperty" + }, + { + "id": "68", + "type": "owl:objectProperty" + }, + { + "id": "114", + "type": "owl:datatypeProperty" + }, + { + "id": "115", + "type": "owl:objectProperty" + }, + { + "id": "117", + "type": "owl:objectProperty" + }, + { + "id": "119", + "type": "owl:datatypeProperty" + }, + { + "id": "23", + "type": "owl:objectProperty" + }, + { + "id": "120", + "type": "owl:objectProperty" + }, + { + "id": "121", + "type": "owl:datatypeProperty" + }, + { + "id": "122", + "type": "owl:objectProperty" + }, + { + "id": "124", + "type": "owl:objectProperty" + }, + { + "id": "125", + "type": "owl:datatypeProperty" + }, + { + "id": "126", + "type": "rdfs:SubClassOf" + }, + { + "id": "128", + "type": "rdfs:SubClassOf" + }, + { + "id": "129", + "type": "owl:datatypeProperty" + }, + { + "id": "131", + "type": "owl:objectProperty" + }, + { + "id": "133", + "type": "owl:objectProperty" + }, + { + "id": "134", + "type": "owl:datatypeProperty" + }, + { + "id": "135", + "type": "owl:objectProperty" + }, + { + "id": "137", + "type": "owl:datatypeProperty" + }, + { + "id": "138", + "type": "owl:objectProperty" + }, + { + "id": "139", + "type": "owl:objectProperty" + }, + { + "id": "140", + "type": "owl:datatypeProperty" + }, + { + "id": "141", + "type": "owl:datatypeProperty" + }, + { + "id": "123", + "type": "owl:objectProperty" + }, + { + "id": "142", + "type": "owl:datatypeProperty" + }, + { + "id": "143", + "type": "owl:objectProperty" + }, + { + "id": "144", + "type": "rdfs:SubClassOf" + }, + { + "id": "145", + "type": "rdfs:SubClassOf" + }, + { + "id": "146", + "type": "owl:datatypeProperty" + }, + { + "id": "148", + "type": "rdfs:SubClassOf" + }, + { + "id": "149", + "type": "rdfs:SubClassOf" + }, + { + "id": "150", + "type": "rdfs:SubClassOf" + }, + { + "id": "2", + "type": "owl:objectProperty" + }, + { + "id": "151", + "type": "owl:objectProperty" + }, + { + "id": "152", + "type": "owl:objectProperty" + }, + { + "id": "154", + "type": "owl:disjointWith" + }, + { + "id": "43", + "type": "owl:objectProperty" + }, + { + "id": "155", + "type": "owl:disjointWith" + }, + { + "id": "156", + "type": "owl:disjointWith" + }, + { + "id": "157", + "type": "owl:disjointWith" + }, + { + "id": "158", + "type": "owl:disjointWith" + }, + { + "id": "159", + "type": "owl:objectProperty" + }, + { + "id": "160", + "type": "owl:disjointWith" + }, + { + "id": "161", + "type": "owl:disjointWith" + }, + { + "id": "162", + "type": "owl:disjointWith" + }, + { + "id": "163", + "type": "owl:datatypeProperty" + }, + { + "id": "17", + "type": "owl:objectProperty" + }, + { + "id": "153", + "type": "owl:objectProperty" + }, + { + "id": "164", + "type": "owl:objectProperty" + }, + { + "id": "165", + "type": "owl:disjointWith" + }, + { + "id": "166", + "type": "owl:disjointWith" + }, + { + "id": "132", + "type": "owl:objectProperty" + }, + { + "id": "167", + "type": "owl:objectProperty" + }, + { + "id": "20", + "type": "owl:objectProperty" + }, + { + "id": "51", + "type": "owl:objectProperty" + }, + { + "id": "168", + "type": "owl:objectProperty" + }, + { + "id": "169", + "type": "owl:datatypeProperty" + }, + { + "id": "61", + "type": "owl:objectProperty" + }, + { + "id": "170", + "type": "owl:objectProperty" + }, + { + "id": "13", + "type": "owl:objectProperty" + }, + { + "id": "171", + "type": "owl:datatypeProperty" + }, + { + "id": "136", + "type": "owl:objectProperty" + }, + { + "id": "118", + "type": "owl:objectProperty" + }, + { + "id": "172", + "type": "owl:objectProperty" + }, + { + "id": "74", + "type": "owl:objectProperty" + }, + { + "id": "173", + "type": "owl:objectProperty" + }, + { + "id": "36", + "type": "owl:objectProperty" + }, + { + "id": "31", + "type": "owl:objectProperty" + } + ], + "propertyAttribute": [ + { + "iri": "http://rdfs.org/sioc/ns#previous_by_date", + "inverse": "2", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "previous_by_date", + "en": "previous by date" + }, + "domain": "1", + "comment": { + "en": "Previous Item or Post in a given Container sorted by date." + }, + "attributes": [ + "object" + ], + "id": "0" + }, + { + "iri": "http://rdfs.org/sioc/ns#later_version", + "inverse": "4", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "later_version", + "en": "later version" + }, + "domain": "1", + "subproperty": [ + "5" + ], + "comment": { + "en": "Links to a later (newer) revision of this Item or Post." + }, + "attributes": [ + "transitive", + "object" + ], + "id": "3" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_space", + "inverse": "13", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "12", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_space", + "en": "has space" + }, + "superproperty": [ + "14" + ], + "domain": "11", + "subproperty": [ + "15" + ], + "comment": { + "en": "A data Space which this resource is a part of." + }, + "attributes": [ + "object" + ], + "id": "10" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_parent", + "inverse": "17", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "8", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_parent", + "en": "has parent" + }, + "superproperty": [ + "14" + ], + "domain": "8", + "comment": { + "en": "A Container or Forum that this Container or Forum is a child of." + }, + "attributes": [ + "object" + ], + "id": "16" + }, + { + "iri": "http://rdfs.org/sioc/ns#part_of", + "inverse": "20", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "19", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "This property is deprecated. Use dcterms:isPartOf from the Dublin Core ontology instead.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "part_of", + "en": "part of" + }, + "domain": "19", + "comment": { + "en": "A resource that the subject is a part of." + }, + "attributes": [ + "object", + "deprecated" + ], + "id": "18" + }, + { + "iri": "http://rdfs.org/sioc/ns#reply_of", + "inverse": "22", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "reply_of", + "en": "reply of" + }, + "superproperty": [ + "23" + ], + "domain": "1", + "comment": { + "en": "Links to an Item or Post which this Item or Post is a reply to." + }, + "attributes": [ + "object" + ], + "id": "21" + }, + { + "iri": "http://purl.org/dc/terms/date", + "baseIri": "http://purl.org/dc/terms", + "range": "25", + "label": { + "IRI-based": "date" + }, + "domain": "19", + "attributes": [ + "datatype", + "external" + ], + "id": "24" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_reply", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_reply", + "en": "has reply" + }, + "superproperty": [ + "23" + ], + "domain": "1", + "comment": { + "en": "Points to an Item or Post that is a reply or response to this Item or Post." + }, + "attributes": [ + "object" + ], + "id": "22" + }, + { + "iri": "http://purl.org/dc/terms/partOf", + "baseIri": "http://purl.org/dc/terms", + "range": "19", + "label": { + "IRI-based": "partOf" + }, + "domain": "19", + "subproperty": [ + "10", + "29", + "16" + ], + "attributes": [ + "external", + "object" + ], + "id": "14" + }, + { + "iri": "http://purl.org/dc/terms/subject", + "baseIri": "http://purl.org/dc/terms", + "range": "19", + "label": { + "IRI-based": "subject" + }, + "domain": "19", + "subproperty": [ + "31" + ], + "attributes": [ + "external", + "object" + ], + "id": "30" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_group", + "inverse": "36", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "19", + "annotations": { + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "This property has been renamed. Use sioc:has_usergroup instead.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "has_group", + "en": "has group" + }, + "domain": "19", + "attributes": [ + "object", + "deprecated" + ], + "id": "35" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_usergroup", + "inverse": "40", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "39", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_usergroup", + "en": "has usergroup" + }, + "domain": "12", + "comment": { + "en": "Points to a Usergroup that has certain access to this Space." + }, + "attributes": [ + "object" + ], + "id": "38" + }, + { + "range": "42", + "domain": "39", + "attributes": [ + "anonymous", + "object" + ], + "id": "41" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_container", + "inverse": "43", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "8", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_container", + "en": "has container" + }, + "superproperty": [ + "14" + ], + "domain": "1", + "comment": { + "en": "The Container to which this Item belongs." + }, + "attributes": [ + "object" + ], + "id": "29" + }, + { + "iri": "http://rdfs.org/sioc/ns#content_encoded", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "46", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "This property is deprecated. Use content:encoded from the RSS 1.0 content module instead.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "content_encoded", + "en": "content encoded" + }, + "domain": "45", + "comment": { + "en": "The encoded content of the Post, contained in CDATA areas." + }, + "attributes": [ + "datatype", + "deprecated" + ], + "id": "44" + }, + { + "range": "48", + "domain": "39", + "attributes": [ + "anonymous", + "object" + ], + "id": "47" + }, + { + "iri": "http://rdfs.org/sioc/ns#usergroup_of", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "12", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "usergroup_of", + "en": "usergroup of" + }, + "domain": "39", + "comment": { + "en": "A Space that the Usergroup has access to." + }, + "attributes": [ + "object" + ], + "id": "40" + }, + { + "iri": "http://rdfs.org/sioc/ns#moderator_of", + "inverse": "51", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "7", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "moderator_of", + "en": "moderator of" + }, + "domain": "42", + "comment": { + "en": "A Forum that a UserAccount is a moderator of." + }, + "attributes": [ + "object" + ], + "id": "50" + }, + { + "iri": "http://rdfs.org/sioc/ns#id", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "26", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "id", + "en": "id" + }, + "domain": "19", + "comment": { + "en": "An identifier of a SIOC concept instance. For example, a user ID. Must be unique for instances of each type of SIOC concept within the same site." + }, + "attributes": [ + "datatype" + ], + "id": "52" + }, + { + "iri": "http://rdfs.org/sioc/ns#avatar", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "54", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "avatar", + "en": "avatar" + }, + "superproperty": [ + "55" + ], + "domain": "42", + "comment": { + "en": "An image or depiction used to represent this UserAccount." + }, + "attributes": [ + "object" + ], + "id": "53" + }, + { + "iri": "http://rdfs.org/sioc/ns#about", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "57", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "about", + "en": "about" + }, + "domain": "1", + "comment": { + "en": "Specifies that this Item is about a particular resource, e.g. a Post describing a book, hotel, etc." + }, + "attributes": [ + "object" + ], + "id": "56" + }, + { + "range": "48", + "domain": "12", + "attributes": [ + "anonymous", + "object" + ], + "id": "58" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_member", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "42", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_member", + "en": "has member" + }, + "domain": "39", + "comment": { + "en": "A UserAccount that is a member of this Usergroup." + }, + "attributes": [ + "object" + ], + "id": "59" + }, + { + "range": "12", + "domain": "39", + "attributes": [ + "anonymous", + "object" + ], + "id": "60" + }, + { + "iri": "http://rdfs.org/sioc/ns#next_version", + "inverse": "61", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "next_version", + "en": "next version" + }, + "superproperty": [ + "3" + ], + "domain": "1", + "comment": { + "en": "Links to the next revision of this Item or Post." + }, + "attributes": [ + "object" + ], + "id": "5" + }, + { + "iri": "http://rdfs.org/sioc/ns#embeds_knowledge", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "63", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "embeds_knowledge", + "en": "embeds knowledge" + }, + "domain": "1", + "comment": { + "en": "This links Items to embedded statements, facts and structured content." + }, + "attributes": [ + "object" + ], + "id": "62" + }, + { + "range": "12", + "domain": "42", + "attributes": [ + "anonymous", + "object" + ], + "id": "64" + }, + { + "range": "66", + "domain": "12", + "attributes": [ + "anonymous", + "object" + ], + "id": "65" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_host", + "inverse": "68", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "67", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_host", + "en": "has host" + }, + "superproperty": [ + "10" + ], + "domain": "8", + "comment": { + "en": "The Site that hosts this Container." + }, + "attributes": [ + "object" + ], + "id": "15" + }, + { + "range": "66", + "domain": "39", + "attributes": [ + "anonymous", + "object" + ], + "id": "69" + }, + { + "range": "48", + "domain": "66", + "attributes": [ + "anonymous", + "object" + ], + "id": "70" + }, + { + "iri": "http://rdfs.org/sioc/ns#earlier_version", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "earlier_version", + "en": "earlier version" + }, + "domain": "1", + "subproperty": [ + "61" + ], + "comment": { + "en": "Links to a previous (older) revision of this Item or Post." + }, + "attributes": [ + "transitive", + "object" + ], + "id": "4" + }, + { + "range": "66", + "domain": "42", + "attributes": [ + "anonymous", + "object" + ], + "id": "71" + }, + { + "range": "1", + "domain": "39", + "attributes": [ + "anonymous", + "object" + ], + "id": "72" + }, + { + "iri": "http://rdfs.org/sioc/ns#owner_of", + "inverse": "74", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "54", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "owner_of", + "en": "owner of" + }, + "domain": "42", + "comment": { + "en": "A resource owned by a particular UserAccount, for example, a weblog or image gallery." + }, + "attributes": [ + "object" + ], + "id": "73" + }, + { + "range": "1", + "domain": "12", + "attributes": [ + "anonymous", + "object" + ], + "id": "75" + }, + { + "range": "1", + "domain": "66", + "attributes": [ + "anonymous", + "object" + ], + "id": "76" + }, + { + "iri": "http://rdfs.org/sioc/ns#shared_by", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "42", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "seeAlso": [ + { + "identifier": "seeAlso", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#sibling", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "shared_by", + "en": "shared by" + }, + "domain": "1", + "comment": { + "en": "For shared Items where there is a certain creator_of and an intermediary who shares or forwards it (e.g. as a sibling Item)." + }, + "attributes": [ + "object" + ], + "id": "77" + }, + { + "iri": "http://rdfs.org/sioc/ns#last_item_date", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "82", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "last_item_date", + "en": "last item date" + }, + "domain": "8", + "comment": { + "en": "The date and time of the last Post (or Item) in a Forum (or a Container), in ISO 8601 format." + }, + "attributes": [ + "datatype" + ], + "id": "81" + }, + { + "iri": "http://rdfs.org/sioc/ns#delivered_at", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "57", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "delivered_at", + "en": "delivered at" + }, + "domain": "1", + "comment": { + "en": "When this was delivered, in ISO 8601 format." + }, + "attributes": [ + "object" + ], + "id": "83" + }, + { + "iri": "http://rdfs.org/sioc/ns#attachment", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "57", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "attachment", + "en": "attachment" + }, + "domain": "1", + "comment": { + "en": "The URI of a file attached to an Item." + }, + "attributes": [ + "object" + ], + "id": "84" + }, + { + "iri": "http://rdfs.org/sioc/ns#description", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "37", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "This property is deprecated. Use sioc:content or other methods (AtomOwl, content:encoded from RSS 1.0, etc.) instead.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "description", + "en": "description" + }, + "domain": "45", + "comment": { + "en": "The content of the Post." + }, + "attributes": [ + "datatype", + "deprecated" + ], + "id": "86" + }, + { + "iri": "http://rdfs.org/sioc/ns#link", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "19", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "link", + "en": "link" + }, + "domain": "19", + "comment": { + "en": "A URI of a document which contains this SIOC object." + }, + "attributes": [ + "object" + ], + "id": "87" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_administrator", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "42", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_administrator", + "en": "has administrator" + }, + "domain": "67", + "comment": { + "en": "A UserAccount that is an administrator of this Site." + }, + "attributes": [ + "object" + ], + "id": "88" + }, + { + "iri": "http://rdfs.org/sioc/ns#content", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "49", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "content", + "en": "content" + }, + "domain": "1", + "comment": { + "en": "The content of the Item in plain text format." + }, + "attributes": [ + "datatype" + ], + "id": "89" + }, + { + "iri": "http://rdfs.org/sioc/ns#note", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "91", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "note", + "en": "note" + }, + "domain": "19", + "comment": { + "en": "A note associated with this resource, for example, if it has been edited by a UserAccount." + }, + "attributes": [ + "datatype" + ], + "id": "90" + }, + { + "iri": "http://rdfs.org/sioc/ns#email_sha1", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "34", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "email_sha1", + "en": "email sha1" + }, + "domain": "42", + "comment": { + "en": "An electronic mail address of the UserAccount, encoded using SHA1." + }, + "attributes": [ + "datatype" + ], + "id": "92" + }, + { + "iri": "http://xmlns.com/foaf/0.1/depiction", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "19", + "label": { + "IRI-based": "depiction" + }, + "domain": "19", + "subproperty": [ + "53" + ], + "attributes": [ + "external", + "object" + ], + "id": "55" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_modifier", + "inverse": "98", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "42", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_modifier", + "en": "has modifier" + }, + "domain": "54", + "comment": { + "en": "A UserAccount that modified this resource (e.g. Item, Container, Space)." + }, + "attributes": [ + "object" + ], + "id": "97" + }, + { + "iri": "http://rdfs.org/sioc/ns#last_activity_date", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "100", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "last_activity_date", + "en": "last activity date" + }, + "domain": "19", + "comment": { + "en": "The date and time of the last activity associated with a SIOC concept instance, and expressed in ISO 8601 format. This could be due to a reply Post or Comment, a modification to an Item, etc." + }, + "attributes": [ + "datatype" + ], + "id": "99" + }, + { + "iri": "http://rdfs.org/sioc/ns#follows", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "42", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "follows", + "en": "follows" + }, + "domain": "42", + "comment": { + "en": "Indicates that one UserAccount follows another UserAccount (e.g. for microblog posts or other content item updates)." + }, + "attributes": [ + "object" + ], + "id": "101" + }, + { + "iri": "http://rdfs.org/sioc/ns#num_items", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "103", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "num_items", + "en": "num items" + }, + "domain": "8", + "comment": { + "en": "The number of Posts (or Items) in a Forum (or a Container)." + }, + "attributes": [ + "datatype" + ], + "id": "102" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_function", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "66", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_function", + "en": "has function" + }, + "domain": "78", + "comment": { + "en": "A Role that this UserAccount has." + }, + "attributes": [ + "object" + ], + "id": "105" + }, + { + "iri": "http://rdfs.org/sioc/ns#last_reply_date", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "108", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "last_reply_date", + "en": "last reply date" + }, + "domain": "19", + "comment": { + "en": "The date and time of the last reply Post or Comment, which could be associated with a starter Item or Post or with a Thread, and expressed in ISO 8601 format." + }, + "attributes": [ + "datatype" + ], + "id": "107" + }, + { + "iri": "http://rdfs.org/sioc/ns#email", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "54", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "email", + "en": "email" + }, + "domain": "42", + "comment": { + "en": "An electronic mail address of the UserAccount." + }, + "attributes": [ + "object" + ], + "id": "109" + }, + { + "iri": "http://xmlns.com/foaf/0.1/account", + "baseIri": "http://xmlns.com/foaf/0.1", + "range": "19", + "label": { + "IRI-based": "account" + }, + "domain": "19", + "attributes": [ + "external", + "object" + ], + "id": "110" + }, + { + "iri": "http://rdfs.org/sioc/ns#modifier_of", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "54", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "modifier_of", + "en": "modifier of" + }, + "domain": "42", + "comment": { + "en": "A resource that this UserAccount has modified." + }, + "attributes": [ + "object" + ], + "id": "98" + }, + { + "iri": "http://rdfs.org/sioc/ns#host_of", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "8", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "host_of", + "en": "host of" + }, + "superproperty": [ + "13" + ], + "domain": "67", + "comment": { + "en": "A Container that is hosted on this Site." + }, + "attributes": [ + "object" + ], + "id": "68" + }, + { + "iri": "http://purl.org/dc/terms/title", + "baseIri": "http://purl.org/dc/terms", + "range": "80", + "label": { + "IRI-based": "title" + }, + "domain": "19", + "attributes": [ + "datatype", + "external" + ], + "id": "114" + }, + { + "iri": "http://rdfs.org/sioc/ns#account_of", + "inverse": "110", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "9", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "account_of", + "en": "account of" + }, + "domain": "42", + "comment": { + "en": "Refers to the foaf:Agent or foaf:Person who owns this sioc:UserAccount." + }, + "attributes": [ + "object" + ], + "id": "115" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_subscriber", + "inverse": "118", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "42", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "seeAlso": [ + { + "identifier": "seeAlso", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#feed", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_subscriber", + "en": "has subscriber" + }, + "domain": "8", + "comment": { + "en": "A UserAccount that is subscribed to this Container." + }, + "attributes": [ + "object" + ], + "id": "117" + }, + { + "iri": "http://rdfs.org/sioc/ns#modified_at", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "112", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "This property is deprecated. Use dcterms:modified from the Dublin Core ontology instead.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "modified_at", + "en": "modified at" + }, + "domain": "45", + "comment": { + "en": "When this was modified, in ISO 8601 format." + }, + "attributes": [ + "datatype", + "deprecated" + ], + "id": "119" + }, + { + "iri": "http://rdfs.org/sioc/ns#related_to", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "19", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "related_to", + "en": "related to" + }, + "domain": "19", + "subproperty": [ + "21", + "22" + ], + "comment": { + "en": "Related resources for this resource, e.g. for Posts, perhaps determined implicitly from topics or references." + }, + "attributes": [ + "object" + ], + "id": "23" + }, + { + "iri": "http://rdfs.org/sioc/ns#administrator_of", + "inverse": "88", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "67", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "administrator_of", + "en": "administrator of" + }, + "domain": "42", + "comment": { + "en": "A Site that the UserAccount is an administrator of." + }, + "attributes": [ + "object" + ], + "id": "120" + }, + { + "iri": "http://rdfs.org/sioc/ns#subject", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "96", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "This property is deprecated. Use dcterms:subject from the Dublin Core ontology for text keywords and sioc:topic if the subject can be represented by a URI instead.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "subject", + "en": "subject" + }, + "domain": "45", + "comment": { + "en": "Keyword(s) describing subject of the Post." + }, + "attributes": [ + "datatype", + "deprecated" + ], + "id": "121" + }, + { + "iri": "http://purl.org/dc/terms/references", + "baseIri": "http://purl.org/dc/terms", + "range": "19", + "label": { + "IRI-based": "references" + }, + "domain": "19", + "subproperty": [ + "123" + ], + "attributes": [ + "external", + "object" + ], + "id": "122" + }, + { + "iri": "http://rdfs.org/sioc/ns#reference", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "79", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "Renamed to sioc:links_to.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "reference", + "en": "reference" + }, + "domain": "45", + "comment": { + "en": "Links either created explicitly or extracted implicitly on the HTML level from the Post." + }, + "attributes": [ + "object", + "deprecated" + ], + "id": "124" + }, + { + "iri": "http://rdfs.org/sioc/ns#last_name", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "116", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "This property is deprecated. Use foaf:name or foaf:surname from the FOAF vocabulary instead.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "last_name", + "en": "last name" + }, + "domain": "42", + "comment": { + "en": "Last (real) name of this user. Synonyms include surname or family name." + }, + "attributes": [ + "datatype", + "deprecated" + ], + "id": "125" + }, + { + "range": "127", + "domain": "45", + "attributes": [ + "anonymous", + "object" + ], + "id": "126" + }, + { + "range": "12", + "domain": "67", + "attributes": [ + "anonymous", + "object" + ], + "id": "128" + }, + { + "iri": "http://rdfs.org/sioc/ns#first_name", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "27", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "This property is deprecated. Use foaf:name or foaf:firstName from the FOAF vocabulary instead.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "first_name", + "en": "first name" + }, + "domain": "42", + "comment": { + "en": "First (real) name of this User. Synonyms include given name or christian name." + }, + "attributes": [ + "datatype", + "deprecated" + ], + "id": "129" + }, + { + "iri": "http://rdfs.org/sioc/ns#creator_of", + "inverse": "132", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "54", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "creator_of", + "en": "creator of" + }, + "domain": "42", + "comment": { + "en": "A resource that the UserAccount is a creator of." + }, + "attributes": [ + "object" + ], + "id": "131" + }, + { + "iri": "http://rdfs.org/sioc/ns#member_of", + "inverse": "59", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "39", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "member_of", + "en": "member of" + }, + "domain": "42", + "comment": { + "en": "A Usergroup that this UserAccount is a member of." + }, + "attributes": [ + "object" + ], + "id": "133" + }, + { + "iri": "http://rdfs.org/sioc/ns#num_authors", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "113", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "num_authors", + "en": "num authors" + }, + "domain": "19", + "comment": { + "en": "The number of unique authors (UserAccounts and unregistered posters) who have contributed to this Item, Thread, Post, etc." + }, + "attributes": [ + "datatype" + ], + "id": "134" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_discussion", + "inverse": "136", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "57", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_discussion", + "en": "has discussion" + }, + "domain": "1", + "comment": { + "en": "A discussion that is related to this Item. The discussion can be anything, for example, a sioc:Forum or sioc:Thread, a sioct:WikiArticle or simply a foaf:Document." + }, + "attributes": [ + "object" + ], + "id": "135" + }, + { + "iri": "http://rdfs.org/sioc/ns#num_views", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "94", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "num_views", + "en": "num views" + }, + "domain": "19", + "comment": { + "en": "The number of times this Item, Thread, UserAccount profile, etc. has been viewed." + }, + "attributes": [ + "datatype" + ], + "id": "137" + }, + { + "iri": "http://rdfs.org/sioc/ns#sibling", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "sibling", + "en": "sibling" + }, + "domain": "1", + "comment": { + "en": "An Item may have a sibling or a twin that exists in a different Container, but the siblings may differ in some small way (for example, language, category, etc.). The sibling of this Item should be self-describing (that is, it should contain all available information)." + }, + "attributes": [ + "symmetric", + "object" + ], + "id": "138" + }, + { + "iri": "http://rdfs.org/sioc/ns#function_of", + "inverse": "105", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "78", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "function_of", + "en": "function of" + }, + "domain": "66", + "comment": { + "en": "A UserAccount that has this Role." + }, + "attributes": [ + "object" + ], + "id": "139" + }, + { + "iri": "http://rdfs.org/sioc/ns#num_replies", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "106", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "num_replies", + "en": "num replies" + }, + "domain": "19", + "comment": { + "en": "The number of replies that this Item, Thread, Post, etc. has. Useful for when the reply structure is absent." + }, + "attributes": [ + "datatype" + ], + "id": "140" + }, + { + "iri": "http://rdfs.org/sioc/ns#created_at", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "33", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "This property is deprecated. Use dcterms:created from the Dublin Core ontology instead.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "created_at", + "en": "created at" + }, + "domain": "45", + "comment": { + "en": "When this was created, in ISO 8601 format." + }, + "attributes": [ + "datatype", + "deprecated" + ], + "id": "141" + }, + { + "iri": "http://rdfs.org/sioc/ns#links_to", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "19", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "links_to", + "en": "links to" + }, + "superproperty": [ + "122" + ], + "domain": "19", + "comment": { + "en": "Links extracted from hyperlinks within a SIOC concept, e.g. Post or Site." + }, + "attributes": [ + "object" + ], + "id": "123" + }, + { + "iri": "http://rdfs.org/sioc/ns#ip_address", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "6", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "ip_address", + "en": "ip address" + }, + "domain": "19", + "comment": { + "en": "The IP address used when creating this Item, UserAccount, etc. This can be associated with a creator. Some wiki articles list the IP addresses for the creator or modifiers when the usernames are absent." + }, + "attributes": [ + "datatype" + ], + "id": "142" + }, + { + "iri": "http://purl.org/dc/terms/hasPart", + "baseIri": "http://purl.org/dc/terms", + "range": "19", + "label": { + "IRI-based": "hasPart" + }, + "domain": "19", + "subproperty": [ + "13", + "17", + "43" + ], + "attributes": [ + "external", + "object" + ], + "id": "143" + }, + { + "range": "85", + "domain": "42", + "attributes": [ + "anonymous", + "object" + ], + "id": "144" + }, + { + "range": "8", + "domain": "28", + "attributes": [ + "anonymous", + "object" + ], + "id": "145" + }, + { + "iri": "http://purl.org/dc/terms/description", + "baseIri": "http://purl.org/dc/terms", + "range": "147", + "label": { + "IRI-based": "description" + }, + "domain": "19", + "attributes": [ + "datatype", + "external" + ], + "id": "146" + }, + { + "range": "85", + "domain": "48", + "attributes": [ + "anonymous", + "object" + ], + "id": "148" + }, + { + "range": "8", + "domain": "7", + "attributes": [ + "anonymous", + "object" + ], + "id": "149" + }, + { + "range": "1", + "domain": "45", + "attributes": [ + "anonymous", + "object" + ], + "id": "150" + }, + { + "iri": "http://rdfs.org/sioc/ns#next_by_date", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "next_by_date", + "en": "next by date" + }, + "domain": "1", + "comment": { + "en": "Next Item or Post in a given Container sorted by date." + }, + "attributes": [ + "object" + ], + "id": "2" + }, + { + "iri": "http://rdfs.org/sioc/ns#generator", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "57", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "generator", + "en": "generator" + }, + "domain": "1", + "comment": { + "en": "A URI for the application used to generate this Item." + }, + "attributes": [ + "object" + ], + "id": "151" + }, + { + "iri": "http://rdfs.org/sioc/ns#scope_of", + "inverse": "153", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "66", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "scope_of", + "en": "scope of" + }, + "domain": "78", + "comment": { + "en": "A Role that has a scope of this resource." + }, + "attributes": [ + "object" + ], + "id": "152" + }, + { + "range": "1", + "domain": "130", + "attributes": [ + "anonymous", + "object" + ], + "id": "154" + }, + { + "iri": "http://rdfs.org/sioc/ns#container_of", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "container_of", + "en": "container of" + }, + "superproperty": [ + "143" + ], + "domain": "8", + "comment": { + "en": "An Item that this Container contains." + }, + "attributes": [ + "object" + ], + "id": "43" + }, + { + "range": "8", + "domain": "42", + "attributes": [ + "anonymous", + "object" + ], + "id": "155" + }, + { + "range": "8", + "domain": "39", + "attributes": [ + "anonymous", + "object" + ], + "id": "156" + }, + { + "range": "8", + "domain": "66", + "attributes": [ + "anonymous", + "object" + ], + "id": "157" + }, + { + "range": "48", + "domain": "8", + "attributes": [ + "anonymous", + "object" + ], + "id": "158" + }, + { + "iri": "http://rdfs.org/sioc/ns#latest_version", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "latest_version", + "en": "latest version" + }, + "domain": "1", + "comment": { + "en": "Links to the latest revision of this Item or Post." + }, + "attributes": [ + "object" + ], + "id": "159" + }, + { + "range": "1", + "domain": "8", + "attributes": [ + "anonymous", + "object" + ], + "id": "160" + }, + { + "range": "1", + "domain": "48", + "attributes": [ + "anonymous", + "object" + ], + "id": "161" + }, + { + "range": "1", + "domain": "42", + "attributes": [ + "anonymous", + "object" + ], + "id": "162" + }, + { + "iri": "http://rdfs.org/sioc/ns#title", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "95", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "This property is deprecated. Use dcterms:title from the Dublin Core ontology instead.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "title", + "en": "title" + }, + "domain": "45", + "comment": { + "en": "This is the title (subject line) of the Post. Note that for a Post within a threaded discussion that has no parents, it would detail the topic thread." + }, + "attributes": [ + "datatype", + "deprecated" + ], + "id": "163" + }, + { + "iri": "http://rdfs.org/sioc/ns#parent_of", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "8", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "parent_of", + "en": "parent of" + }, + "superproperty": [ + "143" + ], + "domain": "8", + "comment": { + "en": "A child Container or Forum that this Container or Forum is a parent of." + }, + "attributes": [ + "object" + ], + "id": "17" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_scope", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "78", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_scope", + "en": "has scope" + }, + "domain": "66", + "comment": { + "en": "A resource that this Role applies to." + }, + "attributes": [ + "object" + ], + "id": "153" + }, + { + "iri": "http://rdfs.org/sioc/ns#respond_to", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "57", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "respond_to", + "en": "respond to" + }, + "domain": "1", + "comment": { + "en": "For the reply-to address set in email messages, IMs, etc. The property name was chosen to avoid confusion with has_reply/reply_of (the reply graph)." + }, + "attributes": [ + "object" + ], + "id": "164" + }, + { + "range": "66", + "domain": "130", + "attributes": [ + "anonymous", + "object" + ], + "id": "165" + }, + { + "range": "130", + "domain": "42", + "attributes": [ + "anonymous", + "object" + ], + "id": "166" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_creator", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "42", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_creator", + "en": "has creator" + }, + "domain": "54", + "comment": { + "en": "This is the UserAccount that made this resource." + }, + "attributes": [ + "object" + ], + "id": "132" + }, + { + "iri": "http://rdfs.org/sioc/ns#read_at", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "57", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "read_at", + "en": "read at" + }, + "domain": "1", + "comment": { + "en": "When this was read, in ISO 8601 format." + }, + "attributes": [ + "object" + ], + "id": "167" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_part", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "19", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "This property is deprecated. Use dcterms:hasPart from the Dublin Core ontology instead.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "has_part", + "en": "has part" + }, + "domain": "19", + "comment": { + "en": "An resource that is a part of this subject." + }, + "attributes": [ + "object", + "deprecated" + ], + "id": "20" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_moderator", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "42", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_moderator", + "en": "has moderator" + }, + "domain": "7", + "comment": { + "en": "A UserAccount that is a moderator of this Forum." + }, + "attributes": [ + "object" + ], + "id": "51" + }, + { + "iri": "http://rdfs.org/sioc/ns#likes", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "19", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "likes", + "en": "likes" + }, + "domain": "19", + "comment": { + "en": "Used to indicate some form of endorsement by a UserAccount or Agent of an Item, Container, Space, UserAccount, etc." + }, + "attributes": [ + "object" + ], + "id": "168" + }, + { + "iri": "http://rdfs.org/sioc/ns#name", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "111", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "name", + "en": "name" + }, + "domain": "19", + "comment": { + "en": "The name of a SIOC concept instance, e.g. a username for a UserAccount, group name for a Usergroup, etc." + }, + "attributes": [ + "datatype" + ], + "id": "169" + }, + { + "iri": "http://rdfs.org/sioc/ns#previous_version", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "previous_version", + "en": "previous version" + }, + "superproperty": [ + "4" + ], + "domain": "1", + "comment": { + "en": "Links to the previous revision of this Item or Post." + }, + "attributes": [ + "object" + ], + "id": "61" + }, + { + "iri": "http://rdfs.org/sioc/ns#addressed_to", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "57", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "addressed_to", + "en": "addressed to" + }, + "domain": "1", + "comment": { + "en": "Refers to who (e.g. a UserAccount, e-mail address, etc.) a particular Item is addressed to." + }, + "attributes": [ + "object" + ], + "id": "170" + }, + { + "iri": "http://rdfs.org/sioc/ns#space_of", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "11", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "space_of", + "en": "space of" + }, + "superproperty": [ + "143" + ], + "domain": "12", + "subproperty": [ + "68" + ], + "comment": { + "en": "A resource which belongs to this data Space." + }, + "attributes": [ + "object" + ], + "id": "13" + }, + { + "iri": "http://rdfs.org/sioc/ns#num_threads", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "104", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "num_threads", + "en": "num threads" + }, + "domain": "7", + "comment": { + "en": "The number of Threads (AKA discussion topics) in a Forum." + }, + "attributes": [ + "datatype" + ], + "id": "171" + }, + { + "iri": "http://rdfs.org/sioc/ns#discussion_of", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "1", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "discussion_of", + "en": "discussion of" + }, + "domain": "57", + "comment": { + "en": "The Item that this discussion is about." + }, + "attributes": [ + "object" + ], + "id": "136" + }, + { + "iri": "http://rdfs.org/sioc/ns#subscriber_of", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "8", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ], + "seeAlso": [ + { + "identifier": "seeAlso", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#feed", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "subscriber_of", + "en": "subscriber of" + }, + "domain": "42", + "comment": { + "en": "A Container that a UserAccount is subscribed to." + }, + "attributes": [ + "object" + ], + "id": "118" + }, + { + "iri": "http://rdfs.org/sioc/ns#feed", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "19", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "feed", + "en": "feed" + }, + "domain": "19", + "comment": { + "en": "A feed (e.g. RSS, Atom, etc.) pertaining to this resource (e.g. for a Forum, Site, UserAccount, etc.)." + }, + "attributes": [ + "object" + ], + "id": "172" + }, + { + "iri": "http://rdfs.org/sioc/ns#has_owner", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "42", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "has_owner", + "en": "has owner" + }, + "domain": "54", + "comment": { + "en": "A UserAccount that this resource is owned by." + }, + "attributes": [ + "object" + ], + "id": "74" + }, + { + "iri": "http://rdfs.org/sioc/ns#mentions", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "42", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "mentions", + "en": "mentions" + }, + "domain": "1", + "comment": { + "en": "Refers to a UserAccount that a particular Item mentions." + }, + "attributes": [ + "object" + ], + "id": "173" + }, + { + "iri": "http://rdfs.org/sioc/ns#group_of", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "19", + "annotations": { + "versionInfo": [ + { + "identifier": "versionInfo", + "language": "undefined", + "value": "This property has been renamed. Use sioc:usergroup_of instead.", + "type": "label" + } + ] + }, + "label": { + "IRI-based": "group_of", + "en": "group of" + }, + "domain": "19", + "attributes": [ + "object", + "deprecated" + ], + "id": "36" + }, + { + "iri": "http://rdfs.org/sioc/ns#topic", + "baseIri": "http://rdfs.org/sioc/ns", + "range": "19", + "annotations": { + "isDefinedBy": [ + { + "identifier": "isDefinedBy", + "language": "undefined", + "value": "http://rdfs.org/sioc/ns#", + "type": "iri" + } + ] + }, + "label": { + "IRI-based": "topic", + "en": "topic" + }, + "superproperty": [ + "30" + ], + "domain": "19", + "comment": { + "en": "A topic of interest, linking to the appropriate URI, e.g. in the Open Directory Project or of a SKOS category." + }, + "attributes": [ + "object" + ], + "id": "31" + } + ] +} \ No newline at end of file diff --git a/src/app/data/template.json b/src/app/data/template.json new file mode 100644 index 0000000000000000000000000000000000000000..003d011fec70c189180146bd205436100a76720d --- /dev/null +++ b/src/app/data/template.json @@ -0,0 +1,163 @@ +{ + "namespace": [ + { + "name": "", + "iri": "" + } + ], + "header": { + "languages": [ + "all", + "occurring", + "languages" + ], + "title": { + "language": "label" + }, + "iri": "", + "version": "", + "author": [ + "Author One", + "Author Two" + ], + "description": { + "language": "label" + }, + "other": { + "someIdentifier": [ + { + "identifier": "someIdentifier", + "language": "undefined", + "value": "http://an.iri/", + "type": "iri" + } + ], + "someOtherIdentifier": [ + { + "identifier": "someOtherIdentifier", + "language": "undefined", + "value": "Some person", + "type": "label" + } + ] + } + }, + "metrics": { + "classCount": 40, + "datatypeCount": 13, + "objectPropertyCount": 23, + "datatypePropertyCount": 13, + "propertyCount": 36, + "nodeCount": 53, + "axiomCount": 216, + "individualCount": 8 + }, + "class": [ + { + "id": "", + "type": "" + } + ], + "classAttribute": [ + { + "id": "", + "label": "", + "iri": "", + "individuals": [ + { + "iri": "", + "labels": { + "language": "label" + }, + "annotations": {} + } + ], + "comment": "", + "equivalent": [ + "" + ], + "union": [ + "" + ], + "intersection": [ + "" + ], + "complement": [ + "" + ], + "attributes": [ + "deprecated", + "external", + "datatype", + "object", + "rdf" + ] + } + ], + "datatype": [ + { + "id": "", + "type": "" + } + ], + "datatypeAttribute": [ + { + "id": "", + "label": { + "language": "label" + }, + "iri": "", + "individuals": [ + { + "iri": "", + "labels": { + "language": "label" + }, + "annotations": {} + } + ], + "comment": "", + "equivalent": [ + "" + ] + } + ], + "property": [ + { + "id": "" + } + ], + "propertyAttribute": [ + { + "id": "", + "domain": "", + "range": "", + "inverse": "", + "label": { + "language": "label" + }, + "type": "", + "comment": "", + "cardinality": "", + "minCardinality": "", + "maxCardinality": "", + "subproperty": [ + "" + ], + "equivalent": [ + "" + ], + "attributes": [ + "deprecated", + "external", + "datatype", + "object", + "rdf", + "transitive", + "functional", + "inverse functional", + "symmetric" + ] + } + ] +} diff --git a/src/app/js/app.js b/src/app/js/app.js new file mode 100644 index 0000000000000000000000000000000000000000..30c8999cc6bfe53472f29efdcd7acd609d37d1aa --- /dev/null +++ b/src/app/js/app.js @@ -0,0 +1,609 @@ +String.prototype.replaceAll = function ( search, replacement ){ + var target = this; + return target.split(search).join(replacement); +}; +module.exports = function (){ + var newOntologyCounter = 1; + var app = {}, + graph = webvowl.graph(), + options = graph.graphOptions(), + languageTools = webvowl.util.languageTools(), + GRAPH_SELECTOR = "#graph", + // Modules for the webvowl app + exportMenu = require("./menu/exportMenu")(graph), + filterMenu = require("./menu/filterMenu")(graph), + gravityMenu = require("./menu/gravityMenu")(graph), + modeMenu = require("./menu/modeMenu")(graph), + debugMenu = require("./menu/debugMenu")(graph), + ontologyMenu = require("./menu/ontologyMenu")(graph), + pauseMenu = require("./menu/pauseMenu")(graph), + resetMenu = require("./menu/resetMenu")(graph), + searchMenu = require("./menu/searchMenu")(graph), + navigationMenu = require("./menu/navigationMenu")(graph), + zoomSlider = require("./menu/zoomSlider")(graph), + sidebar = require("./sidebar")(graph), + leftSidebar = require("./leftSidebar")(graph), + editSidebar = require("./editSidebar")(graph), + configMenu = require("./menu/configMenu")(graph), + loadingModule = require("./loadingModule")(graph), + warningModule = require("./warningModule")(graph), + directInputMod = require("./directInputModule")(graph), + + + // Graph modules + colorExternalsSwitch = webvowl.modules.colorExternalsSwitch(graph), + compactNotationSwitch = webvowl.modules.compactNotationSwitch(graph), + datatypeFilter = webvowl.modules.datatypeFilter(), + disjointFilter = webvowl.modules.disjointFilter(), + focuser = webvowl.modules.focuser(graph), + emptyLiteralFilter = webvowl.modules.emptyLiteralFilter(), + nodeDegreeFilter = webvowl.modules.nodeDegreeFilter(filterMenu), + nodeScalingSwitch = webvowl.modules.nodeScalingSwitch(graph), + objectPropertyFilter = webvowl.modules.objectPropertyFilter(), + pickAndPin = webvowl.modules.pickAndPin(), + selectionDetailDisplayer = webvowl.modules.selectionDetailsDisplayer(sidebar.updateSelectionInformation), + statistics = webvowl.modules.statistics(), + subclassFilter = webvowl.modules.subclassFilter(), + setOperatorFilter = webvowl.modules.setOperatorFilter(); + + + app.getOptions = function (){ + return webvowl.opts; + }; + app.getGraph = function (){ + return webvowl.gr; + }; + // app.afterInitializationCallback=undefined; + + + var executeFileDrop = false; + var wasMessageToShow = false; + var firstTime = false; + + function addFileDropEvents( selector ){ + var node = d3.select(selector); + + node.node().ondragover = function ( e ){ + e.preventDefault(); + + d3.select("#dragDropContainer").classed("hidden", false); + // get svg size + var w = graph.options().width(); + var h = graph.options().height(); + + // get event position; (using clientX and clientY); + var cx = e.clientX; + var cy = e.clientY; + + if ( firstTime === false ) { + var state = d3.select("#loading-info").classed("hidden"); + wasMessageToShow = !state; + firstTime = true; + d3.select("#loading-info").classed("hidden", true); // hide it so it does not conflict with drop event + var bb=d3.select("#drag_msg").node().getBoundingClientRect(); + var hs = bb.height; + var ws = bb.width; + + var icon_scale=Math.min(hs,ws); + icon_scale/=100; + + d3.select("#drag_icon_group").attr("transform", "translate ( " + 0.25 * ws + " " + 0.25 * hs + ")"); + d3.select("#drag_icon").attr("transform","matrix ("+icon_scale+",0,0,"+icon_scale+",0,0)"); + d3.select("#drag_icon_drop").attr("transform","matrix ("+icon_scale+",0,0,"+icon_scale+",0,0)"); + } + + + if ( (cx > 0.25 * w && cx < 0.75 * w) && (cy > 0.25 * h && cy < 0.75 * h) ) { + + d3.select("#drag_msg_text").node().innerHTML = "Drop it here."; + d3.select("#drag_msg").style("background-color", "#67bc0f"); + d3.select("#drag_msg").style("color", "#000000"); + executeFileDrop = true; + // d3.select("#drag_svg").transition() + // .duration(100) + // // .attr("-webkit-transform", "rotate(90)") + // // .attr("-moz-transform", "rotate(90)") + // // .attr("-o-transform", "rotate(90)") + // .attr("transform", "rotate(90)"); + + d3.select("#drag_icon").classed("hidden",true); + d3.select("#drag_icon_drop").classed("hidden",false); + + + } else { + d3.select("#drag_msg_text").node().innerHTML = "Drag ontology file here."; + d3.select("#drag_msg").style("background-color", "#fefefe"); + d3.select("#drag_msg").style("color", "#000000"); + executeFileDrop = false; + + d3.select("#drag_icon").classed("hidden",false); + d3.select("#drag_icon_drop").classed("hidden",true); + + + // d3.select("#drag_svg").transition() + // .duration(100) + // // .attr("-webkit-transform", "rotate(0)") + // // .attr("-moz-transform", "rotate(0)") + // // .attr("-o-transform", "rotate(0)") + // .attr("transform", "rotate(0)"); + // + } + + }; + node.node().ondrop = function ( ev ){ + ev.preventDefault(); + firstTime = false; + if ( executeFileDrop ) { + if ( ev.dataTransfer.items ) { + if ( ev.dataTransfer.items.length === 1 ) { + if ( ev.dataTransfer.items[0].kind === 'file' ) { + var file = ev.dataTransfer.items[0].getAsFile(); + graph.options().loadingModule().fromFileDrop(file.name, file); + } + } + else { + // >> WARNING not multiple file uploaded; + graph.options().warningModule().showMultiFileUploadWarning(); + } + } + } + d3.select("#dragDropContainer").classed("hidden", true); + }; + + node.node().ondragleave = function ( e ){ + var w = graph.options().width(); + var h = graph.options().height(); + + // get event position; (using clientX and clientY); + var cx = e.clientX; + var cy = e.clientY; + + var hidden = false; + firstTime = false; + + if ( cx < 0.1 * w || cx > 0.9 * w ) hidden = true; + if ( cy < 0.1 * h || cy > 0.9 * h ) hidden = true; + d3.select("#dragDropContainer").classed("hidden", hidden); + + d3.select("#loading-info").classed("hidden", !wasMessageToShow); // show it again + // check if it should be visible + var should_show=graph.options().loadingModule().getMessageVisibilityStatus(); + if (should_show===false){ + d3.select("#loading-info").classed("hidden", true); // hide it + } + }; + + } + + + app.initialize = function (){ + addFileDropEvents(GRAPH_SELECTOR); + + window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function ( f ){ + return setTimeout(f, 1000 / 60); + }; // simulate calling code 60 + window.cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame || function ( requestID ){ + clearTimeout(requestID); + }; //fall back + + options.graphContainerSelector(GRAPH_SELECTOR); + options.selectionModules().push(focuser); + options.selectionModules().push(selectionDetailDisplayer); + options.selectionModules().push(pickAndPin); + + options.filterModules().push(emptyLiteralFilter); + options.filterModules().push(statistics); + + options.filterModules().push(nodeDegreeFilter); + options.filterModules().push(datatypeFilter); + options.filterModules().push(objectPropertyFilter); + options.filterModules().push(subclassFilter); + options.filterModules().push(disjointFilter); + options.filterModules().push(setOperatorFilter); + options.filterModules().push(nodeScalingSwitch); + options.filterModules().push(compactNotationSwitch); + options.filterModules().push(colorExternalsSwitch); + + d3.select(window).on("resize", adjustSize); + + exportMenu.setup(); + gravityMenu.setup(); + filterMenu.setup(datatypeFilter, objectPropertyFilter, subclassFilter, disjointFilter, setOperatorFilter, nodeDegreeFilter); + modeMenu.setup(pickAndPin, nodeScalingSwitch, compactNotationSwitch, colorExternalsSwitch); + pauseMenu.setup(); + sidebar.setup(); + loadingModule.setup(); + leftSidebar.setup(); + editSidebar.setup(); + debugMenu.setup(); + var agentVersion = getInternetExplorerVersion(); + if ( agentVersion > 0 && agentVersion <= 11 ) { + console.log("Agent version " + agentVersion); + console.log("This agent is not supported"); + d3.select("#browserCheck").classed("hidden", false); + d3.select("#killWarning").classed("hidden", true); + d3.select("#optionsArea").classed("hidden", true); + d3.select("#logo").classed("hidden", true); + } else { + d3.select("#logo").classed("hidden", false); + if ( agentVersion === 12 ) { + // allow Mircosoft Edge Browser but with warning + d3.select("#browserCheck").classed("hidden", false); + d3.select("#killWarning").classed("hidden", false); + } else { + d3.select("#browserCheck").classed("hidden", true); + } + + resetMenu.setup([gravityMenu, filterMenu, modeMenu, focuser, selectionDetailDisplayer, pauseMenu]); + searchMenu.setup(); + navigationMenu.setup(); + zoomSlider.setup(); + + // give the options the pointer to the some menus for import and export + options.literalFilter(emptyLiteralFilter); + options.nodeDegreeFilter(nodeDegreeFilter); + options.loadingModule(loadingModule); + options.filterMenu(filterMenu); + options.modeMenu(modeMenu); + options.gravityMenu(gravityMenu); + options.pausedMenu(pauseMenu); + options.pickAndPinModule(pickAndPin); + options.resetMenu(resetMenu); + options.searchMenu(searchMenu); + options.ontologyMenu(ontologyMenu); + options.navigationMenu(navigationMenu); + options.sidebar(sidebar); + options.leftSidebar(leftSidebar); + options.editSidebar(editSidebar); + options.exportMenu(exportMenu); + options.graphObject(graph); + options.zoomSlider(zoomSlider); + options.warningModule(warningModule); + options.directInputModule(directInputMod); + options.datatypeFilter(datatypeFilter); + options.objectPropertyFilter(objectPropertyFilter); + options.subclassFilter(subclassFilter); + options.setOperatorFilter(setOperatorFilter); + options.disjointPropertyFilter(disjointFilter); + options.focuserModule(focuser); + options.colorExternalsModule(colorExternalsSwitch); + options.compactNotationModule(compactNotationSwitch); + + ontologyMenu.setup(loadOntologyFromText); + configMenu.setup(); + + leftSidebar.showSidebar(0); + leftSidebar.hideCollapseButton(true); + + + graph.start(); + + var modeOp = d3.select("#modeOfOperationString"); + modeOp.style("font-size", "0.6em"); + modeOp.style("font-style", "italic"); + + adjustSize(); + var defZoom; + var w = graph.options().width(); + var h = graph.options().height(); + defZoom = Math.min(w, h) / 1000; + + var hideDebugOptions = true; + if ( hideDebugOptions === false ) { + graph.setForceTickFunctionWithFPS(); + } + + graph.setDefaultZoom(defZoom); + d3.selectAll(".debugOption").classed("hidden", hideDebugOptions); + + // prevent backspace reloading event + var htmlBody = d3.select("body"); + d3.select(document).on("keydown", function ( e ){ + if ( d3.event.keyCode === 8 && d3.event.target === htmlBody.node() ) { + // we could add here an alert + d3.event.preventDefault(); + } + // using ctrl+Shift+d as debug option + if ( d3.event.ctrlKey && d3.event.shiftKey && d3.event.keyCode === 68 ) { + graph.options().executeHiddenDebugFeatuers(); + d3.event.preventDefault(); + } + }); + if ( d3.select("#maxLabelWidthSliderOption") ) { + var setValue = !graph.options().dynamicLabelWidth(); + d3.select("#maxLabelWidthSlider").node().disabled = setValue; + d3.select("#maxLabelWidthvalueLabel").classed("disabledLabelForSlider", setValue); + d3.select("#maxLabelWidthDescriptionLabel").classed("disabledLabelForSlider", setValue); + } + + d3.select("#blockGraphInteractions").style("position", "absolute") + .style("top", "0") + .style("background-color", "#bdbdbd") + .style("opacity", "0.5") + .style("pointer-events", "auto") + .style("width", graph.options().width() + "px") + .style("height", graph.options().height() + "px") + .on("click", function (){ + d3.event.preventDefault(); + d3.event.stopPropagation(); + }) + .on("dblclick", function (){ + d3.event.preventDefault(); + d3.event.stopPropagation(); + }); + + d3.select("#direct-text-input").on("click", function (){ + directInputMod.setDirectInputMode(); + }); + d3.select("#blockGraphInteractions").node().draggable = false; + options.prefixModule(webvowl.util.prefixTools(graph)); + adjustSize(); + sidebar.updateOntologyInformation(undefined, statistics); + loadingModule.parseUrlAndLoadOntology(); // loads automatically the ontology provided by the parameters + options.debugMenu(debugMenu); + debugMenu.updateSettings(); + + // connect the reloadCachedVersionButton + d3.select("#reloadSvgIcon").on("click", function (){ + if ( d3.select("#reloadSvgIcon").node().disabled === true ) { + graph.options().ontologyMenu().clearCachedVersion(); + return; + } + d3.select("#reloadCachedOntology").classed("hidden", true); + graph.options().ontologyMenu().reloadCachedOntology(); + + }); + // add the initialized objects + webvowl.opts = options; + webvowl.gr = graph; + + } + }; + + + function loadOntologyFromText( jsonText, filename, alternativeFilename ){ + d3.select("#reloadCachedOntology").classed("hidden", true); + pauseMenu.reset(); + graph.options().navigationMenu().hideAllMenus(); + + if ( (jsonText === undefined && filename === undefined) || (jsonText.length === 0) ) { + loadingModule.notValidJsonFile(); + return; + } + graph.editorMode(); // updates the checkbox + var data; + if ( jsonText ) { + // validate JSON FILE + var validJSON; + try { + data = JSON.parse(jsonText); + validJSON = true; + } catch ( e ) { + validJSON = false; + } + if ( validJSON === false ) { + // the server output is not a valid json file + loadingModule.notValidJsonFile(); + return; + } + + if ( !filename ) { + // First look if an ontology title exists, otherwise take the alternative filename + var ontologyNames = data.header ? data.header.title : undefined; + var ontologyName = languageTools.textInLanguage(ontologyNames); + + if ( ontologyName ) { + filename = ontologyName; + } else { + filename = alternativeFilename; + } + } + } + + + // check if we have graph data + var classCount = 0; + if ( data.class !== undefined ) { + classCount = data.class.length; + } + + var loadEmptyOntologyForEditing = false; + if ( location.hash.indexOf("#new_ontology") !== -1 ) { + loadEmptyOntologyForEditing = true; + newOntologyCounter++; + d3.select("#empty").node().href = "#opts=editorMode=true;#new_ontology" + newOntologyCounter; + } + if ( classCount === 0 && graph.editorMode() === false && loadEmptyOntologyForEditing === false ) { + // generate message for the user; + loadingModule.emptyGraphContentError(); + } else { + loadingModule.validJsonFile(); + ontologyMenu.setCachedOntology(filename, jsonText); + exportMenu.setJsonText(jsonText); + options.data(data); + graph.options().loadingModule().setPercentMode(); + if ( loadEmptyOntologyForEditing === true ) { + graph.editorMode(true); + + } + graph.load(); + sidebar.updateOntologyInformation(data, statistics); + exportMenu.setFilename(filename); + graph.updateZoomSliderValueFromOutside(); + adjustSize(); + + var flagOfCheckBox = d3.select("#editorModeModuleCheckbox").node().checked; + graph.editorMode(flagOfCheckBox);// update gui + + } + } + + function adjustSize(){ + var graphContainer = d3.select(GRAPH_SELECTOR), + svg = graphContainer.select("svg"), + height = window.innerHeight - 40, + width = window.innerWidth - (window.innerWidth * 0.22); + + if ( sidebar.getSidebarVisibility() === "0" ) { + height = window.innerHeight - 40; + width = window.innerWidth; + } + + directInputMod.updateLayout(); + d3.select("#blockGraphInteractions").style("width", window.innerWidth + "px"); + d3.select("#blockGraphInteractions").style("height", window.innerHeight + "px"); + + d3.select("#WarningErrorMessagesContainer").style("width", width + "px"); + d3.select("#WarningErrorMessagesContainer").style("height", height + "px"); + + d3.select("#WarningErrorMessages").style("max-height", (height - 12) + "px"); + + graphContainer.style("height", height + "px"); + svg.attr("width", width) + .attr("height", height); + + options.width(width) + .height(height); + + graph.updateStyle(); + + if ( isTouchDevice() === true ) { + if ( graph.isEditorMode() === true ) + d3.select("#modeOfOperationString").node().innerHTML = "touch able device detected"; + graph.setTouchDevice(true); + + } else { + if ( graph.isEditorMode() === true ) + d3.select("#modeOfOperationString").node().innerHTML = "point & click device detected"; + graph.setTouchDevice(false); + } + + d3.select("#loadingInfo-container").style("height", 0.5 * (height - 80) + "px"); + loadingModule.checkForScreenSize(); + + adjustSliderSize(); + // update also the padding options of loading and the logo positions; + var warningDiv = d3.select("#browserCheck"); + if ( warningDiv.classed("hidden") === false ) { + var offset = 10 + warningDiv.node().getBoundingClientRect().height; + d3.select("#logo").style("padding", offset + "px 10px"); + } else { + // remove the dynamic padding from the logo element; + d3.select("#logo").style("padding", "10px"); + } + + // scrollbar tests; + var element = d3.select("#menuElementContainer").node(); + var maxScrollLeft = element.scrollWidth - element.clientWidth; + var leftButton = d3.select("#scrollLeftButton"); + var rightButton = d3.select("#scrollRightButton"); + if ( maxScrollLeft > 0 ) { + // show both and then check how far is bar; + rightButton.classed("hidden", false); + leftButton.classed("hidden", false); + navigationMenu.updateScrollButtonVisibility(); + } else { + // hide both; + rightButton.classed("hidden", true); + leftButton.classed("hidden", true); + } + + // adjust height of the leftSidebar element; + editSidebar.updateElementWidth(); + + + var hs = d3.select("#drag_msg").node().getBoundingClientRect().height; + var ws = d3.select("#drag_msg").node().getBoundingClientRect().width; + d3.select("#drag_icon_group").attr("transform", "translate ( " + 0.25 * ws + " " + 0.25 * hs + ")"); + + } + + function adjustSliderSize(){ + // TODO: refactor and put this into the slider it self + var height = window.innerHeight - 40; + var fullHeight = height; + var zoomOutPos = height - 30; + var sliderHeight = 150; + + // assuming DOM elements are generated in the index.html + // todo: refactor for independent usage of graph and app + if ( fullHeight < 150 ) { + // hide the slider button; + d3.select("#zoomSliderParagraph").classed("hidden", true); + d3.select("#zoomOutButton").classed("hidden", true); + d3.select("#zoomInButton").classed("hidden", true); + d3.select("#centerGraphButton").classed("hidden", true); + return; + } + d3.select("#zoomSliderParagraph").classed("hidden", false); + d3.select("#zoomOutButton").classed("hidden", false); + d3.select("#zoomInButton").classed("hidden", false); + d3.select("#centerGraphButton").classed("hidden", false); + + var zoomInPos = zoomOutPos - 20; + var centerPos = zoomInPos - 20; + if ( fullHeight < 280 ) { + // hide the slider button; + d3.select("#zoomSliderParagraph").classed("hidden", true);//var sliderPos=zoomOutPos-sliderHeight; + d3.select("#zoomOutButton").style("top", zoomOutPos + "px"); + d3.select("#zoomInButton").style("top", zoomInPos + "px"); + d3.select("#centerGraphButton").style("top", centerPos + "px"); + return; + } + + var sliderPos = zoomOutPos - sliderHeight; + zoomInPos = sliderPos - 20; + centerPos = zoomInPos - 20; + d3.select("#zoomSliderParagraph").classed("hidden", false); + d3.select("#zoomOutButton").style("top", zoomOutPos + "px"); + d3.select("#zoomInButton").style("top", zoomInPos + "px"); + d3.select("#centerGraphButton").style("top", centerPos + "px"); + d3.select("#zoomSliderParagraph").style("top", sliderPos + "px"); + } + + function isTouchDevice(){ + try { + document.createEvent("TouchEvent"); + return true; + } catch ( e ) { + return false; + } + } + + + function getInternetExplorerVersion(){ + var ua, + re, + rv = -1; + + // check for edge + var isEdge = /(?:\b(MS)?IE\s+|\bTrident\/7\.0;.*\s+rv:|\bEdge\/)(\d+)/.test(navigator.userAgent); + if ( isEdge ) { + rv = parseInt("12"); + return rv; + } + + var isIE11 = /Trident.*rv[ :]*11\./.test(navigator.userAgent); + if ( isIE11 ) { + rv = parseInt("11"); + return rv; + } + if ( navigator.appName === "Microsoft Internet Explorer" ) { + ua = navigator.userAgent; + re = new RegExp("MSIE ([0-9]{1,}[\\.0-9]{0,})"); + if ( re.exec(ua) !== null ) { + rv = parseFloat(RegExp.$1); + } + } else if ( navigator.appName === "Netscape" ) { + ua = navigator.userAgent; + re = new RegExp("Trident/.*rv:([0-9]{1,}[\\.0-9]{0,})"); + if ( re.exec(ua) !== null ) { + rv = parseFloat(RegExp.$1); + } + } + return rv; + } + + return app; +} +; diff --git a/src/app/js/browserWarning.js b/src/app/js/browserWarning.js new file mode 100644 index 0000000000000000000000000000000000000000..db4a8cfe78455ad4222de547cc92b694dd2d4cae --- /dev/null +++ b/src/app/js/browserWarning.js @@ -0,0 +1,63 @@ +/* Taken from here: http://stackoverflow.com/a/17907562 */ +function getInternetExplorerVersion(){ + var ua, + re, + rv = -1; + + // check for edge + var isEdge = /(?:\b(MS)?IE\s+|\bTrident\/7\.0;.*\s+rv:|\bEdge\/)(\d+)/.test(navigator.userAgent); + if ( isEdge ) { + rv = parseInt("12"); + return rv; + } + + var isIE11 = /Trident.*rv[ :]*11\./.test(navigator.userAgent); + if ( isIE11 ) { + rv = parseInt("11"); + return rv; + } + if ( navigator.appName === "Microsoft Internet Explorer" ) { + ua = navigator.userAgent; + re = new RegExp("MSIE ([0-9]{1,}[\\.0-9]{0,})"); + if ( re.exec(ua) !== null ) { + rv = parseFloat(RegExp.$1); + } + } else if ( navigator.appName === "Netscape" ) { + ua = navigator.userAgent; + re = new RegExp("Trident/.*rv:([0-9]{1,}[\\.0-9]{0,})"); + if ( re.exec(ua) !== null ) { + rv = parseFloat(RegExp.$1); + } + } + return rv; +} + +function showBrowserWarningIfRequired(){ + var version = getInternetExplorerVersion(); + console.log("Browser Version =" + version); + if ( version > 0 && version <= 11 ) { + d3.select("#browserCheck").classed("hidden", false); + d3.select("#killWarning").classed("hidden", true); + d3.select("#optionsArea").classed("hidden", true); + d3.select("#logo").classed("hidden", true); + } + if ( version == 12 ) { + d3.select("#logo").classed("hidden", false); + d3.select("#browserCheck").classed("hidden", false); + // connect the button; + var pb_kill = d3.select("#killWarning"); + pb_kill.on("click", function (){ + console.log("hide the warning please"); + d3.select("#browserCheck").classed("hidden", true); + d3.select("#logo").style("padding", "10px"); + }); + } + else { + d3.select("#logo").classed("hidden", false); + d3.select("#browserCheck").classed("hidden", true); + } + +} + +module.exports = showBrowserWarningIfRequired; +showBrowserWarningIfRequired(); \ No newline at end of file diff --git a/src/app/js/directInputModule.js b/src/app/js/directInputModule.js new file mode 100644 index 0000000000000000000000000000000000000000..738b085e24471b7cdbcd8f89be7d9491239d1cf5 --- /dev/null +++ b/src/app/js/directInputModule.js @@ -0,0 +1,74 @@ +module.exports = function ( graph ){ + /** variable defs **/ + var directInputModule = {}; + var inputContainer = d3.select("#DirectInputContent"); + inputContainer.style("top", "0"); + inputContainer.style("position", "absolute"); + var textArea = d3.select("#directInputTextArea"); + var visibleContainer = false; + + inputContainer.style("border", "1px solid black"); + inputContainer.style("padding", "5px"); + inputContainer.style("background", "#fff"); + + + // connect upload and close button; + directInputModule.handleDirectUpload = function (){ + + var text = textArea.node().value; + var jsonOBJ; + try { + jsonOBJ = JSON.parse(text); + graph.options().loadingModule().directInput(text); + // close if successful + if ( jsonOBJ.class.length > 0 ) { + directInputModule.setDirectInputMode(false); + } + } + catch ( e ) { + try { + // Initialize; + graph.options().loadingModule().initializeLoader(); + graph.options().loadingModule().requestServerTimeStampForDirectInput( + graph.options().ontologyMenu().callbackLoad_Ontology_From_DirectInput, text + ); + } catch ( error2 ) { + console.log("Error " + error2); + d3.select("#Error_onLoad").classed("hidden", false); + d3.select("#Error_onLoad").node().innerHTML = "Failed to convert the input!"; + } + } + }; + + directInputModule.handleCloseButton = function (){ + directInputModule.setDirectInputMode(false); + }; + + directInputModule.updateLayout = function (){ + var w = graph.options().width(); + var h = graph.options().height(); + textArea.style("width", 0.4 * w + "px"); + textArea.style("height", 0.7 * h + "px"); + }; + + directInputModule.setDirectInputMode = function ( val ){ + if ( !val ) { + visibleContainer = !visibleContainer; + } + else { + visibleContainer = val; + } + // update visibility; + directInputModule.updateLayout(); + d3.select("#Error_onLoad").classed("hidden", true); + inputContainer.classed("hidden", !visibleContainer); + }; + + + d3.select("#directUploadBtn").on("click", directInputModule.handleDirectUpload); + d3.select("#close_directUploadBtn").on("click", directInputModule.handleCloseButton); + + return directInputModule; +}; + + diff --git a/src/app/js/editSidebar.js b/src/app/js/editSidebar.js new file mode 100644 index 0000000000000000000000000000000000000000..1593bc8e8d0bedd2e0b7c690ba09d1a396a59a5e --- /dev/null +++ b/src/app/js/editSidebar.js @@ -0,0 +1,1333 @@ +/** + * Contains the logic for the sidebar. + * @param graph the graph that belongs to these controls + * @returns {{}} + */ +module.exports = function ( graph ){ + + var editSidebar = {}, + languageTools = webvowl.util.languageTools(), + elementTools = webvowl.util.elementTools(); + + var prefixModule = webvowl.util.prefixTools(graph); + var selectedElementForCharacteristics; + var oldPrefix, oldPrefixURL; + var prefix_editMode = false; + + + editSidebar.clearMetaObjectValue = function (){ + d3.select("#titleEditor").node().value = ""; + d3.select("#iriEditor").node().value = ""; + d3.select("#versionEditor").node().value = ""; + d3.select("#authorsEditor").node().value = ""; + d3.select("#descriptionEditor").node().value = ""; + // todo add clear description; + }; + + + editSidebar.updatePrefixUi = function (){ + editSidebar.updateElementWidth(); + var prefixListContainer = d3.select("#prefixURL_Container"); + while ( prefixListContainer.node().firstChild ) { + prefixListContainer.node().removeChild(prefixListContainer.node().firstChild); + } + setupPrefixList(); + }; + + editSidebar.setup = function (){ + setupCollapsing(); + setupPrefixList(); + setupAddPrefixButton(); + setupSupportedDatatypes(); + + + d3.select("#titleEditor") + .on("change", function (){ + graph.options().addOrUpdateGeneralObjectEntry("title", d3.select("#titleEditor").node().value); + }) + .on("keydown", function (){ + d3.event.stopPropagation(); + if ( d3.event.keyCode === 13 ) { + d3.event.preventDefault(); + graph.options().addOrUpdateGeneralObjectEntry("title", d3.select("#titleEditor").node().value); + } + }); + d3.select("#iriEditor") + .on("change", function (){ + if ( graph.options().addOrUpdateGeneralObjectEntry("iri", d3.select("#iriEditor").node().value) === false ) { + // restore value + d3.select("#iriEditor").node().value = graph.options().getGeneralMetaObjectProperty('iri'); + } + }) + .on("keydown", function (){ + d3.event.stopPropagation(); + if ( d3.event.keyCode === 13 ) { + d3.event.preventDefault(); + if ( graph.options().addOrUpdateGeneralObjectEntry("iri", d3.select("#iriEditor").node().value) === false ) { + // restore value + d3.select("#iriEditor").node().value = graph.options().getGeneralMetaObjectProperty('iri'); + } + } + }); + d3.select("#versionEditor") + .on("change", function (){ + graph.options().addOrUpdateGeneralObjectEntry("version", d3.select("#versionEditor").node().value); + }) + .on("keydown", function (){ + d3.event.stopPropagation(); + if ( d3.event.keyCode === 13 ) { + d3.event.preventDefault(); + graph.options().addOrUpdateGeneralObjectEntry("version", d3.select("#versionEditor").node().value); + } + }); + d3.select("#authorsEditor") + .on("change", function (){ + graph.options().addOrUpdateGeneralObjectEntry("author", d3.select("#authorsEditor").node().value); + }) + .on("keydown", function (){ + d3.event.stopPropagation(); + if ( d3.event.keyCode === 13 ) { + d3.event.preventDefault(); + graph.options().addOrUpdateGeneralObjectEntry("author", d3.select("#authorsEditor").node().value); + } + }); + d3.select("#descriptionEditor") + .on("change", function (){ + graph.options().addOrUpdateGeneralObjectEntry("description", d3.select("#descriptionEditor").node().value); + }); + + editSidebar.updateElementWidth(); + + }; + + function setupSupportedDatatypes(){ + var datatypeEditorSelection = d3.select("#typeEditor_datatype").node(); + var supportedDatatypes = ["undefined", "xsd:boolean", "xsd:double", "xsd:integer", "xsd:string"]; + for ( var i = 0; i < supportedDatatypes.length; i++ ) { + var optB = document.createElement('option'); + optB.innerHTML = supportedDatatypes[i]; + datatypeEditorSelection.appendChild(optB); + } + } + + function highlightDeleteButton( enable, name ){ + var deletePath = d3.select("#del_pathFor_" + name); + var deleteRect = d3.select("#del_rectFor_" + name); + + if ( enable === false ) { + deletePath.node().style = "stroke: #f00;"; + deleteRect.style("cursor", "auto"); + } else { + deletePath.node().style = "stroke: #ff972d;"; + deleteRect.style("cursor", "pointer"); + } + } + + + function highlightEditButton( enable, name, fill ){ + var editPath = d3.select("#pathFor_" + name); + var editRect = d3.select("#rectFor_" + name); + + if ( enable === false ) { + if ( fill ) + editPath.node().style = "fill: #fff; stroke : #fff; stroke-width : 1px"; + else + editPath.node().style = " stroke : #fff; stroke-width : 1px"; + + editRect.style("cursor", "auto"); + } else { + if ( fill ) + editPath.node().style = "fill: #ff972d; stroke : #ff972d; stroke-width : 1px"; + else + editPath.node().style = "stroke : #ff972d; stroke-width : 1px"; + editRect.style("cursor", "pointer"); + } + + } + + function setupAddPrefixButton(){ + var btn = d3.select("#addPrefixButton"); + btn.on("click", function (){ + + // check if we are still in editMode? + if ( prefix_editMode === false ) { + // create new line entry; + var name = "emptyPrefixEntry"; + var prefixListContainer = d3.select("#prefixURL_Container"); + var prefixEditContainer = prefixListContainer.append("div"); + prefixEditContainer.classed("prefixIRIElements", true); + prefixEditContainer.node().id = "prefixContainerFor_" + name; + + var IconContainer = prefixEditContainer.append("div"); + IconContainer.style("position", "absolute"); + IconContainer.node().id = "containerFor_" + name; + var editButton = IconContainer.append("svg"); + editButton.style("width", "14px"); + editButton.style("height", "20px"); + // editButton.classed("editPrefixButton", true); + editButton.classed("noselect", true); + //editButton.node().innerHTML = "\u2714"; + editButton.node().id = "editButtonFor_" + name; + + editButton.node().elementStyle = "save"; + editButton.node().selectorName = name; + var editIcon = editButton.append("g"); + var editRect = editIcon.append("rect"); + var editPath = editIcon.append("path"); + editIcon.node().id = "iconFor_" + name; + editPath.node().id = "pathFor_" + name; + editRect.node().id = "rectFor_" + name; + + editIcon.node().selectorName = name; + editPath.node().selectorName = name; + editRect.node().selectorName = name; + IconContainer.node().title = "Save new prefix and IRI"; + + editPath.classed("editPrefixIcon"); + editPath.style("stroke", "#fff"); + editPath.style("stroke-width", "1px"); + editPath.style("fill", "#fff"); + editRect.attr("width", "14px"); + editRect.attr("height", "14px"); + editRect.style("fill", "#18202A"); + editRect.attr("transform", "matrix(1,0,0,1,-3,4)"); + + editButton.selectAll("g").on("mouseover", function (){ + highlightEditButton(true, this.selectorName, true); + }); + editButton.selectAll("g").on("mouseout", function (){ + highlightEditButton(false, this.selectorName, true); + }); + // Check mark + // M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z + // pencil + // M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z + editPath.attr("d", "M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"); + editPath.attr("transform", "matrix(0.45,0,0,0.45,0,5)"); + + var prefInput = prefixEditContainer.append("input"); + prefInput.classed("prefixInput", true); + prefInput.node().type = "text"; + prefInput.node().id = "prefixInputFor_" + name; + prefInput.node().autocomplete = "off"; + prefInput.node().value = ""; + prefInput.style("margin-left", "14px"); + + var prefURL = prefixEditContainer.append("input"); + prefURL.classed("prefixURL", true); + prefURL.node().type = "text"; + prefURL.node().id = "prefixURLFor_" + name; + prefURL.node().autocomplete = "off"; + prefURL.node().value = ""; + + prefInput.node().disabled = false; + prefURL.node().disabled = false; + prefix_editMode = true; + var deleteContainer = prefixEditContainer.append("div"); + deleteContainer.style("float", "right"); + var deleteButton = deleteContainer.append("svg"); + deleteButton.node().id = "deleteButtonFor_" + name; + deleteContainer.node().title = "Delete prefix and IRI"; + deleteButton.style("width", "10px"); + deleteButton.style("height", "20px"); + var deleteIcon = deleteButton.append("g"); + var deleteRect = deleteIcon.append("rect"); + var deletePath = deleteIcon.append("path"); + deleteIcon.node().id = "del_iconFor_" + name; + deletePath.node().id = "del_pathFor_" + name; + deleteRect.node().id = "del_rectFor_" + name; + + deleteIcon.node().selectorName = name; + deletePath.node().selectorName = name; + deleteRect.node().selectorName = name; + + + deletePath.style("stroke", "#f00"); + deleteRect.attr("width", "10px"); + deleteRect.attr("height", "14px"); + deleteRect.style("fill", "#18202A"); + deleteRect.attr("transform", "matrix(1,0,0,1,-3,4)"); + + + deletePath.attr("d", "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"); + deletePath.attr("transform", "matrix(0.45,0,0,0.45,0,5)"); + + deleteButton.selectAll("g").on("mouseover", function (){ + highlightDeleteButton(true, this.selectorName); + }); + deleteButton.selectAll("g").on("mouseout", function (){ + highlightDeleteButton(false, this.selectorName); + }); + + + // connect the buttons; + editButton.on("click", enablePrefixEdit); + deleteButton.on("click", deletePrefixLine); + + editSidebar.updateElementWidth(); + // swap focus to prefixInput + prefInput.node().focus(); + oldPrefix = name; + oldPrefixURL = ""; + d3.select("#addPrefixButton").node().innerHTML = "Save Prefix"; + } else { + d3.select("#editButtonFor_emptyPrefixEntry").on("click")(d3.select("#editButtonFor_emptyPrefixEntry").node()); + } + + }); + + } + + function setupPrefixList(){ + if ( graph.isEditorMode() === false ) return; + var prefixListContainer = d3.select("#prefixURL_Container"); + var prefixElements = graph.options().prefixList(); + for ( var name in prefixElements ) { + if ( prefixElements.hasOwnProperty(name) ) { + var prefixEditContainer = prefixListContainer.append("div"); + prefixEditContainer.classed("prefixIRIElements", true); + prefixEditContainer.node().id = "prefixContainerFor_" + name; + + // create edit button which enables the input fields + var IconContainer = prefixEditContainer.append("div"); + IconContainer.style("position", "absolute"); + IconContainer.node().id = "containerFor_" + name; + var editButton = IconContainer.append("svg"); + editButton.style("width", "14px"); + editButton.style("height", "20px"); + editButton.classed("noselect", true); + editButton.node().id = "editButtonFor_" + name; + IconContainer.node().title = "Edit prefix and IRI"; + editButton.node().elementStyle = "save"; + editButton.node().selectorName = name; + + editButton.node().id = "editButtonFor_" + name; + editButton.node().elementStyle = "edit"; + var editIcon = editButton.append("g"); + var editRect = editIcon.append("rect"); + var editPath = editIcon.append("path"); + editIcon.node().id = "iconFor_" + name; + editPath.node().id = "pathFor_" + name; + editRect.node().id = "rectFor_" + name; + + editIcon.node().selectorName = name; + editPath.node().selectorName = name; + editRect.node().selectorName = name; + + + editPath.classed("editPrefixIcon"); + editPath.style("stroke", "#fff"); + editPath.style("stroke-width", "1px"); + editRect.attr("width", "14px"); + editRect.attr("height", "14px"); + editRect.style("fill", "#18202A"); + editRect.attr("transform", "matrix(1,0,0,1,-3,4)"); + + editButton.selectAll("g").on("mouseover", function (){ + var sender = this; + var fill = false; + var enable = true; + var f_editPath = d3.select("#pathFor_" + sender.selectorName); + var f_editRect = d3.select("#rectFor_" + sender.selectorName); + + if ( enable === false ) { + if ( fill ) + f_editPath.node().style = "fill: #fff; stroke : #fff; stroke-width : 1px"; + else + f_editPath.node().style = " stroke : #fff; stroke-width : 1px"; + + f_editRect.style("cursor", "auto"); + } else { + if ( fill ) + f_editPath.node().style = "fill: #ff972d; stroke : #ff972d; stroke-width : 1px"; + else + f_editPath.node().style = "stroke : #ff972d; stroke-width : 1px"; + f_editRect.style("cursor", "pointer"); + } + }); + editButton.selectAll("g").on("mouseout", function (){ + var sender = this; + var fill = false; + var enable = false; + var f_editPath = d3.select("#pathFor_" + sender.selectorName); + var f_editRect = d3.select("#rectFor_" + sender.selectorName); + + if ( enable === false ) { + if ( fill ) + f_editPath.node().style = "fill: #fff; stroke : #fff; stroke-width : 1px"; + else + f_editPath.node().style = " stroke : #fff; stroke-width : 1px"; + + f_editRect.style("cursor", "auto"); + } else { + if ( fill ) + f_editPath.node().style = "fill: #ff972d; stroke : #ff972d; stroke-width : 1px"; + else + f_editPath.node().style = "stroke : #ff972d; stroke-width : 1px"; + f_editRect.style("cursor", "pointer"); + } + }); + + editPath.attr("d", "M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"); + editPath.attr("transform", "matrix(-0.45,0,0,0.45,10,5)"); + + // create input field for prefix + var prefInput = prefixEditContainer.append("input"); + prefInput.classed("prefixInput", true); + prefInput.node().type = "text"; + prefInput.node().id = "prefixInputFor_" + name; + prefInput.node().autocomplete = "off"; + prefInput.node().value = name; + prefInput.style("margin-left", "14px"); + + // create input field for prefix url + var prefURL = prefixEditContainer.append("input"); + prefURL.classed("prefixURL", true); + prefURL.node().type = "text"; + prefURL.node().id = "prefixURLFor_" + name; + prefURL.node().autocomplete = "off"; + prefURL.node().value = prefixElements[name]; + prefURL.node().title = prefixElements[name]; + // disable the input fields (already defined elements can be edited later) + prefInput.node().disabled = true; + prefURL.node().disabled = true; + + // create the delete button + var deleteContainer = prefixEditContainer.append("div"); + deleteContainer.style("float", "right"); + var deleteButton = deleteContainer.append("svg"); + deleteButton.node().id = "deleteButtonFor_" + name; + deleteContainer.node().title = "Delete prefix and IRI"; + deleteButton.style("width", "10px"); + deleteButton.style("height", "20px"); + var deleteIcon = deleteButton.append("g"); + var deleteRect = deleteIcon.append("rect"); + var deletePath = deleteIcon.append("path"); + deleteIcon.node().id = "del_iconFor_" + name; + deletePath.node().id = "del_pathFor_" + name; + deleteRect.node().id = "del_rectFor_" + name; + + deleteIcon.node().selectorName = name; + deletePath.node().selectorName = name; + deleteRect.node().selectorName = name; + + + deletePath.style("stroke", "#f00"); + deleteRect.attr("width", "10px"); + deleteRect.attr("height", "14px"); + deleteRect.style("fill", "#18202A"); + deleteRect.attr("transform", "matrix(1,0,0,1,-3,4)"); + + + deletePath.attr("d", "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"); + deletePath.attr("transform", "matrix(0.45,0,0,0.45,0,5)"); + + deleteButton.selectAll("g").on("mouseover", function (){ + var selector = this; + var enable = true; + var f_deletePath = d3.select("#del_pathFor_" + selector.selectorName); + var f_deleteRect = d3.select("#del_rectFor_" + selector.selectorName); + + if ( enable === false ) { + f_deletePath.node().style = "stroke: #f00;"; + f_deleteRect.style("cursor", "auto"); + } else { + f_deletePath.node().style = "stroke: #ff972d;"; + f_deleteRect.style("cursor", "pointer"); + } + }); + deleteButton.selectAll("g").on("mouseout", function (){ + var selector = this; + var enable = false; + var f_deletePath = d3.select("#del_pathFor_" + selector.selectorName); + var f_deleteRect = d3.select("#del_rectFor_" + selector.selectorName); + + if ( enable === false ) { + f_deletePath.node().style = "stroke: #f00;"; + f_deleteRect.style("cursor", "auto"); + } else { + f_deletePath.node().style = "stroke: #ff972d;"; + f_deleteRect.style("cursor", "pointer"); + } + }); + + + editButton.on("click", enablePrefixEdit); + deleteButton.on("click", deletePrefixLine); + + // EXPERIMENTAL + + if ( name === "rdf" || + name === "rdfs" || + name === "xsd" || name === "dc" || + name === "owl" + ) { + // make them invis so the spacing does not change + IconContainer.classed("hidden", true); + deleteContainer.classed("hidden", true); + } + } + } + prefixModule.updatePrefixModel(); + } + + function deletePrefixLine(){ + if ( this.disabled === true ) return; + d3.select("#addPrefixButton").node().innerHTML = "Add Prefix"; + var selector = this.id.split("_")[1]; + d3.select("#prefixContainerFor_" + selector).remove(); + graph.options().removePrefix(selector); + prefix_editMode = false; // < 0 ) { + var basePref = graph.options().prefixList()[pr]; + if ( basePref === undefined ) { + console.log("ERROR __________________"); + graph.options().warningModule().showWarning("Invalid Element IRI", + "Could not resolve prefix '" + basePref + "'", + "Restoring previous IRI for Element" + element.iri(), 1, false); + d3.select("#element_iriEditor").node().value = element.iri(); + return; + + } + // check if url is not empty + + if ( name.length === 0 ) { + graph.options().warningModule().showWarning("Invalid Element IRI", + "Input IRI is EMPTY", + "Restoring previous IRI for Element" + element.iri(), 1, false); + console.log("NO INPUT PROVIDED"); + d3.select("#element_iriEditor").node().value = element.iri(); + return; + + } + url = basePref + name; + } + else { + url = base + name; + } + } else { + if ( url.length === 0 ) { + // + console.log("NO INPUT PROVIDED"); + d3.select("#element_iriEditor").node().value = element.iri(); + return; + } + // failed to identify anything useful + console.log("Tryig to use the input!"); + url = base + url; + } + } + return url; + } + + function changeIriForElement( element ){ + var url = getURLFROMPrefixedVersion(element); + var base = graph.options().getGeneralMetaObjectProperty("iri"); + var sanityCheckResult; + if ( elementTools.isNode(element) ) { + + sanityCheckResult = graph.checkIfIriClassAlreadyExist(url); + if ( sanityCheckResult === false ) { + element.iri(url); + } else { + // throw warnign + graph.options().warningModule().showWarning("Already seen this class", + "Input IRI: " + url + " for element: " + element.labelForCurrentLanguage() + " already been set", + "Restoring previous IRI for Element : " + element.iri(), 2, false, sanityCheckResult); + + editSidebar.updateSelectionInformation(element); + return; + + } + } + if ( elementTools.isProperty(element) === true ) { + sanityCheckResult = editSidebar.checkProperIriChange(element, url); + if ( sanityCheckResult !== false ) { + graph.options().warningModule().showWarning("Already seen this property", + "Input IRI: " + url + " for element: " + element.labelForCurrentLanguage() + " already been set", + "Restoring previous IRI for Element : " + element.iri(), 1, false, sanityCheckResult); + + editSidebar.updateSelectionInformation(element); + return; + } + } + + // if (element.existingPropertyIRI(url)===true){ + // console.log("I Have seen this Particular URL already "+url); + // graph.options().warningModule().showWarning("Already Seen This one ", + // "Input IRI For Element"+ element.labelForCurrentLanguage()+" already been set ", + // "Restoring previous IRI for Element"+element.iri(),1,false); + // d3.select("#element_iriEditor").node().value=graph.options().prefixModule().getPrefixRepresentationForFullURI(element.iri()); + // editSidebar.updateSelectionInformation(element); + // return; + // } + + element.iri(url); + if ( identifyExternalCharacteristicForElement(base, url) === true ) { + addAttribute(element, "external"); + // background color for external element; + element.backgroundColor("#36C"); + element.redrawElement(); + element.redrawLabelText(); + // handle visual selection + + } else { + removeAttribute(element, "external"); + // background color for external element; + element.backgroundColor(undefined); + element.redrawElement(); + element.redrawLabelText(); + + } + + if ( element.focused() ) { + graph.options().focuserModule().handle(element, true); // unfocus + graph.options().focuserModule().handle(element, true); // focus + } + // graph.options().focuserModule().handle(undefined); + + + d3.select("#element_iriEditor").node().value = prefixModule.getPrefixRepresentationForFullURI(url); + editSidebar.updateSelectionInformation(element); + } + + function validURL( str ){ + var urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/; + return urlregex.test(str); + } + + + function changeLabelForElement( element ){ + element.label(d3.select("#element_labelEditor").node().value); + element.redrawLabelText(); + } + + editSidebar.updateEditDeleteButtonIds = function ( oldPrefix, newPrefix ){ + d3.select("#prefixInputFor_" + oldPrefix).node().id = "prefixInputFor_" + newPrefix; + d3.select("#prefixURLFor_" + oldPrefix).node().id = "prefixURLFor_" + newPrefix; + d3.select("#deleteButtonFor_" + oldPrefix).node().id = "deleteButtonFor_" + newPrefix; + d3.select("#editButtonFor_" + oldPrefix).node().id = "editButtonFor_" + newPrefix; + + d3.select("#prefixContainerFor_" + oldPrefix).node().id = "prefixContainerFor_" + newPrefix; + }; + + editSidebar.checkForExistingURL = function ( url ){ + var i; + var allProps = graph.getUnfilteredData().properties; + for ( i = 0; i < allProps.length; i++ ) { + if ( allProps[i].iri() === url ) return true; + } + return false; + + }; + editSidebar.checkProperIriChange = function ( element, url ){ + console.log("Element changed Label"); + console.log("Testing URL " + url); + if ( element.type() === "rdfs:subClassOf" || element.type() === "owl:disjointWith" ) { + console.log("ignore this for now, already handled in the type and domain range changer"); + } else { + var i; + var allProps = graph.getUnfilteredData().properties; + for ( i = 0; i < allProps.length; i++ ) { + if ( allProps[i] === element ) continue; + if ( allProps[i].iri() === url ) return allProps[i]; + } + } + return false; + }; + + editSidebar.updateSelectionInformation = function ( element ){ + + if ( element === undefined ) { + // show hint; + d3.select("#selectedElementProperties").classed("hidden", true); + d3.select("#selectedElementPropertiesEmptyHint").classed("hidden", false); + selectedElementForCharacteristics = null; + editSidebar.updateElementWidth(); + } + else { + d3.select("#selectedElementProperties").classed("hidden", false); + d3.select("#selectedElementPropertiesEmptyHint").classed("hidden", true); + d3.select("#typeEditForm_datatype").classed("hidden", true); + + // set the element IRI, and labels + d3.select("#element_iriEditor").node().value = element.iri(); + d3.select("#element_labelEditor").node().value = element.labelForCurrentLanguage(); + d3.select("#element_iriEditor").node().title = element.iri(); + + d3.select("#element_iriEditor") + .on("change", function (){ + var elementIRI = element.iri(); + var prefixed = graph.options().prefixModule().getPrefixRepresentationForFullURI(elementIRI); + if ( prefixed === d3.select("#element_iriEditor").node().value ) { + console.log("Iri is identical, nothing has changed!"); + return; + } + + changeIriForElement(element); + }) + .on("keydown", function (){ + d3.event.stopPropagation(); + if ( d3.event.keyCode === 13 ) { + d3.event.preventDefault(); + console.log("IRI CHANGED Via ENTER pressed"); + changeIriForElement(element); + d3.select("#element_iriEditor").node().title = element.iri(); + } + }); + + var forceIRISync = defaultIriValue(element); + d3.select("#element_labelEditor") + .on("change", function (){ + var sanityCheckResult; + console.log("Element changed Label"); + var url = getURLFROMPrefixedVersion(element); + if ( element.iri() !== url ) { + if ( elementTools.isProperty(element) === true ) { + sanityCheckResult = editSidebar.checkProperIriChange(element, url); + if ( sanityCheckResult !== false ) { + graph.options().warningModule().showWarning("Already seen this property", + "Input IRI: " + url + " for element: " + element.labelForCurrentLanguage() + " already been set", + "Continuing with duplicate property!", 1, false, sanityCheckResult); + editSidebar.updateSelectionInformation(element); + return; + } + } + + if ( elementTools.isNode(element) === true ) { + sanityCheckResult = graph.checkIfIriClassAlreadyExist(url); + if ( sanityCheckResult !== false ) { + graph.options().warningModule().showWarning("Already seen this Class", + "Input IRI: " + url + " for element: " + element.labelForCurrentLanguage() + " already been set", + "Restoring previous IRI for Element : " + element.iri(), 2, false, sanityCheckResult); + + editSidebar.updateSelectionInformation(element); + return; + } + } + element.iri(url); + } + changeLabelForElement(element); + editSidebar.updateSelectionInformation(element); // prevents that it will be changed if node is still active + }) + .on("keydown", function (){ + d3.event.stopPropagation(); + if ( d3.event.keyCode === 13 ) { + d3.event.preventDefault(); + var sanityCheckResult; + console.log("Element changed Label"); + var url = getURLFROMPrefixedVersion(element); + if ( element.iri() !== url ) { + if ( elementTools.isProperty(element) === true ) { + sanityCheckResult = editSidebar.checkProperIriChange(element, url); + if ( sanityCheckResult !== false ) { + graph.options().warningModule().showWarning("Already seen this property", + "Input IRI: " + url + " for element: " + element.labelForCurrentLanguage() + " already been set", + "Continuing with duplicate property!", 1, false, sanityCheckResult); + + editSidebar.updateSelectionInformation(element); + return; + } + } + + if ( elementTools.isNode(element) === true ) { + sanityCheckResult = graph.checkIfIriClassAlreadyExist(url); + if ( sanityCheckResult !== false ) { + graph.options().warningModule().showWarning("Already seen this Class", + "Input IRI: " + url + " for element: " + element.labelForCurrentLanguage() + " already been set", + "Restoring previous IRI for Element : " + element.iri(), 2, false, sanityCheckResult); + + editSidebar.updateSelectionInformation(element); + return; + } + } + element.iri(url); + } + changeLabelForElement(element); + } + }) + .on("keyup", function (){ + if ( forceIRISync ) { + var labelName = d3.select("#element_labelEditor").node().value; + var resourceName = labelName.replaceAll(" ", "_"); + var syncedIRI = element.baseIri() + resourceName; + + //element.iri(syncedIRI); + d3.select("#element_iriEditor").node().title = element.iri(); + d3.select("#element_iriEditor").node().value = prefixModule.getPrefixRepresentationForFullURI(syncedIRI); + } + }); + // check if we are allowed to change IRI OR LABEL + d3.select("#element_iriEditor").node().disabled = false; + d3.select("#element_labelEditor").node().disabled = false; + + if ( element.type() === "rdfs:subClassOf" ) { + d3.select("#element_iriEditor").node().value = "http://www.w3.org/2000/01/rdf-schema#subClassOf"; + d3.select("#element_iriEditor").node().title = "http://www.w3.org/2000/01/rdf-schema#subClassOf"; + d3.select("#element_labelEditor").node().value = "Subclass of"; + d3.select("#element_iriEditor").node().disabled = true; + d3.select("#element_labelEditor").node().disabled = true; + } + if ( element.type() === "owl:Thing" ) { + d3.select("#element_iriEditor").node().value = "http://www.w3.org/2002/07/owl#Thing"; + d3.select("#element_iriEditor").node().title = "http://www.w3.org/2002/07/owl#Thing"; + d3.select("#element_labelEditor").node().value = "Thing"; + d3.select("#element_iriEditor").node().disabled = true; + d3.select("#element_labelEditor").node().disabled = true; + } + + if ( element.type() === "owl:disjointWith" ) { + d3.select("#element_iriEditor").node().value = "http://www.w3.org/2002/07/owl#disjointWith"; + d3.select("#element_iriEditor").node().title = "http://www.w3.org/2002/07/owl#disjointWith"; + d3.select("#element_iriEditor").node().disabled = true; + d3.select("#element_labelEditor").node().disabled = true; + } + + if ( element.type() === "rdfs:Literal" ) { + d3.select("#element_iriEditor").node().value = "http://www.w3.org/2000/01/rdf-schema#Literal"; + d3.select("#element_iriEditor").node().title = "http://www.w3.org/2000/01/rdf-schema#Literal"; + d3.select("#element_iriEditor").node().disabled = true; + d3.select("#element_labelEditor").node().disabled = true; + element.iri("http://www.w3.org/2000/01/rdf-schema#Literal"); + } + if ( element.type() === "rdfs:Datatype" ) { + var datatypeEditorSelection = d3.select("#typeEditor_datatype"); + d3.select("#typeEditForm_datatype").classed("hidden", false); + element.iri("http://www.w3.org/2000/01/rdf-schema#Datatype"); + d3.select("#element_iriEditor").node().value = "http://www.w3.org/2000/01/rdf-schema#Datatype"; + d3.select("#element_iriEditor").node().title = "http://www.w3.org/2000/01/rdf-schema#Datatype"; + d3.select("#element_iriEditor").node().disabled = true; + d3.select("#element_labelEditor").node().disabled = true; + + datatypeEditorSelection.node().value = element.dType(); + if ( datatypeEditorSelection.node().value === "undefined" ) { + d3.select("#element_iriEditor").node().disabled = true; // always prevent IRI modifications + d3.select("#element_labelEditor").node().disabled = false; + } + // reconnect the element + datatypeEditorSelection.on("change", function (){ + changeDatatypeType(element); + }); + } + + // add type selector + var typeEditorSelection = d3.select("#typeEditor").node(); + var htmlCollection = typeEditorSelection.children; + var numEntries = htmlCollection.length; + var i; + var elementPrototypes = getElementPrototypes(element); + for ( i = 0; i < numEntries; i++ ) + typeEditorSelection.removeChild(htmlCollection[0]); + + for ( i = 0; i < elementPrototypes.length; i++ ) { + var optA = document.createElement('option'); + optA.innerHTML = elementPrototypes[i]; + typeEditorSelection.appendChild(optA); + } + // set the proper value in the selection + typeEditorSelection.value = element.type(); + d3.select("#typeEditor").on("change", function (){ + elementTypeSelectionChanged(element); + }); + + + // add characteristics selection + var needChar = elementNeedsCharacteristics(element); + d3.select("#property_characteristics_Container").classed("hidden", !needChar); + if ( needChar === true ) { + addElementsCharacteristics(element); + } + var fullURI = d3.select("#element_iriEditor").node().value; + d3.select("#element_iriEditor").node().value = prefixModule.getPrefixRepresentationForFullURI(fullURI); + d3.select("#element_iriEditor").node().title = fullURI; + editSidebar.updateElementWidth(); + } + + }; + + editSidebar.updateGeneralOntologyInfo = function (){ + var preferredLanguage = graph && graph.language ? graph.language() : null; + + // get it from graph.options + var generalMetaObj = graph.options().getGeneralMetaObject(); + if ( generalMetaObj.hasOwnProperty("title") ) { + // title has language to it -.- + if ( typeof generalMetaObj.title === "object" ) { + d3.select("#titleEditor").node().value = languageTools.textInLanguage(generalMetaObj.title, preferredLanguage); + } else + d3.select("#titleEditor").node().value = generalMetaObj.title; + } + if ( generalMetaObj.hasOwnProperty("iri") ) d3.select("#iriEditor").node().value = generalMetaObj.iri; + if ( generalMetaObj.hasOwnProperty("version") ) d3.select("#versionEditor").node().value = generalMetaObj.version; + if ( generalMetaObj.hasOwnProperty("author") ) d3.select("#authorsEditor").node().value = generalMetaObj.author; + + + if ( generalMetaObj.hasOwnProperty("description") ) { + + if ( typeof generalMetaObj.description === "object" ) + d3.select("#descriptionEditor").node().value = + languageTools.textInLanguage(generalMetaObj.description, preferredLanguage); + else + d3.select("#descriptionEditor").node().value = generalMetaObj.description; + } + else + d3.select("#descriptionEditor").node().value = "No Description"; + }; + + editSidebar.updateElementWidth = function (){ + var height = window.innerHeight - 40; + var lsb_offset = d3.select("#logo").node().getBoundingClientRect().height + 5; + var lsb_height = height - lsb_offset; + d3.select("#containerForLeftSideBar").style("top", lsb_offset + "px"); + d3.select("#leftSideBarCollapseButton").style("top", lsb_offset + "px"); + d3.select("#containerForLeftSideBar").style("height", lsb_height + "px"); + + var div_width = d3.select("#generalDetailsEdit").node().getBoundingClientRect().width; + div_width += 10; + + var title_labelWidth = d3.select("#titleEditor-label").node().getBoundingClientRect().width + 20; + var iri_labelWidth = d3.select("#iriEditor-label").node().getBoundingClientRect().width + 20; + var version_labelWidth = d3.select("#versionEditor-label").node().getBoundingClientRect().width + 20; + var author_labelWidth = d3.select("#authorsEditor-label").node().getBoundingClientRect().width + 20; + //find max width; + var maxW = 0; + maxW = Math.max(maxW, title_labelWidth); + maxW = Math.max(maxW, iri_labelWidth); + maxW = Math.max(maxW, version_labelWidth); + maxW = Math.max(maxW, author_labelWidth); + + var meta_inputWidth = div_width - maxW - 10; + + d3.select("#titleEditor").style("width", meta_inputWidth + "px"); + d3.select("#iriEditor").style("width", meta_inputWidth + "px"); + d3.select("#versionEditor").style("width", meta_inputWidth + "px"); + d3.select("#authorsEditor").style("width", meta_inputWidth + "px"); + + + var elementIri_width = d3.select("#element_iriEditor-label").node().getBoundingClientRect().width + 20; + var elementLabel_width = d3.select("#element_labelEditor-label").node().getBoundingClientRect().width + 20; + var elementType_width = d3.select("#typeEditor-label").node().getBoundingClientRect().width + 20; + var elementDType_width = d3.select("#typeEditor_datatype-label").node().getBoundingClientRect().width + 20; + + maxW = 0; + maxW = Math.max(maxW, elementIri_width); + maxW = Math.max(maxW, elementLabel_width); + maxW = Math.max(maxW, elementType_width); + maxW = Math.max(maxW, elementDType_width); + var selectedElement_inputWidth = div_width - maxW - 10; + + d3.select("#element_iriEditor").style("width", selectedElement_inputWidth + "px"); + d3.select("#element_labelEditor").style("width", selectedElement_inputWidth + "px"); + d3.select("#typeEditor").style("width", selectedElement_inputWidth + 4 + "px"); + d3.select("#typeEditor_datatype").style("width", selectedElement_inputWidth + 4 + "px"); + + // update prefix Element width; + var containerWidth = d3.select("#containerForPrefixURL").node().getBoundingClientRect().width; + if ( containerWidth !== 0 ) { + var inputs = d3.selectAll(".prefixInput"); + if ( inputs.node() ) { + var prefixWidth = d3.selectAll(".prefixInput").node().getBoundingClientRect().width; + d3.selectAll(".prefixURL").style("width", containerWidth - prefixWidth - 45 + "px"); + } + } + }; + + function addElementsCharacteristics( element ){ + // save selected element for checkbox handler + selectedElementForCharacteristics = element; + var i; + // KILL old elements + var charSelectionNode = d3.select("#property_characteristics_Selection"); + var htmlCollection = charSelectionNode.node().children; + if ( htmlCollection ) { + var numEntries = htmlCollection.length; + for ( var q = 0; q < numEntries; q++ ) { + charSelectionNode.node().removeChild(htmlCollection[0]); + } + } + // datatypes kind of ignored by the elementsNeedCharacteristics function + // so we need to check if we are a node or not + if ( element.attributes().indexOf("external") > -1 ) { + // add external span to the div; + var externalCharSpan = charSelectionNode.append("span"); + externalCharSpan.classed("spanForCharSelection", true); + externalCharSpan.node().innerHTML = "external"; + } + var filterContainer, + filterCheckbox; + if ( elementTools.isNode(element) === true ) { + // add the deprecated characteristic; + var arrayOfNodeChars = ["deprecated"]; + for ( i = 0; i < arrayOfNodeChars.length; i++ ) { + filterContainer = charSelectionNode + .append("div") + .classed("checkboxContainer", true) + .style("padding-top", "2px"); + + filterCheckbox = filterContainer.append("input") + .classed("filterCheckbox", true) + .attr("id", "CharacteristicsCheckbox" + i) + .attr("type", "checkbox") + .attr("characteristics", arrayOfNodeChars[i]) + .property("checked", getPresentAttribute(element, arrayOfNodeChars[i])); + // + filterContainer.append("label") + .attr("for", "CharacteristicsCheckbox" + i) + .text(arrayOfNodeChars[i]); + + filterCheckbox.on("click", handleCheckBoxClick); + + } + } + + else { + // add the deprecated characteristic; + var arrayOfPropertyChars = ["deprecated", "inverse functional", "functional", "transitive"]; + if ( elementTools.isDatatypeProperty(element) === true ) { + arrayOfPropertyChars = ["deprecated", "functional"]; + } + for ( i = 0; i < arrayOfPropertyChars.length; i++ ) { + filterContainer = charSelectionNode + .append("div") + .classed("checkboxContainer", true) + .style("padding-top", "2px"); + + filterCheckbox = filterContainer.append("input") + .classed("filterCheckbox", true) + .attr("id", "CharacteristicsCheckbox" + i) + .attr("type", "checkbox") + .attr("characteristics", arrayOfPropertyChars[i]) + .property("checked", getPresentAttribute(element, arrayOfPropertyChars[i])); + // + filterContainer.append("label") + .attr("for", "CharacteristicsCheckbox" + i) + .text(arrayOfPropertyChars[i]); + + filterCheckbox.on("click", handleCheckBoxClick); + + } + } + + + } + + function getPresentAttribute( selectedElement, element ){ + return (selectedElement.attributes().indexOf(element) >= 0); + } + + function handleCheckBoxClick(){ + var checked = this.checked; + var char = this.getAttribute("characteristics"); + if ( checked === true ) { + addAttribute(selectedElementForCharacteristics, char); + } else { + removeAttribute(selectedElementForCharacteristics, char); + } + // graph.executeColorExternalsModule(); + selectedElementForCharacteristics.redrawElement(); + // workaround to have the node still be focused as rendering element + selectedElementForCharacteristics.focused(false); + selectedElementForCharacteristics.toggleFocus(); + + } + + + function addAttribute( selectedElement, char ){ + if ( selectedElement.attributes().indexOf(char) === -1 ) { + // not found add it + var attr = selectedElement.attributes(); + attr.push(char); + selectedElement.attributes(attr); + }// indications string update; + if ( selectedElement.indications().indexOf(char) === -1 ) { + var indications = selectedElement.indications(); + indications.push(char); + selectedElement.indications(indications); + } + // add visual attributes + var visAttr; + if ( selectedElement.visualAttributes().indexOf(char) === -1 ) { + visAttr = selectedElement.visualAttributes(); + visAttr.push(char); + selectedElement.visualAttributes(visAttr); + } + if ( getPresentAttribute(selectedElement, "external") && getPresentAttribute(selectedElement, "deprecated") ) { + visAttr = selectedElement.visualAttributes(); + var visInd = visAttr.indexOf("external"); + if ( visInd > -1 ) { + visAttr.splice(visInd, 1); + } + selectedElement.visualAttributes(visAttr); + } + + } + + function removeAttribute( selectedElement, element ){ + var attr = selectedElement.attributes(); + var indications = selectedElement.indications(); + var visAttr = selectedElement.visualAttributes(); + var attrInd = attr.indexOf(element); + if ( attrInd >= 0 ) { + attr.splice(attrInd, 1); + } + var indInd = indications.indexOf(element); + if ( indInd > -1 ) { + indications.splice(indInd, 1); + } + var visInd = visAttr.indexOf(element); + if ( visInd > -1 ) { + visAttr.splice(visInd, 1); + } + selectedElement.attributes(attr); + selectedElement.indications(indications); + selectedElement.visualAttributes(visAttr); + if ( element === "deprecated" ) { + // set its to its original Style + //typeBaseThign + // todo : fix all different types + if ( selectedElement.type() === "owl:Class" ) selectedElement.styleClass("class"); + if ( selectedElement.type() === "owl:DatatypeProperty" ) selectedElement.styleClass("datatypeproperty"); + if ( selectedElement.type() === "owl:ObjectProperty" ) selectedElement.styleClass("objectproperty"); + if ( selectedElement.type() === "owl:disjointWith" ) selectedElement.styleClass("disjointwith"); + } + } + + + function elementNeedsCharacteristics( element ){ + //TODO: Add more types + if ( element.type() === "owl:Thing" || + element.type() === "rdfs:subClassOf" || + element.type() === "rdfs:Literal" || + element.type() === "rdfs:Datatype" || + element.type() === "rdfs:disjointWith" ) + return false; + + // if (element.attributes().indexOf("external")|| + // element.attributes().indexOf("deprecated")) + // return true; + return true; + + } + + function elementTypeSelectionChanged( element ){ + if ( elementTools.isNode(element) ) { + if ( graph.changeNodeType(element) === false ) { + //restore old value + + if ( elementTools.isDatatype(element) === true ) { + + } + editSidebar.updateSelectionInformation(element); + } + } + + if ( elementTools.isProperty(element) ) { + if ( graph.changePropertyType(element) === false ) { + //restore old value + editSidebar.updateSelectionInformation(element); + + } + } + + } + + function getElementPrototypes( selectedElement ){ + var availiblePrototypes = []; + // TODO the text should be also complied with the prefixes loaded into the ontology + if ( elementTools.isProperty(selectedElement) ) { + if ( selectedElement.type() === "owl:DatatypeProperty" ) + availiblePrototypes.push("owl:DatatypeProperty"); + else { + availiblePrototypes.push("owl:ObjectProperty"); + // handling loops ! + if ( selectedElement.domain() !== selectedElement.range() ) { + availiblePrototypes.push("rdfs:subClassOf"); + } + availiblePrototypes.push("owl:disjointWith"); + availiblePrototypes.push("owl:allValuesFrom"); + availiblePrototypes.push("owl:someValuesFrom"); + } + return availiblePrototypes; + } + if ( selectedElement.renderType() === "rect" ) { + availiblePrototypes.push("rdfs:Literal"); + availiblePrototypes.push("rdfs:Datatype"); + } else { + availiblePrototypes.push("owl:Class"); + availiblePrototypes.push("owl:Thing"); + // TODO: ADD MORE TYPES + // availiblePrototypes.push("owl:complementOf"); + // availiblePrototypes.push("owl:disjointUnionOf"); + } + return availiblePrototypes; + } + + + function setupCollapsing(){ + // TODO : Decision , for now I want to have the control over the collapse expand operation of the + // TODO : elements, otherwise the old approach will also randomly collapse other containers + + // adapted version of this example: http://www.normansblog.de/simple-jquery-accordion/ + function collapseContainers( containers ){ + containers.classed("hidden", true); + } + + function expandContainers( containers ){ + containers.classed("hidden", false); + } + + var triggers = d3.selectAll(".accordion-trigger"); + + // Collapse all inactive triggers on startup + // collapseContainers(d3.selectAll(".accordion-trigger:not(.accordion-trigger-active) + div")); + + triggers.on("click", function (){ + var selectedTrigger = d3.select(this); + if ( selectedTrigger.classed("accordion-trigger-active") ) { + // Collapse the active (which is also the selected) trigger + collapseContainers(d3.select(selectedTrigger.node().nextElementSibling)); + selectedTrigger.classed("accordion-trigger-active", false); + } else { + // Collapse the other trigger ... + // collapseContainers(d3.selectAll(".accordion-trigger-active + div")); + + // ... and expand the selected one + expandContainers(d3.select(selectedTrigger.node().nextElementSibling)); + selectedTrigger.classed("accordion-trigger-active", true); + } + editSidebar.updateElementWidth(); + }); + } + + return editSidebar; +}; diff --git a/src/app/js/entry.js b/src/app/js/entry.js new file mode 100644 index 0000000000000000000000000000000000000000..3bb3f1e958f80d962b9767577f33d9f3125e132f --- /dev/null +++ b/src/app/js/entry.js @@ -0,0 +1,4 @@ +require("../css/toolstyle.css"); +require("./browserWarning"); + +module.exports = require("./app"); diff --git a/src/app/js/leftSidebar.js b/src/app/js/leftSidebar.js new file mode 100644 index 0000000000000000000000000000000000000000..e1b25fb512607f5bf05dcb7d5ef92279f961f7fd --- /dev/null +++ b/src/app/js/leftSidebar.js @@ -0,0 +1,268 @@ +/** + * Contains the logic for the sidebar. + * @param graph the graph that belongs to these controls + * @returns {{}} + */ +module.exports = function ( graph ){ + + var leftSidebar = {}, + languageTools = webvowl.util.languageTools(), + elementTools = webvowl.util.elementTools(); + var collapseButton = d3.select("#leftSideBarCollapseButton"); + var visibleSidebar = 0; + var backupVisibility = 0; + var sideBarContent = d3.select("#leftSideBarContent"); + var sideBarContainer = d3.select("#containerForLeftSideBar"); + var defaultClassSelectionContainers = []; + var defaultDatatypeSelectionContainers = []; + var defaultPropertySelectionContainers = []; + + leftSidebar.setup = function (){ + setupCollapsing(); + leftSidebar.initSideBarAnimation(); + + collapseButton.on("click", function (){ + graph.options().navigationMenu().hideAllMenus(); + var settingValue = parseInt(leftSidebar.getSidebarVisibility()); + if ( settingValue === 0 ) leftSidebar.showSidebar(1); + else leftSidebar.showSidebar(0); + backupVisibility = settingValue; + }); + + setupSelectionContainers(); + d3.select("#WarningErrorMessages").node().addEventListener("animationend", function (){ + d3.select("#WarningErrorMessages").style("-webkit-animation-name", "none"); + }); + + }; + + leftSidebar.hideCollapseButton = function ( val ){ + sideBarContainer.classed("hidden", val); + }; + + + function unselectAllElements( container ){ + for ( var i = 0; i < container.length; i++ ) + container[i].classed("defaultSelected", false); + } + + function selectThisDefaultElement( element ){ + d3.select(element).classed("defaultSelected", true); + } + + function updateDefaultNameInAccordion( element, identifier ){ + var elementDescription = ""; + if ( identifier === "defaultClass" ) elementDescription = "Class: "; + if ( identifier === "defaultDatatype" ) elementDescription = "Datatype: "; + if ( identifier === "defaultProperty" ) elementDescription = "Property: "; + + d3.select("#" + identifier).node().innerHTML = elementDescription + element.innerHTML; + d3.select("#" + identifier).node().title = element.innerHTML; + } + + function classSelectorFunction(){ + unselectAllElements(defaultClassSelectionContainers); + selectThisDefaultElement(this); + updateDefaultNameInAccordion(this, "defaultClass"); + } + + function datatypeSelectorFunction(){ + unselectAllElements(defaultDatatypeSelectionContainers); + selectThisDefaultElement(this); + updateDefaultNameInAccordion(this, "defaultDatatype"); + } + + function propertySelectorFunction(){ + unselectAllElements(defaultPropertySelectionContainers); + selectThisDefaultElement(this); + updateDefaultNameInAccordion(this, "defaultProperty"); + } + + + function setupSelectionContainers(){ + var classContainer = d3.select("#classContainer"); + var datatypeContainer = d3.select("#datatypeContainer"); + var propertyContainer = d3.select("#propertyContainer"); + // create the supported elements + + var defaultClass = "owl:Class"; + var defaultDatatype = "rdfs:Literal"; + var defaultProperty = "owl:objectProperty"; + + var supportedClasses = graph.options().supportedClasses(); + var supportedDatatypes = graph.options().supportedDatatypes(); + var supportedProperties = graph.options().supportedProperties(); + var i; + + for ( i = 0; i < supportedClasses.length; i++ ) { + var aClassSelectionContainer; + aClassSelectionContainer = classContainer.append("div"); + aClassSelectionContainer.classed("containerForDefaultSelection", true); + aClassSelectionContainer.classed("noselect", true); + aClassSelectionContainer.node().id = "selectedClass" + supportedClasses[i]; + aClassSelectionContainer.node().innerHTML = supportedClasses[i]; + + if ( supportedClasses[i] === defaultClass ) { + selectThisDefaultElement(aClassSelectionContainer.node()); + } + aClassSelectionContainer.on("click", classSelectorFunction); + defaultClassSelectionContainers.push(aClassSelectionContainer); + } + + for ( i = 0; i < supportedDatatypes.length; i++ ) { + var aDTSelectionContainer = datatypeContainer.append("div"); + aDTSelectionContainer.classed("containerForDefaultSelection", true); + aDTSelectionContainer.classed("noselect", true); + aDTSelectionContainer.node().id = "selectedDatatype" + supportedDatatypes[i]; + aDTSelectionContainer.node().innerHTML = supportedDatatypes[i]; + + if ( supportedDatatypes[i] === defaultDatatype ) { + selectThisDefaultElement(aDTSelectionContainer.node()); + } + aDTSelectionContainer.on("click", datatypeSelectorFunction); + defaultDatatypeSelectionContainers.push(aDTSelectionContainer); + } + for ( i = 0; i < supportedProperties.length; i++ ) { + var aPropSelectionContainer = propertyContainer.append("div"); + aPropSelectionContainer.classed("containerForDefaultSelection", true); + aPropSelectionContainer.classed("noselect", true); + aPropSelectionContainer.node().id = "selectedClass" + supportedProperties[i]; + aPropSelectionContainer.node().innerHTML = supportedProperties[i]; + aPropSelectionContainer.on("click", propertySelectorFunction); + if ( supportedProperties[i] === defaultProperty ) { + selectThisDefaultElement(aPropSelectionContainer.node()); + } + defaultPropertySelectionContainers.push(aPropSelectionContainer); + } + } + + function setupCollapsing(){ + // adapted version of this example: http://www.normansblog.de/simple-jquery-accordion/ + function collapseContainers( containers ){ + containers.classed("hidden", true); + } + + function expandContainers( containers ){ + containers.classed("hidden", false); + } + + var triggers = d3.selectAll(".accordion-trigger"); + + // Collapse all inactive triggers on startup + // collapseContainers(d3.selectAll(".accordion-trigger:not(.accordion-trigger-active) + div")); + + triggers.on("click", function (){ + var selectedTrigger = d3.select(this); + if ( selectedTrigger.classed("accordion-trigger-active") ) { + // Collapse the active (which is also the selected) trigger + collapseContainers(d3.select(selectedTrigger.node().nextElementSibling)); + selectedTrigger.classed("accordion-trigger-active", false); + } else { + // Collapse the other trigger ... + // collapseContainers(d3.selectAll(".accordion-trigger-active + div")); + // activeTriggers.classed("accordion-trigger-active", false); + // ... and expand the selected one + expandContainers(d3.select(selectedTrigger.node().nextElementSibling)); + selectedTrigger.classed("accordion-trigger-active", true); + } + }); + } + + + leftSidebar.isSidebarVisible = function (){ + return visibleSidebar; + }; + + leftSidebar.updateSideBarVis = function ( init ){ + var vis = leftSidebar.getSidebarVisibility(); + leftSidebar.showSidebar(parseInt(vis), init); + }; + + leftSidebar.initSideBarAnimation = function (){ + sideBarContainer.node().addEventListener("animationend", function (){ + sideBarContent.classed("hidden", !visibleSidebar); + if ( visibleSidebar === true ) { + sideBarContainer.style("width", "200px"); + sideBarContent.classed("hidden", false); + d3.select("#leftSideBarCollapseButton").style("left", "200px"); + d3.select("#leftSideBarCollapseButton").classed("hidden", false); + d3.select("#WarningErrorMessages").style("left", "100px"); + } + else { + sideBarContainer.style("width", "0px"); + d3.select("#leftSideBarCollapseButton").style("left", "0px"); + d3.select("#WarningErrorMessages").style("left", "0px"); + d3.select("#leftSideBarCollapseButton").classed("hidden", false); + + } + graph.updateCanvasContainerSize(); + graph.options().navigationMenu().updateScrollButtonVisibility(); + }); + }; + + leftSidebar.showSidebar = function ( val, init ){ + // make val to bool + var collapseButton = d3.select("#leftSideBarCollapseButton"); + if ( init === true ) { + visibleSidebar = (backupVisibility === 0); + sideBarContent.classed("hidden", !visibleSidebar); + sideBarContainer.style("-webkit-animation-name", "none"); + d3.select("#WarningErrorMessages").style("-webkit-animation-name", "none"); + if ( visibleSidebar === true ) { + sideBarContainer.style("width", "200px"); + sideBarContent.classed("hidden", false); + d3.select("#leftSideBarCollapseButton").style("left", "200px"); + d3.select("#leftSideBarCollapseButton").classed("hidden", false); + d3.select("#WarningErrorMessages").style("left", "100px"); + collapseButton.node().innerHTML = "<"; + } + + else { + sideBarContainer.style("width", "0px"); + d3.select("#WarningErrorMessages").style("left", "0px"); + d3.select("#leftSideBarCollapseButton").style("left", "0px"); + d3.select("#leftSideBarCollapseButton").classed("hidden", false); + collapseButton.node().innerHTML = ">"; + } + + graph.updateCanvasContainerSize(); + graph.options().navigationMenu().updateScrollButtonVisibility(); + return; + } + + d3.select("#leftSideBarCollapseButton").classed("hidden", true); + + if ( val === 1 ) { + visibleSidebar = true; + collapseButton.node().innerHTML = "<"; + // call expand animation; + sideBarContainer.style("-webkit-animation-name", "l_sbExpandAnimation"); + sideBarContainer.style("-webkit-animation-duration", "0.5s"); + // prepare the animation; + + d3.select("#WarningErrorMessages").style("-webkit-animation-name", "warn_ExpandLeftBarAnimation"); + d3.select("#WarningErrorMessages").style("-webkit-animation-duration", "0.5s"); + + } + if ( val === 0 ) { + visibleSidebar = false; + sideBarContent.classed("hidden", true); + collapseButton.node().innerHTML = ">"; + // call collapse animation + sideBarContainer.style("-webkit-animation-name", "l_sbCollapseAnimation"); + sideBarContainer.style("-webkit-animation-duration", "0.5s"); + d3.select("#WarningErrorMessages").style("-webkit-animation-name", "warn_CollapseLeftBarAnimation"); + d3.select("#WarningErrorMessages").style("-webkit-animation-duration", "0.5s"); + d3.select("#WarningErrorMessages").style("left", "0"); + } + + }; + + leftSidebar.getSidebarVisibility = function (){ + var isHidden = sideBarContent.classed("hidden"); + if ( isHidden === false ) return String(1); + if ( isHidden === true ) return String(0); + }; + + return leftSidebar; +}; diff --git a/src/app/js/loadingModule.js b/src/app/js/loadingModule.js new file mode 100644 index 0000000000000000000000000000000000000000..e065b71a78266ddd9f570c694d4702fd41989754 --- /dev/null +++ b/src/app/js/loadingModule.js @@ -0,0 +1,726 @@ +module.exports = function ( graph ){ + /** some constants **/ + var PREDEFINED = 0, + FILE_UPLOAD = 1, + JSON_URL = 2, + IRI_URL = 3; + + var PROGRESS_BAR_ERROR = 0, + PROGRESS_BAR_BUSY = 1, + PROGRESS_BAR_PERCENT = 2, + progressBarMode = 1; + + var loadingWasSuccessFul = false; + var missingImportsWarning = false; + var showLoadingDetails = false; + var visibilityStatus = true; + + var DEFAULT_JSON_NAME = "foaf"; // This file is loaded by default + var conversion_sessionId; + + /** variable defs **/ + var loadingModule = {}, + menuContainer = d3.select("#loading-info"), + loadingInfoContainer = d3.select("#loadingInfo-container"), + detailsButton = d3.select("#show-loadingInfo-button"), + closeButton = d3.select("#loadingIndicator_closeButton"), + ontologyMenu, + ontologyIdentifierFromURL; + + /** functon defs **/ + loadingModule.checkForScreenSize = function (){ + // checks for window size and adjusts the loading indicator + var w = graph.options().width(), + h = graph.options().height(); + + if ( w < 270 ) { + d3.select("#loading-info").classed("hidden", true); + } else { + // check if it should be visible + if ( visibilityStatus === true ) { + d3.select("#loading-info").classed("hidden", false); + } else { + d3.select("#loading-info").classed("hidden", true); + } + } + if ( h < 150 ) { + d3.select("#loadingInfo_msgBox").classed("hidden", true); + } else { + d3.select("#loadingInfo_msgBox").classed("hidden", false); + } + if ( h < 80 ) { + d3.select("#progressBarContext").classed("hidden", true); + d3.select("#layoutLoadingProgressBarContainer").style("height", "20px"); + } else { + d3.select("#progressBarContext").classed("hidden", false); + d3.select("#layoutLoadingProgressBarContainer").style("height", "50px"); + } + }; + + loadingModule.getMessageVisibilityStatus = function (){ + return visibilityStatus; + }; + + loadingModule.getProgressBarMode = function (){ + return progressBarMode; + }; + + loadingModule.successfullyLoadedOntology = function (){ + return loadingWasSuccessFul; + }; + + loadingModule.missingImportsWarning = function (){ + return missingImportsWarning; + }; + + loadingModule.setOntologyMenu = function ( m ){ + ontologyMenu = m; + }; + + loadingModule.showErrorDetailsMessage = function (){ + loadingModule.showLoadingIndicator(); + loadingModule.expandDetails(); + d3.select("#loadingIndicator_closeButton").classed("hidden", true); + loadingModule.scrollDownDetails(); + }; + + loadingModule.showWarningDetailsMessage = function (){ + d3.select("#currentLoadingStep").style("color", "#ff0"); + loadingModule.showLoadingIndicator(); + loadingModule.expandDetails(); + d3.select("#loadingIndicator_closeButton").classed("hidden", false); + loadingModule.scrollDownDetails(); + }; + + loadingModule.scrollDownDetails = function (){ + var scrollingElement = d3.select("#loadingInfo-container").node(); + scrollingElement.scrollTop = scrollingElement.scrollHeight; + }; + + loadingModule.hideLoadingIndicator = function (){ + d3.select("#loading-info").classed("hidden", true); + visibilityStatus = false; + }; + + loadingModule.showLoadingIndicator = function (){ + d3.select("#loading-info").classed("hidden", false); + visibilityStatus = true; + + }; + + /** -- SETUP -- **/ + loadingModule.setup = function (){ + // create connections for close and details button; + loadingInfoContainer.classed("hidden", !showLoadingDetails); + detailsButton.on("click", function (){ + showLoadingDetails = !showLoadingDetails; + loadingInfoContainer.classed("hidden", !showLoadingDetails); + detailsButton.classed("accordion-trigger-active", showLoadingDetails); + }); + + closeButton.on("click", function (){ + menuContainer.classed("hidden", true); + }); + loadingModule.setBusyMode(); + }; + + loadingModule.updateSize = function (){ + showLoadingDetails = !(loadingInfoContainer.classed("hidden")); + loadingInfoContainer.classed("hidden", !showLoadingDetails); + detailsButton.classed("accordion-trigger-active", showLoadingDetails); + }; + + loadingModule.getDetailsState = function (){ + return showLoadingDetails; + }; + + loadingModule.expandDetails = function (){ + showLoadingDetails = true; + loadingInfoContainer.classed("hidden", !showLoadingDetails); + detailsButton.classed("accordion-trigger-active", showLoadingDetails); + }; + + loadingModule.collapseDetails = function (){ + showLoadingDetails = false; + loadingInfoContainer.classed("hidden", !showLoadingDetails); + detailsButton.classed("accordion-trigger-active", showLoadingDetails); + }; + + loadingModule.setBusyMode = function (){ + d3.select("#currentLoadingStep").style("color", "#fff"); + d3.select("#progressBarValue").node().innherHTML = ""; + d3.select("#progressBarValue").style("width", "20%"); + d3.select("#progressBarValue").classed("busyProgressBar", true); + progressBarMode = PROGRESS_BAR_BUSY; + }; + + loadingModule.setSuccessful = function (){ + d3.select("#currentLoadingStep").style("color", "#0f0"); + }; + + loadingModule.setErrorMode = function (){ + d3.select("#currentLoadingStep").style("color", "#f00"); + d3.select("#progressBarValue").style("width", "0%"); + d3.select("#progressBarValue").classed("busyProgressBar", false); + d3.select("#progressBarValue").node().innherHTML = ""; + progressBarMode = PROGRESS_BAR_ERROR; + }; + + loadingModule.setPercentMode = function (){ + d3.select("#currentLoadingStep").style("color", "#fff"); + d3.select("#progressBarValue").classed("busyProgressBar", false); + d3.select("#progressBarValue").node().innherHTML = "0%"; + d3.select("#progressBarValue").style("width", "0%"); + progressBarMode = PROGRESS_BAR_PERCENT; + }; + + loadingModule.setPercentValue = function ( val ){ + d3.select("#progressBarValue").node().innherHTML = val; + }; + + loadingModule.emptyGraphContentError = function (){ + graph.clearGraphData(); + ontologyMenu.append_message_toLastBulletPoint("failed"); + ontologyMenu.append_message_toLastBulletPoint("
Error: Received empty graph"); + loadingWasSuccessFul = false; + graph.handleOnLoadingError(); + loadingModule.setErrorMode(); + }; + + loadingModule.isThreadCanceled = function (){ + + }; + + loadingModule.initializeLoader = function ( storeCache ){ + if ( storeCache === true && graph.getCachedJsonObj() !== null ) { + // save cached ontology; + var cachedContent = JSON.stringify(graph.getCachedJsonObj()); + var cachedName = ontologyIdentifierFromURL; + ontologyMenu.setCachedOntology(cachedName, cachedContent); + } + conversion_sessionId = -10000; + ontologyMenu.setConversionID(conversion_sessionId); + ontologyMenu.stopLoadingTimer(); + graph.clearGraphData(); + loadingModule.setBusyMode(); + loadingModule.showLoadingIndicator(); + loadingModule.collapseDetails(); + missingImportsWarning = false; + d3.select("#loadingIndicator_closeButton").classed("hidden", true); + ontologyMenu.clearDetailInformation(); + }; + + /** ------------------ URL Interpreter -------------- **/ + loadingModule.parseUrlAndLoadOntology = function ( storeCache ){ + var autoStore = true; + if ( storeCache === false ) { + autoStore = false; + } + + graph.clearAllGraphData(); + loadingModule.initializeLoader(autoStore); + var urlString = String(location); + var parameterArray = identifyParameter(urlString); + ontologyIdentifierFromURL = DEFAULT_JSON_NAME; + loadGraphOptions(parameterArray); // identifies and loads configuration values + var loadingMethod = identifyOntologyLoadingMethod(ontologyIdentifierFromURL); + d3.select("#progressBarValue").node().innerHTML = " "; + switch ( loadingMethod ) { + case 0: + loadingModule.from_presetOntology(ontologyIdentifierFromURL); + break; + case 1: + loadingModule.from_FileUpload(ontologyIdentifierFromURL); + break; + case 2: + loadingModule.from_JSON_URL(ontologyIdentifierFromURL); + break; + case 3: + loadingModule.from_IRI_URL(ontologyIdentifierFromURL); + break; + default: + console.log("Could not identify loading method , or not IMPLEMENTED YET"); + } + }; + + /** ------------------- LOADING --------------------- **/ + // the loading module splits into 3 branches + // 1] PresetOntology Loading + // 2] File Upload + // 3] Load From URL / IRI + + loadingModule.from_JSON_URL = function ( fileName ){ + var filename = decodeURIComponent(fileName.slice("url=".length)); + ontologyIdentifierFromURL = filename; + + var ontologyContent = ""; + if ( ontologyMenu.cachedOntology(filename) ) { + ontologyMenu.append_bulletPoint("Loading already cached ontology: " + filename); + ontologyContent = ontologyMenu.cachedOntology(filename); + loadingWasSuccessFul = true; // cached Ontology should be true; + parseOntologyContent(ontologyContent); + + } else { + // involve the o2v conveter; + ontologyMenu.append_message("Retrieving ontology from JSON URL " + filename); + requestServerTimeStampForJSON_URL(ontologyMenu.callbackLoad_JSON_FromURL, ["read?json=" + filename, filename]); + } + }; + + function requestServerTimeStampForJSON_URL( callback, parameter ){ + d3.xhr("serverTimeStamp", "application/text", function ( error, request ){ + if ( error ) { + // could not get server timestamp -> no connection to owl2vowl + ontologyMenu.append_bulletPoint("Could not establish connection to OWL2VOWL service"); + fallbackForJSON_URL(callback, parameter); + } else { + conversion_sessionId = request.responseText; + ontologyMenu.setConversionID(conversion_sessionId); + parameter.push(conversion_sessionId); + callback(parameter); + } + }); + + } + + loadingModule.requestServerTimeStampForDirectInput = function ( callback, text ){ + d3.xhr("serverTimeStamp", "application/text", function ( error, request ){ + if ( error ) { + // could not get server timestamp -> no connection to owl2vowl + ontologyMenu.append_bulletPoint("Could not establish connection to OWL2VOWL service"); + loadingModule.setErrorMode(); + ontologyMenu.append_message_toLastBulletPoint("
Could not connect to OWL2VOWL service "); + loadingModule.showErrorDetailsMessage(); + d3.select("#progressBarValue").style("width", "0%"); + d3.select("#progressBarValue").classed("busyProgressBar", false); + d3.select("#progressBarValue").text("0%"); + + } else { + conversion_sessionId = request.responseText; + ontologyMenu.setConversionID(conversion_sessionId); + callback(text, ["conversionID" + conversion_sessionId, conversion_sessionId]); + } + }); + }; + + loadingModule.from_IRI_URL = function ( fileName ){ + // owl2vowl converters the given ontology url and returns json file; + var filename = decodeURIComponent(fileName.slice("iri=".length)); + ontologyIdentifierFromURL = filename; + + var ontologyContent = ""; + if ( ontologyMenu.cachedOntology(filename) ) { + ontologyMenu.append_bulletPoint("Loading already cached ontology: " + filename); + ontologyContent = ontologyMenu.cachedOntology(filename); + loadingWasSuccessFul = true; // cached Ontology should be true; + parseOntologyContent(ontologyContent); + } else { + // involve the o2v conveter; + var encoded = encodeURIComponent(filename); + ontologyMenu.append_bulletPoint("Retrieving ontology from IRI: " + filename); + requestServerTimeStampForIRI_Converte(ontologyMenu.callbackLoad_Ontology_FromIRI, ["convert?iri=" + encoded, filename]); + } + }; + + loadingModule.fromFileDrop = function ( fileName, file ){ + d3.select("#progressBarValue").node().innerHTML = " "; + loadingModule.initializeLoader(false); + + ontologyMenu.append_bulletPoint("Retrieving ontology from dropped file: " + fileName); + var ontologyContent = ""; + + // two options here + //1] Direct Json Upload + if ( fileName.match(/\.json$/) ) { + ontologyMenu.setConversionID(-10000); + var reader = new FileReader(); + reader.readAsText(file); + reader.onload = function (){ + ontologyContent = reader.result; + ontologyIdentifierFromURL = fileName; + parseOntologyContent(ontologyContent); + }; + } else { + //2] File Upload to OWL2VOWL Converter + // 1) check if we can get a timeStamp; + var parameterArray = [file, fileName]; + requestServerTimeStamp(ontologyMenu.callbackLoadFromOntology, parameterArray); + } + }; + + + loadingModule.from_FileUpload = function ( fileName ){ + loadingModule.setBusyMode(); + var filename = decodeURIComponent(fileName.slice("file=".length)); + ontologyIdentifierFromURL = filename; + var ontologyContent = ""; + if ( ontologyMenu.cachedOntology(filename) ) { + ontologyMenu.append_bulletPoint("Loading already cached ontology: " + filename); + ontologyContent = ontologyMenu.cachedOntology(filename); + loadingWasSuccessFul = true; // cached Ontology should be true; + parseOntologyContent(ontologyContent); + + } else { + // d3.select("#currentLoadingStep").node().innerHTML="Loading ontology from file "+ filename; + ontologyMenu.append_bulletPoint("Retrieving ontology from file: " + filename); + // get the file + var selectedFile = d3.select("#file-converter-input").property("files")[0]; + // No selection -> this was triggered by the iri. Unequal names -> reuploading another file + if ( !selectedFile || (filename && (filename !== selectedFile.name)) ) { + ontologyMenu.append_message_toLastBulletPoint("
No cached version of \"" + filename + "\" was found.
Please reupload the file."); + loadingModule.setErrorMode(); + d3.select("#progressBarValue").classed("busyProgressBar", false); + graph.handleOnLoadingError(); + return; + } else { + filename = selectedFile.name; + } + + +// two options here +//1] Direct Json Upload + if ( filename.match(/\.json$/) ) { + ontologyMenu.setConversionID(-10000); + var reader = new FileReader(); + reader.readAsText(selectedFile); + reader.onload = function (){ + ontologyContent = reader.result; + ontologyIdentifierFromURL = filename; + parseOntologyContent(ontologyContent); + }; + } else { +//2] File Upload to OWL2VOWL Converter + // 1) check if we can get a timeStamp; + var parameterArray = [selectedFile, filename]; + requestServerTimeStamp(ontologyMenu.callbackLoadFromOntology, parameterArray); + } + } + }; + + function fallbackForJSON_URL( callback, parameter ){ + ontologyMenu.append_message_toLastBulletPoint("
Trying to convert with other communication protocol."); + callback(parameter); + + } + + function fallbackConversion( parameter ){ + ontologyMenu.append_message_toLastBulletPoint("
Trying to convert with other communication protocol."); + var file = parameter[0]; + var name = parameter[1]; + var formData = new FormData(); + formData.append("ontology", file); + + var xhr = new XMLHttpRequest(); + xhr.open("POST", "convert", true); + var ontologyContent = ""; + xhr.onload = function (){ + if ( xhr.status === 200 ) { + ontologyContent = xhr.responseText; + ontologyMenu.setCachedOntology(name, ontologyContent); + ontologyIdentifierFromURL = name; + missingImportsWarning = true; // using this variable for warnings + ontologyMenu.append_message_toLastBulletPoint("
Success, but you are using a deprecated OWL2VOWL service!"); + parseOntologyContent(ontologyContent); + } + }; + + // check what this thing is doing; + xhr.onreadystatechange = function (){ + if ( xhr.readyState === 4 && xhr.status === 0 ) { + ontologyMenu.append_message_toLastBulletPoint("
Old protocol also failed to establish connection to OWL2VOWL service!"); + loadingModule.setErrorMode(); + ontologyMenu.append_bulletPoint("Failed to load ontology"); + ontologyMenu.append_message_toLastBulletPoint("
Could not connect to OWL2VOWL service "); + loadingModule.showErrorDetailsMessage(); + } + }; + xhr.send(formData); + } + + function requestServerTimeStampForIRI_Converte( callback, parameterArray ){ + d3.xhr("serverTimeStamp", "application/text", function ( error, request ){ + loadingModule.setBusyMode(); + if ( error ) { + // could not get server timestamp -> no connection to owl2vowl + ontologyMenu.append_bulletPoint("Could not establish connection to OWL2VOWL service"); + loadingModule.setErrorMode(); + ontologyMenu.append_bulletPoint("Failed to load ontology"); + ontologyMenu.append_message_toLastBulletPoint("
Could not connect to OWL2VOWL service "); + loadingModule.showErrorDetailsMessage(); + } else { + conversion_sessionId = request.responseText; + ontologyMenu.setConversionID(conversion_sessionId); + // update paramater for new communication paradigm + parameterArray[0] = parameterArray[0] + "&sessionId=" + conversion_sessionId; + parameterArray.push(conversion_sessionId); + callback(parameterArray); + } + }); + } + + function requestServerTimeStamp( callback, parameterArray ){ + d3.xhr("serverTimeStamp", "application/text", function ( error, request ){ + if ( error ) { + // could not get server timestamp -> no connection to owl2vowl + ontologyMenu.append_bulletPoint("Could not establish connection to OWL2VOWL service"); + fallbackConversion(parameterArray); // tries o2v version0.3.4 communication + } else { + conversion_sessionId = request.responseText; + ontologyMenu.setConversionID(conversion_sessionId); + console.log("Request Session ID:" + conversion_sessionId); + callback(parameterArray[0], parameterArray[1], conversion_sessionId); + } + }); + } + + loadingModule.directInput = function ( text ){ + ontologyMenu.clearDetailInformation(); + parseOntologyContent(text); + }; + + loadingModule.loadFromOWL2VOWL = function ( ontoContent, filename ){ + loadingWasSuccessFul = false; + + var old = d3.select("#bulletPoint_container").node().innerHTML; + if ( old.indexOf("(with warnings)") !== -1 ) { + missingImportsWarning = true; + } + + if ( ontologyMenu.cachedOntology(ontoContent) ) { + ontologyMenu.append_bulletPoint("Loading already cached ontology: " + filename); + parseOntologyContent(ontoContent); + } else { // set parse the ontology content; + parseOntologyContent(ontoContent); + } + }; + + loadingModule.from_presetOntology = function ( selectedOntology ){ + ontologyMenu.append_bulletPoint("Retrieving ontology: " + selectedOntology); + loadPresetOntology(selectedOntology); + }; + + function loadPresetOntology( ontology ){ + // check if already cached in ontology menu? + var f2r; + var loadingNewOntologyForEditor=false; + if ( ontology.indexOf("new_ontology") !== -1 ) { + loadingModule.hideLoadingIndicator(); + graph.showEditorHintIfNeeded(); + f2r = "./data/new_ontology.json"; + loadingNewOntologyForEditor=true; + } + + loadingWasSuccessFul = false; + var ontologyContent = ""; + if ( ontologyMenu.cachedOntology(ontology) ) { + ontologyMenu.append_bulletPoint("Loading already cached ontology: " + ontology); + ontologyContent = ontologyMenu.cachedOntology(ontology); + loadingWasSuccessFul = true; // cached Ontology should be true; + loadingModule.showLoadingIndicator(); + parseOntologyContent(ontologyContent); + + } else { + // read the file name + + var fileToRead = "./data/" + ontology + ".json"; + if ( f2r ) { + fileToRead = f2r; + } // overwrite the newOntology Index + // read file + d3.xhr(fileToRead, "application/json", function ( error, request ){ + var loadingSuccessful = !error; + if ( loadingSuccessful ) { + ontologyContent = request.responseText; + parseOntologyContent(ontologyContent); + } else { + + if (loadingNewOntologyForEditor){ + ontologyContent = '{\n' + + ' "_comment": "Empty ontology for WebVOWL Editor",\n' + + ' "header": {\n' + + ' "languages": [\n' + + ' "en"\n' + + ' ],\n' + + ' "baseIris": [\n' + + ' "http://www.w3.org/2000/01/rdf-schema"\n' + + ' ],\n' + + ' "iri": "http://visualdataweb.org/newOntology/",\n' + + ' "title": {\n' + + ' "en": "New ontology"\n' + + ' },\n' + + ' "description": {\n' + + ' "en": "New ontology description"\n' + + ' }\n' + + ' },\n' + + ' "namespace": [],\n' + + ' "metrics": {\n' + + ' "classCount": 0,\n' + + ' "datatypeCount": 0,\n' + + ' "objectPropertyCount": 0,\n' + + ' "datatypePropertyCount": 0,\n' + + ' "propertyCount": 0,\n' + + ' "nodeCount": 0,\n' + + ' "individualCount": 0\n' + + ' }\n' + + '}\n'; + parseOntologyContent(ontologyContent); + }else{ + // some error occurred + ontologyMenu.append_bulletPoint("Failed to load: " + ontology); + if (error.status===0){ // assumption this is CORS error when running locally (error status == 0) + ontologyMenu.append_message_toLastBulletPoint(" ERROR STATUS: " + error.status); + if (window.location.toString().startsWith("file:/")){ + ontologyMenu.append_message_toLastBulletPoint("

WebVOWL runs in a local instance.

"); + ontologyMenu.append_message_toLastBulletPoint("

CORS prevents to automatically load files on host system.

"); + ontologyMenu.append_message_toLastBulletPoint("

You can load preprocessed ontologies (i.e. VOWL-JSON files) using the upload feature in the ontology menu or by dragging the files and dropping them on the canvas.

"); + ontologyMenu.append_message_toLastBulletPoint("

Hint: Note that the conversion of ontologies into the VOWL-JSON format is not part of WebVOWL but requires an additional converter such as OWL2VOWL.

"); + ontologyMenu.append_message_toLastBulletPoint("

Ontologies can be created using the editor mode (i.e. activate editing mode in Modes menu and create a new ontology using the Ontology menu.

"); + } + }else { + ontologyMenu.append_message_toLastBulletPoint(" ERROR STATUS: " + error.status); + } + + + + graph.handleOnLoadingError(); + loadingModule.setErrorMode(); + } + } + }); + } + } + + + /** -- PARSE JSON CONTENT -- **/ + function parseOntologyContent( content ){ + + ontologyMenu.append_bulletPoint("Reading ontology graph ... "); + var _loader = ontologyMenu.getLoadingFunction(); + _loader(content, ontologyIdentifierFromURL, "noAlternativeNameYet"); + } + + loadingModule.notValidJsonFile = function (){ + graph.clearGraphData(); + ontologyMenu.append_message_toLastBulletPoint(" failed"); + ontologyMenu.append_message_toLastBulletPoint("
Error: Received empty graph"); + loadingWasSuccessFul = false; + graph.handleOnLoadingError(); + + }; + + loadingModule.validJsonFile = function (){ + ontologyMenu.append_message_toLastBulletPoint("done"); + loadingWasSuccessFul = true; + }; + + + /** --- HELPER FUNCTIONS **/ + + function identifyParameter( url ){ + var numParameters = (url.match(/#/g) || []).length; + // create parameters array + var paramArray = []; + if ( numParameters > 0 ) { + var tokens = url.split("#"); + // skip the first token since it is the address of the server + for ( var i = 1; i < tokens.length; i++ ) { + if ( tokens[i].length === 0 ) { + // this token belongs actually to the last paramArray + paramArray[paramArray.length - 1] = paramArray[paramArray.length - 1] + "#"; + } else { + paramArray.push(tokens[i]); + } + } + } + return paramArray; + } + + + function loadGraphOptions( parameterArray ){ + var optString = "opts="; + + function loadDefaultConfig(){ + graph.options().setOptionsFromURL(graph.options().defaultConfig(), false); + } + + function loadCustomConfig( opts ){ + var changeEditingFlag = false; + var defObj = graph.options().defaultConfig(); + for ( var i = 0; i < opts.length; i++ ) { + var keyVal = opts[i].split('='); + if ( keyVal[0] === "editorMode" ) { + changeEditingFlag = true; + } + defObj[keyVal[0]] = keyVal[1]; + } + graph.options().setOptionsFromURL(defObj, changeEditingFlag); + } + + function identifyOptions( paramArray ){ + if ( paramArray[0].indexOf(optString) >= 0 ) { + // parse the parameters; + var parameterLength = paramArray[0].length; + var givenOptionsStr = paramArray[0].substr(5, parameterLength - 6); + var optionsArray = givenOptionsStr.split(';'); + loadCustomConfig(optionsArray); + } else { + ontologyIdentifierFromURL = paramArray[0]; + loadDefaultConfig(); + } + } + + function identifyOptionsAndOntology( paramArray ){ + + if ( paramArray[0].indexOf(optString) >= 0 ) { + // parse the parameters; + var parameterLength = paramArray[0].length; + var givenOptionsStr = paramArray[0].substr(5, parameterLength - 6); + var optionsArray = givenOptionsStr.split(';'); + loadCustomConfig(optionsArray); + } else { + loadDefaultConfig(); + } + ontologyIdentifierFromURL = paramArray[1]; + } + + switch ( parameterArray.length ) { + case 0: + loadDefaultConfig(); + break; + case 1: + identifyOptions(parameterArray); + break; + case 2: + identifyOptionsAndOntology(parameterArray); + break; + default : + console.log("To many input parameters , loading default config"); + loadDefaultConfig(); + ontologyIdentifierFromURL = "ERROR_TO_MANY_INPUT_PARAMETERS"; + } + } + + + function identifyOntologyLoadingMethod( url ){ + var iriKey = "iri="; + var urlKey = "url="; + var fileKey = "file="; + + var method = -1; + if ( url.substr(0, fileKey.length) === fileKey ) { + method = FILE_UPLOAD; + } else if ( url.substr(0, urlKey.length) === urlKey ) { + method = JSON_URL; + } else if ( url.substr(0, iriKey.length) === iriKey ) { + method = IRI_URL; + } else { + method = PREDEFINED; + } + return method; + } + + return loadingModule; +} +; + + diff --git a/src/app/js/menu/configMenu.js b/src/app/js/menu/configMenu.js new file mode 100644 index 0000000000000000000000000000000000000000..1da24961ccba8d3482534cf39073e4d81ccafb7e --- /dev/null +++ b/src/app/js/menu/configMenu.js @@ -0,0 +1,133 @@ +module.exports = function ( graph ){ + var configMenu = {}, + checkboxes = []; + + + configMenu.setup = function (){ + var menuEntry = d3.select("#m_modes"); + menuEntry.on("mouseover", function (){ + var searchMenu = graph.options().searchMenu(); + searchMenu.hideSearchEntries(); + }); + + addCheckBox("showZoomSlider", "Zoom controls", "#zoomSliderOption", graph.options().zoomSlider().showSlider, 0); + addLabelWidthSlider("#maxLabelWidthSliderOption", "maxLabelWidth", "Max label width", graph.options().maxLabelWidth); + }; + + + function addLabelWidthSlider( selector, identifier, label, onChangeFunction ){ + var sliderContainer, + sliderValueLabel; + + sliderContainer = d3.select(selector) + .append("div") + .classed("distanceSliderContainer", true); + + var slider = sliderContainer.append("input") + .attr("id", identifier + "Slider") + .attr("type", "range") + .attr("min", 20) + .attr("max", 600) + .attr("value", onChangeFunction()) + .attr("step", 10); + sliderContainer.append("label") + .classed("description", true) + .attr("for", identifier + "Slider") + .attr("id", identifier + "DescriptionLabel") + .text(label); + sliderValueLabel = sliderContainer.append("label") + .classed("value", true) + .attr("for", identifier + "Slider") + .attr("id", identifier + "valueLabel") + .text(onChangeFunction()); + + slider.on("input", function (){ + var value = slider.property("value"); + onChangeFunction(value); + sliderValueLabel.text(value); + if ( graph.options().dynamicLabelWidth() === true ) + graph.animateDynamicLabelWidth(); + }); + + // add wheel event to the slider + slider.on("wheel", function (){ + if ( slider.node().disabled === true ) return; + var wheelEvent = d3.event; + var offset; + if ( wheelEvent.deltaY < 0 ) offset = 10; + if ( wheelEvent.deltaY > 0 ) offset = -10; + var oldVal = parseInt(slider.property("value")); + var newSliderValue = oldVal + offset; + if ( newSliderValue !== oldVal ) { + slider.property("value", newSliderValue); + onChangeFunction(newSliderValue); + slider.on("input")(); // << set text and update the graphStyles + } + d3.event.preventDefault(); + }); + } + + function addCheckBox( identifier, modeName, selector, onChangeFunc, updateLvl ){ + var configOptionContainer = d3.select(selector) + .append("div") + .classed("checkboxContainer", true); + var configCheckbox = configOptionContainer.append("input") + .classed("moduleCheckbox", true) + .attr("id", identifier + "ConfigCheckbox") + .attr("type", "checkbox") + .property("checked", onChangeFunc()); + + + configCheckbox.on("click", function ( silent ){ + var isEnabled = configCheckbox.property("checked"); + onChangeFunc(isEnabled); + if ( silent !== true ) { + // updating graph when silent is false or the parameter is not given. + if ( updateLvl === 1 ) { + graph.lazyRefresh(); + //graph.redrawWithoutForce + } + if ( updateLvl === 2 ) { + graph.update(); + } + + if ( updateLvl === 3 ) { + graph.updateDraggerElements(); + } + } + + }); + checkboxes.push(configCheckbox); + configOptionContainer.append("label") + .attr("for", identifier + "ConfigCheckbox") + .text(modeName); + } + + configMenu.setCheckBoxValue = function ( identifier, value ){ + for ( var i = 0; i < checkboxes.length; i++ ) { + var cbdId = checkboxes[i].attr("id"); + if ( cbdId === identifier ) { + checkboxes[i].property("checked", value); + break; + } + } + }; + + configMenu.getCheckBoxValue = function ( id ){ + for ( var i = 0; i < checkboxes.length; i++ ) { + var cbdId = checkboxes[i].attr("id"); + if ( cbdId === id ) { + return checkboxes[i].property("checked"); + } + } + }; + + configMenu.updateSettings = function (){ + var silent = true; + checkboxes.forEach(function ( checkbox ){ + checkbox.on("click")(silent); + }); + }; + + return configMenu; +}; diff --git a/src/app/js/menu/debugMenu.js b/src/app/js/menu/debugMenu.js new file mode 100644 index 0000000000000000000000000000000000000000..480e695c7843b87fb9e37eeb1f61d5a53b56ad3f --- /dev/null +++ b/src/app/js/menu/debugMenu.js @@ -0,0 +1,149 @@ +module.exports = function ( graph ){ + var debugMenu = {}, + checkboxes = []; + + + var hoverFlag = false; + var specialCbx; + debugMenu.setup = function (){ + var menuEntry = d3.select("#debugMenuHref"); + + menuEntry.on("mouseover", function (){ + if ( hoverFlag === false ) { + var searchMenu = graph.options().searchMenu(); + searchMenu.hideSearchEntries(); + specialCbx.on("click")(true); + if ( graph.editorMode() === false ) { + d3.select("#useAccuracyHelper").style("color", "#979797"); + d3.select("#useAccuracyHelper").style("pointer-events", "none"); + + // regardless the state on which useAccuracyHelper is , we are not in editing mode -> disable it + d3.select("#showDraggerObject").style("color", "#979797"); + d3.select("#showDraggerObject").style("pointer-events", "none"); + } else { + d3.select("#useAccuracyHelper").style("color", "#2980b9"); + d3.select("#useAccuracyHelper").style("pointer-events", "auto"); + } + hoverFlag = true; + } + }); + menuEntry.on("mouseout", function (){ + hoverFlag = false; + }); + + + specialCbx = addCheckBox("useAccuracyHelper", "Use accuracy helper", "#useAccuracyHelper", graph.options().useAccuracyHelper, + function ( enabled, silent ){ + if ( !enabled ) { + d3.select("#showDraggerObject").style("color", "#979797"); + d3.select("#showDraggerObject").style("pointer-events", "none"); + d3.select("#showDraggerObjectConfigCheckbox").node().checked = false; + } else { + d3.select("#showDraggerObject").style("color", "#2980b9"); + d3.select("#showDraggerObject").style("pointer-events", "auto"); + } + + if ( silent === true ) return; + graph.lazyRefresh(); + graph.updateDraggerElements(); + } + ); + addCheckBox("showDraggerObject", "Show accuracy helper", "#showDraggerObject", graph.options().showDraggerObject, + function ( enabled, silent ){ + if ( silent === true ) return; + graph.lazyRefresh(); + graph.updateDraggerElements(); + }); + addCheckBox("showFPS_Statistics", "Show rendering statistics", "#showFPS_Statistics", graph.options().showRenderingStatistic, + function ( enabled, silent ){ + + if ( graph.options().getHideDebugFeatures() === false ) { + d3.select("#FPS_Statistics").classed("hidden", !enabled); + } else { + d3.select("#FPS_Statistics").classed("hidden", true); + } + + + }); + addCheckBox("showModeOfOperation", "Show input modality", "#showModeOfOperation", graph.options().showInputModality, + function ( enabled ){ + if ( graph.options().getHideDebugFeatures() === false ) { + d3.select("#modeOfOperationString").classed("hidden", !enabled); + } else { + d3.select("#modeOfOperationString").classed("hidden", true); + } + }); + + + }; + + + function addCheckBox( identifier, modeName, selector, onChangeFunc, _callbackFunction ){ + var configOptionContainer = d3.select(selector) + .append("div") + .classed("checkboxContainer", true); + var configCheckbox = configOptionContainer.append("input") + .classed("moduleCheckbox", true) + .attr("id", identifier + "ConfigCheckbox") + .attr("type", "checkbox") + .property("checked", onChangeFunc()); + + + configCheckbox.on("click", function ( silent ){ + var isEnabled = configCheckbox.property("checked"); + onChangeFunc(isEnabled); + _callbackFunction(isEnabled, silent); + + }); + checkboxes.push(configCheckbox); + configOptionContainer.append("label") + .attr("for", identifier + "ConfigCheckbox") + .text(modeName); + + return configCheckbox; + } + + debugMenu.setCheckBoxValue = function ( identifier, value ){ + for ( var i = 0; i < checkboxes.length; i++ ) { + var cbdId = checkboxes[i].attr("id"); + if ( cbdId === identifier ) { + checkboxes[i].property("checked", value); + break; + } + } + }; + + debugMenu.getCheckBoxValue = function ( id ){ + for ( var i = 0; i < checkboxes.length; i++ ) { + var cbdId = checkboxes[i].attr("id"); + if ( cbdId === id ) { + return checkboxes[i].property("checked"); + } + } + }; + + debugMenu.updateSettings = function (){ + d3.selectAll(".debugOption").classed("hidden", graph.options().getHideDebugFeatures()); + + var silent = true; + checkboxes.forEach(function ( checkbox ){ + checkbox.on("click")(silent); + }); + if ( graph.editorMode() === false ) { + + d3.select("#useAccuracyHelper").style("color", "#979797"); + d3.select("#useAccuracyHelper").style("pointer-events", "none"); + + // regardless the state on which useAccuracyHelper is , we are not in editing mode -> disable it + d3.select("#showDraggerObject").style("color", "#979797"); + d3.select("#showDraggerObject").style("pointer-events", "none"); + } else { + + d3.select("#useAccuracyHelper").style("color", "#2980b9"); + d3.select("#useAccuracyHelper").style("pointer-events", "auto"); + } + + }; + + return debugMenu; +}; diff --git a/src/app/js/menu/exportMenu.js b/src/app/js/menu/exportMenu.js new file mode 100644 index 0000000000000000000000000000000000000000..7d5d545cbf59e0352561570649d06ceead3c08a1 --- /dev/null +++ b/src/app/js/menu/exportMenu.js @@ -0,0 +1,1465 @@ +/** + * Contains the logic for the export button. + * @returns {{}} + */ +module.exports = function ( graph ){ + + var exportMenu = {}, + exportSvgButton, + exportFilename, + exportJsonButton, + exportTurtleButton, + exportTexButton, + copyButton, + exportableJsonText; + + var exportTTLModule = require("./exportTTLModule")(graph); + + + String.prototype.replaceAll = function ( search, replacement ){ + var target = this; + return target.split(search).join(replacement); + }; + + + /** + * Adds the export button to the website. + */ + exportMenu.setup = function (){ + exportSvgButton = d3.select("#exportSvg") + .on("click", exportSvg); + exportJsonButton = d3.select("#exportJson") + .on("click", exportJson); + + copyButton = d3.select("#copyBt") + .on("click", copyUrl); + + exportTexButton = d3.select("#exportTex") + .on("click", exportTex); + + exportTurtleButton = d3.select("#exportTurtle") + .on("click", exportTurtle); + + var menuEntry = d3.select("#m_export"); + menuEntry.on("mouseover", function (){ + var searchMenu = graph.options().searchMenu(); + searchMenu.hideSearchEntries(); + exportMenu.exportAsUrl(); + }); + }; + function exportTurtle(){ + var success = exportTTLModule.requestExport(); + var result = exportTTLModule.resultingTTL_Content(); + var ontoTitle = "NewOntology"; + console.log("Exporter was successful: " + success); + if ( success ) { + // console.log("The result is : " + result); + // var ontoTitle=graph.options().getGeneralMetaObjectProperty('title'); + // if (ontoTitle===undefined || ontoTitle.length===0) + // ontoTitle="NewOntology"; + // else{ + // // language object -.- + // ontoTitle.replace(" ","_") + // } + + // TODO: show TEXT in warning module? + + + // // write the data + var dataURI = "data:text/json;charset=utf-8," + encodeURIComponent(result); + + exportTurtleButton.attr("href", dataURI) + .attr("download", ontoTitle + ".ttl"); + + // okay restore old href? + // exportTurtleButton.attr("href", oldHref); + } else { + console.log("ShowWarning!"); + graph.options().warningModule().showExporterWarning(); + console.log("Stay on the page! " + window.location.href); + exportTurtleButton.attr("href", window.location.href); + d3.event.preventDefault(); // prevent the href to be called ( reloads the page otherwise ) + } + } + + exportMenu.setFilename = function ( filename ){ + exportFilename = filename || "export"; + }; + + exportMenu.setJsonText = function ( jsonText ){ + exportableJsonText = jsonText; + }; + + function copyUrl(){ + d3.select("#exportedUrl").node().focus(); + d3.select("#exportedUrl").node().select(); + document.execCommand("copy"); + graph.options().navigationMenu().hideAllMenus(); + d3.event.preventDefault(); // prevent the href to be called ( reloads the page otherwise ) + } + + function prepareOptionString( defOpts, currOpts ){ + var setOptions = 0; + var optsString = "opts="; + + for ( var name in defOpts ) { + // define key and value ; + if ( defOpts.hasOwnProperty(name) ) {// for travis warning + var def_value = defOpts[name]; + var cur_value = currOpts[name]; + if ( def_value !== cur_value ) { + optsString += name + "=" + cur_value + ";"; + setOptions++; + } + } + } + optsString += ""; + if ( setOptions === 0 ) { + return ""; + } + return optsString; + } + + exportMenu.exportAsUrl = function (){ + var currObj = {}; + currObj.sidebar = graph.options().sidebar().getSidebarVisibility(); + + // identify default value given by ontology; + var defOntValue = graph.options().filterMenu().getDefaultDegreeValue(); + var currentValue = graph.options().filterMenu().getDegreeSliderValue(); + if ( parseInt(defOntValue) === parseInt(currentValue) ) { + currObj.doc = -1; + } else { + currObj.doc = currentValue; + } + + currObj.cd = graph.options().classDistance(); + currObj.dd = graph.options().datatypeDistance(); + if ( graph.editorMode() === true ) { + currObj.editorMode = "true"; + } else { + currObj.editorMode = "false"; + } + currObj.filter_datatypes = String(graph.options().filterMenu().getCheckBoxValue("datatypeFilterCheckbox")); + currObj.filter_sco = String(graph.options().filterMenu().getCheckBoxValue("subclassFilterCheckbox")); + currObj.filter_disjoint = String(graph.options().filterMenu().getCheckBoxValue("disjointFilterCheckbox")); + currObj.filter_setOperator = String(graph.options().filterMenu().getCheckBoxValue("setoperatorFilterCheckbox")); + currObj.filter_objectProperties = String(graph.options().filterMenu().getCheckBoxValue("objectPropertyFilterCheckbox")); + currObj.mode_dynamic = String(graph.options().dynamicLabelWidth()); + currObj.mode_scaling = String(graph.options().modeMenu().getCheckBoxValue("nodescalingModuleCheckbox")); + currObj.mode_compact = String(graph.options().modeMenu().getCheckBoxValue("compactnotationModuleCheckbox")); + currObj.mode_colorExt = String(graph.options().modeMenu().getCheckBoxValue("colorexternalsModuleCheckbox")); + currObj.mode_multiColor = String(graph.options().modeMenu().colorModeState()); + currObj.mode_pnp = String(graph.options().modeMenu().getCheckBoxValue("pickandpinModuleCheckbox")); + currObj.debugFeatures = String(!graph.options().getHideDebugFeatures()); + currObj.rect = 0; + + var defObj = graph.options().initialConfig(); + var optsString = prepareOptionString(defObj, currObj); + var urlString = String(location); + var htmlElement; + // when everything is default then there is nothing to write + if ( optsString.length === 0 ) { + // building up parameter list; + + // remove the all options form location + var hashCode = location.hash; + urlString = urlString.split(hashCode)[0]; + + var lPos = hashCode.lastIndexOf("#"); + if ( lPos === -1 ) { + htmlElement = d3.select("#exportedUrl").node(); + htmlElement.value = String(location); + htmlElement.title = String(location); + return; // nothing to change in the location String + } + var newURL = hashCode.slice(lPos, hashCode.length); + htmlElement = d3.select("#exportedUrl").node(); + htmlElement.value = urlString + newURL; + htmlElement.title = urlString + newURL; + return; + } + + // generate the options string; + var numParameters = (urlString.match(/#/g) || []).length; + var newUrlString; + if ( numParameters === undefined || numParameters === 0 ) { + newUrlString = urlString + "#" + optsString; + } + if ( numParameters > 0 ) { + var tokens = urlString.split("#"); + var i; + if ( tokens[1].indexOf("opts=") >= 0 ) { + tokens[1] = optsString; + newUrlString = tokens[0]; + } else { + newUrlString = tokens[0] + "#"; + newUrlString += optsString; + } + // append parameters + for ( i = 1; i < tokens.length; i++ ) { + if ( tokens[i].length > 0 ) { + newUrlString += "#" + tokens[i]; + } + } + } + // building up parameter list; + htmlElement = d3.select("#exportedUrl").node(); + htmlElement.value = newUrlString; + htmlElement.title = newUrlString; + + }; + + function exportSvg(){ + graph.options().navigationMenu().hideAllMenus(); + // Get the d3js SVG element + var graphSvg = d3.select(graph.options().graphContainerSelector()).select("svg"), + graphSvgCode, + escapedGraphSvgCode, + dataURI; + + // inline the styles, so that the exported svg code contains the css rules + inlineVowlStyles(); + hideNonExportableElements(); + + graphSvgCode = graphSvg.attr("version", 1.1) + .attr("xmlns", "http://www.w3.org/2000/svg") + .node().parentNode.innerHTML; + + // Insert the reference to VOWL + graphSvgCode = "\n" + graphSvgCode; + + escapedGraphSvgCode = escapeUnicodeCharacters(graphSvgCode); + //btoa(); Creates a base-64 encoded ASCII string from a "string" of binary data. + dataURI = "data:image/svg+xml;base64," + btoa(escapedGraphSvgCode); + + + exportSvgButton.attr("href", dataURI) + .attr("download", exportFilename + ".svg"); + + // remove graphic styles for interaction to go back to normal + removeVowlInlineStyles(); + showNonExportableElements(); + graph.lazyRefresh(); + } + + function escapeUnicodeCharacters( text ){ + var textSnippets = [], + i, textLength = text.length, + character, + charCode; + + for ( i = 0; i < textLength; i++ ) { + character = text.charAt(i); + charCode = character.charCodeAt(0); + + if ( charCode < 128 ) { + textSnippets.push(character); + } else { + textSnippets.push("&#" + charCode + ";"); + } + } + + return textSnippets.join(""); + } + + function inlineVowlStyles(){ + setStyleSensitively(".text", [{ name: "font-family", value: "Helvetica, Arial, sans-serif" }, { + name: "font-size", + value: "12px" + }]); + setStyleSensitively(".subtext", [{ name: "font-size", value: "9px" }]); + setStyleSensitively(".text.instance-count", [{ name: "fill", value: "#666" }]); + setStyleSensitively(".external + text .instance-count", [{ name: "fill", value: "#aaa" }]); + setStyleSensitively(".cardinality", [{ name: "font-size", value: "10px" }]); + setStyleSensitively(".text, .embedded", [{ name: "pointer-events", value: "none" }]); + setStyleSensitively(".class, .object, .disjoint, .objectproperty, .disjointwith, .equivalentproperty, .transitiveproperty, .functionalproperty, .inversefunctionalproperty, .symmetricproperty, .allvaluesfromproperty, .somevaluesfromproperty", [{ + name: "fill", + value: "#acf" + }]); + setStyleSensitively(".label .datatype, .datatypeproperty", [{ name: "fill", value: "#9c6" }]); + setStyleSensitively(".rdf, .rdfproperty", [{ name: "fill", value: "#c9c" }]); + setStyleSensitively(".literal, .node .datatype", [{ name: "fill", value: "#fc3" }]); + setStyleSensitively(".deprecated, .deprecatedproperty", [{ name: "fill", value: "#ccc" }]); + setStyleSensitively(".external, .externalproperty", [{ name: "fill", value: "#36c" }]); + setStyleSensitively("path, .nofill", [{ name: "fill", value: "none" }]); + setStyleSensitively("marker path", [{ name: "fill", value: "#000" }]); + setStyleSensitively(".class, path, line, .fineline", [{ name: "stroke", value: "#000" }]); + setStyleSensitively(".white, .subclass, .subclassproperty, .external + text", [{ name: "fill", value: "#fff" }]); + setStyleSensitively(".class.hovered, .property.hovered, .cardinality.hovered, .cardinality.focused, circle.pin, .filled.hovered, .filled.focused", [{ + name: "fill", + value: "#f00" + }, { name: "cursor", value: "pointer" }]); + setStyleSensitively(".focused, path.hovered", [{ name: "stroke", value: "#f00" }]); + setStyleSensitively(".indirect-highlighting, .feature:hover", [{ name: "fill", value: "#f90" }]); + setStyleSensitively(".values-from", [{ name: "stroke", value: "#69c" }]); + setStyleSensitively(".symbol, .values-from.filled", [{ name: "fill", value: "#69c" }]); + setStyleSensitively(".class, path, line", [{ name: "stroke-width", value: "2" }]); + setStyleSensitively(".fineline", [{ name: "stroke-width", value: "1" }]); + setStyleSensitively(".dashed, .anonymous", [{ name: "stroke-dasharray", value: "8" }]); + setStyleSensitively(".dotted", [{ name: "stroke-dasharray", value: "3" }]); + setStyleSensitively("rect.focused, circle.focused", [{ name: "stroke-width", value: "4px" }]); + setStyleSensitively(".nostroke", [{ name: "stroke", value: "none" }]); + setStyleSensitively("marker path", [{ name: "stroke-dasharray", value: "100" }]); + } + + function setStyleSensitively( selector, styles ){ + var elements = d3.selectAll(selector); + if ( elements.empty() ) { + return; + } + + styles.forEach(function ( style ){ + elements.each(function (){ + var element = d3.select(this); + if ( !shouldntChangeInlineCss(element, style.name) ) { + element.style(style.name, style.value); + } + }); + }); + } + + function shouldntChangeInlineCss( element, style ){ + return style === "fill" && hasBackgroundColorSet(element); + } + + function hasBackgroundColorSet( element ){ + var data = element.datum(); + if ( data === undefined ) { + return false; + } + return data.backgroundColor && !!data.backgroundColor(); + } + + /** + * For example the pin of the pick&pin module should be invisible in the exported graphic. + */ + function hideNonExportableElements(){ + d3.selectAll(".hidden-in-export").style("display", "none"); + } + + function removeVowlInlineStyles(){ + d3.selectAll(".text, .subtext, .text.instance-count, .external + text .instance-count, .cardinality, .text, .embedded, .class, .object, .disjoint, .objectproperty, .disjointwith, .equivalentproperty, .transitiveproperty, .functionalproperty, .inversefunctionalproperty, .symmetricproperty, .allvaluesfromproperty, .somevaluesfromproperty, .label .datatype, .datatypeproperty, .rdf, .rdfproperty, .literal, .node .datatype, .deprecated, .deprecatedproperty, .external, .externalproperty, path, .nofill, .symbol, .values-from.filled, marker path, .class, path, line, .fineline, .white, .subclass, .subclassproperty, .external + text, .class.hovered, .property.hovered, .cardinality.hovered, .cardinality.focused, circle.pin, .filled.hovered, .filled.focused, .focused, path.hovered, .indirect-highlighting, .feature:hover, .values-from, .class, path, line, .fineline, .dashed, .anonymous, .dotted, rect.focused, circle.focused, .nostroke, marker path") + .each(function (){ + var element = d3.select(this); + + var inlineStyles = element.node().style; + for ( var styleName in inlineStyles ) { + if ( inlineStyles.hasOwnProperty(styleName) ) { + if ( shouldntChangeInlineCss(element, styleName) ) { + continue; + } + element.style(styleName, null); + } + } + + if ( element.datum && element.datum() !== undefined && element.datum().type ) { + if ( element.datum().type() === "rdfs:subClassOf" ) { + element.style("fill", null); + } + } + }); + + // repair svg icons in the menu; + var scrollContainer = d3.select("#menuElementContainer").node(); + var controlElements = scrollContainer.children; + var numEntries = controlElements.length; + + for ( var i = 0; i < numEntries; i++ ) { + var currentMenu = controlElements[i].id; + d3.select("#" + currentMenu).select("path").style("stroke-width", "0"); + d3.select("#" + currentMenu).select("path").style("fill", "#fff"); + } + + d3.select("#magnifyingGlass").style("stroke-width", "0"); + d3.select("#magnifyingGlass").style("fill", "#666"); + + } + + function showNonExportableElements(){ + d3.selectAll(".hidden-in-export").style("display", null); + } + + exportMenu.createJSON_exportObject = function (){ + var i, j, k; // an index variable for the for-loops + + /** get data for exporter **/ + if (!graph.options().data()) {return {};} // return an empty json object + // extract onotology information; + var unfilteredData = graph.getUnfilteredData(); + var ontologyComment = graph.options().data()._comment; + var metaObj = graph.options().getGeneralMetaObject(); + var header = graph.options().data().header; + + if ( metaObj.iri && metaObj.iri !== header.iri ) { + header.iri = metaObj.iri; + } + if ( metaObj.title && metaObj.title !== header.title ) { + header.title = metaObj.title; + } + if ( metaObj.version && metaObj.version !== header.version ) { + header.version = metaObj.version; + } + if ( metaObj.author && metaObj.author !== header.author ) { + header.author = metaObj.author; + } + if ( metaObj.description && metaObj.description !== header.description ) { + header.description = metaObj.description; + } + + + var exportText = {}; + exportText._comment = ontologyComment; + exportText.header = header; + exportText.namespace = graph.options().data().namespace; + if ( exportText.namespace === undefined ) { + exportText.namespace = []; // just an empty namespace array + } + // we do have now the unfiltered data which needs to be transfered to class/classAttribute and property/propertyAttribute + + + // var classAttributeString='classAttribute:[ \n'; + var nodes = unfilteredData.nodes; + var nLen = nodes.length; // hope for compiler unroll + var classObjects = []; + var classAttributeObjects = []; + for ( i = 0; i < nLen; i++ ) { + var classObj = {}; + var classAttr = {}; + classObj.id = nodes[i].id(); + classObj.type = nodes[i].type(); + classObjects.push(classObj); + + // define the attributes object + classAttr.id = nodes[i].id(); + classAttr.iri = nodes[i].iri(); + classAttr.baseIri = nodes[i].baseIri(); + classAttr.label = nodes[i].label(); + + if ( nodes[i].attributes().length > 0 ) { + classAttr.attributes = nodes[i].attributes(); + } + if ( nodes[i].comment() ) { + classAttr.comment = nodes[i].comment(); + } + if ( nodes[i].annotations() ) { + classAttr.annotations = nodes[i].annotations(); + } + if ( nodes[i].description() ) { + classAttr.description = nodes[i].description(); + } + + + if ( nodes[i].individuals().length > 0 ) { + var classIndividualElements = []; + var nIndividuals = nodes[i].individuals(); + for ( j = 0; j < nIndividuals.length; j++ ) { + var indObj = {}; + indObj.iri = nIndividuals[j].iri(); + indObj.baseIri = nIndividuals[j].baseIri(); + indObj.labels = nIndividuals[j].label(); + if ( nIndividuals[j].annotations() ) { + indObj.annotations = nIndividuals[j].annotations(); + } + if ( nIndividuals[j].description() ) { + indObj.description = nIndividuals[j].description(); + } + if ( nIndividuals[j].comment() ) { + indObj.comment = nIndividuals[j].comment(); + } + classIndividualElements.push(indObj); + } + classAttr.individuals = classIndividualElements; + } + + var equalsForAttributes = undefined; + if ( nodes[i].equivalents().length > 0 ) { + equalsForAttributes = []; + var equals = nodes[i].equivalents(); + for ( j = 0; j < equals.length; j++ ) { + var eqObj = {}; + var eqAttr = {}; + eqObj.id = equals[j].id(); + equalsForAttributes.push(equals[j].id()); + eqObj.type = equals[j].type(); + classObjects.push(eqObj); + + eqAttr.id = equals[j].id(); + eqAttr.iri = equals[j].iri(); + eqAttr.baseIri = equals[j].baseIri(); + eqAttr.label = equals[j].label(); + + if ( equals[j].attributes().length > 0 ) { + eqAttr.attributes = equals[j].attributes(); + } + if ( equals[j].comment() ) { + eqAttr.comment = equals[j].comment(); + } + if ( equals[j].individuals().length > 0 ) { + eqAttr.individuals = equals[j].individuals(); + } + if ( equals[j].annotations() ) { + eqAttr.annotations = equals[j].annotations(); + } + if ( equals[j].description() ) { + eqAttr.description = equals[j].description(); + } + + if ( equals[j].individuals().length > 0 ) { + var e_classIndividualElements = []; + var e_nIndividuals = equals[i].individuals(); + for ( k = 0; k < e_nIndividuals.length; k++ ) { + var e_indObj = {}; + e_indObj.iri = e_nIndividuals[k].iri(); + e_indObj.baseIri = e_nIndividuals[k].baseIri(); + e_indObj.labels = e_nIndividuals[k].label(); + + if ( e_nIndividuals[k].annotations() ) { + e_indObj.annotations = e_nIndividuals[k].annotations(); + } + if ( e_nIndividuals[k].description() ) { + e_indObj.description = e_nIndividuals[k].description(); + } + if ( e_nIndividuals[k].comment() ) { + e_indObj.comment = e_nIndividuals[k].comment(); + } + e_classIndividualElements.push(e_indObj); + } + eqAttr.individuals = e_classIndividualElements; + } + + classAttributeObjects.push(eqAttr); + } + } + if ( equalsForAttributes && equalsForAttributes.length > 0 ) { + classAttr.equivalent = equalsForAttributes; + } + + // classAttr.subClasses=nodes[i].subClasses(); // not needed + // classAttr.instances=nodes[i].instances(); + + // + // .complement(element.complement) + // .disjointUnion(element.disjointUnion) + // .description(element.description) + // .equivalents(element.equivalent) + // .intersection(element.intersection) + // .type(element.type) Ignore, because we predefined it + // .union(element.union) + classAttributeObjects.push(classAttr); + } + + /** -- properties -- **/ + var properties = unfilteredData.properties; + var pLen = properties.length; // hope for compiler unroll + var propertyObjects = []; + var propertyAttributeObjects = []; + + for ( i = 0; i < pLen; i++ ) { + var pObj = {}; + var pAttr = {}; + pObj.id = properties[i].id(); + pObj.type = properties[i].type(); + propertyObjects.push(pObj); + + // // define the attributes object + pAttr.id = properties[i].id(); + pAttr.iri = properties[i].iri(); + pAttr.baseIri = properties[i].baseIri(); + pAttr.label = properties[i].label(); + + if ( properties[i].attributes().length > 0 ) { + pAttr.attributes = properties[i].attributes(); + } + if ( properties[i].comment() ) { + pAttr.comment = properties[i].comment(); + } + + if ( properties[i].annotations() ) { + pAttr.annotations = properties[i].annotations(); + } + if ( properties[i].maxCardinality() ) { + pAttr.maxCardinality = properties[i].maxCardinality(); + } + if ( properties[i].minCardinality() ) { + pAttr.minCardinality = properties[i].minCardinality(); + } + if ( properties[i].cardinality() ) { + pAttr.cardinality = properties[i].cardinality(); + } + if ( properties[i].description() ) { + pAttr.description = properties[i].description(); + } + + pAttr.domain = properties[i].domain().id(); + pAttr.range = properties[i].range().id(); + // sub properties; + if ( properties[i].subproperties() ) { + var subProps = properties[i].subproperties(); + var subPropsIdArray = []; + for ( j = 0; j < subProps.length; j++ ) { + if ( subProps[j].id ) + subPropsIdArray.push(subProps[j].id()); + } + pAttr.subproperty = subPropsIdArray; + } + + // super properties + if ( properties[i].superproperties() ) { + var superProps = properties[i].superproperties(); + var superPropsIdArray = []; + for ( j = 0; j < superProps.length; j++ ) { + if ( superProps[j].id ) + superPropsIdArray.push(superProps[j].id()); + } + pAttr.superproperty = superPropsIdArray; + } + + // check for inverse element + if ( properties[i].inverse() ) { + if ( properties[i].inverse().id ) + pAttr.inverse = properties[i].inverse().id(); + } + propertyAttributeObjects.push(pAttr); + } + + exportText.class = classObjects; + exportText.classAttribute = classAttributeObjects; + exportText.property = propertyObjects; + exportText.propertyAttribute = propertyAttributeObjects; + + + var nodeElements = graph.graphNodeElements(); // get visible nodes + var propElements = graph.graphLabelElements(); // get visible labels + // var jsonObj = JSON.parse(exportableJsonText); // reparse the original input json + + /** modify comment **/ + var comment = exportText._comment; + var additionalString = " [Additional Information added by WebVOWL Exporter Version: " + "@@WEBVOWL_VERSION" + "]"; + // adding new string to comment only if it does not exist + if ( comment.indexOf(additionalString) === -1 ) { + exportText._comment = comment + " [Additional Information added by WebVOWL Exporter Version: " + "@@WEBVOWL_VERSION" + "]"; + } + + var classAttribute = exportText.classAttribute; + var propAttribute = exportText.propertyAttribute; + /** remove previously stored variables **/ + for ( i = 0; i < classAttribute.length; i++ ) { + var classObj_del = classAttribute[i]; + delete classObj_del.pos; + delete classObj_del.pinned; + } + var propertyObj; + for ( i = 0; i < propAttribute.length; i++ ) { + propertyObj = propAttribute[i]; + delete propertyObj.pos; + delete propertyObj.pinned; + } + /** add new variables to jsonObj **/ + // class attribute variables + nodeElements.each(function ( node ){ + var nodeId = node.id(); + for ( i = 0; i < classAttribute.length; i++ ) { + var classObj = classAttribute[i]; + if ( classObj.id === nodeId ) { + // store relative positions + classObj.pos = [parseFloat(node.x.toFixed(2)), parseFloat(node.y.toFixed(2))]; + if ( node.pinned() ) + classObj.pinned = true; + break; + } + } + }); + // property attribute variables + for ( j = 0; j < propElements.length; j++ ) { + var correspondingProp = propElements[j].property(); + for ( i = 0; i < propAttribute.length; i++ ) { + propertyObj = propAttribute[i]; + if ( propertyObj.id === correspondingProp.id() ) { + propertyObj.pos = [parseFloat(propElements[j].x.toFixed(2)), parseFloat(propElements[j].y.toFixed(2))]; + if ( propElements[j].pinned() ) + propertyObj.pinned = true; + break; + } + } + } + /** create the variable for settings and set their values **/ + exportText.settings = {}; + + // Global Settings + var zoom = graph.scaleFactor(); + var paused = graph.paused(); + var translation = [parseFloat(graph.translation()[0].toFixed(2)), parseFloat(graph.translation()[1].toFixed(2))]; + exportText.settings.global = {}; + exportText.settings.global.zoom = zoom.toFixed(2); + exportText.settings.global.translation = translation; + exportText.settings.global.paused = paused; + + // shared variable declaration + var cb_text; + var isEnabled; + var cb_obj; + + // Gravity Settings + var classDistance = graph.options().classDistance(); + var datatypeDistance = graph.options().datatypeDistance(); + exportText.settings.gravity = {}; + exportText.settings.gravity.classDistance = classDistance; + exportText.settings.gravity.datatypeDistance = datatypeDistance; + + // Filter Settings + var fMenu = graph.options().filterMenu(); + var fContainer = fMenu.getCheckBoxContainer(); + var cbCont = []; + for ( i = 0; i < fContainer.length; i++ ) { + cb_text = fContainer[i].checkbox.attr("id"); + isEnabled = fContainer[i].checkbox.property("checked"); + cb_obj = {}; + cb_obj.id = cb_text; + cb_obj.checked = isEnabled; + cbCont.push(cb_obj); + } + var degreeSliderVal = fMenu.getDegreeSliderValue(); + exportText.settings.filter = {}; + exportText.settings.filter.checkBox = cbCont; + exportText.settings.filter.degreeSliderValue = degreeSliderVal; + + // Modes Settings + var mMenu = graph.options().modeMenu(); + var mContainer = mMenu.getCheckBoxContainer(); + var cb_modes = []; + for ( i = 0; i < mContainer.length; i++ ) { + cb_text = mContainer[i].attr("id"); + isEnabled = mContainer[i].property("checked"); + cb_obj = {}; + cb_obj.id = cb_text; + cb_obj.checked = isEnabled; + cb_modes.push(cb_obj); + } + var colorSwitchState = mMenu.colorModeState(); + exportText.settings.modes = {}; + exportText.settings.modes.checkBox = cb_modes; + exportText.settings.modes.colorSwitchState = colorSwitchState; + + var exportObj = {}; + // todo: [ ] find better way for ordering the objects + // hack for ordering of objects, so settings is after metrics + exportObj._comment = exportText._comment; + exportObj.header = exportText.header; + exportObj.namespace = exportText.namespace; + exportObj.metrics = exportText.metrics; + exportObj.settings = exportText.settings; + exportObj.class = exportText.class; + exportObj.classAttribute = exportText.classAttribute; + exportObj.property = exportText.property; + exportObj.propertyAttribute = exportText.propertyAttribute; + + return exportObj; + }; + + function exportJson(){ + graph.options().navigationMenu().hideAllMenus(); + /** check if there is data **/ + if ( !exportableJsonText ) { + alert("No graph data available."); + // Stop the redirection to the path of the href attribute + d3.event.preventDefault(); + return; + } + + var exportObj = exportMenu.createJSON_exportObject(); + + // make a string again; + var exportText = JSON.stringify(exportObj, null, ' '); + // write the data + var dataURI = "data:text/json;charset=utf-8," + encodeURIComponent(exportText); + var jsonExportFileName = exportFilename; + + if ( !jsonExportFileName.endsWith(".json") ) + jsonExportFileName += ".json"; + exportJsonButton.attr("href", dataURI) + .attr("download", jsonExportFileName); + } + + var curveFunction = d3.svg.line() + .x(function ( d ){ + return d.x; + }) + .y(function ( d ){ + return d.y; + }) + .interpolate("cardinal"); + var loopFunction = d3.svg.line() + .x(function ( d ){ + return d.x; + }) + .y(function ( d ){ + return d.y; + }) + .interpolate("cardinal") + .tension(-1); + + function exportTex(){ + var zoom = graph.scaleFactor(); + var grTranslate = graph.translation(); + var bbox = graph.getBoundingBoxForTex(); + var comment = " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; + comment += " % Generated with the experimental alpha version of the TeX exporter of WebVOWL (version 1.1.3) %%% \n"; + comment += " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n"; + comment += " % The content can be used as import in other TeX documents. \n"; + comment += " % Parent document has to use the following packages \n"; + comment += " % \\usepackage{tikz} \n"; + comment += " % \\usepackage{helvet} \n"; + comment += " % \\usetikzlibrary{decorations.markings,decorations.shapes,decorations,arrows,automata,backgrounds,petri,shapes.geometric} \n"; + comment += " % \\usepackage{xcolor} \n\n"; + comment += " %%%%%%%%%%%%%%% Example Parent Document %%%%%%%%%%%%%%%%%%%%%%%\n"; + comment += " %\\documentclass{article} \n"; + comment += " %\\usepackage{tikz} \n"; + comment += " %\\usepackage{helvet} \n"; + comment += " %\\usetikzlibrary{decorations.markings,decorations.shapes,decorations,arrows,automata,backgrounds,petri,shapes.geometric} \n"; + comment += " %\\usepackage{xcolor} \n\n"; + comment += " %\\begin{document} \n"; + comment += " %\\section{Example} \n"; + comment += " % This is an example. \n"; + comment += " % \\begin{figure} \n"; + comment += " % \\input{} % << tex file name for the graph \n"; + comment += " % \\caption{A generated graph with TKIZ using alpha version of the TeX exporter of WebVOWL (version 1.1.3) } \n"; + comment += " % \\end{figure} \n"; + comment += " %\\end{document} \n"; + comment += " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n"; + + + var texString = comment + "\\definecolor{imageBGCOLOR}{HTML}{FFFFFF} \n" + + "\\definecolor{owlClassColor}{HTML}{AACCFF}\n" + + "\\definecolor{owlObjectPropertyColor}{HTML}{AACCFF}\n" + + "\\definecolor{owlExternalClassColor}{HTML}{AACCFF}\n" + + "\\definecolor{owlDatatypePropertyColor}{HTML}{99CC66}\n" + + "\\definecolor{owlDatatypeColor}{HTML}{FFCC33}\n" + + "\\definecolor{owlThingColor}{HTML}{FFFFFF}\n" + + "\\definecolor{valuesFrom}{HTML}{6699CC}\n" + + "\\definecolor{rdfPropertyColor}{HTML}{CC99CC}\n" + + "\\definecolor{unionColor}{HTML}{6699cc}\n" + + "\\begin{center} \n" + + "\\resizebox{\\linewidth}{!}{\n" + + + "\\begin{tikzpicture}[framed]\n" + + "\\clip (" + bbox[0] + "pt , " + bbox[1] + "pt ) rectangle (" + bbox[2] + "pt , " + bbox[3] + "pt);\n" + + "\\tikzstyle{dashed}=[dash pattern=on 4pt off 4pt] \n" + + "\\tikzstyle{dotted}=[dash pattern=on 2pt off 2pt] \n" + + "\\fontfamily{sans-serif}{\\fontsize{12}{12}\\selectfont}\n \n"; + + + texString += "\\tikzset{triangleBlack/.style = {fill=black, draw=black, line width=1pt,scale=0.7,regular polygon, regular polygon sides=3} }\n"; + texString += "\\tikzset{triangleWhite/.style = {fill=white, draw=black, line width=1pt,scale=0.7,regular polygon, regular polygon sides=3} }\n"; + texString += "\\tikzset{triangleBlue/.style = {fill=valuesFrom, draw=valuesFrom, line width=1pt,scale=0.7,regular polygon, regular polygon sides=3} }\n"; + + texString += "\\tikzset{Diamond/.style = {fill=white, draw=black, line width=2pt,scale=1.2,regular polygon, regular polygon sides=4} }\n"; + + + texString += "\\tikzset{Literal/.style={rectangle,align=center,\n" + + "font={\\fontsize{12pt}{12}\\selectfont \\sffamily },\n" + + "black, draw=black, dashed, line width=1pt, fill=owlDatatypeColor, minimum width=80pt,\n" + + "minimum height = 20pt}}\n\n"; + + texString += "\\tikzset{Datatype/.style={rectangle,align=center,\n" + + "font={\\fontsize{12pt}{12}\\selectfont \\sffamily },\n" + + "black, draw=black, line width=1pt, fill=owlDatatypeColor, minimum width=80pt,\n" + + "minimum height = 20pt}}\n\n"; + + + texString += "\\tikzset{owlClass/.style={circle, inner sep=0mm,align=center, \n" + + "font={\\fontsize{12pt}{12}\\selectfont \\sffamily },\n" + + "black, draw=black, line width=1pt, fill=owlClassColor, minimum size=101pt}}\n\n"; + + texString += "\\tikzset{anonymousClass/.style={circle, inner sep=0mm,align=center, \n" + + "font={\\fontsize{12pt}{12}\\selectfont \\sffamily },\n" + + "black, dashed, draw=black, line width=1pt, fill=owlClassColor, minimum size=101pt}}\n\n"; + + + texString += "\\tikzset{owlThing/.style={circle, inner sep=0mm,align=center,\n" + + "font={\\fontsize{12pt}{12}\\selectfont \\sffamily },\n" + + "black, dashed, draw=black, line width=1pt, fill=owlThingColor, minimum size=62pt}}\n\n"; + + + texString += "\\tikzset{owlObjectProperty/.style={rectangle,align=center,\n" + + "inner sep=0mm,\n" + + "font={\\fontsize{12pt}{12}\\selectfont \\sffamily },\n" + + "fill=owlObjectPropertyColor, minimum width=80pt,\n" + + "minimum height = 25pt}}\n\n"; + + texString += "\\tikzset{rdfProperty/.style={rectangle,align=center,\n" + + "inner sep=0mm,\n" + + "font={\\fontsize{12pt}{12}\\selectfont \\sffamily },\n" + + "fill=rdfPropertyColor, minimum width=80pt,\n" + + "minimum height = 25pt}}\n\n"; + + + texString += "\\tikzset{owlDatatypeProperty/.style={rectangle,align=center,\n" + + "fill=owlDatatypePropertyColor, minimum width=80pt,\n" + + "inner sep=0mm,\n" + + "font={\\fontsize{12pt}{12}\\selectfont \\sffamily },\n" + + "minimum height = 25pt}}\n\n"; + + texString += "\\tikzset{rdfsSubClassOf/.style={rectangle,align=center,\n" + + "font={\\fontsize{12pt}{12}\\selectfont \\sffamily },\n" + + "inner sep=0mm,\n" + + "fill=imageBGCOLOR, minimum width=80pt,\n" + + "minimum height = 25pt}}\n\n"; + + texString += "\\tikzset{unionOf/.style={circle, inner sep=0mm,align=center,\n" + + "font={\\fontsize{12pt}{12}\\selectfont \\sffamily },\n" + + "black, draw=black, line width=1pt, fill=unionColor, minimum size=25pt}}\n\n"; + + texString += "\\tikzset{disjointWith/.style={circle, inner sep=0mm,align=center,\n" + + "font={\\fontsize{12pt}{12}\\selectfont \\sffamily },\n" + + "black, draw=black, line width=1pt, fill=unionColor, minimum size=20pt}}\n\n"; + + + texString += "\\tikzset{owlEquivalentClass/.style={circle,align=center,\n" + + "font={\\fontsize{12pt}{12}\\selectfont \\sffamily },\n" + + "inner sep=0mm,\n" + + "black, solid, draw=black, line width=3pt, fill=owlExternalClassColor, minimum size=101pt,\n" + + "postaction = {draw,line width=1pt, white}}}\n\n"; + + // draw a bounding box; + + // get bbox coordinates; + + + graph.options().navigationMenu().hideAllMenus(); + /** check if there is data **/ + if ( !exportableJsonText ) { + alert("No graph data available."); + // Stop the redirection to the path of the href attribute + d3.event.preventDefault(); + return; + } + + var i = 0, identifier; + + /** get data for exporter **/ + var nodeElements = graph.graphNodeElements(); // get visible nodes + var propElements = graph.graphLabelElements(); // get visible labels + var links = graph.graphLinkElements(); + + // export only nodes; + // draw Links; + for ( i = 0; i < links.length; i++ ) { + var link = links[i]; + // console.log("\n****************\nInverstigating Link for property "+link.property().labelForCurrentLanguage()); + + var prop = link.property(); + var dx, dy, px, py, rx, ry; + var colorStr = "black"; + var linkDomainIntersection; + var linkRangeIntersection; + var center; + var linkStyle = ""; + var isLoop = ""; + var curvePoint; + var pathStart; + var pathEnd; + var controlPoints; + var len; + var ahAngle; + var pathLen; + var markerOffset = 7; + + var arrowType = "triangleBlack"; + var linkWidth = ",line width=2pt"; + if ( prop.linkType ) { + if ( prop.linkType() === "dotted" ) { + //stroke-dasharray: 3; + linkStyle = ", dotted "; + arrowType = "triangleWhite"; + } + if ( prop.linkType() === "dashed" ) { + //stroke-dasharray: 3; + linkStyle = ", dashed "; + } + + if ( prop.linkType() === "values-from" ) { + colorStr = "valuesFrom"; + } + + } + + var startX, startY, endX, endY, normX, normY, lg; + + if ( link.layers().length === 1 && !link.loops() ) { + + linkDomainIntersection = graph.math().calculateIntersection(link.range(), link.domain(), 1); + linkRangeIntersection = graph.math().calculateIntersection(link.domain(), link.range(), 1); + center = graph.math().calculateCenter(linkDomainIntersection, linkRangeIntersection); + dx = linkDomainIntersection.x; + dy = -linkDomainIntersection.y; + px = center.x; + py = -center.y; + rx = linkRangeIntersection.x; + ry = -linkRangeIntersection.y; + + + pathStart = linkDomainIntersection; + curvePoint = center; + pathEnd = linkRangeIntersection; + + var nx = rx - px; + var ny = ry - py; + + // normalize ; + len = Math.sqrt(nx * nx + ny * ny); + + nx = nx / len; + ny = ny / len; + + ahAngle = Math.atan2(ny, nx) * (180 / Math.PI); + normX = nx; + normY = ny; + } + else { + if ( link.isLoop() ) { + isLoop = ", tension=3"; + controlPoints = graph.math().calculateLoopPoints(link); + pathStart = controlPoints[0]; + curvePoint = controlPoints[1]; + pathEnd = controlPoints[2]; + } else { + curvePoint = link.label(); + pathStart = graph.math().calculateIntersection(curvePoint, link.domain(), 1); + pathEnd = graph.math().calculateIntersection(curvePoint, link.range(), 1); + } + dx = pathStart.x; + dy = -pathStart.y; + px = curvePoint.x; + py = -curvePoint.y; + rx = pathEnd.x; + ry = -pathEnd.y; + } + + texString += "\\draw [" + colorStr + linkStyle + linkWidth + isLoop + "] plot [smooth] coordinates {(" + + dx + "pt, " + dy + "pt) (" + px + "pt, " + py + "pt) (" + rx + "pt, " + ry + "pt)};\n"; + + + if ( link.property().markerElement() === undefined ) continue; + + // add arrow head; + + + if ( link.property().type() === "owl:someValuesFrom" || link.property().type() === "owl:allValuesFrom" ) { + arrowType = "triangleBlue"; + } + + lg = link.pathObj(); + pathLen = Math.floor(lg.node().getTotalLength()); + var p1 = lg.node().getPointAtLength(pathLen - 4); + var p2 = lg.node().getPointAtLength(pathLen); + var markerCenter = lg.node().getPointAtLength(pathLen - 6); + + if ( link.property().type() === "setOperatorProperty" ) { + p1 = lg.node().getPointAtLength(4); + p2 = lg.node().getPointAtLength(0); + markerCenter = lg.node().getPointAtLength(8); + arrowType = "Diamond"; + } + + startX = p1.x; + startY = p1.y; + endX = p2.x; + endY = p2.y; + normX = endX - startX; + normY = endY - startY; + len = Math.sqrt(normX * normX + normY * normY); + normX = normX / len; + normY = normY / len; + + ahAngle = -1.0 * Math.atan2(normY, normX) * (180 / Math.PI); + ahAngle -= 90; + if ( link.property().type() === "setOperatorProperty" ) { + ahAngle -= 45; + } + // console.log(link.property().labelForCurrentLanguage()+ ": "+normX+ " "+normY +" "+ahAngle); + rx = markerCenter.x; + ry = markerCenter.y; + if ( link.layers().length === 1 && !link.loops() ) { + // markerOffset=-1*m + ry = -1 * ry; + texString += "\\node[" + arrowType + ", rotate=" + ahAngle + "] at (" + rx + "pt, " + ry + "pt) (single_marker" + i + ") {};\n "; + } else { + ry = -1 * ry; + texString += "\\node[" + arrowType + ", rotate=" + ahAngle + "] at (" + rx + "pt, " + ry + "pt) (marker" + i + ") {};\n "; + } + + // if (link.isLoop()){ + // rotAngle=-10+angle * (180 / Math.PI); + // } + + // add cardinality; + var cardinalityText = link.property().generateCardinalityText(); + if ( cardinalityText && cardinalityText.length > 0 ) { + var cardinalityCenter = lg.node().getPointAtLength(pathLen - 18); + var cx = cardinalityCenter.x - (10 * normY); + var cy = cardinalityCenter.y + (10 * normX); // using orthonormal y Coordinate + cy *= -1.0; + var textColor = "black"; + if ( cardinalityText.indexOf("A") > -1 ) { + cardinalityText = "$\\forall$"; + } + if ( cardinalityText.indexOf("E") > -1 ) { + cardinalityText = "$\\exists$"; + } + + + texString += "\\node[font={\\fontsize{12pt}{12}\\selectfont \\sffamily },text=" + textColor + "] at (" + cx + "pt, " + cy + "pt) (cardinalityText" + i + ") {" + cardinalityText + "};\n "; + } + + + if ( link.property().inverse() ) { + lg = link.pathObj(); + pathLen = Math.floor(lg.node().getTotalLength()); + var p1_inv = lg.node().getPointAtLength(4); + var p2_inv = lg.node().getPointAtLength(0); + var markerCenter_inv = lg.node().getPointAtLength(6); + startX = p1_inv.x; + startY = p1_inv.y; + endX = p2_inv.x; + endY = p2_inv.y; + normX = endX - startX; + normY = endY - startY; + len = Math.sqrt(normX * normX + normY * normY); + normX = normX / len; + normY = normY / len; + + ahAngle = -1.0 * Math.atan2(normY, normX) * (180 / Math.PI); + ahAngle -= 90; + // console.log("INV>>\n "+link.property().inverse().labelForCurrentLanguage()+ ": "+normX+ " "+normY +" "+ahAngle); + rx = markerCenter_inv.x; + ry = markerCenter_inv.y; + if ( link.layers().length === 1 && !link.loops() ) { + // markerOffset=-1*m + ry = -1 * ry; + texString += "\\node[" + arrowType + ", rotate=" + ahAngle + "] at (" + rx + "pt, " + ry + "pt) (INV_single_marker" + i + ") {};\n "; + } else { + ry = -1 * ry; + texString += "\\node[" + arrowType + ", rotate=" + ahAngle + "] at (" + rx + "pt, " + ry + "pt) (INV_marker" + i + ") {};\n "; + } + } + + + } + + + nodeElements.each(function ( node ){ + + px = node.x; + py = -node.y; + identifier = node.labelForCurrentLanguage(); + // console.log("Writing : "+ identifier); + if ( identifier === undefined ) identifier = ""; + var qType = "owlClass"; + if ( node.type() === "owl:Thing" || node.type() === "owl:Nothing" ) + qType = "owlThing"; + + if ( node.type() === "owl:equivalentClass" ) { + qType = "owlEquivalentClass"; + } + var textColorStr = ""; + if ( node.textBlock ) { + var txtColor = node.textBlock()._textBlock().style("fill"); + if ( txtColor === "rgb(0, 0, 0)" ) { + textColorStr = ", text=black"; + } + if ( txtColor === "rgb(255, 255, 255)" ) { + textColorStr = ", text=white"; + } + + + var tspans = node.textBlock()._textBlock().node().children; + if ( tspans[0] ) { + identifier = tspans[0].innerHTML; + if ( node.individuals() && node.individuals().length === parseInt(tspans[0].innerHTML) ) { + identifier = "{\\color{gray} " + tspans[0].innerHTML + " }"; + } + for ( var t = 1; t < tspans.length; t++ ) { + if ( node.individuals() && node.individuals().length === parseInt(tspans[t].innerHTML) ) { + identifier += "\\\\ {\\color{gray} " + tspans[t].innerHTML + " }"; + } else { + identifier += "\\\\ {\\small " + tspans[t].innerHTML + " }"; + } + } + } + } + if ( node.type() === "rdfs:Literal" ) { + qType = "Literal"; + } + if ( node.type() === "rdfs:Datatype" ) { + qType = "Datatype"; + } + if ( node.attributes().indexOf("anonymous") !== -1 ) { + qType = "anonymousClass"; + } + + + if ( node.type() === "owl:unionOf" || node.type() === "owl:complementOf" || node.type() === "owl:disjointUnionOf" || node.type() === "owl:intersectionOf" ) + qType = "owlClass"; + + var bgColorStr = ""; + var widthString = ""; + + if ( node.type() === "rdfs:Literal" || node.type() === "rdfs:Datatype" ) { + var width = node.width(); + widthString = ",minimum width=" + width + "pt"; + } + else { + widthString = ",minimum size=" + 2 * node.actualRadius() + "pt"; + + } + if ( node.backgroundColor() ) { + var bgColor = node.backgroundColor(); + bgColor.toUpperCase(); + bgColor = bgColor.slice(1, bgColor.length); + texString += "\\definecolor{Node" + i + "_COLOR}{HTML}{" + bgColor + "} \n "; + bgColorStr = ", fill=Node" + i + "_COLOR "; + } + if ( node.attributes().indexOf("deprecated") > -1 ) { + texString += "\\definecolor{Node" + i + "_COLOR}{HTML}{CCCCCC} \n "; + bgColorStr = ", fill=Node" + i + "_COLOR "; + } + + var leftPos = px - 7; + var rightPos = px + 7; + var txtOffset = py + 20; + if ( node.type() !== "owl:unionOf" || node.type() !== "owl:disjointUnionOf" ) { + texString += "\\node[" + qType + " " + widthString + " " + bgColorStr + " " + textColorStr + "] at (" + px + "pt, " + py + "pt) (Node" + i + ") {" + identifier.replaceAll("_", "\\_ ") + "};\n"; + } + if ( node.type() === "owl:unionOf" ) { + // add symbol to it; + texString += "\\node[" + qType + " " + widthString + " " + bgColorStr + " " + textColorStr + "] at (" + px + "pt, " + py + "pt) (Node" + i + ") {};\n"; + texString += "\\node[unionOf , text=black] at (" + leftPos + "pt, " + py + "pt) (SymbolNode" + i + ") {};\n"; + texString += "\\node[unionOf , text=black] at (" + rightPos + "pt, " + py + "pt) (SymbolNode" + i + ") {};\n"; + texString += "\\node[unionOf ,fill=none , text=black] at (" + leftPos + "pt, " + py + "pt) (SymbolNode" + i + ") {};\n"; + texString += "\\node[text=black] at (" + px + "pt, " + py + "pt) (unionText13) {$\\mathbf{\\cup}$};\n"; + texString += "\\node[font={\\fontsize{12pt}{12}\\selectfont \\sffamily }" + textColorStr + "] at (" + px + "pt, " + txtOffset + "pt) (Node_text" + i + ") {" + identifier.replaceAll("_", "\\_ ") + "};\n"; + } + // OWL DISJOINT UNION OF + if ( node.type() === "owl:disjointUnionOf" ) { + texString += "\\node[" + qType + " " + widthString + " " + bgColorStr + " " + textColorStr + "] at (" + px + "pt, " + py + "pt) (Node" + i + ") {};\n"; + texString += "\\node[unionOf , text=black] at (" + leftPos + "pt, " + py + "pt) (SymbolNode" + i + ") {};\n"; + texString += "\\node[unionOf , text=black] at (" + rightPos + "pt, " + py + "pt) (SymbolNode" + i + ") {};\n"; + texString += "\\node[unionOf ,fill=none , text=black] at (" + leftPos + "pt, " + py + "pt) (SymbolNode" + i + ") {};\n"; + texString += "\\node[font={\\fontsize{12pt}{12}\\selectfont \\sffamily }" + textColorStr + "] at (" + px + "pt, " + py + "pt) (disjointUnoinText" + i + ") {1};\n"; + texString += "\\node[font={\\fontsize{12pt}{12}\\selectfont \\sffamily }" + textColorStr + "] at (" + px + "pt, " + txtOffset + "pt) (Node_text" + i + ") {" + identifier.replaceAll("_", "\\_ ") + "};\n"; + } + // OWL COMPLEMENT OF + if ( node.type() === "owl:complementOf" ) { + // add symbol to it; + texString += "\\node[" + qType + " " + widthString + " " + bgColorStr + " " + textColorStr + "] at (" + px + "pt, " + py + "pt) (Node" + i + ") {};\n"; + texString += "\\node[unionOf , text=black] at (" + px + "pt, " + py + "pt) (SymbolNode" + i + ") {};\n"; + texString += "\\node[font={\\fontsize{18pt}{18}\\selectfont \\sffamily }" + textColorStr + "] at (" + px + "pt, " + py + "pt) (unionText13) {$\\neg$};\n"; + texString += "\\node[font={\\fontsize{12pt}{12}\\selectfont \\sffamily }" + textColorStr + "] at (" + px + "pt, " + txtOffset + "pt) (Node_text" + i + ") {" + identifier.replaceAll("_", "\\_ ") + "};\n"; + } + // OWL INTERSECTION OF + if ( node.type() === "owl:intersectionOf" ) { + texString += "\\node[" + qType + " " + widthString + " " + bgColorStr + " " + textColorStr + "] at (" + px + "pt, " + py + "pt) (Node" + i + ") {};\n"; + texString += "\\node[unionOf , text=black] at (" + leftPos + "pt, " + py + "pt) (SymbolNode" + i + ") {};\n"; + texString += "\\node[unionOf , text=black] at (" + rightPos + "pt, " + py + "pt) (SymbolNode" + i + ") {};\n"; + texString += "\\node[unionOf ,fill=none , text=black] at (" + leftPos + "pt, " + py + "pt) (SymbolNode" + i + ") {};\n"; + + // add now the outer colors; + texString += "\\filldraw[even odd rule,fill=owlClassColor,line width=1pt] (" + leftPos + "pt, " + py + "pt) circle (12.5pt) (" + rightPos + "pt, " + py + "pt) circle (12.5pt);\n "; + + // add texts + texString += "\\node[font={\\fontsize{12pt}{12}\\selectfont \\sffamily }" + textColorStr + "] at (" + px + "pt, " + py + "pt) (intersectionText" + i + ") {$\\cap$};\n"; + texString += "\\node[font={\\fontsize{12pt}{12}\\selectfont \\sffamily }" + textColorStr + "] at (" + px + "pt, " + txtOffset + "pt) (Node_text" + i + ") {" + identifier.replaceAll("_", "\\_ ") + "};\n"; + + } + + + i++; + + }); + for ( i = 0; i < propElements.length; i++ ) { + var correspondingProp = propElements[i].property(); + var p_px = propElements[i].x; + var p_py = -propElements[i].y; + identifier = correspondingProp.labelForCurrentLanguage(); + if ( identifier === undefined ) identifier = ""; + var textColorStr = ""; + if ( correspondingProp.textBlock && correspondingProp.textBlock() ) { + var txtColor = correspondingProp.textBlock()._textBlock().style("fill"); + // console.log("PropertyTextColor="+txtColor); + if ( txtColor === "rgb(0, 0, 0)" ) { + textColorStr = ", text=black"; + } + if ( txtColor === "rgb(255, 255, 255)" ) { + textColorStr = ", text=white"; + } + var tspans = correspondingProp.textBlock()._textBlock().node().children; + + // identifier=node.textBlock()._textBlock().text(); + // console.log(tspans); + if ( tspans[0] ) { + identifier = tspans[0].innerHTML; + + for ( var t = 1; t < tspans.length; t++ ) { + var spanText = tspans[t].innerHTML; + if ( spanText.indexOf("(") > -1 ) { + identifier += "\\\\ {\\small " + tspans[t].innerHTML + " }"; + } + else { + identifier += "\\\\ " + tspans[t].innerHTML; + } + } + } + else { + } + } + if ( correspondingProp.type() === "setOperatorProperty" ) { + continue; // this property does not have a label + } + var qType = "owlObjectProperty"; + if ( correspondingProp.type() === "owl:DatatypeProperty" ) { + qType = "owlDatatypeProperty"; + } + if ( correspondingProp.type() === "rdfs:subClassOf" ) { + qType = "rdfsSubClassOf"; + } + if ( correspondingProp.type() === "rdf:Property" ) { + qType = "rdfProperty"; + } + + + var bgColorStr = ""; + if ( correspondingProp.backgroundColor() ) { + // console.log("Found backGround color"); + var bgColor = correspondingProp.backgroundColor(); + //console.log(bgColor); + bgColor.toUpperCase(); + bgColor = bgColor.slice(1, bgColor.length); + texString += "\\definecolor{property" + i + "_COLOR}{HTML}{" + bgColor + "} \n "; + bgColorStr = ", fill=property" + i + "_COLOR "; + } + if ( correspondingProp.attributes().indexOf("deprecated") > -1 ) { + texString += "\\definecolor{property" + i + "_COLOR}{HTML}{CCCCCC} \n "; + bgColorStr = ", fill=property" + i + "_COLOR "; + } + + var widthString = ""; + var width = correspondingProp.textWidth(); + widthString = ",minimum width=" + width + "pt"; + + + // OWL INTERSECTION OF + if ( correspondingProp.type() === "owl:disjointWith" ) { + var leftPos = p_px - 12; + var rightPos = p_px + 12; + var txtOffset = p_py - 20; + texString += "\\node[" + qType + " " + widthString + " " + bgColorStr + " " + textColorStr + "] at (" + p_px + "pt, " + p_py + "pt) (Node" + i + ") {};\n"; + texString += "\\node[disjointWith , text=black] at (" + leftPos + "pt, " + p_py + "pt) (SymbolNode" + i + ") {};\n"; + texString += "\\node[disjointWith , text=black] at (" + rightPos + "pt, " + p_py + "pt) (SymbolNode" + i + ") {};\n"; + texString += "\\node[font={\\fontsize{12pt}{12}\\selectfont \\sffamily }" + textColorStr + "] at (" + p_px + "pt, " + txtOffset + "pt) (Node_text" + i + ") {"; + if ( graph.options().compactNotation() === false ) { + texString += "(disjoint)"; + } + texString += "};\n"; + continue; + } + + + if ( correspondingProp.inverse() ) { + var inv_correspondingProp = correspondingProp.inverse(); + // create the rendering element for the inverse property; + var inv_identifier = inv_correspondingProp.labelForCurrentLanguage(); + if ( inv_identifier === undefined ) inv_identifier = ""; + var inv_textColorStr = ""; + //console.log(inv_correspondingProp); + //console.log(inv_correspondingProp.textBlock()); + + if ( inv_correspondingProp.textBlock && inv_correspondingProp.textBlock() ) { + + var inv_txtColor = inv_correspondingProp.textBlock()._textBlock().style("fill"); + // console.log("PropertyTextColor="+inv_txtColor); + if ( inv_txtColor === "rgb(0, 0, 0)" ) { + inv_textColorStr = ", text=black"; + } + if ( inv_txtColor === "rgb(255, 255, 255)" ) { + inv_textColorStr = ", text=white"; + } + var inv_tspans = inv_correspondingProp.textBlock()._textBlock().node().children; + + // identifier=node.textBlock()._textBlock().text(); + // console.log(inv_tspans); + if ( inv_tspans[0] ) { + inv_identifier = inv_tspans[0].innerHTML; + + for ( var inv_t = 1; inv_t < inv_tspans.length; inv_t++ ) { + var ispanText = inv_tspans[inv_t].innerHTML; + if ( ispanText.indexOf("(") > -1 ) { + inv_identifier += "\\\\ {\\small " + inv_tspans[inv_t].innerHTML + " }"; + } else { + inv_identifier += "\\\\ " + inv_tspans[inv_t].innerHTML; + } + } + } + } + var inv_qType = "owlObjectProperty"; + var inv_bgColorStr = ""; + + if ( inv_correspondingProp.backgroundColor() ) { + // console.log("Found backGround color"); + var inv_bgColor = inv_correspondingProp.backgroundColor(); + // console.log(inv_bgColor); + inv_bgColor.toUpperCase(); + inv_bgColor = inv_bgColor.slice(1, inv_bgColor.length); + texString += "\\definecolor{inv_property" + i + "_COLOR}{HTML}{" + inv_bgColor + "} \n "; + inv_bgColorStr = ", fill=inv_property" + i + "_COLOR "; + } + if ( inv_correspondingProp.attributes().indexOf("deprecated") > -1 ) { + texString += "\\definecolor{inv_property" + i + "_COLOR}{HTML}{CCCCCC} \n "; + inv_bgColorStr = ", fill=inv_property" + i + "_COLOR "; + } + + var inv_widthString = ""; + var inv_width = inv_correspondingProp.textWidth(); + + var pOY1 = p_py - 14; + var pOY2 = p_py + 14; + inv_widthString = ",minimum width=" + inv_width + "pt"; + texString += "% Createing Inverse Property \n"; + texString += "\\node[" + inv_qType + " " + inv_widthString + " " + inv_bgColorStr + " " + inv_textColorStr + "] at (" + p_px + "pt, " + pOY1 + "pt) (property" + i + ") {" + inv_identifier.replaceAll("_", "\\_ ") + "};\n"; + texString += "% " + inv_qType + " vs " + qType + "\n"; + texString += "% " + inv_widthString + " vs " + widthString + "\n"; + texString += "% " + inv_bgColorStr + " vs " + bgColorStr + "\n"; + texString += "% " + inv_textColorStr + " vs " + textColorStr + "\n"; + + texString += "\\node[" + qType + " " + widthString + " " + bgColorStr + " " + textColorStr + "] at (" + p_px + "pt, " + pOY2 + "pt) (property" + i + ") {" + identifier.replaceAll("_", "\\_ ") + "};\n"; + + } else { + texString += "\\node[" + qType + " " + widthString + " " + bgColorStr + " " + textColorStr + "] at (" + p_px + "pt, " + p_py + "pt) (property" + i + ") {" + identifier.replaceAll("_", "\\_ ") + "};\n"; + } + } + + texString += "\\end{tikzpicture}\n}\n \\end{center}\n"; + + // console.log("Tex Output\n"+ texString); + var dataURI = "data:text/json;charset=utf-8," + encodeURIComponent(texString); + exportTexButton.attr("href", dataURI) + .attr("download", exportFilename + ".tex"); + + + } + + function calculateRadian( angle ){ + angle = angle % 360; + if ( angle < 0 ) { + angle = angle + 360; + } + return (Math.PI * angle) / 180; + } + + function calculateAngle( radian ){ + return radian * (180 / Math.PI); + } + + return exportMenu; +}; diff --git a/src/app/js/menu/exportTTLModule.js b/src/app/js/menu/exportTTLModule.js new file mode 100644 index 0000000000000000000000000000000000000000..a22793487ef81c501cb9b70d1eb0191d877f837e --- /dev/null +++ b/src/app/js/menu/exportTTLModule.js @@ -0,0 +1,590 @@ +/** + * Contains the logic for the export button. + * @returns {{}} + */ +module.exports = function ( graph ){ + var exportTTLModule = {}; + var resultingTTLContent = ""; + var currentNodes; + var currentProperties; + var currentAxioms; + var Map_ID2Node = {}; + var Map_ID2Prop = {}; + var prefixModule = webvowl.util.prefixTools(graph); + + exportTTLModule.requestExport = function (){ + prefixModule.updatePrefixModel(); + resultingTTLContent = ""; + currentNodes = graph.getClassDataForTtlExport(); + var i; + for ( i = 0; i < currentNodes.length; i++ ) { + Map_ID2Node[currentNodes[i].id()] = currentNodes[i]; + } + currentProperties = graph.getPropertyDataForTtlExport(); + + for ( i = 0; i < currentProperties.length; i++ ) { + Map_ID2Prop[currentProperties[i].id()] = currentProperties[i]; + } + + + prepareHeader(); + preparePrefixList(); + prepareOntologyDef(); + resultingTTLContent += "#################################################################\r\n\r\n"; + preparePrefixRepresentation(); + var property_success = exportProperties(); + var class_success = exportClasses(); + currentNodes = null; + currentProperties = null; + Map_ID2Node = {}; + Map_ID2Prop = {}; + if ( property_success === false || class_success === false ) + return false; + return true; + + }; + + function preparePrefixRepresentation(){ + var i; + var allNodes = graph.getUnfilteredData().nodes; + var allProps = graph.getUnfilteredData().properties; + for ( i = 0; i < allNodes.length; i++ ) { + var nodeIRI = prefixModule.getPrefixRepresentationForFullURI(allNodes[i].iri()); + if ( prefixModule.validURL(nodeIRI) === true ) + allNodes[i].prefixRepresentation = "<" + nodeIRI + ">"; + else + allNodes[i].prefixRepresentation = nodeIRI; + } + for ( i = 0; i < allProps.length; i++ ) { + var propIRI = prefixModule.getPrefixRepresentationForFullURI(allProps[i].iri()); + if ( prefixModule.validURL(propIRI) === true ) + allProps[i].prefixRepresentation = "<" + propIRI + ">"; + else + allProps[i].prefixRepresentation = propIRI; + } + } + + function exportProperties(){ + if ( currentProperties.length === 0 ) return; // we dont need to write that + resultingTTLContent += "### Property Definitions (Number of Property) " + currentProperties.length + " ###\r\n"; + for ( var i = 0; i < currentProperties.length; i++ ) { + + resultingTTLContent += "# --------------------------- Property " + i + "------------------------- \r\n"; + var addedElement = extractPropertyDescription(currentProperties[i]); + resultingTTLContent += addedElement; + //@ workaround for not supported elements + if ( addedElement.indexOf("WHYEMPTYNAME") !== -1 ) { + return false; + } + } + return true; + } + + + function exportClasses(){ + if ( currentNodes.length === 0 ) return; // we dont need to write that + resultingTTLContent += "### Class Definitions (Number of Classes) " + currentNodes.length + " ###\r\n"; + for ( var i = 0; i < currentNodes.length; i++ ) { + // check for node type here and return false + resultingTTLContent += "# --------------------------- Class " + i + "------------------------- \r\n"; + var addedElement = extractClassDescription(currentNodes[i]); + resultingTTLContent += addedElement; + + if ( addedElement.indexOf("WHYEMPTYNAME") !== -1 ) { + return false; + } + } + return true; + } + + function getPresentAttribute( selectedElement, element ){ + var attr = selectedElement.attributes(); + return (attr.indexOf(element) >= 0); + } + + function extractClassDescription( node ){ + var subject = node.prefixRepresentation; + var predicate = "rdf:type"; + var object = node.type(); + if ( node.type() === "owl:equivalentClass" ) + object = "owl:Class"; + if ( node.type() === "owl:disjointUnionOf" ) + object = "owl:Class"; + if ( node.type() === "owl:unionOf" ) + object = "owl:Class"; + var arrayOfNodes = []; + var arrayOfUnionNodes = []; + + if ( node.union() ) { + var union = node.union(); + for ( var u = 0; u < union.length; u++ ) { + var u_node = Map_ID2Node[union[u]]; + arrayOfUnionNodes.push(u_node); + } + } + + if ( node.disjointUnion() ) { + var distUnion = node.disjointUnion(); + for ( var du = 0; du < distUnion.length; du++ ) { + var du_node = Map_ID2Node[distUnion[du]]; + arrayOfNodes.push(du_node); + } + } + + var objectDef = subject + " " + predicate + " " + object; + if ( getPresentAttribute(node, "deprecated") === true ) { + objectDef += ", owl:DeprecatedProperty"; + } + // equivalent class handeled using type itself! + + // check for equivalent classes; + var indent = getIndent(subject); + objectDef += "; \r\n"; + for ( var e = 0; e < node.equivalents().length; e++ ) { + var eqIRI = prefixModule.getPrefixRepresentationForFullURI(node.equivalents()[e].iri()); + var eqNode_prefRepresentation = ""; + if ( prefixModule.validURL(eqIRI) === true ) + eqNode_prefRepresentation = "<" + eqIRI + ">"; + else + eqNode_prefRepresentation = eqIRI; + objectDef += indent + " owl:equivalentClass " + eqNode_prefRepresentation + " ;\r\n"; + } + + // if (getPresentAttribute(node,"equivalent")===true){ + // objectDef+=", owl:EquivalentClass"; + // } + + // add Comments + + if ( node.commentForCurrentLanguage() ) { + + objectDef += indent + " rdfs:comment \"" + node.commentForCurrentLanguage() + "\" ;\r\n"; + } + + if ( node.annotations() ) { + var annotations = node.annotations(); + for ( var an in annotations ) { + if ( annotations.hasOwnProperty(an) ) { + var anArrayObj = annotations[an]; + var anObj = anArrayObj[0]; + var an_ident = anObj.identifier; + var an_val = anObj.value; + + if ( an_ident === "isDefinedBy" ) { + objectDef += indent + " rdfs:isDefinedBy <" + an_val + "> ;\r\n"; + } + if ( an_ident === "term_status" ) { + objectDef += indent + " vs:term_status \"" + an_val + "\" ;\r\n"; + } + } + } + } + + + if ( arrayOfNodes.length > 0 ) { + // add disjoint unionOf + objectDef += indent + " owl:disjointUnionOf ("; + for ( var duE = 0; duE < arrayOfNodes.length; duE++ ) { + var duIri = prefixModule.getPrefixRepresentationForFullURI(arrayOfNodes[duE].iri()); + var duNode_prefRepresentation = ""; + if ( prefixModule.validURL(duIri) === true ) + duNode_prefRepresentation = "<" + duIri + ">"; + else + duNode_prefRepresentation = duIri; + objectDef += indent + indent + duNode_prefRepresentation + " \n"; + } + objectDef += ") ;\r\n"; + } + + if ( arrayOfUnionNodes.length > 0 ) { + // add disjoint unionOf + objectDef += indent + " rdfs:subClassOf [ rdf:type owl:Class ; \r\n"; + objectDef += indent + indent + " owl:unionOf ( "; + + for ( var uE = 0; uE < arrayOfUnionNodes.length; uE++ ) { + + if ( arrayOfUnionNodes[uE] && arrayOfUnionNodes[uE].iri() ) { + var uIri = prefixModule.getPrefixRepresentationForFullURI(arrayOfUnionNodes[uE].iri()); + var uNode_prefRepresentation = ""; + if ( prefixModule.validURL(uIri) === true ) + uNode_prefRepresentation = "<" + uIri + ">"; + else + uNode_prefRepresentation = uIri; + objectDef += indent + indent + indent + uNode_prefRepresentation + " \n"; + } + } + objectDef += ") ;\r\n"; + + + } + + + var allProps = graph.getUnfilteredData().properties; + var myProperties = []; + var i; + for ( i = 0; i < allProps.length; i++ ) { + if ( allProps[i].domain() === node && + ( allProps[i].type() === "rdfs:subClassOf" || + allProps[i].type() === "owl:allValuesFrom" || + allProps[i].type() === "owl:someValuesFrom") + ) { + myProperties.push(allProps[i]); + } + // special case disjoint with>> both domain and range get that property + if ( (allProps[i].domain() === node) && + allProps[i].type() === "owl:disjointWith" ) { + myProperties.push(allProps[i]); + } + + } + for ( i = 0; i < myProperties.length; i++ ) { + // depending on the property we have to do some things; + + // special case + if ( myProperties[i].type() === "owl:someValuesFrom" ) { + objectDef += indent + " rdfs:subClassOf [ rdf:type owl:Restriction ; \r\n"; + objectDef += indent + " owl:onProperty " + myProperties[i].prefixRepresentation + ";\r\n"; + if ( myProperties[i].range().type() !== "owl:Thing" ) { + objectDef += indent + " owl:someValuesFrom " + myProperties[i].range().prefixRepresentation + "\r\n"; + } + objectDef += indent + " ];\r\n"; + continue; + } + + if ( myProperties[i].type() === "owl:allValuesFrom" ) { + objectDef += indent + " rdfs:subClassOf [ rdf:type owl:Restriction ; \r\n"; + objectDef += indent + " owl:onProperty " + myProperties[i].prefixRepresentation + ";\r\n"; + if ( myProperties[i].range().type() !== "owl:Thing" ) { + objectDef += indent + " owl:allValuesFrom " + myProperties[i].range().prefixRepresentation + "\r\n"; + } + objectDef += indent + " ];\r\n"; + continue; + } + + if ( myProperties[i].range().type() !== "owl:Thing" ) { + objectDef += indent + " " + myProperties[i].prefixRepresentation + + " " + myProperties[i].range().prefixRepresentation + " ;\r\n"; + + + } + } + + + objectDef += general_Label_languageExtractor(indent, node.label(), "rdfs:label", true); + return objectDef; + + } + + function extractPropertyDescription( property ){ + var subject = property.prefixRepresentation; + if ( subject.length === 0 ) { + console.log("THIS SHOULD NOT HAPPEN"); + var propIRI = prefixModule.getPrefixRepresentationForFullURI(property.iri()); + console.log("FOUND " + propIRI); + + + } + var predicate = "rdf:type"; + var object = property.type(); + + var objectDef = subject + " " + predicate + " " + object; + if ( getPresentAttribute(property, "deprecated") === true ) { + objectDef += ", owl:DeprecatedProperty"; + } + if ( getPresentAttribute(property, "functional") === true ) { + objectDef += ", owl:FunctionalProperty"; + } + if ( getPresentAttribute(property, "inverse functional") === true ) { + objectDef += ", owl:InverseFunctionalProperty"; + } + if ( getPresentAttribute(property, "symmetric") === true ) { + objectDef += ", owl:SymmetricProperty"; + } + if ( getPresentAttribute(property, "transitive") === true ) { + objectDef += ", owl:TransitiveProperty"; + } + var indent = getIndent(subject); + + if ( property.inverse() ) { + objectDef += "; \r\n"; + objectDef += indent + " owl:inverseOf " + property.inverse().prefixRepresentation; + } + + // check for domain and range; + + + var closeStatement = false; + var domain = property.domain(); + var range = property.range(); + + + objectDef += " ;\r\n"; + + + if ( property.commentForCurrentLanguage() ) { + + objectDef += indent + " rdfs:comment \"" + property.commentForCurrentLanguage() + "\" ;\r\n"; + } + + if ( property.superproperties() ) { + var superProps = property.superproperties(); + for ( var sP = 0; sP < superProps.length; sP++ ) { + var sPelement = superProps[sP]; + objectDef += indent + "rdfs:subPropertyOf " + sPelement.prefixRepresentation + ";\r\n"; + } + // for (var an in annotations){ + // if (annotations.hasOwnProperty(an)){ + // var anArrayObj=annotations[an]; + // var anObj=anArrayObj[0]; + // var an_ident=anObj.identifier; + // var an_val=anObj.value; + // console.log(an_ident + " "+ an_val); + // + // if (an_ident==="isDefinedBy"){ + // objectDef+=indent+" rdfs:isDefinedBy <"+an_val+"> ;\r\n"; + // } + // if (an_ident==="term_status"){ + // objectDef+=indent+" vs:term_status \""+an_val+"\" ;\r\n"; + // } + // } + // } + + } + + if ( property.annotations() ) { + var annotations = property.annotations(); + for ( var an in annotations ) { + if ( annotations.hasOwnProperty(an) ) { + var anArrayObj = annotations[an]; + var anObj = anArrayObj[0]; + var an_ident = anObj.identifier; + var an_val = anObj.value; + + if ( an_ident === "isDefinedBy" ) { + objectDef += indent + " rdfs:isDefinedBy <" + an_val + "> ;\r\n"; + } + if ( an_ident === "term_status" ) { + objectDef += indent + " vs:term_status \"" + an_val + "\" ;\r\n"; + } + } + } + } + + + if ( domain.type() === "owl:Thing" && range.type() === "owl:Thing" ) { + // we do not write domain and range + if ( typeof property.label() !== "object" && property.label().length === 0 ) { + closeStatement = true; + } + } + + + if ( closeStatement === true ) { + var uobjectDef = objectDef.substring(0, objectDef.length - 2); + objectDef = uobjectDef + " . \r\n"; + return objectDef; + } + // objectDef+="; \r\n"; + var labelDescription; + + + if ( domain.type() === "owl:Thing" && range.type() === "owl:Thing" ) { + labelDescription = general_Label_languageExtractor(indent, property.label(), "rdfs:label", true); + objectDef += labelDescription; + } + else { + // do not close the statement; + labelDescription = general_Label_languageExtractor(indent, property.label(), "rdfs:label"); + objectDef += labelDescription; + if ( domain.type() !== "owl:Thing" ) { + objectDef += indent + " rdfs:domain " + domain.prefixRepresentation + ";\r\n"; + } + if ( range.type() !== "owl:Thing" ) { + objectDef += indent + " rdfs:range " + range.prefixRepresentation + ";\r\n"; + } + + // close statement now; + + var s_needUpdate = objectDef; + var s_lastPtr = s_needUpdate.lastIndexOf(";"); + objectDef = s_needUpdate.substring(0, s_lastPtr) + " . \r\n"; + } + + return objectDef; + + } + + + exportTTLModule.resultingTTL_Content = function (){ + return resultingTTLContent; + }; + + function getIndent( name ){ + if ( name === undefined ) { + return "WHYEMPTYNAME?"; + } + return new Array(name.length + 1).join(" "); + } + + function prepareHeader(){ + resultingTTLContent += "#################################################################\r\n"; + resultingTTLContent += "### Generated with the experimental alpha version of the TTL exporter of WebVOWL (version 1.1.7) " + + " http://visualdataweb.de/webvowl/ ###\r\n"; + resultingTTLContent += "#################################################################\r\n\r\n"; + + } + + function preparePrefixList(){ + var ontoIri = graph.options().getGeneralMetaObjectProperty('iri'); + var prefixList = graph.options().prefixList(); + var prefixDef = []; + prefixDef.push('@prefix : \t\t<' + ontoIri + '> .'); + for ( var name in prefixList ) { + if ( prefixList.hasOwnProperty(name) ) { + prefixDef.push('@prefix ' + name + ': \t\t<' + prefixList[name] + '> .'); + } + } + prefixDef.push('@base \t\t\t<' + ontoIri + '> .\r\n'); + + for ( var i = 0; i < prefixDef.length; i++ ) { + resultingTTLContent += prefixDef[i] + '\r\n'; + } + } + + function prepareOntologyDef(){ + var ontoIri = graph.options().getGeneralMetaObjectProperty('iri'); + var indent = getIndent('<' + ontoIri + '>'); + resultingTTLContent += '<' + ontoIri + '> rdf:type owl:Ontology ;\r\n' + + getOntologyTitle(indent) + + getOntologyDescription(indent) + + getOntologyVersion(indent) + + getOntologyAuthor(indent); + + // close the statement; + var s_needUpdate = resultingTTLContent; + var s_lastPtr = s_needUpdate.lastIndexOf(";"); + resultingTTLContent = s_needUpdate.substring(0, s_lastPtr) + " . \r\n"; + } + + function getOntologyTitle( indent ){ + return general_languageExtractor(indent, "title", "dc:title"); + } + + function getOntologyDescription( indent ){ + return general_languageExtractor(indent, "description", "dc:description"); + } + + function getOntologyAuthor( indent ){ + var languageElement = graph.options().getGeneralMetaObjectProperty('author'); + if ( languageElement ) { + if ( typeof languageElement !== "object" ) { + if ( languageElement.length === 0 ) + return ""; // an empty string + var aString = indent + " dc:creator " + '"' + languageElement + '";\r\n'; + return aString; + } + // we assume this thing is an array; + var authorString = indent + " dc:creator " + '"'; + for ( var i = 0; i < languageElement.length - 1; i++ ) { + authorString += languageElement[i] + ", "; + } + authorString += languageElement[languageElement.length - 1] + '";\r\n'; + return authorString; + } else { + return ""; // an empty string + } + } + + function getOntologyVersion( indent ){ + var languageElement = graph.options().getGeneralMetaObjectProperty('version'); + if ( languageElement ) { + if ( typeof languageElement !== "object" ) { + if ( languageElement.length === 0 ) + return ""; // an empty string + } + return general_languageExtractor(indent, "version", "owl:versionInfo"); + } else return ""; // an empty string + } + + function general_languageExtractor( indent, metaObjectDescription, annotationDescription, endStatement ){ + var languageElement = graph.options().getGeneralMetaObjectProperty(metaObjectDescription); + + if ( typeof languageElement === 'object' ) { + + var resultingLanguages = []; + for ( var name in languageElement ) { + if ( languageElement.hasOwnProperty(name) ) { + var content = languageElement[name]; + if ( name === "undefined" ) { + resultingLanguages.push(indent + " " + annotationDescription + ' "' + content + '"@en; \r\n'); + } + else { + resultingLanguages.push(indent + " " + annotationDescription + ' "' + content + '"@' + name + '; \r\n'); + } + } + } + // create resulting titles; + + var resultingString = ""; + for ( var i = 0; i < resultingLanguages.length; i++ ) { + resultingString += resultingLanguages[i]; + } + if ( endStatement && endStatement === true ) { + var needUpdate = resultingString; + var lastPtr = needUpdate.lastIndexOf(";"); + return needUpdate.substring(0, lastPtr) + ". \r\n"; + } else { + return resultingString; + } + + } else { + if ( endStatement && endStatement === true ) { + var s_needUpdate = indent + " " + annotationDescription + ' "' + languageElement + '"@en; \r\n'; + var s_lastPtr = s_needUpdate.lastIndexOf(";"); + return s_needUpdate.substring(0, s_lastPtr) + " . \r\n"; + } + return indent + " " + annotationDescription + ' "' + languageElement + '"@en;\r\n'; + } + } + + function general_Label_languageExtractor( indent, label, annotationDescription, endStatement ){ + var languageElement = label; + + if ( typeof languageElement === 'object' ) { + var resultingLanguages = []; + for ( var name in languageElement ) { + if ( languageElement.hasOwnProperty(name) ) { + var content = languageElement[name]; + if ( name === "undefined" ) { + resultingLanguages.push(indent + " " + annotationDescription + ' "' + content + '"@en; \r\n'); + } + else { + resultingLanguages.push(indent + " " + annotationDescription + ' "' + content + '"@' + name + '; \r\n'); + } + } + } + // create resulting titles; + var resultingString = ""; + for ( var i = 0; i < resultingLanguages.length; i++ ) { + resultingString += resultingLanguages[i]; + } + if ( endStatement && endStatement === true ) { + var needUpdate = resultingString; + var lastPtr = needUpdate.lastIndexOf(";"); + return needUpdate.substring(0, lastPtr) + " . \r\n"; + } else { + return resultingString; + } + + } else { + if ( endStatement && endStatement === true ) { + var s_needUpdate = indent + " " + annotationDescription + ' "' + languageElement + '"@en; \r\n'; + var s_lastPtr = s_needUpdate.lastIndexOf(";"); + return s_needUpdate.substring(0, s_lastPtr) + " . \r\n"; + } + return indent + " " + annotationDescription + ' "' + languageElement + '"@en; \r\n'; + } + } + + return exportTTLModule; +}; diff --git a/src/app/js/menu/filterMenu.js b/src/app/js/menu/filterMenu.js new file mode 100644 index 0000000000000000000000000000000000000000..aae3546b9d4f47141e46ef2ea56b04c65c2e8fbf --- /dev/null +++ b/src/app/js/menu/filterMenu.js @@ -0,0 +1,288 @@ +/** + * Contains the logic for connecting the filters with the website. + * + * @param graph required for calling a refresh after a filter change + * @returns {{}} + */ +module.exports = function ( graph ){ + + var filterMenu = {}, + checkboxData = [], + menuElement = d3.select("#m_filter"), + menuControl = d3.select("#c_filter a"), + nodeDegreeContainer = d3.select("#nodeDegreeFilteringOption"), + graphDegreeLevel, + defaultDegreeValue = 0, + degreeSlider; + + filterMenu.setDefaultDegreeValue = function ( val ){ + defaultDegreeValue = val; + }; + filterMenu.getDefaultDegreeValue = function (){ + return defaultDegreeValue; + }; + + filterMenu.getGraphObject = function (){ + return graph; + }; + /** some getter function **/ + filterMenu.getCheckBoxContainer = function (){ + return checkboxData; + }; + + filterMenu.getDegreeSliderValue = function (){ + return degreeSlider.property("value"); + }; + /** + * Connects the website with graph filters. + * @param datatypeFilter filter for all datatypes + * @param objectPropertyFilter filter for all object properties + * @param subclassFilter filter for all subclasses + * @param disjointFilter filter for all disjoint with properties + * @param setOperatorFilter filter for all set operators with properties + * @param nodeDegreeFilter filters nodes by their degree + */ + filterMenu.setup = function ( datatypeFilter, objectPropertyFilter, subclassFilter, disjointFilter, setOperatorFilter, nodeDegreeFilter ){ + // TODO: is this here really necessarry? << new menu visualization style? + menuControl.on("mouseover", function (){ + var searchMenu = graph.options().searchMenu(); + searchMenu.hideSearchEntries(); + }); + menuControl.on("mouseleave", function (){ + filterMenu.highlightForDegreeSlider(false); + }); + + addFilterItem(datatypeFilter, "datatype", "Datatype properties", "#datatypeFilteringOption"); + addFilterItem(objectPropertyFilter, "objectProperty", "Object properties", "#objectPropertyFilteringOption"); + addFilterItem(subclassFilter, "subclass", "Solitary subclasses", "#subclassFilteringOption"); + addFilterItem(disjointFilter, "disjoint", "Class disjointness", "#disjointFilteringOption"); + addFilterItem(setOperatorFilter, "setoperator", "Set operators", "#setOperatorFilteringOption"); + + addNodeDegreeFilter(nodeDegreeFilter, nodeDegreeContainer); + addAnimationFinishedListener(); + }; + + + function addFilterItem( filter, identifier, pluralNameOfFilteredItems, selector ){ + var filterContainer, + filterCheckbox; + + filterContainer = d3.select(selector) + .append("div") + .classed("checkboxContainer", true); + + filterCheckbox = filterContainer.append("input") + .classed("filterCheckbox", true) + .attr("id", identifier + "FilterCheckbox") + .attr("type", "checkbox") + .property("checked", filter.enabled()); + + // Store for easier resetting + checkboxData.push({ checkbox: filterCheckbox, defaultState: filter.enabled() }); + + filterCheckbox.on("click", function ( silent ){ + // There might be no parameters passed because of a manual + // invocation when resetting the filters + var isEnabled = filterCheckbox.property("checked"); + filter.enabled(isEnabled); + if ( silent !== true ) { + // updating graph when silent is false or the parameter is not given. + graph.update(); + } + }); + + filterContainer.append("label") + .attr("for", identifier + "FilterCheckbox") + .text(pluralNameOfFilteredItems); + } + + function addNodeDegreeFilter( nodeDegreeFilter, container ){ + nodeDegreeFilter.setMaxDegreeSetter(function ( maxDegree ){ + degreeSlider.attr("max", maxDegree); + setSliderValue(degreeSlider, Math.min(maxDegree, degreeSlider.property("value"))); + }); + + nodeDegreeFilter.setDegreeGetter(function (){ + return degreeSlider.property("value"); + }); + + nodeDegreeFilter.setDegreeSetter(function ( value ){ + setSliderValue(degreeSlider, value); + }); + + var sliderContainer, + sliderValueLabel; + + sliderContainer = container.append("div") + .classed("distanceSliderContainer", true); + + degreeSlider = sliderContainer.append("input") + .attr("id", "nodeDegreeDistanceSlider") + .attr("type", "range") + .attr("min", 0) + .attr("step", 1); + + sliderContainer.append("label") + .classed("description", true) + .attr("for", "nodeDegreeDistanceSlider") + .text("Degree of collapsing"); + + sliderValueLabel = sliderContainer.append("label") + .classed("value", true) + .attr("for", "nodeDegreeDistanceSlider") + .text(0); + + + degreeSlider.on("change", function ( silent ){ + if ( silent !== true ) { + graph.update(); + graphDegreeLevel = degreeSlider.property("value"); + } + }); + + + degreeSlider.on("input", function (){ + var degree = degreeSlider.property("value"); + sliderValueLabel.text(degree); + }); + + + // adding wheel events + degreeSlider.on("wheel", handleWheelEvent); + degreeSlider.on("focusout", function (){ + if ( degreeSlider.property("value") !== graphDegreeLevel ) { + graph.update(); + } + }); + } + + function handleWheelEvent(){ + var wheelEvent = d3.event; + + var offset; + if ( wheelEvent.deltaY < 0 ) offset = 1; + if ( wheelEvent.deltaY > 0 ) offset = -1; + var maxDeg = parseInt(degreeSlider.attr("max")); + var oldVal = parseInt(degreeSlider.property("value")); + var newSliderValue = oldVal + offset; + if ( oldVal !== newSliderValue && (newSliderValue >= 0 && newSliderValue <= maxDeg) ) { + // only update when they are different [reducing redundant updates] + // set the new value and emit an update signal + degreeSlider.property("value", newSliderValue); + degreeSlider.on("input")();// <<-- sets the text value + graph.update(); + } + d3.event.preventDefault(); + } + + function setSliderValue( slider, value ){ + slider.property("value", value).on("input")(); + } + + /** + * Resets the filters (and also filtered elements) to their default. + */ + filterMenu.reset = function (){ + checkboxData.forEach(function ( checkboxData ){ + var checkbox = checkboxData.checkbox, + enabledByDefault = checkboxData.defaultState, + isChecked = checkbox.property("checked"); + + if ( isChecked !== enabledByDefault ) { + checkbox.property("checked", enabledByDefault); + // Call onclick event handlers programmatically + checkbox.on("click")(); + } + }); + + setSliderValue(degreeSlider, 0); + degreeSlider.on("change")(); + }; + + function addAnimationFinishedListener(){ + menuControl.node().addEventListener("animationend", function (){ + menuControl.classed("buttonPulse", false); + menuControl.classed("filterMenuButtonHighlight", true); + + }); + } + + filterMenu.killButtonAnimation = function (){ + menuControl.classed("buttonPulse", false); + menuControl.classed("filterMenuButtonHighlight", false); + }; + + + filterMenu.highlightForDegreeSlider = function ( enable ){ + if ( !arguments.length ) { + enable = true; + } + menuControl.classed("highlighted", enable); + nodeDegreeContainer.classed("highlighted", enable); + // pulse button handling + if ( menuControl.classed("buttonPulse") === true && enable === true ) { + menuControl.classed("buttonPulse", false); + var timer = setTimeout(function (){ + menuControl.classed("buttonPulse", enable); + clearTimeout(timer); + // after the time is done, remove the pulse but stay highlighted + }, 100); + } else { + menuControl.classed("buttonPulse", enable); + menuControl.classed("filterMenuButtonHighlight", enable); + } + }; + + + /** importer functions **/ + // setting manually the values of the filter + // no update of the gui settings, these are updated in updateSettings + filterMenu.setCheckBoxValue = function ( id, checked ){ + for ( var i = 0; i < checkboxData.length; i++ ) { + var cbdId = checkboxData[i].checkbox.attr("id"); + if ( cbdId === id ) { + checkboxData[i].checkbox.property("checked", checked); + break; + } + } + }; + + filterMenu.getCheckBoxValue = function ( id ){ + for ( var i = 0; i < checkboxData.length; i++ ) { + var cbdId = checkboxData[i].checkbox.attr("id"); + if ( cbdId === id ) { + return checkboxData[i].checkbox.property("checked"); + + } + } + }; + // set the value of the slider + filterMenu.setDegreeSliderValue = function ( val ){ + degreeSlider.property("value", val); + }; + + filterMenu.getDegreeSliderValue = function (){ + return degreeSlider.property("value"); + }; + + // update the gui without invoking graph update (calling silent onclick function) + filterMenu.updateSettings = function (){ + var silent = true; + var sliderValue = degreeSlider.property("value"); + if ( sliderValue > 0 ) { + filterMenu.highlightForDegreeSlider(true); + } else { + filterMenu.highlightForDegreeSlider(false); + } + checkboxData.forEach(function ( checkboxData ){ + var checkbox = checkboxData.checkbox; + checkbox.on("click")(silent); + }); + + degreeSlider.on("input")(); + degreeSlider.on("change")(); + + }; + + return filterMenu; +}; diff --git a/src/app/js/menu/gravityMenu.js b/src/app/js/menu/gravityMenu.js new file mode 100644 index 0000000000000000000000000000000000000000..11c14bbd85b61a6c05171c8cd93bdf17dca53bf6 --- /dev/null +++ b/src/app/js/menu/gravityMenu.js @@ -0,0 +1,112 @@ +/** + * Contains the logic for setting up the gravity sliders. + * + * @param graph the associated webvowl graph + * @returns {{}} + */ +module.exports = function ( graph ){ + + var gravityMenu = {}, + sliders = [], + options = graph.graphOptions(), + defaultCharge = options.charge(); + + + /** + * Adds the gravity sliders to the website. + */ + gravityMenu.setup = function (){ + var menuEntry = d3.select("#m_gravity"); + menuEntry.on("mouseover", function (){ + var searchMenu = graph.options().searchMenu(); + searchMenu.hideSearchEntries(); + }); + addDistanceSlider("#classSliderOption", "class", "Class distance", options.classDistance); + addDistanceSlider("#datatypeSliderOption", "datatype", "Datatype distance", options.datatypeDistance); + }; + + function addDistanceSlider( selector, identifier, label, distanceFunction ){ + var defaultLinkDistance = distanceFunction(); + + var sliderContainer, + sliderValueLabel; + + sliderContainer = d3.select(selector) + .append("div") + .datum({ distanceFunction: distanceFunction }) // connect the options-function with the slider + .classed("distanceSliderContainer", true); + + var slider = sliderContainer.append("input") + .attr("id", identifier + "DistanceSlider") + .attr("type", "range") + .attr("min", 10) + .attr("max", 600) + .attr("value", distanceFunction()) + .attr("step", 10); + + sliderContainer.append("label") + .classed("description", true) + .attr("for", identifier + "DistanceSlider") + .text(label); + + sliderValueLabel = sliderContainer.append("label") + .classed("value", true) + .attr("for", identifier + "DistanceSlider") + .text(distanceFunction()); + + // Store slider for easier resetting + sliders.push(slider); + + slider.on("focusout", function (){ + graph.updateStyle(); + }); + + slider.on("input", function (){ + var distance = slider.property("value"); + distanceFunction(distance); + adjustCharge(defaultLinkDistance); + sliderValueLabel.text(distance); + graph.updateStyle(); + }); + + // add wheel event to the slider + slider.on("wheel", function (){ + var wheelEvent = d3.event; + var offset; + if ( wheelEvent.deltaY < 0 ) offset = 10; + if ( wheelEvent.deltaY > 0 ) offset = -10; + var oldVal = parseInt(slider.property("value")); + var newSliderValue = oldVal + offset; + if ( newSliderValue !== oldVal ) { + slider.property("value", newSliderValue); + distanceFunction(newSliderValue); + slider.on("input")(); // << set text and update the graphStyles + } + d3.event.preventDefault(); + }); + } + + function adjustCharge( defaultLinkDistance ){ + var greaterDistance = Math.max(options.classDistance(), options.datatypeDistance()), + ratio = greaterDistance / defaultLinkDistance, + newCharge = defaultCharge * ratio; + + options.charge(newCharge); + } + + /** + * Resets the gravity sliders to their default. + */ + gravityMenu.reset = function (){ + sliders.forEach(function ( slider ){ + slider.property("value", function ( d ){ + // Simply reload the distance from the options + return d.distanceFunction(); + }); + slider.on("input")(); + }); + }; + + + return gravityMenu; +}; diff --git a/src/app/js/menu/modeMenu.js b/src/app/js/menu/modeMenu.js new file mode 100644 index 0000000000000000000000000000000000000000..84fd30a637f34b44b23caec1e93d43e9dc5a5b79 --- /dev/null +++ b/src/app/js/menu/modeMenu.js @@ -0,0 +1,256 @@ +/** + * Contains the logic for connecting the modes with the website. + * + * @param graph the graph that belongs to these controls + * @returns {{}} + */ +module.exports = function ( graph ){ + + var SAME_COLOR_MODE = { text: "Multicolor", type: "same" }; + var GRADIENT_COLOR_MODE = { text: "Multicolor", type: "gradient" }; + + var modeMenu = {}, + checkboxes = [], + colorModeSwitch; + + var dynamicLabelWidthCheckBox; + // getter and setter for the state of color modes + modeMenu.colorModeState = function ( s ){ + if ( !arguments.length ) return colorModeSwitch.datum().active; + colorModeSwitch.datum().active = s; + return modeMenu; + }; + + + modeMenu.setDynamicLabelWidth = function ( val ){ + dynamicLabelWidthCheckBox.property("checked", val); + }; + // getter for checkboxes + modeMenu.getCheckBoxContainer = function (){ + return checkboxes; + }; + // getter for the color switch [needed? ] + modeMenu.colorModeSwitch = function (){ + return colorModeSwitch; + }; + + /** + * Connects the website with the available graph modes. + */ + modeMenu.setup = function ( pickAndPin, nodeScaling, compactNotation, colorExternals ){ + var menuEntry = d3.select("#m_modes"); + menuEntry.on("mouseover", function (){ + var searchMenu = graph.options().searchMenu(); + searchMenu.hideSearchEntries(); + }); + addCheckBoxD("labelWidth", "Dynamic label width", "#dynamicLabelWidth", graph.options().dynamicLabelWidth, 1); + addCheckBox("editorMode", "Editing ", "#editMode", graph.editorMode); + addModeItem(pickAndPin, "pickandpin", "Pick & pin", "#pickAndPinOption", false); + addModeItem(nodeScaling, "nodescaling", "Node scaling", "#nodeScalingOption", true); + addModeItem(compactNotation, "compactnotation", "Compact notation", "#compactNotationOption", true); + var container = addModeItem(colorExternals, "colorexternals", "Color externals", "#colorExternalsOption", true); + colorModeSwitch = addExternalModeSelection(container, colorExternals); + }; + function addCheckBoxD( identifier, modeName, selector, onChangeFunc, updateLvl ){ + var moduleOptionContainer = d3.select(selector) + .append("div") + .classed("checkboxContainer", true); + + var moduleCheckbox = moduleOptionContainer.append("input") + .classed("moduleCheckbox", true) + .attr("id", identifier + "ModuleCheckbox") + .attr("type", "checkbox") + .property("checked", onChangeFunc()); + + moduleCheckbox.on("click", function ( d ){ + var isEnabled = moduleCheckbox.property("checked"); + onChangeFunc(isEnabled); + d3.select("#maxLabelWidthSlider").node().disabled = !isEnabled; + d3.select("#maxLabelWidthvalueLabel").classed("disabledLabelForSlider", !isEnabled); + d3.select("#maxLabelWidthDescriptionLabel").classed("disabledLabelForSlider", !isEnabled); + + if ( updateLvl > 0 ) { + graph.animateDynamicLabelWidth(); + // graph.lazyRefresh(); + } + }); + moduleOptionContainer.append("label") + .attr("for", identifier + "ModuleCheckbox") + .text(modeName); + if ( identifier === "editorMode" ) { + moduleOptionContainer.append("label") + .attr("style", "font-size:10px;padding-top:3px") + .text("(experimental)"); + } + + dynamicLabelWidthCheckBox = moduleCheckbox; + } + + function addCheckBox( identifier, modeName, selector, onChangeFunc ){ + var moduleOptionContainer = d3.select(selector) + .append("div") + .classed("checkboxContainer", true); + + var moduleCheckbox = moduleOptionContainer.append("input") + .classed("moduleCheckbox", true) + .attr("id", identifier + "ModuleCheckbox") + .attr("type", "checkbox") + .property("checked", onChangeFunc()); + + moduleCheckbox.on("click", function ( d ){ + var isEnabled = moduleCheckbox.property("checked"); + onChangeFunc(isEnabled); + if ( isEnabled === true ) + graph.showEditorHintIfNeeded(); + }); + moduleOptionContainer.append("label") + .attr("for", identifier + "ModuleCheckbox") + .text(modeName); + if ( identifier === "editorMode" ) { + moduleOptionContainer.append("label") + .attr("style", "font-size:10px;padding-top:3px") + .text(" (experimental)"); + } + } + + function addModeItem( module, identifier, modeName, selector, updateGraphOnClick ){ + var moduleOptionContainer, + moduleCheckbox; + + moduleOptionContainer = d3.select(selector) + .append("div") + .classed("checkboxContainer", true) + .datum({ module: module, defaultState: module.enabled() }); + + moduleCheckbox = moduleOptionContainer.append("input") + .classed("moduleCheckbox", true) + .attr("id", identifier + "ModuleCheckbox") + .attr("type", "checkbox") + .property("checked", module.enabled()); + + // Store for easier resetting all modes + checkboxes.push(moduleCheckbox); + + moduleCheckbox.on("click", function ( d, silent ){ + var isEnabled = moduleCheckbox.property("checked"); + d.module.enabled(isEnabled); + if ( updateGraphOnClick && silent !== true ) { + graph.executeColorExternalsModule(); + graph.executeCompactNotationModule(); + graph.lazyRefresh(); + } + }); + + moduleOptionContainer.append("label") + .attr("for", identifier + "ModuleCheckbox") + .text(modeName); + + return moduleOptionContainer; + } + + function addExternalModeSelection( container, colorExternalsMode ){ + var button = container.append("button").datum({ active: false }).classed("color-mode-switch", true); + applyColorModeSwitchState(button, colorExternalsMode); + + button.on("click", function ( silent ){ + var data = button.datum(); + data.active = !data.active; + applyColorModeSwitchState(button, colorExternalsMode); + if ( colorExternalsMode.enabled() && silent !== true ) { + graph.executeColorExternalsModule(); + graph.lazyRefresh(); + } + }); + + return button; + } + + function applyColorModeSwitchState( element, colorExternalsMode ){ + var isActive = element.datum().active; + var activeColorMode = getColorModeByState(isActive); + + element.classed("active", isActive) + .text(activeColorMode.text); + + if ( colorExternalsMode ) { + colorExternalsMode.colorModeType(activeColorMode.type); + } + } + + function getColorModeByState( isActive ){ + return isActive ? GRADIENT_COLOR_MODE : SAME_COLOR_MODE; + } + + /** + * Resets the modes to their default. + */ + modeMenu.reset = function (){ + checkboxes.forEach(function ( checkbox ){ + var defaultState = checkbox.datum().defaultState, + isChecked = checkbox.property("checked"); + + if ( isChecked !== defaultState ) { + checkbox.property("checked", defaultState); + // Call onclick event handlers programmatically + checkbox.on("click")(checkbox.datum()); + } + + // Reset the module that is connected with the checkbox + checkbox.datum().module.reset(); + }); + + // set the switch to active and simulate disabling + colorModeSwitch.datum().active = true; + colorModeSwitch.on("click")(); + }; + + /** importer functions **/ + // setting manually the values of the filter + // no update of the gui settings, these are updated in updateSettings + modeMenu.setCheckBoxValue = function ( id, checked ){ + for ( var i = 0; i < checkboxes.length; i++ ) { + var cbdId = checkboxes[i].attr("id"); + + if ( cbdId === id ) { + checkboxes[i].property("checked", checked); + break; + } + } + }; + modeMenu.getCheckBoxValue = function ( id ){ + for ( var i = 0; i < checkboxes.length; i++ ) { + var cbdId = checkboxes[i].attr("id"); + if ( cbdId === id ) { + return checkboxes[i].property("checked"); + } + } + }; + + modeMenu.setColorSwitchState = function ( state ){ + // need the !state because we simulate later a click + modeMenu.colorModeState(!state); + }; + modeMenu.setColorSwitchStateUsingURL = function ( state ){ + // need the !state because we simulate later a click + modeMenu.colorModeState(!state); + colorModeSwitch.on("click")(true); + }; + + + modeMenu.updateSettingsUsingURL = function (){ + var silent = true; + checkboxes.forEach(function ( checkbox ){ + checkbox.on("click")(checkbox.datum(), silent); + }); + }; + + modeMenu.updateSettings = function (){ + var silent = true; + checkboxes.forEach(function ( checkbox ){ + checkbox.on("click")(checkbox.datum(), silent); + }); + // this simulates onclick and inverts its state + colorModeSwitch.on("click")(silent); + }; + return modeMenu; +}; diff --git a/src/app/js/menu/navigationMenu.js b/src/app/js/menu/navigationMenu.js new file mode 100644 index 0000000000000000000000000000000000000000..60483ad78b92d512f54aa15eac3ef45c90b85b43 --- /dev/null +++ b/src/app/js/menu/navigationMenu.js @@ -0,0 +1,255 @@ +/** + * Contains the navigation "engine" + * + * @param graph the associated webvowl graph + * @returns {{}} + */ +module.exports = function ( graph ){ + var navigationMenu = {}, + scrollContainer = d3.select("#menuElementContainer").node(), + menuContainer = d3.select("#menuContainer").node(), + leftButton = d3.select("#scrollLeftButton"), + rightButton = d3.select("#scrollRightButton"), + scrolLeftValue, + scrollMax, + currentlyVisibleMenu, + currentlyHoveredEntry, + touchedElement = false, + t_scrollLeft, + t_scrollRight, + c_select = [], + m_select = []; + + + function clearAllTimers(){ + cancelAnimationFrame(t_scrollLeft); + cancelAnimationFrame(t_scrollRight); + } + + function timed_scrollRight(){ + scrolLeftValue += 5; + scrollContainer.scrollLeft = scrolLeftValue; + navigationMenu.updateScrollButtonVisibility(); + if ( scrolLeftValue >= scrollMax ) { + clearAllTimers(); + return; + } + t_scrollRight = requestAnimationFrame(timed_scrollRight); + + } + + function timed_scrollLeft(){ + scrolLeftValue -= 5; + scrollContainer.scrollLeft = scrolLeftValue; + navigationMenu.updateScrollButtonVisibility(); + if ( scrolLeftValue <= 0 ) { + clearAllTimers(); + return; + } + t_scrollRight = requestAnimationFrame(timed_scrollLeft); + } + + // collect all menu entries and stuff; + function setupControlsAndMenus(){ + // HEURISTIC : to match the menus and their controllers we remove the first 2 letters and match + c_select = []; + m_select = []; + + var c_temp = []; + var m_temp = []; + var i; + var controlElements = scrollContainer.children; + var numEntries = controlElements.length; + + for ( i = 0; i < numEntries; i++ ) { + c_temp.push(controlElements[i].id.slice(2)); + } + + var menuElements = menuContainer.children; + numEntries = menuElements.length; + for ( i = 0; i < numEntries; i++ ) { + m_temp.push(menuElements[i].id.slice(2)); + } + + numEntries = controlElements.length; + for ( i = 0; i < numEntries; i++ ) { + c_select[i] = "c_" + c_temp[i]; + if ( m_temp.indexOf(c_temp[i]) > -1 ) { + m_select[i] = "m_" + c_temp[i]; + } else { + m_select[i] = undefined; + } + // create custom behavior for click, touch, and hover + d3.select("#" + c_select[i]).on("mouseover", menuElementOnHovered); + d3.select("#" + c_select[i]).on("mouseout", menuElementOutHovered); + + d3.select("#" + c_select[i]).on("click", menuElementClicked); + d3.select("#" + c_select[i]).on("touchstart", menuElementTouched); + + } + + // connect to mouseWheel + d3.select("#menuElementContainer").on("wheel", function (){ + var wheelEvent = d3.event; + var offset; + if ( wheelEvent.deltaY < 0 ) offset = 20; + if ( wheelEvent.deltaY > 0 ) offset = -20; + scrollContainer.scrollLeft += offset; + navigationMenu.hideAllMenus(); + navigationMenu.updateScrollButtonVisibility(); + }); + + // connect scrollIndicator Buttons; + d3.select("#scrollRightButton").on("mousedown", function (){ + scrolLeftValue = scrollContainer.scrollLeft; + navigationMenu.hideAllMenus(); + t_scrollRight = requestAnimationFrame(timed_scrollRight); + + }).on("touchstart", function (){ + scrolLeftValue = scrollContainer.scrollLeft; + navigationMenu.hideAllMenus(); + t_scrollRight = requestAnimationFrame(timed_scrollRight); + }).on("mouseup", clearAllTimers) + .on("touchend", clearAllTimers) + .on("touchcancel", clearAllTimers); + + d3.select("#scrollLeftButton").on("mousedown", function (){ + scrolLeftValue = scrollContainer.scrollLeft; + navigationMenu.hideAllMenus(); + t_scrollLeft = requestAnimationFrame(timed_scrollLeft); + }).on("touchstart", function (){ + scrolLeftValue = scrollContainer.scrollLeft; + navigationMenu.hideAllMenus(); + t_scrollLeft = requestAnimationFrame(timed_scrollLeft); + }).on("mouseup", clearAllTimers) + .on("touchend", clearAllTimers) + .on("touchcancel", clearAllTimers); + + // connect the scroll functionality; + d3.select("#menuElementContainer").on("scroll", function (){ + navigationMenu.updateScrollButtonVisibility(); + navigationMenu.hideAllMenus(); + }); + } + + function menuElementOnHovered(){ + navigationMenu.hideAllMenus(); + if ( touchedElement ) { + return; + } + showSingleMenu(this.id); + } + + function menuElementOutHovered(){ + hoveroutedControMenu(this.id); + } + + function menuElementClicked(){ + var m_element = m_select[c_select.indexOf(this.id)]; + if ( m_element ) { + var menuElement = d3.select("#" + m_element); + if ( menuElement ) { + if ( menuElement.style("display") === "block" ) { + menuElement.style("display", "none");// hide it + } else { + showSingleMenu(this.id); + } + } + } + } + + function menuElementTouched(){ + // it sets a flag that we have touched it, + // since d3. propagates the event for touch as hover and then click, we block the hover event + touchedElement = true; + } + + + function hoveroutedControMenu( controllerID ){ + currentlyHoveredEntry = d3.select("#" + controllerID); + if ( controllerID !== "c_search" ) { + d3.select("#" + controllerID).select("path").style("stroke-width", "0"); + d3.select("#" + controllerID).select("path").style("fill", "#fff"); + } + + } + + function showSingleMenu( controllerID ){ + currentlyHoveredEntry = d3.select("#" + controllerID).node(); + // get the corresponding menu element for this controller + var m_element = m_select[c_select.indexOf(controllerID)]; + if ( m_element ) { + if ( controllerID !== "c_search" ) { + + d3.select("#" + controllerID).select("path").style("stroke-width", "0"); + d3.select("#" + controllerID).select("path").style("fill", "#bdc3c7"); + } + // show it if we have a menu + currentlyVisibleMenu = d3.select("#" + m_element); + currentlyVisibleMenu.style("display", "block"); + if ( m_element === "m_export" ) + graph.options().exportMenu().exportAsUrl(); + updateMenuPosition(); + } + } + + function updateMenuPosition(){ + if ( currentlyHoveredEntry ) { + var leftOffset = currentlyHoveredEntry.offsetLeft; + var scrollOffset = scrollContainer.scrollLeft; + var totalOffset = leftOffset - scrollOffset; + var finalOffset = Math.max(0, totalOffset); + var fullContainer_width = scrollContainer.getBoundingClientRect().width; + var elementWidth = currentlyVisibleMenu.node().getBoundingClientRect().width; + // make priority > first check if we are right + if ( finalOffset + elementWidth > fullContainer_width ) { + finalOffset = fullContainer_width - elementWidth; + } + // fix priority; + finalOffset = Math.max(0, finalOffset); + currentlyVisibleMenu.style("left", finalOffset + "px"); + + // // check if outside the viewport + // var menuWidth=currentlyHoveredEntry.getBoundingClientRect().width; + // var bt_width=36; + // if (totalOffset+menuWidthfullContainer_width){ + // navigationMenu.hideAllMenus(); + // currentlyHoveredEntry=undefined; + // } + } + } + + navigationMenu.hideAllMenus = function (){ + d3.selectAll(".toolTipMenu").style("display", "none"); // hiding all menus + }; + + navigationMenu.updateScrollButtonVisibility = function (){ + scrollMax = scrollContainer.scrollWidth - scrollContainer.clientWidth - 2; + if ( scrollContainer.scrollLeft === 0 ) { + leftButton.classed("hidden", true); + } else { + leftButton.classed("hidden", false); + } + + if ( scrollContainer.scrollLeft > scrollMax ) { + rightButton.classed("hidden", true); + } else { + rightButton.classed("hidden", false); + } + + }; + + navigationMenu.setup = function (){ + setupControlsAndMenus(); + // make sure that the menu elements follow their controller and also their restrictions + // some hovering behavior -- lets the menu disappear when hovered in graph or sidebar; + d3.select("#graph").on("mouseover", function (){ + navigationMenu.hideAllMenus(); + }); + d3.select("#generalDetails").on("mouseover", function (){ + navigationMenu.hideAllMenus(); + }); + }; + + return navigationMenu; +}; diff --git a/src/app/js/menu/ontologyMenu.js b/src/app/js/menu/ontologyMenu.js new file mode 100644 index 0000000000000000000000000000000000000000..e1c30bb6432c67871cdc30a4f5f390d2bce93d54 --- /dev/null +++ b/src/app/js/menu/ontologyMenu.js @@ -0,0 +1,666 @@ +var unescape = require("lodash/unescape"); + +module.exports = function ( graph ){ + + var ontologyMenu = {}, + loadingInfo = d3.select("#loading-info"), + loadingProgress = d3.select("#loading-progress"), + + ontologyMenuTimeout, + fileToLoad, + stopTimer = false, + loadingError = false, + loadingStatusTimer, + conversion_sessionId, + cachedConversions = {}, + loadingModule, + loadOntologyFromText; + var currentLoadedOntologyName = ""; + + String.prototype.beginsWith = function ( string ){ + return (this.indexOf(string) === 0); + }; + + ontologyMenu.getLoadingFunction = function (){ + return loadOntologyFromText; + }; + + ontologyMenu.clearCachedVersion = function (){ + if ( cachedConversions[currentLoadedOntologyName] ) { + cachedConversions[currentLoadedOntologyName] = undefined; + } + }; + + + ontologyMenu.reloadCachedOntology = function (){ + ontologyMenu.clearCachedVersion(); + graph.clearGraphData(); + loadingModule.parseUrlAndLoadOntology(false); + }; + + ontologyMenu.cachedOntology = function ( ontoName ){ + currentLoadedOntologyName = ontoName; + if ( cachedConversions[ontoName] ) { + var locStr = String(location.hash); + d3.select("#reloadSvgIcon").node().disabled = false; + graph.showReloadButtonAfterLayoutOptimization(true); + if ( locStr.indexOf("#file") > -1 ) { + d3.select("#reloadSvgIcon").node().disabled = true; + d3.select("#reloadCachedOntology").node().title = "reloading original version not possible, please reload the file"; + d3.select("#reloadSvgIcon").classed("disabledReloadElement", true); + d3.select("#svgStringText").style("fill", "gray"); + d3.select("#svgStringText").classed("noselect", true); + } + else { + d3.select("#reloadCachedOntology").node().title = "generate new visualization and overwrite cached ontology"; + d3.select("#reloadSvgIcon").classed("disabledReloadElement", false); + d3.select("#svgStringText").style("fill", "black"); + d3.select("#svgStringText").classed("noselect", true); + } + } else { + graph.showReloadButtonAfterLayoutOptimization(false); + + } + return cachedConversions[ontoName]; + }; + ontologyMenu.setCachedOntology = function ( ontoName, ontoContent ){ + cachedConversions[ontoName] = ontoContent; + currentLoadedOntologyName = ontoName; + }; + + ontologyMenu.getErrorStatus = function (){ + return loadingError; + }; + + ontologyMenu.setup = function ( _loadOntologyFromText ){ + loadOntologyFromText = _loadOntologyFromText; + loadingModule = graph.options().loadingModule(); + var menuEntry = d3.select("#m_select"); + menuEntry.on("mouseover", function (){ + var searchMenu = graph.options().searchMenu(); + searchMenu.hideSearchEntries(); + }); + + setupConverterButtons(); + setupUploadButton(); + + var descriptionButton = d3.select("#error-description-button").datum({ open: false }); + descriptionButton.on("click", function ( data ){ + var errorContainer = d3.select("#error-description-container"); + var errorDetailsButton = d3.select(this); + + // toggle the state + data.open = !data.open; + var descriptionVisible = data.open; + if ( descriptionVisible ) { + errorDetailsButton.text("Hide error details"); + } else { + errorDetailsButton.text("Show error details"); + } + errorContainer.classed("hidden", !descriptionVisible); + }); + + setupUriListener(); + loadingModule.setOntologyMenu(ontologyMenu); + }; + + + function setupUriListener(){ + // reload ontology when hash parameter gets changed manually + d3.select(window).on("hashchange", function (){ + var oldURL = d3.event.oldURL, newURL = d3.event.newURL; + if ( oldURL !== newURL ) { + // don't reload when just the hash parameter gets appended + if ( newURL === oldURL + "#" ) { + return; + } + updateNavigationHrefs(); + loadingModule.parseUrlAndLoadOntology(); + } + }); + updateNavigationHrefs(); + } + + ontologyMenu.stopLoadingTimer = function (){ + stopTimer = true; + clearTimeout(loadingStatusTimer); + }; + + /** + * Quick fix: update all anchor tags that are used as buttons because a click on them + * changes the url and this will load an other ontology. + */ + function updateNavigationHrefs(){ + d3.selectAll("#menuElementContainer > li > a").attr("href", location.hash || "#"); + } + + ontologyMenu.setIriText = function ( text ){ + d3.select("#iri-converter-input").node().value = text; + d3.select("#iri-converter-button").attr("disabled", false); + d3.select("#iri-converter-form").on("submit")(); + }; + + ontologyMenu.clearDetailInformation = function (){ + var bpContainer = d3.select("#bulletPoint_container"); + var htmlCollection = bpContainer.node().children; + var numEntries = htmlCollection.length; + + for ( var i = 0; i < numEntries; i++ ) { + htmlCollection[0].remove(); + } + }; + ontologyMenu.append_message = function ( msg ){ + // forward call + append_message(msg); + }; + function append_message( msg ){ + var bpContainer = d3.select("#bulletPoint_container"); + var div = bpContainer.append("div"); + div.node().innerHTML = msg; + loadingModule.scrollDownDetails(); + } + + ontologyMenu.append_message_toLastBulletPoint = function ( msg ){ + // forward call + append_message_toLastBulletPoint(msg); + }; + + ontologyMenu.append_bulletPoint = function ( msg ){ + // forward call + append_bulletPoint(msg); + }; + function append_message_toLastBulletPoint( msg ){ + var bpContainer = d3.select("#bulletPoint_container"); + var htmlCollection = bpContainer.node().getElementsByTagName("LI"); + var lastItem = htmlCollection.length - 1; + if ( lastItem >= 0 ) { + var oldText = htmlCollection[lastItem].innerHTML; + htmlCollection[lastItem].innerHTML = oldText + msg; + } + loadingModule.scrollDownDetails(); + } + + function append_bulletPoint( msg ){ + var bp_container = d3.select("#bulletPoint_container"); + var bp = bp_container.append("li"); + bp.node().innerHTML = msg; + d3.select("#currentLoadingStep").node().innerHTML = msg; + loadingModule.scrollDownDetails(); + } + + + function setupConverterButtons(){ + var iriConverterButton = d3.select("#iri-converter-button"); + var iriConverterInput = d3.select("#iri-converter-input"); + + iriConverterInput.on("input", function (){ + keepOntologySelectionOpenShortly(); + + var inputIsEmpty = iriConverterInput.property("value") === ""; + iriConverterButton.attr("disabled", inputIsEmpty || undefined); + }).on("click", function (){ + keepOntologySelectionOpenShortly(); + }); + + d3.select("#iri-converter-form").on("submit", function (){ + var inputName = iriConverterInput.property("value"); + + // remove first spaces + var clearedName = inputName.replace(/%20/g, " "); + while ( clearedName.beginsWith(" ") ) { + clearedName = clearedName.substr(1, clearedName.length); + } + // remove ending spaces + while ( clearedName.endsWith(" ") ) { + clearedName = clearedName.substr(0, clearedName.length - 1); + } + // check if iri is actually an url for a json file (ends with .json) + // create lowercase filenames; + inputName = clearedName; + var lc_iri = inputName.toLowerCase(); + if ( lc_iri.endsWith(".json") ) { + location.hash = "url=" + inputName; + iriConverterInput.property("value", ""); + iriConverterInput.on("input")(); + } else { + location.hash = "iri=" + inputName; + iriConverterInput.property("value", ""); + iriConverterInput.on("input")(); + } + d3.event.preventDefault(); + return false; + }); + } + + function setupUploadButton(){ + var input = d3.select("#file-converter-input"), + inputLabel = d3.select("#file-converter-label"), + uploadButton = d3.select("#file-converter-button"); + + input.on("change", function (){ + var selectedFiles = input.property("files"); + if ( selectedFiles.length <= 0 ) { + inputLabel.text("Select ontology file"); + uploadButton.property("disabled", true); + } else { + inputLabel.text(selectedFiles[0].name); + fileToLoad = selectedFiles[0].name; + uploadButton.property("disabled", false); + uploadButton.node().click(); + // close menu; + graph.options().navigationMenu().hideAllMenus(); + } + }); + + uploadButton.on("click", function (){ + var selectedFile = input.property("files")[0]; + if ( !selectedFile ) { + return false; + } + var newHashParameter = "file=" + selectedFile.name; + // Trigger the reupload manually, because the iri is not changing + if ( location.hash === "#" + newHashParameter ) { + loadingModule.parseUrlAndLoadOntology(); + } else { + location.hash = newHashParameter; + } + }); + } + + function setLoadingStatusInfo( message ){ + // check if there is a owl2vowl li item; + var o2vConverterContainer = d3.select("#o2vConverterContainer"); + if ( !o2vConverterContainer.node() ) { + var bp_container = d3.select("#bulletPoint_container"); + var div = bp_container.append("div"); + o2vConverterContainer = div.append("ul"); + o2vConverterContainer.attr("id", "o2vConverterContainer"); + o2vConverterContainer.style("margin-left", "-25px"); + } + // clear o2vConverterContainer; + var htmlCollection = o2vConverterContainer.node().children; + var numEntries = htmlCollection.length; + for ( var i = 0; i < numEntries; i++ ) { + htmlCollection[0].remove(); + } + // split tokens provided by o2v messages + var tokens = message.split("* "); + var liForToken; + for ( var t = 0; t < tokens.length; t++ ) { + var tokenMessage = tokens[t]; + // create li for tokens; + if ( tokenMessage.length > 0 ) { + liForToken = o2vConverterContainer.append("li"); + liForToken.attr("type", "disc"); + liForToken.node().innerHTML = tokenMessage.replace(/\n/g, "
"); + } + } + if ( liForToken ) + liForToken.node().innerHTML += "
"; + + loadingModule.scrollDownDetails(); + } + + ontologyMenu.setLoadingStatusInfo = function ( message ){ + // forward call + setLoadingStatusInfo(message); + }; + + function getLoadingStatusOnceCallBacked( callback, parameter ){ + d3.xhr("loadingStatus?sessionId=" + conversion_sessionId, "application/text", function ( error, request ){ + if ( error ) { + console.log("ontologyMenu getLoadingStatusOnceCallBacked throws error"); + console.log("---------Error -----------"); + console.log(error); + console.log("---------Request -----------"); + console.log(request); + } + setLoadingStatusInfo(request.responseText); + callback(parameter); + }); + } + + function getLoadingStatusTimeLooped(){ + d3.xhr("loadingStatus?sessionId=" + conversion_sessionId, "application/text", function ( error, request ){ + if ( error ) { + console.log("ontologyMenu getLoadingStatusTimeLooped throws error"); + console.log("---------Error -----------"); + console.log(error); + console.log("---------Request -----------"); + console.log(request); + } + if ( stopTimer === false ) { + setLoadingStatusInfo(request.responseText); + timedLoadingStatusLogger(); + } + }); + } + + function timedLoadingStatusLogger(){ + clearTimeout(loadingStatusTimer); + if ( stopTimer === false ) { + loadingStatusTimer = setTimeout(function (){ + getLoadingStatusTimeLooped(); + }, 1000); + } + } + + function callbackUpdateLoadingMessage( msg ){ + d3.xhr("loadingStatus", "application/text", function ( error, request ){ + if ( request !== undefined ) { + setLoadingStatusInfo(request.responseText + "
" + msg); + } else { + append_message(msg); + } + }); + } + + ontologyMenu.setConversionID = function ( id ){ + conversion_sessionId = id; + }; + + ontologyMenu.callbackLoad_Ontology_FromIRI = function ( parameter ){ + var relativePath = parameter[0]; + var ontoName = parameter[1]; + var localThreadId = parameter[2]; + stopTimer = false; + timedLoadingStatusLogger(); + d3.xhr(relativePath, "application/json", function ( error, request ){ + var loadingSuccessful = !error; + // check if error occurred or responseText is empty + if ( (error !== null && error.status === 500) || (request && request.responseText.length === 0) ) { + clearTimeout(loadingStatusTimer); + stopTimer = true; + getLoadingStatusOnceCallBacked(callbackFromIRI_URL_ERROR, [error, request, localThreadId]); + } + var jsonText; + if ( loadingSuccessful ) { + clearTimeout(loadingStatusTimer); + stopTimer = true; + jsonText = request.responseText; + getLoadingStatusOnceCallBacked(callbackFromIRI_Success, [jsonText, ontoName, localThreadId]); + } + }); + }; + + + ontologyMenu.callbackLoad_Ontology_From_DirectInput = function ( text, parameter ){ + var input = text; + var sessionId = parameter[1]; + stopTimer = false; + timedLoadingStatusLogger(); + + var formData = new FormData(); + formData.append("input", input); + formData.append("sessionId", sessionId); + var xhr = new XMLHttpRequest(); + + xhr.open("POST", "directInput", true); + xhr.onload = function (){ + clearTimeout(loadingStatusTimer); + stopTimer = true; + getLoadingStatusOnceCallBacked(callbackForConvert, [xhr, input, sessionId]); + }; + timedLoadingStatusLogger(); + xhr.send(formData); + + }; + function callbackFromIRI_Success( parameter ){ + var local_conversionId = parameter[2]; + if ( local_conversionId !== conversion_sessionId ) { + console.log("The conversion process for file:" + parameter[1] + " has been canceled!"); + ontologyMenu.conversionFinished(local_conversionId); + return; + } + loadingModule.loadFromOWL2VOWL(parameter[0], parameter[1]); + ontologyMenu.conversionFinished(); + + } + + function callbackFromDirectInput_Success( parameter ){ + var local_conversionId = parameter[1]; + if ( local_conversionId !== conversion_sessionId ) { + console.log("The conversion process for file:" + parameter[1] + " has been canceled!"); + ontologyMenu.conversionFinished(local_conversionId); + return; + } + loadingModule.loadFromOWL2VOWL(parameter[0], "DirectInputConversionID" + local_conversionId); + ontologyMenu.conversionFinished(); + + } + + ontologyMenu.getConversionId = function (){ + return conversion_sessionId; + }; + + ontologyMenu.callbackLoad_JSON_FromURL = function ( parameter ){ + var relativePath = parameter[0]; + var ontoName = parameter[1]; + var local_conversionId = parameter[2]; + stopTimer = false; + timedLoadingStatusLogger(); + d3.xhr(relativePath, "application/json", function ( error, request ){ + var loadingSuccessful = !error; + // check if error occurred or responseText is empty + if ( (error !== null && error.status === 500) || (request && request.responseText.length === 0) ) { + clearTimeout(loadingStatusTimer); + stopTimer = true; + loadingSuccessful = false; + console.log(request); + console.log(request.responseText.length); + getLoadingStatusOnceCallBacked(callbackFromJSON_URL_ERROR, [error, request, local_conversionId]); + } + if ( loadingSuccessful ) { + clearTimeout(loadingStatusTimer); + stopTimer = true; + var jsonText = request.responseText; + getLoadingStatusOnceCallBacked(callbackFromJSON_Success, [jsonText, ontoName, local_conversionId]); + } + }); + }; + + function callbackFromJSON_Success( parameter ){ + var local_conversionId = parameter[2]; + if ( local_conversionId !== conversion_sessionId ) { + console.log("The conversion process for file:" + parameter[1] + " has been canceled!"); + return; + } + loadingModule.loadFromOWL2VOWL(parameter[0], parameter[1]); + } + + function callbackFromJSON_URL_ERROR( parameter ){ + var error = parameter[0]; + var request = parameter[1]; + var local_conversionId = parameter[2]; + if ( local_conversionId !== conversion_sessionId ) { + console.log("This thread has been canceled!!"); + ontologyMenu.conversionFinished(local_conversionId); + return; + } + callbackUpdateLoadingMessage("
Failed to convert the file. " + + " Ontology could not be loaded.
Is it a valid OWL ontology? Please check with OWL Validator"); + + if ( error !== null && error.status === 500 ) { + append_message("Could not find ontology at the URL"); + } + if ( request && request.responseText.length === 0 ) { + append_message("Received empty graph"); + } + graph.handleOnLoadingError(); + ontologyMenu.conversionFinished(); + } + + + function callbackFromIRI_URL_ERROR( parameter ){ + var error = parameter[0]; + var request = parameter[1]; + var local_conversionId = parameter[2]; + if ( local_conversionId !== conversion_sessionId ) { + console.log("This thread has been canceled!!"); + ontologyMenu.conversionFinished(local_conversionId); + return; + } + callbackUpdateLoadingMessage("
Failed to convert the file. " + + " Ontology could not be loaded.
Is it a valid OWL ontology? Please check with OWL Validator"); + + if ( error !== null && error.status === 500 ) { + append_message("Could not find ontology at the URL"); + } + if ( request && request.responseText.length === 0 ) { + append_message("Received empty graph"); + } + graph.handleOnLoadingError(); + ontologyMenu.conversionFinished(); + } + + function callbackFromDirectInput_ERROR( parameter ){ + + var error = parameter[0]; + var request = parameter[1]; + var local_conversionId = parameter[2]; + if ( local_conversionId !== conversion_sessionId ) { + console.log("The loading process for direct input has been canceled!"); + return; + } + // callbackUpdateLoadingMessage("
Failed to convert the file. "+ + // "Ontology could not be loaded.
Is it a valid OWL ontology? Please check with OWL Validator"); + if ( error !== null && error.status === 500 ) { + append_message("Could not convert direct input"); + } + if ( request && request.responseText.length === 0 ) { + append_message("Received empty graph"); + } + + graph.handleOnLoadingError(); + ontologyMenu.conversionFinished(); + } + + ontologyMenu.callbackLoadFromOntology = function ( selectedFile, filename, local_threadId ){ + callbackLoadFromOntology(selectedFile, filename, local_threadId); + }; + + function callbackLoadFromOntology( selectedFile, filename, local_threadId ){ + stopTimer = false; + timedLoadingStatusLogger(); + + var formData = new FormData(); + formData.append("ontology", selectedFile); + formData.append("sessionId", local_threadId); + var xhr = new XMLHttpRequest(); + + xhr.open("POST", "convert", true); + xhr.onload = function (){ + clearTimeout(loadingStatusTimer); + stopTimer = true; + console.log(xhr); + getLoadingStatusOnceCallBacked(callbackForConvert, [xhr, filename, local_threadId]); + }; + timedLoadingStatusLogger(); + xhr.send(formData); + } + + function callbackForConvert( parameter ){ + var xhr = parameter[0]; + var filename = parameter[1]; + var local_threadId = parameter[2]; + if ( local_threadId !== conversion_sessionId ) { + console.log("The conversion process for file:" + filename + " has been canceled!"); + ontologyMenu.conversionFinished(local_threadId); + return; + } + if ( xhr.status === 200 ) { + loadingModule.loadFromOWL2VOWL(xhr.responseText, filename); + ontologyMenu.conversionFinished(); + } else { + var uglyJson=xhr.responseText; + var jsonResut=JSON.parse(uglyJson); + var niceJSON=JSON.stringify(jsonResut, 'null', ' '); + niceJSON= niceJSON.replace(new RegExp('\r?\n','g'), '
'); + callbackUpdateLoadingMessage("Failed to convert the file. " + + "
Server answer:
"+ + "
"+niceJSON+ "
"+ + "Ontology could not be loaded.
Is it a valid OWL ontology? Please check with OWL Validator"); + + graph.handleOnLoadingError(); + ontologyMenu.conversionFinished(); + } + } + + ontologyMenu.conversionFinished = function ( id ){ + var local_id = conversion_sessionId; + if ( id ) { + local_id = id; + } + d3.xhr("conversionDone?sessionId=" + local_id, "application/text", function ( error, request ){ + if ( error ) { + console.log("ontologyMenu conversionFinished throws error"); + console.log("---------Error -----------"); + console.log(error); + console.log("---------Request -----------"); + console.log(request); + } + }); + }; + + function keepOntologySelectionOpenShortly(){ + // Events in the menu should not be considered + var ontologySelection = d3.select("#select .toolTipMenu"); + ontologySelection.on("click", function (){ + d3.event.stopPropagation(); + }).on("keydown", function (){ + d3.event.stopPropagation(); + }); + + ontologySelection.style("display", "block"); + + function disableKeepingOpen(){ + ontologySelection.style("display", undefined); + + clearTimeout(ontologyMenuTimeout); + d3.select(window).on("click", undefined).on("keydown", undefined); + ontologySelection.on("mouseover", undefined); + } + + // Clear the timeout to handle fast calls of this function + clearTimeout(ontologyMenuTimeout); + ontologyMenuTimeout = setTimeout(function (){ + disableKeepingOpen(); + }, 3000); + + // Disable forced open selection on interaction + d3.select(window).on("click", function (){ + disableKeepingOpen(); + }).on("keydown", function (){ + disableKeepingOpen(); + }); + + ontologySelection.on("mouseover", function (){ + disableKeepingOpen(); + }); + } + + ontologyMenu.showLoadingStatus = function ( visible ){ + if ( visible === true ) { + displayLoadingIndicators(); + } + else { + hideLoadingInformations(); + } + }; + + function displayLoadingIndicators(){ + d3.select("#layoutLoadingProgressBarContainer").classed("hidden", false); + loadingInfo.classed("hidden", false); + loadingProgress.classed("hidden", false); + } + + function hideLoadingInformations(){ + loadingInfo.classed("hidden", true); + } + + return ontologyMenu; +}; diff --git a/src/app/js/menu/pauseMenu.js b/src/app/js/menu/pauseMenu.js new file mode 100644 index 0000000000000000000000000000000000000000..38c42813d49919844788e5076e88ebe2f82da472 --- /dev/null +++ b/src/app/js/menu/pauseMenu.js @@ -0,0 +1,67 @@ +/** + * Contains the logic for the pause and resume button. + * + * @param graph the associated webvowl graph + * @returns {{}} + */ +module.exports = function ( graph ){ + + var pauseMenu = {}, + pauseButton; + + + /** + * Adds the pause button to the website. + */ + pauseMenu.setup = function (){ + var menuEntry = d3.select("#pauseOption"); + menuEntry.on("mouseover", function (){ + var searchMenu = graph.options().searchMenu(); + searchMenu.hideSearchEntries(); + }); + pauseButton = d3.select("#pause-button") + .datum({ paused: false }) + .on("click", function ( d ){ + graph.paused(!d.paused); + d.paused = !d.paused; + updatePauseButton(); + pauseButton.classed("highlighted", d.paused); + }); + // Set these properties the first time manually + updatePauseButton(); + }; + + pauseMenu.setPauseValue = function ( value ){ + pauseButton.datum().paused = value; + graph.paused(value); + pauseButton.classed("highlighted", value); + updatePauseButton(); + }; + + function updatePauseButton(){ + updatePauseButtonClass(); + updatePauseButtonText(); + } + + function updatePauseButtonClass(){ + pauseButton.classed("paused", function ( d ){ + return d.paused; + }); + } + + function updatePauseButtonText(){ + if ( pauseButton.datum().paused ) { + pauseButton.text("Resume"); + } else { + pauseButton.text("Pause"); + } + } + + pauseMenu.reset = function (){ + // resuming + pauseMenu.setPauseValue(false); + }; + + + return pauseMenu; +}; diff --git a/src/app/js/menu/resetMenu.js b/src/app/js/menu/resetMenu.js new file mode 100644 index 0000000000000000000000000000000000000000..0ce98a24e1a60dc4a7b1f10e409fd3eee7d9c77c --- /dev/null +++ b/src/app/js/menu/resetMenu.js @@ -0,0 +1,48 @@ +/** + * Contains the logic for the reset button. + * + * @param graph the associated webvowl graph + * @returns {{}} + */ +module.exports = function ( graph ){ + + var resetMenu = {}, + options = graph.graphOptions(), + resettableModules, + untouchedOptions = webvowl.options(); + + + /** + * Adds the reset button to the website. + * @param _resettableModules modules that can be resetted + */ + resetMenu.setup = function ( _resettableModules ){ + resettableModules = _resettableModules; + d3.select("#reset-button").on("click", resetGraph); + var menuEntry = d3.select("#resetOption"); + menuEntry.on("mouseover", function (){ + var searchMenu = graph.options().searchMenu(); + searchMenu.hideSearchEntries(); + }); + }; + + function resetGraph(){ + graph.resetSearchHighlight(); + graph.options().searchMenu().clearText(); + options.classDistance(untouchedOptions.classDistance()); + options.datatypeDistance(untouchedOptions.datatypeDistance()); + options.charge(untouchedOptions.charge()); + options.gravity(untouchedOptions.gravity()); + options.linkStrength(untouchedOptions.linkStrength()); + graph.reset(); + + resettableModules.forEach(function ( module ){ + module.reset(); + }); + + graph.updateStyle(); + } + + + return resetMenu; +}; diff --git a/src/app/js/menu/searchMenu.js b/src/app/js/menu/searchMenu.js new file mode 100644 index 0000000000000000000000000000000000000000..31c198161e1a8e8c0eb48c25fb8a6b93a37f5bfd --- /dev/null +++ b/src/app/js/menu/searchMenu.js @@ -0,0 +1,514 @@ +/** + * Contains the search "engine" + * + * @param graph the associated webvowl graph + * @returns {{}} + */ +module.exports = function ( graph ){ + var searchMenu = {}, + dictionary = [], + entryNames = [], + searchLineEdit, + mergedStringsList, + mergedIdList, + maxEntries = 6, + dictionaryUpdateRequired = true, + labelDictionary, + inputText, + viewStatusOfSearchEntries = false; + + var results = []; + var resultID = []; + var c_locate = d3.select("#locateSearchResult"); + var c_search = d3.select("#c_search"); + var m_search = d3.select("#m_search"); // << dropdown container; + + + String.prototype.beginsWith = function ( string ){ + return (this.indexOf(string) === 0); + }; + + searchMenu.requestDictionaryUpdate = function (){ + dictionaryUpdateRequired = true; + // clear possible pre searched entries + var htmlCollection = m_search.node().children; + var numEntries = htmlCollection.length; + + for ( var i = 0; i < numEntries; i++ ) + htmlCollection[0].remove(); + searchLineEdit.node().value = ""; + }; + + + function updateSearchDictionary(){ + labelDictionary = graph.getUpdateDictionary(); + dictionaryUpdateRequired = false; + dictionary = []; + entryNames = []; + var idList = []; + var stringList = []; + + var i; + for ( i = 0; i < labelDictionary.length; i++ ) { + var lEntry = labelDictionary[i].labelForCurrentLanguage(); + idList.push(labelDictionary[i].id()); + stringList.push(lEntry); + // add all equivalents to the search space; + if ( labelDictionary[i].equivalents && labelDictionary[i].equivalents().length > 0 ) { + var eqs = labelDictionary[i].equivalentsString(); + var eqsLabels = eqs.split(", "); + for ( var e = 0; e < eqsLabels.length; e++ ) { + idList.push(labelDictionary[i].id()); + stringList.push(eqsLabels[e]); + } + } + } + + mergedStringsList = []; + mergedIdList = []; + var indexInStringList = -1; + var currentString; + var currentObjectId; + + for ( i = 0; i < stringList.length; i++ ) { + if ( i === 0 ) { + // just add the elements + mergedStringsList.push(stringList[i]); + mergedIdList.push([]); + mergedIdList[0].push(idList[i]); + continue; + } + else { + currentString = stringList[i]; + currentObjectId = idList[i]; + indexInStringList = mergedStringsList.indexOf(currentString); + } + if ( indexInStringList === -1 ) { + mergedStringsList.push(stringList[i]); + mergedIdList.push([]); + var lastEntry = mergedIdList.length; + mergedIdList[lastEntry - 1].push(currentObjectId); + } else { + mergedIdList[indexInStringList].push(currentObjectId); + } + } + + for ( i = 0; i < mergedStringsList.length; i++ ) { + var aString = mergedStringsList[i]; + var correspondingIdList = mergedIdList[i]; + var idListResult = "[ "; + for ( var j = 0; j < correspondingIdList.length; j++ ) { + idListResult = idListResult + correspondingIdList[j].toString(); + idListResult = idListResult + ", "; + } + idListResult = idListResult.substring(0, idListResult.length - 2); + idListResult = idListResult + " ]"; + + dictionary.push(aString); + entryNames.push(aString); + } + } + + searchMenu.setup = function (){ + // clear dictionary; + dictionary = []; + searchLineEdit = d3.select("#search-input-text"); + searchLineEdit.on("input", userInput); + searchLineEdit.on("keydown", userNavigation); + searchLineEdit.on("click", toggleSearchEntryView); + searchLineEdit.on("mouseover", hoverSearchEntryView); + + c_locate.on("click", function (){ + graph.locateSearchResult(); + }); + + c_locate.on("mouseover", function (){ + searchMenu.hideSearchEntries(); + }); + + }; + + function hoverSearchEntryView(){ + updateSelectionStatusFlags(); + searchMenu.showSearchEntries(); + } + + function toggleSearchEntryView(){ + if ( viewStatusOfSearchEntries ) { + searchMenu.hideSearchEntries(); + } else { + searchMenu.showSearchEntries(); + } + } + + searchMenu.hideSearchEntries = function (){ + m_search.style("display", "none"); + viewStatusOfSearchEntries = false; + }; + + searchMenu.showSearchEntries = function (){ + m_search.style("display", "block"); + viewStatusOfSearchEntries = true; + }; + + function ValidURL( str ){ + var urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/; + return urlregex.test(str); + + } + + + function updateSelectionStatusFlags(){ + if ( searchLineEdit.node().value.length === 0 ) { + createSearchEntries(); + return; + } + handleAutoCompletion(); + } + + function userNavigation(){ + if ( dictionaryUpdateRequired ) { + updateSearchDictionary(); + } + + var htmlCollection = m_search.node().children; + var numEntries = htmlCollection.length; + + + var move = 0; + var i; + var selectedEntry = -1; + for ( i = 0; i < numEntries; i++ ) { + var atr = htmlCollection[i].getAttribute('class'); + if ( atr === "dbEntrySelected" ) { + selectedEntry = i; + } + } + if ( d3.event.keyCode === 13 ) { + if ( selectedEntry >= 0 && selectedEntry < numEntries ) { + // simulate onClick event + htmlCollection[selectedEntry].onclick(); + searchMenu.hideSearchEntries(); + } + else if ( numEntries === 0 ) { + inputText = searchLineEdit.node().value; + // check if input text ends or begins with with space + // remove first spaces + var clearedText = inputText.replace(/%20/g, " "); + while ( clearedText.beginsWith(" ") ) { + clearedText = clearedText.substr(1, clearedText.length); + } + // remove ending spaces + while ( clearedText.endsWith(" ") ) { + clearedText = clearedText.substr(0, clearedText.length - 1); + } + var iri = clearedText.replace(/ /g, "%20"); + + var valid = ValidURL(iri); + // validate url: + if ( valid ) { + var ontM = graph.options().ontologyMenu(); + ontM.setIriText(iri); + searchLineEdit.node().value = ""; + } + else { + console.log(iri + " is not a valid URL!"); + } + } + } + if ( d3.event.keyCode === 38 ) { + move = -1; + searchMenu.showSearchEntries(); + } + if ( d3.event.keyCode === 40 ) { + move = +1; + searchMenu.showSearchEntries(); + } + + var newSelection = selectedEntry + move; + if ( newSelection !== selectedEntry ) { + + if ( newSelection < 0 && selectedEntry <= 0 ) { + htmlCollection[0].setAttribute('class', "dbEntrySelected"); + } + + if ( newSelection >= numEntries ) { + htmlCollection[selectedEntry].setAttribute('class', "dbEntrySelected"); + } + if ( newSelection >= 0 && newSelection < numEntries ) { + htmlCollection[newSelection].setAttribute('class', "dbEntrySelected"); + if ( selectedEntry >= 0 ) + htmlCollection[selectedEntry].setAttribute('class', "dbEntry"); + } + } + } + + searchMenu.getSearchString = function (){ + return searchLineEdit.node().value; + }; + + + function clearSearchEntries(){ + var htmlCollection = m_search.node().children; + var numEntries = htmlCollection.length; + for ( var i = 0; i < numEntries; i++ ) { + htmlCollection[0].remove(); + } + results = []; + resultID = []; + + } + + function createSearchEntries(){ + inputText = searchLineEdit.node().value; + var i; + var lc_text = inputText.toLowerCase(); + var token; + + for ( i = 0; i < dictionary.length; i++ ) { + var tokenElement = dictionary[i]; + if ( tokenElement === undefined ) { + //@WORKAROUND : nodes with undefined labels are skipped + //@FIX: these nodes are now not added to the dictionary + continue; + } + token = dictionary[i].toLowerCase(); + if ( token.indexOf(lc_text) > -1 ) { + results.push(dictionary[i]); + resultID.push(i); + } + } + } + + function measureTextWidth( text, textStyle ){ + // Set a default value + if ( !textStyle ) { + textStyle = "text"; + } + var d = d3.select("body") + .append("div") + .attr("class", textStyle) + .attr("id", "width-test") // tag this element to identify it + .attr("style", "position:absolute; float:left; white-space:nowrap; visibility:hidden;") + .text(text), + w = document.getElementById("width-test").offsetWidth; + d.remove(); + return w; + } + + function cropText( input ){ + var maxWidth = 250; + var textStyle = "dbEntry"; + var truncatedText = input; + var textWidth; + var ratio; + var newTruncatedTextLength; + while ( true ) { + textWidth = measureTextWidth(truncatedText, textStyle); + if ( textWidth <= maxWidth ) { + break; + } + + ratio = textWidth / maxWidth; + newTruncatedTextLength = Math.floor(truncatedText.length / ratio); + + // detect if nothing changes + if ( truncatedText.length === newTruncatedTextLength ) { + break; + } + + truncatedText = truncatedText.substring(0, newTruncatedTextLength); + } + + if ( input.length > truncatedText.length ) { + return input.substring(0, truncatedText.length - 6); + } + return input; + } + + function createDropDownElements(){ + var numEntries; + var copyRes = results; + var i; + var token; + var newResults = []; + var newResultsIds = []; + + var lc_text = searchLineEdit.node().value.toLowerCase(); + // set the number of shown results to be maxEntries or less; + numEntries = results.length; + if ( numEntries > maxEntries ) + numEntries = maxEntries; + + + for ( i = 0; i < numEntries; i++ ) { + // search for the best entry + var indexElement = 1000000; + var lengthElement = 1000000; + var bestElement = -1; + for ( var j = 0; j < copyRes.length; j++ ) { + token = copyRes[j].toLowerCase(); + var tIe = token.indexOf(lc_text); + var tLe = token.length; + if ( tIe > -1 && tIe <= indexElement && tLe <= lengthElement ) { + bestElement = j; + indexElement = tIe; + lengthElement = tLe; + } + } + newResults.push(copyRes[bestElement]); + newResultsIds.push(resultID[bestElement]); + copyRes[bestElement] = ""; + } + + // add the results to the entry menu + //****************************************** + numEntries = results.length; + if ( numEntries > maxEntries ) + numEntries = maxEntries; + + var filteredOutElements = 0; + for ( i = 0; i < numEntries; i++ ) { + //add results to the dropdown menu + var testEntry = document.createElement('li'); + testEntry.setAttribute('elementID', newResultsIds[i]); + testEntry.onclick = handleClick(newResultsIds[i]); + testEntry.setAttribute('class', "dbEntry"); + + var entries = mergedIdList[newResultsIds[i]]; + var eLen = entries.length; + + var croppedText = cropText(newResults[i]); + + var el0 = entries[0]; + var allSame = true; + var nodeMap = graph.getNodeMapForSearch(); + var visible = eLen; + if ( eLen > 1 ) { + for ( var q = 0; q < eLen; q++ ) { + if ( nodeMap[entries[q]] === undefined ) { + visible--; + } + } + } + + for ( var a = 0; a < eLen; a++ ) { + if ( el0 !== entries[a] ) { + allSame = false; + } + } + if ( croppedText !== newResults[i] ) { + // append ...(#numElements) if needed + if ( eLen > 1 && allSame === false ) { + if ( eLen !== visible ) + croppedText += "... (" + visible + "/" + eLen + ")"; + } + else { + croppedText += "..."; + } + testEntry.title = newResults[i]; + } + else { + if ( eLen > 1 && allSame === false ) { + if ( eLen !== visible ) + croppedText += " (" + visible + "/" + eLen + ")"; + else + croppedText += " (" + eLen + ")"; + } + } + + var searchEntryNode = d3.select(testEntry); + if ( eLen === 1 || allSame === true ) { + if ( nodeMap[entries[0]] === undefined ) { + searchEntryNode.style("color", "#979797"); + testEntry.title = newResults[i] + "\nElement is filtered out."; + testEntry.onclick = function (){ + }; + d3.select(testEntry).style("cursor", "default"); + filteredOutElements++; + } + } else { + if ( visible < 1 ) { + searchEntryNode.style("color", "#979797"); + testEntry.onclick = function (){ + }; + testEntry.title = newResults[i] + "\nAll elements are filtered out."; + d3.select(testEntry).style("cursor", "default"); + filteredOutElements++; + } else { + searchEntryNode.style("color", ""); + } + if ( visible < eLen && visible > 1 ) { + testEntry.title = newResults[i] + "\n" + visible + "/" + eLen + " elements are visible."; + } + } + searchEntryNode.node().innerHTML = croppedText; + m_search.node().appendChild(testEntry); + } + } + + + function handleAutoCompletion(){ + /** pre condition: autoCompletion has already a valid text**/ + clearSearchEntries(); + createSearchEntries(); + createDropDownElements(); + } + + function userInput(){ + c_locate.classed("highlighted", false); + c_locate.node().title = "Nothing to locate"; + + if ( dictionaryUpdateRequired ) { + updateSearchDictionary(); + } + graph.resetSearchHighlight(); + + if ( dictionary.length === 0 ) { + console.log("dictionary is empty"); + return; + } + inputText = searchLineEdit.node().value; + + clearSearchEntries(); + if ( inputText.length !== 0 ) { + createSearchEntries(); + createDropDownElements(); + } + + searchMenu.showSearchEntries(); + } + + function handleClick( elementId ){ + + return function (){ + var id = elementId; + var correspondingIds = mergedIdList[id]; + + // autoComplete the text for the user + var autoComStr = entryNames[id]; + searchLineEdit.node().value = autoComStr; + + graph.resetSearchHighlight(); + graph.highLightNodes(correspondingIds); + c_locate.node().title = "Locate search term"; + if ( autoComStr !== inputText ) { + handleAutoCompletion(); + } + searchMenu.hideSearchEntries(); + }; + } + + searchMenu.clearText = function (){ + searchLineEdit.node().value = ""; + c_locate.classed("highlighted", false); + c_locate.node().title = "Nothing to locate"; + var htmlCollection = m_search.node().children; + var numEntries = htmlCollection.length; + for ( var i = 0; i < numEntries; i++ ) { + htmlCollection[0].remove(); + } + }; + + return searchMenu; +}; diff --git a/src/app/js/menu/zoomSlider.js b/src/app/js/menu/zoomSlider.js new file mode 100644 index 0000000000000000000000000000000000000000..0e2c4c38cd0401b191dea3e7f7f0aa6c61282a79 --- /dev/null +++ b/src/app/js/menu/zoomSlider.js @@ -0,0 +1,114 @@ +/** The zoom Slider **/ +module.exports = function ( graph ){ + var zoomSlider = {}; + var minMag = graph.options().minMagnification(), + maxMag = graph.options().maxMagnification(), + defZoom, + t_zoomOut, + t_zoomIn, + zoomValue, + showSlider = true, + w = graph.options().width(), + h = graph.options().height(), + slider; + + defZoom = Math.min(w, h) / 1000; + + function clearAllTimers(){ + cancelAnimationFrame(t_zoomOut); + cancelAnimationFrame(t_zoomIn); + } + + function timed_zoomOut(){ + zoomValue = 0.98 * zoomValue; + // fail saves + if ( zoomValue < minMag ) { + zoomValue = minMag; + } + graph.setSliderZoom(zoomValue); + t_zoomOut = requestAnimationFrame(timed_zoomOut); + } + + function timed_zoomIn(){ + zoomValue = 1.02 * zoomValue; + // fail saves + if ( zoomValue > maxMag ) { + zoomValue = maxMag; + } + graph.setSliderZoom(zoomValue); + t_zoomIn = requestAnimationFrame(timed_zoomIn); + } + + zoomSlider.setup = function (){ + slider = d3.select("#zoomSliderParagraph").append("input") + .datum({}) + .attr("id", "zoomSliderElement") + .attr("type", "range") + .attr("value", defZoom) + .attr("min", minMag) + .attr("max", maxMag) + .attr("step", (maxMag - minMag) / 40) + .attr("title", "zoom factor") + .on("input", function (){ + zoomSlider.zooming(); + }); + + d3.select("#zoomOutButton").on("mousedown", function (){ + graph.options().navigationMenu().hideAllMenus(); + zoomValue = graph.scaleFactor(); + t_zoomOut = requestAnimationFrame(timed_zoomOut); + }) + .on("touchstart", function (){ + graph.options().navigationMenu().hideAllMenus(); + zoomValue = graph.scaleFactor(); + t_zoomOut = requestAnimationFrame(timed_zoomOut); + }) + .on("mouseup", clearAllTimers) + .on("touchend", clearAllTimers) + .on("touchcancel", clearAllTimers) + .attr("title", "zoom out"); + + d3.select("#zoomInButton").on("mousedown", function (){ + graph.options().navigationMenu().hideAllMenus(); + zoomValue = graph.scaleFactor(); + t_zoomIn = requestAnimationFrame(timed_zoomIn); + }) + .on("touchstart", function (){ + graph.options().navigationMenu().hideAllMenus(); + zoomValue = graph.scaleFactor(); + t_zoomIn = requestAnimationFrame(timed_zoomIn); + }) + .on("mouseup", clearAllTimers) + .on("touchend", clearAllTimers) + .on("touchcancel", clearAllTimers) + .attr("title", "zoom in"); + + d3.select("#centerGraphButton").on("click", function (){ + graph.options().navigationMenu().hideAllMenus(); + graph.forceRelocationEvent(); + }).attr("title", "center graph"); + + }; + + zoomSlider.showSlider = function ( val ){ + if ( !arguments.length ) return showSlider; + d3.select("#zoomSlider").classed("hidden", !val); + showSlider = val; + }; + + zoomSlider.zooming = function (){ + graph.options().navigationMenu().hideAllMenus(); + var zoomValue = slider.property("value"); + slider.attr("value", zoomValue); + graph.setSliderZoom(zoomValue); + }; + + zoomSlider.updateZoomSliderValue = function ( val ){ + if ( slider ) { + slider.attr("value", val); + slider.property("value", val); + } + }; + + return zoomSlider; +}; diff --git a/src/app/js/sidebar.js b/src/app/js/sidebar.js new file mode 100644 index 0000000000000000000000000000000000000000..1265ea5ea79a7b358d463e52d64a51e753b59c72 --- /dev/null +++ b/src/app/js/sidebar.js @@ -0,0 +1,603 @@ +/** + * Contains the logic for the sidebar. + * @param graph the graph that belongs to these controls + * @returns {{}} + */ +module.exports = function ( graph ){ + + var sidebar = {}, + languageTools = webvowl.util.languageTools(), + elementTools = webvowl.util.elementTools(), + // Required for reloading when the language changes + ontologyInfo, + visibleSidebar = 1, + lastSelectedElement, + + detailArea = d3.select("#detailsArea"), + graphArea = d3.select("#canvasArea"), + menuArea = d3.select("#swipeBarContainer"), + collapseButton = d3.select("#sidebarExpandButton"); + + /** + * Setup the menu bar. + */ + + + function setupCollapsing(){ + // adapted version of this example: http://www.normansblog.de/simple-jquery-accordion/ + function collapseContainers( containers ){ + containers.classed("hidden", true); + } + + function expandContainers( containers ){ + containers.classed("hidden", false); + } + + var triggers = d3.selectAll(".accordion-trigger"); + + // Collapse all inactive triggers on startup + collapseContainers(d3.selectAll(".accordion-trigger:not(.accordion-trigger-active) + div")); + + triggers.on("click", function (){ + var selectedTrigger = d3.select(this), + activeTriggers = d3.selectAll(".accordion-trigger-active"); + + if ( selectedTrigger.classed("accordion-trigger-active") ) { + // Collapse the active (which is also the selected) trigger + collapseContainers(d3.select(selectedTrigger.node().nextElementSibling)); + selectedTrigger.classed("accordion-trigger-active", false); + } else { + // Collapse the other trigger ... + collapseContainers(d3.selectAll(".accordion-trigger-active + div")); + activeTriggers.classed("accordion-trigger-active", false); + // ... and expand the selected one + expandContainers(d3.select(selectedTrigger.node().nextElementSibling)); + selectedTrigger.classed("accordion-trigger-active", true); + } + }); + } + + sidebar.clearOntologyInformation = function (){ + + d3.select("#title").text("No title available"); + d3.select("#about").attr("href", "#").attr("target", "_blank").text("not given"); + d3.select("#version").text("--"); + d3.select("#authors").text("--"); + d3.select("#description").text("No description available."); + var container = d3.select("#ontology-metadata"); + container.selectAll("*").remove(); + d3.select("#classCount") + .text("0"); + d3.select("#objectPropertyCount") + .text("0"); + d3.select("#datatypePropertyCount") + .text("0"); + d3.select("#individualCount") + .text("0"); + d3.select("#nodeCount") + .text("0"); + d3.select("#edgeCount") + .text("0"); + + // clear selectedNode info + var isTriggerActive = d3.select("#selection-details-trigger").classed("accordion-trigger-active"); + if ( isTriggerActive ) { + // close accordion + d3.select("#selection-details-trigger").node().click(); + } + showSelectionAdvice(); + + }; + + /** + * Updates the information of the passed ontology. + * @param data the graph data + * @param statistics the statistics module + */ + sidebar.updateOntologyInformation = function ( data, statistics ){ + data = data || {}; + ontologyInfo = data.header || {}; + + updateGraphInformation(); + displayGraphStatistics(undefined, statistics); + displayMetadata(ontologyInfo.other); + + // Reset the sidebar selection + sidebar.updateSelectionInformation(undefined); + + setLanguages(ontologyInfo.languages); + }; + + function setLanguages( languages ){ + languages = languages || []; + + // Put the default and unset label on top of the selection labels + languages.sort(function ( a, b ){ + if ( a === webvowl.util.constants().LANG_IRIBASED ) { + return -1; + } else if ( b === webvowl.util.constants().LANG_IRIBASED ) { + return 1; + } + if ( a === webvowl.util.constants().LANG_UNDEFINED ) { + return -1; + } else if ( b === webvowl.util.constants().LANG_UNDEFINED ) { + return 1; + } + return a.localeCompare(b); + }); + + var languageSelection = d3.select("#language") + .on("change", function (){ + graph.language(d3.event.target.value); + updateGraphInformation(); + sidebar.updateSelectionInformation(lastSelectedElement); + }); + + languageSelection.selectAll("option").remove(); + languageSelection.selectAll("option") + .data(languages) + .enter().append("option") + .attr("value", function ( d ){ + return d; + }) + .text(function ( d ){ + return d; + }); + + if ( !trySelectDefaultLanguage(languageSelection, languages, "en") ) { + if ( !trySelectDefaultLanguage(languageSelection, languages, webvowl.util.constants().LANG_UNDEFINED) ) { + trySelectDefaultLanguage(languageSelection, languages, webvowl.util.constants().LANG_IRIBASED); + } + } + } + + function trySelectDefaultLanguage( selection, languages, language ){ + var langIndex = languages.indexOf(language); + if ( langIndex >= 0 ) { + selection.property("selectedIndex", langIndex); + graph.language(language); + return true; + } + + return false; + } + + function updateGraphInformation(){ + var title = languageTools.textInLanguage(ontologyInfo.title, graph.language()); + d3.select("#title").text(title || "No title available"); + d3.select("#about").attr("href", ontologyInfo.iri).attr("target", "_blank").text(ontologyInfo.iri); + d3.select("#version").text(ontologyInfo.version || "--"); + var authors = ontologyInfo.author; + if ( typeof authors === "string" ) { + // Stay compatible with author info as strings after change in january 2015 + d3.select("#authors").text(authors); + } else if ( authors instanceof Array ) { + d3.select("#authors").text(authors.join(", ")); + } else { + d3.select("#authors").text("--"); + } + + var description = languageTools.textInLanguage(ontologyInfo.description, graph.language()); + d3.select("#description").text(description || "No description available."); + } + + function displayGraphStatistics( deliveredMetrics, statistics ){ + // Metrics are optional and may be undefined + deliveredMetrics = deliveredMetrics || {}; + + d3.select("#classCount") + .text(deliveredMetrics.classCount || statistics.classCount()); + d3.select("#objectPropertyCount") + .text(deliveredMetrics.objectPropertyCount || statistics.objectPropertyCount()); + d3.select("#datatypePropertyCount") + .text(deliveredMetrics.datatypePropertyCount || statistics.datatypePropertyCount()); + d3.select("#individualCount") + .text(deliveredMetrics.totalIndividualCount || statistics.totalIndividualCount()); + d3.select("#nodeCount") + .text(statistics.nodeCount()); + d3.select("#edgeCount") + .text(statistics.edgeCount()); + } + + function displayMetadata( metadata ){ + var container = d3.select("#ontology-metadata"); + container.selectAll("*").remove(); + + listAnnotations(container, metadata); + + if ( container.selectAll(".annotation").size() <= 0 ) { + container.append("p").text("No annotations available."); + } + } + + function listAnnotations( container, annotationObject ){ + annotationObject = annotationObject || {}; //todo + + // Collect the annotations in an array for simpler processing + var annotations = []; + for ( var annotation in annotationObject ) { + if ( annotationObject.hasOwnProperty(annotation) ) { + annotations.push(annotationObject[annotation][0]); + } + } + + container.selectAll(".annotation").remove(); + container.selectAll(".annotation").data(annotations).enter().append("p") + .classed("annotation", true) + .classed("statisticDetails", true) + .text(function ( d ){ + return d.identifier + ":"; + }) + .append("span") + .each(function ( d ){ + appendIriLabel(d3.select(this), d.value, d.type === "iri" ? d.value : undefined); + }); + } + + /** + * Update the information of the selected node. + * @param selectedElement the selection or null if nothing is selected + */ + sidebar.updateSelectionInformation = function ( selectedElement ){ + lastSelectedElement = selectedElement; + + // Click event was prevented when dragging + if ( d3.event && d3.event.defaultPrevented ) { + return; + } + + var isTriggerActive = d3.select("#selection-details-trigger").classed("accordion-trigger-active"); + if ( selectedElement && !isTriggerActive ) { + d3.select("#selection-details-trigger").node().click(); + } else if ( !selectedElement && isTriggerActive ) { + showSelectionAdvice(); + return; + } + + if ( elementTools.isProperty(selectedElement) ) { + displayPropertyInformation(selectedElement); + } else if ( elementTools.isNode(selectedElement) ) { + displayNodeInformation(selectedElement); + } + }; + + function showSelectionAdvice(){ + setSelectionInformationVisibility(false, false, true); + } + + function setSelectionInformationVisibility( showClasses, showProperties, showAdvice ){ + d3.select("#classSelectionInformation").classed("hidden", !showClasses); + d3.select("#propertySelectionInformation").classed("hidden", !showProperties); + d3.select("#noSelectionInformation").classed("hidden", !showAdvice); + } + + function displayPropertyInformation( property ){ + showPropertyInformations(); + + setIriLabel(d3.select("#propname"), property.labelForCurrentLanguage(), property.iri()); + d3.select("#typeProp").text(property.type()); + + if ( property.inverse() !== undefined ) { + d3.select("#inverse").classed("hidden", false); + setIriLabel(d3.select("#inverse span"), property.inverse().labelForCurrentLanguage(), property.inverse().iri()); + } else { + d3.select("#inverse").classed("hidden", true); + } + + var equivalentIriSpan = d3.select("#propEquivUri"); + listNodeArray(equivalentIriSpan, property.equivalents()); + + listNodeArray(d3.select("#subproperties"), property.subproperties()); + listNodeArray(d3.select("#superproperties"), property.superproperties()); + + if ( property.minCardinality() !== undefined ) { + d3.select("#infoCardinality").classed("hidden", true); + d3.select("#minCardinality").classed("hidden", false); + d3.select("#minCardinality span").text(property.minCardinality()); + d3.select("#maxCardinality").classed("hidden", false); + + if ( property.maxCardinality() !== undefined ) { + d3.select("#maxCardinality span").text(property.maxCardinality()); + } else { + d3.select("#maxCardinality span").text("*"); + } + + } else if ( property.cardinality() !== undefined ) { + d3.select("#minCardinality").classed("hidden", true); + d3.select("#maxCardinality").classed("hidden", true); + d3.select("#infoCardinality").classed("hidden", false); + d3.select("#infoCardinality span").text(property.cardinality()); + } else { + d3.select("#infoCardinality").classed("hidden", true); + d3.select("#minCardinality").classed("hidden", true); + d3.select("#maxCardinality").classed("hidden", true); + } + + setIriLabel(d3.select("#domain"), property.domain().labelForCurrentLanguage(), property.domain().iri()); + setIriLabel(d3.select("#range"), property.range().labelForCurrentLanguage(), property.range().iri()); + + displayAttributes(property.attributes(), d3.select("#propAttributes")); + + setTextAndVisibility(d3.select("#propDescription"), property.descriptionForCurrentLanguage()); + setTextAndVisibility(d3.select("#propComment"), property.commentForCurrentLanguage()); + + listAnnotations(d3.select("#propertySelectionInformation"), property.annotations()); + } + + function showPropertyInformations(){ + setSelectionInformationVisibility(false, true, false); + } + + function setIriLabel( element, name, iri ){ + var parent = d3.select(element.node().parentNode); + + if ( name ) { + element.selectAll("*").remove(); + appendIriLabel(element, name, iri); + parent.classed("hidden", false); + } else { + parent.classed("hidden", true); + } + } + + function appendIriLabel( element, name, iri ){ + var tag; + + if ( iri ) { + tag = element.append("a") + .attr("href", iri) + .attr("title", iri) + .attr("target", "_blank"); + } else { + tag = element.append("span"); + } + tag.text(name); + } + + function displayAttributes( attributes, textSpan ){ + var spanParent = d3.select(textSpan.node().parentNode); + + if ( attributes && attributes.length > 0 ) { + // Remove redundant redundant attributes for sidebar + removeElementFromArray("object", attributes); + removeElementFromArray("datatype", attributes); + removeElementFromArray("rdf", attributes); + } + + if ( attributes && attributes.length > 0 ) { + textSpan.text(attributes.join(", ")); + + spanParent.classed("hidden", false); + } else { + spanParent.classed("hidden", true); + } + } + + function removeElementFromArray( element, array ){ + var index = array.indexOf(element); + if ( index > -1 ) { + array.splice(index, 1); + } + } + + function displayNodeInformation( node ){ + showClassInformations(); + + setIriLabel(d3.select("#name"), node.labelForCurrentLanguage(), node.iri()); + + /* Equivalent stuff. */ + var equivalentIriSpan = d3.select("#classEquivUri"); + listNodeArray(equivalentIriSpan, node.equivalents()); + + d3.select("#typeNode").text(node.type()); + listNodeArray(d3.select("#individuals"), node.individuals()); + + /* Disjoint stuff. */ + var disjointNodes = d3.select("#disjointNodes"); + var disjointNodesParent = d3.select(disjointNodes.node().parentNode); + + if ( node.disjointWith() !== undefined ) { + disjointNodes.selectAll("*").remove(); + + node.disjointWith().forEach(function ( element, index ){ + if ( index > 0 ) { + disjointNodes.append("span").text(", "); + } + appendIriLabel(disjointNodes, element.labelForCurrentLanguage(), element.iri()); + }); + + disjointNodesParent.classed("hidden", false); + } else { + disjointNodesParent.classed("hidden", true); + } + + displayAttributes(node.attributes(), d3.select("#classAttributes")); + + setTextAndVisibility(d3.select("#nodeDescription"), node.descriptionForCurrentLanguage()); + setTextAndVisibility(d3.select("#nodeComment"), node.commentForCurrentLanguage()); + + listAnnotations(d3.select("#classSelectionInformation"), node.annotations()); + } + + function showClassInformations(){ + setSelectionInformationVisibility(true, false, false); + } + + function listNodeArray( textSpan, nodes ){ + var spanParent = d3.select(textSpan.node().parentNode); + + if ( nodes && nodes.length ) { + textSpan.selectAll("*").remove(); + nodes.forEach(function ( element, index ){ + if ( index > 0 ) { + textSpan.append("span").text(", "); + } + appendIriLabel(textSpan, element.labelForCurrentLanguage(), element.iri()); + }); + + spanParent.classed("hidden", false); + } else { + spanParent.classed("hidden", true); + } + } + + function setTextAndVisibility( label, value ){ + var parentNode = d3.select(label.node().parentNode); + var hasValue = !!value; + if ( value ) { + label.text(value); + } + parentNode.classed("hidden", !hasValue); + } + + /** Collapsible Sidebar functions; **/ + + sidebar.showSidebar = function ( val, init ){ + // make val to bool + if ( val === 1 ) { + visibleSidebar = true; + collapseButton.node().innerHTML = ">"; + detailArea.classed("hidden", true); + if ( init === true ) { + detailArea.classed("hidden", !visibleSidebar); + graphArea.style("width", "78%"); + graphArea.style("-webkit-animation-name", "none"); + + menuArea.style("width", "78%"); + menuArea.style("-webkit-animation-name", "none"); + + d3.select("#WarningErrorMessagesContainer").style("width", "78%"); + d3.select("#WarningErrorMessagesContainer").style("-webkit-animation-name", "none"); + } else { + graphArea.style("width", "78%"); + graphArea.style("-webkit-animation-name", "sbCollapseAnimation"); + graphArea.style("-webkit-animation-duration", "0.5s"); + + menuArea.style("width", "78%"); + menuArea.style("-webkit-animation-name", "sbCollapseAnimation"); + menuArea.style("-webkit-animation-duration", "0.5s"); + + d3.select("#WarningErrorMessagesContainer").style("width", "78%"); + d3.select("#WarningErrorMessagesContainer").style("-webkit-animation-name", "warn_ExpandRightBarAnimation"); + d3.select("#WarningErrorMessagesContainer").style("-webkit-animation-duration", "0.5s"); + } + graph.options().width(window.innerWidth - (window.innerWidth * 0.22)); + graph.options().navigationMenu().updateScrollButtonVisibility(); + } + if ( val === 0 ) { + visibleSidebar = false; + detailArea.classed("hidden", true); + + collapseButton.node().innerHTML = "<"; + // adjust the layout + if ( init === true ) { + graphArea.style("width", "100%"); + graphArea.style("-webkit-animation-name", "none"); + + menuArea.style("width", "100%"); + menuArea.style("-webkit-animation-name", "none"); + + d3.select("#WarningErrorMessagesContainer").style("width", "100%"); + d3.select("#WarningErrorMessagesContainer").style("-webkit-animation-name", "none"); + } else { + graphArea.style("width", "100%"); + graphArea.style("-webkit-animation-name", "sbExpandAnimation"); + graphArea.style("-webkit-animation-duration", "0.5s"); + + menuArea.style("width", "100%"); + menuArea.style("-webkit-animation-name", "sbExpandAnimation"); + menuArea.style("-webkit-animation-duration", "0.5s"); + + d3.select("#WarningErrorMessagesContainer").style("width", "100%"); + d3.select("#WarningErrorMessagesContainer").style("-webkit-animation-name", "warn_CollapseRightBarAnimation"); + d3.select("#WarningErrorMessagesContainer").style("-webkit-animation-duration", "0.5s"); + + } + graph.options().width(window.innerWidth); + graph.updateCanvasContainerSize(); + graph.options().navigationMenu().updateScrollButtonVisibility(); + } + }; + + sidebar.isSidebarVisible = function (){ + return visibleSidebar; + }; + + sidebar.updateSideBarVis = function ( init ){ + var vis = sidebar.getSidebarVisibility(); + sidebar.showSidebar(parseInt(vis), init); + }; + + sidebar.getSidebarVisibility = function (){ + var isHidden = detailArea.classed("hidden"); + if ( isHidden === false ) return String(1); + if ( isHidden === true ) return String(0); + }; + + sidebar.initSideBarAnimation = function (){ + graphArea.node().addEventListener("animationend", function (){ + detailArea.classed("hidden", !visibleSidebar); + graph.updateCanvasContainerSize(); + graph.options().navigationMenu().updateScrollButtonVisibility(); + }); + }; + + sidebar.setup = function (){ + setupCollapsing(); + sidebar.initSideBarAnimation(); + + collapseButton.on("click", function (){ + graph.options().navigationMenu().hideAllMenus(); + var settingValue = parseInt(sidebar.getSidebarVisibility()); + if ( settingValue === 1 ) sidebar.showSidebar(0); + else sidebar.showSidebar(1); + }); + }; + + + sidebar.updateShowedInformation = function (){ + var editMode = graph.editorMode(); + d3.select("#generalDetails").classed("hidden", editMode); + d3.select("#generalDetailsEdit").classed("hidden", !editMode); + + // store the meta information in graph.options() + + // todo: update edit meta info + graph.options().editSidebar().updateGeneralOntologyInfo(); + + // todo: update showed meta info; + graph.options().sidebar().updateGeneralOntologyInfo(); + + }; + + sidebar.updateGeneralOntologyInfo = function (){ + // get it from graph.options + var generalMetaObj = graph.options().getGeneralMetaObject(); + var preferredLanguage = graph && graph.language ? graph.language() : null; + if ( generalMetaObj.hasOwnProperty("title") ) { + // title has language to it -.- + if ( typeof generalMetaObj.title === "object" ) { + d3.select("#title").node().value = languageTools.textInLanguage(generalMetaObj.title, preferredLanguage); + } else { + d3.select("#title").node().innerHTML = generalMetaObj.title; + } + + } + if ( generalMetaObj.hasOwnProperty("iri") ) d3.select("#about").node().innerHTML = generalMetaObj.iri; + if ( generalMetaObj.hasOwnProperty("iri") ) d3.select("#about").node().href = generalMetaObj.iri; + if ( generalMetaObj.hasOwnProperty("version") ) d3.select("#version").node().innerHTML = generalMetaObj.version; + if ( generalMetaObj.hasOwnProperty("author") ) d3.select("#authors").node().innerHTML = generalMetaObj.author; + // this could also be an object >> + if ( generalMetaObj.hasOwnProperty("description") ) { + if ( typeof generalMetaObj.description === "object" ) { + d3.select("#description").node().innerHTML = languageTools.textInLanguage(generalMetaObj.description, preferredLanguage); + } + else { + d3.select("#description").node().innerHTML = generalMetaObj.description; + } + } + }; + + + return sidebar; +}; diff --git a/src/app/js/warningModule.js b/src/app/js/warningModule.js new file mode 100644 index 0000000000000000000000000000000000000000..67bff1504da14bc3ff9aceff5275f5b556a4b2df --- /dev/null +++ b/src/app/js/warningModule.js @@ -0,0 +1,427 @@ +module.exports = function ( graph ){ + /** variable defs **/ + var warningModule = {}; + var superContainer = d3.select("#WarningErrorMessages"); + var _messageContainers = []; + var _messageContext = []; + var _visibleStatus = []; + + var _filterHintId; + var _editorHintId; + var _messageId = -1; + superContainer.style("display", "inline-block"); + var cssStyleIndex = 0; + var styleSelectorIndex = 2; + + + // helper for standalone webvowl in chrome + function createCSSSelector( name, rules ){ + var style = document.createElement('style'); + style.type = 'text/css'; + document.getElementsByTagName('head')[0].appendChild(style); + if ( !(style.sheet || {}).insertRule ) + (style.styleSheet || style.sheet).addRule(name, rules); + else + style.sheet.insertRule(name + "{" + rules + "}", 0); + } + + + function findCSS_Index(){ + createCSSSelector("@keyframes msg_CollapseAnimation", " 0% { top: 0; } 100% { top: -400px;}"); + console.log(document.styleSheets ); + } + + findCSS_Index(); + + warningModule.addMessageBox = function (){ + + // add a container; + _messageId++; + var messageContainer = d3.select("#WarningErrorMessages").append("div"); + messageContainer.node().id = "messageContainerId_" + _messageId; + + var messageContext = messageContainer.append("div"); + messageContext.node().id = "messageContextId_" + _messageId; + messageContext.style("top", "0"); + messageContainer.style("position", "relative"); + messageContainer.style("width", "100%"); + //save in array + _messageContainers.push(messageContainer); + _messageContext.push(messageContext); + + // add animation to the container + messageContainer.node().addEventListener("animationend", _msgContainer_animationEnd); + + // set visible flag that is used in end of animation + _visibleStatus[_messageId] = true; + return _messageId; + }; + + function _msgContainer_animationEnd(){ + var containerId = this.id; + var tokens = containerId.split("_")[1]; + var mContainer = d3.select("#" + containerId); + // get number of children + mContainer.classed("hidden", !_visibleStatus[tokens]); + // clean up DOM + if ( !_visibleStatus[tokens] ) { + mContainer.remove(); + _messageContext[tokens] = null; + _messageContainers[tokens] = null; + } + // remove event listener + var c = d3.select(this); + // c.node().removeEventListener("animationend",_msgContainer_animationEnd); + } + + warningModule.createMessageContext = function ( id ){ + var warningContainer = _messageContext[id]; + var moduleContainer = _messageContainers[id]; + var generalHint = warningContainer.append('div'); + generalHint.node().innerHTML = ""; + _editorHintId = id; + /** Editing mode activated. You can now modify an existing ontology or create a new one via the ontology menu. You can save any ontology using the export menu (and exporting it as TTL file).**/ + generalHint.node().innerHTML += "Editing mode activated.
" + + "You can now modify an existing ontology or create a new one via the ontology menu.
" + + "You can save any ontology using the export menu (and exporting it as TTL file)."; + + generalHint.style("padding", "5px"); + generalHint.style("line-height", "1.2em"); + generalHint.style("font-size", "1.2em"); + + + var ul = warningContainer.append('ul'); + ul.append('li').node().innerHTML = "Create a class with double click / tap on empty canvas area."; + ul.append('li').node().innerHTML = "Edit names with double click / tap on element."; + ul.append('li').node().innerHTML = "Selection of default constructors is provided in the left sidebar."; + ul.append('li').node().innerHTML = "Additional editing functionality is provided in the right sidebar."; + + + var gotItButton = warningContainer.append("label"); + gotItButton.node().id = "killWarningErrorMessages_" + id; + gotItButton.node().innerHTML = "Got It"; + gotItButton.on("click", warningModule.closeMessage); + + moduleContainer.classed("hidden", false); + moduleContainer.style("-webkit-animation-name", "warn_ExpandAnimation"); + moduleContainer.style("-webkit-animation-duration", "0.5s"); + }; + + warningModule.showMessage = function ( id ){ + var moduleContainer = _messageContainers[id]; + moduleContainer.classed("hidden", false); + moduleContainer.style("-webkit-animation-name", "warn_ExpandAnimation"); + moduleContainer.style("-webkit-animation-duration", "0.5s"); + }; + + warningModule.closeMessage = function ( id ){ + var nId; + if ( id === undefined ) { + var givenId = this.id; + nId = givenId.split("_")[1]; + } else { + nId = id; + } + if ( id && id.indexOf("_") !== -1 ) { + nId = id.split("_")[1]; + } + _visibleStatus[nId] = false; + // get module; + var moduleContainer = _messageContainers[nId]; + moduleContainer.style("-webkit-animation-name", "warn_CollapseAnimation"); + moduleContainer.style("-webkit-animation-duration", "0.5s"); + + var m_height = moduleContainer.node().getBoundingClientRect().height; + + // find my id in the children + var pNode = moduleContainer.node().parentNode; + + var followingChildren = []; + var pChild = pNode.children; + var pChild_len = pChild.length; + var containerId = moduleContainer.node().id; + var found_me = false; + for ( var i = 0; i < pChild_len; i++ ) { + if ( found_me === true ) { + followingChildren.push(pChild[i].id); + } + + if ( containerId === pChild[i].id ) { + found_me = true; + } + } + + for ( var fc = 0; fc < followingChildren.length; fc++ ) { + var child = d3.select("#" + followingChildren[fc]); + // get the document style and overwrite it; + var superCss = document.styleSheets[styleSelectorIndex].cssRules[cssStyleIndex]; + // remove the existing 0% and 100% rules + superCss.deleteRule("0%"); + superCss.deleteRule("100%"); + + superCss.appendRule("0% {top: 0;}"); + superCss.appendRule("100% {top: -" + m_height + "px;"); + + child.style("-webkit-animation-name", "msg_CollapseAnimation"); + child.style("-webkit-animation-duration", "0.5s"); + child.node().addEventListener("animationend", _child_animationEnd); + } + }; + + function _child_animationEnd(){ + var c = d3.select(this); + c.style("-webkit-animation-name", ""); + c.style("-webkit-animation-duration", ""); + c.node().removeEventListener("animationend", _child_animationEnd); + } + + warningModule.closeFilterHint = function (){ + if ( _messageContainers[_filterHintId] ) { + _messageContainers[_filterHintId].classed("hidden", true); + _messageContainers[_filterHintId].remove(); + _messageContainers[_filterHintId] = null; + _messageContext[_filterHintId] = null; + _visibleStatus[_filterHintId] = false; + } + }; + + warningModule.showEditorHint = function (){ + var id = warningModule.addMessageBox(); + warningModule.createMessageContext(id); + }; + + warningModule.showExporterWarning=function (){ + warningModule.showWarning("Can not export ontology", "Detected unsupported ontology axioms, (e.g. owl:Union)", "Ontology is not exported", 1, false); + }; + + + + warningModule.responseWarning = function ( header, reason, action, callback, parameterArray, forcedWarning ){ + var id = warningModule.addMessageBox(); + var warningContainer = _messageContext[id]; + var moduleContainer = _messageContainers[id]; + _visibleStatus[id] = true; + d3.select("#blockGraphInteractions").classed("hidden", false); + var graphWidth = 0.5 * graph.options().width(); + + if ( header.length > 0 ) { + var head = warningContainer.append("div"); + head.style("padding", "5px"); + var titleHeader = head.append("div"); + // some classes + titleHeader.style("display", "inline-flex"); + titleHeader.node().innerHTML = "Warning:"; + titleHeader.style("padding-right", "3px"); + var msgHeader = head.append("div"); + // some classes + msgHeader.style("display", "inline-flex"); + msgHeader.style("max-width", graphWidth + "px"); + + msgHeader.node().innerHTML = header; + } + if ( reason.length > 0 ) { + var reasonContainer = warningContainer.append("div"); + reasonContainer.style("padding", "5px"); + var reasonHeader = reasonContainer.append("div"); + // some classes + reasonHeader.style("display", "inline-flex"); + reasonHeader.style("padding-right", "3px"); + + reasonHeader.node().innerHTML = "Reason:"; + var msgReason = reasonContainer.append("div"); + // some classes + msgReason.style("display", "inline-flex"); + msgReason.style("max-width", graphWidth + "px"); + msgReason.node().innerHTML = reason; + } + if ( action.length > 0 ) { + var actionContainer = warningContainer.append("div"); + actionContainer.style("padding", "5px"); + var actionHeader = actionContainer.append("div"); + // some classes + actionHeader.style("display", "inline-flex"); + actionHeader.style("padding-right", "8px"); + actionHeader.node().innerHTML = "Action:"; + var msgAction = actionContainer.append("div"); + // some classes + msgAction.style("display", "inline-flex"); + msgAction.style("max-width", graphWidth + "px"); + msgAction.node().innerHTML = action; + } + + var gotItButton = warningContainer.append("label"); + gotItButton.node().id = "killWarningErrorMessages_" + id; + gotItButton.node().innerHTML = "Continue"; + gotItButton.on("click", function (){ + warningModule.closeMessage(this.id); + d3.select("#blockGraphInteractions").classed("hidden", true); + callback(parameterArray[0], parameterArray[1], parameterArray[2], parameterArray[3]); + }); + warningContainer.append("span").node().innerHTML = "|"; + var cancelButton = warningContainer.append("label"); + cancelButton.node().id = "cancelButton_" + id; + cancelButton.node().innerHTML = "Cancel"; + cancelButton.on("click", function (){ + warningModule.closeMessage(this.id); + d3.select("#blockGraphInteractions").classed("hidden", true); + }); + moduleContainer.classed("hidden", false); + moduleContainer.style("-webkit-animation-name", "warn_ExpandAnimation"); + moduleContainer.style("-webkit-animation-duration", "0.5s"); + }; + + warningModule.showFilterHint = function (){ + var id = warningModule.addMessageBox(); + var warningContainer = _messageContext[id]; + var moduleContainer = _messageContainers[id]; + _visibleStatus[id] = true; + + _filterHintId = id; + var generalHint = warningContainer.append('div'); + /** Editing mode activated. You can now modify an existing ontology or create a new one via the ontology menu. You can save any ontology using the export menu (and exporting it as TTL file).**/ + generalHint.node().innerHTML = "Collapsing filter activated.
" + + "The number of visualized elements has been automatically reduced.
" + + "Use the degree of collapsing slider in the filter menu to adjust the visualization.

" + + "Note: A performance decrease could be experienced with a growing amount of visual elements in the graph."; + + + generalHint.style("padding", "5px"); + generalHint.style("line-height", "1.2em"); + generalHint.style("font-size", "1.2em"); + + var gotItButton = warningContainer.append("label"); + gotItButton.node().id = "killFilterMessages_" + id; + gotItButton.node().innerHTML = "Got It"; + gotItButton.on("click", warningModule.closeMessage); + + moduleContainer.classed("hidden", false); + moduleContainer.style("-webkit-animation-name", "warn_ExpandAnimation"); + moduleContainer.style("-webkit-animation-duration", "0.5s"); + }; + + warningModule.showMultiFileUploadWarning = function (){ + var id = warningModule.addMessageBox(); + var warningContainer = _messageContext[id]; + var moduleContainer = _messageContainers[id]; + _visibleStatus[id] = true; + + _filterHintId = id; + var generalHint = warningContainer.append('div'); + + generalHint.node().innerHTML = "Uploading multiple files is not supported.
"; + + generalHint.style("padding", "5px"); + generalHint.style("line-height", "1.2em"); + generalHint.style("font-size", "1.2em"); + + var gotItButton = warningContainer.append("label"); + gotItButton.node().id = "killFilterMessages_" + id; + gotItButton.node().innerHTML = "Got It"; + gotItButton.on("click", warningModule.closeMessage); + + moduleContainer.classed("hidden", false); + moduleContainer.style("-webkit-animation-name", "warn_ExpandAnimation"); + moduleContainer.style("-webkit-animation-duration", "0.5s"); + }; + + warningModule.showWarning = function ( header, reason, action, type, forcedWarning, additionalOpts ){ + var id = warningModule.addMessageBox(); + var warningContainer = _messageContext[id]; + var moduleContainer = _messageContainers[id]; + _visibleStatus[id] = true; + + // add new one; + var graphWidth = 0.5 * graph.options().width(); + + if ( header.length > 0 ) { + var head = warningContainer.append("div"); + head.style("padding", "5px"); + var titleHeader = head.append("div"); + // some classes + titleHeader.style("display", "inline-flex"); + titleHeader.node().innerHTML = "Warning:"; + titleHeader.style("padding-right", "3px"); + var msgHeader = head.append("div"); + // some classes + msgHeader.style("display", "inline-flex"); + msgHeader.style("max-width", graphWidth + "px"); + + msgHeader.node().innerHTML = header; + } + if ( reason.length > 0 ) { + var reasonContainer = warningContainer.append("div"); + reasonContainer.style("padding", "5px"); + var reasonHeader = reasonContainer.append("div"); + // some classes + reasonHeader.style("display", "inline-flex"); + reasonHeader.style("padding-right", "3px"); + + reasonHeader.node().innerHTML = "Reason:"; + var msgReason = reasonContainer.append("div"); + // some classes + msgReason.style("display", "inline-flex"); + msgReason.style("max-width", graphWidth + "px"); + msgReason.node().innerHTML = reason; + } + if ( action.length > 0 ) { + var actionContainer = warningContainer.append("div"); + actionContainer.style("padding", "5px"); + var actionHeader = actionContainer.append("div"); + // some classes + actionHeader.style("display", "inline-flex"); + actionHeader.style("padding-right", "8px"); + actionHeader.node().innerHTML = "Action:"; + var msgAction = actionContainer.append("div"); + // some classes + msgAction.style("display", "inline-flex"); + msgAction.style("max-width", graphWidth + "px"); + msgAction.node().innerHTML = action; + } + + var gotItButton; + if ( type === 1 ) { + gotItButton = warningContainer.append("label"); + gotItButton.node().id = "killWarningErrorMessages_" + id; + gotItButton.node().innerHTML = "Got It"; + gotItButton.on("click", warningModule.closeMessage); + } + + if ( type === 2 ) { + gotItButton = warningContainer.append("label"); + gotItButton.node().id = "killWarningErrorMessages_" + id; + gotItButton.node().innerHTML = "Got It"; + gotItButton.on("click", warningModule.closeMessage); + warningContainer.append("span").node().innerHTML = "|"; + var zoomToElementButton = warningContainer.append("label"); + zoomToElementButton.node().id = "zoomElementThing_" + id; + zoomToElementButton.node().innerHTML = "Zoom to element "; + zoomToElementButton.on("click", function (){ + // assume the additional Element is for halo; + graph.zoomToElementInGraph(additionalOpts); + }); + warningContainer.append("span").node().innerHTML = "|"; + var ShowElementButton = warningContainer.append("label"); + ShowElementButton.node().id = "showElementThing_" + id; + ShowElementButton.node().innerHTML = "Indicate element"; + ShowElementButton.on("click", function (){ + // assume the additional Element is for halo; + if ( additionalOpts.halo() === false ) { + additionalOpts.drawHalo(); + graph.updatePulseIds([additionalOpts.id()]); + } else { + additionalOpts.removeHalo(); + additionalOpts.drawHalo(); + graph.updatePulseIds([additionalOpts.id()]); + } + }); + } + moduleContainer.classed("hidden", false); + moduleContainer.style("-webkit-animation-name", "warn_ExpandAnimation"); + moduleContainer.style("-webkit-animation-duration", "0.5s"); + moduleContainer.classed("hidden", false); + }; + + return warningModule; +}; + + diff --git a/src/favicon.ico b/src/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a857d51f1c78d8be8fe2103fde3a10b9a72b041b Binary files /dev/null and b/src/favicon.ico differ diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000000000000000000000000000000000000..f0a2f672c5e7ba15436ec99eb7af9b9660dba67a --- /dev/null +++ b/src/index.html @@ -0,0 +1,544 @@ + + + + + + + + + + + + + + WebVOWL + + +
+
+ + + + + + + +
+ + + + + +
+ +
+ + +
+ +
+
>
+ +
+ +
+ + +
+
+
+

+

+

+

+

-

+
+
+ + +
+
+
+
+ + + + +
+ + + + + + diff --git a/src/webvowl/css/vowl.css b/src/webvowl/css/vowl.css new file mode 100644 index 0000000000000000000000000000000000000000..bd066236a27a7e89b55a97911f012dfef58f2dea --- /dev/null +++ b/src/webvowl/css/vowl.css @@ -0,0 +1,296 @@ +/*----------------------------------------------------------------- + VOWL graphical elements (part of spec) - mixed CSS and SVG styles +-----------------------------------------------------------------*/ + +/*-------- Text --------*/ +.text { + font-family: Helvetica, Arial, sans-serif; + font-size: 12px; +} + +.subtext { + font-size: 9px; +} + +.text.instance-count { + fill: #666; +} + +.external + text .instance-count { + fill: #aaa; +} + +.cardinality { + font-size: 10px; +} + +.text, .embedded { + pointer-events: none; +} + +/*------- Colors ------*/ +.class, .object, .disjoint, .objectproperty, .disjointwith, .equivalentproperty, .transitiveproperty, .functionalproperty, .inversefunctionalproperty, .symmetricproperty, .allvaluesfromproperty, .somevaluesfromproperty { + fill: #acf; +} + +.label .datatype, .datatypeproperty { + fill: #9c6; +} + +.rdf, .rdfproperty { + fill: #c9c; +} + +.literal, .node .datatype { + fill: #fc3; +} + +.deprecated, .deprecatedproperty { + fill: #ccc; +} + +.external, .externalproperty { + /*fill: #36c;*/ +} + +path, .nofill { + fill: none; +} + +marker path { + fill: #000; +} + +.class, path, line, .fineline { + stroke: #000; +} + +.white, .subclass, .subclassproperty, .external + text { + fill: #fff; +} + +.class.hovered, .property.hovered, .cardinality.hovered, .cardinality.focused, .filled.hovered, .filled.focused, .values-from.filled.hovered { + fill: #f00 !important; + cursor: pointer; +} + +.hoveredForEditing { + fill: #f00 !important; + cursor: pointer; +} + +.feature { + fill: #f00; + cursor: pointer; +} + +@-webkit-keyframes pulseAnimation { + 0% { + -webkit-transform: scale(1.5); + stroke-width: 3.33; + } + 50% { + stroke-width: 4; + } + 100% { + -webkit-transform: scale(1.0); + stroke-width: 5; + } +} + +@-moz-keyframes pulseAnimation { + 0% { + -webkit-transform: scale(1.5); + stroke-width: 3.33; + } + 50% { + stroke-width: 4; + } + 100% { + -webkit-transform: scale(1.0); + stroke-width: 5; + } +} + +@-o-keyframes pulseAnimation { + 0% { + -webkit-transform: scale(1.5); + stroke-width: 3.33; + } + 50% { + stroke-width: 4; + } + 100% { + -webkit-transform: scale(1.0); + stroke-width: 5; + } +} + +@keyframes pulseAnimation { + 0% { + -webkit-transform: scale(1.5); + stroke-width: 3.33; + } + 50% { + stroke-width: 4; + } + 100% { + -webkit-transform: scale(1.0); + stroke-width: 5; + } +} + +.searchResultA { + fill: none; + stroke-width: 5; + stroke: #f00; + -webkit-animation-name: pulseAnimation; + -moz-animation-name: pulseAnimation; + -o-animation-name: pulseAnimation; + animation-name: pulseAnimation; + + -webkit-animation-duration: 0.8s; + -moz-animation-duration: 0.8s; + -o-animation-duration: 0.8s; + animation-duration: 0.8s; + + -webkit-transform: translateZ(0); + -o-transform: translateZ(0); + -webkit-animation-iteration-count: 3; + -moz-animation-iteration-count: 3; + -o-animation-iteration-count: 3; + animation-iteration-count: 3; + + -webkit-animation-timing-function: linear; + -moz-animation-timing-function: linear; + -o-animation-timing-function: linear; + animation-timing-function: linear; + +} + +/* a class for not animated search results (hovered over node)*/ +.searchResultB { + fill: none; + stroke-width: 5; + stroke: #f00; +} + +.hovered-MathSymbol { + fill: none; + stroke: #f00 !important; +} + +.focused, path.hovered { + stroke: #f00 !important; +} + +.indirect-highlighting, .feature:hover { + fill: #f90; + cursor: pointer; +} + +.feature_hover { + fill: #f90; + cursor: pointer; +} + +.values-from { + stroke: #69c; +} + +.symbol, .values-from.filled { + fill: #69c; +} + +/*------- Strokes ------*/ +.class, path, line { + stroke-width: 2; +} + +.fineline { + stroke-width: 1; +} + +.dashed, .anonymous { + stroke-dasharray: 8; +} + +.dotted { + stroke-dasharray: 3; +} + +rect.focused, circle.focused { + stroke-width: 4px; +} + +.nostroke { + stroke: none; +} + +/*----------------------------------------------------------------- + Additional elements for the WebVOWL demo (NOT part of spec) +-----------------------------------------------------------------*/ + +.addDataPropertyElement { + fill: #9c6 !important; + cursor: pointer; + stroke-width: 2; + stroke: black; +} + +.addDataPropertyElement:hover { + fill: #f90 !important; + cursor: pointer; + stroke-width: 2; + stroke: black; +} + +.superHiddenElement { + fill: rgba(255, 153, 0, 0.4); + cursor: pointer; + stroke-width: 0; + stroke: black; + /*opacity:0;*/ +} + +.superOpacityElement { + opacity: 0; +} + +.deleteParentElement:hover { + fill: #f90; + cursor: pointer; + stroke-width: 2; + stroke: black; +} + +.deleteParentElement { + fill: #f00; + cursor: pointer; + stroke-width: 2; + stroke: black; +} + +.classNodeDragPath { + stroke: black; + stroke-width: 2px; +} + +.classDraggerNodeHovered { + fill: #f90; + stroke: black; + stroke-width: 2px; + cursor: pointer; +} + +.classDraggerNode { + fill: #acf; + stroke: black; + stroke-width: 2px; +} + +marker path { + /* Safari and Chrome workaround for inheriting the style of its link. + Use any value that is larger than the length of the marker path. */ + stroke-dasharray: 100; +} diff --git a/src/webvowl/js/classDragger.js b/src/webvowl/js/classDragger.js new file mode 100644 index 0000000000000000000000000000000000000000..6e3eb82de421e815782e529ce93176cec4cbf7f5 --- /dev/null +++ b/src/webvowl/js/classDragger.js @@ -0,0 +1,250 @@ +module.exports = function ( graph ){ + /** variable defs **/ + var Class_dragger = {}; + Class_dragger.nodeId = 10001; + Class_dragger.parent = undefined; + Class_dragger.x = 0; + Class_dragger.y = 0; + Class_dragger.rootElement = undefined; + Class_dragger.rootNodeLayer = undefined; + Class_dragger.pathLayer = undefined; + Class_dragger.mouseEnteredVar = false; + Class_dragger.mouseButtonPressed = false; + Class_dragger.nodeElement = undefined; + Class_dragger.draggerObject = undefined; + Class_dragger.pathElement = undefined; + Class_dragger.typus = "Class_dragger"; + + Class_dragger.type = function (){ + return Class_dragger.typus; + }; + + Class_dragger.parentNode = function (){ + return Class_dragger.parent; + }; + + Class_dragger.hideClass_dragger = function ( val ){ + Class_dragger.pathElement.classed("hidden", val); + Class_dragger.nodeElement.classed("hidden", val); + Class_dragger.draggerObject.classed("hidden", val); + }; + + Class_dragger.setParentNode = function ( parentNode ){ + Class_dragger.parent = parentNode; + + if ( Class_dragger.mouseButtonPressed === false ) { + if ( Class_dragger.parent.actualRadius && Class_dragger.parent.actualRadius() ) { + Class_dragger.x = Class_dragger.parent.x + 10 + Class_dragger.parent.actualRadius(); + Class_dragger.y = Class_dragger.parent.y + 10 + Class_dragger.parent.actualRadius(); + } else { + Class_dragger.x = Class_dragger.parent.x + 60; + Class_dragger.y = Class_dragger.parent.y + 60; + } + } + Class_dragger.updateElement(); + }; + + Class_dragger.hideDragger = function ( val ){ + if ( Class_dragger.pathElement ) Class_dragger.pathElement.classed("hidden", val); + if ( Class_dragger.nodeElement ) Class_dragger.nodeElement.classed("hidden", val); + if ( Class_dragger.draggerObject ) Class_dragger.draggerObject.classed("hidden", val); + + }; + /** BASE HANDLING FUNCTIONS ------------------------------------------------- **/ + Class_dragger.id = function ( index ){ + if ( !arguments.length ) { + return Class_dragger.nodeId; + } + Class_dragger.nodeId = index; + }; + + Class_dragger.svgPathLayer = function ( layer ){ + Class_dragger.pathLayer = layer.append('g'); + }; + + Class_dragger.svgRoot = function ( root ){ + if ( !arguments.length ) + return Class_dragger.rootElement; + Class_dragger.rootElement = root; + Class_dragger.rootNodeLayer = Class_dragger.rootElement.append('g'); + Class_dragger.addMouseEvents(); + }; + + /** DRAWING FUNCTIONS ------------------------------------------------- **/ + Class_dragger.drawNode = function (){ + Class_dragger.pathElement = Class_dragger.pathLayer.append('line') + .classed("classNodeDragPath", true); + Class_dragger.pathElement.attr("x1", 0) + .attr("y1", 0) + .attr("x2", 0) + .attr("y2", 0); + + // var lineData = [ + // {"x": 0, "y": 0}, + // {"x": 0, "y": 40}, + // {"x": -40, "y": 0}, + // {"x": 0, "y": -40}, + // {"x": 0, "y": 0} + // ]; + + var lineData = [ + { "x": -40, "y": 0 }, // start + { "x": -20, "y": -10 }, + { "x": 20, "y": -50 }, + { "x": -10, "y": 0 }, // center + { "x": 20, "y": 50 }, + { "x": -20, "y": 10 }, + { "x": -40, "y": 0 } + ]; + + + var lineFunction = d3.svg.line() + .x(function ( d ){ + return d.x; + }) + .y(function ( d ){ + return d.y; + }) + .interpolate("basis-closed"); + var pathData = "M 20,40 C 0,15 0,-15 20,-40 L -40,0 Z"; + // var pathData="M 20,40 C 0,15 0,-15 20,-40 20,-40 -35.22907,-23.905556 -45.113897,0.06313453 -35.22907,20.095453 20,40 20,40 Z"; + // var pathData="M 39.107144,51.25 C 0,17.362169 0,-13.75 39.285715,-49.821429 c 0,0 -69.58321,34.511175 -100.714286,50.35714329 C -22.96643,20.324376 39.107144,51.25 39.107144,51.25 Z"; + + Class_dragger.nodeElement = Class_dragger.rootNodeLayer.append('path').attr("d", pathData); + Class_dragger.nodeElement.classed("classDraggerNode", true); + Class_dragger.draggerObject = Class_dragger.rootNodeLayer.append("circle"); + if ( graph.options().useAccuracyHelper() ) { + Class_dragger.draggerObject.attr("r", 40) + .attr("cx", 0) + .attr("cy", 0) + .classed("superHiddenElement", true); + Class_dragger.draggerObject.classed("superOpacityElement", !graph.options().showDraggerObject()); + } + + + }; + + Class_dragger.updateElement = function (){ + + // Class_dragger.pathLayer.attr("transform", "translate(" + Class_dragger.x + "," + Class_dragger.y + ")"); + // Class_dragger.rootElement.attr("transform", "translate(" + Class_dragger.x + "," + Class_dragger.y + ")"); + if ( Class_dragger.pathElement ) { + + // compute start point ; + + + var sX = Class_dragger.parent.x, + sY = Class_dragger.parent.y, + eX = Class_dragger.x, + eY = Class_dragger.y; + + + // this is used only when you dont have a proper layout ordering; + var dirX = eX - sX; + var dirY = eY - sY; + var len = Math.sqrt((dirX * dirX) + (dirY * dirY)); + + var nX = dirX / len; + var nY = dirY / len; + + var ppX = sX + nX * Class_dragger.parent.actualRadius(); + var ppY = sY + nY * Class_dragger.parent.actualRadius(); + + var ncx = nX * 15; + var ncy = nY * 15; + Class_dragger.draggerObject.attr("cx", ncx) + .attr("cy", ncy); + + Class_dragger.pathElement.attr("x1", ppX) + .attr("y1", ppY) + .attr("x2", eX) + .attr("y2", eY); + } + var angle = Math.atan2(Class_dragger.parent.y - Class_dragger.y, Class_dragger.parent.x - Class_dragger.x) * 180 / Math.PI; + + Class_dragger.nodeElement.attr("transform", "translate(" + Class_dragger.x + "," + Class_dragger.y + ")" + "rotate(" + angle + ")"); + Class_dragger.draggerObject.attr("transform", "translate(" + Class_dragger.x + "," + Class_dragger.y + ")"); + // console.log("update Elmenent root element"+Class_dragger.x + "," + Class_dragger.y ); + // + // Class_dragger.nodeElement.attr("transform", function (d) { + // return "rotate(" + angle + ")"; + // }); + }; + + /** MOUSE HANDLING FUNCTIONS ------------------------------------------------- **/ + + Class_dragger.addMouseEvents = function (){ + // console.log("adding mouse events"); + Class_dragger.rootNodeLayer.selectAll("*").on("mouseover", Class_dragger.onMouseOver) + .on("mouseout", Class_dragger.onMouseOut) + .on("click", function (){ + }) + .on("dblclick", function (){ + }) + .on("mousedown", Class_dragger.mouseDown) + .on("mouseup", Class_dragger.mouseUp); + }; + + Class_dragger.mouseDown = function (){ + Class_dragger.nodeElement.style("cursor", "move"); + Class_dragger.nodeElement.classed("classDraggerNodeHovered", true); + Class_dragger.mouseButtonPressed = true; + console.log("Mouse DOWN from Dragger"); + }; + + Class_dragger.mouseUp = function (){ + Class_dragger.nodeElement.style("cursor", "auto"); + Class_dragger.mouseButtonPressed = false; + console.log("Mouse UP from Dragger"); + }; + + + Class_dragger.mouseEntered = function ( p ){ + if ( !arguments.length ) return Class_dragger.mouseEnteredVar; + Class_dragger.mouseEnteredVar = p; + return Class_dragger; + }; + + Class_dragger.selectedViaTouch = function ( val ){ + Class_dragger.nodeElement.classed("classDraggerNode", !val); + Class_dragger.nodeElement.classed("classDraggerNodeHovered", val); + + }; + + Class_dragger.onMouseOver = function (){ + if ( Class_dragger.mouseEntered() ) { + return; + } + Class_dragger.nodeElement.classed("classDraggerNode", false); + Class_dragger.nodeElement.classed("classDraggerNodeHovered", true); + var selectedNode = Class_dragger.rootElement.node(), + nodeContainer = selectedNode.parentNode; + nodeContainer.appendChild(selectedNode); + + Class_dragger.mouseEntered(true); + + }; + Class_dragger.onMouseOut = function (){ + if ( Class_dragger.mouseButtonPressed === true ) + return; + Class_dragger.nodeElement.classed("classDraggerNodeHovered", false); + Class_dragger.nodeElement.classed("classDraggerNode", true); + Class_dragger.mouseEntered(false); + }; + + Class_dragger.setPosition = function ( x, y ){ + + Class_dragger.x = x; + Class_dragger.y = y; + Class_dragger.updateElement(); + }; + + Class_dragger.setAdditionalClassForClass_dragger = function ( name, val ){ + // console.log("Class_dragger should sett the class here") + // Class_dragger.nodeElement.classed(name,val); + + }; + return Class_dragger; +}; + + diff --git a/src/webvowl/js/domainDragger.js b/src/webvowl/js/domainDragger.js new file mode 100644 index 0000000000000000000000000000000000000000..91bc4b2d274fe7e345ac4884e970390c50e3e05f --- /dev/null +++ b/src/webvowl/js/domainDragger.js @@ -0,0 +1,335 @@ +module.exports = function ( graph ){ + /** variable defs **/ + var Domain_dragger = {}; + Domain_dragger.nodeId = 10002; + Domain_dragger.parent = undefined; + Domain_dragger.x = 0; + Domain_dragger.y = 0; + Domain_dragger.rootElement = undefined; + Domain_dragger.rootNodeLayer = undefined; + Domain_dragger.pathLayer = undefined; + Domain_dragger.mouseEnteredVar = false; + Domain_dragger.mouseButtonPressed = false; + Domain_dragger.nodeElement = undefined; + Domain_dragger.draggerObject = undefined; + + Domain_dragger.pathElement = undefined; + Domain_dragger.typus = "Domain_dragger"; + + Domain_dragger.type = function (){ + return Domain_dragger.typus; + }; + + + // TODO: We need the endPoint of the Link here! + Domain_dragger.parentNode = function (){ + return Domain_dragger.parent; + }; + + Domain_dragger.hide_dragger = function ( val ){ + Domain_dragger.pathElement.classed("hidden", val); + Domain_dragger.nodeElement.classed("hidden", val); + Domain_dragger.draggerObject.classed("hidden", val); + }; + + Domain_dragger.reDrawEverthing = function (){ + Domain_dragger.setParentProperty(Domain_dragger.parent); + }; + Domain_dragger.updateDomain = function ( newDomain ){ + + if ( graph.genericPropertySanityCheck(Domain_dragger.parent.range(), newDomain, Domain_dragger.parent.type(), + "Could not update domain", "Restoring previous domain") === false ) { + Domain_dragger.updateElement(); + return; + } + + if ( graph.propertyCheckExistenceChecker(Domain_dragger.parent, newDomain, Domain_dragger.parent.range()) === false ) + return; + + + if ( Domain_dragger.parent.labelElement() === undefined ) { + Domain_dragger.updateElement(); + return; + } + if ( Domain_dragger.parent.labelElement().attr("transform") === "translate(0,15)" || + Domain_dragger.parent.labelElement().attr("transform") === "translate(0,-15)" ) { + var prop = Domain_dragger.parent; + Domain_dragger.parent.inverse().inverse(null); + Domain_dragger.parent.inverse(null); + console.log("SPLITTING ITEMS!"); + prop.domain(newDomain); + } + else { + Domain_dragger.parent.domain(newDomain); + } + + // update the position of the new range + var rX = Domain_dragger.parent.range().x; + var rY = Domain_dragger.parent.range().y; + var dX = newDomain.x; + var dY = newDomain.y; + + // center + var cX = 0.49 * (dX + rX); + var cY = 0.49 * (dY + rY); + // put position there; + Domain_dragger.parent.labelObject().x = cX; + Domain_dragger.parent.labelObject().px = cX; + Domain_dragger.parent.labelObject().y = cY; + Domain_dragger.parent.labelObject().py = cY; + Domain_dragger.updateElement(); + + }; + + Domain_dragger.setParentProperty = function ( parentProperty, inverted ){ + Domain_dragger.invertedProperty = inverted; + var renElem; + var iP; + Domain_dragger.isLoopProperty = false; + if ( parentProperty.domain() === parentProperty.range() ) + Domain_dragger.isLoopProperty = true; + + Domain_dragger.parent = parentProperty; + renElem = parentProperty.labelObject(); + if ( inverted === true ) { + + // this is the lower element + if ( parentProperty.labelElement() && parentProperty.labelElement().attr("transform") === "translate(0,15)" ) { + // console.log("This is the lower element!"); + iP = renElem.linkRangeIntersection; + if ( renElem.linkRangeIntersection ) { + Domain_dragger.x = iP.x; + Domain_dragger.y = iP.y; + } + } + else { + // console.log("This is the upper element"); + iP = renElem.linkDomainIntersection; + if ( renElem.linkDomainIntersection ) { + Domain_dragger.x = iP.x; + Domain_dragger.y = iP.y; + } + } + } + else { + // console.log("This is single element"); + iP = renElem.linkDomainIntersection; + if ( renElem.linkDomainIntersection ) { + Domain_dragger.x = iP.x; + Domain_dragger.y = iP.y; + } + } + Domain_dragger.updateElement(); + + }; + + Domain_dragger.hideDragger = function ( val ){ + if ( Domain_dragger.pathElement ) Domain_dragger.pathElement.classed("hidden", val); + if ( Domain_dragger.nodeElement ) Domain_dragger.nodeElement.classed("hidden", val); + if ( Domain_dragger.draggerObject ) Domain_dragger.draggerObject.classed("hidden", val); + + + }; + /** BASE HANDLING FUNCTIONS ------------------------------------------------- **/ + Domain_dragger.id = function ( index ){ + if ( !arguments.length ) { + return Domain_dragger.nodeId; + } + Domain_dragger.nodeId = index; + }; + + Domain_dragger.svgPathLayer = function ( layer ){ + Domain_dragger.pathLayer = layer.append('g'); + }; + + Domain_dragger.svgRoot = function ( root ){ + if ( !arguments.length ) + return Domain_dragger.rootElement; + Domain_dragger.rootElement = root; + Domain_dragger.rootNodeLayer = Domain_dragger.rootElement.append('g'); + Domain_dragger.addMouseEvents(); + }; + + /** DRAWING FUNCTIONS ------------------------------------------------- **/ + Domain_dragger.drawNode = function (){ + Domain_dragger.pathElement = Domain_dragger.pathLayer.append('line') + .classed("classNodeDragPath", true); + Domain_dragger.pathElement.attr("x1", 0) + .attr("y1", 0) + .attr("x2", 0) + .attr("y2", 0); + + var pathData = "M 10,40 C -10,15 -10,-15 10,-40 -8.8233455,-13.641384 -36.711107,-5.1228436 -50,0 -36.696429,4.9079017 -8.6403157,13.745728 10,40 Z"; + Domain_dragger.nodeElement = Domain_dragger.rootNodeLayer.append('path').attr("d", pathData); + Domain_dragger.nodeElement.classed("classDraggerNode", true); + if ( graph.options().useAccuracyHelper() ) { + Domain_dragger.draggerObject = Domain_dragger.rootNodeLayer.append("circle"); + Domain_dragger.draggerObject.attr("r", 40) + .attr("cx", 0) + .attr("cy", 0) + .classed("superHiddenElement", true); + Domain_dragger.draggerObject.classed("superOpacityElement", !graph.options().showDraggerObject()); + } + + + }; + Domain_dragger.updateElementViaRangeDragger = function ( x, y ){ + var range_x = x; + var range_y = y; + + var dex = Domain_dragger.parent.domain().x; + var dey = Domain_dragger.parent.domain().y; + + var dir_X = x - dex; + var dir_Y = y - dey; + + var len = Math.sqrt(dir_X * dir_X + dir_Y * dir_Y); + + var nX = dir_X / len; + var nY = dir_Y / len; + + + var ep_range_x = dex + nX * Domain_dragger.parent.domain().actualRadius(); + var ep_range_y = dey + nY * Domain_dragger.parent.domain().actualRadius(); + + var angle = Math.atan2(ep_range_y - range_y, ep_range_x - range_x) * 180 / Math.PI; + + Domain_dragger.nodeElement.attr("transform", "translate(" + ep_range_x + "," + ep_range_y + ")" + "rotate(" + angle + ")"); + var dox = ep_range_x + nX * 20; + var doy = ep_range_y + nY * 20; + Domain_dragger.draggerObject.attr("transform", "translate(" + dox + "," + doy + ")"); + }; + + + Domain_dragger.updateElement = function (){ + if ( Domain_dragger.mouseButtonPressed === true || Domain_dragger.parent === undefined ) return; + + var domain = Domain_dragger.parent.domain(); + var iP = Domain_dragger.parent.labelObject().linkDomainIntersection; + if ( Domain_dragger.parent.labelElement() === undefined ) return; + if ( Domain_dragger.parent.labelElement().attr("transform") === "translate(0,15)" ) { + Domain_dragger.parent.inverse().domain(); + iP = Domain_dragger.parent.labelObject().linkRangeIntersection; + + } + var range_x = domain.x; + var range_y = domain.y; + + + if ( iP === undefined ) return; + var ep_range_x = iP.x; + var ep_range_y = iP.y; + + var dx = range_x - ep_range_x; + var dy = range_y - ep_range_y; + var len = Math.sqrt(dx * dx + dy * dy); + + var nX = dx / len; + var nY = dy / len; + + var dox = ep_range_x - nX * 20; + var doy = ep_range_y - nY * 20; + var angle = Math.atan2(ep_range_y - range_y, ep_range_x - range_x) * 180 / Math.PI + 180; + + Domain_dragger.nodeElement.attr("transform", "translate(" + ep_range_x + "," + ep_range_y + ")" + "rotate(" + angle + ")"); + Domain_dragger.draggerObject.attr("transform", "translate(" + dox + "," + doy + ")"); + }; + + /** MOUSE HANDLING FUNCTIONS ------------------------------------------------- **/ + + Domain_dragger.addMouseEvents = function (){ + var rootLayer = Domain_dragger.rootNodeLayer.selectAll("*"); + rootLayer.on("mouseover", Domain_dragger.onMouseOver) + .on("mouseout", Domain_dragger.onMouseOut) + .on("click", function (){ + }) + .on("dblclick", function (){ + }) + .on("mousedown", Domain_dragger.mouseDown) + .on("mouseup", Domain_dragger.mouseUp); + }; + + Domain_dragger.mouseDown = function (){ + Domain_dragger.nodeElement.style("cursor", "move"); + Domain_dragger.nodeElement.classed("classDraggerNodeHovered", true); + Domain_dragger.mouseButtonPressed = true; + }; + + Domain_dragger.mouseUp = function (){ + Domain_dragger.nodeElement.style("cursor", "auto"); + Domain_dragger.nodeElement.classed("classDraggerNodeHovered", false); + Domain_dragger.mouseButtonPressed = false; + }; + + + Domain_dragger.mouseEntered = function ( p ){ + if ( !arguments.length ) return Domain_dragger.mouseEnteredVar; + Domain_dragger.mouseEnteredVar = p; + return Domain_dragger; + }; + + Domain_dragger.selectedViaTouch = function ( val ){ + Domain_dragger.nodeElement.classed("classDraggerNode", !val); + Domain_dragger.nodeElement.classed("classDraggerNodeHovered", val); + + }; + + Domain_dragger.onMouseOver = function (){ + if ( Domain_dragger.mouseEntered() ) { + return; + } + Domain_dragger.nodeElement.classed("classDraggerNode", false); + Domain_dragger.nodeElement.classed("classDraggerNodeHovered", true); + var selectedNode = Domain_dragger.rootElement.node(), + nodeContainer = selectedNode.parentNode; + nodeContainer.appendChild(selectedNode); + + Domain_dragger.mouseEntered(true); + + }; + Domain_dragger.onMouseOut = function (){ + if ( Domain_dragger.mouseButtonPressed === true ) + return; + Domain_dragger.nodeElement.classed("classDraggerNodeHovered", false); + Domain_dragger.nodeElement.classed("classDraggerNode", true); + Domain_dragger.mouseEntered(false); + }; + + Domain_dragger.setPosition = function ( x, y ){ + var range_x = Domain_dragger.parent.range().x; + var range_y = Domain_dragger.parent.range().y; + + // var position of the rangeEndPoint + var ep_range_x = x; + var ep_range_y = y; + + // offset for dragger object + var dx = range_x - ep_range_x; + var dy = range_y - ep_range_y; + + var len = Math.sqrt(dx * dx + dy * dy); + + var nX = dx / len; + var nY = dy / len; + var dox = ep_range_x + nX * 20; + var doy = ep_range_y + nY * 20; + + var angle = Math.atan2(range_y - ep_range_y, range_x - ep_range_x) * 180 / Math.PI + 180; + + Domain_dragger.nodeElement.attr("transform", "translate(" + ep_range_x + "," + ep_range_y + ")" + "rotate(" + angle + ")"); + Domain_dragger.draggerObject.attr("transform", "translate(" + dox + "," + doy + ")"); + + Domain_dragger.x = x; + Domain_dragger.y = y; + + }; + + Domain_dragger.setAdditionalClassForClass_dragger = function ( name, val ){ + // console.log("Class_dragger should sett the class here") + // Class_dragger.nodeElement.classed(name,val); + + }; + return Domain_dragger; +}; + + diff --git a/src/webvowl/js/elements/BaseElement.js b/src/webvowl/js/elements/BaseElement.js new file mode 100644 index 0000000000000000000000000000000000000000..a1c52647f273632f5623565a6d68fb3fe4e57578 --- /dev/null +++ b/src/webvowl/js/elements/BaseElement.js @@ -0,0 +1,193 @@ +/** + * The base element for all visual elements of webvowl. + */ +module.exports = (function (){ + + var Base = function ( graph ){ + // Basic attributes + var equivalents = [], + id, + label, + type, + iri, + baseIri, + // Additional attributes + annotations, + attributes = [], + backgroundColor, + comment, + description, + equivalentBase, + visualAttributes = [], + // Style attributes + focused = false, + indications = [], + mouseEntered = false, + styleClass, + visible = true, + + backupLabel, + // Other + languageTools = require("../util/languageTools")(); + + + this.backupLabel = function ( label ){ + if ( !arguments.length ) return backupLabel; + backupLabel = label; + }; + // Properties + this.attributes = function ( p ){ + if ( !arguments.length ) return attributes; + attributes = p; + return this; + }; + + this.annotations = function ( p ){ + if ( !arguments.length ) return annotations; + annotations = p; + return this; + }; + + this.redrawElement = function (){ + // TODO: OVERLOADED BY INDIVIDUAL ELEMENTS + }; + + this.backgroundColor = function ( p ){ + if ( !arguments.length ) return backgroundColor; + backgroundColor = p; + return this; + }; + + this.baseIri = function ( p ){ + if ( !arguments.length ) return baseIri; + baseIri = p; + return this; + }; + + this.comment = function ( p ){ + if ( !arguments.length ) return comment; + comment = p; + return this; + }; + + this.description = function ( p ){ + if ( !arguments.length ) return description; + description = p; + return this; + }; + + this.equivalents = function ( p ){ + if ( !arguments.length ) return equivalents; + equivalents = p || []; + return this; + }; + + this.equivalentBase = function ( p ){ + if ( !arguments.length ) return equivalentBase; + equivalentBase = p; + return this; + }; + + this.focused = function ( p ){ + if ( !arguments.length ) return focused; + focused = p; + return this; + }; + + this.id = function ( p ){ + if ( !arguments.length ) return id; + id = p; + return this; + }; + + this.indications = function ( p ){ + if ( !arguments.length ) return indications; + indications = p; + return this; + }; + + this.iri = function ( p ){ + if ( !arguments.length ) return iri; + iri = p; + return this; + }; + + this.label = function ( p ){ + if ( !arguments.length ) return label; + label = p; + return this; + }; + + this.mouseEntered = function ( p ){ + if ( !arguments.length ) return mouseEntered; + mouseEntered = p; + return this; + }; + + this.styleClass = function ( p ){ + if ( !arguments.length ) return styleClass; + styleClass = p; + return this; + }; + + this.type = function ( p ){ + if ( !arguments.length ) return type; + type = p; + return this; + }; + + this.visible = function ( p ){ + if ( !arguments.length ) return visible; + visible = p; + return this; + }; + + this.visualAttributes = function ( p ){ + if ( !arguments.length ) return visualAttributes; + visualAttributes = p; + return this; + }; + + + this.commentForCurrentLanguage = function (){ + return languageTools.textInLanguage(this.comment(), graph.language()); + }; + + /** + * @returns {string} the css class of this node.. + */ + this.cssClassOfNode = function (){ + return "node" + this.id(); + }; + + this.descriptionForCurrentLanguage = function (){ + return languageTools.textInLanguage(this.description(), graph.language()); + }; + + this.defaultLabel = function (){ + return languageTools.textInLanguage(this.label(), "default"); + }; + + this.indicationString = function (){ + return this.indications().join(", "); + }; + + this.labelForCurrentLanguage = function (){ + var preferredLanguage = graph && graph.language ? graph.language() : null; + return languageTools.textInLanguage(this.label(), preferredLanguage); + }; + }; + + Base.prototype.constructor = Base; + + Base.prototype.equals = function ( other ){ + return other instanceof Base && this.id() === other.id(); + }; + + Base.prototype.toString = function (){ + return this.labelForCurrentLanguage() + " (" + this.type() + ")"; + }; + + + return Base; +}()); diff --git a/src/webvowl/js/elements/drawTools.js b/src/webvowl/js/elements/drawTools.js new file mode 100644 index 0000000000000000000000000000000000000000..f17503783b9365deea86e1a07541defafd14f998 --- /dev/null +++ b/src/webvowl/js/elements/drawTools.js @@ -0,0 +1,204 @@ +/** + * Contains reusable function for drawing nodes. + */ +module.exports = (function (){ + + var tools = {}; + + /** + * Append a circular class node with the passed attributes. + * @param parent the parent element to which the circle will be appended + * @param radius + * @param [cssClasses] an array of additional css classes + * @param [tooltip] + * @param [backgroundColor] + * @returns {*} + */ + tools.appendCircularClass = function ( parent, radius, cssClasses, tooltip, backgroundColor ){ + var circle = parent.append("circle") + .classed("class", true) + .attr("r", radius); + + addCssClasses(circle, cssClasses); + addToolTip(circle, tooltip); + addBackgroundColor(circle, backgroundColor); + + return circle; + }; + + function addCssClasses( element, cssClasses ){ + if ( cssClasses instanceof Array ) { + cssClasses.forEach(function ( cssClass ){ + element.classed(cssClass, true); + }); + } + } + + function addToolTip( element, tooltip ){ + if ( tooltip ) { + element.append("title").text(tooltip); + } + } + + function addBackgroundColor( element, backgroundColor ){ + if ( backgroundColor ) { + element.style("fill", backgroundColor); + } + } + + /** + * Appends a rectangular class node with the passed attributes. + * @param parent the parent element to which the rectangle will be appended + * @param width + * @param height + * @param [cssClasses] an array of additional css classes + * @param [tooltip] + * @param [backgroundColor] + * @returns {*} + */ + tools.appendRectangularClass = function ( parent, width, height, cssClasses, tooltip, backgroundColor ){ + var rectangle = parent.append("rect") + .classed("class", true) + .attr("x", -width / 2) + .attr("y", -height / 2) + .attr("width", width) + .attr("height", height); + + addCssClasses(rectangle, cssClasses); + addToolTip(rectangle, tooltip); + addBackgroundColor(rectangle, backgroundColor); + + return rectangle; + }; + + tools.drawPin = function ( container, dx, dy, onClick, accuraciesHelperFunction, useAccuracyHelper ){ + var pinGroupElement = container + .append("g") + .classed("hidden-in-export", true) + .attr("transform", "translate(" + dx + "," + dy + ")"); + + var base = pinGroupElement.append("circle") + .classed("class pin feature", true) + .attr("r", 12) + .on("click", function (){ + if ( onClick ) { + onClick(); + } + d3.event.stopPropagation(); + }); + + pinGroupElement.append("line") + .attr("x1", 0) + .attr("x2", 0) + .attr("y1", 12) + .attr("y2", 16); + + if ( useAccuracyHelper === true ) { + pinGroupElement.append("circle") + .attr("r", 15) + .attr("cx", -7) + .attr("cy", -7) + .classed("superHiddenElement ", true) + .classed("superOpacityElement", !accuraciesHelperFunction()) + .on("click", function (){ + if ( onClick ) { + onClick(); + } + d3.event.stopPropagation(); + }) + .on("mouseover", function (){ + base.classed("feature_hover", true); + }) + .on("mouseout", function (){ + base.classed("feature_hover", false); + }) + ; + + } + + + return pinGroupElement; + }; + + tools.drawRectHalo = function ( node, width, height, offset ){ + var container; + if ( node.nodeElement ) + container = node.nodeElement(); + else + container = node.labelElement(); + + if ( !container ) { + // console.log("no container found"); + return; + } + + var haloGroupElement = container + .append("g") + .classed("hidden-in-export", true); + + haloGroupElement.append("rect") + .classed("searchResultA", true) + .attr("x", (-width - offset) / 2) + .attr("y", (-offset - height) / 2) + .attr("width", width + offset) + .attr("height", height + offset); + haloGroupElement.attr("animationRunning", true); + + haloGroupElement.node().addEventListener("webkitAnimationEnd", function (){ + var test = haloGroupElement.selectAll(".searchResultA"); + test.classed("searchResultA", false) + .classed("searchResultB", true); + haloGroupElement.attr("animationRunning", false); + }); + haloGroupElement.node().addEventListener("animationend", function (){ + var test = haloGroupElement.selectAll(".searchResultA"); + test.classed("searchResultA", false) + .classed("searchResultB", true); + haloGroupElement.attr("animationRunning", false); + }); + + + return haloGroupElement; + + }; + tools.drawHalo = function ( container, radius ){ + if ( container === undefined ) { + return null; + // there is no element to add the halo to; + // this means the node was not rendered previously + } + + var haloGroupElement = container + .append("g") + .classed("hidden-in-export", true); + + + haloGroupElement.append("circle", ":first-child") + .classed("searchResultA", true) + .attr("r", radius + 15); + haloGroupElement.attr("animationRunning", true); + + + haloGroupElement.node().addEventListener("webkitAnimationEnd", function (){ + var test = haloGroupElement.selectAll(".searchResultA"); + test.classed("searchResultA", false) + .classed("searchResultB", true) + .attr("animationRunning", false); + haloGroupElement.attr("animationRunning", false); + }); + haloGroupElement.node().addEventListener("animationend", function (){ + var test = haloGroupElement.selectAll(".searchResultA"); + test.classed("searchResultA", false) + .classed("searchResultB", true) + .attr("animationRunning", false); + haloGroupElement.attr("animationRunning", false); + }); + + return haloGroupElement; + }; + + return function (){ + // Encapsulate into function to maintain default.module.path() + return tools; + }; +})(); diff --git a/src/webvowl/js/elements/forceLayoutNodeFunctions.js b/src/webvowl/js/elements/forceLayoutNodeFunctions.js new file mode 100644 index 0000000000000000000000000000000000000000..78988d35b31538834de3312ed3365012a7fd49ff --- /dev/null +++ b/src/webvowl/js/elements/forceLayoutNodeFunctions.js @@ -0,0 +1,69 @@ +/** + * The functions for controlling attributes of nodes of the force layout can't be modelled to the element hierarchy, + * which is used for inheriting visual and OWL-like attributes. + * + * To reduce code redundancy the common functions for controlling the force layout node attributes are excluded into this + * module, which can add them to the node objects. + * + * @type {{}} + */ +var nodeFunctions = {}; +module.exports = function (){ + return nodeFunctions; +}; + + +nodeFunctions.addTo = function ( node ){ + addFixedLocationFunctions(node); +}; + +function addFixedLocationFunctions( node ){ + var locked = false, + frozen = false, + halo = false, + pinned = false; + + node.locked = function ( p ){ + if ( !arguments.length ) { + return locked; + } + locked = p; + applyFixedLocationAttributes(); + return node; + }; + + node.frozen = function ( p ){ + if ( !arguments.length ) { + return frozen; + } + frozen = p; + applyFixedLocationAttributes(); + return node; + }; + + node.halo = function ( p ){ + if ( !arguments.length ) { + return halo; + } + halo = p; + applyFixedLocationAttributes(); + return node; + }; + + node.pinned = function ( p ){ + if ( !arguments.length ) { + return pinned; + } + pinned = p; + applyFixedLocationAttributes(); + return node; + }; + + function applyFixedLocationAttributes(){ + if ( node.locked() || node.frozen() || node.pinned() ) { + node.fixed = true; + } else { + node.fixed = false; + } + } +} diff --git a/src/webvowl/js/elements/links/ArrowLink.js b/src/webvowl/js/elements/links/ArrowLink.js new file mode 100644 index 0000000000000000000000000000000000000000..9c59f73143750145ac8940dae000c7d99e99358c --- /dev/null +++ b/src/webvowl/js/elements/links/ArrowLink.js @@ -0,0 +1,71 @@ +var PlainLink = require("./PlainLink"); + + +module.exports = ArrowLink; + +function ArrowLink( domain, range, property ){ + PlainLink.apply(this, arguments); +} + +ArrowLink.prototype = Object.create(PlainLink.prototype); +ArrowLink.prototype.constructor = ArrowLink; + + +ArrowLink.prototype.draw = function ( linkGroup, markerContainer ){ + var property = this.label().property(); + var inverse = this.label().inverse(); + + createPropertyMarker(markerContainer, property); + if ( inverse ) { + createInverseMarker(markerContainer, inverse); + } + + PlainLink.prototype.draw.apply(this, arguments); + + // attach the markers to the link + linkGroup.attr("marker-end", "url(#" + property.markerId() + ")"); + if ( inverse ) { + linkGroup.attr("marker-start", "url(#" + inverse.markerId() + ")"); + } +}; + +function createPropertyMarker( markerContainer, property ){ + var marker = appendBasicMarker(markerContainer, property); + //marker.attr("refX", 12); + var m1X = -12; + var m1Y = 8; + var m2X = -12; + var m2Y = -8; + marker.append("path") + //.attr("d", "M0,-8L12,0L0,8Z") + .attr("d", "M0,0L " + m1X + "," + m1Y + "L" + m2X + "," + m2Y + "L" + 0 + "," + 0) + .classed(property.markerType(), true); + + property.markerElement(marker); +} + +function createInverseMarker( markerContainer, inverse ){ + var m1X = -12; + var m1Y = 8; + var m2X = -12; + var m2Y = -8; + var inverseMarker = appendBasicMarker(markerContainer, inverse); + inverseMarker.append("path") + //.attr("d", "M12,-8L0,0L12,8Z") + .attr("d", "M0,0L " + -m1X + "," + -m1Y + "L" + -m2X + "," + -m2Y + "L" + 0 + "," + 0) + .classed(inverse.markerType(), true); + + inverse.markerElement(inverseMarker); +} + +function appendBasicMarker( markerContainer, property ){ + return markerContainer.append("marker") + .datum(property) + .attr("id", property.markerId()) + + .attr("viewBox", "-14 -10 28 20") + .attr("markerWidth", 10) + .attr("markerHeight", 10) + //.attr("markerUnits", "userSpaceOnUse") + .attr("orient", "auto"); +} diff --git a/src/webvowl/js/elements/links/BoxArrowLink.js b/src/webvowl/js/elements/links/BoxArrowLink.js new file mode 100644 index 0000000000000000000000000000000000000000..6005c18e0be9d0b10bf9e7a086ffae95b7f1a89c --- /dev/null +++ b/src/webvowl/js/elements/links/BoxArrowLink.js @@ -0,0 +1,62 @@ +var PlainLink = require("./PlainLink"); + + +module.exports = BoxArrowLink; + +function BoxArrowLink( domain, range, property ){ + PlainLink.apply(this, arguments); +} + +BoxArrowLink.prototype = Object.create(PlainLink.prototype); +BoxArrowLink.prototype.constructor = BoxArrowLink; + + +BoxArrowLink.prototype.draw = function ( linkGroup, markerContainer ){ + var property = this.label().property(); + var inverse = this.label().inverse(); + + createPropertyMarker(markerContainer, property); + if ( inverse ) { + createInverseMarker(markerContainer, inverse); + } + + PlainLink.prototype.draw.apply(this, arguments); + + // attach the markers to the link + linkGroup.attr("marker-start", "url(#" + property.markerId() + ")"); + if ( inverse ) { + linkGroup.attr("marker-end", "url(#" + inverse.markerId() + ")"); + } +}; + + +function createPropertyMarker( markerContainer, inverse ){ + var inverseMarker = appendBasicMarker(markerContainer, inverse); + inverseMarker.attr("refX", -8); + inverseMarker.append("path") + .attr("d", "M0,-8L8,0L0,8L-8,0L0,-8L8,0") + .classed(inverse.markerType(), true); + + inverse.markerElement(inverseMarker); +} + +function createInverseMarker( markerContainer, property ){ + var marker = appendBasicMarker(markerContainer, property); + marker.attr("refX", 8); + marker.append("path") + .attr("d", "M0,-8L8,0L0,8L-8,0L0,-8L8,0") + .classed(property.markerType(), true); + + property.markerElement(marker); +} + +function appendBasicMarker( markerContainer, property ){ + return markerContainer.append("marker") + .datum(property) + .attr("id", property.markerId()) + .attr("viewBox", "-10 -10 20 20") + .attr("markerWidth", 20) + .attr("markerHeight", 20) + .attr("markerUnits", "userSpaceOnUse") + .attr("orient", "auto"); +} diff --git a/src/webvowl/js/elements/links/Label.js b/src/webvowl/js/elements/links/Label.js new file mode 100644 index 0000000000000000000000000000000000000000..2968ae16b12947c3635898867a0e97a53c8e43d2 --- /dev/null +++ b/src/webvowl/js/elements/links/Label.js @@ -0,0 +1,62 @@ +module.exports = Label; + +/** + * A label represents the element(s) which further describe a link. + * It encapsulates the property and its inverse property. + * @param property the property; the inverse is inferred + * @param link the link this label belongs to + */ +function Label( property, link ){ + this.link = function (){ + return link; + }; + + this.property = function (){ + return property; + }; + + // "Forward" the fixed value set on the property to avoid having to access this container + Object.defineProperty(this, "fixed", { + get: function (){ + var inverseFixed = property.inverse() ? property.inverse().fixed : false; + return property.fixed || inverseFixed; + }, + set: function ( v ){ + property.fixed = v; + if ( property.inverse() ) property.inverse().fixed = v; + } + }); + this.frozen = property.frozen; + this.locked = property.locked; + this.pinned = property.pinned; +} + +Label.prototype.actualRadius = function (){ + return this.property().actualRadius(); +}; + +Label.prototype.draw = function ( container ){ + return this.property().draw(container); +}; + +Label.prototype.inverse = function (){ + return this.property().inverse(); +}; + +Label.prototype.equals = function ( other ){ + if ( !other ) { + return false; + } + + var instance = other instanceof Label; + var equalProperty = this.property().equals(other.property()); + + var equalInverse = false; + if ( this.inverse() ) { + equalInverse = this.inverse().equals(other.inverse()); + } else if ( !other.inverse() ) { + equalInverse = true; + } + + return instance && equalProperty && equalInverse; +}; diff --git a/src/webvowl/js/elements/links/PlainLink.js b/src/webvowl/js/elements/links/PlainLink.js new file mode 100644 index 0000000000000000000000000000000000000000..44c543de264f90e97947a7887b3fdaa2987bc9e6 --- /dev/null +++ b/src/webvowl/js/elements/links/PlainLink.js @@ -0,0 +1,104 @@ +var Label = require("./Label"); + + +module.exports = PlainLink; + +/** + * A link connects at least two VOWL nodes. + * The properties connecting the VOWL nodes are stored separately into the label. + * @param domain + * @param range + * @param property + */ +function PlainLink( domain, range, property ){ + var layers, + layerIndex, + loops, + loopIndex, + pathEl, + label = new Label(property, this); + + var backPart = require("./linkPart")(domain, label, this), + frontPart = require("./linkPart")(label, range, this); + + + this.layers = function ( p ){ + if ( !arguments.length ) return layers; + layers = p; + return this; + }; + + this.layerIndex = function ( p ){ + if ( !arguments.length ) return layerIndex; + layerIndex = p; + return this; + }; + + this.loops = function ( p ){ + if ( !arguments.length ) return loops; + loops = p; + return this; + }; + + this.loopIndex = function ( p ){ + if ( !arguments.length ) return loopIndex; + loopIndex = p; + return this; + }; + + + this.domain = function (){ + return domain; + }; + + this.label = function (){ + return label; + }; + + this.linkParts = function (){ + return [frontPart, backPart]; + }; + + this.range = function (){ + return range; + }; + this.pathObj = function ( pE ){ + if ( !arguments.length ) { + return pathEl; + } + pathEl = pE; + }; +} + + +PlainLink.prototype.draw = function ( linkGroup ){ + var property = this.label().property(); + var inverse = this.label().inverse(); + + property.linkGroup(linkGroup); + if ( inverse ) { + inverse.linkGroup(linkGroup); + } + + var pathElement = linkGroup.append("path"); + pathElement.classed("link-path", true) + .classed(this.domain().cssClassOfNode(), true) + .classed(this.range().cssClassOfNode(), true) + .classed(property.linkType(), true); + this.pathObj(pathElement); + +}; + + +PlainLink.prototype.inverse = function (){ + return this.label().inverse(); +}; + +PlainLink.prototype.isLoop = function (){ + return this.domain().equals(this.range()); +}; + +PlainLink.prototype.property = function (){ + return this.label().property(); +}; + diff --git a/src/webvowl/js/elements/links/linkPart.js b/src/webvowl/js/elements/links/linkPart.js new file mode 100644 index 0000000000000000000000000000000000000000..decbe9ed8c346693f9978fcaf5286ff63c29b710 --- /dev/null +++ b/src/webvowl/js/elements/links/linkPart.js @@ -0,0 +1,35 @@ +/** + * A linkPart connects two force layout nodes. + * It reprents a link which can be used in d3's force layout. + * @param _domain + * @param _range + * @param _link + */ +module.exports = function ( _domain, _range, _link ){ + var linkPart = {}, + domain = _domain, + link = _link, + range = _range; + + // Define d3 properties + Object.defineProperties(linkPart, { + "source": { value: domain, writable: true }, + "target": { value: range, writable: true } + }); + + + linkPart.domain = function (){ + return domain; + }; + + linkPart.link = function (){ + return link; + }; + + linkPart.range = function (){ + return range; + }; + + + return linkPart; +}; diff --git a/src/webvowl/js/elements/nodes/BaseNode.js b/src/webvowl/js/elements/nodes/BaseNode.js new file mode 100644 index 0000000000000000000000000000000000000000..60b17465c5fa0d7813a14a64e5bc9259866bd701 --- /dev/null +++ b/src/webvowl/js/elements/nodes/BaseNode.js @@ -0,0 +1,399 @@ +var BaseElement = require("../BaseElement"); +var forceLayoutNodeFunctions = require("../forceLayoutNodeFunctions")(); + +module.exports = (function (){ + + var Base = function ( graph ){ + BaseElement.apply(this, arguments); + + var that = this, + // Basic attributes + complement, + disjointUnion, + disjointWith, + individuals = [], + intersection, + union, + links, + rendertype = "round", + // Additional attributes + maxIndividualCount, + fobj, // foreigner object for editing + ignoreLocalHoverEvents = false, + backupFullIri, + // Element containers + nodeElement; + + // array to store my properties; // we will need this also later for semantic zooming stuff + var assignedProperties = []; + that.editingTextElement = false; + + this.isPropertyAssignedToThisElement = function ( property ){ + // this goes via IRIS + console.log("Element IRI :" + property.iri()); + if ( property.type() === "rdfs:subClassOf" ) + for ( var i = 0; i < assignedProperties.length; i++ ) { + var iriEl = assignedProperties[i].iri(); + if ( property.iri() === iriEl ) { + return true; + } + if ( property.type() === "rdfs:subClassOf" && assignedProperties[i].type() === "rdfs:subClassOf" ) + return true; + if ( property.type() === "owl:disjointWith" && assignedProperties[i].type() === "owl:disjointWith" ) + return true; + + } + return false; + }; + + + this.existingPropertyIRI = function ( url ){ + // this goes via IRIS + for ( var i = 0; i < assignedProperties.length; i++ ) { + var iriEl = assignedProperties[i].iri(); + if ( iriEl === url ) { + return true; + } + } + return false; + }; + + this.addProperty = function ( property ){ + if ( assignedProperties.indexOf(property) === -1 ) { + assignedProperties.push(property); + } + }; + + this.removePropertyElement = function ( property ){ + // console.log("Calling removing old property!"+ property.iri()); + if ( assignedProperties.indexOf(property) !== -1 ) { + // console.log("Found it!"); + assignedProperties.splice(assignedProperties.indexOf(property), 1); + } + }; + this.getMyProperties = function (){ + return assignedProperties; + }; + this.copyOtherProperties = function ( otherProperties ){ + assignedProperties = otherProperties; + }; + + this.copyInformation = function ( other ){ + console.log(other.labelForCurrentLanguage()); + if ( other.type() !== "owl:Thing" ) + that.label(other.label()); + that.complement(other.complement()); + that.iri(other.iri()); + that.copyOtherProperties(other.getMyProperties()); + that.baseIri(other.baseIri()); + if ( other.type() === "owl:Class" ) { + that.backupLabel(other.label()); + // console.log("copied backup label"+that.backupLabel()); + } + if ( other.backupLabel() !== undefined ) { + that.backupLabel(other.backupLabel()); + } + }; + + this.enableEditing = function ( autoEditing ){ + if ( autoEditing === false ) + return; + that.raiseDoubleClickEdit(true); + }; + + this.raiseDoubleClickEdit = function ( forceIRISync ){ + d3.selectAll(".foreignelements").remove(); + if ( nodeElement === undefined || this.type() === "owl:Thing" || this.type() === "rdfs:Literal" ) { + console.log("No Container found"); + return; + } + if ( fobj !== undefined ) { + nodeElement.selectAll(".foreignelements").remove(); + } + + backupFullIri = undefined; + graph.options().focuserModule().handle(undefined); + graph.options().focuserModule().handle(that); + // add again the editing elements to that one + if ( graph.isTouchDevice() === true ) { + graph.activateHoverElements(true, that, true); + } + that.editingTextElement = true; + ignoreLocalHoverEvents = true; + that.nodeElement().selectAll("circle").classed("hoveredForEditing", true); + graph.killDelayedTimer(); + graph.ignoreOtherHoverEvents(false); + fobj = nodeElement.append("foreignObject") + .attr("x", -0.5 * (that.textWidth() - 2)) + .attr("y", -12) + .attr("height", 30) + .attr("class", "foreignelements") + .on("dragstart", function (){ + return false; + }) // remove drag operations of text element) + .attr("width", that.textWidth() - 2); + + var editText = fobj.append("xhtml:input") + .attr("class", "nodeEditSpan") + .attr("id", that.id()) + .attr("align", "center") + .attr("contentEditable", "true") + .on("dragstart", function (){ + return false; + }); // remove drag operations of text element) + + var bgColor = '#f00'; + var txtWidth = that.textWidth() - 2; + editText.style({ + + 'align': 'center', + 'color': 'black', + 'width': txtWidth + "px", + 'height': '15px', + 'background-color': bgColor, + 'border-bottom': '2px solid black' + }); + var txtNode = editText.node(); + txtNode.value = that.labelForCurrentLanguage(); + txtNode.focus(); + txtNode.select(); + that.frozen(true); // << releases the not after selection + that.locked(true); + + + d3.event.stopPropagation(); + // ignoreNodeHoverEvent=true; + // // add some events that relate to this object + editText.on("click", function (){ + d3.event.stopPropagation(); + }); + // // remove hover Events for now; + editText.on("mouseout", function (){ + d3.event.stopPropagation(); + + + }); + editText.on("mousedown", function (){ + d3.event.stopPropagation(); + }) + .on("keydown", function (){ + d3.event.stopPropagation(); + if ( d3.event.keyCode === 13 ) { + this.blur(); + that.frozen(false); // << releases the not after selection + that.locked(false); + } + }) + .on("keyup", function (){ + if ( forceIRISync ) { + var labelName = editText.node().value; + var resourceName = labelName.replaceAll(" ", "_"); + var syncedIRI = that.baseIri() + resourceName; + backupFullIri = syncedIRI; + + d3.select("#element_iriEditor").node().title = syncedIRI; + d3.select("#element_iriEditor").node().value = graph.options().prefixModule().getPrefixRepresentationForFullURI(syncedIRI); + } + d3.select("#element_labelEditor").node().value = editText.node().value; + + }) + .on("blur", function (){ + that.editingTextElement = false; + ignoreLocalHoverEvents = false; + that.nodeElement().selectAll("circle").classed("hoveredForEditing", false); + var newLabel = editText.node().value; + nodeElement.selectAll(".foreignelements").remove(); + // that.setLabelForCurrentLanguage(classNameConvention(editText.node().value)); + that.label(newLabel); + that.backupLabel(newLabel); + that.redrawLabelText(); + that.frozen(graph.paused()); + that.locked(graph.paused()); + graph.ignoreOtherHoverEvents(false); + // console.log("Calling blur on Node!"); + if ( backupFullIri ) { + var sanityCheckResult = graph.checkIfIriClassAlreadyExist(backupFullIri); + if ( sanityCheckResult === false ) { + that.iri(backupFullIri); + } else { + // throw warnign + graph.options().warningModule().showWarning("Already seen this class", + "Input IRI: " + backupFullIri + " for element: " + that.labelForCurrentLanguage() + " already been set", + "Restoring previous IRI for Element : " + that.iri(), 2, false, sanityCheckResult); + + } + } + if ( graph.isADraggerActive() === false ) { + graph.options().focuserModule().handle(undefined); + graph.options().focuserModule().handle(that); + } + }); // add a foreiner element to this thing; + }; + + + this.renderType = function ( t ){ + if ( !arguments.length ) return rendertype; + rendertype = t; + return this; + }; + // Properties + this.complement = function ( p ){ + if ( !arguments.length ) return complement; + complement = p; + return this; + }; + + this.disjointUnion = function ( p ){ + if ( !arguments.length ) return disjointUnion; + disjointUnion = p; + return this; + }; + + this.disjointWith = function ( p ){ + if ( !arguments.length ) return disjointWith; + disjointWith = p; + return this; + }; + + this.individuals = function ( p ){ + if ( !arguments.length ) return individuals; + individuals = p || []; + return this; + }; + + this.intersection = function ( p ){ + if ( !arguments.length ) return intersection; + intersection = p; + return this; + }; + + this.links = function ( p ){ + if ( !arguments.length ) return links; + links = p; + return this; + }; + + this.maxIndividualCount = function ( p ){ + if ( !arguments.length ) return maxIndividualCount; + maxIndividualCount = p; + return this; + }; + + this.nodeElement = function ( p ){ + if ( !arguments.length ) return nodeElement; + nodeElement = p; + return this; + }; + + this.union = function ( p ){ + if ( !arguments.length ) return union; + union = p; + return this; + }; + + + /** + * Returns css classes generated from the data of this object. + * @returns {Array} + */ + that.collectCssClasses = function (){ + var cssClasses = []; + + if ( typeof that.styleClass() === "string" ) { + cssClasses.push(that.styleClass()); + } + + cssClasses = cssClasses.concat(that.visualAttributes()); + + return cssClasses; + }; + + + // Reused functions TODO refactor + this.addMouseListeners = function (){ + // Empty node + if ( !that.nodeElement() ) { + console.warn(this); + return; + } + + that.nodeElement().selectAll("*") + .on("mouseover", onMouseOver) + .on("mouseout", onMouseOut); + }; + + this.animationProcess = function (){ + var animRuns = false; + if ( that.getHalos() ) { + var haloGr = that.getHalos(); + var haloEls = haloGr.selectAll(".searchResultA"); + animRuns = haloGr.attr("animationRunning"); + if ( typeof animRuns !== "boolean" ) { + // parse this to a boolean value + animRuns = (animRuns === 'true'); + } + if ( animRuns === false ) { + haloEls.classed("searchResultA", false); + haloEls.classed("searchResultB", true); + } + } + return animRuns; + }; + + this.foreground = function (){ + var selectedNode = that.nodeElement().node(), + nodeContainer = selectedNode.parentNode; + // check if the halo is present and an animation is running + if ( that.animationProcess() === false ) { + // Append hovered element as last child to the container list. + nodeContainer.appendChild(selectedNode); + } + + }; + + function onMouseOver(){ + if ( that.mouseEntered() || ignoreLocalHoverEvents === true ) { + return; + } + + var selectedNode = that.nodeElement().node(), + nodeContainer = selectedNode.parentNode; + + // Append hovered element as last child to the container list. + if ( that.animationProcess() === false ) { + nodeContainer.appendChild(selectedNode); + } + if ( graph.isTouchDevice() === false ) { + that.setHoverHighlighting(true); + that.mouseEntered(true); + if ( graph.editorMode() === true && graph.ignoreOtherHoverEvents() === false ) { + graph.activateHoverElements(true, that); + } + } else { + if ( graph.editorMode() === true && graph.ignoreOtherHoverEvents() === false ) { + graph.activateHoverElements(true, that, true); + } + + } + + + } + + function onMouseOut(){ + that.setHoverHighlighting(false); + that.mouseEntered(false); + if ( graph.editorMode() === true && graph.ignoreOtherHoverEvents() === false ) { + graph.activateHoverElements(false); + } + } + + + forceLayoutNodeFunctions.addTo(this); + }; + + Base.prototype = Object.create(BaseElement.prototype); + Base.prototype.constructor = Base; + + + return Base; +}()); diff --git a/src/webvowl/js/elements/nodes/DatatypeNode.js b/src/webvowl/js/elements/nodes/DatatypeNode.js new file mode 100644 index 0000000000000000000000000000000000000000..95b842e16ec68c0bdfc12355bf3664ea1075cd32 --- /dev/null +++ b/src/webvowl/js/elements/nodes/DatatypeNode.js @@ -0,0 +1,12 @@ +var RectangularNode = require("./RectangularNode"); + +module.exports = (function (){ + + var o = function ( graph ){ + RectangularNode.apply(this, arguments); + }; + o.prototype = Object.create(RectangularNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/RectangularNode.js b/src/webvowl/js/elements/nodes/RectangularNode.js new file mode 100644 index 0000000000000000000000000000000000000000..e1964062ccecd686ad9f2f9150378ae8163d13c9 --- /dev/null +++ b/src/webvowl/js/elements/nodes/RectangularNode.js @@ -0,0 +1,268 @@ +var BaseNode = require("./BaseNode"); +var CenteringTextElement = require("../../util/CenteringTextElement"); +var drawTools = require("../drawTools")(); +var rectangularElementTools = require("../rectangularElementTools")(); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseNode.apply(this, arguments); + + var that = this, + height = 20, + width = 60, + pinGroupElement, + haloGroupElement, + labelWidth = 80, + myWidth = 80, + defaultWidth = 80, + shapeElement, + textBlock, + smallestRadius = height / 2; + + that.renderType("rect"); + // Properties + this.height = function ( p ){ + if ( !arguments.length ) return height; + height = p; + return this; + }; + + this.width = function ( p ){ + if ( !arguments.length ) return width; + width = p; + return this; + }; + + this.getHalos = function (){ + return haloGroupElement; + }; + + // Functions + // for compatibility reasons // TODO resolve + this.actualRadius = function (){ + return smallestRadius; + }; + + this.distanceToBorder = function ( dx, dy ){ + return rectangularElementTools.distanceToBorder(that, dx, dy); + }; + + this.setHoverHighlighting = function ( enable ){ + that.nodeElement().selectAll("rect").classed("hovered", enable); + + var haloGroup = that.getHalos(); + if ( haloGroup ) { + var test = haloGroup.selectAll(".searchResultA"); + test.classed("searchResultA", false); + test.classed("searchResultB", true); + } + + }; + + + // overwrite the labelWith; + + + this.textWidth = function (){ + return labelWidth; + }; + this.width = function (){ + return labelWidth; + }; + + this.getMyWidth = function (){ + // use a simple heuristic + var text = that.labelForCurrentLanguage(); + myWidth = measureTextWidth(text, "text") + 20; + + // check for sub names; + var indicatorText = that.indicationString(); + var indicatorWidth = measureTextWidth(indicatorText, "subtext") + 20; + if ( indicatorWidth > myWidth ) + myWidth = indicatorWidth; + + return myWidth; + }; + + this.textWidth = function (){ + return that.width(); + }; + function measureTextWidth( text, textStyle ){ + // Set a default value + if ( !textStyle ) { + textStyle = "text"; + } + var d = d3.select("body") + .append("div") + .attr("class", textStyle) + .attr("id", "width-test") // tag this element to identify it + .attr("style", "position:absolute; float:left; white-space:nowrap; visibility:hidden;") + .text(text), + w = document.getElementById("width-test").offsetWidth; + d.remove(); + return w; + } + + this.toggleFocus = function (){ + that.focused(!that.focused()); + that.nodeElement().select("rect").classed("focused", that.focused()); + graph.resetSearchHighlight(); + graph.options().searchMenu().clearText(); + }; + + /** + * Draws the rectangular node. + * @param parentElement the element to which this node will be appended + * @param [additionalCssClasses] additional css classes + */ + this.draw = function ( parentElement, additionalCssClasses ){ + var cssClasses = that.collectCssClasses(); + + that.nodeElement(parentElement); + + if ( additionalCssClasses instanceof Array ) { + cssClasses = cssClasses.concat(additionalCssClasses); + } + + // set the value for that.width() + // update labelWidth Value; + if ( graph.options().dynamicLabelWidth() === true ) labelWidth = Math.min(that.getMyWidth(), graph.options().maxLabelWidth()); + else labelWidth = defaultWidth; + + width = labelWidth; + shapeElement = drawTools.appendRectangularClass(parentElement, that.width(), that.height(), cssClasses, that.labelForCurrentLanguage(), that.backgroundColor()); + + textBlock = new CenteringTextElement(parentElement, that.backgroundColor()); + textBlock.addText(that.labelForCurrentLanguage()); + + that.addMouseListeners(); + + if ( that.pinned() ) { + that.drawPin(); + } + if ( that.halo() ) { + that.drawHalo(false); + } + }; + + this.drawPin = function (){ + that.pinned(true); + // if (graph.options().dynamicLabelWidth()===true) labelWidth=that.getMyWidth(); + // else labelWidth=defaultWidth; + // width=labelWidth; + // console.log("this element label Width is "+labelWidth); + var dx = -0.5 * labelWidth + 5, + dy = -1.1 * height; + + pinGroupElement = drawTools.drawPin(that.nodeElement(), dx, dy, this.removePin, graph.options().showDraggerObject, graph.options().useAccuracyHelper()); + + }; + + this.removePin = function (){ + that.pinned(false); + if ( pinGroupElement ) { + pinGroupElement.remove(); + } + graph.updateStyle(); + }; + + this.removeHalo = function (){ + that.halo(false); + if ( haloGroupElement ) { + haloGroupElement.remove(); + haloGroupElement = null; + } + }; + + this.drawHalo = function ( pulseAnimation ){ + that.halo(true); + + var offset = 0; + haloGroupElement = drawTools.drawRectHalo(that, this.width(), this.height(), offset); + + if ( pulseAnimation === false ) { + var pulseItem = haloGroupElement.selectAll(".searchResultA"); + pulseItem.classed("searchResultA", false); + pulseItem.classed("searchResultB", true); + pulseItem.attr("animationRunning", false); + } + + if ( that.pinned() ) { + var selectedNode = pinGroupElement.node(); + var nodeContainer = selectedNode.parentNode; + nodeContainer.appendChild(selectedNode); + } + + }; + + this.updateTextElement = function (){ + textBlock.updateAllTextElements(); + + }; + + this.textBlock = function (){ + return textBlock; + }; + + this.redrawLabelText = function (){ + textBlock.remove(); + textBlock = new CenteringTextElement(that.nodeElement(), that.backgroundColor()); + textBlock.addText(that.labelForCurrentLanguage()); + that.animateDynamicLabelWidth(graph.options().dynamicLabelWidth()); + shapeElement.select("title").text(that.labelForCurrentLanguage()); + }; + + this.animateDynamicLabelWidth = function ( dynamic ){ + that.removeHalo(); + var height = that.height(); + if ( dynamic === true ) { + labelWidth = Math.min(that.getMyWidth(), graph.options().maxLabelWidth()); + shapeElement.transition().tween("attr", function (){ + }) + .ease('linear') + .duration(100) + .attr({ x: -labelWidth / 2, y: -height / 2, width: labelWidth, height: height }) + .each("end", function (){ + that.updateTextElement(); + }); + + } else { + labelWidth = defaultWidth; + that.updateTextElement(); + shapeElement.transition().tween("attr", function (){ + }) + .ease('linear') + .duration(100) + .attr({ x: -labelWidth / 2, y: -height / 2, width: labelWidth, height: height }); + + } + + // for the pin we dont need to differ between different widths -- they are already set + if ( that.pinned() === true && pinGroupElement ) { + + var dx = 0.5 * labelWidth - 10, + dy = -1.1 * height; + + pinGroupElement.transition() + .tween("attr.translate", function (){ + }) + .attr("transform", "translate(" + dx + "," + dy + ")") + .ease('linear') + .duration(100); + } + }; + + this.addTextLabelElement = function (){ + var parentElement = that.nodeElement(); + textBlock = new CenteringTextElement(parentElement, this.backgroundColor()); + textBlock.addText(that.labelForCurrentLanguage()); + }; + + + }; + o.prototype = Object.create(BaseNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/RoundNode.js b/src/webvowl/js/elements/nodes/RoundNode.js new file mode 100644 index 0000000000000000000000000000000000000000..8fe5d27244188894f612ffef6c31dd3f04f59959 --- /dev/null +++ b/src/webvowl/js/elements/nodes/RoundNode.js @@ -0,0 +1,284 @@ +var BaseNode = require("./BaseNode"); +var CenteringTextElement = require("../../util/CenteringTextElement"); +var drawTools = require("../drawTools")(); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseNode.apply(this, arguments); + + var that = this, + collapsible = false, + radius = 50, + collapsingGroupElement, + pinGroupElement, + haloGroupElement = null, + rectangularRepresentation = false, + renderingElement, + textBlock; + + this.setRectangularRepresentation = function ( val ){ + rectangularRepresentation = val; + }; + this.getRectangularRepresentation = function (){ + return rectangularRepresentation; + }; + + this.getHalos = function (){ + return haloGroupElement; + }; + + // Properties + this.collapsible = function ( p ){ + if ( !arguments.length ) return collapsible; + collapsible = p; + return this; + }; + + this.textBlock = function ( p ){ + if ( !arguments.length ) return textBlock; + textBlock = p; + return this; + }; + + /** + * This might not be equal to the actual radius, because the instance count is used for its calculation. + * @param p + * @returns {*} + */ + this.radius = function ( p ){ + if ( !arguments.length ) return radius; + radius = p; + return this; + }; + + + // Functions + this.setHoverHighlighting = function ( enable ){ + that.nodeElement().selectAll("circle").classed("hovered", enable); + }; + + this.textWidth = function ( yOffset ){ + var availableWidth = this.actualRadius() * 2; + + // if the text is not placed in the center of the circle, it can't have the full width + if ( yOffset ) { + var relativeOffset = Math.abs(yOffset) / this.actualRadius(); + var isOffsetInsideOfNode = relativeOffset <= 1; + + if ( isOffsetInsideOfNode ) { + availableWidth = Math.cos(relativeOffset) * availableWidth; + } else { + availableWidth = 0; + } + } + + return availableWidth; + }; + + this.toggleFocus = function (){ + that.focused(!that.focused()); + if ( that.nodeElement() ) + that.nodeElement().select("circle").classed("focused", that.focused()); + graph.resetSearchHighlight(); + graph.options().searchMenu().clearText(); + + }; + + this.actualRadius = function (){ + if ( !graph.options().scaleNodesByIndividuals() || that.individuals().length <= 0 ) { + return that.radius(); + } else { + // we could "listen" for radius and maxIndividualCount changes, but this is easier + var MULTIPLIER = 8, + additionalRadius = Math.log(that.individuals().length + 1) * MULTIPLIER + 5; + + return that.radius() + additionalRadius; + } + }; + + this.distanceToBorder = function (){ + return that.actualRadius(); + }; + + this.removeHalo = function (){ + if ( that.halo() ) { + that.halo(false); + if ( haloGroupElement ) { + haloGroupElement.remove(); + } + } + }; + + this.drawHalo = function ( pulseAnimation ){ + that.halo(true); + if ( rectangularRepresentation === true ) { + haloGroupElement = drawTools.drawRectHalo(that.nodeElement(), 80, 80, 5); + } else { + haloGroupElement = drawTools.drawHalo(that.nodeElement(), that.actualRadius(), this.removeHalo); + } + if ( pulseAnimation === false ) { + var pulseItem = haloGroupElement.selectAll(".searchResultA"); + pulseItem.classed("searchResultA", false); + pulseItem.classed("searchResultB", true); + pulseItem.attr("animationRunning", false); + } + }; + + /** + * Draws the pin on a round node on a position depending on its radius. + */ + this.drawPin = function (){ + that.pinned(true); + var dx = (-3.5 / 5) * that.actualRadius(), + dy = (-7 / 10) * that.actualRadius(); + pinGroupElement = drawTools.drawPin(that.nodeElement(), dx, dy, this.removePin, graph.options().showDraggerObject, graph.options().useAccuracyHelper()); + + + }; + + /** + * Removes the pin and refreshs the graph to update the force layout. + */ + this.removePin = function (){ + that.pinned(false); + if ( pinGroupElement ) { + pinGroupElement.remove(); + } + graph.updateStyle(); + }; + + this.drawCollapsingButton = function (){ + + collapsingGroupElement = that.nodeElement() + .append("g") + .classed("hidden-in-export", true) + .attr("transform", function (){ + var dx = (-2 / 5) * that.actualRadius(), + dy = (1 / 2) * that.actualRadius(); + return "translate(" + dx + "," + dy + ")"; + }); + + collapsingGroupElement.append("rect") + .classed("class pin feature", true) + .attr("x", 0) + .attr("y", 0) + .attr("width", 40) + .attr("height", 24); + + collapsingGroupElement.append("line") + .attr("x1", 13) + .attr("y1", 12) + .attr("x2", 27) + .attr("y2", 12); + + collapsingGroupElement.append("line") + .attr("x1", 20) + .attr("y1", 6) + .attr("x2", 20) + .attr("y2", 18); + }; + + /** + * Draws a circular node. + * @param parentElement the element to which this node will be appended + * @param [additionalCssClasses] additional css classes + */ + this.draw = function ( parentElement, additionalCssClasses ){ + var cssClasses = that.collectCssClasses(); + that.nodeElement(parentElement); + + var bgColor = that.backgroundColor(); + if ( bgColor === null ) bgColor = undefined; + if ( that.attributes().indexOf("deprecated") > -1 ) { + bgColor = undefined; + } + if ( additionalCssClasses instanceof Array ) { + cssClasses = cssClasses.concat(additionalCssClasses); + } + if ( rectangularRepresentation === true ) { + renderingElement = drawTools.appendRectangularClass(parentElement, 80, 80, cssClasses, that.labelForCurrentLanguage(), bgColor); + } else { + renderingElement = drawTools.appendCircularClass(parentElement, that.actualRadius(), cssClasses, that.labelForCurrentLanguage(), bgColor); + } + that.postDrawActions(parentElement); + }; + + this.redrawElement = function (){ + renderingElement.remove(); + textBlock.remove(); + var bgColor = that.backgroundColor(); + if ( that.attributes().indexOf("deprecated") > -1 ) { + bgColor = undefined; + } + + var cssClasses = that.collectCssClasses(); + + if ( rectangularRepresentation === true ) { + renderingElement = drawTools.appendRectangularClass(that.nodeElement(), 80, 80, cssClasses, that.labelForCurrentLanguage(), bgColor); + } else { + renderingElement = drawTools.appendCircularClass(that.nodeElement(), that.actualRadius(), cssClasses, that.labelForCurrentLanguage(), bgColor); + } + that.postDrawActions(that.nodeElement()); + }; + /** + * Common actions that should be invoked after drawing a node. + */ + this.postDrawActions = function (){ + that.textBlock(createTextBlock()); + + that.addMouseListeners(); + if ( that.pinned() ) { + that.drawPin(); + } + if ( that.halo() ) { + that.drawHalo(false); + } + if ( that.collapsible() ) { + that.drawCollapsingButton(); + } + }; + + this.redrawLabelText = function (){ + that.textBlock().remove(); + that.textBlock(createTextBlock()); + renderingElement.select("title").text(that.labelForCurrentLanguage()); + }; + function createTextBlock(){ + var bgColor = that.backgroundColor(); + if ( that.attributes().indexOf("deprecated") > -1 ) + bgColor = undefined; + + var textBlock = new CenteringTextElement(that.nodeElement(), bgColor); + + var equivalentsString = that.equivalentsString(); + var suffixForFollowingEquivalents = equivalentsString ? "," : ""; + + textBlock.addText(that.labelForCurrentLanguage(), "", suffixForFollowingEquivalents); + textBlock.addEquivalents(equivalentsString); + if ( !graph.options().compactNotation() ) { + textBlock.addSubText(that.indicationString()); + } + textBlock.addInstanceCount(that.individuals().length); + + return textBlock; + } + + this.equivalentsString = function (){ + var equivalentClasses = that.equivalents(); + if ( !equivalentClasses ) { + return; + } + + return equivalentClasses + .map(function ( node ){ + return node.labelForCurrentLanguage(); + }) + .join(", "); + }; + }; + o.prototype = Object.create(BaseNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/SetOperatorNode.js b/src/webvowl/js/elements/nodes/SetOperatorNode.js new file mode 100644 index 0000000000000000000000000000000000000000..eedae438301b99b0f6f10e6f978f25c88a8bd152 --- /dev/null +++ b/src/webvowl/js/elements/nodes/SetOperatorNode.js @@ -0,0 +1,73 @@ +var AbsoluteTextElement = require("../../util/AbsoluteTextElement"); +var BoxArrowLink = require("../links/BoxArrowLink"); +var RoundNode = require("./RoundNode"); +var drawTools = require("../drawTools")(); + +module.exports = (function (){ + + var o = function ( graph ){ + RoundNode.apply(this, arguments); + + var that = this, + superHoverHighlightingFunction = that.setHoverHighlighting, + superPostDrawActions = that.postDrawActions; + + this.setHoverHighlighting = function ( enable ){ + superHoverHighlightingFunction(enable); + + // Highlight links pointing to included nodes when hovering the set operator + that.links() + .filter(function ( link ){ + return link instanceof BoxArrowLink; + }) + .filter(function ( link ){ + return link.domain().equals(that); + }) + .forEach(function ( link ){ + link.property().setHighlighting(enable); + }); + }; + + this.draw = function ( element ){ + that.nodeElement(element); + + drawTools.appendCircularClass(element, that.actualRadius(), + that.collectCssClasses().join(" "), + that.labelForCurrentLanguage(), that.backgroundColor()); + }; + + this.postDrawActions = function (){ + superPostDrawActions(); + that.textBlock().remove(); + + var textElement = new AbsoluteTextElement(that.nodeElement(), that.backgroundColor()); + + var equivalentsString = that.equivalentsString(); + var offsetForFollowingEquivalents = equivalentsString ? -30 : -17; + var suffixForFollowingEquivalents = equivalentsString ? "," : ""; + textElement.addText(that.labelForCurrentLanguage(), offsetForFollowingEquivalents, "", + suffixForFollowingEquivalents); + + textElement.addEquivalents(equivalentsString, -17); + + + if ( !graph.options().compactNotation() ) { + + if ( that.indicationString().length > 0 ) { + textElement.addSubText(that.indicationString(), 17); + textElement.addInstanceCount(that.individuals().length, 30); + } else { + textElement.addInstanceCount(that.individuals().length, 17); + } + } else { + textElement.addInstanceCount(that.individuals().length, 17); + } + + that.textBlock(textElement); + }; + }; + o.prototype = Object.create(RoundNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/implementations/ExternalClass.js b/src/webvowl/js/elements/nodes/implementations/ExternalClass.js new file mode 100644 index 0000000000000000000000000000000000000000..489e04256662a61991572530f2312f6a0799184c --- /dev/null +++ b/src/webvowl/js/elements/nodes/implementations/ExternalClass.js @@ -0,0 +1,15 @@ +var RoundNode = require("../RoundNode"); + +module.exports = (function (){ + + var o = function ( graph ){ + RoundNode.apply(this, arguments); + + this.attributes(["external"]) + .type("ExternalClass"); + }; + o.prototype = Object.create(RoundNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/implementations/OwlClass.js b/src/webvowl/js/elements/nodes/implementations/OwlClass.js new file mode 100644 index 0000000000000000000000000000000000000000..e2b1de000005dc34f74e8ba2c762e4c0201e12e1 --- /dev/null +++ b/src/webvowl/js/elements/nodes/implementations/OwlClass.js @@ -0,0 +1,14 @@ +var RoundNode = require("../RoundNode"); + +module.exports = (function (){ + + var o = function ( graph ){ + RoundNode.apply(this, arguments); + + this.type("owl:Class"); + }; + o.prototype = Object.create(RoundNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/implementations/OwlComplementOf.js b/src/webvowl/js/elements/nodes/implementations/OwlComplementOf.js new file mode 100644 index 0000000000000000000000000000000000000000..5e37a1f87797321777689867ee216815e19cc91a --- /dev/null +++ b/src/webvowl/js/elements/nodes/implementations/OwlComplementOf.js @@ -0,0 +1,38 @@ +var SetOperatorNode = require("../SetOperatorNode"); + +module.exports = (function (){ + + var o = function ( graph ){ + SetOperatorNode.apply(this, arguments); + + var that = this, + superDrawFunction = that.draw; + + this.styleClass("complementof") + .type("owl:complementOf"); + + this.draw = function ( element ){ + superDrawFunction(element); + + var symbol = element.append("g").classed("embedded", true); + + symbol.append("circle") + .attr("class", "symbol") + .classed("fineline", true) + .attr("r", 10); + symbol.append("path") + .attr("class", "nofill") + .attr("d", "m -7,-1.5 12,0 0,6") + .attr("transform", "scale(.5)"); + + symbol.attr("transform", + "translate(-" + (that.radius() - 15) / 100 + ",-" + (that.radius() - 15) / 100 + ")"); + + that.postDrawActions(); + }; + }; + o.prototype = Object.create(SetOperatorNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/implementations/OwlDeprecatedClass.js b/src/webvowl/js/elements/nodes/implementations/OwlDeprecatedClass.js new file mode 100644 index 0000000000000000000000000000000000000000..ae3b54cb84736d9fb9b3031ef1f2ae9a76fbbc6c --- /dev/null +++ b/src/webvowl/js/elements/nodes/implementations/OwlDeprecatedClass.js @@ -0,0 +1,17 @@ +var RoundNode = require("../RoundNode"); + +module.exports = (function (){ + + var o = function ( graph ){ + RoundNode.apply(this, arguments); + + this.attributes(["deprecated"]) + .type("owl:DeprecatedClass") + .styleClass("deprecated") + .indications(["deprecated"]); + }; + o.prototype = Object.create(RoundNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/implementations/OwlDisjointUnionOf.js b/src/webvowl/js/elements/nodes/implementations/OwlDisjointUnionOf.js new file mode 100644 index 0000000000000000000000000000000000000000..568a601bbd1c5168077d710c98c6f6763791f0f6 --- /dev/null +++ b/src/webvowl/js/elements/nodes/implementations/OwlDisjointUnionOf.js @@ -0,0 +1,46 @@ +var SetOperatorNode = require("../SetOperatorNode"); + +module.exports = (function (){ + + var o = function ( graph ){ + SetOperatorNode.apply(this, arguments); + + var that = this, + superDrawFunction = that.draw; + + this.styleClass("disjointunionof") + .type("owl:disjointUnionOf"); + + this.draw = function ( element ){ + superDrawFunction(element); + + var symbol = element.append("g").classed("embedded", true); + + var symbolRadius = 10; + symbol.append("circle") + .attr("class", "symbol") + .attr("r", symbolRadius); + symbol.append("circle") + .attr("cx", 10) + .attr("class", "symbol") + .classed("fineline", true) + .attr("r", symbolRadius); + symbol.append("circle") + .attr("class", "nofill") + .classed("fineline", true) + .attr("r", symbolRadius); + symbol.append("text") + .attr("class", "link") + .text("1") + .attr("transform", "scale(.7)translate(3,5)"); + + symbol.attr("transform", "translate(-" + (that.radius() - 15) / 7 + ",-" + (that.radius() - 15) / 100 + ")"); + + that.postDrawActions(); + }; + }; + o.prototype = Object.create(SetOperatorNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/implementations/OwlEquivalentClass.js b/src/webvowl/js/elements/nodes/implementations/OwlEquivalentClass.js new file mode 100644 index 0000000000000000000000000000000000000000..1cb43e940eadaa9c3fa029555316e17217af1a57 --- /dev/null +++ b/src/webvowl/js/elements/nodes/implementations/OwlEquivalentClass.js @@ -0,0 +1,80 @@ +var RoundNode = require("../RoundNode"); +var drawTools = require("../../drawTools")(); + +module.exports = (function (){ + + var o = function ( graph ){ + RoundNode.apply(this, arguments); + + var CIRCLE_SIZE_DIFFERENCE = 4; + var renderingElement; + var that = this, + superActualRadiusFunction = that.actualRadius; + + this.styleClass("equivalentclass") + .type("owl:equivalentClass"); + + this.actualRadius = function (){ + return superActualRadiusFunction() + CIRCLE_SIZE_DIFFERENCE; + }; + + this.redrawElement = function (){ + renderingElement.remove(); + that.textBlock().remove(); + var bgColor = that.backgroundColor(); + + if ( that.attributes().indexOf("deprecated") > -1 ) { + bgColor = undefined; + } + var cssClasses = that.collectCssClasses(); + renderingElement = that.nodeElement().append("g"); + + if ( that.getRectangularRepresentation() === true ) { + drawTools.appendRectangularClass(renderingElement, 84, 84, ["white", "embedded"]); + drawTools.appendRectangularClass(renderingElement, 80 - CIRCLE_SIZE_DIFFERENCE, 80 - CIRCLE_SIZE_DIFFERENCE, cssClasses, that.labelForCurrentLanguage(), bgColor); + } else { + drawTools.appendCircularClass(renderingElement, that.actualRadius(), ["white", "embedded"]); + console.log(cssClasses); + console.log(that.attributes()); + console.log("what is bgColor" + bgColor); + drawTools.appendCircularClass(renderingElement, that.actualRadius() - CIRCLE_SIZE_DIFFERENCE, cssClasses, that.labelForCurrentLanguage(), bgColor); + + } + that.postDrawActions(that.nodeElement()); + + }; + this.draw = function ( parentElement ){ + var cssClasses = that.collectCssClasses(); + + that.nodeElement(parentElement); + renderingElement = parentElement.append("g"); + var bgColor = that.backgroundColor(); + if ( that.attributes().indexOf("deprecated") > -1 ) { + bgColor = undefined; + } + // draw the outer circle at first and afterwards the inner circle + if ( that.getRectangularRepresentation() === true ) { + drawTools.appendRectangularClass(renderingElement, 84, 84, ["white", "embedded"]); + drawTools.appendRectangularClass(renderingElement, 80 - CIRCLE_SIZE_DIFFERENCE, 80 - CIRCLE_SIZE_DIFFERENCE, cssClasses, that.labelForCurrentLanguage(), bgColor); + } else { + drawTools.appendCircularClass(renderingElement, that.actualRadius(), ["white", "embedded"]); + drawTools.appendCircularClass(renderingElement, that.actualRadius() - CIRCLE_SIZE_DIFFERENCE, cssClasses, that.labelForCurrentLanguage(), bgColor); + + } + + that.postDrawActions(); + }; + + /** + * Sets the hover highlighting of this node. + * @param enable + */ + that.setHoverHighlighting = function ( enable ){ + that.nodeElement().selectAll("circle:last-of-type").classed("hovered", enable); + }; + }; + o.prototype = Object.create(RoundNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/implementations/OwlIntersectionOf.js b/src/webvowl/js/elements/nodes/implementations/OwlIntersectionOf.js new file mode 100644 index 0000000000000000000000000000000000000000..361e35a85039dc3dff6c7c0a149b6418fe57f420 --- /dev/null +++ b/src/webvowl/js/elements/nodes/implementations/OwlIntersectionOf.js @@ -0,0 +1,67 @@ +var SetOperatorNode = require("../SetOperatorNode"); + +module.exports = (function (){ + + var o = function ( graph ){ + SetOperatorNode.apply(this, arguments); + + var that = this, + superDrawFunction = that.draw, + INTERSECTION_BACKGROUND_PATH = createIntersectionPath(); + + this.styleClass("intersectionof") + .type("owl:intersectionOf"); + + this.draw = function ( element ){ + superDrawFunction(element); + + var symbol = element.append("g").classed("embedded", true); + + var symbolRadius = 10; + symbol.append("path") + .attr("class", "nostroke") + .classed("symbol", true) + .attr("d", INTERSECTION_BACKGROUND_PATH); + symbol.append("circle") + .attr("class", "nofill") + .classed("fineline", true) + .attr("r", symbolRadius); + symbol.append("circle") + .attr("cx", 10) + .attr("class", "nofill") + .classed("fineline", true) + .attr("r", symbolRadius); + symbol.append("path") + .attr("class", "nofill") + .attr("d", "m 9,5 c 0,-2 0,-4 0,-6 0,0 0,0 0,0 0,0 0,-1.8 -1,-2.3 -0.7,-0.6 -1.7,-0.8 -2.9," + + "-0.8 -1.2,0 -2,0 -3,0.8 -0.7,0.5 -1,1.4 -1,2.3 0,2 0,4 0,6") + .attr("transform", "scale(.5)translate(5,0)"); + + symbol.attr("transform", + "translate(-" + (that.radius() - 15) / 7 + ",-" + (that.radius() - 15) / 100 + ")"); + + that.postDrawActions(); + }; + + function createIntersectionPath(){ + var height = 18; + + var offsetX = 5; + var offsetY = -(height / 2); + + var bezierX = 7; + var bezierY = 5; + var bottomBezierY = height - bezierY; + + var startPosition = "M" + offsetX + "," + offsetY; + var rightSide = "c" + bezierX + "," + bezierY + " " + bezierX + "," + bottomBezierY + " 0," + height; + var leftSide = "c" + -bezierX + "," + -bezierY + " " + -bezierX + "," + -bottomBezierY + " 0," + -height; + + return startPosition + rightSide + leftSide; + } + }; + o.prototype = Object.create(SetOperatorNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/implementations/OwlNothing.js b/src/webvowl/js/elements/nodes/implementations/OwlNothing.js new file mode 100644 index 0000000000000000000000000000000000000000..046e40e03f09d153360c23c00fd294e749011c68 --- /dev/null +++ b/src/webvowl/js/elements/nodes/implementations/OwlNothing.js @@ -0,0 +1,16 @@ +var OwlThing = require("./OwlThing"); + +module.exports = (function (){ + + var o = function ( graph ){ + OwlThing.apply(this, arguments); + + this.label("Nothing") + .type("owl:Nothing") + .iri("http://www.w3.org/2002/07/owl#Nothing"); + }; + o.prototype = Object.create(OwlThing.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/implementations/OwlThing.js b/src/webvowl/js/elements/nodes/implementations/OwlThing.js new file mode 100644 index 0000000000000000000000000000000000000000..9d9e8504af04c96e5a70d879d3dcf4bc729c89df --- /dev/null +++ b/src/webvowl/js/elements/nodes/implementations/OwlThing.js @@ -0,0 +1,23 @@ +var RoundNode = require("../RoundNode"); + +module.exports = (function (){ + + var o = function ( graph ){ + RoundNode.apply(this, arguments); + + var superDrawFunction = this.draw; + + this.label("Thing") + .type("owl:Thing") + .iri("http://www.w3.org/2002/07/owl#Thing") + .radius(30); + + this.draw = function ( element ){ + superDrawFunction(element, ["white", "dashed"]); + }; + }; + o.prototype = Object.create(RoundNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/implementations/OwlUnionOf.js b/src/webvowl/js/elements/nodes/implementations/OwlUnionOf.js new file mode 100644 index 0000000000000000000000000000000000000000..12daa34901b141ec5094bbb9a64f4fd4de5fb6cc --- /dev/null +++ b/src/webvowl/js/elements/nodes/implementations/OwlUnionOf.js @@ -0,0 +1,46 @@ +var SetOperatorNode = require("../SetOperatorNode"); + +module.exports = (function (){ + + var o = function ( graph ){ + SetOperatorNode.apply(this, arguments); + + var that = this, + superDrawFunction = that.draw; + + this.styleClass("unionof") + .type("owl:unionOf"); + + this.draw = function ( element ){ + superDrawFunction(element); + + var symbol = element.append("g").classed("embedded", true); + + var symbolRadius = 10; + symbol.append("circle") + .attr("class", "symbol") + .attr("r", symbolRadius); + symbol.append("circle") + .attr("cx", 10) + .attr("class", "symbol") + .classed("fineline", true) + .attr("r", symbolRadius); + symbol.append("circle") + .attr("class", "nofill") + .classed("fineline", true) + .attr("r", symbolRadius); + symbol.append("path") + .attr("class", "link") + .attr("d", "m 1,-3 c 0,2 0,4 0,6 0,0 0,0 0,0 0,2 2,3 4,3 2,0 4,-1 4,-3 0,-2 0,-4 0,-6") + .attr("transform", "scale(.5)translate(5,0)"); + + symbol.attr("transform", "translate(-" + (that.radius() - 15) / 7 + ",-" + (that.radius() - 15) / 100 + ")"); + + that.postDrawActions(); + }; + }; + o.prototype = Object.create(SetOperatorNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/implementations/RdfsClass.js b/src/webvowl/js/elements/nodes/implementations/RdfsClass.js new file mode 100644 index 0000000000000000000000000000000000000000..0b8c94e84127bbd5ad24281fc8f147836076e59e --- /dev/null +++ b/src/webvowl/js/elements/nodes/implementations/RdfsClass.js @@ -0,0 +1,15 @@ +var RoundNode = require("../RoundNode"); + +module.exports = (function (){ + + var o = function ( graph ){ + RoundNode.apply(this, arguments); + + this.attributes(["rdf"]) + .type("rdfs:Class"); + }; + o.prototype = Object.create(RoundNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/implementations/RdfsDatatype.js b/src/webvowl/js/elements/nodes/implementations/RdfsDatatype.js new file mode 100644 index 0000000000000000000000000000000000000000..208daac4ceef9a285fb7819c5f2262959b4870a9 --- /dev/null +++ b/src/webvowl/js/elements/nodes/implementations/RdfsDatatype.js @@ -0,0 +1,21 @@ +var DatatypeNode = require("../DatatypeNode"); + +module.exports = (function (){ + + var o = function ( graph ){ + DatatypeNode.apply(this, arguments); + var dTypeString = "undefined"; + this.attributes(["datatype"]) + .type("rdfs:Datatype") + .styleClass("datatype"); + this.dType = function ( val ){ + if ( !arguments.length ) return dTypeString; + dTypeString = val; + + }; + }; + o.prototype = Object.create(DatatypeNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/implementations/RdfsLiteral.js b/src/webvowl/js/elements/nodes/implementations/RdfsLiteral.js new file mode 100644 index 0000000000000000000000000000000000000000..5a6fda0435632654fc30ba13ccd2f64a8e6bbe9f --- /dev/null +++ b/src/webvowl/js/elements/nodes/implementations/RdfsLiteral.js @@ -0,0 +1,30 @@ +var DatatypeNode = require("../DatatypeNode"); + +module.exports = (function (){ + + var o = function ( graph ){ + DatatypeNode.apply(this, arguments); + + var superDrawFunction = this.draw, + superLabelFunction = this.label; + + this.attributes(["datatype"]) + .label("Literal") + .styleClass("literal") + .type("rdfs:Literal") + .iri("http://www.w3.org/2000/01/rdf-schema#Literal"); + + this.draw = function ( element ){ + superDrawFunction(element, ["dashed"]); + }; + + this.label = function ( p ){ + if ( !arguments.length ) return superLabelFunction(); + return this; + }; + }; + o.prototype = Object.create(DatatypeNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/implementations/RdfsResource.js b/src/webvowl/js/elements/nodes/implementations/RdfsResource.js new file mode 100644 index 0000000000000000000000000000000000000000..42bf27ec709d019e7051fa49d3a6a3ba087c6c75 --- /dev/null +++ b/src/webvowl/js/elements/nodes/implementations/RdfsResource.js @@ -0,0 +1,24 @@ +var RoundNode = require("../RoundNode"); + +module.exports = (function (){ + + var o = function ( graph ){ + RoundNode.apply(this, arguments); + + var superDrawFunction = this.draw; + + this.attributes(["rdf"]) + .label("Resource") + .radius(30) + .styleClass("rdfsresource") + .type("rdfs:Resource"); + + this.draw = function ( element ){ + superDrawFunction(element, ["rdf", "dashed"]); + }; + }; + o.prototype = Object.create(RoundNode.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/nodes/nodeMap.js b/src/webvowl/js/elements/nodes/nodeMap.js new file mode 100644 index 0000000000000000000000000000000000000000..4a8557b38458ea415e34f791cb92d51af0049da4 --- /dev/null +++ b/src/webvowl/js/elements/nodes/nodeMap.js @@ -0,0 +1,23 @@ +var nodes = []; +nodes.push(require("./implementations/ExternalClass")); +nodes.push(require("./implementations/OwlClass")); +nodes.push(require("./implementations/OwlComplementOf")); +nodes.push(require("./implementations/OwlDeprecatedClass")); +nodes.push(require("./implementations/OwlDisjointUnionOf")); +nodes.push(require("./implementations/OwlEquivalentClass")); +nodes.push(require("./implementations/OwlIntersectionOf")); +nodes.push(require("./implementations/OwlNothing")); +nodes.push(require("./implementations/OwlThing")); +nodes.push(require("./implementations/OwlUnionOf")); +nodes.push(require("./implementations/RdfsClass")); +nodes.push(require("./implementations/RdfsDatatype")); +nodes.push(require("./implementations/RdfsLiteral")); +nodes.push(require("./implementations/RdfsResource")); + +var map = d3.map(nodes, function ( Prototype ){ + return new Prototype().type(); +}); + +module.exports = function (){ + return map; +}; diff --git a/src/webvowl/js/elements/properties/BaseProperty.js b/src/webvowl/js/elements/properties/BaseProperty.js new file mode 100644 index 0000000000000000000000000000000000000000..a7df3105377788d9cba3709e3fefd07489128fea --- /dev/null +++ b/src/webvowl/js/elements/properties/BaseProperty.js @@ -0,0 +1,894 @@ +var BaseElement = require("../BaseElement"); +var CenteringTextElement = require("../../util/CenteringTextElement"); +var drawTools = require("../drawTools")(); +var forceLayoutNodeFunctions = require("../forceLayoutNodeFunctions")(); +var rectangularElementTools = require("../rectangularElementTools")(); +var math = require("../../util/math")(); + +module.exports = (function (){ + + // Static variables + var labelHeight = 28, + labelWidth = 80, + smallestRadius = labelHeight / 2; + + + // Constructor, private variables and privileged methods + var Base = function ( graph ){ + BaseElement.apply(this, arguments); + + var that = this, + // Basic attributes + cardinality, + domain, + inverse, + link, + minCardinality, + maxCardinality, + range, + subproperties, + superproperties, + // Style attributes + linkType = "normal", + markerType = "filled", + labelVisible = true, + // Element containers + cardinalityElement, + labelElement, + linkGroup, + markerElement, + // Other + ignoreLocalHoverEvents, + fobj, + pinGroupElement, + haloGroupElement, + myWidth = 80, + defaultWidth = 80, + shapeElement, + textElement, + parent_labelObject, + backupFullIri, + + redundantProperties = []; + + + this.existingPropertyIRI = function ( url ){ + return graph.options().editSidebar().checkForExistingURL(url); + }; + + this.getHalos = function (){ + return haloGroupElement; + }; + + this.getPin = function (){ + return pinGroupElement; + }; + this.labelObject = function ( lo, once ){ + if ( !arguments.length ) { + return parent_labelObject; + } + else { + parent_labelObject = lo; + if ( that.inverse() && once !== true ) { + that.inverse().labelObject(lo, true); + } + + } + }; + this.hide = function ( val ){ + that.labelElement().classed("hidden", val); + that.linkGroup().classed("hidden", val); + if ( that.cardinalityElement() ) + that.cardinalityElement().classed("hidden", val); + }; + + // Properties + this.cardinality = function ( p ){ + if ( !arguments.length ) return cardinality; + cardinality = p; + return this; + }; + + this.cardinalityElement = function ( p ){ + if ( !arguments.length ) return cardinalityElement; + cardinalityElement = p; + return this; + }; + + this.domain = function ( p ){ + if ( !arguments.length ) return domain; + domain = p; + return this; + }; + + this.inverse = function ( p ){ + if ( !arguments.length ) return inverse; + inverse = p; + return this; + }; + + this.labelElement = function ( p ){ + if ( !arguments.length ) return labelElement; + labelElement = p; + return this; + }; + + this.labelVisible = function ( p ){ + if ( !arguments.length ) return labelVisible; + labelVisible = p; + return this; + }; + + this.link = function ( p ){ + if ( !arguments.length ) return link; + link = p; + return this; + }; + + this.linkGroup = function ( p ){ + if ( !arguments.length ) return linkGroup; + linkGroup = p; + return this; + }; + + this.linkType = function ( p ){ + if ( !arguments.length ) return linkType; + linkType = p; + return this; + }; + + this.markerElement = function ( p ){ + if ( !arguments.length ) return markerElement; + markerElement = p; + return this; + }; + + this.markerType = function ( p ){ + if ( !arguments.length ) return markerType; + markerType = p; + return this; + }; + + this.maxCardinality = function ( p ){ + if ( !arguments.length ) return maxCardinality; + maxCardinality = p; + return this; + }; + + this.minCardinality = function ( p ){ + if ( !arguments.length ) return minCardinality; + minCardinality = p; + return this; + }; + + this.range = function ( p ){ + if ( !arguments.length ) return range; + range = p; + return this; + }; + + this.redundantProperties = function ( p ){ + if ( !arguments.length ) return redundantProperties; + redundantProperties = p; + return this; + }; + + this.subproperties = function ( p ){ + if ( !arguments.length ) return subproperties; + subproperties = p; + return this; + }; + + this.superproperties = function ( p ){ + if ( !arguments.length ) return superproperties; + superproperties = p; + return this; + }; + + + // Functions + this.distanceToBorder = function ( dx, dy ){ + return rectangularElementTools.distanceToBorder(that, dx, dy); + }; + + this.linkHasMarker = function (){ + return linkType !== "dashed"; + }; + + this.markerId = function (){ + return "marker" + that.id(); + }; + + this.toggleFocus = function (){ + that.focused(!that.focused()); + labelElement.select("rect").classed("focused", that.focused()); + graph.resetSearchHighlight(); + graph.options().searchMenu().clearText(); + }; + this.getShapeElement = function (){ + return shapeElement; + }; + + this.textBlock = function (){ + return textElement; + }; + + this.redrawElement = function (){ + shapeElement.remove(); + textElement.remove(); + + that.drawLabel(that.labelElement()); + that.animateDynamicLabelWidth(graph.options().dynamicLabelWidth()); + + + // shapeElement=this.addRect(that.labelElement()); + // + // var equivalentsString = that.equivalentsString(); + // var suffixForFollowingEquivalents = equivalentsString ? "," : ""; + // + // textElement = new CenteringTextElement(labelContainer, this.backgroundColor()); + // textElement.addText(this.labelForCurrentLanguage(), "", suffixForFollowingEquivalents); + // textElement.addEquivalents(equivalentsString); + // textElement.addSubText(this.indicationString()); + + }; + + // Reused functions TODO refactor + this.draw = function ( labelGroup ){ + function attachLabel( property ){ + var labelContainer = labelGroup.append("g") + .datum(property) + .classed("label", true) + .attr("id", property.id()); + + property.drawLabel(labelContainer); + return labelContainer; + } + + if ( !that.labelVisible() ) { + return undefined; + } + if ( graph.options().dynamicLabelWidth() === true ) myWidth = Math.min(that.getMyWidth(), graph.options().maxLabelWidth()); + else myWidth = defaultWidth; + + that.labelElement(attachLabel(that)); + // Draw an inverse label and reposition both labels if necessary + if ( that.inverse() ) { + var yTransformation = (that.height() / 2) + 1 /* additional space */; + that.inverse() + .labelElement(attachLabel(that.inverse())); + + that.labelElement() + .attr("transform", "translate(" + 0 + ",-" + yTransformation + ")"); + that.inverse() + .labelElement() + .attr("transform", "translate(" + 0 + "," + yTransformation + ")"); + } + + if ( that.pinned() ) { + that.drawPin(); + } else if ( that.inverse() && that.inverse().pinned() ) { + that.inverse().drawPin(); + } + + if ( that.halo() ) + that.drawHalo(false); + + return that.labelElement(); + }; + + this.addRect = function ( labelContainer ){ + var rect = labelContainer.append("rect") + .classed(that.styleClass(), true) + .classed("property", true) + .attr("x", -that.width() / 2) + .attr("y", -that.height() / 2) + .attr("width", that.width()) + .attr("height", that.height()) + .on("mouseover", function (){ + onMouseOver(); + }) + .on("mouseout", function (){ + onMouseOut(); + }); + + rect.append("title") + .text(that.labelForCurrentLanguage()); + + if ( that.visualAttributes() ) { + rect.classed(that.visualAttributes(), true); + } + + var bgColor = that.backgroundColor(); + + if ( that.attributes().indexOf("deprecated") > -1 ) { + bgColor = undefined; + rect.classed("deprecatedproperty", true); + } else { + rect.classed("deprecatedproperty", false); + } + rect.style("fill", bgColor); + + return rect; + }; + this.drawLabel = function ( labelContainer ){ + shapeElement = this.addRect(labelContainer); + + var equivalentsString = that.equivalentsString(); + var suffixForFollowingEquivalents = equivalentsString ? "," : ""; + + var bgColor = that.backgroundColor(); + if ( that.attributes().indexOf("deprecated") > -1 ) { + bgColor = undefined; + } + textElement = new CenteringTextElement(labelContainer, bgColor); + textElement.addText(this.labelForCurrentLanguage(), "", suffixForFollowingEquivalents); + textElement.addEquivalents(equivalentsString); + textElement.addSubText(this.indicationString()); + }; + + this.equivalentsString = function (){ + var equivalentProperties = that.equivalents(); + if ( !equivalentProperties ) { + return; + } + + return equivalentProperties + .map(function ( property ){ + if ( property === undefined || typeof(property) === "string" ) { // @WORKAROUND + return "ERROR"; + } + return property.labelForCurrentLanguage(); + }) + .join(", "); + }; + + this.drawCardinality = function ( container ){ + var cardinalityText = this.generateCardinalityText(); + + if ( cardinalityText ) { + that.cardinalityElement(container); + if ( cardinalityText.indexOf("A") === 0 && cardinalityText.length === 1 ) { + + // replacing text elements to svg elements; + container.classed("cardinality", true) + .attr("text-anchor", "middle") + .append("path") + .classed("cardinality", true) + .attr("d", "m -8.8832678,-11.303355 -7.97e-4,0 0.717374,1.833297 8.22987151,21.371761 8.66826659,-21.2123526 0.797082,-1.9927054 0.02471,0 -0.8218553,1.9927054 -2.2517565,5.4201577 -12.4444429,8e-6 -2.2019394,-5.5795821 z") + .style("fill", "none") + .attr("transform", "matrix(0.5,0,0,0.5,0.5,0.5)"); + return true; + } else if ( cardinalityText.indexOf("E") === 0 && cardinalityText.length === 1 ) { + container.classed("cardinality", true) + .attr("text-anchor", "middle") + .append("path") + .classed("cardinality", true) + .attr("d", "m -5.5788451,-8.0958763 10.8749368,0 0,8.34681523 -9.5707468,0.040132 9.5707468,-0.040132 0,8.42707237 -10.9150654,0") + .style("fill", "none") + .attr("transform", "matrix(0.5,0,0,0.5,0.5,0.5)"); + return true; + } + else { + container.append("text") + .classed("cardinality", true) + .attr("text-anchor", "middle") + .attr("dy", "0.5ex") + .text(cardinalityText); + return true; // drawing successful + } + } else { + return false; + } + }; + + this.generateCardinalityText = function (){ + if ( that.cardinality() ) { + return that.cardinality(); + } else if ( that.minCardinality() || that.maxCardinality() ) { + var minBoundary = that.minCardinality() || "0"; + var maxBoundary = that.maxCardinality() || "*"; + return minBoundary + ".." + maxBoundary; + } + }; + + that.setHighlighting = function ( enable ){ + if ( that.labelElement && that.labelElement() ) { + that.labelElement().select("rect").classed("hovered", enable); + } + that.linkGroup().selectAll("path, text").classed("hovered", enable); + if ( that.markerElement() ) { + that.markerElement().select("path").classed("hovered", enable); + if ( that.cardinalityElement() ) { + that.cardinalityElement().selectAll("path").classed("hovered-MathSymbol", enable); + that.cardinalityElement().classed("hovered", enable); + } + } + var subAndSuperProperties = getSubAndSuperProperties(); + subAndSuperProperties.forEach(function ( property ){ + + if ( property.labelElement && property.labelElement() ) { + property.labelElement().select("rect") + .classed("indirect-highlighting", enable); + } + + }); + var inversed = false; + + if ( graph.ignoreOtherHoverEvents() === false ) { + if ( that.inverse() ) { + inversed = true; + } + + if ( graph.isTouchDevice() === false ) { + graph.activateHoverElementsForProperties(enable, that, inversed); + } + else { + that.labelElement().select("rect").classed("hovered", false); + that.linkGroup().selectAll("path, text").classed("hovered", false); + if ( that.markerElement() ) { + that.markerElement().select("path").classed("hovered", false); + if ( that.cardinalityElement() ) { + that.cardinalityElement().classed("hovered", false); + } + } + graph.activateHoverElementsForProperties(enable, that, inversed, true); + } + } + }; + + /** + * Combines the sub- and superproperties into a single array, because + * they're often used equivalently. + * @returns {Array} + */ + function getSubAndSuperProperties(){ + var properties = []; + + if ( that.subproperties() ) { + properties = properties.concat(that.subproperties()); + } + if ( that.superproperties() ) { + properties = properties.concat(that.superproperties()); + } + + return properties; + } + + /** + * Foregrounds the property, its inverse and the link. + */ + this.foreground = function (){ + // check for additional objects that we can highlight + if ( !that.labelElement() ) + return; + if ( that.labelElement().node().parentNode === null ) { + return; + } + var selectedLabelGroup = that.labelElement().node().parentNode, + labelContainer = selectedLabelGroup.parentNode, + selectedLinkGroup = that.linkGroup().node(), + linkContainer = that.linkGroup().node().parentNode; + if ( that.animationProcess() === false ) { + labelContainer.appendChild(selectedLabelGroup); + } + linkContainer.appendChild(selectedLinkGroup); + }; + + /** + * Foregrounds the sub- and superproperties of this property. + * This is separated from the foreground-function to prevent endless loops. + */ + function foregroundSubAndSuperProperties(){ + var subAndSuperProperties = getSubAndSuperProperties(); + + subAndSuperProperties.forEach(function ( property ){ + if ( property.foreground ) property.foreground(); + }); + } + + function onMouseOver(){ + if ( that.mouseEntered() || ignoreLocalHoverEvents === true ) { + return; + } + that.mouseEntered(true); + that.setHighlighting(true); + that.foreground(); + foregroundSubAndSuperProperties(); + } + + function onMouseOut(){ + that.mouseEntered(false); + that.setHighlighting(false); + } + + this.drawPin = function (){ + that.pinned(true); + if ( graph.options().dynamicLabelWidth() === true ) myWidth = that.getMyWidth(); + else myWidth = defaultWidth; + + if ( that.inverse() ) { + // check which element is rendered on top and add a pin to it + var tr_that = that.labelElement().attr("transform"); + var tr_inv = that.inverse().labelElement().attr("transform"); + + var thatY = /translate\(\s*([^\s,)]+)[ ,]([^\s,)]+)/.exec(tr_that)[2]; + var invY = /translate\(\s*([^\s,)]+)[ ,]([^\s,)]+)/.exec(tr_inv)[2]; + + if ( thatY < invY ) + pinGroupElement = drawTools.drawPin(that.labelElement(), -0.5 * that.width() + 10, -25, this.removePin, graph.options().showDraggerObject, graph.options().useAccuracyHelper()); + else + pinGroupElement = drawTools.drawPin(that.inverse().labelElement(), -0.5 * that.inverse().width() + 10, -25, this.removePin, graph.options().showDraggerObject, graph.options().useAccuracyHelper()); + + } + else { + pinGroupElement = drawTools.drawPin(that.labelElement(), -0.5 * that.width() + 10, -25, this.removePin, graph.options().showDraggerObject, graph.options().useAccuracyHelper()); + } + + + }; + + /** + * Removes the pin and refreshs the graph to update the force layout. + */ + this.removePin = function (){ + that.pinned(false); + if ( pinGroupElement ) { + pinGroupElement.remove(); + } + graph.updateStyle(); + }; + + this.removeHalo = function (){ + that.halo(false); + if ( haloGroupElement ) { + haloGroupElement.remove(); + haloGroupElement = null; + } + }; + + this.animationProcess = function (){ + var animRuns = false; + if ( that.getHalos() ) { + var haloGr = that.getHalos(); + var haloEls = haloGr.selectAll(".searchResultA"); + animRuns = haloGr.attr("animationRunning"); + + if ( typeof animRuns !== "boolean" ) { + // parse this to a boolean value + animRuns = (animRuns === 'true'); + } + if ( animRuns === false ) { + haloEls.classed("searchResultA", false); + haloEls.classed("searchResultB", true); + } + } + return animRuns; + }; + + this.drawHalo = function ( pulseAnimation ){ + that.halo(true); + var offset = 0; + if ( that.labelElement() && that.labelElement().node() ) { + var labelNode = that.labelElement().node(); + var labelContainer = labelNode.parentNode; + // do this only if animation is not running + if ( that.animationProcess() === false ) + labelContainer.appendChild(labelNode); + } + haloGroupElement = drawTools.drawRectHalo(that, that.width(), that.height(), offset); + if ( haloGroupElement ) { + var haloNode = haloGroupElement.node(); + var haloContainer = haloNode.parentNode; + haloContainer.appendChild(haloNode); + } + var selectedNode; + var nodeContainer; + if ( that.pinned() ) { + selectedNode = pinGroupElement.node(); + nodeContainer = selectedNode.parentNode; + nodeContainer.appendChild(selectedNode); + } + if ( that.inverse() && that.inverse().pinned() ) { + if ( that.inverse().getPin() ) { + selectedNode = that.inverse().getPin().node(); + nodeContainer = selectedNode.parentNode; + nodeContainer.appendChild(selectedNode); + } + } + if ( pulseAnimation === false ) { + var pulseItem = haloGroupElement.selectAll(".searchResultA"); + pulseItem.classed("searchResultA", false); + pulseItem.classed("searchResultB", true); + pulseItem.attr("animationRunning", false); + } + }; + + this.getMyWidth = function (){ + var text = that.labelForCurrentLanguage(); + myWidth = measureTextWidth(text, "text") + 20; + // check for sub names; + var indicatorText = that.indicationString(); + var indicatorWidth = measureTextWidth(indicatorText, "subtext") + 20; + if ( indicatorWidth > myWidth ) + myWidth = indicatorWidth; + + return myWidth; + }; + + function measureTextWidth( text, textStyle ){ + // Set a default value + if ( !textStyle ) { + textStyle = "text"; + } + var d = d3.select("body") + .append("div") + .attr("class", textStyle) + .attr("id", "width-test") // tag this element to identify it + .attr("style", "position:absolute; float:left; white-space:nowrap; visibility:hidden;") + .text(text), + w = document.getElementById("width-test").offsetWidth; + d.remove(); + return w; + } + + this.textWidth = function (){ + return myWidth; + }; + this.width = function (){ + return myWidth; + }; + + this.animateDynamicLabelWidth = function ( dynamic ){ + that.removeHalo(); + if ( shapeElement === undefined ) {// this handles setOperatorProperties which dont have a shapeElement! + return; + } + + var h = that.height(); + if ( dynamic === true ) { + myWidth = Math.min(that.getMyWidth(), graph.options().maxLabelWidth()); + shapeElement.transition().tween("attr", function (){ + }) + .ease('linear') + .duration(100) + .attr({ x: -myWidth / 2, y: -h / 2, width: myWidth, height: h }) + .each("end", function (){ + that.updateTextElement(); + }); + } else { + // Static width for property labels = 80 + myWidth = defaultWidth; + that.updateTextElement(); + shapeElement.transition().tween("attr", function (){ + }) + .ease('linear') + .duration(100) + .attr({ x: -myWidth / 2, y: -h / 2, width: myWidth, height: h }); + } + if ( that.pinned() === true && pinGroupElement ) { + var dx = -0.5 * myWidth + 10, + dy = -25; + pinGroupElement.transition() + .tween("attr.translate", function (){ + }) + .attr("transform", "translate(" + dx + "," + dy + ")") + .ease('linear') + .duration(100); + } + }; + + this.redrawLabelText = function (){ + textElement.remove(); + that.addTextLabelElement(); + that.animateDynamicLabelWidth(graph.options().dynamicLabelWidth()); + shapeElement.select("title").text(that.labelForCurrentLanguage()); + }; + + this.addTextLabelElement = function (){ + var labelContainer = that.labelElement(); + + var equivalentsString = that.equivalentsString(); + var suffixForFollowingEquivalents = equivalentsString ? "," : ""; + + textElement = new CenteringTextElement(labelContainer, this.backgroundColor()); + textElement.addText(this.labelForCurrentLanguage(), "", suffixForFollowingEquivalents); + textElement.addEquivalents(equivalentsString); + textElement.addSubText(this.indicationString()); + }; + + this.updateTextElement = function (){ + textElement.updateAllTextElements(); + }; + this.enableEditing = function ( autoEditing ){ + if ( autoEditing === false ) + return; + that.raiseDoubleClickEdit(true); + }; + + this.raiseDoubleClickEdit = function ( forceIRISync ){ + d3.selectAll(".foreignelements").remove(); + if ( that.labelElement() === undefined || this.type() === "owl:disjointWith" || this.type() === "rdfs:subClassOf" ) { + console.log("No Container found"); + return; + } + if ( fobj !== undefined ) { + that.labelElement().selectAll(".foreignelements").remove(); + } + backupFullIri = undefined; + graph.options().focuserModule().handle(undefined); + graph.options().focuserModule().handle(that); + that.editingTextElement = true; + ignoreLocalHoverEvents = true; + that.labelElement().selectAll("rect").classed("hoveredForEditing", true); + that.frozen(true); + graph.killDelayedTimer(); + graph.ignoreOtherHoverEvents(false); + fobj = that.labelElement().append("foreignObject") + .attr("x", -0.5 * that.textWidth()) + .attr("y", -13) + .attr("height", 25) + .attr("class", "foreignelements") + .on("dragstart", function (){ + return false; + }) // remove drag operations of text element) + .attr("width", that.textWidth() - 2); + // adding a Style to the fObject + // + // + // + var editText = fobj.append("xhtml:input") + .attr("class", "nodeEditSpan") + .attr("id", that.id()) + .attr("align", "center") + .attr("contentEditable", "true") + .on("dragstart", function (){ + return false; + }); // remove drag operations of text element) + + var bgColor = '#f00'; + var txtWidth = that.textWidth() - 2; + editText.style({ + // 'line-height': '30px', + 'align': 'center', + 'color': 'black', + 'width': txtWidth + "px", + 'background-color': bgColor, + 'border-bottom': '2px solid black' + }); + var txtNode = editText.node(); + txtNode.value = that.labelForCurrentLanguage(); + txtNode.focus(); + txtNode.select(); + if ( d3.event.stopPropagation ) d3.event.stopPropagation(); + if ( d3.event.sourceEvent && d3.event.sourceEvent.stopPropagation ) d3.event.sourceEvent.stopPropagation(); + + // add some events that relate to this object + editText.on("click", function (){ + if ( d3.event.stopPropagation ) d3.event.stopPropagation(); + if ( d3.event.sourceEvent && d3.event.sourceEvent.stopPropagation ) d3.event.sourceEvent.stopPropagation(); + + }); + // // remove hover Events for now; + editText.on("mouseout", function (){ + if ( d3.event.stopPropagation ) d3.event.stopPropagation(); + if ( d3.event.sourceEvent && d3.event.sourceEvent.stopPropagation ) d3.event.sourceEvent.stopPropagation(); + }); + editText.on("mousedown", function (){ + if ( d3.event.stopPropagation ) d3.event.stopPropagation(); + if ( d3.event.sourceEvent && d3.event.sourceEvent.stopPropagation ) d3.event.sourceEvent.stopPropagation(); + }) + .on("keydown", function (){ + + if ( d3.event.keyCode === 13 ) { + this.blur(); + that.frozen(false); // << releases the not after selection + that.locked(false); + } + }) + .on("keyup", function (){ + if ( forceIRISync ) { + var labelName = editText.node().value; + var resourceName = labelName.replaceAll(" ", "_"); + var syncedIRI = that.baseIri() + resourceName; + backupFullIri = syncedIRI; + + d3.select("#element_iriEditor").node().title = syncedIRI; + d3.select("#element_iriEditor").node().value = graph.options().prefixModule().getPrefixRepresentationForFullURI(syncedIRI); + } + d3.select("#element_labelEditor").node().value = editText.node().value; + + }) + .on("blur", function (){ + + + that.editingTextElement = false; + ignoreLocalHoverEvents = false; + that.labelElement().selectAll("rect").classed("hoveredForEditing", false); + var newLabel = editText.node().value; + that.labelElement().selectAll(".foreignelements").remove(); + // that.setLabelForCurrentLanguage(classNameConvention(editText.node().value)); + that.label(newLabel); + that.backupLabel(newLabel); + that.redrawLabelText(); + updateHoverElements(true); + graph.showHoverElementsAfterAnimation(that, false); + graph.ignoreOtherHoverEvents(false); + + + that.frozen(graph.paused()); + that.locked(graph.paused()); + that.domain().frozen(graph.paused()); + that.domain().locked(graph.paused()); + that.range().frozen(graph.paused()); + that.range().locked(graph.paused()); + graph.removeEditElements(); + if ( backupFullIri ) { + // console.log("Checking if element is Identical ?"); + var sanityCheckResult = graph.options().editSidebar().checkProperIriChange(that, backupFullIri); + if ( sanityCheckResult !== false ) { + graph.options().warningModule().showWarning("Already seen this property", + "Input IRI: " + backupFullIri + " for element: " + that.labelForCurrentLanguage() + " already been set", + "Continuing with duplicate property!", 1, false, sanityCheckResult); + } + that.iri(backupFullIri); + } + graph.options().focuserModule().handle(undefined); + graph.options().focuserModule().handle(that); + graph.updatePropertyDraggerElements(that); + + + }); // add a foreiner element to this thing; + + }; + + // update hover elements + function updateHoverElements( enable ){ + if ( graph.ignoreOtherHoverEvents() === false ) { + var inversed = false; + if ( that.inverse() ) { + inversed = true; + } + if ( enable === true ) { + graph.activateHoverElementsForProperties(enable, that, inversed); + } + } + } + + that.copyInformation = function ( other ){ + that.label(other.label()); + that.iri(other.iri()); + that.baseIri(other.baseIri()); + if ( other.type() === "owl:ObjectProperty" || + other.type() === "owl:DatatypeProperty" ) { + that.backupLabel(other.label()); + // console.log("copied backup label"+that.backupLabel()); + } + if ( other.backupLabel() !== undefined ) { + that.backupLabel(other.backupLabel()); + } + }; + + forceLayoutNodeFunctions.addTo(this); + }; + + Base.prototype = Object.create(BaseElement.prototype); + Base.prototype.constructor = Base; + + Base.prototype.height = function (){ + return labelHeight; + }; + + Base.prototype.width = function (){ + return labelWidth; + }; + + Base.prototype.actualRadius = function (){ + return smallestRadius; + }; + + Base.prototype.textWidth = Base.prototype.width; + + + return Base; +}()); diff --git a/src/webvowl/js/elements/properties/implementations/OwlAllValuesFromProperty.js b/src/webvowl/js/elements/properties/implementations/OwlAllValuesFromProperty.js new file mode 100644 index 0000000000000000000000000000000000000000..e607d5b9cd343e0f4630467ab6f3a4939af78f24 --- /dev/null +++ b/src/webvowl/js/elements/properties/implementations/OwlAllValuesFromProperty.js @@ -0,0 +1,32 @@ +var BaseProperty = require("../BaseProperty"); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseProperty.apply(this, arguments); + + var superGenerateCardinalityText = this.generateCardinalityText; + + this.linkType("values-from") + .markerType("filled values-from") + .styleClass("allvaluesfromproperty") + .type("owl:allValuesFrom"); + + this.generateCardinalityText = function (){ + var cardinalityText = "A"; + + var superCardinalityText = superGenerateCardinalityText(); + if ( superCardinalityText ) { + cardinalityText += ", " + superCardinalityText; + } + + return cardinalityText; + }; + }; + o.prototype = Object.create(BaseProperty.prototype); + o.prototype.constructor = o; + + return o; +}()); + + diff --git a/src/webvowl/js/elements/properties/implementations/OwlDatatypeProperty.js b/src/webvowl/js/elements/properties/implementations/OwlDatatypeProperty.js new file mode 100644 index 0000000000000000000000000000000000000000..45e6ee22ad89bd75fe75d1faf3eba11fe38a98be --- /dev/null +++ b/src/webvowl/js/elements/properties/implementations/OwlDatatypeProperty.js @@ -0,0 +1,16 @@ +var BaseProperty = require("../BaseProperty"); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseProperty.apply(this, arguments); + + this.attributes(["datatype"]) + .styleClass("datatypeproperty") + .type("owl:DatatypeProperty"); + }; + o.prototype = Object.create(BaseProperty.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/properties/implementations/OwlDeprecatedProperty.js b/src/webvowl/js/elements/properties/implementations/OwlDeprecatedProperty.js new file mode 100644 index 0000000000000000000000000000000000000000..fe6eee007d9c41e37aae72e454951e7098d41b8f --- /dev/null +++ b/src/webvowl/js/elements/properties/implementations/OwlDeprecatedProperty.js @@ -0,0 +1,16 @@ +var BaseProperty = require("../BaseProperty"); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseProperty.apply(this, arguments); + + this.attributes(["deprecated"]) + .styleClass("deprecatedproperty") + .type("owl:DeprecatedProperty"); + }; + o.prototype = Object.create(BaseProperty.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/properties/implementations/OwlDisjointWith.js b/src/webvowl/js/elements/properties/implementations/OwlDisjointWith.js new file mode 100644 index 0000000000000000000000000000000000000000..825306d74bff24d3b4516a49c0051ea6f1b1836f --- /dev/null +++ b/src/webvowl/js/elements/properties/implementations/OwlDisjointWith.js @@ -0,0 +1,56 @@ +var BaseProperty = require("../BaseProperty"); +var CenteringTextElement = require("../../../util/CenteringTextElement"); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseProperty.apply(this, arguments); + + var label = "Disjoint With"; + var shapeElement; + // Disallow overwriting the label + this.label = function ( p ){ + if ( !arguments.length ) return label; + return this; + }; + + this.linkType("dashed") + .styleClass("disjointwith") + .type("owl:disjointWith"); + + this.drawLabel = function ( labelContainer ){ + shapeElement = this.addRect(labelContainer); + + labelContainer.append("circle") + .classed("symbol", true) + .classed("fineline", true) + .classed("embedded", true) + .attr("cx", -12.5) + .attr("r", 10); + + labelContainer.append("circle") + .classed("symbol", true) + .classed("fineline", true) + .classed("embedded", true) + .attr("cx", 12.5) + .attr("r", 10); + + var textElement = new CenteringTextElement(labelContainer, this.backgroundColor()); + if ( !graph.options().compactNotation() ) { + textElement.addSubText("disjoint"); + } + textElement.translation(0, 20); + }; + this.getShapeElement = function (){ + return shapeElement; + }; + this.markerElement = function (){ + return undefined; + }; + + }; + o.prototype = Object.create(BaseProperty.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/properties/implementations/OwlEquivalentProperty.js b/src/webvowl/js/elements/properties/implementations/OwlEquivalentProperty.js new file mode 100644 index 0000000000000000000000000000000000000000..644c1911c56d6dd82c5fdf0a00aa3e686fe0ec22 --- /dev/null +++ b/src/webvowl/js/elements/properties/implementations/OwlEquivalentProperty.js @@ -0,0 +1,15 @@ +var BaseProperty = require("../BaseProperty"); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseProperty.apply(this, arguments); + + this.styleClass("equivalentproperty") + .type("owl:equivalentProperty"); + }; + o.prototype = Object.create(BaseProperty.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/properties/implementations/OwlFunctionalProperty.js b/src/webvowl/js/elements/properties/implementations/OwlFunctionalProperty.js new file mode 100644 index 0000000000000000000000000000000000000000..19da91d4ef2ec5b8a3c24c942b559781d77908d0 --- /dev/null +++ b/src/webvowl/js/elements/properties/implementations/OwlFunctionalProperty.js @@ -0,0 +1,16 @@ +var BaseProperty = require("../BaseProperty"); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseProperty.apply(this, arguments); + + this.attributes(["functional"]) + .styleClass("functionalproperty") + .type("owl:FunctionalProperty"); + }; + o.prototype = Object.create(BaseProperty.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/properties/implementations/OwlInverseFunctionalProperty.js b/src/webvowl/js/elements/properties/implementations/OwlInverseFunctionalProperty.js new file mode 100644 index 0000000000000000000000000000000000000000..414ce012582444e9926a4eae17010365f96c06db --- /dev/null +++ b/src/webvowl/js/elements/properties/implementations/OwlInverseFunctionalProperty.js @@ -0,0 +1,16 @@ +var BaseProperty = require("../BaseProperty"); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseProperty.apply(this, arguments); + + this.attributes(["inverse functional"]) + .styleClass("inversefunctionalproperty") + .type("owl:InverseFunctionalProperty"); + }; + o.prototype = Object.create(BaseProperty.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/properties/implementations/OwlObjectProperty.js b/src/webvowl/js/elements/properties/implementations/OwlObjectProperty.js new file mode 100644 index 0000000000000000000000000000000000000000..da47a7c2174ab1319760d2204384c7c6f435e4e9 --- /dev/null +++ b/src/webvowl/js/elements/properties/implementations/OwlObjectProperty.js @@ -0,0 +1,18 @@ +var BaseProperty = require("../BaseProperty"); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseProperty.apply(this, arguments); + + this.attributes(["object"]) + .styleClass("objectproperty") + .type("owl:ObjectProperty"); + }; + o.prototype = Object.create(BaseProperty.prototype); + o.prototype.constructor = o; + + return o; +}()); + + diff --git a/src/webvowl/js/elements/properties/implementations/OwlSomeValuesFromProperty.js b/src/webvowl/js/elements/properties/implementations/OwlSomeValuesFromProperty.js new file mode 100644 index 0000000000000000000000000000000000000000..2f387193f867fd9ffa6b90c310ee4ce6da3e64e0 --- /dev/null +++ b/src/webvowl/js/elements/properties/implementations/OwlSomeValuesFromProperty.js @@ -0,0 +1,32 @@ +var BaseProperty = require("../BaseProperty"); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseProperty.apply(this, arguments); + + var superGenerateCardinalityText = this.generateCardinalityText; + + this.linkType("values-from") + .markerType("filled values-from") + .styleClass("somevaluesfromproperty") + .type("owl:someValuesFrom"); + + this.generateCardinalityText = function (){ + var cardinalityText = "E"; + + var superCardinalityText = superGenerateCardinalityText(); + if ( superCardinalityText ) { + cardinalityText += ", " + superCardinalityText; + } + + return cardinalityText; + }; + }; + o.prototype = Object.create(BaseProperty.prototype); + o.prototype.constructor = o; + + return o; +}()); + + diff --git a/src/webvowl/js/elements/properties/implementations/OwlSymmetricProperty.js b/src/webvowl/js/elements/properties/implementations/OwlSymmetricProperty.js new file mode 100644 index 0000000000000000000000000000000000000000..a3255715b831f8497baf0f3e35be925ddaf54000 --- /dev/null +++ b/src/webvowl/js/elements/properties/implementations/OwlSymmetricProperty.js @@ -0,0 +1,16 @@ +var BaseProperty = require("../BaseProperty"); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseProperty.apply(this, arguments); + + this.attributes(["symmetric"]) + .styleClass("symmetricproperty") + .type("owl:SymmetricProperty"); + }; + o.prototype = Object.create(BaseProperty.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/properties/implementations/OwlTransitiveProperty.js b/src/webvowl/js/elements/properties/implementations/OwlTransitiveProperty.js new file mode 100644 index 0000000000000000000000000000000000000000..7a43a43801cafe935e0b90be08ed0ca230dc2c97 --- /dev/null +++ b/src/webvowl/js/elements/properties/implementations/OwlTransitiveProperty.js @@ -0,0 +1,16 @@ +var BaseProperty = require("../BaseProperty"); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseProperty.apply(this, arguments); + + this.attributes(["transitive"]) + .styleClass("transitiveproperty") + .type("owl:TransitiveProperty"); + }; + o.prototype = Object.create(BaseProperty.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/properties/implementations/RdfProperty.js b/src/webvowl/js/elements/properties/implementations/RdfProperty.js new file mode 100644 index 0000000000000000000000000000000000000000..c7c2b53bbc62c25676075b270c5f78271a37e642 --- /dev/null +++ b/src/webvowl/js/elements/properties/implementations/RdfProperty.js @@ -0,0 +1,16 @@ +var BaseProperty = require("../BaseProperty"); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseProperty.apply(this, arguments); + + this.attributes(["rdf"]) + .styleClass("rdfproperty") + .type("rdf:Property"); + }; + o.prototype = Object.create(BaseProperty.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/properties/implementations/RdfsSubClassOf.js b/src/webvowl/js/elements/properties/implementations/RdfsSubClassOf.js new file mode 100644 index 0000000000000000000000000000000000000000..25e50165212dba05f1fdfc3a4cf170d38a90bb0f --- /dev/null +++ b/src/webvowl/js/elements/properties/implementations/RdfsSubClassOf.js @@ -0,0 +1,36 @@ +var BaseProperty = require("../BaseProperty"); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseProperty.apply(this, arguments); + + var that = this, + superDrawFunction = that.draw, + label = "Subclass of"; + + this.draw = function ( labelGroup ){ + that.labelVisible(!graph.options().compactNotation()); + return superDrawFunction(labelGroup); + }; + + // Disallow overwriting the label + this.label = function ( p ){ + if ( !arguments.length ) return label; + return this; + }; + + this.linkType("dotted") + .markerType("white") + .styleClass("subclass") + .type("rdfs:subClassOf"); + + that.baseIri("http://www.w3.org/2000/01/rdf-schema#"); + that.iri("http://www.w3.org/2000/01/rdf-schema#subClassOf"); + + }; + o.prototype = Object.create(BaseProperty.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/properties/implementations/SetOperatorProperty.js b/src/webvowl/js/elements/properties/implementations/SetOperatorProperty.js new file mode 100644 index 0000000000000000000000000000000000000000..a0920b3243ea9e81fc1862a7fc3c320833fe804e --- /dev/null +++ b/src/webvowl/js/elements/properties/implementations/SetOperatorProperty.js @@ -0,0 +1,18 @@ +var BaseProperty = require("../BaseProperty"); + +module.exports = (function (){ + + var o = function ( graph ){ + BaseProperty.apply(this, arguments); + + this.labelVisible(false) + .linkType("dashed") + .markerType("white") + .styleClass("setoperatorproperty") + .type("setOperatorProperty"); + }; + o.prototype = Object.create(BaseProperty.prototype); + o.prototype.constructor = o; + + return o; +}()); diff --git a/src/webvowl/js/elements/properties/propertyMap.js b/src/webvowl/js/elements/properties/propertyMap.js new file mode 100644 index 0000000000000000000000000000000000000000..13e8b4a967efbb0d4f382d94b2c90a7f21c11eca --- /dev/null +++ b/src/webvowl/js/elements/properties/propertyMap.js @@ -0,0 +1,23 @@ +var properties = []; +properties.push(require("./implementations/OwlAllValuesFromProperty")); +properties.push(require("./implementations/OwlDatatypeProperty")); +properties.push(require("./implementations/OwlDeprecatedProperty")); +properties.push(require("./implementations/OwlDisjointWith")); +properties.push(require("./implementations/OwlEquivalentProperty")); +properties.push(require("./implementations/OwlFunctionalProperty")); +properties.push(require("./implementations/OwlInverseFunctionalProperty")); +properties.push(require("./implementations/OwlObjectProperty")); +properties.push(require("./implementations/OwlSomeValuesFromProperty")); +properties.push(require("./implementations/OwlSymmetricProperty")); +properties.push(require("./implementations/OwlTransitiveProperty")); +properties.push(require("./implementations/RdfProperty")); +properties.push(require("./implementations/RdfsSubClassOf")); +properties.push(require("./implementations/SetOperatorProperty")); + +var map = d3.map(properties, function ( Prototype ){ + return new Prototype().type(); +}); + +module.exports = function (){ + return map; +}; diff --git a/src/webvowl/js/elements/rectangularElementTools.js b/src/webvowl/js/elements/rectangularElementTools.js new file mode 100644 index 0000000000000000000000000000000000000000..c455651d761c2f0ff00739c380fd946a4ae9c071 --- /dev/null +++ b/src/webvowl/js/elements/rectangularElementTools.js @@ -0,0 +1,25 @@ +var tools = {}; +module.exports = function (){ + return tools; +}; + +tools.distanceToBorder = function ( rect, dx, dy ){ + var width = rect.width(), + height = rect.height(); + + var innerDistance, + m_link = Math.abs(dy / dx), + m_rect = height / width; + + if ( m_link <= m_rect ) { + var timesX = dx / (width / 2), + rectY = dy / timesX; + innerDistance = Math.sqrt(Math.pow(width / 2, 2) + Math.pow(rectY, 2)); + } else { + var timesY = dy / (height / 2), + rectX = dx / timesY; + innerDistance = Math.sqrt(Math.pow(height / 2, 2) + Math.pow(rectX, 2)); + } + + return innerDistance; +}; diff --git a/src/webvowl/js/entry.js b/src/webvowl/js/entry.js new file mode 100644 index 0000000000000000000000000000000000000000..5e738cd575139f7b7bfb6c5ae89343de4ba5122a --- /dev/null +++ b/src/webvowl/js/entry.js @@ -0,0 +1,50 @@ +require("../css/vowl.css"); + +var nodeMap = require("./elements/nodes/nodeMap")(); +var propertyMap = require("./elements/properties/propertyMap")(); + + +var webvowl = {}; +webvowl.graph = require("./graph"); +webvowl.options = require("./options"); +webvowl.version = "@@WEBVOWL_VERSION"; + +webvowl.util = {}; +webvowl.util.constants = require("./util/constants"); +webvowl.util.languageTools = require("./util/languageTools"); +webvowl.util.elementTools = require("./util/elementTools"); +webvowl.util.prefixTools = require("./util/prefixRepresentationModule"); +webvowl.modules = {}; +webvowl.modules.colorExternalsSwitch = require("./modules/colorExternalsSwitch"); +webvowl.modules.compactNotationSwitch = require("./modules/compactNotationSwitch"); +webvowl.modules.datatypeFilter = require("./modules/datatypeFilter"); +webvowl.modules.disjointFilter = require("./modules/disjointFilter"); +webvowl.modules.focuser = require("./modules/focuser"); +webvowl.modules.emptyLiteralFilter = require("./modules/emptyLiteralFilter"); +webvowl.modules.nodeDegreeFilter = require("./modules/nodeDegreeFilter"); +webvowl.modules.nodeScalingSwitch = require("./modules/nodeScalingSwitch"); +webvowl.modules.objectPropertyFilter = require("./modules/objectPropertyFilter"); +webvowl.modules.pickAndPin = require("./modules/pickAndPin"); +webvowl.modules.selectionDetailsDisplayer = require("./modules/selectionDetailsDisplayer"); +webvowl.modules.setOperatorFilter = require("./modules/setOperatorFilter"); +webvowl.modules.statistics = require("./modules/statistics"); +webvowl.modules.subclassFilter = require("./modules/subclassFilter"); + + +webvowl.nodes = {}; +nodeMap.entries().forEach(function ( entry ){ + mapEntryToIdentifier(webvowl.nodes, entry); +}); + +webvowl.properties = {}; +propertyMap.entries().forEach(function ( entry ){ + mapEntryToIdentifier(webvowl.properties, entry); +}); + +function mapEntryToIdentifier( map, entry ){ + var identifier = entry.key.replace(":", "").toLowerCase(); + map[identifier] = entry.value; +} + + +module.exports = webvowl; diff --git a/src/webvowl/js/graph.js b/src/webvowl/js/graph.js new file mode 100644 index 0000000000000000000000000000000000000000..a519e8e12e663ecefd67f3ac885c4a4ccd6650d8 --- /dev/null +++ b/src/webvowl/js/graph.js @@ -0,0 +1,3899 @@ +var _ = require("lodash/core"); +var math = require("./util/math")(); +var linkCreator = require("./parsing/linkCreator")(); +var elementTools = require("./util/elementTools")(); +// add some maps for nodes and properties -- used for object generation +var nodePrototypeMap = require("./elements/nodes/nodeMap")(); +var propertyPrototypeMap = require("./elements/properties/propertyMap")(); + + +module.exports = function ( graphContainerSelector ){ + var graph = {}, + CARDINALITY_HDISTANCE = 20, + CARDINALITY_VDISTANCE = 10, + curveFunction = d3.svg.line() + .x(function ( d ){ + return d.x; + }) + .y(function ( d ){ + return d.y; + }) + .interpolate("cardinal"), + options = require("./options")(), + parser = require("./parser")(graph), + language = "default", + paused = false, + // Container for visual elements + graphContainer, + nodeContainer, + labelContainer, + cardinalityContainer, + linkContainer, + // Visual elements + nodeElements, + initialLoad = true, + updateRenderingDuringSimulation = false, + labelGroupElements, + linkGroups, + linkPathElements, + cardinalityElements, + // Internal data + classNodes, + labelNodes, + links, + properties, + unfilteredData, + // Graph behaviour + force, + dragBehaviour, + zoomFactor = 1.0, + centerGraphViewOnLoad = false, + transformAnimation = false, + graphTranslation = [0, 0], + graphUpdateRequired = false, + pulseNodeIds = [], + nodeArrayForPulse = [], + nodeMap = [], + locationId = 0, + defaultZoom = 1.0, + defaultTargetZoom = 0.8, + global_dof = -1, + touchDevice = false, + last_touch_time, + originalD3_dblClickFunction = null, + originalD3_touchZoomFunction = null, + + // editing elements + deleteGroupElement, + addDataPropertyGroupElement, + editContainer, + draggerLayer = null, + draggerObjectsArray = [], + delayedHider, + nodeFreezer, + hoveredNodeElement = null, + currentlySelectedNode = null, + hoveredPropertyElement = null, + draggingStarted = false, + frozenDomainForPropertyDragger, + frozenRangeForPropertyDragger, + + eP = 0, // id for new properties + eN = 0, // id for new Nodes + editMode = true, + debugContainer = d3.select("#FPS_Statistics"), + finishedLoadingSequence = false, + + ignoreOtherHoverEvents = false, + forceNotZooming = false, + now, then, // used for fps computation + showFPS = false, + seenEditorHint = false, + seenFilterWarning = false, + showFilterWarning = false, + + keepDetailsCollapsedOnLoading = true, + adjustingGraphSize = false, + showReloadButtonAfterLayoutOptimization = false, + zoom; + //var prefixModule=require("./prefixRepresentationModule")(graph); + var NodePrototypeMap = createLowerCasePrototypeMap(nodePrototypeMap); + var PropertyPrototypeMap = createLowerCasePrototypeMap(propertyPrototypeMap); + var classDragger = require("./classDragger")(graph); + var rangeDragger = require("./rangeDragger")(graph); + var domainDragger = require("./domainDragger")(graph); + var shadowClone = require("./shadowClone")(graph); + + graph.math = function (){ + return math; + }; + /** --------------------------------------------------------- **/ + /** -- getter and setter definitions -- **/ + /** --------------------------------------------------------- **/ + graph.isEditorMode = function (){ + return editMode; + }; + graph.getGlobalDOF = function (){ + return global_dof; + }; + graph.setGlobalDOF = function ( val ){ + global_dof = val; + }; + + graph.updateZoomSliderValueFromOutside = function (){ + graph.options().zoomSlider().updateZoomSliderValue(zoomFactor); + }; + + graph.setDefaultZoom = function ( val ){ + defaultZoom = val; + graph.reset(); + graph.options().zoomSlider().updateZoomSliderValue(defaultZoom); + }; + graph.setTargetZoom = function ( val ){ + defaultTargetZoom = val; + }; + graph.graphOptions = function (){ + return options; + }; + + graph.scaleFactor = function (){ + return zoomFactor; + }; + graph.translation = function (){ + return graphTranslation; + }; + + // Returns the visible nodes + graph.graphNodeElements = function (){ + return nodeElements; + }; + // Returns the visible Label Nodes + graph.graphLabelElements = function (){ + return labelNodes; + }; + + graph.graphLinkElements = function (){ + return links; + }; + + graph.setSliderZoom = function ( val ){ + + var cx = 0.5 * graph.options().width(); + var cy = 0.5 * graph.options().height(); + var cp = getWorldPosFromScreen(cx, cy, graphTranslation, zoomFactor); + var sP = [cp.x, cp.y, graph.options().height() / zoomFactor]; + var eP = [cp.x, cp.y, graph.options().height() / val]; + var pos_intp = d3.interpolateZoom(sP, eP); + + graphContainer.attr("transform", transform(sP, cx, cy)) + .transition() + .duration(1) + .attrTween("transform", function (){ + return function ( t ){ + return transform(pos_intp(t), cx, cy); + }; + }) + .each("end", function (){ + graphContainer.attr("transform", "translate(" + graphTranslation + ")scale(" + zoomFactor + ")"); + zoom.translate(graphTranslation); + zoom.scale(zoomFactor); + graph.options().zoomSlider().updateZoomSliderValue(zoomFactor); + }); + }; + + + graph.setZoom = function ( value ){ + zoom.scale(value); + }; + + graph.setTranslation = function ( translation ){ + zoom.translate([translation[0], translation[1]]); + }; + + graph.options = function (){ + return options; + }; + // search functionality + graph.getUpdateDictionary = function (){ + return parser.getDictionary(); + }; + + graph.language = function ( newLanguage ){ + if ( !arguments.length ) return language; + + // Just update if the language changes + if ( language !== newLanguage ) { + language = newLanguage || "default"; + redrawContent(); + recalculatePositions(); + graph.options().searchMenu().requestDictionaryUpdate(); + graph.resetSearchHighlight(); + } + return graph; + }; + + + /** --------------------------------------------------------- **/ + /** graph / rendering related functions **/ + /** --------------------------------------------------------- **/ + + // Initializes the graph. + function initializeGraph(){ + + options.graphContainerSelector(graphContainerSelector); + var moved = false; + force = d3.layout.force() + .on("tick", hiddenRecalculatePositions); + + dragBehaviour = d3.behavior.drag() + .origin(function ( d ){ + return d; + }) + .on("dragstart", function ( d ){ + d3.event.sourceEvent.stopPropagation(); // Prevent panning + graph.ignoreOtherHoverEvents(true); + if ( d.type && d.type() === "Class_dragger" ) { + classDragger.mouseButtonPressed = true; + clearTimeout(delayedHider); + classDragger.selectedViaTouch(true); + d.parentNode().locked(true); + draggingStarted = true; + } else if ( d.type && d.type() === "Range_dragger" ) { + graph.ignoreOtherHoverEvents(true); + clearTimeout(delayedHider); + frozenDomainForPropertyDragger = shadowClone.parentNode().domain(); + frozenRangeForPropertyDragger = shadowClone.parentNode().range(); + shadowClone.setInitialPosition(); + shadowClone.hideClone(false); + shadowClone.hideParentProperty(true); + shadowClone.updateElement(); + deleteGroupElement.classed("hidden", true); + addDataPropertyGroupElement.classed("hidden", true); + frozenDomainForPropertyDragger.frozen(true); + frozenDomainForPropertyDragger.locked(true); + frozenRangeForPropertyDragger.frozen(true); + frozenRangeForPropertyDragger.locked(true); + domainDragger.updateElement(); + domainDragger.mouseButtonPressed = true; + rangeDragger.updateElement(); + rangeDragger.mouseButtonPressed = true; + // shadowClone.setPosition(d.x, d.y); + + + } else if ( d.type && d.type() === "Domain_dragger" ) { + graph.ignoreOtherHoverEvents(true); + clearTimeout(delayedHider); + frozenDomainForPropertyDragger = shadowClone.parentNode().domain(); + frozenRangeForPropertyDragger = shadowClone.parentNode().range(); + shadowClone.setInitialPosition(); + shadowClone.hideClone(false); + shadowClone.hideParentProperty(true); + shadowClone.updateElement(); + deleteGroupElement.classed("hidden", true); + addDataPropertyGroupElement.classed("hidden", true); + + frozenDomainForPropertyDragger.frozen(true); + frozenDomainForPropertyDragger.locked(true); + frozenRangeForPropertyDragger.frozen(true); + frozenRangeForPropertyDragger.locked(true); + domainDragger.updateElement(); + domainDragger.mouseButtonPressed = true; + rangeDragger.updateElement(); + rangeDragger.mouseButtonPressed = true; + } + else { + d.locked(true); + moved = false; + } + }) + .on("drag", function ( d ){ + + if ( d.type && d.type() === "Class_dragger" ) { + clearTimeout(delayedHider); + classDragger.setPosition(d3.event.x, d3.event.y); + } else if ( d.type && d.type() === "Range_dragger" ) { + clearTimeout(delayedHider); + rangeDragger.setPosition(d3.event.x, d3.event.y); + shadowClone.setPosition(d3.event.x, d3.event.y); + domainDragger.updateElementViaRangeDragger(d3.event.x, d3.event.y); + } + else if ( d.type && d.type() === "Domain_dragger" ) { + clearTimeout(delayedHider); + domainDragger.setPosition(d3.event.x, d3.event.y); + shadowClone.setPositionDomain(d3.event.x, d3.event.y); + rangeDragger.updateElementViaDomainDragger(d3.event.x, d3.event.y); + } + + else { + d.px = d3.event.x; + d.py = d3.event.y; + force.resume(); + updateHaloRadius(); + moved = true; + if ( d.renderType && d.renderType() === "round" ) { + classDragger.setParentNode(d); + } + + } + }) + .on("dragend", function ( d ){ + graph.ignoreOtherHoverEvents(false); + if ( d.type && d.type() === "Class_dragger" ) { + var nX = classDragger.x; + var nY = classDragger.y; + clearTimeout(delayedHider); + classDragger.mouseButtonPressed = false; + classDragger.selectedViaTouch(false); + d.setParentNode(d.parentNode()); + + var draggerEndPos = [nX, nY]; + var targetNode = graph.getTargetNode(draggerEndPos); + if ( targetNode ) { + createNewObjectProperty(d.parentNode(), targetNode, draggerEndPos); + } + if ( touchDevice === false ) { + editElementHoverOut(); + } + draggingStarted = false; + } else if ( d.type && d.type() === "Range_dragger" ) { + graph.ignoreOtherHoverEvents(false); + frozenDomainForPropertyDragger.frozen(false); + frozenDomainForPropertyDragger.locked(false); + frozenRangeForPropertyDragger.frozen(false); + frozenRangeForPropertyDragger.locked(false); + rangeDragger.mouseButtonPressed = false; + domainDragger.mouseButtonPressed = false; + domainDragger.updateElement(); + rangeDragger.updateElement(); + shadowClone.hideClone(true); + var rX = rangeDragger.x; + var rY = rangeDragger.y; + var rangeDraggerEndPos = [rX, rY]; + var targetRangeNode = graph.getTargetNode(rangeDraggerEndPos); + if ( elementTools.isDatatype(targetRangeNode) === true ) { + targetRangeNode = null; + console.log("---------------TARGET NODE IS A DATATYPE/ LITERAL ------------"); + } + + if ( targetRangeNode === null ) { + d.reDrawEverthing(); + shadowClone.hideParentProperty(false); + } + else { + d.updateRange(targetRangeNode); + graph.update(); + shadowClone.hideParentProperty(false); + } + } else if ( d.type && d.type() === "Domain_dragger" ) { + graph.ignoreOtherHoverEvents(false); + frozenDomainForPropertyDragger.frozen(false); + frozenDomainForPropertyDragger.locked(false); + frozenRangeForPropertyDragger.frozen(false); + frozenRangeForPropertyDragger.locked(false); + rangeDragger.mouseButtonPressed = false; + domainDragger.mouseButtonPressed = false; + domainDragger.updateElement(); + rangeDragger.updateElement(); + shadowClone.hideClone(true); + + var dX = domainDragger.x; + var dY = domainDragger.y; + var domainDraggerEndPos = [dX, dY]; + var targetDomainNode = graph.getTargetNode(domainDraggerEndPos); + if ( elementTools.isDatatype(targetDomainNode) === true ) { + targetDomainNode = null; + console.log("---------------TARGET NODE IS A DATATYPE/ LITERAL ------------"); + } + shadowClone.hideClone(true); + if ( targetDomainNode === null ) { + d.reDrawEverthing(); + shadowClone.hideParentProperty(false); + } + else { + d.updateDomain(targetDomainNode); + graph.update(); + shadowClone.hideParentProperty(false); + } + } + + else { + d.locked(false); + var pnp = graph.options().pickAndPinModule(); + if ( pnp.enabled() === true && moved === true ) { + if ( d.id ) { // node + pnp.handle(d, true); + } + if ( d.property ) { + pnp.handle(d.property(), true); + } + } + } + }); + + // Apply the zooming factor. + zoom = d3.behavior.zoom() + .duration(150) + .scaleExtent([options.minMagnification(), options.maxMagnification()]) + .on("zoom", zoomed); + + draggerObjectsArray.push(classDragger); + draggerObjectsArray.push(rangeDragger); + draggerObjectsArray.push(domainDragger); + draggerObjectsArray.push(shadowClone); + force.stop(); + } + + graph.lazyRefresh = function (){ + redrawContent(); + recalculatePositions(); + }; + + graph.adjustingGraphSize = function ( val ){ + adjustingGraphSize = val; + }; + + graph.showReloadButtonAfterLayoutOptimization = function ( show ){ + showReloadButtonAfterLayoutOptimization = show; + }; + + + function hiddenRecalculatePositions(){ + finishedLoadingSequence = false; + if ( graph.options().loadingModule().successfullyLoadedOntology() === false ) { + force.stop(); + d3.select("#progressBarValue").node().innerHTML = ""; + graph.updateProgressBarMode(); + graph.options().loadingModule().showErrorDetailsMessage(hiddenRecalculatePositions); + if ( keepDetailsCollapsedOnLoading && adjustingGraphSize === false ) { + graph.options().loadingModule().collapseDetails("hiddenRecalculatePositions"); + } + return; + } + if ( updateRenderingDuringSimulation === false ) { + var value = 1.0 - 10 * force.alpha(); + var percent = parseInt(200 * value) + "%"; + graph.options().loadingModule().setPercentValue(percent); + d3.select("#progressBarValue").style("width", percent); + d3.select("#progressBarValue").node().innerHTML = percent; + + if ( value > 0.49 ) { + updateRenderingDuringSimulation = true; + // show graph container; + if ( graphContainer ) { + graphContainer.style("opacity", "1"); + percent = "100%"; + d3.select("#progressBarValue").style("width", percent); + d3.select("#progressBarValue").node().innerHTML = percent; + graph.options().ontologyMenu().append_message_toLastBulletPoint("done"); + d3.select("#reloadCachedOntology").classed("hidden", !showReloadButtonAfterLayoutOptimization); + if ( showFilterWarning === true && seenFilterWarning === false ) { + graph.options().warningModule().showFilterHint(); + seenFilterWarning = true; + } + } + + if ( initialLoad ) { + if ( graph.paused() === false ) + force.resume(); // resume force + initialLoad = false; + + } + + + finishedLoadingSequence = true; + if ( showFPS === true ) { + force.on("tick", recalculatePositionsWithFPS); + recalculatePositionsWithFPS(); + } + else { + force.on("tick", recalculatePositions); + recalculatePositions(); + } + + if ( centerGraphViewOnLoad === true && force.nodes().length > 0 ) { + if ( force.nodes().length < 10 ) graph.forceRelocationEvent(true); // uses dynamic zoomer; + else graph.forceRelocationEvent(); + centerGraphViewOnLoad = false; + // console.log("--------------------------------------") + } + + + graph.showEditorHintIfNeeded(); + + if ( graph.options().loadingModule().missingImportsWarning() === false ) { + graph.options().loadingModule().hideLoadingIndicator(); + graph.options().ontologyMenu().append_bulletPoint("Successfully loaded ontology"); + graph.options().loadingModule().setSuccessful(); + } else { + graph.options().loadingModule().showWarningDetailsMessage(); + graph.options().ontologyMenu().append_bulletPoint("Loaded ontology with warnings"); + } + } + } + } + + graph.showEditorHintIfNeeded = function (){ + if ( seenEditorHint === false && editMode === true ) { + seenEditorHint = true; + graph.options().warningModule().showEditorHint(); + } + }; + + graph.setForceTickFunctionWithFPS = function (){ + showFPS = true; + if ( force && finishedLoadingSequence === true ) { + force.on("tick", recalculatePositionsWithFPS); + } + + }; + graph.setDefaultForceTickFunction = function (){ + showFPS = false; + if ( force && finishedLoadingSequence === true ) { + force.on("tick", recalculatePositions); + } + }; + function recalculatePositionsWithFPS(){ + // compute the fps + + recalculatePositions(); + now = Date.now(); + var diff = now - then; + var fps = (1000 / (diff)).toFixed(2); + + debugContainer.node().innerHTML = "FPS: " + fps + "
" + "Nodes: " + force.nodes().length + "
" + "Links: " + force.links().length; + then = Date.now(); + + } + + function recalculatePositions(){ + // Set node positions + + + // add switch for edit mode to make this faster; + if ( !editMode ) { + nodeElements.attr("transform", function ( node ){ + return "translate(" + node.x + "," + node.y + ")"; + }); + + // Set label group positions + labelGroupElements.attr("transform", function ( label ){ + var position; + + // force centered positions on single-layered links + var link = label.link(); + if ( link.layers().length === 1 && !link.loops() ) { + var linkDomainIntersection = math.calculateIntersection(link.range(), link.domain(), 0); + var linkRangeIntersection = math.calculateIntersection(link.domain(), link.range(), 0); + position = math.calculateCenter(linkDomainIntersection, linkRangeIntersection); + label.x = position.x; + label.y = position.y; + } + return "translate(" + label.x + "," + label.y + ")"; + }); + // Set link paths and calculate additional information + linkPathElements.attr("d", function ( l ){ + if ( l.isLoop() ) { + return math.calculateLoopPath(l); + } + var curvePoint = l.label(); + var pathStart = math.calculateIntersection(curvePoint, l.domain(), 1); + var pathEnd = math.calculateIntersection(curvePoint, l.range(), 1); + + return curveFunction([pathStart, curvePoint, pathEnd]); + }); + + // Set cardinality positions + cardinalityElements.attr("transform", function ( property ){ + + var label = property.link().label(), + pos = math.calculateIntersection(label, property.range(), CARDINALITY_HDISTANCE), + normalV = math.calculateNormalVector(label, property.range(), CARDINALITY_VDISTANCE); + + return "translate(" + (pos.x + normalV.x) + "," + (pos.y + normalV.y) + ")"; + }); + + + updateHaloRadius(); + return; + } + + // TODO: this is Editor redraw function // we need to make this faster!! + + + nodeElements.attr("transform", function ( node ){ + return "translate(" + node.x + "," + node.y + ")"; + }); + + // Set label group positions + labelGroupElements.attr("transform", function ( label ){ + var position; + + // force centered positions on single-layered links + var link = label.link(); + if ( link.layers().length === 1 && !link.loops() ) { + var linkDomainIntersection = math.calculateIntersection(link.range(), link.domain(), 0); + var linkRangeIntersection = math.calculateIntersection(link.domain(), link.range(), 0); + position = math.calculateCenter(linkDomainIntersection, linkRangeIntersection); + label.x = position.x; + label.y = position.y; + label.linkRangeIntersection = linkRangeIntersection; + label.linkDomainIntersection = linkDomainIntersection; + if ( link.property().focused() === true || hoveredPropertyElement !== undefined ) { + rangeDragger.updateElement(); + domainDragger.updateElement(); + // shadowClone.setPosition(link.property().range().x,link.property().range().y); + // shadowClone.setPositionDomain(link.property().domain().x,link.property().domain().y); + } + } else { + label.linkDomainIntersection = math.calculateIntersection(link.label(), link.domain(), 0); + label.linkRangeIntersection = math.calculateIntersection(link.label(), link.range(), 0); + if ( link.property().focused() === true || hoveredPropertyElement !== undefined ) { + rangeDragger.updateElement(); + domainDragger.updateElement(); + // shadowClone.setPosition(link.property().range().x,link.property().range().y); + // shadowClone.setPositionDomain(link.property().domain().x,link.property().domain().y); + } + + } + return "translate(" + label.x + "," + label.y + ")"; + }); + // Set link paths and calculate additional information + linkPathElements.attr("d", function ( l ){ + if ( l.isLoop() ) { + + var ptrAr = math.getLoopPoints(l); + l.label().linkRangeIntersection = ptrAr[1]; + l.label().linkDomainIntersection = ptrAr[0]; + + if ( l.property().focused() === true || hoveredPropertyElement !== undefined ) { + rangeDragger.updateElement(); + domainDragger.updateElement(); + } + return math.calculateLoopPath(l); + } + var curvePoint = l.label(); + var pathStart = math.calculateIntersection(curvePoint, l.domain(), 1); + var pathEnd = math.calculateIntersection(curvePoint, l.range(), 1); + l.linkRangeIntersection = pathStart; + l.linkDomainIntersection = pathEnd; + if ( l.property().focused() === true || hoveredPropertyElement !== undefined ) { + domainDragger.updateElement(); + rangeDragger.updateElement(); + // shadowClone.setPosition(l.property().range().x,l.property().range().y); + // shadowClone.setPositionDomain(l.property().domain().x,l.property().domain().y); + } + return curveFunction([pathStart, curvePoint, pathEnd]); + }); + + // Set cardinality positions + cardinalityElements.attr("transform", function ( property ){ + + var label = property.link().label(), + pos = math.calculateIntersection(label, property.range(), CARDINALITY_HDISTANCE), + normalV = math.calculateNormalVector(label, property.range(), CARDINALITY_VDISTANCE); + + return "translate(" + (pos.x + normalV.x) + "," + (pos.y + normalV.y) + ")"; + }); + + if ( hoveredNodeElement ) { + setDeleteHoverElementPosition(hoveredNodeElement); + setAddDataPropertyHoverElementPosition(hoveredNodeElement); + if ( draggingStarted === false ) { + classDragger.setParentNode(hoveredNodeElement); + } + } + if ( hoveredPropertyElement ) { + setDeleteHoverElementPositionProperty(hoveredPropertyElement); + } + + updateHaloRadius(); + } + + graph.updatePropertyDraggerElements = function ( property ){ + if ( property.type() !== "owl:DatatypeProperty" ) { + + shadowClone.setParentProperty(property); + rangeDragger.setParentProperty(property); + rangeDragger.hideDragger(false); + rangeDragger.addMouseEvents(); + domainDragger.setParentProperty(property); + domainDragger.hideDragger(false); + domainDragger.addMouseEvents(); + + } + else { + rangeDragger.hideDragger(true); + domainDragger.hideDragger(true); + shadowClone.hideClone(true); + } + }; + + function addClickEvents(){ + function executeModules( selectedElement ){ + options.selectionModules().forEach(function ( module ){ + module.handle(selectedElement); + }); + } + + nodeElements.on("click", function ( clickedNode ){ + + // manaual double clicker // helper for iphone 6 etc... + if ( touchDevice === true && doubletap() === true ) { + d3.event.stopPropagation(); + if ( editMode === true ) { + clickedNode.raiseDoubleClickEdit(defaultIriValue(clickedNode)); + } + } + else { + executeModules(clickedNode); + } + }); + + nodeElements.on("dblclick", function ( clickedNode ){ + + d3.event.stopPropagation(); + if ( editMode === true ) { + clickedNode.raiseDoubleClickEdit(defaultIriValue(clickedNode)); + } + }); + + labelGroupElements.selectAll(".label").on("click", function ( clickedProperty ){ + executeModules(clickedProperty); + + // this is for enviroments that do not define dblClick function; + if ( touchDevice === true && doubletap() === true ) { + d3.event.stopPropagation(); + if ( editMode === true ) { + clickedProperty.raiseDoubleClickEdit(defaultIriValue(clickedProperty)); + } + } + + // currently removed the selection of an element to invoke the dragger + // if (editMode===true && clickedProperty.editingTextElement!==true) { + // return; + // // We say that Datatype properties are not allowed to have domain range draggers + // if (clickedProperty.focused() && clickedProperty.type() !== "owl:DatatypeProperty") { + // shadowClone.setParentProperty(clickedProperty); + // rangeDragger.setParentProperty(clickedProperty); + // rangeDragger.hideDragger(false); + // rangeDragger.addMouseEvents(); + // domainDragger.setParentProperty(clickedProperty); + // domainDragger.hideDragger(false); + // domainDragger.addMouseEvents(); + // + // if (clickedProperty.domain()===clickedProperty.range()){ + // clickedProperty.labelObject().increasedLoopAngle=true; + // recalculatePositions(); + // + // } + // + // } else if (clickedProperty.focused() && clickedProperty.type() === "owl:DatatypeProperty") { + // shadowClone.setParentProperty(clickedProperty); + // rangeDragger.setParentProperty(clickedProperty); + // rangeDragger.hideDragger(true); + // rangeDragger.addMouseEvents(); + // domainDragger.setParentProperty(clickedProperty); + // domainDragger.hideDragger(false); + // domainDragger.addMouseEvents(); + // + // } + // else { + // rangeDragger.hideDragger(true); + // domainDragger.hideDragger(true); + // if (clickedProperty.domain()===clickedProperty.range()){ + // clickedProperty.labelObject().increasedLoopAngle=false; + // recalculatePositions(); + // + // } + // } + // } + }); + labelGroupElements.selectAll(".label").on("dblclick", function ( clickedProperty ){ + d3.event.stopPropagation(); + if ( editMode === true ) { + clickedProperty.raiseDoubleClickEdit(defaultIriValue(clickedProperty)); + } + + }); + } + + function defaultIriValue( element ){ + // get the iri of that element; + if ( graph.options().getGeneralMetaObject().iri ) { + var str2Compare = graph.options().getGeneralMetaObject().iri + element.id(); + return element.iri() === str2Compare; + } + return false; + } + + /** Adjusts the containers current scale and position. */ + function zoomed(){ + if ( forceNotZooming === true ) { + zoom.translate(graphTranslation); + zoom.scale(zoomFactor); + return; + } + + + var zoomEventByMWheel = false; + if ( d3.event.sourceEvent ) { + if ( d3.event.sourceEvent.deltaY ) zoomEventByMWheel = true; + } + if ( zoomEventByMWheel === false ) { + if ( transformAnimation === true ) { + return; + } + zoomFactor = d3.event.scale; + graphTranslation = d3.event.translate; + graphContainer.attr("transform", "translate(" + graphTranslation + ")scale(" + zoomFactor + ")"); + updateHaloRadius(); + graph.options().zoomSlider().updateZoomSliderValue(zoomFactor); + return; + } + /** animate the transition **/ + zoomFactor = d3.event.scale; + graphTranslation = d3.event.translate; + graphContainer.transition() + .tween("attr.translate", function (){ + return function ( t ){ + transformAnimation = true; + var tr = d3.transform(graphContainer.attr("transform")); + graphTranslation[0] = tr.translate[0]; + graphTranslation[1] = tr.translate[1]; + zoomFactor = tr.scale[0]; + updateHaloRadius(); + graph.options().zoomSlider().updateZoomSliderValue(zoomFactor); + }; + }) + .each("end", function (){ + transformAnimation = false; + }) + .attr("transform", "translate(" + graphTranslation + ")scale(" + zoomFactor + ")") + .ease('linear') + .duration(250); + }// end of zoomed function + + function redrawGraph(){ + remove(); + + graphContainer = d3.selectAll(options.graphContainerSelector()) + .append("svg") + .classed("vowlGraph", true) + .attr("width", options.width()) + .attr("height", options.height()) + .call(zoom) + .append("g"); + // add touch and double click functions + + var svgGraph = d3.selectAll(".vowlGraph"); + originalD3_dblClickFunction = svgGraph.on("dblclick.zoom"); + originalD3_touchZoomFunction = svgGraph.on("touchstart"); + svgGraph.on("touchstart", touchzoomed); + if ( editMode === true ) { + svgGraph.on("dblclick.zoom", graph.modified_dblClickFunction); + } + else { + svgGraph.on("dblclick.zoom", originalD3_dblClickFunction); + } + + } + + function generateEditElements(){ + addDataPropertyGroupElement = editContainer.append('g') + .classed("hidden-in-export", true) + .classed("hidden", true) + .classed("addDataPropertyElement", true) + .attr("transform", "translate(" + 0 + "," + 0 + ")"); + + + addDataPropertyGroupElement.append("circle") + // .classed("deleteElement", true) + .attr("r", 12) + .attr("cx", 0) + .attr("cy", 0) + .append("title").text("Add Datatype Property"); + + addDataPropertyGroupElement.append("line") + // .classed("deleteElementIcon ",true) + .attr("x1", -8) + .attr("y1", 0) + .attr("x2", 8) + .attr("y2", 0) + .append("title").text("Add Datatype Property"); + + addDataPropertyGroupElement.append("line") + // .classed("deleteElementIcon",true) + .attr("x1", 0) + .attr("y1", -8) + .attr("x2", 0) + .attr("y2", 8) + .append("title").text("Add Datatype Property"); + + if ( graph.options().useAccuracyHelper() ) { + addDataPropertyGroupElement.append("circle") + .attr("r", 15) + .attr("cx", -7) + .attr("cy", 7) + .classed("superHiddenElement", true) + .classed("superOpacityElement", !graph.options().showDraggerObject()); + } + + + deleteGroupElement = editContainer.append('g') + .classed("hidden-in-export", true) + .classed("hidden", true) + .classed("deleteParentElement", true) + .attr("transform", "translate(" + 0 + "," + 0 + ")"); + + deleteGroupElement.append("circle") + .attr("r", 12) + .attr("cx", 0) + .attr("cy", 0) + .append("title").text("Delete This Node"); + + var crossLen = 5; + deleteGroupElement.append("line") + .attr("x1", -crossLen) + .attr("y1", -crossLen) + .attr("x2", crossLen) + .attr("y2", crossLen) + .append("title").text("Delete This Node"); + + deleteGroupElement.append("line") + .attr("x1", crossLen) + .attr("y1", -crossLen) + .attr("x2", -crossLen) + .attr("y2", crossLen) + .append("title").text("Delete This Node"); + + if ( graph.options().useAccuracyHelper() ) { + deleteGroupElement.append("circle") + .attr("r", 15) + .attr("cx", 7) + .attr("cy", -7) + .classed("superHiddenElement", true) + .classed("superOpacityElement", !graph.options().showDraggerObject()); + } + + + } + + graph.getUnfilteredData = function (){ + return unfilteredData; + }; + + graph.getClassDataForTtlExport = function (){ + var allNodes = unfilteredData.nodes; + var nodeData = []; + for ( var i = 0; i < allNodes.length; i++ ) { + if ( allNodes[i].type() !== "rdfs:Literal" && + allNodes[i].type() !== "rdfs:Datatype" && + allNodes[i].type() !== "owl:Thing" ) { + nodeData.push(allNodes[i]); + } + } + return nodeData; + }; + + graph.getPropertyDataForTtlExport = function (){ + var propertyData = []; + var allProperties = unfilteredData.properties; + for ( var i = 0; i < allProperties.length; i++ ) { + // currently using only the object properties + if ( allProperties[i].type() === "owl:ObjectProperty" || + allProperties[i].type() === "owl:DatatypeProperty" || + allProperties[i].type() === "owl:ObjectProperty" + + ) { + propertyData.push(allProperties[i]); + } else { + if ( allProperties[i].type() === "rdfs:subClassOf" ) { + allProperties[i].baseIri("http://www.w3.org/2000/01/rdf-schema#"); + allProperties[i].iri("http://www.w3.org/2000/01/rdf-schema#subClassOf"); + } + if ( allProperties[i].type() === "owl:disjointWith" ) { + allProperties[i].baseIri("http://www.w3.org/2002/07/owl#"); + allProperties[i].iri("http://www.w3.org/2002/07/owl#disjointWith"); + } + } + } + return propertyData; + }; + + graph.getAxiomsForTtlExport = function (){ + var axioms = []; + var allProperties = unfilteredData.properties; + for ( var i = 0; i < allProperties.length; i++ ) { + // currently using only the object properties + if ( allProperties[i].type() === "owl:ObjectProperty" || + allProperties[i].type() === "owl:DatatypeProperty" || + allProperties[i].type() === "owl:ObjectProperty" || + allProperties[i].type() === "rdfs:subClassOf" + ) { + } else { + } + } + return axioms; + }; + + + graph.getUnfilteredData = function (){ + return unfilteredData; + }; + + graph.getClassDataForTtlExport = function (){ + var allNodes = unfilteredData.nodes; + var nodeData = []; + for ( var i = 0; i < allNodes.length; i++ ) { + if ( allNodes[i].type() !== "rdfs:Literal" && + allNodes[i].type() !== "rdfs:Datatype" && + allNodes[i].type() !== "owl:Thing" ) { + nodeData.push(allNodes[i]); + } + } + return nodeData; + }; + + + function redrawContent(){ + var markerContainer; + + if ( !graphContainer ) { + return; + } + + // Empty the graph container + graphContainer.selectAll("*").remove(); + + // Last container -> elements of this container overlap others + linkContainer = graphContainer.append("g").classed("linkContainer", true); + cardinalityContainer = graphContainer.append("g").classed("cardinalityContainer", true); + labelContainer = graphContainer.append("g").classed("labelContainer", true); + nodeContainer = graphContainer.append("g").classed("nodeContainer", true); + + // adding editing Elements + var draggerPathLayer = graphContainer.append("g").classed("linkContainer", true); + draggerLayer = graphContainer.append("g").classed("editContainer", true); + editContainer = graphContainer.append("g").classed("editContainer", true); + + draggerPathLayer.classed("hidden-in-export", true); + editContainer.classed("hidden-in-export", true); + draggerLayer.classed("hidden-in-export", true); + + // Add an extra container for all markers + markerContainer = linkContainer.append("defs"); + var drElement = draggerLayer.selectAll(".node") + .data(draggerObjectsArray).enter() + .append("g") + .classed("node", true) + .classed("hidden-in-export", true) + .attr("id", function ( d ){ + return d.id(); + }) + .call(dragBehaviour); + drElement.each(function ( node ){ + node.svgRoot(d3.select(this)); + node.svgPathLayer(draggerPathLayer); + if ( node.type() === "shadowClone" ) { + node.drawClone(); + node.hideClone(true); + } else { + node.drawNode(); + node.hideDragger(true); + } + }); + generateEditElements(); + + + // Add an extra container for all markers + markerContainer = linkContainer.append("defs"); + + // Draw nodes + + if ( classNodes === undefined ) classNodes = []; + + nodeElements = nodeContainer.selectAll(".node") + .data(classNodes).enter() + .append("g") + .classed("node", true) + .attr("id", function ( d ){ + return d.id(); + }) + .call(dragBehaviour); + nodeElements.each(function ( node ){ + node.draw(d3.select(this)); + }); + + + if ( labelNodes === undefined ) labelNodes = []; + + // Draw label groups (property + inverse) + labelGroupElements = labelContainer.selectAll(".labelGroup") + .data(labelNodes).enter() + .append("g") + .classed("labelGroup", true) + .call(dragBehaviour); + + labelGroupElements.each(function ( label ){ + var success = label.draw(d3.select(this)); + label.property().labelObject(label); + // Remove empty groups without a label. + if ( !success ) { + d3.select(this).remove(); + } + }); + // Place subclass label groups on the bottom of all labels + labelGroupElements.each(function ( label ){ + // the label might be hidden e.g. in compact notation + if ( !this.parentNode ) { + return; + } + + if ( elementTools.isRdfsSubClassOf(label.property()) ) { + var parentNode = this.parentNode; + parentNode.insertBefore(this, parentNode.firstChild); + } + }); + if ( properties === undefined ) properties = []; + // Draw cardinality elements + cardinalityElements = cardinalityContainer.selectAll(".cardinality") + .data(properties).enter() + .append("g") + .classed("cardinality", true); + + cardinalityElements.each(function ( property ){ + var success = property.drawCardinality(d3.select(this)); + + // Remove empty groups without a label. + if ( !success ) { + d3.select(this).remove(); + } + }); + // Draw links + if ( links === undefined ) links = []; + linkGroups = linkContainer.selectAll(".link") + .data(links).enter() + .append("g") + .classed("link", true); + + linkGroups.each(function ( link ){ + link.draw(d3.select(this), markerContainer); + }); + linkPathElements = linkGroups.selectAll("path"); + // Select the path for direct access to receive a better performance + addClickEvents(); + } + + function remove(){ + if ( graphContainer ) { + // Select the parent element because the graph container is a group (e.g. for zooming) + d3.select(graphContainer.node().parentNode).remove(); + } + } + + initializeGraph(); // << call the initialization function + + graph.updateCanvasContainerSize = function (){ + if ( graphContainer ) { + var svgElement = d3.selectAll(".vowlGraph"); + svgElement.attr("width", options.width()); + svgElement.attr("height", options.height()); + graphContainer.attr("transform", "translate(" + graphTranslation + ")scale(" + zoomFactor + ")"); + } + }; + + // Loads all settings, removes the old graph (if it exists) and draws a new one. + graph.start = function (){ + force.stop(); + loadGraphData(true); + redrawGraph(); + graph.update(true); + + if ( graph.options().loadingModule().successfullyLoadedOntology() === false ) { + graph.options().loadingModule().setErrorMode(); + } + + }; + + // Updates only the style of the graph. + graph.updateStyle = function (){ + refreshGraphStyle(); + if ( graph.options().loadingModule().successfullyLoadedOntology() === false ) { + force.stop(); + } else { + force.start(); + } + }; + + graph.reload = function (){ + loadGraphData(); + graph.update(); + + }; + + graph.load = function (){ + force.stop(); + loadGraphData(); + refreshGraphData(); + for ( var i = 0; i < labelNodes.length; i++ ) { + var label = labelNodes[i]; + if ( label.property().x && label.property().y ) { + label.x = label.property().x; + label.y = label.property().y; + // also set the prev position of the label + label.px = label.x; + label.py = label.y; + } + } + graph.update(); + }; + + graph.fastUpdate = function (){ + // fast update function for editor calls; + // -- experimental ; + quick_refreshGraphData(); + updateNodeMap(); + force.start(); + redrawContent(); + graph.updatePulseIds(nodeArrayForPulse); + refreshGraphStyle(); + updateHaloStyles(); + + }; + + graph.getNodeMapForSearch = function (){ + return nodeMap; + }; + function updateNodeMap(){ + nodeMap = []; + var node; + for ( var j = 0; j < force.nodes().length; j++ ) { + node = force.nodes()[j]; + if ( node.id ) { + nodeMap[node.id()] = j; + // check for equivalents + var eqs = node.equivalents(); + if ( eqs.length > 0 ) { + for ( var e = 0; e < eqs.length; e++ ) { + var eqObject = eqs[e]; + nodeMap[eqObject.id()] = j; + } + } + } + if ( node.property ) { + nodeMap[node.property().id()] = j; + var inverse = node.inverse(); + if ( inverse ) { + nodeMap[inverse.id()] = j; + } + } + } + } + + function updateHaloStyles(){ + var haloElement; + var halo; + var node; + for ( var j = 0; j < force.nodes().length; j++ ) { + node = force.nodes()[j]; + if ( node.id ) { + haloElement = node.getHalos(); + if ( haloElement ) { + halo = haloElement.selectAll(".searchResultA"); + halo.classed("searchResultA", false); + halo.classed("searchResultB", true); + } + } + + if ( node.property ) { + haloElement = node.property().getHalos(); + if ( haloElement ) { + halo = haloElement.selectAll(".searchResultA"); + halo.classed("searchResultA", false); + halo.classed("searchResultB", true); + } + } + } + } + + // Updates the graphs displayed data and style. + graph.update = function ( init ){ + var validOntology = graph.options().loadingModule().successfullyLoadedOntology(); + if ( validOntology === false && (init && init === true) ) { + graph.options().loadingModule().collapseDetails(); + return; + } + if ( validOntology === false ) { + return; + } + + keepDetailsCollapsedOnLoading = false; + refreshGraphData(); + // update node map + updateNodeMap(); + + force.start(); + redrawContent(); + graph.updatePulseIds(nodeArrayForPulse); + refreshGraphStyle(); + updateHaloStyles(); + }; + + graph.paused = function ( p ){ + if ( !arguments.length ) return paused; + paused = p; + graph.updateStyle(); + return graph; + }; + // resetting the graph + graph.reset = function (){ + // window size + var w = 0.5 * graph.options().width(); + var h = 0.5 * graph.options().height(); + // computing initial translation for the graph due tue the dynamic default zoom level + var tx = w - defaultZoom * w; + var ty = h - defaultZoom * h; + zoom.translate([tx, ty]) + .scale(defaultZoom); + }; + + + graph.zoomOut = function (){ + + var minMag = options.minMagnification(), + maxMag = options.maxMagnification(); + var stepSize = (maxMag - minMag) / 10; + var val = zoomFactor - stepSize; + if ( val < minMag ) val = minMag; + + var cx = 0.5 * graph.options().width(); + var cy = 0.5 * graph.options().height(); + var cp = getWorldPosFromScreen(cx, cy, graphTranslation, zoomFactor); + var sP = [cp.x, cp.y, graph.options().height() / zoomFactor]; + var eP = [cp.x, cp.y, graph.options().height() / val]; + var pos_intp = d3.interpolateZoom(sP, eP); + + graphContainer.attr("transform", transform(sP, cx, cy)) + .transition() + .duration(250) + .attrTween("transform", function (){ + return function ( t ){ + return transform(pos_intp(t), cx, cy); + }; + }) + .each("end", function (){ + graphContainer.attr("transform", "translate(" + graphTranslation + ")scale(" + zoomFactor + ")"); + zoom.translate(graphTranslation); + zoom.scale(zoomFactor); + updateHaloRadius(); + options.zoomSlider().updateZoomSliderValue(zoomFactor); + }); + + }; + + graph.zoomIn = function (){ + var minMag = options.minMagnification(), + maxMag = options.maxMagnification(); + var stepSize = (maxMag - minMag) / 10; + var val = zoomFactor + stepSize; + if ( val > maxMag ) val = maxMag; + var cx = 0.5 * graph.options().width(); + var cy = 0.5 * graph.options().height(); + var cp = getWorldPosFromScreen(cx, cy, graphTranslation, zoomFactor); + var sP = [cp.x, cp.y, graph.options().height() / zoomFactor]; + var eP = [cp.x, cp.y, graph.options().height() / val]; + var pos_intp = d3.interpolateZoom(sP, eP); + + graphContainer.attr("transform", transform(sP, cx, cy)) + .transition() + .duration(250) + .attrTween("transform", function (){ + return function ( t ){ + return transform(pos_intp(t), cx, cy); + }; + }) + .each("end", function (){ + graphContainer.attr("transform", "translate(" + graphTranslation + ")scale(" + zoomFactor + ")"); + zoom.translate(graphTranslation); + zoom.scale(zoomFactor); + updateHaloRadius(); + options.zoomSlider().updateZoomSliderValue(zoomFactor); + }); + + + }; + + /** --------------------------------------------------------- **/ + /** -- data related handling -- **/ + /** --------------------------------------------------------- **/ + + var cachedJsonOBJ = null; + graph.clearAllGraphData = function (){ + if ( graph.graphNodeElements() && graph.graphNodeElements().length > 0 ) { + cachedJsonOBJ = graph.options().exportMenu().createJSON_exportObject(); + } else { + cachedJsonOBJ = null; + } + force.stop(); + if ( unfilteredData ) { + unfilteredData.nodes = []; + unfilteredData.properties = []; + } + }; + graph.getCachedJsonObj = function (){ + return cachedJsonOBJ; + }; + + // removes data when data could not be loaded + graph.clearGraphData = function (){ + force.stop(); + var sidebar = graph.options().sidebar(); + if ( sidebar ) + sidebar.clearOntologyInformation(); + if ( graphContainer ) + redrawGraph(); + }; + + function generateDictionary( data ){ + var i; + var originalDictionary = []; + var nodes = data.nodes; + for ( i = 0; i < nodes.length; i++ ) { + // check if node has a label + if ( nodes[i].labelForCurrentLanguage() !== undefined ) + originalDictionary.push(nodes[i]); + } + var props = data.properties; + for ( i = 0; i < props.length; i++ ) { + if ( props[i].labelForCurrentLanguage() !== undefined ) + originalDictionary.push(props[i]); + } + parser.setDictionary(originalDictionary); + + var literFilter = graph.options().literalFilter(); + var idsToRemove = literFilter.removedNodes(); + var originalDict = parser.getDictionary(); + var newDict = []; + + // go through the dictionary and remove the ids; + for ( i = 0; i < originalDict.length; i++ ) { + var dictElement = originalDict[i]; + var dictElementId; + if ( dictElement.property ) + dictElementId = dictElement.property().id(); + else + dictElementId = dictElement.id(); + // compare against the removed ids; + var addToDictionary = true; + for ( var j = 0; j < idsToRemove.length; j++ ) { + var currentId = idsToRemove[j]; + if ( currentId === dictElementId ) { + addToDictionary = false; + } + } + if ( addToDictionary === true ) { + newDict.push(dictElement); + } + } + // tell the parser that the dictionary is updated + parser.setDictionary(newDict); + + } + + graph.updateProgressBarMode = function (){ + var loadingModule = graph.options().loadingModule(); + + var state = loadingModule.getProgressBarMode(); + switch ( state ) { + case 0: + loadingModule.setErrorMode(); + break; + case 1: + loadingModule.setBusyMode(); + break; + case 2: + loadingModule.setPercentMode(); + break; + default: + loadingModule.setPercentMode(); + } + }; + + graph.setFilterWarning = function ( val ){ + showFilterWarning = val; + }; + function loadGraphData( init ){ + // reset the locate button and previously selected locations and other variables + + var loadingModule = graph.options().loadingModule(); + force.stop(); + + force.nodes([]); + force.links([]); + nodeArrayForPulse = []; + pulseNodeIds = []; + locationId = 0; + d3.select("#locateSearchResult").classed("highlighted", false); + d3.select("#locateSearchResult").node().title = "Nothing to locate"; + graph.clearGraphData(); + + if ( init ) { + force.stop(); + return; + } + + showFilterWarning = false; + parser.parse(options.data()); + unfilteredData = { + nodes: parser.nodes(), + properties: parser.properties() + }; + // fixing class and property id counter for the editor + eN = unfilteredData.nodes.length + 1; + eP = unfilteredData.properties.length + 1; + + + // using the ids of elements if to ensure that loaded elements will not get the same id; + for ( var p = 0; p < unfilteredData.properties.length; p++ ) { + var currentId = unfilteredData.properties[p].id(); + if ( currentId.indexOf('objectProperty') !== -1 ) { + // could be ours; + var idStr = currentId.split('objectProperty'); + if ( idStr[0].length === 0 ) { + var idInt = parseInt(idStr[1]); + if ( eP < idInt ) { + eP = idInt + 1; + } + } + } + } + // using the ids of elements if to ensure that loaded elements will not get the same id; + for ( var n = 0; n < unfilteredData.nodes.length; n++ ) { + var currentId_Nodes = unfilteredData.nodes[n].id(); + if ( currentId_Nodes.indexOf('Class') !== -1 ) { + // could be ours; + var idStr_Nodes = currentId_Nodes.split('Class'); + if ( idStr_Nodes[0].length === 0 ) { + var idInt_Nodes = parseInt(idStr_Nodes[1]); + if ( eN < idInt_Nodes ) { + eN = idInt_Nodes + 1; + } + } + } + } + + initialLoad = true; + graph.options().warningModule().closeFilterHint(); + + // loading handler + updateRenderingDuringSimulation = true; + var validOntology = graph.options().loadingModule().successfullyLoadedOntology(); + if ( graphContainer && validOntology === true ) { + + updateRenderingDuringSimulation = false; + graph.options().ontologyMenu().append_bulletPoint("Generating visualization ... "); + loadingModule.setPercentMode(); + + if ( unfilteredData.nodes.length > 0 ) { + graphContainer.style("opacity", "0"); + force.on("tick", hiddenRecalculatePositions); + } else { + graphContainer.style("opacity", "1"); + if ( showFPS === true ) { + force.on("tick", recalculatePositionsWithFPS); + } + else { + force.on("tick", recalculatePositions); + } + } + + force.start(); + } else { + force.stop(); + graph.options().ontologyMenu().append_bulletPoint("Failed to load ontology"); + loadingModule.setErrorMode(); + } + // update prefixList( + // update general MetaOBJECT + graph.options().clearMetaObject(); + graph.options().clearGeneralMetaObject(); + graph.options().editSidebar().clearMetaObjectValue(); + if ( options.data() !== undefined ) { + var header = options.data().header; + if ( header ) { + if ( header.iri ) { + graph.options().addOrUpdateGeneralObjectEntry("iri", header.iri); + } + if ( header.title ) { + graph.options().addOrUpdateGeneralObjectEntry("title", header.title); + } + if ( header.author ) { + graph.options().addOrUpdateGeneralObjectEntry("author", header.author); + } + if ( header.version ) { + graph.options().addOrUpdateGeneralObjectEntry("version", header.version); + } + if ( header.description ) { + graph.options().addOrUpdateGeneralObjectEntry("description", header.description); + } + if ( header.prefixList ) { + var pL = header.prefixList; + for ( var pr in pL ) { + if ( pL.hasOwnProperty(pr) ) { + var val = pL[pr]; + graph.options().addPrefix(pr, val); + } + } + } + // get other metadata; + if ( header.other ) { + var otherObjects = header.other; + for ( var name in otherObjects ) { + if ( otherObjects.hasOwnProperty(name) ) { + var otherObj = otherObjects[name]; + if ( otherObj.hasOwnProperty("identifier") && otherObj.hasOwnProperty("value") ) { + graph.options().addOrUpdateMetaObjectEntry(otherObj.identfier, otherObj.value); + } + } + } + } + } + } + // update more meta OBJECT + // Initialize filters with data to replicate consecutive filtering + var initializationData = _.clone(unfilteredData); + options.filterModules().forEach(function ( module ){ + initializationData = filterFunction(module, initializationData, true); + }); + // generate dictionary here ; + generateDictionary(unfilteredData); + + parser.parseSettings(); + graphUpdateRequired = parser.settingsImported(); + centerGraphViewOnLoad = true; + if ( parser.settingsImportGraphZoomAndTranslation() === true ) { + centerGraphViewOnLoad = false; + } + graph.options().searchMenu().requestDictionaryUpdate(); + graph.options().editSidebar().updateGeneralOntologyInfo(); + graph.options().editSidebar().updatePrefixUi(); + graph.options().editSidebar().updateElementWidth(); + } + + graph.handleOnLoadingError = function (){ + force.stop(); + graph.clearGraphData(); + graph.options().ontologyMenu().append_bulletPoint("Failed to load ontology"); + d3.select("#progressBarValue").node().innherHTML = ""; + d3.select("#progressBarValue").classed("busyProgressBar", false); + graph.options().loadingModule().setErrorMode(); + graph.options().loadingModule().showErrorDetailsMessage(); + }; + + function quick_refreshGraphData(){ + links = linkCreator.createLinks(properties); + labelNodes = links.map(function ( link ){ + return link.label(); + }); + + storeLinksOnNodes(classNodes, links); + setForceLayoutData(classNodes, labelNodes, links); + } + + //Applies the data of the graph options object and parses it. The graph is not redrawn. + function refreshGraphData(){ + var shouldExecuteEmptyFilter = options.literalFilter().enabled(); + graph.executeEmptyLiteralFilter(); + options.literalFilter().enabled(shouldExecuteEmptyFilter); + + var preprocessedData = _.clone(unfilteredData); + + // Filter the data + options.filterModules().forEach(function ( module ){ + preprocessedData = filterFunction(module, preprocessedData); + }); + options.focuserModule().handle(undefined, true); + classNodes = preprocessedData.nodes; + properties = preprocessedData.properties; + links = linkCreator.createLinks(properties); + labelNodes = links.map(function ( link ){ + return link.label(); + }); + storeLinksOnNodes(classNodes, links); + setForceLayoutData(classNodes, labelNodes, links); + // for (var i = 0; i < classNodes.length; i++) { + // if (classNodes[i].setRectangularRepresentation) + // classNodes[i].setRectangularRepresentation(graph.options().rectangularRepresentation()); + // } + } + + function filterFunction( module, data, initializing ){ + links = linkCreator.createLinks(data.properties); + storeLinksOnNodes(data.nodes, links); + + if ( initializing ) { + if ( module.initialize ) { + module.initialize(data.nodes, data.properties); + } + } + module.filter(data.nodes, data.properties); + return { + nodes: module.filteredNodes(), + properties: module.filteredProperties() + }; + } + + + /** --------------------------------------------------------- **/ + /** -- force-layout related functions -- **/ + /** --------------------------------------------------------- **/ + function storeLinksOnNodes( nodes, links ){ + for ( var i = 0, nodesLength = nodes.length; i < nodesLength; i++ ) { + var node = nodes[i], + connectedLinks = []; + + // look for properties where this node is the domain or range + for ( var j = 0, linksLength = links.length; j < linksLength; j++ ) { + var link = links[j]; + + if ( link.domain() === node || link.range() === node ) { + connectedLinks.push(link); + } + } + node.links(connectedLinks); + } + } + + function setForceLayoutData( classNodes, labelNodes, links ){ + var d3Links = []; + links.forEach(function ( link ){ + d3Links = d3Links.concat(link.linkParts()); + }); + + var d3Nodes = [].concat(classNodes).concat(labelNodes); + setPositionOfOldLabelsOnNewLabels(force.nodes(), labelNodes); + + force.nodes(d3Nodes) + .links(d3Links); + } + + // The label nodes are positioned randomly, because they are created from scratch if the data changes and lose + // their position information. With this hack the position of old labels is copied to the new labels. + function setPositionOfOldLabelsOnNewLabels( oldLabelNodes, labelNodes ){ + labelNodes.forEach(function ( labelNode ){ + for ( var i = 0; i < oldLabelNodes.length; i++ ) { + var oldNode = oldLabelNodes[i]; + if ( oldNode.equals(labelNode) ) { + labelNode.x = oldNode.x; + labelNode.y = oldNode.y; + labelNode.px = oldNode.px; + labelNode.py = oldNode.py; + break; + } + } + }); + } + + // Applies all options that don't change the graph data. + function refreshGraphStyle(){ + zoom = zoom.scaleExtent([options.minMagnification(), options.maxMagnification()]); + if ( graphContainer ) { + zoom.event(graphContainer); + } + + force.charge(function ( element ){ + var charge = options.charge(); + if ( elementTools.isLabel(element) ) { + charge *= 0.8; + } + return charge; + }) + .size([options.width(), options.height()]) + .linkDistance(calculateLinkPartDistance) + .gravity(options.gravity()) + .linkStrength(options.linkStrength()); // Flexibility of links + + force.nodes().forEach(function ( n ){ + n.frozen(paused); + }); + } + + function calculateLinkPartDistance( linkPart ){ + var link = linkPart.link(); + + if ( link.isLoop() ) { + return options.loopDistance(); + } + + // divide by 2 to receive the length for a single link part + var linkPartDistance = getVisibleLinkDistance(link) / 2; + linkPartDistance += linkPart.domain().actualRadius(); + linkPartDistance += linkPart.range().actualRadius(); + return linkPartDistance; + } + + function getVisibleLinkDistance( link ){ + if ( elementTools.isDatatype(link.domain()) || elementTools.isDatatype(link.range()) ) { + return options.datatypeDistance(); + } else { + return options.classDistance(); + } + } + + /** --------------------------------------------------------- **/ + /** -- animation functions for the nodes -- **/ + /** --------------------------------------------------------- **/ + + graph.animateDynamicLabelWidth = function (){ + var wantedWidth = options.dynamicLabelWidth(); + var i; + for ( i = 0; i < classNodes.length; i++ ) { + var nodeElement = classNodes[i]; + if ( elementTools.isDatatype(nodeElement) ) { + nodeElement.animateDynamicLabelWidth(wantedWidth); + } + } + for ( i = 0; i < properties.length; i++ ) { + properties[i].animateDynamicLabelWidth(wantedWidth); + } + }; + + + /** --------------------------------------------------------- **/ + /** -- halo and localization functions -- **/ + /** --------------------------------------------------------- **/ + function updateHaloRadius(){ + if ( pulseNodeIds && pulseNodeIds.length > 0 ) { + var forceNodes = force.nodes(); + for ( var i = 0; i < pulseNodeIds.length; i++ ) { + var node = forceNodes[pulseNodeIds[i]]; + if ( node ) { + if ( node.property ) { + // match search strings with property label + if ( node.property().inverse ) { + var searchString = graph.options().searchMenu().getSearchString().toLowerCase(); + var name = node.property().labelForCurrentLanguage().toLowerCase(); + if ( name === searchString ) computeDistanceToCenter(node); + else { + node.property().removeHalo(); + if ( node.property().inverse() ) { + if ( !node.property().inverse().getHalos() ) + node.property().inverse().drawHalo(); + computeDistanceToCenter(node, true); + } + if ( node.property().equivalents() ) { + var eq = node.property().equivalents(); + for ( var e = 0; e < eq.length; e++ ) { + if ( !eq[e].getHalos() ) + eq[e].drawHalo(); + } + if ( !node.property().getHalos() ) + node.property().drawHalo(); + computeDistanceToCenter(node, false); + + } + } + } + } + computeDistanceToCenter(node); + } + } + } + } + + function getScreenCoords( x, y, translate, scale ){ + var xn = translate[0] + x * scale; + var yn = translate[1] + y * scale; + return { x: xn, y: yn }; + } + + function getClickedScreenCoords( x, y, translate, scale ){ + var xn = (x - translate[0]) / scale; + var yn = (y - translate[1]) / scale; + return { x: xn, y: yn }; + } + + + function computeDistanceToCenter( node, inverse ){ + var container = node; + var w = graph.options().width(); + var h = graph.options().height(); + var posXY = getScreenCoords(node.x, node.y, graphTranslation, zoomFactor); + + var highlightOfInv = false; + + if ( inverse && inverse === true ) { + highlightOfInv = true; + posXY = getScreenCoords(node.x, node.y + 20, graphTranslation, zoomFactor); + } + var x = posXY.x; + var y = posXY.y; + var nodeIsRect = false; + var halo; + var roundHalo; + var rectHalo; + var borderPoint_x = 0; + var borderPoint_y = 0; + var defaultRadius; + var offset = 15; + var radius; + + if ( node.property && highlightOfInv === true ) { + if ( node.property().inverse() ) { + rectHalo = node.property().inverse().getHalos().select("rect"); + + } else { + if ( node.property().getHalos() ) + rectHalo = node.property().getHalos().select("rect"); + else { + node.property().drawHalo(); + rectHalo = node.property().getHalos().select("rect"); + } + } + rectHalo.classed("hidden", true); + if ( node.property().inverse() ) { + if ( node.property().inverse().getHalos() ) { + roundHalo = node.property().inverse().getHalos().select("circle"); + } + } else { + roundHalo = node.property().getHalos().select("circle"); + } + if ( roundHalo.node() === null ) { + radius = node.property().inverse().width() + 15; + + roundHalo = node.property().inverse().getHalos().append("circle") + .classed("searchResultB", true) + .classed("searchResultA", false) + .attr("r", radius + 15); + + } + halo = roundHalo; // swap the halo to be round + nodeIsRect = true; + container = node.property().inverse(); + } + + if ( node.id ) { + if ( !node.getHalos() ) return; // something went wrong before + halo = node.getHalos().select("rect"); + if ( halo.node() === null ) { + // this is a round node + nodeIsRect = false; + roundHalo = node.getHalos().select("circle"); + defaultRadius = node.actualRadius(); + roundHalo.attr("r", defaultRadius + offset); + halo = roundHalo; + } else { // this is a rect node + nodeIsRect = true; + rectHalo = node.getHalos().select("rect"); + rectHalo.classed("hidden", true); + roundHalo = node.getHalos().select("circle"); + if ( roundHalo.node() === null ) { + radius = node.width(); + roundHalo = node.getHalos().append("circle") + .classed("searchResultB", true) + .classed("searchResultA", false) + .attr("r", radius + offset); + } + halo = roundHalo; + } + } + if ( node.property && !inverse ) { + if ( !node.property().getHalos() ) return; // something went wrong before + rectHalo = node.property().getHalos().select("rect"); + rectHalo.classed("hidden", true); + + roundHalo = node.property().getHalos().select("circle"); + if ( roundHalo.node() === null ) { + radius = node.property().width(); + + roundHalo = node.property().getHalos().append("circle") + .classed("searchResultB", true) + .classed("searchResultA", false) + .attr("r", radius + 15); + + } + halo = roundHalo; // swap the halo to be round + nodeIsRect = true; + container = node.property(); + } + + if ( x < 0 || x > w || y < 0 || y > h ) { + // node outside viewport; + // check for quadrant and get the correct boarder point (intersection with viewport) + if ( x < 0 && y < 0 ) { + borderPoint_x = 0; + borderPoint_y = 0; + } else if ( x > 0 && x < w && y < 0 ) { + borderPoint_x = x; + borderPoint_y = 0; + } else if ( x > w && y < 0 ) { + borderPoint_x = w; + borderPoint_y = 0; + } else if ( x > w && y > 0 && y < h ) { + borderPoint_x = w; + borderPoint_y = y; + } else if ( x > w && y > h ) { + borderPoint_x = w; + borderPoint_y = h; + } else if ( x > 0 && x < w && y > h ) { + borderPoint_x = x; + borderPoint_y = h; + } else if ( x < 0 && y > h ) { + borderPoint_x = 0; + borderPoint_y = h; + } else if ( x < 0 && y > 0 && y < h ) { + borderPoint_x = 0; + borderPoint_y = y; + } + // kill all pulses of nodes that are outside the viewport + container.getHalos().select("rect").classed("searchResultA", false); + container.getHalos().select("circle").classed("searchResultA", false); + container.getHalos().select("rect").classed("searchResultB", true); + container.getHalos().select("circle").classed("searchResultB", true); + halo.classed("hidden", false); + // compute in pixel coordinates length of difference vector + var borderRadius_x = borderPoint_x - x; + var borderRadius_y = borderPoint_y - y; + + var len = borderRadius_x * borderRadius_x + borderRadius_y * borderRadius_y; + len = Math.sqrt(len); + + var normedX = borderRadius_x / len; + var normedY = borderRadius_y / len; + + len = len + 20; // add 20 px; + + // re-normalized vector + var newVectorX = normedX * len + x; + var newVectorY = normedY * len + y; + // compute world coordinates of this point + var wX = (newVectorX - graphTranslation[0]) / zoomFactor; + var wY = (newVectorY - graphTranslation[1]) / zoomFactor; + + // compute distance in world coordinates + var dx = wX - node.x; + var dy = wY - node.y; + if ( highlightOfInv === true ) + dy = wY - node.y - 20; + + if ( highlightOfInv === false && node.property && node.property().inverse() ) + dy = wY - node.y + 20; + + var newRadius = Math.sqrt(dx * dx + dy * dy); + halo = container.getHalos().select("circle"); + // sanity checks and setting new halo radius + if ( !nodeIsRect ) { + defaultRadius = node.actualRadius() + offset; + if ( newRadius < defaultRadius ) { + newRadius = defaultRadius; + } + halo.attr("r", newRadius); + } else { + defaultRadius = 0.5 * container.width(); + if ( newRadius < defaultRadius ) + newRadius = defaultRadius; + halo.attr("r", newRadius); + } + } else { // node is in viewport , render original; + // reset the halo to original radius + defaultRadius = node.actualRadius() + 15; + if ( !nodeIsRect ) { + halo.attr("r", defaultRadius); + } else { // this is rectangular node render as such + halo = container.getHalos().select("rect"); + halo.classed("hidden", false); + //halo.classed("searchResultB", true); + //halo.classed("searchResultA", false); + var aCircHalo = container.getHalos().select("circle"); + aCircHalo.classed("hidden", true); + + container.getHalos().select("rect").classed("hidden", false); + container.getHalos().select("circle").classed("hidden", true); + } + } + } + + function transform( p, cx, cy ){ + // one iteration step for the locate target animation + zoomFactor = graph.options().height() / p[2]; + graphTranslation = [(cx - p[0] * zoomFactor), (cy - p[1] * zoomFactor)]; + updateHaloRadius(); + // update the values in case the user wants to break the animation + zoom.translate(graphTranslation); + zoom.scale(zoomFactor); + graph.options().zoomSlider().updateZoomSliderValue(zoomFactor); + return "translate(" + graphTranslation[0] + "," + graphTranslation[1] + ")scale(" + zoomFactor + ")"; + } + + graph.zoomToElementInGraph = function ( element ){ + targetLocationZoom(element); + }; + graph.updateHaloRadius = function ( element ){ + computeDistanceToCenter(element); + }; + + function targetLocationZoom( target ){ + // store the original information + var cx = 0.5 * graph.options().width(); + var cy = 0.5 * graph.options().height(); + var cp = getWorldPosFromScreen(cx, cy, graphTranslation, zoomFactor); + var sP = [cp.x, cp.y, graph.options().height() / zoomFactor]; + + var zoomLevel = Math.max(defaultZoom + 0.5 * defaultZoom, defaultTargetZoom); + var eP = [target.x, target.y, graph.options().height() / zoomLevel]; + var pos_intp = d3.interpolateZoom(sP, eP); + + var lenAnimation = pos_intp.duration; + if ( lenAnimation > 2500 ) { + lenAnimation = 2500; + } + + graphContainer.attr("transform", transform(sP, cx, cy)) + .transition() + .duration(lenAnimation) + .attrTween("transform", function (){ + return function ( t ){ + return transform(pos_intp(t), cx, cy); + }; + }) + .each("end", function (){ + graphContainer.attr("transform", "translate(" + graphTranslation + ")scale(" + zoomFactor + ")"); + zoom.translate(graphTranslation); + zoom.scale(zoomFactor); + updateHaloRadius(); + }); + } + + function getWorldPosFromScreen( x, y, translate, scale ){ + var temp = scale[0], xn, yn; + if ( temp ) { + xn = (x - translate[0]) / temp; + yn = (y - translate[1]) / temp; + } else { + xn = (x - translate[0]) / scale; + yn = (y - translate[1]) / scale; + } + return { x: xn, y: yn }; + } + + graph.locateSearchResult = function (){ + if ( pulseNodeIds && pulseNodeIds.length > 0 ) { + // move the center of the viewport to this location + if ( transformAnimation === true ) return; // << prevents incrementing the location id if we are in an animation + var node = force.nodes()[pulseNodeIds[locationId]]; + locationId++; + locationId = locationId % pulseNodeIds.length; + if ( node.id ) node.foreground(); + if ( node.property ) node.property().foreground(); + + targetLocationZoom(node); + } + }; + + graph.resetSearchHighlight = function (){ + // get all nodes (handle also already filtered nodes ) + pulseNodeIds = []; + nodeArrayForPulse = []; + // clear from stored nodes + var nodes = unfilteredData.nodes; + var props = unfilteredData.properties; + var j; + for ( j = 0; j < nodes.length; j++ ) { + var node = nodes[j]; + if ( node.removeHalo ) + node.removeHalo(); + } + for ( j = 0; j < props.length; j++ ) { + var prop = props[j]; + if ( prop.removeHalo ) + prop.removeHalo(); + } + }; + + graph.updatePulseIds = function ( nodeIdArray ){ + pulseNodeIds = []; + for ( var i = 0; i < nodeIdArray.length; i++ ) { + var selectedId = nodeIdArray[i]; + var forceId = nodeMap[selectedId]; + if ( forceId !== undefined ) { + var le_node = force.nodes()[forceId]; + if ( le_node.id ) { + if ( pulseNodeIds.indexOf(forceId) === -1 ) { + pulseNodeIds.push(forceId); + } + } + if ( le_node.property ) { + if ( pulseNodeIds.indexOf(forceId) === -1 ) { + pulseNodeIds.push(forceId); + } + } + } + } + locationId = 0; + if ( pulseNodeIds.length > 0 ) { + d3.select("#locateSearchResult").classed("highlighted", true); + d3.select("#locateSearchResult").node().title = "Locate search term"; + } + else { + d3.select("#locateSearchResult").classed("highlighted", false); + d3.select("#locateSearchResult").node().title = "Nothing to locate"; + } + + }; + + graph.highLightNodes = function ( nodeIdArray ){ + if ( nodeIdArray.length === 0 ) { + return; // nothing to highlight + } + pulseNodeIds = []; + nodeArrayForPulse = nodeIdArray; + var missedIds = []; + + // identify the force id to highlight + for ( var i = 0; i < nodeIdArray.length; i++ ) { + var selectedId = nodeIdArray[i]; + var forceId = nodeMap[selectedId]; + if ( forceId !== undefined ) { + var le_node = force.nodes()[forceId]; + if ( le_node.id ) { + if ( pulseNodeIds.indexOf(forceId) === -1 ) { + pulseNodeIds.push(forceId); + le_node.foreground(); + le_node.drawHalo(); + } + } + if ( le_node.property ) { + if ( pulseNodeIds.indexOf(forceId) === -1 ) { + pulseNodeIds.push(forceId); + le_node.property().foreground(); + le_node.property().drawHalo(); + } + } + } + else { + missedIds.push(selectedId); + } + } + + if ( missedIds.length === nodeIdArray.length ) { + + } + // store the highlight on the missed nodes; + var s_nodes = unfilteredData.nodes; + var s_props = unfilteredData.properties; + for ( i = 0; i < missedIds.length; i++ ) { + var missedId = missedIds[i]; + // search for this in the nodes; + for ( var n = 0; n < s_nodes.length; n++ ) { + var nodeId = s_nodes[n].id(); + if ( nodeId === missedId ) { + s_nodes[n].drawHalo(); + } + } + for ( var p = 0; p < s_props.length; p++ ) { + var propId = s_props[p].id(); + if ( propId === missedId ) { + s_props[p].drawHalo(); + } + } + } + if ( missedIds.length === nodeIdArray.length ) { + d3.select("#locateSearchResult").classed("highlighted", false); + } + else { + d3.select("#locateSearchResult").classed("highlighted", true); + } + locationId = 0; + updateHaloRadius(); + }; + + graph.hideHalos = function (){ + var haloElements = d3.selectAll(".searchResultA,.searchResultB"); + haloElements.classed("hidden", true); + return haloElements; + }; + + function nodeInViewport( node, property ){ + + var w = graph.options().width(); + var h = graph.options().height(); + var posXY = getScreenCoords(node.x, node.y, graphTranslation, zoomFactor); + var x = posXY.x; + var y = posXY.y; + + var retVal = !(x < 0 || x > w || y < 0 || y > h); + return retVal; + } + + graph.getBoundingBoxForTex = function (){ + var halos = graph.hideHalos(); + var bbox = graphContainer.node().getBoundingClientRect(); + halos.classed("hidden", false); + var w = graph.options().width(); + var h = graph.options().height(); + + // get the graph coordinates + var topLeft = getWorldPosFromScreen(0, 0, graphTranslation, zoomFactor); + var botRight = getWorldPosFromScreen(w, h, graphTranslation, zoomFactor); + + + var t_topLeft = getWorldPosFromScreen(bbox.left, bbox.top, graphTranslation, zoomFactor); + var t_botRight = getWorldPosFromScreen(bbox.right, bbox.bottom, graphTranslation, zoomFactor); + + // tighten up the bounding box; + + var tX = Math.max(t_topLeft.x, topLeft.x); + var tY = Math.max(t_topLeft.y, topLeft.y); + + var bX = Math.min(t_botRight.x, botRight.x); + var bY = Math.min(t_botRight.y, botRight.y); + + + // tighten further; + var allForceNodes = force.nodes(); + var numNodes = allForceNodes.length; + var visibleNodes = []; + var bbx; + + + var contentBBox = { tx: 1000000000000, ty: 1000000000000, bx: -1000000000000, by: -1000000000000 }; + + for ( var i = 0; i < numNodes; i++ ) { + var node = allForceNodes[i]; + if ( node ) { + if ( node.property ) { + if ( nodeInViewport(node, true) ) { + if ( node.property().labelElement() === undefined ) continue; + bbx = node.property().labelElement().node().getBoundingClientRect(); + if ( bbx ) { + contentBBox.tx = Math.min(contentBBox.tx, bbx.left); + contentBBox.bx = Math.max(contentBBox.bx, bbx.right); + contentBBox.ty = Math.min(contentBBox.ty, bbx.top); + contentBBox.by = Math.max(contentBBox.by, bbx.bottom); + } + } + } else { + if ( nodeInViewport(node, false) ) { + bbx = node.nodeElement().node().getBoundingClientRect(); + if ( bbx ) { + contentBBox.tx = Math.min(contentBBox.tx, bbx.left); + contentBBox.bx = Math.max(contentBBox.bx, bbx.right); + contentBBox.ty = Math.min(contentBBox.ty, bbx.top); + contentBBox.by = Math.max(contentBBox.by, bbx.bottom); + } + } + } + } + } + + var tt_topLeft = getWorldPosFromScreen(contentBBox.tx, contentBBox.ty, graphTranslation, zoomFactor); + var tt_botRight = getWorldPosFromScreen(contentBBox.bx, contentBBox.by, graphTranslation, zoomFactor); + + tX = Math.max(tX, tt_topLeft.x); + tY = Math.max(tY, tt_topLeft.y); + + bX = Math.min(bX, tt_botRight.x); + bY = Math.min(bY, tt_botRight.y); + // y axis flip for tex + return [tX, -tY, bX, -bY]; + + }; + + var updateTargetElement = function (){ + var bbox = graphContainer.node().getBoundingClientRect(); + + + // get the graph coordinates + var bboxOffset = 50; // default radius of a node; + var topLeft = getWorldPosFromScreen(bbox.left, bbox.top, graphTranslation, zoomFactor); + var botRight = getWorldPosFromScreen(bbox.right, bbox.bottom, graphTranslation, zoomFactor); + + var w = graph.options().width(); + if ( graph.options().leftSidebar().isSidebarVisible() === true ) + w -= 200; + var h = graph.options().height(); + topLeft.x += bboxOffset; + topLeft.y -= bboxOffset; + botRight.x -= bboxOffset; + botRight.y += bboxOffset; + + var g_w = botRight.x - topLeft.x; + var g_h = botRight.y - topLeft.y; + + // endpoint position calculations + var posX = 0.5 * (topLeft.x + botRight.x); + var posY = 0.5 * (topLeft.y + botRight.y); + var cx = 0.5 * w, + cy = 0.5 * h; + + if ( graph.options().leftSidebar().isSidebarVisible() === true ) + cx += 200; + var cp = getWorldPosFromScreen(cx, cy, graphTranslation, zoomFactor); + + // zoom factor calculations and fail safes; + var newZoomFactor = 1.0; // fail save if graph and window are squares + //get the smaller one + var a = w / g_w; + var b = h / g_h; + if ( a < b ) newZoomFactor = a; + else newZoomFactor = b; + + + // fail saves + if ( newZoomFactor > zoom.scaleExtent()[1] ) { + newZoomFactor = zoom.scaleExtent()[1]; + } + if ( newZoomFactor < zoom.scaleExtent()[0] ) { + newZoomFactor = zoom.scaleExtent()[0]; + } + + // apply Zooming + var sP = [cp.x, cp.y, h / zoomFactor]; + var eP = [posX, posY, h / newZoomFactor]; + + + var pos_intp = d3.interpolateZoom(sP, eP); + return [pos_intp, cx, cy]; + + }; + + graph.forceRelocationEvent = function ( dynamic ){ + // we need to kill the halo to determine the bounding box; + var halos = graph.hideHalos(); + var bbox = graphContainer.node().getBoundingClientRect(); + halos.classed("hidden", false); + + // get the graph coordinates + var bboxOffset = 50; // default radius of a node; + var topLeft = getWorldPosFromScreen(bbox.left, bbox.top, graphTranslation, zoomFactor); + var botRight = getWorldPosFromScreen(bbox.right, bbox.bottom, graphTranslation, zoomFactor); + + var w = graph.options().width(); + if ( graph.options().leftSidebar().isSidebarVisible() === true ) + w -= 200; + var h = graph.options().height(); + topLeft.x += bboxOffset; + topLeft.y -= bboxOffset; + botRight.x -= bboxOffset; + botRight.y += bboxOffset; + + var g_w = botRight.x - topLeft.x; + var g_h = botRight.y - topLeft.y; + + // endpoint position calculations + var posX = 0.5 * (topLeft.x + botRight.x); + var posY = 0.5 * (topLeft.y + botRight.y); + var cx = 0.5 * w, + cy = 0.5 * h; + + if ( graph.options().leftSidebar().isSidebarVisible() === true ) + cx += 200; + var cp = getWorldPosFromScreen(cx, cy, graphTranslation, zoomFactor); + + // zoom factor calculations and fail safes; + var newZoomFactor = 1.0; // fail save if graph and window are squares + //get the smaller one + var a = w / g_w; + var b = h / g_h; + if ( a < b ) newZoomFactor = a; + else newZoomFactor = b; + + + // fail saves + if ( newZoomFactor > zoom.scaleExtent()[1] ) { + newZoomFactor = zoom.scaleExtent()[1]; + } + if ( newZoomFactor < zoom.scaleExtent()[0] ) { + newZoomFactor = zoom.scaleExtent()[0]; + } + + // apply Zooming + var sP = [cp.x, cp.y, h / zoomFactor]; + var eP = [posX, posY, h / newZoomFactor]; + + + var pos_intp = d3.interpolateZoom(sP, eP); + var lenAnimation = pos_intp.duration; + if ( lenAnimation > 2500 ) { + lenAnimation = 2500; + } + graphContainer.attr("transform", transform(sP, cx, cy)) + .transition() + .duration(lenAnimation) + .attrTween("transform", function (){ + return function ( t ){ + if ( dynamic ) { + var param = updateTargetElement(); + var nV = param[0](t); + return transform(nV, cx, cy); + } + return transform(pos_intp(t), cx, cy); + }; + }) + .each("end", function (){ + if ( dynamic ) { + return; + } + + graphContainer.attr("transform", "translate(" + graphTranslation + ")scale(" + zoomFactor + ")"); + zoom.translate(graphTranslation); + zoom.scale(zoomFactor); + graph.options().zoomSlider().updateZoomSliderValue(zoomFactor); + + + }); + }; + + + graph.isADraggerActive = function (){ + if ( classDragger.mouseButtonPressed === true || + domainDragger.mouseButtonPressed === true || + rangeDragger.mouseButtonPressed === true ) { + return true; + } + return false; + }; + + /** --------------------------------------------------------- **/ + /** -- VOWL EDITOR create/ edit /delete functions -- **/ + /** --------------------------------------------------------- **/ + + graph.changeNodeType = function ( element ){ + + var typeString = d3.select("#typeEditor").node().value; + + if ( graph.classesSanityCheck(element, typeString) === false ) { + // call reselection to restore previous type selection + graph.options().editSidebar().updateSelectionInformation(element); + return; + } + + var prototype = NodePrototypeMap.get(typeString.toLowerCase()); + var aNode = new prototype(graph); + + aNode.x = element.x; + aNode.y = element.y; + aNode.px = element.x; + aNode.py = element.y; + aNode.id(element.id()); + aNode.copyInformation(element); + + if ( typeString === "owl:Thing" ) { + aNode.label("Thing"); + } + else if ( elementTools.isDatatype(element) === false ) { + if ( element.backupLabel() !== undefined ) { + aNode.label(element.backupLabel()); + } else if ( aNode.backupLabel() !== undefined ) { + aNode.label(aNode.backupLabel()); + } else { + aNode.label("NewClass"); + } + } + + if ( typeString === "rdfs:Datatype" ) { + if ( aNode.dType() === "undefined" ) + aNode.label("undefined"); + else { + var identifier = aNode.dType().split(":")[1]; + aNode.label(identifier); + } + } + var i; + // updates the property domain and range + for ( i = 0; i < unfilteredData.properties.length; i++ ) { + if ( unfilteredData.properties[i].domain() === element ) { + // unfilteredData.properties[i].toString(); + unfilteredData.properties[i].domain(aNode); + } + if ( unfilteredData.properties[i].range() === element ) { + unfilteredData.properties[i].range(aNode); + // unfilteredData.properties[i].toString(); + } + } + + // update for fastUpdate: + for ( i = 0; i < properties.length; i++ ) { + if ( properties[i].domain() === element ) { + // unfilteredData.properties[i].toString(); + properties[i].domain(aNode); + } + if ( properties[i].range() === element ) { + properties[i].range(aNode); + // unfilteredData.properties[i].toString(); + } + } + + var remId = unfilteredData.nodes.indexOf(element); + if ( remId !== -1 ) + unfilteredData.nodes.splice(remId, 1); + remId = classNodes.indexOf(element); + if ( remId !== -1 ) + classNodes.splice(remId, 1); + // very important thing for selection!; + addNewNodeElement(aNode); + // handle focuser! + options.focuserModule().handle(aNode); + generateDictionary(unfilteredData); + graph.getUpdateDictionary(); + element = null; + }; + + + graph.changePropertyType = function ( element ){ + var typeString = d3.select("#typeEditor").node().value; + + // create warning + if ( graph.sanityCheckProperty(element.domain(), element.range(), typeString) === false ) return false; + + var propPrototype = PropertyPrototypeMap.get(typeString.toLowerCase()); + var aProp = new propPrototype(graph); + aProp.copyInformation(element); + aProp.id(element.id()); + + element.domain().removePropertyElement(element); + element.range().removePropertyElement(element); + aProp.domain(element.domain()); + aProp.range(element.range()); + + if ( element.backupLabel() !== undefined ) { + aProp.label(element.backupLabel()); + } else { + aProp.label("newObjectProperty"); + } + + if ( aProp.type() === "rdfs:subClassOf" ) { + aProp.iri("http://www.w3.org/2000/01/rdf-schema#subClassOf"); + } else { + if ( element.iri() === "http://www.w3.org/2000/01/rdf-schema#subClassOf" ) + aProp.iri(graph.options().getGeneralMetaObjectProperty('iri') + aProp.id()); + + } + + + if ( graph.propertyCheckExistenceChecker(aProp, element.domain(), element.range()) === false ) { + graph.options().editSidebar().updateSelectionInformation(element); + return; + } + // // TODO: change its base IRI to proper value + // var ontoIRI="http://someTest.de"; + // aProp.baseIri(ontoIRI); + // aProp.iri(aProp.baseIri()+aProp.id()); + + + // add this to the data; + unfilteredData.properties.push(aProp); + if ( properties.indexOf(aProp) === -1 ) + properties.push(aProp); + var remId = unfilteredData.properties.indexOf(element); + if ( remId !== -1 ) + unfilteredData.properties.splice(remId, 1); + if ( properties.indexOf(aProp) === -1 ) + properties.push(aProp); + remId = properties.indexOf(element); + if ( remId !== -1 ) + properties.splice(remId, 1); + graph.fastUpdate(); + aProp.domain().addProperty(aProp); + aProp.range().addProperty(aProp); + if ( element.labelObject() && aProp.labelObject() ) { + aProp.labelObject().x = element.labelObject().x; + aProp.labelObject().px = element.labelObject().px; + aProp.labelObject().y = element.labelObject().y; + aProp.labelObject().py = element.labelObject().py; + } + + options.focuserModule().handle(aProp); + element = null; + }; + + graph.removeEditElements = function (){ + // just added to be called form outside + removeEditElements(); + }; + + function removeEditElements(){ + rangeDragger.hideDragger(true); + domainDragger.hideDragger(true); + shadowClone.hideClone(true); + + classDragger.hideDragger(true); + if ( addDataPropertyGroupElement ) + addDataPropertyGroupElement.classed("hidden", true); + if ( deleteGroupElement ) + deleteGroupElement.classed("hidden", true); + + + if ( hoveredNodeElement ) { + if ( hoveredNodeElement.pinned() === false ) { + hoveredNodeElement.locked(graph.paused()); + hoveredNodeElement.frozen(graph.paused()); + } + } + if ( hoveredPropertyElement ) { + if ( hoveredPropertyElement.pinned() === false ) { + hoveredPropertyElement.locked(graph.paused()); + hoveredPropertyElement.frozen(graph.paused()); + } + } + + + } + + graph.editorMode = function ( val ){ + var create_entry = d3.select("#empty"); + var create_container = d3.select("#emptyContainer"); + + var modeOfOpString = d3.select("#modeOfOperationString").node(); + if ( !arguments.length ) { + create_entry.node().checked = editMode; + if ( editMode === false ) { + create_container.node().title = "Enable editing in modes menu to create a new ontology"; + create_entry.node().title = "Enable editing in modes menu to create a new ontology"; + create_entry.style("pointer-events", "none"); + } else { + create_container.node().title = "Creates a new empty ontology"; + create_entry.node().title = "Creates a new empty ontology"; + d3.select("#useAccuracyHelper").style("color", "#2980b9"); + d3.select("#useAccuracyHelper").style("pointer-events", "auto"); + create_entry.node().disabled = false; + create_entry.style("pointer-events", "auto"); + } + + return editMode; + } + graph.options().setEditorModeForDefaultObject(val); + + // if (seenEditorHint===false && val===true){ + // seenEditorHint=true; + // graph.options().warningModule().showEditorHint(); + // } + editMode = val; + + if ( create_entry ) { + create_entry.classed("disabled", !editMode); + if ( !editMode ) { + create_container.node().title = "Enable editing in modes menu to create a new ontology"; + create_entry.node().title = "Enable editing in modes menu to create a new ontology"; + create_entry.node().disabled = true; + d3.select("#useAccuracyHelper").style("color", "#979797"); + d3.select("#useAccuracyHelper").style("pointer-events", "none"); + create_entry.style("pointer-events", "none"); + } else { + create_container.node().title = "Creates a new empty ontology"; + create_entry.node().title = "Creates a new empty ontology"; + d3.select("#useAccuracyHelper").style("color", "#2980b9"); + d3.select("#useAccuracyHelper").style("pointer-events", "auto"); + create_entry.style("pointer-events", "auto"); + } + } + + // adjust compact notation + // selector = compactNotationOption; + // box =ModuleCheckbox + var compactNotationContainer = d3.select("#compactnotationModuleCheckbox"); + if ( compactNotationContainer ) { + compactNotationContainer.classed("disabled", !editMode); + if ( !editMode ) { + compactNotationContainer.node().title = ""; + compactNotationContainer.node().disabled = false; + compactNotationContainer.style("pointer-events", "auto"); + d3.select("#compactNotationOption").style("color", ""); + d3.select("#compactNotationOption").node().title = ""; + options.literalFilter().enabled(true); + graph.update(); + } else { + // if editor Mode + //1) uncheck the element + d3.select("#compactNotationOption").node().title = "Compact notation can only be used in view mode"; + compactNotationContainer.node().disabled = true; + compactNotationContainer.node().checked = false; + options.compactNotationModule().enabled(false); + options.literalFilter().enabled(false); + graph.executeCompactNotationModule(); + graph.executeEmptyLiteralFilter(); + graph.lazyRefresh(); + compactNotationContainer.style("pointer-events", "none"); + d3.select("#compactNotationOption").style("color", "#979797"); + } + } + + if ( modeOfOpString ) { + if ( touchDevice === true ) { + modeOfOpString.innerHTML = "touch able device detected"; + } else { + modeOfOpString.innerHTML = "point & click device detected"; + } + } + var svgGraph = d3.selectAll(".vowlGraph"); + + if ( editMode === true ) { + options.leftSidebar().showSidebar(options.leftSidebar().getSidebarVisibility(), true); + options.leftSidebar().hideCollapseButton(false); + graph.options().editSidebar().updatePrefixUi(); + graph.options().editSidebar().updateElementWidth(); + svgGraph.on("dblclick.zoom", graph.modified_dblClickFunction); + + } else { + svgGraph.on("dblclick.zoom", originalD3_dblClickFunction); + options.leftSidebar().showSidebar(0); + options.leftSidebar().hideCollapseButton(true); + // hide hovered edit elements + removeEditElements(); + } + options.sidebar().updateShowedInformation(); + options.editSidebar().updateElementWidth(); + + }; + + function createLowerCasePrototypeMap( prototypeMap ){ + return d3.map(prototypeMap.values(), function ( Prototype ){ + return new Prototype().type().toLowerCase(); + }); + } + + function createNewNodeAtPosition( pos ){ + var aNode, prototype; + var forceUpdate = true; + // create a node of that id; + + var typeToCreate = d3.select("#defaultClass").node().title; + prototype = NodePrototypeMap.get(typeToCreate.toLowerCase()); + aNode = new prototype(graph); + var autoEditElement = false; + if ( typeToCreate === "owl:Thing" ) { + aNode.label("Thing"); + } + else { + aNode.label("NewClass"); + autoEditElement = true; + } + aNode.x = pos.x; + aNode.y = pos.y; + aNode.px = aNode.x; + aNode.py = aNode.y; + aNode.id("Class" + eN++); + // aNode.paused(true); + + aNode.baseIri(d3.select("#iriEditor").node().value); + aNode.iri(aNode.baseIri() + aNode.id()); + addNewNodeElement(aNode, forceUpdate); + options.focuserModule().handle(aNode, true); + aNode.frozen(graph.paused()); + aNode.locked(graph.paused()); + aNode.enableEditing(autoEditElement); + } + + + function addNewNodeElement( element ){ + unfilteredData.nodes.push(element); + if ( classNodes.indexOf(element) === -1 ) + classNodes.push(element); + + generateDictionary(unfilteredData); + graph.getUpdateDictionary(); + graph.fastUpdate(); + } + + graph.getTargetNode = function ( position ){ + var dx = position[0]; + var dy = position[1]; + var tN = null; + var minDist = 1000000000000; + // This is a bit OVERKILL for the computation of one node >> TODO: KD-TREE SEARCH + unfilteredData.nodes.forEach(function ( el ){ + var cDist = Math.sqrt((el.x - dx) * (el.x - dx) + (el.y - dy) * (el.y - dy)); + if ( cDist < minDist ) { + minDist = cDist; + tN = el; + } + }); + if ( hoveredNodeElement ) { + var offsetDist = hoveredNodeElement.actualRadius() + 30; + if ( minDist > offsetDist ) return null; + if ( tN.renderType() === "rect" ) return null; + if ( tN === hoveredNodeElement && minDist <= hoveredNodeElement.actualRadius() ) { + return tN; + } else if ( tN === hoveredNodeElement && minDist > hoveredNodeElement.actualRadius() ) { + return null; + } + return tN; + } + else { + + if ( minDist > (tN.actualRadius() + 30) ) + return null; + else return tN; + + } + }; + + graph.genericPropertySanityCheck = function ( domain, range, typeString, header, action ){ + if ( domain === range && typeString === "rdfs:subClassOf" ) { + graph.options().warningModule().showWarning(header, + "rdfs:subClassOf can not be created as loops (domain == range)", + action, 1, false); + return false; + } + if ( domain === range && typeString === "owl:disjointWith" ) { + graph.options().warningModule().showWarning(header, + "owl:disjointWith can not be created as loops (domain == range)", + action, 1, false); + return false; + } + // allProps[i].type()==="owl:allValuesFrom" || + // allProps[i].type()==="owl:someValuesFrom" + if ( domain.type() === "owl:Thing" && typeString === "owl:allValuesFrom" ) { + graph.options().warningModule().showWarning(header, + "owl:allValuesFrom can not originate from owl:Thing", + action, 1, false); + return false; + } + if ( domain.type() === "owl:Thing" && typeString === "owl:someValuesFrom" ) { + graph.options().warningModule().showWarning(header, + "owl:someValuesFrom can not originate from owl:Thing", + action, 1, false); + return false; + } + + if ( range.type() === "owl:Thing" && typeString === "owl:allValuesFrom" ) { + graph.options().warningModule().showWarning(header, + "owl:allValuesFrom can not be connected to owl:Thing", + action, 1, false); + return false; + } + if ( range.type() === "owl:Thing" && typeString === "owl:someValuesFrom" ) { + graph.options().warningModule().showWarning(header, + "owl:someValuesFrom can not be connected to owl:Thing", + action, 1, false); + return false; + } + + return true; // we can Change the domain or range + }; + + graph.checkIfIriClassAlreadyExist = function ( url ){ + // search for a class node with this url + var allNodes = unfilteredData.nodes; + for ( var i = 0; i < allNodes.length; i++ ) { + if ( elementTools.isDatatype(allNodes[i]) === true || allNodes[i].type() === "owl:Thing" ) + continue; + + // now we are a real class; + //get class IRI + var classIRI = allNodes[i].iri(); + + // this gives me the node for halo + if ( url === classIRI ) { + return allNodes[i]; + } + } + return false; + }; + + graph.classesSanityCheck = function ( classElement, targetType ){ + // this is added due to someValuesFrom properties + // we should not be able to change a classElement to a owl:Thing + // when it has a property attached to it that uses these restrictions + // + + if ( targetType === "owl:Class" ) return true; + + else { + // collect all properties which have that one as a domain or range + var allProps = unfilteredData.properties; + for ( var i = 0; i < allProps.length; i++ ) { + if ( allProps[i].range() === classElement || allProps[i].domain() === classElement ) { + // check for the type of that property + if ( allProps[i].type() === "owl:someValuesFrom" ) { + graph.options().warningModule().showWarning("Can not change class type", + "The element has a property that is of type owl:someValuesFrom", + "Element type not changed!", 1, true); + return false; + } + if ( allProps[i].type() === "owl:allValuesFrom" ) { + graph.options().warningModule().showWarning("Can not change class type", + "The element has a property that is of type owl:allValuesFrom", + "Element type not changed!", 1, true); + return false; + } + } + } + + + } + return true; + }; + + graph.propertyCheckExistenceChecker = function ( property, domain, range ){ + var allProps = unfilteredData.properties; + var i; + if ( property.type() === "rdfs:subClassOf" || property.type() === "owl:disjointWith" ) { + + for ( i = 0; i < allProps.length; i++ ) { + if ( allProps[i] === property ) continue; + if ( allProps[i].domain() === domain && allProps[i].range() === range && allProps[i].type() === property.type() ) { + graph.options().warningModule().showWarning("Warning", + "This triple already exist!", + "Element not created!", 1, false); + return false; + } + if ( allProps[i].domain() === range && allProps[i].range() === domain && allProps[i].type() === property.type() ) { + graph.options().warningModule().showWarning("Warning", + "Inverse assignment already exist! ", + "Element not created!", 1, false); + return false; + } + } + return true; + } + return true; + }; + + // graph.checkForTripleDuplicate=function(property){ + // var domain=property.domain(); + // var range=property.range(); + // console.log("checking for duplicates"); + // var b1= domain.isPropertyAssignedToThisElement(property); + // var b2= range.isPropertyAssignedToThisElement(property); + // + // console.log("test domain results in "+ b1); + // console.log("test range results in "+ b1); + // + // if (b1 && b2 ){ + // graph.options().warningModule().showWarning("Warning", + // "This triple already exist!", + // "Element not created!",1,false); + // return false; + // } + // return true; + // }; + + graph.sanityCheckProperty = function ( domain, range, typeString ){ + + // check for duplicate triple in the element; + + + if ( typeString === "owl:objectProperty" && graph.options().objectPropertyFilter().enabled() === true ) { + graph.options().warningModule().showWarning("Warning", + "Object properties are filtered out in the visualization!", + "Element not created!", 1, false); + return false; + } + + if ( typeString === "owl:disjointWith" && graph.options().disjointPropertyFilter().enabled() === true ) { + graph.options().warningModule().showWarning("Warning", + "owl:disjointWith properties are filtered out in the visualization!", + "Element not created!", 1, false); + return false; + } + + + if ( domain === range && typeString === "rdfs:subClassOf" ) { + graph.options().warningModule().showWarning("Warning", + "rdfs:subClassOf can not be created as loops (domain == range)", + "Element not created!", 1, false); + return false; + } + if ( domain === range && typeString === "owl:disjointWith" ) { + graph.options().warningModule().showWarning("Warning", + "owl:disjointWith can not be created as loops (domain == range)", + "Element not created!", 1, false); + return false; + } + + if ( domain.type() === "owl:Thing" && typeString === "owl:someValuesFrom" ) { + graph.options().warningModule().showWarning("Warning", + "owl:someValuesFrom can not originate from owl:Thing", + "Element not created!", 1, false); + return false; + } + if ( domain.type() === "owl:Thing" && typeString === "owl:allValuesFrom" ) { + graph.options().warningModule().showWarning("Warning", + "owl:allValuesFrom can not originate from owl:Thing", + "Element not created!", 1, false); + return false; + } + + if ( range.type() === "owl:Thing" && typeString === "owl:allValuesFrom" ) { + graph.options().warningModule().showWarning("Warning", + "owl:allValuesFrom can not be connected to owl:Thing", + "Element not created!", 1, false); + return false; + } + if ( range.type() === "owl:Thing" && typeString === "owl:someValuesFrom" ) { + graph.options().warningModule().showWarning("Warning", + "owl:someValuesFrom can not be connected to owl:Thing", + "Element not created!", 1, false); + return false; + } + return true; // we can create a property + }; + + function createNewObjectProperty( domain, range, draggerEndposition ){ + // check type of the property that we want to create; + + var defaultPropertyName = d3.select("#defaultProperty").node().title; + + // check if we are allow to create that property + if ( graph.sanityCheckProperty(domain, range, defaultPropertyName) === false ) return false; + + + var propPrototype = PropertyPrototypeMap.get(defaultPropertyName.toLowerCase()); + var aProp = new propPrototype(graph); + aProp.id("objectProperty" + eP++); + aProp.domain(domain); + aProp.range(range); + aProp.label("newObjectProperty"); + aProp.baseIri(d3.select("#iriEditor").node().value); + aProp.iri(aProp.baseIri() + aProp.id()); + + // check for duplicate; + if ( graph.propertyCheckExistenceChecker(aProp, domain, range) === false ) { + // delete aProp; + // hope for garbage collection here -.- + return false; + } + + var autoEditElement = false; + + if ( defaultPropertyName === "owl:objectProperty" ) { + autoEditElement = true; + } + var pX = 0.49 * (domain.x + range.x); + var pY = 0.49 * (domain.y + range.y); + + if ( domain === range ) { + // we use the dragger endposition to determine an angle to put the loop there; + var dirD_x = draggerEndposition[0] - domain.x; + var dirD_y = draggerEndposition[1] - domain.y; + + // normalize; + var len = Math.sqrt(dirD_x * dirD_x + dirD_y * dirD_y); + // it should be very hard to set the position on the same sport but why not handling this + var nx = dirD_x / len; + var ny = dirD_y / len; + // is Nan in javascript like in c len==len returns false when it is not a number? + if ( isNaN(len) ) { + nx = 0; + ny = -1; + } + + // get domain actual raidus + var offset = 2 * domain.actualRadius() + 50; + pX = domain.x + offset * nx; + pY = domain.y + offset * ny; + } + + // add this property to domain and range; + domain.addProperty(aProp); + range.addProperty(aProp); + + + // add this to the data; + unfilteredData.properties.push(aProp); + if ( properties.indexOf(aProp) === -1 ) + properties.push(aProp); + graph.fastUpdate(); + aProp.labelObject().x = pX; + aProp.labelObject().px = pX; + aProp.labelObject().y = pY; + aProp.labelObject().py = pY; + + aProp.frozen(graph.paused()); + aProp.locked(graph.paused()); + domain.frozen(graph.paused()); + domain.locked(graph.paused()); + range.frozen(graph.paused()); + range.locked(graph.paused()); + + + generateDictionary(unfilteredData); + graph.getUpdateDictionary(); + + options.focuserModule().handle(aProp); + graph.activateHoverElementsForProperties(true, aProp, false, touchDevice); + aProp.labelObject().increasedLoopAngle = true; + aProp.enableEditing(autoEditElement); + } + + graph.createDataTypeProperty = function ( node ){ + // random postion issues; + clearTimeout(nodeFreezer); + // tells user when element is filtered out + if ( graph.options().datatypeFilter().enabled() === true ) { + graph.options().warningModule().showWarning("Warning", + "Datatype properties are filtered out in the visualization!", + "Element not created!", 1, false); + return; + } + + + var aNode, prototype; + + // create a default datatype Node >> HERE LITERAL; + var defaultDatatypeName = d3.select("#defaultDatatype").node().title; + if ( defaultDatatypeName === "rdfs:Literal" ) { + prototype = NodePrototypeMap.get("rdfs:literal"); + aNode = new prototype(graph); + aNode.label("Literal"); + aNode.iri("http://www.w3.org/2000/01/rdf-schema#Literal"); + aNode.baseIri("http://www.w3.org/2000/01/rdf-schema#"); + } else { + prototype = NodePrototypeMap.get("rdfs:datatype"); + aNode = new prototype(graph); + var identifier = ""; + if ( defaultDatatypeName === "undefined" ) { + identifier = "undefined"; + + aNode.label(identifier); + // TODO : HANDLER FOR UNDEFINED DATATYPES!!<<<>>>>>>>>>>>.. + aNode.iri("http://www.undefinedDatatype.org/#" + identifier); + aNode.baseIri("http://www.undefinedDatatype.org/#"); + aNode.dType(defaultDatatypeName); + } else { + identifier = defaultDatatypeName.split(":")[1]; + aNode.label(identifier); + aNode.dType(defaultDatatypeName); + aNode.iri("http://www.w3.org/2001/XMLSchema#" + identifier); + aNode.baseIri("http://www.w3.org/2001/XMLSchema#"); + } + } + + + var nX = node.x - node.actualRadius() - 100; + var nY = node.y + node.actualRadius() + 100; + + aNode.x = nX; + aNode.y = nY; + aNode.px = aNode.x; + aNode.py = aNode.y; + aNode.id("NodeId" + eN++); + // add this property to the nodes; + unfilteredData.nodes.push(aNode); + if ( classNodes.indexOf(aNode) === -1 ) + classNodes.push(aNode); + + + // add also the datatype Property to it + var propPrototype = PropertyPrototypeMap.get("owl:datatypeproperty"); + var aProp = new propPrototype(graph); + aProp.id("datatypeProperty" + eP++); + + // create the connection + aProp.domain(node); + aProp.range(aNode); + aProp.label("newDatatypeProperty"); + + + // TODO: change its base IRI to proper value + var ontoIri = d3.select("#iriEditor").node().value; + aProp.baseIri(ontoIri); + aProp.iri(ontoIri + aProp.id()); + // add this to the data; + unfilteredData.properties.push(aProp); + if ( properties.indexOf(aProp) === -1 ) + properties.push(aProp); + graph.fastUpdate(); + generateDictionary(unfilteredData); + graph.getUpdateDictionary(); + + nodeFreezer = setTimeout(function (){ + if ( node && node.frozen() === true && node.pinned() === false && graph.paused() === false ) { + node.frozen(graph.paused()); + node.locked(graph.paused()); + } + }, 1000); + options.focuserModule().handle(undefined); + if ( node ) { + node.frozen(true); + node.locked(true); + } + }; + + graph.removeNodesViaResponse = function ( nodesToRemove, propsToRemove ){ + var i, remId; + // splice them; + for ( i = 0; i < propsToRemove.length; i++ ) { + remId = unfilteredData.properties.indexOf(propsToRemove[i]); + if ( remId !== -1 ) + unfilteredData.properties.splice(remId, 1); + remId = properties.indexOf(propsToRemove[i]); + if ( remId !== -1 ) + properties.splice(remId, 1); + propsToRemove[i] = null; + } + for ( i = 0; i < nodesToRemove.length; i++ ) { + remId = unfilteredData.nodes.indexOf(nodesToRemove[i]); + if ( remId !== -1 ) { + unfilteredData.nodes.splice(remId, 1); + } + remId = classNodes.indexOf(nodesToRemove[i]); + if ( remId !== -1 ) + classNodes.splice(remId, 1); + nodesToRemove[i] = null; + } + graph.fastUpdate(); + generateDictionary(unfilteredData); + graph.getUpdateDictionary(); + options.focuserModule().handle(undefined); + nodesToRemove = null; + propsToRemove = null; + + }; + + graph.removeNodeViaEditor = function ( node ){ + var propsToRemove = []; + var nodesToRemove = []; + var datatypes = 0; + + var remId; + + nodesToRemove.push(node); + for ( var i = 0; i < unfilteredData.properties.length; i++ ) { + if ( unfilteredData.properties[i].domain() === node || unfilteredData.properties[i].range() === node ) { + propsToRemove.push(unfilteredData.properties[i]); + if ( unfilteredData.properties[i].type().toLocaleLowerCase() === "owl:datatypeproperty" && + unfilteredData.properties[i].range() !== node ) { + nodesToRemove.push(unfilteredData.properties[i].range()); + datatypes++; + } + } + } + var removedItems = propsToRemove.length + nodesToRemove.length; + if ( removedItems > 2 ) { + var text = "You are about to delete 1 class and " + propsToRemove.length + " properties"; + if ( datatypes !== 0 ) { + text = "You are about to delete 1 class, " + datatypes + " datatypes and " + propsToRemove.length + " properties"; + } + + + graph.options().warningModule().responseWarning( + "Removing elements", + text, + "Awaiting response!", graph.removeNodesViaResponse, [nodesToRemove, propsToRemove], false); + + + // + // if (confirm("Remove :\n"+propsToRemove.length + " properties\n"+nodesToRemove.length+" classes? ")===false){ + // return; + // }else{ + // // todo : store for undo delete button ; + // } + } else { + // splice them; + for ( i = 0; i < propsToRemove.length; i++ ) { + remId = unfilteredData.properties.indexOf(propsToRemove[i]); + if ( remId !== -1 ) + unfilteredData.properties.splice(remId, 1); + remId = properties.indexOf(propsToRemove[i]); + if ( remId !== -1 ) + properties.splice(remId, 1); + propsToRemove[i] = null; + } + for ( i = 0; i < nodesToRemove.length; i++ ) { + remId = unfilteredData.nodes.indexOf(nodesToRemove[i]); + if ( remId !== -1 ) + unfilteredData.nodes.splice(remId, 1); + remId = classNodes.indexOf(nodesToRemove[i]); + if ( remId !== -1 ) + classNodes.splice(remId, 1); + nodesToRemove[i] = null; + } + graph.fastUpdate(); + generateDictionary(unfilteredData); + graph.getUpdateDictionary(); + options.focuserModule().handle(undefined); + nodesToRemove = null; + propsToRemove = null; + } + }; + + graph.removePropertyViaEditor = function ( property ){ + property.domain().removePropertyElement(property); + property.range().removePropertyElement(property); + var remId; + + if ( property.type().toLocaleLowerCase() === "owl:datatypeproperty" ) { + var datatype = property.range(); + remId = unfilteredData.nodes.indexOf(property.range()); + if ( remId !== -1 ) + unfilteredData.nodes.splice(remId, 1); + remId = classNodes.indexOf(property.range()); + if ( remId !== -1 ) + classNodes.splice(remId, 1); + datatype = null; + } + remId = unfilteredData.properties.indexOf(property); + if ( remId !== -1 ) + unfilteredData.properties.splice(remId, 1); + remId = properties.indexOf(property); + if ( remId !== -1 ) + properties.splice(remId, 1); + if ( property.inverse() ) { + // so we have inverse + property.inverse().inverse(0); + + } + + + hoveredPropertyElement = undefined; + graph.fastUpdate(); + generateDictionary(unfilteredData); + graph.getUpdateDictionary(); + options.focuserModule().handle(undefined); + property = null; + }; + + graph.executeColorExternalsModule = function (){ + options.colorExternalsModule().filter(unfilteredData.nodes, unfilteredData.properties); + }; + + graph.executeCompactNotationModule = function (){ + if ( unfilteredData ) { + options.compactNotationModule().filter(unfilteredData.nodes, unfilteredData.properties); + } + + }; + graph.executeEmptyLiteralFilter = function (){ + + if ( unfilteredData && unfilteredData.nodes.length > 1 ) { + options.literalFilter().filter(unfilteredData.nodes, unfilteredData.properties); + unfilteredData.nodes = options.literalFilter().filteredNodes(); + unfilteredData.properties = options.literalFilter().filteredProperties(); + } + + }; + + + /** --------------------------------------------------------- **/ + /** -- animation functions for the nodes -- **/ + /** --------------------------------------------------------- **/ + + graph.animateDynamicLabelWidth = function (){ + var wantedWidth = options.dynamicLabelWidth(); + var i; + for ( i = 0; i < classNodes.length; i++ ) { + var nodeElement = classNodes[i]; + if ( elementTools.isDatatype(nodeElement) ) { + nodeElement.animateDynamicLabelWidth(wantedWidth); + } + } + for ( i = 0; i < properties.length; i++ ) { + properties[i].animateDynamicLabelWidth(wantedWidth); + } + }; + + + /** --------------------------------------------------------- **/ + /** -- Touch behaviour functions -- **/ + /** --------------------------------------------------------- **/ + + graph.setTouchDevice = function ( val ){ + touchDevice = val; + }; + + graph.isTouchDevice = function (){ + return touchDevice; + }; + + graph.modified_dblClickFunction = function (){ + + d3.event.stopPropagation(); + d3.event.preventDefault(); + // get position where we want to add the node; + var grPos = getClickedScreenCoords(d3.event.clientX, d3.event.clientY, graph.translation(), graph.scaleFactor()); + createNewNodeAtPosition(grPos); + }; + + function doubletap(){ + var touch_time = d3.event.timeStamp; + var numTouchers = 1; + if ( d3.event && d3.event.touches && d3.event.touches.length ) + numTouchers = d3.event.touches.length; + + if ( touch_time - last_touch_time < 300 && numTouchers === 1 ) { + d3.event.stopPropagation(); + if ( editMode === true ) { + //graph.modified_dblClickFunction(); + d3.event.preventDefault(); + d3.event.stopPropagation(); + last_touch_time = touch_time; + return true; + } + } + last_touch_time = touch_time; + return false; + } + + + function touchzoomed(){ + forceNotZooming = true; + + + var touch_time = d3.event.timeStamp; + if ( touch_time - last_touch_time < 300 && d3.event.touches.length === 1 ) { + d3.event.stopPropagation(); + + if ( editMode === true ) { + //graph.modified_dblClickFunction(); + d3.event.preventDefault(); + d3.event.stopPropagation(); + zoom.translate(graphTranslation); + zoom.scale(zoomFactor); + graph.modified_dblTouchFunction(); + } + else { + forceNotZooming = false; + if ( originalD3_touchZoomFunction ) + originalD3_touchZoomFunction(); + } + return; + } + forceNotZooming = false; + last_touch_time = touch_time; + // TODO: WORK AROUND TO CHECK FOR ORIGINAL FUNCTION + if ( originalD3_touchZoomFunction ) + originalD3_touchZoomFunction(); + } + + graph.modified_dblTouchFunction = function ( d ){ + d3.event.stopPropagation(); + d3.event.preventDefault(); + var xy; + if ( editMode === true ) { + xy = d3.touches(d3.selectAll(".vowlGraph").node()); + } + var grPos = getClickedScreenCoords(xy[0][0], xy[0][1], graph.translation(), graph.scaleFactor()); + createNewNodeAtPosition(grPos); + }; + + /** --------------------------------------------------------- **/ + /** -- Hover and Selection functions, adding edit elements -- **/ + /** --------------------------------------------------------- **/ + + graph.ignoreOtherHoverEvents = function ( val ){ + if ( !arguments.length ) { + return ignoreOtherHoverEvents; + } + else ignoreOtherHoverEvents = val; + }; + + function delayedHiddingHoverElements( tbh ){ + if ( tbh === true ) return; + if ( hoveredNodeElement ) { + if ( hoveredNodeElement.editingTextElement === true ) return; + delayedHider = setTimeout(function (){ + deleteGroupElement.classed("hidden", true); + addDataPropertyGroupElement.classed("hidden", true); + classDragger.hideDragger(true); + if ( hoveredNodeElement && hoveredNodeElement.pinned() === false && graph.paused() === false && hoveredNodeElement.editingTextElement === false ) { + hoveredNodeElement.frozen(false); + hoveredNodeElement.locked(false); + } + }, 1000); + } + if ( hoveredPropertyElement ) { + if ( hoveredPropertyElement.editingTextElement === true ) return; + delayedHider = setTimeout(function (){ + deleteGroupElement.classed("hidden", true); + addDataPropertyGroupElement.classed("hidden", true); + classDragger.hideDragger(true); + rangeDragger.hideDragger(true); + domainDragger.hideDragger(true); + shadowClone.hideClone(true); + if ( hoveredPropertyElement && hoveredPropertyElement.focused() === true && graph.options().drawPropertyDraggerOnHover() === true ) { + hoveredPropertyElement.labelObject().increasedLoopAngle = false; + // lazy update + recalculatePositions(); + } + + if ( hoveredPropertyElement && hoveredPropertyElement.pinned() === false && graph.paused() === false && hoveredPropertyElement.editingTextElement === false ) { + hoveredPropertyElement.frozen(false); + hoveredPropertyElement.locked(false); + } + }, 1000); + } + + } + + + // TODO : experimental code for updating dynamic label with and its hover element + graph.hideHoverPropertyElementsForAnimation = function (){ + deleteGroupElement.classed("hidden", true); + }; + graph.showHoverElementsAfterAnimation = function ( property, inversed ){ + setDeleteHoverElementPositionProperty(property, inversed); + deleteGroupElement.classed("hidden", false); + + }; + + function editElementHoverOnHidden(){ + classDragger.nodeElement.classed("classDraggerNodeHovered", true); + classDragger.nodeElement.classed("classDraggerNode", false); + editElementHoverOn(); + } + + function editElementHoverOutHidden(){ + classDragger.nodeElement.classed("classDraggerNodeHovered", false); + classDragger.nodeElement.classed("classDraggerNode", true); + editElementHoverOut(); + } + + function editElementHoverOn( touch ){ + if ( touch === true ) return; + clearTimeout(delayedHider); // ignore touch behaviour + + } + + graph.killDelayedTimer = function (){ + clearTimeout(delayedHider); + clearTimeout(nodeFreezer); + }; + + + function editElementHoverOut( tbh ){ + if ( hoveredNodeElement ) { + if ( graph.ignoreOtherHoverEvents() === true || tbh === true || hoveredNodeElement.editingTextElement === true ) return; + delayedHider = setTimeout(function (){ + if ( graph.isADraggerActive() === true ) return; + deleteGroupElement.classed("hidden", true); + addDataPropertyGroupElement.classed("hidden", true); + classDragger.hideDragger(true); + if ( hoveredNodeElement && hoveredNodeElement.pinned() === false && graph.paused() === false ) { + hoveredNodeElement.frozen(false); + hoveredNodeElement.locked(false); + } + + }, 1000); + } + if ( hoveredPropertyElement ) { + if ( graph.ignoreOtherHoverEvents() === true || tbh === true || hoveredPropertyElement.editingTextElement === true ) return; + delayedHider = setTimeout(function (){ + if ( graph.isADraggerActive() === true ) return; + deleteGroupElement.classed("hidden", true); + addDataPropertyGroupElement.classed("hidden", true); + classDragger.hideDragger(true); + if ( hoveredPropertyElement && hoveredPropertyElement.pinned() === false && graph.paused() === false ) { + hoveredPropertyElement.frozen(false); + hoveredPropertyElement.locked(false); + } + + }, 1000); + } + } + + graph.activateHoverElementsForProperties = function ( val, property, inversed, touchBehaviour ){ + if ( editMode === false ) return; // nothing to do; + + if ( touchBehaviour === undefined ) + touchBehaviour = false; + + if ( val === true ) { + clearTimeout(delayedHider); + if ( hoveredPropertyElement ) { + if ( hoveredPropertyElement.domain() === hoveredPropertyElement.range() ) { + hoveredPropertyElement.labelObject().increasedLoopAngle = false; + recalculatePositions(); + } + } + + hoveredPropertyElement = property; + if ( graph.options().drawPropertyDraggerOnHover() === true ) { + + + if ( property.type() !== "owl:DatatypeProperty" ) { + if ( property.domain() === property.range() ) { + property.labelObject().increasedLoopAngle = true; + recalculatePositions(); + } + shadowClone.setParentProperty(property, inversed); + rangeDragger.setParentProperty(property, inversed); + rangeDragger.hideDragger(false); + rangeDragger.addMouseEvents(); + domainDragger.setParentProperty(property, inversed); + domainDragger.hideDragger(false); + domainDragger.addMouseEvents(); + + + } else if ( property.type() === "owl:DatatypeProperty" ) { + shadowClone.setParentProperty(property, inversed); + rangeDragger.setParentProperty(property, inversed); + rangeDragger.hideDragger(true); + rangeDragger.addMouseEvents(); + domainDragger.setParentProperty(property, inversed); + domainDragger.hideDragger(false); + domainDragger.addMouseEvents(); + } + } + else { // hide when we dont want that option + if ( graph.options().drawPropertyDraggerOnHover() === true ) { + rangeDragger.hideDragger(true); + domainDragger.hideDragger(true); + shadowClone.hideClone(true); + if ( property.domain() === property.range() ) { + property.labelObject().increasedLoopAngle = false; + recalculatePositions(); + } + } + } + + if ( hoveredNodeElement ) { + if ( hoveredNodeElement && hoveredNodeElement.pinned() === false && graph.paused() === false ) { + hoveredNodeElement.frozen(false); + hoveredNodeElement.locked(false); + } + } + hoveredNodeElement = undefined; + deleteGroupElement.classed("hidden", false); + setDeleteHoverElementPositionProperty(property, inversed); + deleteGroupElement.selectAll("*").on("click", function (){ + if ( touchBehaviour && property.focused() === false ) { + graph.options().focuserModule().handle(property); + return; + } + graph.removePropertyViaEditor(property); + d3.event.stopPropagation(); + }); + classDragger.hideDragger(true); + addDataPropertyGroupElement.classed("hidden", true); + } else { + delayedHiddingHoverElements(); + } + }; + + graph.updateDraggerElements = function (){ + + // set opacity style for all elements + + rangeDragger.draggerObject.classed("superOpacityElement", !graph.options().showDraggerObject()); + domainDragger.draggerObject.classed("superOpacityElement", !graph.options().showDraggerObject()); + classDragger.draggerObject.classed("superOpacityElement", !graph.options().showDraggerObject()); + + nodeContainer.selectAll(".superHiddenElement").classed("superOpacityElement", !graph.options().showDraggerObject()); + labelContainer.selectAll(".superHiddenElement").classed("superOpacityElement", !graph.options().showDraggerObject()); + + deleteGroupElement.selectAll(".superHiddenElement").classed("superOpacityElement", !graph.options().showDraggerObject()); + addDataPropertyGroupElement.selectAll(".superHiddenElement").classed("superOpacityElement", !graph.options().showDraggerObject()); + + + }; + + function setAddDataPropertyHoverElementPosition( node ){ + var delX, delY = 0; + if ( node.renderType() === "round" ) { + var scale = 0.5 * Math.sqrt(2.0); + var oX = scale * node.actualRadius(); + var oY = scale * node.actualRadius(); + delX = node.x - oX; + delY = node.y + oY; + addDataPropertyGroupElement.attr("transform", "translate(" + delX + "," + delY + ")"); + } + } + + function setDeleteHoverElementPosition( node ){ + var delX, delY = 0; + if ( node.renderType() === "round" ) { + var scale = 0.5 * Math.sqrt(2.0); + var oX = scale * node.actualRadius(); + var oY = scale * node.actualRadius(); + delX = node.x + oX; + delY = node.y - oY; + } else { + delX = node.x + 0.5 * node.width() + 6; + delY = node.y - 0.5 * node.height() - 6; + } + deleteGroupElement.attr("transform", "translate(" + delX + "," + delY + ")"); + } + + function setDeleteHoverElementPositionProperty( property, inversed ){ + if ( property && property.labelElement() ) { + var pos = [property.labelObject().x, property.labelObject().y]; + var widthElement = parseFloat(property.getShapeElement().attr("width")); + var heightElement = parseFloat(property.getShapeElement().attr("height")); + var delX = pos[0] + 0.5 * widthElement + 6; + var delY = pos[1] - 0.5 * heightElement - 6; + // this is the lower element + if ( property.labelElement().attr("transform") === "translate(0,15)" ) + delY += 15; + // this is upper element + if ( property.labelElement().attr("transform") === "translate(0,-15)" ) + delY -= 15; + deleteGroupElement.attr("transform", "translate(" + delX + "," + delY + ")"); + } else { + deleteGroupElement.classed("hidden", true);// hide when there is no property + } + + + } + + graph.activateHoverElements = function ( val, node, touchBehaviour ){ + if ( editMode === false ) { + return; // nothing to do; + } + if ( touchBehaviour === undefined ) touchBehaviour = false; + if ( val === true ) { + if ( graph.options().drawPropertyDraggerOnHover() === true ) { + rangeDragger.hideDragger(true); + domainDragger.hideDragger(true); + shadowClone.hideClone(true); + } + // make them visible + clearTimeout(delayedHider); + clearTimeout(nodeFreezer); + if ( hoveredNodeElement && node.pinned() === false && graph.paused() === false ) { + hoveredNodeElement.frozen(false); + hoveredNodeElement.locked(false); + } + hoveredNodeElement = node; + if ( node && node.frozen() === false && node.pinned() === false ) { + node.frozen(true); + node.locked(false); + } + if ( hoveredPropertyElement && hoveredPropertyElement.focused() === false ) { + hoveredPropertyElement.labelObject().increasedLoopAngle = false; + recalculatePositions(); + // update the loopAngles; + + } + hoveredPropertyElement = undefined; + deleteGroupElement.classed("hidden", false); + setDeleteHoverElementPosition(node); + + + deleteGroupElement.selectAll("*").on("click", function (){ + if ( touchBehaviour && node.focused() === false ) { + graph.options().focuserModule().handle(node); + return; + } + graph.removeNodeViaEditor(node); + d3.event.stopPropagation(); + }) + .on("mouseover", function (){ + editElementHoverOn(node, touchBehaviour); + }) + .on("mouseout", function (){ + editElementHoverOut(node, touchBehaviour); + }); + + addDataPropertyGroupElement.classed("hidden", true); + classDragger.nodeElement.on("mouseover", editElementHoverOn) + .on("mouseout", editElementHoverOut); + classDragger.draggerObject.on("mouseover", editElementHoverOnHidden) + .on("mouseout", editElementHoverOutHidden); + + // add the dragger element; + if ( node.renderType() === "round" ) { + classDragger.svgRoot(draggerLayer); + classDragger.setParentNode(node); + classDragger.hideDragger(false); + addDataPropertyGroupElement.classed("hidden", false); + setAddDataPropertyHoverElementPosition(node); + addDataPropertyGroupElement.selectAll("*").on("click", function (){ + if ( touchBehaviour && node.focused() === false ) { + graph.options().focuserModule().handle(node); + return; + } + graph.createDataTypeProperty(node); + d3.event.stopPropagation(); + }) + .on("mouseover", function (){ + editElementHoverOn(node, touchBehaviour); + }) + .on("mouseout", function (){ + editElementHoverOut(node, touchBehaviour); + }); + } else { + classDragger.hideDragger(true); + + } + + } else { + delayedHiddingHoverElements(node, touchBehaviour); + + } + }; + + + return graph; +}; diff --git a/src/webvowl/js/modules/collapsing.js b/src/webvowl/js/modules/collapsing.js new file mode 100644 index 0000000000000000000000000000000000000000..0acd139d2dcc27a508b0977fb1933bb12257b5e5 --- /dev/null +++ b/src/webvowl/js/modules/collapsing.js @@ -0,0 +1,43 @@ +var elementTools = require("../util/elementTools")(); + +module.exports = function (){ + var collapsing = {}, + enabled = false, + filteredNodes, filteredProperties; + + collapsing.filter = function ( nodes, properties ){ + // Nothing is filtered, we just need to draw everywehere + filteredNodes = nodes; + filteredProperties = properties; + + + var i, l, node; + + for ( i = 0, l = nodes.length; i < l; i++ ) { + node = nodes[i]; + if ( !elementTools.isDatatype(node) ) { + node.collapsible(enabled); + } + } + }; + + collapsing.enabled = function ( p ){ + if ( !arguments.length ) return enabled; + enabled = p; + return collapsing; + }; + + collapsing.reset = function (){ + // todo + }; + + collapsing.filteredNodes = function (){ + return filteredNodes; + }; + + collapsing.filteredProperties = function (){ + return filteredProperties; + }; + + return collapsing; +}; diff --git a/src/webvowl/js/modules/colorExternalsSwitch.js b/src/webvowl/js/modules/colorExternalsSwitch.js new file mode 100644 index 0000000000000000000000000000000000000000..eb3d17af3265e1642d015127c2a82489f311536d --- /dev/null +++ b/src/webvowl/js/modules/colorExternalsSwitch.js @@ -0,0 +1,118 @@ +var _ = require("lodash/core"); + +module.exports = function (){ + + var DEFAULT_STATE = true; + var COLOR_MODES = [ + { type: "same", range: [d3.rgb("#36C"), d3.rgb("#36C")] }, + { type: "gradient", range: [d3.rgb("#36C"), d3.rgb("#EE2867")] } // taken from LD-VOWL + ]; + + var filter = {}, + nodes, + properties, + enabled = DEFAULT_STATE, + filteredNodes, + filteredProperties, + colorModeType = "same"; + + + filter.filter = function ( untouchedNodes, untouchedProperties ){ + nodes = untouchedNodes; + properties = untouchedProperties; + + var externalElements = filterExternalElements(nodes.concat(properties)); + + if ( enabled ) { + setColorsForExternals(externalElements); + } else { + resetBackgroundColors(externalElements); + } + + filteredNodes = nodes; + filteredProperties = properties; + }; + + function filterExternalElements( elements ){ + return elements.filter(function ( element ){ + if ( element.visualAttributes().indexOf("deprecated") >= 0 ) { + // deprecated is the only attribute which has preference over external + return false; + } + + return element.attributes().indexOf("external") >= 0; + }); + } + + function setColorsForExternals( elements ){ + var iriMap = mapExternalsToBaseUri(elements); + var entries = iriMap.entries(); + + var colorScale = d3.scale.linear() + .domain([0, entries.length - 1]) + .range(_.find(COLOR_MODES, { type: colorModeType }).range) + .interpolate(d3.interpolateHsl); + + for ( var i = 0; i < entries.length; i++ ) { + var groupedElements = entries[i].value; + setBackgroundColorForElements(groupedElements, colorScale(i)); + } + } + + function mapExternalsToBaseUri( elements ){ + var map = d3.map(); + + elements.forEach(function ( element ){ + var baseIri = element.baseIri(); + + if ( !map.has(baseIri) ) { + map.set(baseIri, []); + } + map.get(baseIri).push(element); + }); + + return map; + } + + function setBackgroundColorForElements( elements, backgroundColor ){ + elements.forEach(function ( element ){ + element.backgroundColor(backgroundColor); + }); + } + + function resetBackgroundColors( elements ){ + console.log("Resetting color"); + elements.forEach(function ( element ){ + element.backgroundColor(null); + }); + } + + filter.colorModeType = function ( p ){ + if ( !arguments.length ) return colorModeType; + colorModeType = p; + return filter; + }; + + filter.enabled = function ( p ){ + if ( !arguments.length ) return enabled; + enabled = p; + return filter; + }; + + filter.reset = function (){ + enabled = DEFAULT_STATE; + }; + + + // Functions a filter must have + filter.filteredNodes = function (){ + return filteredNodes; + }; + + filter.filteredProperties = function (){ + return filteredProperties; + }; + + + return filter; +}; diff --git a/src/webvowl/js/modules/compactNotationSwitch.js b/src/webvowl/js/modules/compactNotationSwitch.js new file mode 100644 index 0000000000000000000000000000000000000000..bd1e23c49d0298a8b4f2b680e410680dc41061bb --- /dev/null +++ b/src/webvowl/js/modules/compactNotationSwitch.js @@ -0,0 +1,55 @@ +/** + * This module abuses the filter function a bit like the statistics module. Nothing is filtered. + * + * @returns {{}} + */ + + +module.exports = function ( graph ){ + + var DEFAULT_STATE = false; + + var filter = {}, + nodes, + properties, + enabled = DEFAULT_STATE, + filteredNodes, + filteredProperties; + + + /** + * If enabled, redundant details won't be drawn anymore. + * @param untouchedNodes + * @param untouchedProperties + */ + filter.filter = function ( untouchedNodes, untouchedProperties ){ + nodes = untouchedNodes; + properties = untouchedProperties; + graph.options().compactNotation(enabled); + filteredNodes = nodes; + filteredProperties = properties; + }; + + filter.enabled = function ( p ){ + if ( !arguments.length ) return enabled; + enabled = p; + return filter; + }; + + filter.reset = function (){ + enabled = DEFAULT_STATE; + }; + + + // Functions a filter must have + filter.filteredNodes = function (){ + return filteredNodes; + }; + + filter.filteredProperties = function (){ + return filteredProperties; + }; + + + return filter; +}; diff --git a/src/webvowl/js/modules/datatypeFilter.js b/src/webvowl/js/modules/datatypeFilter.js new file mode 100644 index 0000000000000000000000000000000000000000..eb0476ef329e6e373c124c64fcb550e19d1933f4 --- /dev/null +++ b/src/webvowl/js/modules/datatypeFilter.js @@ -0,0 +1,60 @@ +var elementTools = require("../util/elementTools")(); +var filterTools = require("../util/filterTools")(); + +module.exports = function (){ + + var filter = {}, + nodes, + properties, + enabled = false, + filteredNodes, + filteredProperties; + + + /** + * If enabled, all datatypes and literals including connected properties are filtered. + * @param untouchedNodes + * @param untouchedProperties + */ + filter.filter = function ( untouchedNodes, untouchedProperties ){ + nodes = untouchedNodes; + properties = untouchedProperties; + + if ( this.enabled() ) { + removeDatatypesAndLiterals(); + } + + filteredNodes = nodes; + filteredProperties = properties; + }; + + function removeDatatypesAndLiterals(){ + var filteredData = filterTools.filterNodesAndTidy(nodes, properties, isNoDatatypeOrLiteral); + + nodes = filteredData.nodes; + properties = filteredData.properties; + } + + function isNoDatatypeOrLiteral( node ){ + return !elementTools.isDatatype(node); + } + + filter.enabled = function ( p ){ + if ( !arguments.length ) return enabled; + enabled = p; + return filter; + }; + + + // Functions a filter must have + filter.filteredNodes = function (){ + return filteredNodes; + }; + + filter.filteredProperties = function (){ + return filteredProperties; + }; + + + return filter; +}; diff --git a/src/webvowl/js/modules/disjointFilter.js b/src/webvowl/js/modules/disjointFilter.js new file mode 100644 index 0000000000000000000000000000000000000000..3868e3e3a1eb171468653d3a01e63420c70e95b6 --- /dev/null +++ b/src/webvowl/js/modules/disjointFilter.js @@ -0,0 +1,64 @@ +var OwlDisjointWith = require("../elements/properties/implementations/OwlDisjointWith"); + +module.exports = function (){ + + var filter = {}, + nodes, + properties, + // According to the specification enabled by default + enabled = true, + filteredNodes, + filteredProperties; + + + /** + * If enabled, all disjoint with properties are filtered. + * @param untouchedNodes + * @param untouchedProperties + */ + filter.filter = function ( untouchedNodes, untouchedProperties ){ + nodes = untouchedNodes; + properties = untouchedProperties; + + if ( this.enabled() ) { + removeDisjointWithProperties(); + } + + filteredNodes = nodes; + filteredProperties = properties; + }; + + function removeDisjointWithProperties(){ + var cleanedProperties = [], + i, l, property; + + for ( i = 0, l = properties.length; i < l; i++ ) { + property = properties[i]; + + if ( !(property instanceof OwlDisjointWith) ) { + cleanedProperties.push(property); + } + } + + properties = cleanedProperties; + } + + filter.enabled = function ( p ){ + if ( !arguments.length ) return enabled; + enabled = p; + return filter; + }; + + + // Functions a filter must have + filter.filteredNodes = function (){ + return filteredNodes; + }; + + filter.filteredProperties = function (){ + return filteredProperties; + }; + + + return filter; +}; diff --git a/src/webvowl/js/modules/emptyLiteralFilter.js b/src/webvowl/js/modules/emptyLiteralFilter.js new file mode 100644 index 0000000000000000000000000000000000000000..0dcf72d58c4128d7da75af7a4da96ba9cbb5fd7b --- /dev/null +++ b/src/webvowl/js/modules/emptyLiteralFilter.js @@ -0,0 +1,102 @@ +/** @WORKAROUND CODE: + * clears empty literals that are provided by owl2vowl: 0.2.2x*/ + + +module.exports = function (){ + + var filter = {}, + enabled = true, + filteredNodes, + removedNodes, + filteredProperties; + + filter.enabled = function ( val ){ + if ( !arguments.length ) { + return enabled; + } + enabled = val; + }; + + filter.filter = function ( nodes, properties ){ + if ( enabled === false ) { + filteredNodes = nodes; + filteredProperties = properties; + removedNodes = []; + return; + } + var literalUsageMap = []; + var thingUsageMap = []; + var node; + for ( var i = 0; i < properties.length; i++ ) { + // get property range; + var prop = properties[i]; + + // checking for literals + if ( prop.range() ) { + node = prop.range(); + if ( node.type() === "rdfs:Literal" ) { + literalUsageMap[node.id()] = 1; + } + } + // checking for thing + if ( prop.range() ) { + node = prop.range(); + if ( node.type() === "owl:Thing" ) { + thingUsageMap[node.id()] = 1; + } + } + if ( prop.domain() ) { + node = prop.domain(); + if ( node.type() === "owl:Thing" ) { + thingUsageMap[node.id()] = 1; + } + } + + } + var nodesToRemove = []; + var newNodes = []; + // todo: test and make it faster + for ( i = 0; i < nodes.length; i++ ) { + var nodeId = nodes[i].id(); + if ( nodes[i].type() === "rdfs:Literal" ) { + if ( literalUsageMap[nodeId] === undefined ) { + nodesToRemove.push(nodeId); + } + else { + newNodes.push(nodes[i]); + } + // check for node type == OWL:THING + } else if ( nodes[i].type() === "owl:Thing" ) { + if ( thingUsageMap[nodeId] === undefined ) { + nodesToRemove.push(nodeId); + } + else { + newNodes.push(nodes[i]); + } + } else { + newNodes.push(nodes[i]); + } + } + + filteredNodes = newNodes; + filteredProperties = properties; + removedNodes = nodesToRemove; + }; + + + // Functions a filter must have + filter.filteredNodes = function (){ + return filteredNodes; + }; + + filter.removedNodes = function (){ + return removedNodes; + }; + + filter.filteredProperties = function (){ + return filteredProperties; + }; + + + return filter; +}; diff --git a/src/webvowl/js/modules/filterModuleTemplate.js b/src/webvowl/js/modules/filterModuleTemplate.js new file mode 100644 index 0000000000000000000000000000000000000000..f2023bb207c11b657b5600c8bec94abb5268cb84 --- /dev/null +++ b/src/webvowl/js/modules/filterModuleTemplate.js @@ -0,0 +1,28 @@ +module.exports = function (){ + + var filter = {}, + filteredNodes, + filteredProperties; + + + filter.filter = function ( nodes, properties ){ + + // Filter the data + + filteredNodes = nodes; + filteredProperties = properties; + }; + + + // Functions a filter must have + filter.filteredNodes = function (){ + return filteredNodes; + }; + + filter.filteredProperties = function (){ + return filteredProperties; + }; + + + return filter; +}; diff --git a/src/webvowl/js/modules/focuser.js b/src/webvowl/js/modules/focuser.js new file mode 100644 index 0000000000000000000000000000000000000000..75f566bdbaecbf955381b1332167d8b8adcacb38 --- /dev/null +++ b/src/webvowl/js/modules/focuser.js @@ -0,0 +1,51 @@ +module.exports = function ( graph ){ + var focuser = {}, + focusedElement; + var elementTools = webvowl.util.elementTools(); + focuser.handle = function ( selectedElement, forced ){ + // Don't display details on a drag event, which will be prevented + if ( d3.event && d3.event.defaultPrevented && forced === undefined ) { + return; + } + + if ( focusedElement !== undefined ) { + focusedElement.toggleFocus(); + } + + if ( focusedElement !== selectedElement && selectedElement ) { + selectedElement.toggleFocus(); + focusedElement = selectedElement; + } else { + focusedElement = undefined; + } + if ( focusedElement && focusedElement.focused() ) { + graph.options().editSidebar().updateSelectionInformation(focusedElement); + if ( elementTools.isProperty(selectedElement) === true ) { + var inversed = false; + if ( selectedElement.inverse() ) { + inversed = true; + } + graph.activateHoverElementsForProperties(true, selectedElement, inversed, graph.isTouchDevice()); + } + else { + graph.activateHoverElements(true, selectedElement, graph.isTouchDevice()); + } + } + else { + graph.options().editSidebar().updateSelectionInformation(undefined); + graph.removeEditElements(); + } + }; + + /** + * Removes the focus if an element is focussed. + */ + focuser.reset = function (){ + if ( focusedElement ) { + focusedElement.toggleFocus(); + focusedElement = undefined; + } + }; + + return focuser; +}; diff --git a/src/webvowl/js/modules/nodeDegreeFilter.js b/src/webvowl/js/modules/nodeDegreeFilter.js new file mode 100644 index 0000000000000000000000000000000000000000..36bb6290196bd22e89c4f9deff3a584dff8f4c4e --- /dev/null +++ b/src/webvowl/js/modules/nodeDegreeFilter.js @@ -0,0 +1,156 @@ +var elementTools = require("../util/elementTools")(); +var filterTools = require("../util/filterTools")(); + +module.exports = function ( menu ){ + + var filter = {}, + nodes, + properties, + enabled = true, + filteredNodes, + filteredProperties, + maxDegreeSetter, + degreeGetter, + lastFiltedDegree, + degreeSetter; + + + var NODE_COUNT_LIMIT_FOR_AUTO_ENABLING = 50; + + + filter.initialize = function ( nodes, properties ){ + lastFiltedDegree = -1; + var maxLinkCount = findMaxLinkCount(nodes); + if ( maxDegreeSetter instanceof Function ) { + maxDegreeSetter(maxLinkCount); + } + + menu.setDefaultDegreeValue(findAutoDefaultDegree(nodes, properties, maxLinkCount)); + var defaultDegree = findDefaultDegree(maxLinkCount); + if ( degreeSetter instanceof Function ) { + degreeSetter(defaultDegree); + if ( defaultDegree > 0 ) { + menu.highlightForDegreeSlider(true); + menu.getGraphObject().setFilterWarning(true); + + } + } else { + console.error("No degree setter function set."); + } + }; + + function findAutoDefaultDegree( nodes, properties, maxDegree ){ + for ( var degree = 0; degree < maxDegree; degree++ ) { + var filteredData = filterByNodeDegree(nodes, properties, degree); + + if ( filteredData.nodes.length <= NODE_COUNT_LIMIT_FOR_AUTO_ENABLING ) { + return degree; + } + } + return 0; + } + + function findDefaultDegree( maxDegree ){ + var globalDegOfFilter = menu.getGraphObject().getGlobalDOF(); + if ( globalDegOfFilter >= 0 ) { + if ( globalDegOfFilter <= maxDegree ) { + return globalDegOfFilter; + } else { + menu.getGraphObject().setGlobalDOF(maxDegree); + return maxDegree; + } + } + return menu.getDefaultDegreeValue(); + } + + /** + * If enabled, all nodes are filter by their node degree. + * @param untouchedNodes + * @param untouchedProperties + */ + filter.filter = function ( untouchedNodes, untouchedProperties ){ + nodes = untouchedNodes; + properties = untouchedProperties; + + if ( this.enabled() ) { + if ( degreeGetter instanceof Function ) { + filterByNodeDegreeAndApply(degreeGetter()); + } else { + console.error("No degree query function set."); + } + } + + filteredNodes = nodes; + filteredProperties = properties; + + if ( filteredNodes.length === 0 ) { + degreeSetter(0); + filteredNodes = untouchedNodes; + filteredProperties = untouchedProperties; + } + lastFiltedDegree = degreeGetter(); + }; + + function findMaxLinkCount( nodes ){ + var maxLinkCount = 0; + for ( var i = 0, l = nodes.length; i < l; i++ ) { + var linksWithoutDatatypes = filterOutDatatypes(nodes[i].links()); + + maxLinkCount = Math.max(maxLinkCount, linksWithoutDatatypes.length); + } + return maxLinkCount; + } + + function filterOutDatatypes( links ){ + return links.filter(function ( link ){ + return !elementTools.isDatatypeProperty(link.property()); + }); + } + + function filterByNodeDegreeAndApply( minDegree ){ + var filteredData = filterByNodeDegree(nodes, properties, minDegree); + nodes = filteredData.nodes; + properties = filteredData.properties; + } + + function filterByNodeDegree( nodes, properties, minDegree ){ + return filterTools.filterNodesAndTidy(nodes, properties, hasRequiredDegree(minDegree)); + } + + function hasRequiredDegree( minDegree ){ + return function ( node ){ + return filterOutDatatypes(node.links()).length >= minDegree; + }; + } + + filter.setMaxDegreeSetter = function ( _maxDegreeSetter ){ + maxDegreeSetter = _maxDegreeSetter; + }; + + filter.setDegreeGetter = function ( _degreeGetter ){ + degreeGetter = _degreeGetter; + }; + + filter.setDegreeSetter = function ( _degreeSetter ){ + degreeSetter = _degreeSetter; + }; + + filter.enabled = function ( p ){ + if ( !arguments.length ) return enabled; + enabled = p; + return filter; + }; + + + // Functions a filter must have + filter.filteredNodes = function (){ + return filteredNodes; + }; + + filter.filteredProperties = function (){ + return filteredProperties; + }; + + + return filter; +}; diff --git a/src/webvowl/js/modules/nodeScalingSwitch.js b/src/webvowl/js/modules/nodeScalingSwitch.js new file mode 100644 index 0000000000000000000000000000000000000000..691e52b2000281a3d27e794840cc80bf0e5f294e --- /dev/null +++ b/src/webvowl/js/modules/nodeScalingSwitch.js @@ -0,0 +1,55 @@ +/** + * This module abuses the filter function a bit like the statistics module. Nothing is filtered. + * + * @returns {{}} + */ +module.exports = function ( graph ){ + + var DEFAULT_STATE = true; + + var filter = {}, + nodes, + properties, + enabled = DEFAULT_STATE, + filteredNodes, + filteredProperties; + + + /** + * If enabled, the scaling of nodes according to individuals will be enabled. + * @param untouchedNodes + * @param untouchedProperties + */ + filter.filter = function ( untouchedNodes, untouchedProperties ){ + nodes = untouchedNodes; + properties = untouchedProperties; + + graph.options().scaleNodesByIndividuals(enabled); + + filteredNodes = nodes; + filteredProperties = properties; + }; + + filter.enabled = function ( p ){ + if ( !arguments.length ) return enabled; + enabled = p; + return filter; + }; + + filter.reset = function (){ + enabled = DEFAULT_STATE; + }; + + + // Functions a filter must have + filter.filteredNodes = function (){ + return filteredNodes; + }; + + filter.filteredProperties = function (){ + return filteredProperties; + }; + + + return filter; +}; diff --git a/src/webvowl/js/modules/objectPropertyFilter.js b/src/webvowl/js/modules/objectPropertyFilter.js new file mode 100644 index 0000000000000000000000000000000000000000..037f9e2a8f790398c74f44224108e136c03f8bb5 --- /dev/null +++ b/src/webvowl/js/modules/objectPropertyFilter.js @@ -0,0 +1,79 @@ +var elementTools = require("../util/elementTools")(); + + +module.exports = function (){ + + var filter = {}, + nodes, + properties, + enabled = false, + filteredNodes, + filteredProperties; + + + /** + * If enabled, all object properties and things without any other property are filtered. + * @param untouchedNodes + * @param untouchedProperties + */ + filter.filter = function ( untouchedNodes, untouchedProperties ){ + nodes = untouchedNodes; + properties = untouchedProperties; + + if ( this.enabled() ) { + removeObjectProperties(); + } + + filteredNodes = nodes; + filteredProperties = properties; + }; + + function removeObjectProperties(){ + properties = properties.filter(isNoObjectProperty); + nodes = nodes.filter(isNoFloatingThing); + } + + function isNoObjectProperty( property ){ + return !elementTools.isObjectProperty(property); + } + + function isNoFloatingThing( node ){ + var isNoThing = !elementTools.isThing(node); + var hasNonFilteredProperties = hasPropertiesOtherThanObjectProperties(node, properties); + return isNoThing || hasNonFilteredProperties; + } + + function hasPropertiesOtherThanObjectProperties( node, properties ){ + for ( var i = 0; i < properties.length; i++ ) { + var property = properties[i]; + if ( property.domain() !== node && property.range() !== node ) { + continue; + } + + if ( isNoObjectProperty(property) ) { + return true; + } + } + + return false; + } + + filter.enabled = function ( p ){ + if ( !arguments.length ) return enabled; + enabled = p; + return filter; + }; + + + // Functions a filter must have + filter.filteredNodes = function (){ + return filteredNodes; + }; + + filter.filteredProperties = function (){ + return filteredProperties; + }; + + + return filter; +}; diff --git a/src/webvowl/js/modules/pickAndPin.js b/src/webvowl/js/modules/pickAndPin.js new file mode 100644 index 0000000000000000000000000000000000000000..fbcca0187eaf9d327007271a9df1b0011ecf1a4c --- /dev/null +++ b/src/webvowl/js/modules/pickAndPin.js @@ -0,0 +1,64 @@ +var _ = require("lodash/array"); +var elementTools = require("../util/elementTools")(); + +module.exports = function (){ + var pap = {}, + enabled = false, + pinnedElements = []; + + pap.addPinnedElement = function ( element ){ + // check if element is already in list + var indexInArray = pinnedElements.indexOf(element); + if ( indexInArray === -1 ) { + pinnedElements.push(element); + } + }; + + pap.handle = function ( selection, forced ){ + if ( !enabled ) { + return; + } + + if ( !forced ) { + if ( wasNotDragged() ) { + return; + } + } + if ( elementTools.isProperty(selection) ) { + if ( selection.inverse() && selection.inverse().pinned() ) { + return; + } else if ( hasNoParallelProperties(selection) ) { + return; + } + } + + if ( !selection.pinned() ) { + selection.drawPin(); + pap.addPinnedElement(selection); + } + }; + + function wasNotDragged(){ + return !d3.event.defaultPrevented; + } + + function hasNoParallelProperties( property ){ + return _.intersection(property.domain().links(), property.range().links()).length === 1; + } + + pap.enabled = function ( p ){ + if ( !arguments.length ) return enabled; + enabled = p; + return pap; + }; + + pap.reset = function (){ + pinnedElements.forEach(function ( element ){ + element.removePin(); + }); + // Clear the array of stored nodes + pinnedElements.length = 0; + }; + + return pap; +}; diff --git a/src/webvowl/js/modules/selectionDetailsDisplayer.js b/src/webvowl/js/modules/selectionDetailsDisplayer.js new file mode 100644 index 0000000000000000000000000000000000000000..1f3139d7a98bbbb24227d5dc0b5f8031fa7dc3f2 --- /dev/null +++ b/src/webvowl/js/modules/selectionDetailsDisplayer.js @@ -0,0 +1,44 @@ +module.exports = function ( handlerFunction ){ + var viewer = {}, + lastSelectedElement; + + viewer.handle = function ( selectedElement ){ + // Don't display details on a drag event, which will be prevented + if ( d3.event.defaultPrevented ) { + return; + } + + var isSelection = true; + + // Deselection of the focused element + if ( lastSelectedElement === selectedElement ) { + isSelection = false; + } + + if ( handlerFunction instanceof Function ) { + if ( isSelection ) { + handlerFunction(selectedElement); + } else { + handlerFunction(undefined); + } + } + + if ( isSelection ) { + lastSelectedElement = selectedElement; + } else { + lastSelectedElement = undefined; + } + }; + + /** + * Resets the displayed information to its default. + */ + viewer.reset = function (){ + if ( lastSelectedElement ) { + handlerFunction(undefined); + lastSelectedElement = undefined; + } + }; + + return viewer; +}; diff --git a/src/webvowl/js/modules/setOperatorFilter.js b/src/webvowl/js/modules/setOperatorFilter.js new file mode 100644 index 0000000000000000000000000000000000000000..d51432458144c57f50e54b4ea32207dad77884ab --- /dev/null +++ b/src/webvowl/js/modules/setOperatorFilter.js @@ -0,0 +1,60 @@ +var SetOperatorNode = require("../elements/nodes/SetOperatorNode"); + +module.exports = function (){ + + var filter = {}, + nodes, + properties, + enabled = false, + filteredNodes, + filteredProperties, + filterTools = require("../util/filterTools")(); + + + /** + * If enabled, all set operators including connected properties are filtered. + * @param untouchedNodes + * @param untouchedProperties + */ + filter.filter = function ( untouchedNodes, untouchedProperties ){ + nodes = untouchedNodes; + properties = untouchedProperties; + + if ( this.enabled() ) { + removeSetOperators(); + } + + filteredNodes = nodes; + filteredProperties = properties; + }; + + function removeSetOperators(){ + var filteredData = filterTools.filterNodesAndTidy(nodes, properties, isNoSetOperator); + + nodes = filteredData.nodes; + properties = filteredData.properties; + } + + function isNoSetOperator( node ){ + return !(node instanceof SetOperatorNode); + } + + filter.enabled = function ( p ){ + if ( !arguments.length ) return enabled; + enabled = p; + return filter; + }; + + + // Functions a filter must have + filter.filteredNodes = function (){ + return filteredNodes; + }; + + filter.filteredProperties = function (){ + return filteredProperties; + }; + + + return filter; +}; diff --git a/src/webvowl/js/modules/statistics.js b/src/webvowl/js/modules/statistics.js new file mode 100644 index 0000000000000000000000000000000000000000..b07c6c5c43e408a55a9010e57eb0bb325242afbc --- /dev/null +++ b/src/webvowl/js/modules/statistics.js @@ -0,0 +1,227 @@ +var SetOperatorNode = require("../elements/nodes/SetOperatorNode"); +var OwlThing = require("../elements/nodes/implementations/OwlThing"); +var OwlNothing = require("../elements/nodes/implementations/OwlNothing"); +var elementTools = require("../util/elementTools")(); + +module.exports = function (){ + + var statistics = {}, + nodeCount, + occurencesOfClassAndDatatypeTypes = {}, + edgeCount, + occurencesOfPropertyTypes = {}, + classCount, + datatypeCount, + datatypePropertyCount, + objectPropertyCount, + propertyCount, + totalIndividualCount, + filteredNodes, + filteredProperties; + + + statistics.filter = function ( classesAndDatatypes, properties ){ + resetStoredData(); + + storeTotalCounts(classesAndDatatypes, properties); + storeClassAndDatatypeCount(classesAndDatatypes); + storePropertyCount(properties); + + storeOccurencesOfTypes(classesAndDatatypes, occurencesOfClassAndDatatypeTypes); + storeOccurencesOfTypes(properties, occurencesOfPropertyTypes); + + storeTotalIndividualCount(classesAndDatatypes); + + filteredNodes = classesAndDatatypes; + filteredProperties = properties; + }; + + function resetStoredData(){ + nodeCount = 0; + edgeCount = 0; + classCount = 0; + datatypeCount = 0; + datatypePropertyCount = 0; + objectPropertyCount = 0; + propertyCount = 0; + totalIndividualCount = 0; + } + + function storeTotalCounts( classesAndDatatypes, properties ){ + nodeCount = classesAndDatatypes.length; + + var seenProperties = require("../util/set")(), i, l, property; + for ( i = 0, l = properties.length; i < l; i++ ) { + property = properties[i]; + if ( !seenProperties.has(property) ) { + edgeCount += 1; + } + + seenProperties.add(property); + if ( property.inverse() ) { + seenProperties.add(property.inverse()); + } + } + } + + function storeClassAndDatatypeCount( classesAndDatatypes ){ + // Each datatype should be counted just a single time + var datatypeSet = d3.set(), + hasThing = false, + hasNothing = false; + classCount = 0; + var old = 0, newcc = 0; + classesAndDatatypes.forEach(function ( node ){ + if ( elementTools.isDatatype(node) ) { + datatypeSet.add(node.defaultLabel()); + } else if ( !(node instanceof SetOperatorNode) ) { + if ( node instanceof OwlThing ) { + hasThing = true; + } else if ( node instanceof OwlNothing ) { + hasNothing = true; + } else { + old = classCount; + var adds = 1 + countElementArray(node.equivalents()); + classCount += adds; + newcc = classCount; + } + } else if ( node instanceof SetOperatorNode ) { + old = classCount; + classCount += 1; + newcc = classCount; + } + }); + + // count things and nothings just a single time + // classCount += hasThing ? 1 : 0; + // classCount += hasNothing ? 1 : 0; + + datatypeCount = datatypeSet.size(); + } + + function storePropertyCount( properties ){ + for ( var i = 0, l = properties.length; i < l; i++ ) { + var property = properties[i]; + var attr; + var result = false; + if ( property.attributes ) { + attr = property.attributes(); + if ( attr && attr.indexOf("datatype") !== -1 ) { + result = true; + } + } + if ( result === true ) { + datatypePropertyCount += getExtendedPropertyCount(property); + } else if ( elementTools.isObjectProperty(property) ) { + objectPropertyCount += getExtendedPropertyCount(property); + } + } + propertyCount = objectPropertyCount + datatypePropertyCount; + } + + function getExtendedPropertyCount( property ){ + // count the property itself + var count = 1; + + // and count properties this property represents + count += countElementArray(property.equivalents()); + count += countElementArray(property.redundantProperties()); + + return count; + } + + function countElementArray( properties ){ + if ( properties ) { + return properties.length; + } + return 0; + } + + function storeOccurencesOfTypes( elements, storage ){ + elements.forEach(function ( element ){ + var type = element.type(), + typeCount = storage[type]; + + if ( typeof typeCount === "undefined" ) { + typeCount = 0; + } else { + typeCount += 1; + } + storage[type] = typeCount; + }); + } + + function storeTotalIndividualCount( nodes ){ + var sawIndividuals = {}; + var totalCount = 0; + for ( var i = 0, l = nodes.length; i < l; i++ ) { + var individuals = nodes[i].individuals(); + + var tempCount = 0; + for ( var iA = 0; iA < individuals.length; iA++ ) { + if ( sawIndividuals[individuals[iA].iri()] === undefined ) { + sawIndividuals[individuals[iA].iri()] = 1; // this iri for that individual is now set to 1 >> seen it + tempCount++; + } + } + totalCount += tempCount; + } + totalIndividualCount = totalCount; + sawIndividuals = {}; // clear the object + + } + + + statistics.nodeCount = function (){ + return nodeCount; + }; + + statistics.occurencesOfClassAndDatatypeTypes = function (){ + return occurencesOfClassAndDatatypeTypes; + }; + + statistics.edgeCount = function (){ + return edgeCount; + }; + + statistics.occurencesOfPropertyTypes = function (){ + return occurencesOfPropertyTypes; + }; + + statistics.classCount = function (){ + return classCount; + }; + + statistics.datatypeCount = function (){ + return datatypeCount; + }; + + statistics.datatypePropertyCount = function (){ + return datatypePropertyCount; + }; + + statistics.objectPropertyCount = function (){ + return objectPropertyCount; + }; + + statistics.propertyCount = function (){ + return propertyCount; + }; + + statistics.totalIndividualCount = function (){ + return totalIndividualCount; + }; + + + // Functions a filter must have + statistics.filteredNodes = function (){ + return filteredNodes; + }; + + statistics.filteredProperties = function (){ + return filteredProperties; + }; + + + return statistics; +}; diff --git a/src/webvowl/js/modules/subclassFilter.js b/src/webvowl/js/modules/subclassFilter.js new file mode 100644 index 0000000000000000000000000000000000000000..e682439535055b7c12bbb81adb108fa30cd14662 --- /dev/null +++ b/src/webvowl/js/modules/subclassFilter.js @@ -0,0 +1,180 @@ +var elementTools = require("../util/elementTools")(); + +module.exports = function (){ + + var filter = {}, + nodes, + properties, + enabled = false, + filteredNodes, + filteredProperties; + + + /** + * If enabled subclasses that have only subclass properties are filtered. + * @param untouchedNodes + * @param untouchedProperties + */ + filter.filter = function ( untouchedNodes, untouchedProperties ){ + nodes = untouchedNodes; + properties = untouchedProperties; + + if ( this.enabled() ) { + hideSubclassesWithoutOwnProperties(); + } + + filteredNodes = nodes; + filteredProperties = properties; + }; + + function hideSubclassesWithoutOwnProperties(){ + var unneededProperties = [], + unneededClasses = [], + subclasses = [], + connectedProperties, + subclass, + property, + i, // index, + l; // length + + + for ( i = 0, l = properties.length; i < l; i++ ) { + property = properties[i]; + if ( elementTools.isRdfsSubClassOf(property) ) { + subclasses.push(property.domain()); + } + } + + for ( i = 0, l = subclasses.length; i < l; i++ ) { + subclass = subclasses[i]; + connectedProperties = findRelevantConnectedProperties(subclass, properties); + + // Only remove the node and its properties, if they're all subclassOf properties + if ( areOnlySubclassProperties(connectedProperties) && + doesNotInheritFromMultipleClasses(subclass, connectedProperties) ) { + + unneededProperties = unneededProperties.concat(connectedProperties); + unneededClasses.push(subclass); + } + } + + nodes = removeUnneededElements(nodes, unneededClasses); + properties = removeUnneededElements(properties, unneededProperties); + } + + /** + * Looks recursively for connected properties. Because just subclasses are relevant, + * we just look recursively for their properties. + * + * @param node + * @param allProperties + * @param visitedNodes a visited nodes which is used on recursive invocation + * @returns {Array} + */ + function findRelevantConnectedProperties( node, allProperties, visitedNodes ){ + var connectedProperties = [], + property, + i, + l; + + for ( i = 0, l = allProperties.length; i < l; i++ ) { + property = allProperties[i]; + if ( property.domain() === node || + property.range() === node ) { + + connectedProperties.push(property); + + + /* Special case: SuperClass <-(1) Subclass <-(2) Subclass ->(3) e.g. Datatype + * We need to find the last property recursively. Otherwise, we would remove the subClassOf + * property (1) because we didn't see the datatype property (3). + */ + + // Look only for subclass properties, because these are the relevant properties + if ( elementTools.isRdfsSubClassOf(property) ) { + var domain = property.domain(); + visitedNodes = visitedNodes || require("../util/set")(); + + // If we have the range, there might be a nested property on the domain + if ( node === property.range() && !visitedNodes.has(domain) ) { + visitedNodes.add(domain); + var nestedConnectedProperties = findRelevantConnectedProperties(domain, allProperties, visitedNodes); + connectedProperties = connectedProperties.concat(nestedConnectedProperties); + } + } + } + } + + return connectedProperties; + } + + function areOnlySubclassProperties( connectedProperties ){ + var onlySubclassProperties = true, + property, + i, + l; + + for ( i = 0, l = connectedProperties.length; i < l; i++ ) { + property = connectedProperties[i]; + + if ( !elementTools.isRdfsSubClassOf(property) ) { + onlySubclassProperties = false; + break; + } + } + + return onlySubclassProperties; + } + + function doesNotInheritFromMultipleClasses( subclass, connectedProperties ){ + var superClassCount = 0; + + for ( var i = 0, l = connectedProperties.length; i < l; i++ ) { + var property = connectedProperties[i]; + + if ( property.domain() === subclass ) { + superClassCount += 1; + } + + if ( superClassCount > 1 ) { + return false; + } + } + + return true; + } + + function removeUnneededElements( array, removableElements ){ + var disjoint = [], + element, + i, + l; + + for ( i = 0, l = array.length; i < l; i++ ) { + element = array[i]; + if ( removableElements.indexOf(element) === -1 ) { + disjoint.push(element); + } + } + return disjoint; + } + + filter.enabled = function ( p ){ + if ( !arguments.length ) return enabled; + enabled = p; + return filter; + }; + + + // Functions a filter must have + filter.filteredNodes = function (){ + return filteredNodes; + }; + + filter.filteredProperties = function (){ + return filteredProperties; + }; + + + return filter; +}; diff --git a/src/webvowl/js/options.js b/src/webvowl/js/options.js new file mode 100644 index 0000000000000000000000000000000000000000..bf1042057c88b0f42b26d4b583e09a693938fbba --- /dev/null +++ b/src/webvowl/js/options.js @@ -0,0 +1,731 @@ +module.exports = function (){ + var options = {}, + data, + graphContainerSelector, + classDistance = 200, + datatypeDistance = 120, + loopDistance = 150, + charge = -500, + gravity = 0.025, + linkStrength = 1, + height = 600, + width = 800, + selectionModules = [], + filterModules = [], + minMagnification = 0.01, + maxMagnification = 4, + compactNotation = false, + dynamicLabelWidth = true, + // some filters + literalFilter, + // menus + gravityMenu, + filterMenu, + loadingModule, + modeMenu, + pausedMenu, + pickAndPinModule, + resetMenu, + searchMenu, + ontologyMenu, + sidebar, + leftSidebar, + editSidebar, + navigationMenu, + exportMenu, + graphObject, + zoomSlider, + datatypeFilter, + focuserModule, + colorExternalsModule, + compactNotationModule, + objectPropertyFilter, + subclassFilter, + setOperatorFilter, + maxLabelWidth = 120, + metadataObject = {}, + generalOntologyMetaData = {}, + disjointPropertyFilter, + rectangularRep = false, + warningModule, + prefixModule, + drawPropertyDraggerOnHover = true, + showDraggerObject = false, + directInputModule, + scaleNodesByIndividuals = true, + useAccuracyHelper = true, + showRenderingStatistic = true, + showInputModality = false, + hideDebugOptions = true, + nodeDegreeFilter, + debugMenu, + + supportedDatatypes = ["rdfs:Literal", "xsd:boolean", "xsd:double", "xsd:integer", "xsd:string", "undefined"], + supportedClasses = ["owl:Thing", "owl:Class", "owl:DeprecatedClass"], + supportedProperties = ["owl:objectProperty", + "rdfs:subClassOf", + "owl:disjointWith", + "owl:allValuesFrom", + "owl:someValuesFrom" + ], + prefixList = { + rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', + rdfs: 'http://www.w3.org/2000/01/rdf-schema#', + owl: 'http://www.w3.org/2002/07/owl#', + xsd: 'http://www.w3.org/2001/XMLSchema#', + dc: 'http://purl.org/dc/elements/1.1/#', + xml: 'http://www.w3.org/XML/1998/namespace' + }; + + options.clearMetaObject = function (){ + generalOntologyMetaData = {}; + }; + options.clearGeneralMetaObject = function (){ + generalOntologyMetaData = {}; + }; + + options.debugMenu = function ( val ){ + if ( !arguments.length ) return debugMenu; + debugMenu = val; + }; + + options.getHideDebugFeatures = function (){ + return hideDebugOptions; + }; + options.executeHiddenDebugFeatuers = function (){ + hideDebugOptions = !hideDebugOptions; + d3.selectAll(".debugOption").classed("hidden", hideDebugOptions); + if ( hideDebugOptions === false ) { + graphObject.setForceTickFunctionWithFPS(); + } + else { + graphObject.setDefaultForceTickFunction(); + } + if ( debugMenu ) { + debugMenu.updateSettings(); + } + options.setHideDebugFeaturesForDefaultObject(hideDebugOptions); + }; + + + options.addOrUpdateGeneralObjectEntry = function ( property, value ){ + if ( generalOntologyMetaData.hasOwnProperty(property) ) { + //console.log("Updating Property:"+ property); + if ( property === "iri" ) { + if ( validURL(value) === false ) { + warningModule.showWarning("Invalid Ontology IRI", "Input IRI does not represent an URL", "Restoring previous IRI for ontology", 1, false); + return false; + } + } + generalOntologyMetaData[property] = value; + } else { + generalOntologyMetaData[property] = value; + } + return true; + }; + + options.getGeneralMetaObjectProperty = function ( property ){ + if ( generalOntologyMetaData.hasOwnProperty(property) ) { + return generalOntologyMetaData[property]; + } + }; + + options.getGeneralMetaObject = function (){ + return generalOntologyMetaData; + }; + + options.addOrUpdateMetaObjectEntry = function ( property, value ){ + + if ( metadataObject.hasOwnProperty(property) ) { + metadataObject[property] = value; + } else { + metadataObject[property] = value; + } + }; + + options.getMetaObjectProperty = function ( property ){ + if ( metadataObject.hasOwnProperty(property) ) { + return metadataObject[property]; + } + }; + options.getMetaObject = function (){ + return metadataObject; + }; + + + options.prefixList = function (){ + return prefixList; + }; + options.addPrefix = function ( prefix, url ){ + prefixList[prefix] = url; + }; + + function validURL( str ){ + var urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/; + return urlregex.test(str); + } + + options.updatePrefix = function ( oldPrefix, newPrefix, oldURL, newURL ){ + if ( oldPrefix === newPrefix && oldURL === newURL ) { + // console.log("Nothing to update"); + return true; + } + if ( oldPrefix === newPrefix && oldURL !== newURL && validURL(newURL) === true ) { + // console.log("Update URL"); + prefixList[oldPrefix] = newURL; + } else if ( oldPrefix === newPrefix && oldURL !== newURL && validURL(newURL) === false ) { + if ( validURL(newURL) === false ) { + warningModule.showWarning("Invalid Prefix IRI", "Input IRI does not represent an IRI", "You should enter a valid IRI in form of a URL", 1, false); + return false; + } + + return false; + } + if ( oldPrefix !== newPrefix && validURL(newURL) === true ) { + + // sanity check + if ( prefixList.hasOwnProperty(newPrefix) ) { + // console.log("Already have this prefix!"); + warningModule.showWarning("Prefix Already Exist", "Prefix: " + newPrefix + " is already defined", "You should use an other one", 1, false); + return false; + } + options.removePrefix(oldPrefix); + options.addPrefix(newPrefix, newURL); + editSidebar.updateEditDeleteButtonIds(oldPrefix, newPrefix); + return true; + } + + // console.log("Is new URL ("+newURL+") valid? >> "+validURL(newURL)); + if ( validURL(newURL) === false ) { + warningModule.showWarning("Invalid Prefix IRI", "Input IRI does not represent an URL", "You should enter a valid URL", 1, false); + + } + return false; + }; + + options.removePrefix = function ( prefix ){ + delete prefixList[prefix]; + }; + + + options.supportedDatatypes = function (){ + return supportedDatatypes; + }; + options.supportedClasses = function (){ + return supportedClasses; + }; + options.supportedProperties = function (){ + return supportedProperties; + }; + + options.datatypeFilter = function ( val ){ + if ( !arguments.length ) return datatypeFilter; + datatypeFilter = val; + }; + + options.showDraggerObject = function ( val ){ + if ( !arguments.length ) { + return showDraggerObject; + } + showDraggerObject = val; + }; + options.useAccuracyHelper = function ( val ){ + if ( !arguments.length ) { + return useAccuracyHelper; + } + useAccuracyHelper = val; + }; + options.showAccuracyHelper = function ( val ){ + if ( !arguments.length ) { + return options.showDraggerObject(); + } + options.showDraggerObject(val); + }; + options.showRenderingStatistic = function ( val ){ + if ( !arguments.length ) { + return showRenderingStatistic; + } + showRenderingStatistic = val; + }; + options.showInputModality = function ( val ){ + if ( !arguments.length ) { + return showInputModality; + } + showInputModality = val; + }; + + options.drawPropertyDraggerOnHover = function ( val ){ + if ( !arguments.length ) return drawPropertyDraggerOnHover; + drawPropertyDraggerOnHover = val; + }; + + options.warningModule = function ( val ){ + if ( !arguments.length ) return warningModule; + warningModule = val; + }; + options.directInputModule = function ( val ){ + if ( !arguments.length ) return directInputModule; + directInputModule = val; + }; + options.prefixModule = function ( val ){ + if ( !arguments.length ) return prefixModule; + prefixModule = val; + }; + + options.focuserModule = function ( val ){ + if ( !arguments.length ) return focuserModule; + focuserModule = val; + }; + options.colorExternalsModule = function ( val ){ + if ( !arguments.length ) return colorExternalsModule; + colorExternalsModule = val; + }; + options.compactNotationModule = function ( val ){ + if ( !arguments.length ) return compactNotationModule; + compactNotationModule = val; + }; + + options.maxLabelWidth = function ( val ){ + if ( !arguments.length ) return maxLabelWidth; + maxLabelWidth = val; + }; + options.objectPropertyFilter = function ( val ){ + if ( !arguments.length ) return objectPropertyFilter; + objectPropertyFilter = val; + }; + options.disjointPropertyFilter = function ( val ){ + if ( !arguments.length ) return disjointPropertyFilter; + disjointPropertyFilter = val; + }; + options.subclassFilter = function ( val ){ + if ( !arguments.length ) return subclassFilter; + subclassFilter = val; + }; + options.setOperatorFilter = function ( val ){ + if ( !arguments.length ) return setOperatorFilter; + setOperatorFilter = val; + }; + options.leftSidebar = function ( val ){ + if ( !arguments.length ) return leftSidebar; + leftSidebar = val; + }; + options.editSidebar = function ( val ){ + if ( !arguments.length ) return editSidebar; + editSidebar = val; + }; + + options.zoomSlider = function ( val ){ + if ( !arguments.length ) return zoomSlider; + zoomSlider = val; + }; + + options.graphObject = function ( val ){ + if ( !arguments.length ) return graphObject; + graphObject = val; + }; + + + var defaultOptionsConfig = {}; + defaultOptionsConfig.sidebar = "1"; + defaultOptionsConfig.doc = -1; + defaultOptionsConfig.cd = 200; + defaultOptionsConfig.dd = 120; + defaultOptionsConfig.editorMode = "false"; + defaultOptionsConfig.filter_datatypes = "false"; + defaultOptionsConfig.filter_objectProperties = "false"; + defaultOptionsConfig.filter_sco = "false"; + defaultOptionsConfig.filter_disjoint = "true"; + defaultOptionsConfig.filter_setOperator = "false"; + defaultOptionsConfig.mode_dynamic = "true"; + defaultOptionsConfig.mode_scaling = "true"; + defaultOptionsConfig.mode_compact = "false"; + defaultOptionsConfig.mode_colorExt = "true"; + defaultOptionsConfig.mode_multiColor = "false"; + defaultOptionsConfig.debugFeatures = "false"; + defaultOptionsConfig.rect = 0; + + + options.initialConfig = function (){ + var initCfg = {}; + initCfg.sidebar = "1"; + initCfg.doc = -1; + initCfg.cd = 200; + initCfg.dd = 120; + initCfg.editorMode = "false"; + initCfg.filter_datatypes = "false"; + initCfg.filter_objectProperties = "false"; + initCfg.filter_sco = "false"; + initCfg.filter_disjoint = "true"; + initCfg.filter_setOperator = "false"; + initCfg.mode_dynamic = "true"; + initCfg.mode_scaling = "true"; + initCfg.mode_compact = "false"; + initCfg.mode_colorExt = "true"; + initCfg.mode_multiColor = "false"; + initCfg.mode_pnp = "false"; + initCfg.debugFeatures = "false"; + initCfg.rect = 0; + return initCfg; + }; + + options.setEditorModeForDefaultObject = function ( val ){ + defaultOptionsConfig.editorMode = String(val); + }; + options.setHideDebugFeaturesForDefaultObject = function ( val ){ + defaultOptionsConfig.debugFeatures = String(!val); + }; + + function updateConfigObject(){ + defaultOptionsConfig.sidebar = options.sidebar().getSidebarVisibility(); + defaultOptionsConfig.cd = options.classDistance(); + defaultOptionsConfig.dd = options.datatypeDistance(); + defaultOptionsConfig.filter_datatypes = String(options.filterMenu().getCheckBoxValue("datatypeFilterCheckbox")); + defaultOptionsConfig.filter_sco = String(options.filterMenu().getCheckBoxValue("subclassFilterCheckbox")); + defaultOptionsConfig.filter_disjoint = String(options.filterMenu().getCheckBoxValue("disjointFilterCheckbox")); + defaultOptionsConfig.filter_setOperator = String(options.filterMenu().getCheckBoxValue("setoperatorFilterCheckbox")); + defaultOptionsConfig.filter_objectProperties = String(options.filterMenu().getCheckBoxValue("objectPropertyFilterCheckbox")); + defaultOptionsConfig.mode_dynamic = String(options.dynamicLabelWidth()); + defaultOptionsConfig.mode_scaling = String(options.modeMenu().getCheckBoxValue("nodescalingModuleCheckbox")); + defaultOptionsConfig.mode_compact = String(options.modeMenu().getCheckBoxValue("compactnotationModuleCheckbox")); + defaultOptionsConfig.mode_colorExt = String(options.modeMenu().getCheckBoxValue("colorexternalsModuleCheckbox")); + defaultOptionsConfig.mode_multiColor = String(options.modeMenu().colorModeState()); + defaultOptionsConfig.mode_pnp = String(options.modeMenu().getCheckBoxValue("pickandpinModuleCheckbox")); + defaultOptionsConfig.rect = 0; + } + + options.defaultConfig = function (){ + updateConfigObject(); + return defaultOptionsConfig; + }; + + options.exportMenu = function ( val ){ + if ( !arguments.length ) return exportMenu; + exportMenu = val; + }; + + options.rectangularRepresentation = function ( val ){ + if ( !arguments.length ) { + return rectangularRep; + } else { + var intVal = parseInt(val); + if ( intVal === 0 ) { + rectangularRep = false; + } else { + rectangularRep = true; + } + } + }; + + options.dynamicLabelWidth = function ( val ){ + if ( !arguments.length ) + return dynamicLabelWidth; + else { + dynamicLabelWidth = val; + } + }; + options.sidebar = function ( s ){ + if ( !arguments.length ) return sidebar; + sidebar = s; + return options; + + }; + + options.navigationMenu = function ( m ){ + if ( !arguments.length ) return navigationMenu; + navigationMenu = m; + return options; + + }; + + options.ontologyMenu = function ( m ){ + if ( !arguments.length ) return ontologyMenu; + ontologyMenu = m; + return options; + }; + + options.searchMenu = function ( m ){ + if ( !arguments.length ) return searchMenu; + searchMenu = m; + return options; + }; + + options.resetMenu = function ( m ){ + if ( !arguments.length ) return resetMenu; + resetMenu = m; + return options; + }; + + options.pausedMenu = function ( m ){ + if ( !arguments.length ) return pausedMenu; + pausedMenu = m; + return options; + }; + + options.pickAndPinModule = function ( m ){ + if ( !arguments.length ) return pickAndPinModule; + pickAndPinModule = m; + return options; + }; + + options.gravityMenu = function ( m ){ + if ( !arguments.length ) return gravityMenu; + gravityMenu = m; + return options; + }; + + options.filterMenu = function ( m ){ + if ( !arguments.length ) return filterMenu; + filterMenu = m; + return options; + }; + + options.modeMenu = function ( m ){ + if ( !arguments.length ) return modeMenu; + modeMenu = m; + return options; + }; + + options.charge = function ( p ){ + if ( !arguments.length ) return charge; + charge = +p; + return options; + }; + + options.classDistance = function ( p ){ + if ( !arguments.length ) return classDistance; + classDistance = +p; + return options; + }; + + options.compactNotation = function ( p ){ + + if ( !arguments.length ) return compactNotation; + compactNotation = p; + return options; + }; + + options.data = function ( p ){ + if ( !arguments.length ) return data; + data = p; + return options; + }; + + options.datatypeDistance = function ( p ){ + if ( !arguments.length ) return datatypeDistance; + datatypeDistance = +p; + return options; + }; + + options.filterModules = function ( p ){ + if ( !arguments.length ) return filterModules; + filterModules = p; + return options; + }; + + options.graphContainerSelector = function ( p ){ + if ( !arguments.length ) return graphContainerSelector; + graphContainerSelector = p; + return options; + }; + + options.gravity = function ( p ){ + if ( !arguments.length ) return gravity; + gravity = +p; + return options; + }; + + options.height = function ( p ){ + if ( !arguments.length ) return height; + height = +p; + return options; + }; + + options.linkStrength = function ( p ){ + if ( !arguments.length ) return linkStrength; + linkStrength = +p; + return options; + }; + + options.loopDistance = function ( p ){ + if ( !arguments.length ) return loopDistance; + loopDistance = p; + return options; + }; + + options.minMagnification = function ( p ){ + if ( !arguments.length ) return minMagnification; + minMagnification = +p; + return options; + }; + + options.maxMagnification = function ( p ){ + if ( !arguments.length ) return maxMagnification; + maxMagnification = +p; + return options; + }; + + options.scaleNodesByIndividuals = function ( p ){ + if ( !arguments.length ) return scaleNodesByIndividuals; + scaleNodesByIndividuals = p; + return options; + }; + + options.selectionModules = function ( p ){ + if ( !arguments.length ) return selectionModules; + selectionModules = p; + return options; + }; + + options.width = function ( p ){ + if ( !arguments.length ) return width; + width = +p; + return options; + }; + + options.literalFilter = function ( p ){ + if ( !arguments.length ) return literalFilter; + literalFilter = p; + return options; + }; + options.nodeDegreeFilter = function ( p ){ + if ( !arguments.length ) return nodeDegreeFilter; + nodeDegreeFilter = p; + return options; + }; + + options.loadingModule = function ( p ){ + if ( !arguments.length ) return loadingModule; + loadingModule = p; + return options; + }; + + // define url loadable options; + // update all set values in the default object + options.setOptionsFromURL = function ( opts, changeEditFlag ){ + if ( opts.sidebar !== undefined ) sidebar.showSidebar(parseInt(opts.sidebar), true); + if ( opts.doc ) { + var asInt = parseInt(opts.doc); + filterMenu.setDegreeSliderValue(asInt); + graphObject.setGlobalDOF(asInt); + // reset the value to be -1; + defaultOptionsConfig.doc = -1; + } + var settingFlag = false; + if ( opts.editorMode ) { + if ( opts.editorMode === "true" ) settingFlag = true; + d3.select("#editorModeModuleCheckbox").node().checked = settingFlag; + + if ( changeEditFlag && changeEditFlag === true ) { + graphObject.editorMode(settingFlag); + } + + // update config object + defaultOptionsConfig.editorMode = opts.editorMode; + + } + if ( opts.cd ) { // class distance + options.classDistance(opts.cd); // class distance + defaultOptionsConfig.cd = opts.cd; + } + if ( opts.dd ) { // data distance + options.datatypeDistance(opts.dd); + defaultOptionsConfig.cd = opts.cd; + } + if ( opts.cd || opts.dd ) options.gravityMenu().reset(); // reset the values so the slider is updated; + + + settingFlag = false; + if ( opts.filter_datatypes ) { + if ( opts.filter_datatypes === "true" ) settingFlag = true; + filterMenu.setCheckBoxValue("datatypeFilterCheckbox", settingFlag); + defaultOptionsConfig.filter_datatypes = opts.filter_datatypes; + } + if ( opts.debugFeatures ) { + if ( opts.debugFeatures === "true" ) settingFlag = true; + hideDebugOptions = settingFlag; + if ( options.getHideDebugFeatures() === false ) { + options.executeHiddenDebugFeatuers(); + } + defaultOptionsConfig.debugFeatures = opts.debugFeatures; + } + + settingFlag = false; + if ( opts.filter_objectProperties ) { + if ( opts.filter_objectProperties === "true" ) settingFlag = true; + filterMenu.setCheckBoxValue("objectPropertyFilterCheckbox", settingFlag); + defaultOptionsConfig.filter_objectProperties = opts.filter_objectProperties; + } + settingFlag = false; + if ( opts.filter_sco ) { + if ( opts.filter_sco === "true" ) settingFlag = true; + filterMenu.setCheckBoxValue("subclassFilterCheckbox", settingFlag); + defaultOptionsConfig.filter_sco = opts.filter_sco; + } + settingFlag = false; + if ( opts.filter_disjoint ) { + if ( opts.filter_disjoint === "true" ) settingFlag = true; + filterMenu.setCheckBoxValue("disjointFilterCheckbox", settingFlag); + defaultOptionsConfig.filter_disjoint = opts.filter_disjoint; + } + settingFlag = false; + if ( opts.filter_setOperator ) { + if ( opts.filter_setOperator === "true" ) settingFlag = true; + filterMenu.setCheckBoxValue("setoperatorFilterCheckbox", settingFlag); + defaultOptionsConfig.filter_setOperator = opts.filter_setOperator; + } + filterMenu.updateSettings(); + + // modesMenu + settingFlag = false; + if ( opts.mode_dynamic ) { + if ( opts.mode_dynamic === "true" ) settingFlag = true; + modeMenu.setDynamicLabelWidth(settingFlag); + dynamicLabelWidth = settingFlag; + defaultOptionsConfig.mode_dynamic = opts.mode_dynamic; + } + // settingFlag=false; + // THIS SHOULD NOT BE SET USING THE OPTIONS ON THE URL + // if (opts.mode_picnpin) { + // graph.options().filterMenu().setCheckBoxValue("pickandpin ModuleCheckbox", settingFlag); + // } + + settingFlag = false; + if ( opts.mode_pnp ) { + if ( opts.mode_pnp === "true" ) settingFlag = true; + modeMenu.setCheckBoxValue("pickandpinModuleCheckbox", settingFlag); + defaultOptionsConfig.mode_pnp = opts.mode_pnp; + } + + settingFlag = false; + if ( opts.mode_scaling ) { + if ( opts.mode_scaling === "true" ) settingFlag = true; + modeMenu.setCheckBoxValue("nodescalingModuleCheckbox", settingFlag); + defaultOptionsConfig.mode_scaling = opts.mode_scaling; + } + + settingFlag = false; + if ( opts.mode_compact ) { + if ( opts.mode_compact === "true" ) settingFlag = true; + modeMenu.setCheckBoxValue("compactnotationModuleCheckbox", settingFlag); + defaultOptionsConfig.mode_compact = opts.mode_compact; + } + + settingFlag = false; + if ( opts.mode_colorExt ) { + if ( opts.mode_colorExt === "true" ) settingFlag = true; + modeMenu.setCheckBoxValue("colorexternalsModuleCheckbox", settingFlag); + defaultOptionsConfig.mode_colorExt = opts.mode_colorExt; + } + + settingFlag = false; + if ( opts.mode_multiColor ) { + if ( opts.mode_multiColor === "true" ) settingFlag = true; + modeMenu.setColorSwitchStateUsingURL(settingFlag); + defaultOptionsConfig.mode_multiColor = opts.mode_multiColor; + } + modeMenu.updateSettingsUsingURL(); + options.rectangularRepresentation(opts.rect); + }; + + return options; +}; diff --git a/src/webvowl/js/parser.js b/src/webvowl/js/parser.js new file mode 100644 index 0000000000000000000000000000000000000000..7961c81be10c9fd8ff2e1655be9c03d077b6fa87 --- /dev/null +++ b/src/webvowl/js/parser.js @@ -0,0 +1,740 @@ +var OwlDisjointWith = require("./elements/properties/implementations/OwlDisjointWith"); +var attributeParser = require("./parsing/attributeParser")(); +var equivalentPropertyMerger = require("./parsing/equivalentPropertyMerger")(); +var nodePrototypeMap = require("./elements/nodes/nodeMap")(); +var propertyPrototypeMap = require("./elements/properties/propertyMap")(); + +/** + * Encapsulates the parsing and preparation logic of the input data. + * @param graph the graph object that will be passed to the elements + * @returns {{}} + */ +module.exports = function ( graph ){ + var parser = {}, + nodes, + properties, + classMap, + settingsData, + settingsImported = false, + settingsImportGraphZoomAndTranslation = false, + dictionary = [], + propertyMap; + + parser.getDictionary = function (){ + return dictionary; + }; + + parser.setDictionary = function ( d ){ + dictionary = d; + }; + + parser.settingsImported = function (){ + return settingsImported; + }; + parser.settingsImportGraphZoomAndTranslation = function (){ + return settingsImportGraphZoomAndTranslation; + }; + + parser.parseSettings = function (){ + settingsImported = true; + settingsImportGraphZoomAndTranslation = false; + + if ( !settingsData ) { + settingsImported = false; + return; + } + /** global settings **********************************************************/ + if ( settingsData.global ) { + if ( settingsData.global.zoom ) { + var zoomFactor = settingsData.global.zoom; + graph.setZoom(zoomFactor); + settingsImportGraphZoomAndTranslation = true; + } + + if ( settingsData.global.translation ) { + var translation = settingsData.global.translation; + graph.setTranslation(translation); + settingsImportGraphZoomAndTranslation = true; + } + + if ( settingsData.global.paused ) { + var paused = settingsData.global.paused; + graph.options().pausedMenu().setPauseValue(paused); + } + } + /** Gravity Settings **********************************************************/ + if ( settingsData.gravity ) { + if ( settingsData.gravity.classDistance ) { + var classDistance = settingsData.gravity.classDistance; + graph.options().classDistance(classDistance); + } + if ( settingsData.gravity.datatypeDistance ) { + var datatypeDistance = settingsData.gravity.datatypeDistance; + graph.options().datatypeDistance(datatypeDistance); + } + graph.options().gravityMenu().reset(); // reads the options values and sets the gui values + } + + + // shared variable declaration + + var i; + var id; + var checked; + /** Filter Settings **********************************************************/ + if ( settingsData.filter ) { + // checkbox settings + if ( settingsData.filter.checkBox ) { + var filter_cb = settingsData.filter.checkBox; + for ( i = 0; i < filter_cb.length; i++ ) { + id = filter_cb[i].id; + checked = filter_cb[i].checked; + graph.options().filterMenu().setCheckBoxValue(id, checked); + } + } + // node degree filter settings + if ( settingsData.filter.degreeSliderValue ) { + var degreeSliderValue = settingsData.filter.degreeSliderValue; + graph.options().filterMenu().setDegreeSliderValue(degreeSliderValue); + } + graph.options().filterMenu().updateSettings(); + } + + /** Modes Setting **********************************************************/ + if ( settingsData.modes ) { + // checkbox settings + if ( settingsData.modes.checkBox ) { + var modes_cb = settingsData.modes.checkBox; + for ( i = 0; i < modes_cb.length; i++ ) { + id = modes_cb[i].id; + checked = modes_cb[i].checked; + graph.options().modeMenu().setCheckBoxValue(id, checked); + } + } + // color switch settings + var state = settingsData.modes.colorSwitchState; + // state could be undefined + if ( state === true || state === false ) { + graph.options().modeMenu().setColorSwitchState(state); + } + graph.options().modeMenu().updateSettings(); + } + graph.updateStyle(); // updates graph representation(setting charges and distances) + }; + + + /** + * Parses the ontology data and preprocesses it (e.g. connecting inverse properties and so on). + * @param ontologyData the loaded ontology json file + */ + parser.parse = function ( ontologyData ){ + if ( !ontologyData ) { + nodes = []; + properties = []; + dictionary = []; + return; + } + dictionary = []; + if ( ontologyData.settings ) settingsData = ontologyData.settings; + else settingsData = undefined; + + var classes = combineClasses(ontologyData.class, ontologyData.classAttribute), + datatypes = combineClasses(ontologyData.datatype, ontologyData.datatypeAttribute), + combinedClassesAndDatatypes = classes.concat(datatypes), + unparsedProperties = ontologyData.property || [], + combinedProperties; + + // Inject properties for unions, intersections, ... + addSetOperatorProperties(combinedClassesAndDatatypes, unparsedProperties); + combinedProperties = combineProperties(unparsedProperties, ontologyData.propertyAttribute); + classMap = mapElements(combinedClassesAndDatatypes); + propertyMap = mapElements(combinedProperties); + mergeRangesOfEquivalentProperties(combinedProperties, combinedClassesAndDatatypes); + + // Process the graph data + convertTypesToIris(combinedClassesAndDatatypes, ontologyData.namespace); + convertTypesToIris(combinedProperties, ontologyData.namespace); + nodes = createNodeStructure(combinedClassesAndDatatypes, classMap); + properties = createPropertyStructure(combinedProperties, classMap, propertyMap); + }; + + /** + * @return {Array} the preprocessed nodes + */ + parser.nodes = function (){ + return nodes; + }; + + /** + * @returns {Array} the preprocessed properties + */ + parser.properties = function (){ + return properties; + }; + + /** + * Combines the passed objects with its attributes and prototypes. This also applies + * attributes defined in the base of the prototype. + */ + function combineClasses( baseObjects, attributes ){ + var combinations = []; + var prototypeMap = createLowerCasePrototypeMap(nodePrototypeMap); + + if ( baseObjects ) { + baseObjects.forEach(function ( element ){ + var matchingAttribute; + + if ( attributes ) { + // Look for an attribute with the same id and merge them + for ( var i = 0; i < attributes.length; i++ ) { + var attribute = attributes[i]; + if ( element.id === attribute.id ) { + matchingAttribute = attribute; + break; + } + } + addAdditionalAttributes(element, matchingAttribute); + } + + // Then look for a prototype to add its properties + var Prototype = prototypeMap.get(element.type.toLowerCase()); + + if ( Prototype ) { + addAdditionalAttributes(element, Prototype); // TODO might be unnecessary + + var node = new Prototype(graph); + node.annotations(element.annotations) + .baseIri(element.baseIri) + .comment(element.comment) + .complement(element.complement) + .disjointUnion(element.disjointUnion) + .description(element.description) + .equivalents(element.equivalent) + .id(element.id) + .intersection(element.intersection) + .label(element.label) + // .type(element.type) Ignore, because we predefined it + .union(element.union) + .iri(element.iri); + if ( element.pos ) { + node.x = element.pos[0]; + node.y = element.pos[1]; + node.px = node.x; + node.py = node.y; + } + //class element pin + var elementPinned = element.pinned; + if ( elementPinned === true ) { + node.pinned(true); + graph.options().pickAndPinModule().addPinnedElement(node); + } + // Create node objects for all individuals + if ( element.individuals ) { + element.individuals.forEach(function ( individual ){ + var individualNode = new Prototype(graph); + individualNode.label(individual.labels) + .iri(individual.iri); + + node.individuals().push(individualNode); + }); + } + + if ( element.attributes ) { + var deduplicatedAttributes = d3.set(element.attributes.concat(node.attributes())); + node.attributes(deduplicatedAttributes.values()); + } + combinations.push(node); + } else { + console.error("Unknown element type: " + element.type); + } + }); + } + + return combinations; + } + + function combineProperties( baseObjects, attributes ){ + var combinations = []; + var prototypeMap = createLowerCasePrototypeMap(propertyPrototypeMap); + + if ( baseObjects ) { + baseObjects.forEach(function ( element ){ + var matchingAttribute; + + if ( attributes ) { + // Look for an attribute with the same id and merge them + for ( var i = 0; i < attributes.length; i++ ) { + var attribute = attributes[i]; + if ( element.id === attribute.id ) { + matchingAttribute = attribute; + break; + } + } + addAdditionalAttributes(element, matchingAttribute); + } + + // Then look for a prototype to add its properties + var Prototype = prototypeMap.get(element.type.toLowerCase()); + + if ( Prototype ) { + // Create the matching object and set the properties + var property = new Prototype(graph); + property.annotations(element.annotations) + .baseIri(element.baseIri) + .cardinality(element.cardinality) + .comment(element.comment) + .domain(element.domain) + .description(element.description) + .equivalents(element.equivalent) + .id(element.id) + .inverse(element.inverse) + .label(element.label) + .minCardinality(element.minCardinality) + .maxCardinality(element.maxCardinality) + .range(element.range) + .subproperties(element.subproperty) + .superproperties(element.superproperty) + // .type(element.type) Ignore, because we predefined it + .iri(element.iri); + + // adding property position + if ( element.pos ) { + property.x = element.pos[0]; + property.y = element.pos[1]; + property.px = element.pos[0]; + property.py = element.pos[1]; + } + var elementPinned = element.pinned; + if ( elementPinned === true ) { + property.pinned(true); + graph.options().pickAndPinModule().addPinnedElement(property); + } + + + if ( element.attributes ) { + var deduplicatedAttributes = d3.set(element.attributes.concat(property.attributes())); + property.attributes(deduplicatedAttributes.values()); + } + combinations.push(property); + } else { + console.error("Unknown element type: " + element.type); + } + + }); + } + + return combinations; + } + + function createLowerCasePrototypeMap( prototypeMap ){ + return d3.map(prototypeMap.values(), function ( Prototype ){ + return new Prototype().type().toLowerCase(); + }); + } + + function mergeRangesOfEquivalentProperties( properties, nodes ){ + // pass clones of arrays into the merger to keep the current functionality of this module + var newNodes = equivalentPropertyMerger.merge(properties.slice(), nodes.slice(), propertyMap, classMap, graph); + + // replace all the existing nodes and map the nodes again + nodes.length = 0; + Array.prototype.push.apply(nodes, newNodes); + classMap = mapElements(nodes); + } + + /** + * Checks all attributes which have to be rewritten. + * For example: + * equivalent is filled with only ID's of the corresponding nodes. It would be better to used the + * object instead of the ID so we swap the ID's with the correct object reference and can delete it from drawing + * because it is not necessary. + */ + function createNodeStructure( rawNodes, classMap ){ + var nodes = []; + + // Set the default values + var maxIndividualCount = 0; + rawNodes.forEach(function ( node ){ + maxIndividualCount = Math.max(maxIndividualCount, node.individuals().length); + node.visible(true); + }); + + rawNodes.forEach(function ( node ){ + // Merge and connect the equivalent nodes + processEquivalentIds(node, classMap); + + attributeParser.parseClassAttributes(node); + + node.maxIndividualCount(maxIndividualCount); + }); + + // Collect all nodes that should be displayed + rawNodes.forEach(function ( node ){ + if ( node.visible() ) { + nodes.push(node); + } + }); + + return nodes; + } + + /** + * Sets the disjoint attribute of the nodes if a disjoint label is found. + * @param property + */ + function processDisjoints( property ){ + if ( property instanceof OwlDisjointWith === false ) { + return; + } + + var domain = property.domain(), + range = property.range(); + + // Check the domain. + if ( !domain.disjointWith() ) { + domain.disjointWith([]); + } + + // Check the range. + if ( !range.disjointWith() ) { + range.disjointWith([]); + } + + domain.disjointWith().push(property.range()); + range.disjointWith().push(property.domain()); + } + + /** + * Connect all properties and also their sub- and superproperties. + * We iterate over the rawProperties array because it is way faster than iterating + * over an object and its attributes. + * + * @param rawProperties the properties + * @param classMap a map of all classes + * @param propertyMap the properties in a map + */ + function createPropertyStructure( rawProperties, classMap, propertyMap ){ + var properties = []; + // Set default values + rawProperties.forEach(function ( property ){ + property.visible(true); + }); + + // Connect properties + rawProperties.forEach(function ( property ){ + var domain, + range, + domainObject, + rangeObject, + inverse; + + /* Skip properties that have no information about their domain and range, like + inverse properties with optional inverse and optional domain and range attributes */ + if ( (property.domain() && property.range()) || property.inverse() ) { + + var inversePropertyId = findId(property.inverse()); + // Look if an inverse property exists + if ( inversePropertyId ) { + inverse = propertyMap[inversePropertyId]; + if ( !inverse ) { + console.warn("No inverse property was found for id: " + inversePropertyId); + property.inverse(undefined); + } + } + + // Either domain and range are set on this property or at the inverse + if ( typeof property.domain() !== "undefined" && typeof property.range() !== "undefined" ) { + domain = findId(property.domain()); + range = findId(property.range()); + + domainObject = classMap[domain]; + rangeObject = classMap[range]; + } else if ( inverse ) { + // Domain and range need to be switched + domain = findId(inverse.range()); + range = findId(inverse.domain()); + + domainObject = classMap[domain]; + rangeObject = classMap[range]; + } else { + console.warn("Domain and range not found for property: " + property.id()); + } + + // Set the references on this property + property.domain(domainObject); + property.range(rangeObject); + + // Also set the attributes of the inverse property + if ( inverse ) { + property.inverse(inverse); + inverse.inverse(property); + + // Switch domain and range + inverse.domain(rangeObject); + inverse.range(domainObject); + } + } + // Reference sub- and superproperties + referenceSubOrSuperProperties(property.subproperties()); + referenceSubOrSuperProperties(property.superproperties()); + }); + + // Merge equivalent properties and process disjoints. + rawProperties.forEach(function ( property ){ + processEquivalentIds(property, propertyMap); + processDisjoints(property); + + attributeParser.parsePropertyAttributes(property); + }); + // Add additional information to the properties + rawProperties.forEach(function ( property ){ + // Properties of merged classes should point to/from the visible equivalent class + var propertyWasRerouted = false; + + if ( property.domain() === undefined ) { + console.warn("No Domain was found for id:" + property.id()); + return; + } + + if ( wasNodeMerged(property.domain()) ) { + property.domain(property.domain().equivalentBase()); + propertyWasRerouted = true; + } + if ( property.range() === undefined ) { + console.warn("No range was found for id:" + property.id()); + return; + } + if ( wasNodeMerged(property.range()) ) { + property.range(property.range().equivalentBase()); + propertyWasRerouted = true; + } + // But there should not be two equal properties between the same domain and range + var equalProperty = getOtherEqualProperty(rawProperties, property); + + if ( propertyWasRerouted && equalProperty ) { + property.visible(false); + + equalProperty.redundantProperties().push(property); + } + + // Hide property if source or target node is hidden + if ( !property.domain().visible() || !property.range().visible() ) { + property.visible(false); + } + + // Collect all properties that should be displayed + if ( property.visible() ) { + properties.push(property); + } + }); + return properties; + } + + function referenceSubOrSuperProperties( subOrSuperPropertiesArray ){ + var i, l; + + if ( !subOrSuperPropertiesArray ) { + return; + } + + for ( i = 0, l = subOrSuperPropertiesArray.length; i < l; ++i ) { + var subOrSuperPropertyId = findId(subOrSuperPropertiesArray[i]); + var subOrSuperProperty = propertyMap[subOrSuperPropertyId]; + + if ( subOrSuperProperty ) { + // Replace id with object + subOrSuperPropertiesArray[i] = subOrSuperProperty; + } else { + console.warn("No sub-/superproperty was found for id: " + subOrSuperPropertyId); + } + } + } + + function wasNodeMerged( node ){ + return !node.visible() && node.equivalentBase(); + } + + function getOtherEqualProperty( properties, referenceProperty ){ + var i, l, property; + + for ( i = 0, l = properties.length; i < l; i++ ) { + property = properties[i]; + + if ( referenceProperty === property ) { + continue; + } + if ( referenceProperty.domain() !== property.domain() || + referenceProperty.range() !== property.range() ) { + continue; + } + + // Check for an equal IRI, if non existent compare label and type + if ( referenceProperty.iri() && property.iri() ) { + if ( referenceProperty.iri() === property.iri() ) { + return property; + } + } else if ( referenceProperty.type() === property.type() && + referenceProperty.defaultLabel() === property.defaultLabel() ) { + return property; + } + } + + return undefined; + } + + /** + * Generates and adds properties for links to set operators. + * @param classes unprocessed classes + * @param properties unprocessed properties + */ + function addSetOperatorProperties( classes, properties ){ + function addProperties( domainId, rangeIds, operatorType ){ + if ( !rangeIds ) { + return; + } + + rangeIds.forEach(function ( rangeId, index ){ + var property = { + id: "GENERATED-" + operatorType + "-" + domainId + "-" + rangeId + "-" + index, + type: "setOperatorProperty", + domain: domainId, + range: rangeId + }; + + properties.push(property); + }); + } + + classes.forEach(function ( clss ){ + addProperties(clss.id(), clss.complement(), "COMPLEMENT"); + addProperties(clss.id(), clss.intersection(), "INTERSECTION"); + addProperties(clss.id(), clss.union(), "UNION"); + addProperties(clss.id(), clss.disjointUnion(), "DISJOINTUNION"); + }); + } + + /** + * Replaces the ids of equivalent nodes/properties with the matching objects, cross references them + * and tags them as processed. + * @param element a node or a property + * @param elementMap a map where nodes/properties can be looked up + */ + function processEquivalentIds( element, elementMap ){ + var eqIds = element.equivalents(); + + if ( !eqIds || element.equivalentBase() ) { + return; + } + + // Replace ids with the corresponding objects + for ( var i = 0, l = eqIds.length; i < l; ++i ) { + var eqId = findId(eqIds[i]); + var eqObject = elementMap[eqId]; + + if ( eqObject ) { + // Cross reference both objects + eqObject.equivalents(eqObject.equivalents()); + eqObject.equivalents().push(element); + eqObject.equivalentBase(element); + eqIds[i] = eqObject; + + // Hide other equivalent nodes + eqObject.visible(false); + } else { + console.warn("No class/property was found for equivalent id: " + eqId); + } + } + } + + /** + * Tries to convert the type to an iri and sets it. + * @param elements classes or properties + * @param namespaces an array of namespaces + */ + function convertTypesToIris( elements, namespaces ){ + elements.forEach(function ( element ){ + if ( typeof element.iri() === "string" ) { + element.iri(replaceNamespace(element.iri(), namespaces)); + } + }); + } + + /** + * Creates a map by mapping the array with the passed function. + * @param array the array + * @returns {{}} + */ + function mapElements( array ){ + var map = {}; + for ( var i = 0, length = array.length; i < length; i++ ) { + var element = array[i]; + map[element.id()] = element; + } + return map; + } + + /** + * Adds the attributes of the additional object to the base object, but doesn't + * overwrite existing ones. + * + * @param base the base object + * @param addition the object with additional data + * @returns the combination is also returned + */ + function addAdditionalAttributes( base, addition ){ + // Check for an undefined value + addition = addition || {}; + + for ( var addAttribute in addition ) { + // Add the attribute if it doesn't exist + if ( !(addAttribute in base) && addition.hasOwnProperty(addAttribute) ) { + base[addAttribute] = addition[addAttribute]; + } + } + return base; + } + + /** + * Replaces the namespace (and the separator) if one exists and returns the new value. + * @param address the address with a namespace in it + * @param namespaces an array of namespaces + * @returns {string} the processed address with the (possibly) replaced namespace + */ + function replaceNamespace( address, namespaces ){ + var separatorIndex = address.indexOf(":"); + if ( separatorIndex === -1 ) { + return address; + } + var namespaceName = address.substring(0, separatorIndex); + + for ( var i = 0, length = namespaces.length; i < length; ++i ) { + var namespace = namespaces[i]; + if ( namespaceName === namespace.name ) { + return namespace.iri + address.substring(separatorIndex + 1); + } + } + + return address; + } + + /** + * Looks whether the passed object is already the id or if it was replaced + * with the object that belongs to the id. + * @param object an id, a class or a property + * @returns {string} the id of the passed object or undefined + */ + function findId( object ){ + if ( !object ) { + return undefined; + } else if ( typeof object === "string" ) { + return object; + } else if ( "id" in object ) { + return object.id(); + } else { + console.warn("No Id was found for this object: " + object); + return undefined; + } + } + + return parser; +}; diff --git a/src/webvowl/js/parsing/attributeParser.js b/src/webvowl/js/parsing/attributeParser.js new file mode 100644 index 0000000000000000000000000000000000000000..b2a9e2ddb8888ac281c455411617d5e084d88ab5 --- /dev/null +++ b/src/webvowl/js/parsing/attributeParser.js @@ -0,0 +1,107 @@ +/** + * Parses the attributes an element has and sets the corresponding attributes. + * @returns {Function} + */ +module.exports = (function (){ + var attributeParser = {}, + // Style + ANONYMOUS = "anonymous", + DATATYPE = "datatype", + DEPRECATED = "deprecated", + EXTERNAL = "external", + OBJECT = "object", + RDF = "rdf", + // Representations + ASYMMETRIC = "asymmetric", + FUNCTIONAL = "functional", + INVERSE_FUNCTIONAL = "inverse functional", + IRREFLEXIVE = "irreflexive", + KEY = "key", + REFLEXIVE = "reflexive", + SYMMETRIC = "symmetric", + TRANSITIVE = "transitive", + // Attribute groups + VISUAL_ATTRIBUTE_GROUPS = [ + [DEPRECATED, DATATYPE, OBJECT, RDF], + [ANONYMOUS] + ], + CLASS_INDICATIONS = [DEPRECATED, EXTERNAL], + PROPERTY_INDICATIONS = [ASYMMETRIC, FUNCTIONAL, INVERSE_FUNCTIONAL, IRREFLEXIVE, KEY, REFLEXIVE, SYMMETRIC, + TRANSITIVE]; + + /** + * Parses and sets the attributes of a class. + * @param clazz + */ + attributeParser.parseClassAttributes = function ( clazz ){ + if ( !(clazz.attributes() instanceof Array) ) { + return; + } + + parseVisualAttributes(clazz); + parseClassIndications(clazz); + }; + + function parseVisualAttributes( element ){ + VISUAL_ATTRIBUTE_GROUPS.forEach(function ( attributeGroup ){ + setVisualAttributeOfGroup(element, attributeGroup); + }); + } + + function setVisualAttributeOfGroup( element, group ){ + var i, l, attribute; + + for ( i = 0, l = group.length; i < l; i++ ) { + attribute = group[i]; + if ( element.attributes().indexOf(attribute) >= 0 ) { + element.visualAttributes().push(attribute); + + // Just a single attribute is possible + break; + } + } + } + + function parseClassIndications( clazz ){ + var i, l, indication; + + for ( i = 0, l = CLASS_INDICATIONS.length; i < l; i++ ) { + indication = CLASS_INDICATIONS[i]; + + if ( clazz.attributes().indexOf(indication) >= 0 ) { + clazz.indications().push(indication); + } + } + } + + /** + * Parses and sets the attributes of a property. + * @param property + */ + attributeParser.parsePropertyAttributes = function ( property ){ + if ( !(property.attributes() instanceof Array) ) { + return; + } + + parseVisualAttributes(property); + parsePropertyIndications(property); + }; + + function parsePropertyIndications( property ){ + var i, l, indication; + + for ( i = 0, l = PROPERTY_INDICATIONS.length; i < l; i++ ) { + indication = PROPERTY_INDICATIONS[i]; + + if ( property.attributes().indexOf(indication) >= 0 ) { + property.indications().push(indication); + } + } + } + + + return function (){ + // Return a function to keep module interfaces consistent + return attributeParser; + }; +})(); diff --git a/src/webvowl/js/parsing/equivalentPropertyMerger.js b/src/webvowl/js/parsing/equivalentPropertyMerger.js new file mode 100644 index 0000000000000000000000000000000000000000..0f4838fbea953ec7bf96b7a79d134b6d8a40037d --- /dev/null +++ b/src/webvowl/js/parsing/equivalentPropertyMerger.js @@ -0,0 +1,147 @@ +var OwlThing = require("../elements/nodes/implementations/OwlThing"); +var RdfsLiteral = require("../elements/nodes/implementations/RdfsLiteral"); +var elementTools = require("../util/elementTools")(); + +var equivalentPropertyMerger = {}; +module.exports = function (){ + return equivalentPropertyMerger; +}; + +var PREFIX = "GENERATED-MERGED_RANGE-"; +var OBJECT_PROPERTY_DEFAULT_RANGE_TYPE = "owl:Thing"; +var DATA_PROPERTY_DEFAULT_RANGE_TYPE = "rdfs:Literal"; + + +equivalentPropertyMerger.merge = function ( properties, nodes, propertyMap, nodeMap, graph ){ + var totalNodeIdsToHide = d3.set(); + var processedPropertyIds = d3.set(); + var mergeNodes = []; + + for ( var i = 0; i < properties.length; i++ ) { + var property = properties[i]; + var equivalents = property.equivalents().map(createIdToPropertyMapper(propertyMap)); + + if ( equivalents.length === 0 || processedPropertyIds.has(property.id()) ) { + continue; + } + + var propertyWithEquivalents = equivalents.concat(property); + + var mergeNode = findMergeNode(propertyWithEquivalents, nodeMap); + if ( !mergeNode ) { + if ( mergeNode !== undefined ) { + mergeNode = createDefaultMergeNode(property, graph); + mergeNodes.push(mergeNode); + } + } + + var nodeIdsToHide = replaceRangesAndCollectNodesToHide(propertyWithEquivalents, mergeNode, properties, + processedPropertyIds); + for ( var j = 0; j < nodeIdsToHide.length; j++ ) { + totalNodeIdsToHide.add(nodeIdsToHide[j]); + } + } + + return filterVisibleNodes(nodes.concat(mergeNodes), totalNodeIdsToHide); +}; + + +function createIdToPropertyMapper( propertyMap ){ + return function ( id ){ + return propertyMap[id]; + }; +} + +function findMergeNode( propertyWithEquivalents, nodeMap ){ + var typeMap = mapPropertiesRangesToType(propertyWithEquivalents, nodeMap); + var typeSet = d3.set(typeMap.keys()); + + // default types are the fallback values and should be ignored for the type determination + typeSet.remove(OBJECT_PROPERTY_DEFAULT_RANGE_TYPE); + typeSet.remove(DATA_PROPERTY_DEFAULT_RANGE_TYPE); + + // exactly one type to chose from -> take the node of this type as range + if ( typeSet.size() === 1 ) { + var type = typeSet.values()[0]; + var ranges = typeMap.get(type); + + if ( ranges.length === 1 ) { + return ranges[0]; + } + } +} + +function mapPropertiesRangesToType( properties, nodeMap ){ + var typeMap = d3.map(); + + properties.forEach(function ( property ){ + if ( property === undefined ) //@ WORKAROUND + return; + + var range = nodeMap[property.range()]; + var type = range.type(); + + if ( !typeMap.has(type) ) { + typeMap.set(type, []); + } + + typeMap.get(type).push(range); + }); + + return typeMap; +} + +function createDefaultMergeNode( property, graph ){ + var range; + + if ( elementTools.isDatatypeProperty(property) ) { + range = new RdfsLiteral(graph); + } else { + range = new OwlThing(graph); + } + range.id(PREFIX + property.id()); + + return range; +} + +function replaceRangesAndCollectNodesToHide( propertyWithEquivalents, mergeNode, properties, processedPropertyIds ){ + var nodesToHide = []; + + propertyWithEquivalents.forEach(function ( property ){ + + if ( property === undefined || mergeNode === undefined ) // @ WORKAROUND + return; + var oldRangeId = property.range(); + property.range(mergeNode.id()); + if ( !isDomainOrRangeOfOtherProperty(oldRangeId, properties) ) { + nodesToHide.push(oldRangeId); + } + + processedPropertyIds.add(property.id()); + }); + + return nodesToHide; +} + +function isDomainOrRangeOfOtherProperty( nodeId, properties ){ + for ( var i = 0; i < properties.length; i++ ) { + var property = properties[i]; + if ( property.domain() === nodeId || property.range() === nodeId ) { + return true; + } + } + + return false; +} + +function filterVisibleNodes( nodes, nodeIdsToHide ){ + var filteredNodes = []; + + nodes.forEach(function ( node ){ + if ( !nodeIdsToHide.has(node.id()) ) { + filteredNodes.push(node); + } + }); + + return filteredNodes; +} diff --git a/src/webvowl/js/parsing/linkCreator.js b/src/webvowl/js/parsing/linkCreator.js new file mode 100644 index 0000000000000000000000000000000000000000..a20ae33e613669fd1d0a64521b8b2a6391a213da --- /dev/null +++ b/src/webvowl/js/parsing/linkCreator.js @@ -0,0 +1,133 @@ +var ArrowLink = require("../elements/links/ArrowLink"); +var BoxArrowLink = require("../elements/links/BoxArrowLink"); +var PlainLink = require("../elements/links/PlainLink"); +var OwlDisjointWith = require("../elements/properties/implementations/OwlDisjointWith"); +var SetOperatorProperty = require("../elements/properties/implementations/SetOperatorProperty"); + +/** + * Stores the passed properties in links. + * @returns {Function} + */ +module.exports = (function (){ + var linkCreator = {}; + + /** + * Creates links from the passed properties. + * @param properties + */ + linkCreator.createLinks = function ( properties ){ + var links = groupPropertiesToLinks(properties); + + for ( var i = 0, l = links.length; i < l; i++ ) { + var link = links[i]; + + countAndSetLayers(link, links); + countAndSetLoops(link, links); + } + + return links; + }; + + /** + * Creates links of properties and - if existing - their inverses. + * @param properties the properties + * @returns {Array} + */ + function groupPropertiesToLinks( properties ){ + var links = [], + property, + addedProperties = require("../util/set")(); + + for ( var i = 0, l = properties.length; i < l; i++ ) { + property = properties[i]; + + if ( !addedProperties.has(property) ) { + var link = createLink(property); + + property.link(link); + if ( property.inverse() ) { + property.inverse().link(link); + } + + links.push(link); + + addedProperties.add(property); + if ( property.inverse() ) { + addedProperties.add(property.inverse()); + } + } + } + + return links; + } + + function countAndSetLayers( link, allLinks ){ + var layer, + layers, + i, l; + + if ( typeof link.layers() === "undefined" ) { + layers = []; + + // Search for other links that are another layer + for ( i = 0, l = allLinks.length; i < l; i++ ) { + var otherLink = allLinks[i]; + if ( link.domain() === otherLink.domain() && link.range() === otherLink.range() || + link.domain() === otherLink.range() && link.range() === otherLink.domain() ) { + layers.push(otherLink); + } + } + + // Set the results on each of the layers + for ( i = 0, l = layers.length; i < l; ++i ) { + layer = layers[i]; + + layer.layerIndex(i); + layer.layers(layers); + } + } + } + + function countAndSetLoops( link, allLinks ){ + var loop, + loops, + i, l; + + if ( typeof link.loops() === "undefined" ) { + loops = []; + + // Search for other links that are also loops of the same node + for ( i = 0, l = allLinks.length; i < l; i++ ) { + var otherLink = allLinks[i]; + if ( link.domain() === otherLink.domain() && link.domain() === otherLink.range() ) { + loops.push(otherLink); + } + } + + // Set the results on each of the loops + for ( i = 0, l = loops.length; i < l; ++i ) { + loop = loops[i]; + + loop.loopIndex(i); + loop.loops(loops); + } + } + } + + function createLink( property ){ + var domain = property.domain(); + var range = property.range(); + + if ( property instanceof OwlDisjointWith ) { + return new PlainLink(domain, range, property); + } else if ( property instanceof SetOperatorProperty ) { + return new BoxArrowLink(domain, range, property); + } + return new ArrowLink(domain, range, property); + } + + return function (){ + // Return a function to keep module interfaces consistent + return linkCreator; + }; +})(); diff --git a/src/webvowl/js/rangeDragger.js b/src/webvowl/js/rangeDragger.js new file mode 100644 index 0000000000000000000000000000000000000000..ebca9376ea04fba85e1536ada44270eb5b2f31f4 --- /dev/null +++ b/src/webvowl/js/rangeDragger.js @@ -0,0 +1,362 @@ +module.exports = function ( graph ){ + /** variable defs **/ + var Range_dragger = {}; + Range_dragger.nodeId = 10002; + Range_dragger.parent = undefined; + Range_dragger.x = 0; + Range_dragger.y = 0; + Range_dragger.rootElement = undefined; + Range_dragger.rootNodeLayer = undefined; + Range_dragger.pathLayer = undefined; + Range_dragger.mouseEnteredVar = false; + Range_dragger.mouseButtonPressed = false; + Range_dragger.nodeElement = undefined; + Range_dragger.draggerObject = undefined; + + Range_dragger.pathElement = undefined; + Range_dragger.typus = "Range_dragger"; + + Range_dragger.type = function (){ + return Range_dragger.typus; + }; + + // TODO: We need the endPoint of the Link here! + Range_dragger.parentNode = function (){ + return Range_dragger.parent; + }; + + Range_dragger.hide_dragger = function ( val ){ + Range_dragger.pathElement.classed("hidden", val); + Range_dragger.nodeElement.classed("hidden", val); + Range_dragger.draggerObject.classed("hidden", val); + }; + Range_dragger.hideDragger = function ( val ){ + if ( Range_dragger.pathElement ) Range_dragger.pathElement.classed("hidden", val); + if ( Range_dragger.nodeElement ) Range_dragger.nodeElement.classed("hidden", val); + if ( Range_dragger.draggerObject ) Range_dragger.draggerObject.classed("hidden", val); + + + }; + + Range_dragger.reDrawEverthing = function (){ + Range_dragger.setParentProperty(Range_dragger.parent); + }; + Range_dragger.updateRange = function ( newRange ){ + + if ( graph.genericPropertySanityCheck(Range_dragger.parent.domain(), newRange, + Range_dragger.parent.type(), + "Could not update range", "Restoring previous range") === false ) return; + + // check for triple duplicates! + + if ( graph.propertyCheckExistenceChecker(Range_dragger.parent, Range_dragger.parent.domain(), newRange) === false ) + return; + if ( Range_dragger.parent.labelElement() === undefined ) return; + if ( Range_dragger.parent.labelElement().attr("transform") === "translate(0,15)" || + Range_dragger.parent.labelElement().attr("transform") === "translate(0,-15)" ) { + var prop = Range_dragger.parent; + Range_dragger.parent.inverse().inverse(null); + Range_dragger.parent.inverse(null); + prop.range(newRange); + } + + else { + Range_dragger.parent.range(newRange); + } + // update the position of the new range + var rX = newRange.x; + var rY = newRange.y; + + var dX = Range_dragger.parent.domain().x; + var dY = Range_dragger.parent.domain().y; + + + // center + var cX = 0.49 * (dX + rX); + var cY = 0.49 * (dY + rY); + // put position there; + Range_dragger.parent.labelElement().x = cX; + Range_dragger.parent.labelElement().px = cX; + Range_dragger.parent.labelElement().y = cY; + Range_dragger.parent.labelElement().py = cY; + + }; + + Range_dragger.setParentProperty = function ( parentProperty, inversed ){ + Range_dragger.parent = parentProperty; + var iP; + var renElem; + Range_dragger.isLoopProperty = false; + if ( parentProperty.domain() === parentProperty.range() ) Range_dragger.isLoopProperty = true; + Range_dragger.parent = parentProperty; + renElem = parentProperty.labelObject(); + if ( inversed === true ) { + if ( parentProperty.labelElement() && parentProperty.labelElement().attr("transform") === "translate(0,15)" ) { + iP = renElem.linkDomainIntersection; + if ( renElem.linkDomainIntersection ) { + Range_dragger.x = iP.x; + Range_dragger.y = iP.y; + } + } else { + iP = renElem.linkRangeIntersection; + if ( renElem.linkRangeIntersection ) { + Range_dragger.x = iP.x; + Range_dragger.y = iP.y; + } + } + } + else { + iP = renElem.linkRangeIntersection; + if ( renElem.linkRangeIntersection ) { + Range_dragger.x = iP.x; + Range_dragger.y = iP.y; + } + } + + Range_dragger.updateElement(); + }; + + + /** BASE HANDLING FUNCTIONS ------------------------------------------------- **/ + Range_dragger.id = function ( index ){ + if ( !arguments.length ) { + return Range_dragger.nodeId; + } + Range_dragger.nodeId = index; + }; + + Range_dragger.svgPathLayer = function ( layer ){ + Range_dragger.pathLayer = layer.append('g'); + }; + + Range_dragger.svgRoot = function ( root ){ + if ( !arguments.length ) + return Range_dragger.rootElement; + Range_dragger.rootElement = root; + Range_dragger.rootNodeLayer = Range_dragger.rootElement.append('g'); + Range_dragger.addMouseEvents(); + }; + + /** DRAWING FUNCTIONS ------------------------------------------------- **/ + Range_dragger.drawNode = function (){ + Range_dragger.pathElement = Range_dragger.pathLayer.append('line') + .classed("classNodeDragPath", true); + Range_dragger.pathElement.attr("x1", 0) + .attr("y1", 0) + .attr("x2", 0) + .attr("y2", 0); + + // var lineData = [ + // {"x": 0, "y": 0}, + // {"x": 0, "y": 40}, + // {"x": -40, "y": 0}, + // {"x": 0, "y": -40}, + // {"x": 0, "y": 0} + // ]; + + var lineData = [ + { "x": -40, "y": 0 }, // start + { "x": -20, "y": -10 }, + { "x": 20, "y": -50 }, + { "x": -10, "y": 0 }, // center + { "x": 20, "y": 50 }, + { "x": -20, "y": 10 }, + { "x": -40, "y": 0 } + ]; + + + var lineFunction = d3.svg.line() + .x(function ( d ){ + return d.x; + }) + .y(function ( d ){ + return d.y; + }) + .interpolate("basis-closed"); + var pathData = "M 61,40 C 41,15 41,-15 61,-40 L 1,0 Z"; + + Range_dragger.nodeElement = Range_dragger.rootNodeLayer.append('path').attr("d", pathData); + Range_dragger.nodeElement.classed("classDraggerNode", true); + if ( graph.options().useAccuracyHelper() ) { + Range_dragger.draggerObject = Range_dragger.rootNodeLayer.append("circle"); + Range_dragger.draggerObject.attr("r", 40) + .attr("cx", 0) + .attr("cy", 0) + .classed("superHiddenElement", true); + Range_dragger.draggerObject.classed("superOpacityElement", !graph.options().showDraggerObject()); + } + + + }; + + Range_dragger.updateElementViaDomainDragger = function ( x, y ){ + + var range_x = x; + var range_y = y; + + var dex = Range_dragger.parent.range().x; + var dey = Range_dragger.parent.range().y; + + var dir_X = x - dex; + var dir_Y = y - dey; + + var len = Math.sqrt(dir_X * dir_X + dir_Y * dir_Y); + + var nX = dir_X / len; + var nY = dir_Y / len; + + + var ep_range_x = dex + nX * Range_dragger.parent.range().actualRadius(); + var ep_range_y = dey + nY * Range_dragger.parent.range().actualRadius(); + + + var dx = range_x - ep_range_x; + var dy = range_y - ep_range_y; + len = Math.sqrt(dx * dx + dy * dy); + nX = dx / len; + nY = dy / len; + + var angle = Math.atan2(ep_range_y - range_y, ep_range_x - range_x) * 180 / Math.PI + 180; + Range_dragger.nodeElement.attr("transform", "translate(" + ep_range_x + "," + ep_range_y + ")" + "rotate(" + angle + ")"); + var doX = ep_range_x + nX * 40; + var doY = ep_range_y + nY * 40; + Range_dragger.draggerObject.attr("transform", "translate(" + doX + "," + doY + ")"); + + }; + + + Range_dragger.updateElement = function (){ + if ( Range_dragger.mouseButtonPressed === true || Range_dragger.parent === undefined ) return; + + var range = Range_dragger.parent.range(); + var iP = Range_dragger.parent.labelObject().linkRangeIntersection; + if ( Range_dragger.parent.labelElement() === undefined ) return; + var offsetForLoop = 48; + if ( Range_dragger.parent.labelElement().attr("transform") === "translate(0,15)" ) { + range = Range_dragger.parent.inverse().domain(); + iP = Range_dragger.parent.labelObject().linkDomainIntersection; + offsetForLoop = -48; + } + + if ( iP === undefined ) return; + var range_x = range.x; + var range_y = range.y; + + var ep_range_x = iP.x; + var ep_range_y = iP.y; + // offset for dragger object + var dx = range_x - ep_range_x; + var dy = range_y - ep_range_y; + var len = Math.sqrt(dx * dx + dy * dy); + var nX = dx / len; + var nY = dy / len; + var angle = Math.atan2(ep_range_y - range_y, ep_range_x - range_x) * 180 / Math.PI; + + var doX = ep_range_x - nX * 40; + var doY = ep_range_y - nY * 40; + + if ( Range_dragger.isLoopProperty === true ) + angle -= offsetForLoop; + + + Range_dragger.nodeElement.attr("transform", "translate(" + ep_range_x + "," + ep_range_y + ")" + "rotate(" + angle + ")"); + Range_dragger.draggerObject.attr("transform", "translate(" + doX + "," + doY + ")"); + + + }; + + /** MOUSE HANDLING FUNCTIONS ------------------------------------------------- **/ + + Range_dragger.addMouseEvents = function (){ + var rootLayer = Range_dragger.rootNodeLayer.selectAll("*"); + rootLayer.on("mouseover", Range_dragger.onMouseOver) + .on("mouseout", Range_dragger.onMouseOut) + .on("click", function (){ + }) + .on("dblclick", function (){ + }) + .on("mousedown", Range_dragger.mouseDown) + .on("mouseup", Range_dragger.mouseUp); + }; + + Range_dragger.mouseDown = function (){ + Range_dragger.nodeElement.style("cursor", "move"); + Range_dragger.nodeElement.classed("classDraggerNodeHovered", true); + Range_dragger.mouseButtonPressed = true; + }; + + Range_dragger.mouseUp = function (){ + Range_dragger.nodeElement.style("cursor", "auto"); + Range_dragger.nodeElement.classed("classDraggerNodeHovered", false); + Range_dragger.mouseButtonPressed = false; + }; + + + Range_dragger.mouseEntered = function ( p ){ + if ( !arguments.length ) return Range_dragger.mouseEnteredVar; + Range_dragger.mouseEnteredVar = p; + return Range_dragger; + }; + + Range_dragger.selectedViaTouch = function ( val ){ + Range_dragger.nodeElement.classed("classDraggerNode", !val); + Range_dragger.nodeElement.classed("classDraggerNodeHovered", val); + + }; + + Range_dragger.onMouseOver = function (){ + if ( Range_dragger.mouseEntered() ) { + return; + } + Range_dragger.nodeElement.classed("classDraggerNode", false); + Range_dragger.nodeElement.classed("classDraggerNodeHovered", true); + var selectedNode = Range_dragger.rootElement.node(), + nodeContainer = selectedNode.parentNode; + nodeContainer.appendChild(selectedNode); + + Range_dragger.mouseEntered(true); + + }; + Range_dragger.onMouseOut = function (){ + if ( Range_dragger.mouseButtonPressed === true ) + return; + Range_dragger.nodeElement.classed("classDraggerNodeHovered", false); + Range_dragger.nodeElement.classed("classDraggerNode", true); + Range_dragger.mouseEntered(false); + }; + + Range_dragger.setPosition = function ( x, y ){ + var range_x = Range_dragger.parent.domain().x; + var range_y = Range_dragger.parent.domain().y; + + // var position of the rangeEndPoint + var ep_range_x = x; + var ep_range_y = y; + + // offset for dragger object + var dx = range_x - ep_range_x; + var dy = range_y - ep_range_y; + + var len = Math.sqrt(dx * dx + dy * dy); + + var nX = dx / len; + var nY = dy / len; + + + var angle = Math.atan2(dy, dx) * 180 / Math.PI; + var doX = ep_range_x + nX * 40; + var doY = ep_range_y + nY * 40; + Range_dragger.nodeElement.attr("transform", "translate(" + ep_range_x + "," + ep_range_y + ")" + "rotate(" + angle + ")"); + Range_dragger.draggerObject.attr("transform", "translate(" + doX + "," + doY + ")"); + Range_dragger.x = x; + Range_dragger.y = y; + + }; + + Range_dragger.setAdditionalClassForClass_dragger = function ( name, val ){ + + }; + return Range_dragger; +}; + + diff --git a/src/webvowl/js/shadowClone.js b/src/webvowl/js/shadowClone.js new file mode 100644 index 0000000000000000000000000000000000000000..28f3f2c55756fa5b1b1a9189219903512e168a52 --- /dev/null +++ b/src/webvowl/js/shadowClone.js @@ -0,0 +1,297 @@ +var CenteringTextElement = require("./util/CenteringTextElement"); +var elementTools = require("./util/elementTools")(); +var math = require("./util/math")(); +module.exports = function ( graph ){ + /** variable defs **/ + var ShadowClone = {}; + ShadowClone.nodeId = 10003; + ShadowClone.parent = undefined; + ShadowClone.s_x = 0; + ShadowClone.s_y = 0; + ShadowClone.e_x = 0; + ShadowClone.e_y = 0; + ShadowClone.rootElement = undefined; + ShadowClone.rootNodeLayer = undefined; + ShadowClone.pathLayer = undefined; + ShadowClone.nodeElement = undefined; + ShadowClone.pathElement = undefined; + ShadowClone.typus = "shadowClone"; + + + ShadowClone.type = function (){ + return ShadowClone.typus; + }; + + // TODO: We need the endPoint of the Link here! + ShadowClone.parentNode = function (){ + return ShadowClone.parent; + }; + + ShadowClone.setParentProperty = function ( parentProperty, inverted ){ + ShadowClone.invertedProperty = inverted; + ShadowClone.parent = parentProperty; + var renElment; + if ( inverted === true ) { + renElment = parentProperty.inverse().labelObject(); + if ( renElment.linkRangeIntersection && renElment.linkDomainIntersection ) { + var iiP_range = renElment.linkDomainIntersection; + var iiP_domain = renElment.linkRangeIntersection; + ShadowClone.s_x = iiP_domain.x; + ShadowClone.s_y = iiP_domain.y; + ShadowClone.e_x = iiP_range.x; + ShadowClone.e_y = iiP_range.y; + } + } + else { + renElment = parentProperty.labelObject(); + + if ( renElment.linkRangeIntersection && renElment.linkDomainIntersection ) { + var iP_range = renElment.linkRangeIntersection; + var iP_domain = renElment.linkDomainIntersection; + ShadowClone.s_x = iP_domain.x; + ShadowClone.s_y = iP_domain.y; + ShadowClone.e_x = iP_range.x; + ShadowClone.e_y = iP_range.y; + } + + } + + ShadowClone.rootNodeLayer.remove(); + ShadowClone.rootNodeLayer = ShadowClone.rootElement.append('g'); + ShadowClone.rootNodeLayer.datum(parentProperty); + + // ShadowClone.pathElement.remove(); + // ShadowClone.pathElement = ShadowClone.pathLayer.append('line'); + // + // ShadowClone.pathElement.attr("x1", ShadowClone.s_x) + // .attr("y1", ShadowClone.s_y) + // .attr("x2", ShadowClone.e_x) + // .attr("y2", ShadowClone.e_y); + ShadowClone.pathElement.remove(); + ShadowClone.pathElement = ShadowClone.pathLayer.append('line'); + ShadowClone.markerElement = ShadowClone.pathLayer.append("marker"); + ShadowClone.markerElement.attr("id", "shadowCloneMarker"); + ShadowClone.pathElement.attr("x1", ShadowClone.e_x) + .attr("y1", ShadowClone.e_y) + .attr("x2", ShadowClone.s_x) + .attr("y2", ShadowClone.s_y); + ShadowClone.pathElement.classed(parentProperty.linkType(), true); + + if ( parentProperty.markerElement() ) { + ShadowClone.markerElement.attr("viewBox", parentProperty.markerElement().attr("viewBox")) + .attr("markerWidth", parentProperty.markerElement().attr("markerWidth")) + .attr("markerHeight", parentProperty.markerElement().attr("markerHeight")) + .attr("orient", parentProperty.markerElement().attr("orient")); + + var markerPath = parentProperty.markerElement().select("path"); + ShadowClone.markerElement.append("path") + .attr("d", markerPath.attr("d")) + .classed(parentProperty.markerType(), true); + + ShadowClone.pathElement.attr("marker-end", "url(#" + "shadowCloneMarker" + ")"); + ShadowClone.markerElement.classed("hidden", !elementTools.isDatatypeProperty(parentProperty)); + } + var rect = ShadowClone.rootNodeLayer.append("rect") + .classed(parentProperty.styleClass(), true) + .classed("property", true) + .attr("x", -parentProperty.width() / 2) + .attr("y", -parentProperty.height() / 2) + .attr("width", parentProperty.width()) + .attr("height", parentProperty.height()); + + if ( parentProperty.visualAttributes() ) { + rect.classed(parentProperty.visualAttributes(), true); + } + rect.classed("datatype", false); + var bgColor = parentProperty.backgroundColor(); + + if ( parentProperty.attributes().indexOf("deprecated") > -1 ) { + bgColor = undefined; + rect.classed("deprecatedproperty", true); + } else { + rect.classed("deprecatedproperty", false); + } + rect.style("fill", bgColor); + + // add Text; + var equivalentsString = parentProperty.equivalentsString(); + var suffixForFollowingEquivalents = equivalentsString ? "," : ""; + + + var textElement = new CenteringTextElement(ShadowClone.rootNodeLayer, bgColor); + textElement.addText(parentProperty.labelForCurrentLanguage(), "", suffixForFollowingEquivalents); + textElement.addEquivalents(equivalentsString); + textElement.addSubText(parentProperty.indicationString()); + + + var cx = 0.5 * (ShadowClone.s_x + ShadowClone.e_x); + var cy = 0.5 * (ShadowClone.s_y + ShadowClone.e_y); + ShadowClone.rootNodeLayer.attr("transform", "translate(" + cx + "," + cy + ")"); + ShadowClone.rootNodeLayer.classed("hidden", true); + ShadowClone.pathElement.classed("hidden", true); + + + }; + + ShadowClone.hideClone = function ( val ){ + if ( ShadowClone.rootNodeLayer ) ShadowClone.rootNodeLayer.classed("hidden", val); + if ( ShadowClone.pathElement ) ShadowClone.pathElement.classed("hidden", val); + }; + + ShadowClone.hideParentProperty = function ( val ){ + + var labelObj = ShadowClone.parent.labelObject(); + if ( labelObj ) { + if ( ShadowClone.parent.labelElement().attr("transform") === "translate(0,15)" || + ShadowClone.parent.labelElement().attr("transform") === "translate(0,-15)" ) + ShadowClone.parent.inverse().hide(val); + + + } + ShadowClone.parent.hide(val); + + + }; + + /** BASE HANDLING FUNCTIONS ------------------------------------------------- **/ + ShadowClone.id = function ( index ){ + if ( !arguments.length ) { + return ShadowClone.nodeId; + } + ShadowClone.nodeId = index; + }; + + ShadowClone.svgPathLayer = function ( layer ){ + ShadowClone.pathLayer = layer.append('g'); + }; + + ShadowClone.svgRoot = function ( root ){ + if ( !arguments.length ) + return ShadowClone.rootElement; + ShadowClone.rootElement = root; + ShadowClone.rootNodeLayer = ShadowClone.rootElement.append('g'); + + }; + + /** DRAWING FUNCTIONS ------------------------------------------------- **/ + ShadowClone.drawClone = function (){ + ShadowClone.pathElement = ShadowClone.pathLayer.append('line'); + + ShadowClone.pathElement.attr("x1", 0) + .attr("y1", 0) + .attr("x2", 0) + .attr("y2", 0); + + }; + + + ShadowClone.updateElement = function (){ + ShadowClone.pathElement.attr("x1", ShadowClone.e_x) + .attr("y1", ShadowClone.e_y) + .attr("x2", ShadowClone.s_x) + .attr("y2", ShadowClone.s_y); + + var cx = 0.5 * (ShadowClone.s_x + ShadowClone.e_x); + var cy = 0.5 * (ShadowClone.s_y + ShadowClone.e_y); + ShadowClone.rootNodeLayer.attr("transform", "translate(" + cx + "," + cy + ")"); + }; + + ShadowClone.setInitialPosition = function (){ + + var renElment = ShadowClone.parent.labelObject(); + if ( renElment.linkRangeIntersection && renElment.linkDomainIntersection ) { + var iP_range = renElment.linkRangeIntersection; + var iP_domain = renElment.linkDomainIntersection; + ShadowClone.e_x = iP_domain.x; + ShadowClone.e_y = iP_domain.y; + ShadowClone.s_x = iP_range.x; + ShadowClone.s_y = iP_range.y; + } + ShadowClone.updateElement(); + return; + // + // var rex=ShadowClone.parent.range().x; + // var rey=ShadowClone.parent.range().y; + // + // + // var dex=ShadowClone.parent.domain().x; + // var dey=ShadowClone.parent.domain().y; + // + // + // var dir_X= rex-dex; + // var dir_Y= rey-dey; + // + // var len=Math.sqrt(dir_X*dir_X+dir_Y*dir_Y); + // var nX=dir_X/len; + // var nY=dir_Y/len; + // ShadowClone.s_x=rex-nX*ShadowClone.parent.range().actualRadius(); + // ShadowClone.s_y=rey-nY*ShadowClone.parent.range().actualRadius(); + // + // ShadowClone.e_x=dex+nX*ShadowClone.parent.domain().actualRadius(); + // ShadowClone.e_y=dey+nY*ShadowClone.parent.domain().actualRadius(); + // ShadowClone.updateElement(); + + }; + ShadowClone.setPositionDomain = function ( e_x, e_y ){ + + var rex = ShadowClone.parent.range().x; + var rey = ShadowClone.parent.range().y; + + + if ( elementTools.isDatatype(ShadowClone.parent.range()) === true ) { + var intersection = math.calculateIntersection({ x: e_x, y: e_y }, ShadowClone.parent.range(), 0); + ShadowClone.s_x = intersection.x; + ShadowClone.s_y = intersection.y; + } else { + var dir_X = rex - e_x; + var dir_Y = rey - e_y; + + var len = Math.sqrt(dir_X * dir_X + dir_Y * dir_Y); + + var nX = dir_X / len; + var nY = dir_Y / len; + ShadowClone.s_x = rex - nX * ShadowClone.parent.range().actualRadius(); + ShadowClone.s_y = rey - nY * ShadowClone.parent.range().actualRadius(); + + } + + + ShadowClone.e_x = e_x; + ShadowClone.e_y = e_y; + ShadowClone.updateElement(); + }; + + ShadowClone.setPosition = function ( s_x, s_y ){ + ShadowClone.s_x = s_x; + ShadowClone.s_y = s_y; + + // add normalized dir; + + var dex = ShadowClone.parent.domain().x; + var dey = ShadowClone.parent.domain().y; + + var dir_X = s_x - dex; + var dir_Y = s_y - dey; + + var len = Math.sqrt(dir_X * dir_X + dir_Y * dir_Y); + + var nX = dir_X / len; + var nY = dir_Y / len; + + + ShadowClone.e_x = dex + nX * ShadowClone.parent.domain().actualRadius(); + ShadowClone.e_y = dey + nY * ShadowClone.parent.domain().actualRadius(); + + + ShadowClone.updateElement(); + + + }; + + + /** MOUSE HANDLING FUNCTIONS ------------------------------------------------- **/ + + return ShadowClone; +}; + + diff --git a/src/webvowl/js/util/AbsoluteTextElement.js b/src/webvowl/js/util/AbsoluteTextElement.js new file mode 100644 index 0000000000000000000000000000000000000000..44c1c393eb23e2d9552b4bde6633e3a56e5f24d2 --- /dev/null +++ b/src/webvowl/js/util/AbsoluteTextElement.js @@ -0,0 +1,56 @@ +var textTools = require("./textTools")(); +var AbstractTextElement = require("./AbstractTextElement"); + +module.exports = AbsoluteTextElement; +function AbsoluteTextElement( container, backgroundColor ){ + AbstractTextElement.apply(this, arguments); +} + +AbsoluteTextElement.prototype = Object.create(AbstractTextElement.prototype); +AbsoluteTextElement.prototype.constructor = AbsoluteTextElement; + +AbsoluteTextElement.prototype.addText = function ( text, yShift, prefix, suffix ){ + if ( text ) { + this.addTextline(text, this.CSS_CLASSES.default, yShift, prefix, suffix); + } +}; + +AbsoluteTextElement.prototype.addSubText = function ( text, yShift ){ + if ( text ) { + this.addTextline(text, this.CSS_CLASSES.subtext, yShift, "(", ")"); + } +}; + +AbsoluteTextElement.prototype.addEquivalents = function ( text, yShift ){ + if ( text ) { + this.addTextline(text, this.CSS_CLASSES.default, yShift); + } +}; + +AbsoluteTextElement.prototype.addInstanceCount = function ( instanceCount, yShift ){ + if ( instanceCount ) { + this.addTextline(instanceCount.toString(), this.CSS_CLASSES.instanceCount, yShift); + } +}; + + +AbsoluteTextElement.prototype.addTextline = function ( text, style, yShift, prefix, postfix ){ + var truncatedText = textTools.truncate(text, this._textBlock().datum().textWidth(yShift), style); + + var tspan = this._textBlock().append("tspan") + .classed(this.CSS_CLASSES.default, true) + .classed(style, true) + .text(this._applyPreAndPostFix(truncatedText, prefix, postfix)) + .attr("x", 0); + this._repositionTextLine(tspan, yShift); +}; + +AbsoluteTextElement.prototype._repositionTextLine = function ( tspan, yShift ){ + var fontSizeProperty = window.getComputedStyle(tspan.node()).getPropertyValue("font-size"); + var fontSize = parseFloat(fontSizeProperty); + + /* BBox height is not supported in Firefox for tspans and dominant-baseline doesn't work in some SVG editors */ + var approximatedShiftForVerticalCentering = (1 / 3) * fontSize; + + tspan.attr("y", approximatedShiftForVerticalCentering + (yShift || 0) + "px"); +}; diff --git a/src/webvowl/js/util/AbstractTextElement.js b/src/webvowl/js/util/AbstractTextElement.js new file mode 100644 index 0000000000000000000000000000000000000000..6f4674459906f8a041573312ba8a5a6d28af5ef0 --- /dev/null +++ b/src/webvowl/js/util/AbstractTextElement.js @@ -0,0 +1,58 @@ +module.exports = AbstractTextElement; + +function AbstractTextElement( container, backgroundColor ){ + var textBlock = container.append("text") + .classed("text", true) + .style("fill", this._getTextColor(backgroundColor)) + .attr("text-anchor", "middle"); + + this._textBlock = function (){ + return textBlock; + }; +} + +AbstractTextElement.prototype.LINE_DISTANCE = 1; +AbstractTextElement.prototype.CSS_CLASSES = { + default: "text", + subtext: "subtext", + instanceCount: "instance-count" +}; +AbstractTextElement.prototype.DARK_TEXT_COLOR = "#000"; +AbstractTextElement.prototype.LIGHT_TEXT_COLOR = "#fff"; + +AbstractTextElement.prototype.translation = function ( x, y ){ + this._textBlock().attr("transform", "translate(" + x + ", " + y + ")"); + return this; +}; + +AbstractTextElement.prototype.remove = function (){ + this._textBlock().remove(); + return this; +}; + +AbstractTextElement.prototype._applyPreAndPostFix = function ( text, prefix, postfix ){ + if ( prefix ) { + text = prefix + text; + } + if ( postfix ) { + text += postfix; + } + return text; +}; + +AbstractTextElement.prototype._getTextColor = function ( rawBackgroundColor ){ + if ( !rawBackgroundColor ) { + return AbstractTextElement.prototype.DARK_TEXT_COLOR; + } + + var backgroundColor = d3.rgb(rawBackgroundColor); + if ( calculateLuminance(backgroundColor) > 0.5 ) { + return AbstractTextElement.prototype.DARK_TEXT_COLOR; + } else { + return AbstractTextElement.prototype.LIGHT_TEXT_COLOR; + } +}; + +function calculateLuminance( color ){ + return 0.3 * (color.r / 255) + 0.59 * (color.g / 255) + 0.11 * (color.b / 255); +} diff --git a/src/webvowl/js/util/CenteringTextElement.js b/src/webvowl/js/util/CenteringTextElement.js new file mode 100644 index 0000000000000000000000000000000000000000..6856519da37edf04439cdcdcb941c30e4639710b --- /dev/null +++ b/src/webvowl/js/util/CenteringTextElement.js @@ -0,0 +1,102 @@ +var textTools = require("./textTools")(); +var AbstractTextElement = require("./AbstractTextElement"); + +module.exports = CenteringTextElement; +function CenteringTextElement( container, backgroundColor ){ + AbstractTextElement.apply(this, arguments); + this.storedFullTextLines = []; + this.storedSpanArrays = []; + this.storedStyle = []; + +} + +CenteringTextElement.prototype = Object.create(AbstractTextElement.prototype); +CenteringTextElement.prototype.constructor = CenteringTextElement; + +CenteringTextElement.prototype.addText = function ( text, prefix, suffix ){ + if ( text ) { + this.addTextline(text, this.CSS_CLASSES.default, prefix, suffix); + } +}; + +CenteringTextElement.prototype.addSubText = function ( text ){ + if ( text ) { + this.addTextline(text, this.CSS_CLASSES.subtext, "(", ")"); + } +}; + +CenteringTextElement.prototype.addEquivalents = function ( text ){ + if ( text ) { + this.addTextline(text, this.CSS_CLASSES.default); + } +}; + +CenteringTextElement.prototype.addInstanceCount = function ( instanceCount ){ + if ( instanceCount ) { + this.addTextline(instanceCount.toString(), this.CSS_CLASSES.instanceCount); + } +}; +CenteringTextElement.prototype.saveCorrespondingSpan = function ( correspondingSpan ){ + this.storedSpanArrays.push(correspondingSpan); +}; +CenteringTextElement.prototype.saveFullTextLine = function ( fullText ){ + this.storedFullTextLines.push(fullText); +}; +CenteringTextElement.prototype.saveStyle = function ( style ){ + this.storedStyle.push(style); +}; + +CenteringTextElement.prototype.updateAllTextElements = function (){ + // TODO : TEST THIS postPrefix >>> _applyPreAndPostFix + for ( var i = 0; i < this.storedSpanArrays.length; i++ ) { + var truncatedText = textTools.truncate(this.storedFullTextLines[i], this._textBlock().datum().textWidth(), this.storedStyle[i]); + this.storedSpanArrays[i].text(truncatedText); + } +}; + + +CenteringTextElement.prototype.addTextline = function ( text, style, prefix, postfix ){ + var truncatedText = textTools.truncate(text, this._textBlock().datum().textWidth(), style); + this.saveFullTextLine(text); + this.saveStyle(style); + var tspan = this._textBlock().append("tspan") + .classed(this.CSS_CLASSES.default, true) + .classed(style, true) + .text(this._applyPreAndPostFix(truncatedText, prefix, postfix)) + .attr("x", 0); + this._repositionTextLine(tspan); + this.saveCorrespondingSpan(tspan); + + this._repositionTextBlock(); +}; + +CenteringTextElement.prototype._repositionTextLine = function ( tspan ){ + var fontSizeProperty = window.getComputedStyle(tspan.node()).getPropertyValue("font-size"); + var fontSize = parseFloat(fontSizeProperty); + + var siblingCount = this._lineCount() - 1; + var lineDistance = siblingCount > 0 ? this.LINE_DISTANCE : 0; + + tspan.attr("dy", fontSize + lineDistance + "px"); +}; + +CenteringTextElement.prototype.getTextBox = function (){ + return this._textBlock(); +}; + + +CenteringTextElement.prototype._repositionTextBlock = function (){ + // Nothing to do if no child elements exist + var lineCount = this._lineCount(); + if ( lineCount < 1 ) { + this._textBlock().attr("y", 0); + return; + } + + var textBlockHeight = this._textBlock().node().getBBox().height; + this._textBlock().attr("y", -textBlockHeight * 0.5 + "px"); +}; + +CenteringTextElement.prototype._lineCount = function (){ + return this._textBlock().property("childElementCount"); +}; diff --git a/src/webvowl/js/util/constants.js b/src/webvowl/js/util/constants.js new file mode 100644 index 0000000000000000000000000000000000000000..b5e0585e67750edf4847d30882712a50e5e44758 --- /dev/null +++ b/src/webvowl/js/util/constants.js @@ -0,0 +1,13 @@ +module.exports = (function (){ + + var constants = {}; + + constants.LANG_IRIBASED = "IRI-based"; + constants.LANG_UNDEFINED = "undefined"; + + return function (){ + /* Use a function here to keep a consistent style like webvowl.path.to.module() + * despite having just a single object. */ + return constants; + }; +})(); diff --git a/src/webvowl/js/util/elementTools.js b/src/webvowl/js/util/elementTools.js new file mode 100644 index 0000000000000000000000000000000000000000..b2c29b85f4fe9025a6f2dfb5f71adea2214eff86 --- /dev/null +++ b/src/webvowl/js/util/elementTools.js @@ -0,0 +1,46 @@ +var BaseProperty = require("../elements/properties/BaseProperty"); +var BaseNode = require("../elements/nodes/BaseNode"); +var DatatypeNode = require("../elements/nodes/DatatypeNode"); +var Thing = require("../elements/nodes/implementations/OwlThing"); +var ObjectProperty = require("../elements/properties/implementations/OwlObjectProperty"); +var DatatypeProperty = require("../elements/properties/implementations/OwlDatatypeProperty"); +var RdfsSubClassOf = require("../elements/properties/implementations/RdfsSubClassOf"); +var Label = require("../elements/links/Label"); + + +var tools = {}; +module.exports = function (){ + return tools; +}; + +tools.isLabel = function ( element ){ + return element instanceof Label; +}; + +tools.isNode = function ( element ){ + return element instanceof BaseNode; +}; + +tools.isDatatype = function ( node ){ + return node instanceof DatatypeNode; +}; + +tools.isThing = function ( node ){ + return node instanceof Thing; +}; + +tools.isProperty = function ( element ){ + return element instanceof BaseProperty; +}; + +tools.isObjectProperty = function ( element ){ + return element instanceof ObjectProperty; +}; + +tools.isDatatypeProperty = function ( element ){ + return element instanceof DatatypeProperty; +}; + +tools.isRdfsSubClassOf = function ( property ){ + return property instanceof RdfsSubClassOf; +}; diff --git a/src/webvowl/js/util/filterTools.js b/src/webvowl/js/util/filterTools.js new file mode 100644 index 0000000000000000000000000000000000000000..478c88fa0429fccaa38e75305187fc90b0b504cf --- /dev/null +++ b/src/webvowl/js/util/filterTools.js @@ -0,0 +1,59 @@ +var elementTools = require("./elementTools")(); + +module.exports = (function (){ + + var tools = {}; + + /** + * Filters the passed nodes and removes dangling properties. + * @param nodes + * @param properties + * @param shouldKeepNode function that returns true if the node should be kept + * @returns {{nodes: Array, properties: Array}} the filtered nodes and properties + */ + tools.filterNodesAndTidy = function ( nodes, properties, shouldKeepNode ){ + var removedNodes = require("./set")(), + cleanedNodes = [], + cleanedProperties = []; + + nodes.forEach(function ( node ){ + if ( shouldKeepNode(node) ) { + cleanedNodes.push(node); + } else { + removedNodes.add(node); + } + }); + + properties.forEach(function ( property ){ + if ( propertyHasVisibleNodes(removedNodes, property) ) { + cleanedProperties.push(property); + } else if ( elementTools.isDatatypeProperty(property) ) { + // Remove floating datatypes/literals, because they belong to their datatype property + var index = cleanedNodes.indexOf(property.range()); + if ( index >= 0 ) { + cleanedNodes.splice(index, 1); + } + } + }); + + return { + nodes: cleanedNodes, + properties: cleanedProperties + }; + }; + + /** + * Returns true, if the domain and the range of this property have not been removed. + * @param removedNodes + * @param property + * @returns {boolean} true if property isn't dangling + */ + function propertyHasVisibleNodes( removedNodes, property ){ + return !removedNodes.has(property.domain()) && !removedNodes.has(property.range()); + } + + + return function (){ + return tools; + }; +})(); diff --git a/src/webvowl/js/util/languageTools.js b/src/webvowl/js/util/languageTools.js new file mode 100644 index 0000000000000000000000000000000000000000..a5207eec7f12addd42fd370253408c0cc038e3e7 --- /dev/null +++ b/src/webvowl/js/util/languageTools.js @@ -0,0 +1,50 @@ +var constants = require("./constants")(); + +/** + * Encapsulates methods which return a label in a specific language for a preferred language. + */ +module.exports = (function (){ + + var languageTools = {}; + + + languageTools.textInLanguage = function ( textObject, preferredLanguage ){ + if ( typeof textObject === "undefined" ) { + return undefined; + } + + if ( typeof textObject === "string" ) { + return textObject; + } + + if ( preferredLanguage && textObject.hasOwnProperty(preferredLanguage) ) { + return textObject[preferredLanguage]; + } + + var textForLanguage = searchLanguage(textObject, "en"); + if ( textForLanguage ) { + return textForLanguage; + } + textForLanguage = searchLanguage(textObject, constants.LANG_UNDEFINED); + if ( textForLanguage ) { + return textForLanguage; + } + + return textObject[constants.LANG_IRIBASED]; + }; + + + function searchLanguage( textObject, preferredLanguage ){ + for ( var language in textObject ) { + if ( language === preferredLanguage && textObject.hasOwnProperty(language) ) { + return textObject[language]; + } + } + } + + return function (){ + /* Use a function here to keep a consistent style like webvowl.path.to.module() + * despite having just a single languageTools object. */ + return languageTools; + }; +})(); diff --git a/src/webvowl/js/util/math.js b/src/webvowl/js/util/math.js new file mode 100644 index 0000000000000000000000000000000000000000..6bcaa7ea8ded2eab2ae8de3e38577bfa73ff94c5 --- /dev/null +++ b/src/webvowl/js/util/math.js @@ -0,0 +1,214 @@ +/** + * Contains a collection of mathematical functions with some additional data + * used for WebVOWL. + */ +module.exports = (function (){ + + var math = {}, + loopFunction = d3.svg.line() + .x(function ( d ){ + return d.x; + }) + .y(function ( d ){ + return d.y; + }) + .interpolate("cardinal") + .tension(-1); + + + /** + * Calculates the normal vector of the path between the two nodes. + * @param source the first node + * @param target the second node + * @param length the length of the calculated normal vector + * @returns {{x: number, y: number}} + */ + math.calculateNormalVector = function ( source, target, length ){ + var dx = target.x - source.x, + dy = target.y - source.y; + + var nx = -dy, + ny = dx; + + var vlength = Math.sqrt(nx * nx + ny * ny); + + var ratio = vlength !== 0 ? length / vlength : 0; + + return { "x": nx * ratio, "y": ny * ratio }; + }; + + /** + * Calculates the path for a link, if it is a loop. Currently only working for circlular nodes. + * @param link the link + * @returns {*} + */ + + + + math.getLoopPoints = function ( link ){ + var node = link.domain(), + label = link.label(); + + var fairShareLoopAngle = 360 / link.loops().length, + fairShareLoopAngleWithMargin = fairShareLoopAngle * 0.8, + loopAngle = Math.min(60, fairShareLoopAngleWithMargin); + + if ( label.increasedLoopAngle === true ) + loopAngle = 120; + + + var dx = label.x - node.x, + dy = label.y - node.y, + labelRadian = Math.atan2(dy, dx), + labelAngle = calculateAngle(labelRadian); + + var startAngle = labelAngle - loopAngle / 2, + endAngle = labelAngle + loopAngle / 2; + + + var arcFrom = calculateRadian(startAngle), + arcTo = calculateRadian(endAngle), + + x1 = Math.cos(arcFrom) * node.actualRadius(), + y1 = Math.sin(arcFrom) * node.actualRadius(), + + x2 = Math.cos(arcTo) * node.actualRadius(), + y2 = Math.sin(arcTo) * node.actualRadius(), + + fixPoint1 = { "x": node.x + x1, "y": node.y + y1 }, + fixPoint2 = { "x": node.x + x2, "y": node.y + y2 }; + + return [fixPoint1, fixPoint2]; + }; + math.calculateLoopPath = function ( link ){ + var node = link.domain(), + label = link.label(); + + + var fairShareLoopAngle = 360 / link.loops().length, + fairShareLoopAngleWithMargin = fairShareLoopAngle * 0.8, + loopAngle = Math.min(60, fairShareLoopAngleWithMargin); + + if ( label.increasedLoopAngle === true ) + loopAngle = 120; + + var dx = label.x - node.x, + dy = label.y - node.y, + labelRadian = Math.atan2(dy, dx), + labelAngle = calculateAngle(labelRadian); + + var startAngle = labelAngle - loopAngle / 2, + endAngle = labelAngle + loopAngle / 2; + + var arcFrom = calculateRadian(startAngle), + arcTo = calculateRadian(endAngle), + + x1 = Math.cos(arcFrom) * node.actualRadius(), + y1 = Math.sin(arcFrom) * node.actualRadius(), + + x2 = Math.cos(arcTo) * node.actualRadius(), + y2 = Math.sin(arcTo) * node.actualRadius(), + + fixPoint1 = { "x": node.x + x1, "y": node.y + y1 }, + fixPoint2 = { "x": node.x + x2, "y": node.y + y2 }; + + return loopFunction([fixPoint1, link.label(), fixPoint2]); + }; + + math.calculateLoopPoints = function ( link ){ + var node = link.domain(), + label = link.label(); + + var fairShareLoopAngle = 360 / link.loops().length, + fairShareLoopAngleWithMargin = fairShareLoopAngle * 0.8, + loopAngle = Math.min(60, fairShareLoopAngleWithMargin); + + var dx = label.x - node.x, + dy = label.y - node.y, + labelRadian = Math.atan2(dy, dx), + labelAngle = calculateAngle(labelRadian); + + var startAngle = labelAngle - loopAngle / 2, + endAngle = labelAngle + loopAngle / 2; + + var arcFrom = calculateRadian(startAngle), + arcTo = calculateRadian(endAngle), + + x1 = Math.cos(arcFrom) * node.actualRadius(), + y1 = Math.sin(arcFrom) * node.actualRadius(), + + x2 = Math.cos(arcTo) * (node.actualRadius()), + y2 = Math.sin(arcTo) * (node.actualRadius()), + + fixPoint1 = { "x": node.x + x1, "y": node.y + y1 }, + fixPoint2 = { "x": node.x + x2, "y": node.y + y2 }; + + return [fixPoint1, link.label(), fixPoint2]; + }; + + /** + * @param angle + * @returns {number} the radian of the angle + */ + function calculateRadian( angle ){ + angle = angle % 360; + if ( angle < 0 ) { + angle = angle + 360; + } + return (Math.PI * angle) / 180; + } + + /** + * @param radian + * @returns {number} the angle of the radian + */ + function calculateAngle( radian ){ + return radian * (180 / Math.PI); + } + + /** + * Calculates the point where the link between the source and target node + * intersects the border of the target node. + * @param source the source node + * @param target the target node + * @param additionalDistance additional distance the + * @returns {{x: number, y: number}} + */ + math.calculateIntersection = function ( source, target, additionalDistance ){ + var dx = target.x - source.x, + dy = target.y - source.y, + length = Math.sqrt(dx * dx + dy * dy); + + if ( length === 0 ) { + return { x: source.x, y: source.y }; + } + + var innerDistance = target.distanceToBorder(dx, dy); + + var ratio = (length - (innerDistance + additionalDistance)) / length, + x = dx * ratio + source.x, + y = dy * ratio + source.y; + + return { x: x, y: y }; + }; + + /** + * Calculates the position between the two points. + * @param firstPoint + * @param secondPoint + * @returns {{x: number, y: number}} + */ + math.calculateCenter = function ( firstPoint, secondPoint ){ + return { + x: (firstPoint.x + secondPoint.x) / 2, + y: (firstPoint.y + secondPoint.y) / 2 + }; + }; + + + return function (){ + /* Use a function here to keep a consistent style like webvowl.path.to.module() + * despite having just a single math object. */ + return math; + }; +})(); diff --git a/src/webvowl/js/util/prefixRepresentationModule.js b/src/webvowl/js/util/prefixRepresentationModule.js new file mode 100644 index 0000000000000000000000000000000000000000..491ffd8361045901575c8df7612bdfa345870ae9 --- /dev/null +++ b/src/webvowl/js/util/prefixRepresentationModule.js @@ -0,0 +1,77 @@ +module.exports = function ( graph ){ + /** variable defs **/ + var prefixRepresentationModule = {}; + + var currentPrefixModel; + + prefixRepresentationModule.updatePrefixModel = function (){ + currentPrefixModel = graph.options().prefixList(); + }; + + + prefixRepresentationModule.validURL = function ( url ){ + return validURL(url); + }; + function validURL( str ){ + var urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/; + return urlregex.test(str); + } + + function splitURLIntoBaseAndResource( fullURL ){ + var splitedURL = { base: "", resource: "" }; + if ( fullURL === undefined ) { + splitedURL = { base: "ERROR", resource: "NOT FOUND" }; + return splitedURL; + } + + var resource, base; + // check if there is a last hashTag + if ( fullURL.indexOf("#") > -1 ) { + resource = fullURL.substring(fullURL.lastIndexOf('#') + 1); + base = fullURL.substring(0, fullURL.length - resource.length); + // overwrite base if it is ontologyIri; + if ( base === graph.options().getGeneralMetaObjectProperty('iri') ) { + base = ":"; + } + splitedURL.base = base; + splitedURL.resource = resource; + } else { + resource = fullURL.substring(fullURL.lastIndexOf('/') + 1); + base = fullURL.substring(0, fullURL.length - resource.length); + // overwrite base if it is ontologyIri; + if ( base === graph.options().getGeneralMetaObjectProperty('iri') ) { + base = ":"; + } + splitedURL.base = base; + splitedURL.resource = resource; + } + return splitedURL; + } + + prefixRepresentationModule.getPrefixRepresentationForFullURI = function ( fullURL ){ + prefixRepresentationModule.updatePrefixModel(); + var splittedURL = splitURLIntoBaseAndResource(fullURL); + + // lazy approach , for + // loop over prefix model + for ( var name in currentPrefixModel ) { + if ( currentPrefixModel.hasOwnProperty(name) ) { + // THIS IS CASE SENSITIVE! + if ( currentPrefixModel[name] === splittedURL.base ) { + return name + ":" + splittedURL.resource; + } + } + } + + if ( splittedURL.base === ":" ) { + return ":" + splittedURL.resource; + } + + return fullURL; + }; + + + return prefixRepresentationModule; +}; + + diff --git a/src/webvowl/js/util/set.js b/src/webvowl/js/util/set.js new file mode 100644 index 0000000000000000000000000000000000000000..90808872da2c03915c163f575fa5df231c58417c --- /dev/null +++ b/src/webvowl/js/util/set.js @@ -0,0 +1,31 @@ +/** + * A simple incomplete encapsulation of the d3 set, which is able to store webvowl + * elements by using their id. + */ +module.exports = function ( array ){ + + var set = {}, + d3Set = d3.set(array); + + set.has = function ( webvowlElement ){ + return d3Set.has(webvowlElement.id()); + }; + + set.add = function ( webvowlElement ){ + return d3Set.add(webvowlElement.id()); + }; + + set.remove = function ( webvowlElement ){ + return d3Set.remove(webvowlElement.id()); + }; + + set.empty = function (){ + return d3Set.empty(); + }; + + set.size = function (){ + return d3Set.size(); + }; + + return set; +}; diff --git a/src/webvowl/js/util/textTools.js b/src/webvowl/js/util/textTools.js new file mode 100644 index 0000000000000000000000000000000000000000..7fb250eb4e317a6a48f4a8fdbc868b0fbd0ad026 --- /dev/null +++ b/src/webvowl/js/util/textTools.js @@ -0,0 +1,58 @@ +var ADDITIONAL_TEXT_SPACE = 4; + +var tools = {}; + +function measureTextWidth( text, textStyle ){ + // Set a default value + if ( !textStyle ) { + textStyle = "text"; + } + var d = d3.select("body") + .append("div") + .attr("class", textStyle) + .attr("id", "width-test") // tag this element to identify it + .attr("style", "position:absolute; float:left; white-space:nowrap; visibility:hidden;") + .text(text), + w = document.getElementById("width-test").offsetWidth; + d.remove(); + return w; +} + +tools.truncate = function ( text, maxWidth, textStyle, additionalTextSpace ){ + maxWidth -= isNaN(additionalTextSpace) ? ADDITIONAL_TEXT_SPACE : additionalTextSpace; + if ( isNaN(maxWidth) || maxWidth <= 0 ) { + return text; + } + + var truncatedText = text, + newTruncatedTextLength, + textWidth, + ratio; + + while ( true ) { + textWidth = measureTextWidth(truncatedText, textStyle); + if ( textWidth <= maxWidth ) { + break; + } + + ratio = textWidth / maxWidth; + newTruncatedTextLength = Math.floor(truncatedText.length / ratio); + + // detect if nothing changes + if ( truncatedText.length === newTruncatedTextLength ) { + break; + } + + truncatedText = truncatedText.substring(0, newTruncatedTextLength); + } + + if ( text.length > truncatedText.length ) { + return text.substring(0, truncatedText.length - 3) + "..."; + } + return text; +}; + + +module.exports = function (){ + return tools; +}; diff --git a/util/VowlCssToD3RuleConverter/README.md b/util/VowlCssToD3RuleConverter/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e629a8ba90f0f62412c8588c3d3aba236c1899f1 --- /dev/null +++ b/util/VowlCssToD3RuleConverter/README.md @@ -0,0 +1,14 @@ +# VOWLCSSToD3RuleConverter + +This tool converts all rules from the `vowl.css` file into javascript code that can be executed to +inline the styles. This is required because otherwise the exported SVG files won't have any styles. + +This should be integrated into the build process so it won't be overlooked. + + +## How to run + +1. Run `npm install` in the root directory of this project to install the dependency which +processes the css code. +2. Run it with `node code.js` to receive the javascript code which can inline and remove the styles. +3. Insert the two code blocks into the matching functions in the `exportMenu.js` file. diff --git a/util/VowlCssToD3RuleConverter/code.js b/util/VowlCssToD3RuleConverter/code.js new file mode 100644 index 0000000000000000000000000000000000000000..b1805a64a00dbe913d3c93c1458323fd8df5b4e4 --- /dev/null +++ b/util/VowlCssToD3RuleConverter/code.js @@ -0,0 +1,96 @@ +var css = require("css"), + fs = require("fs"), + filePath = "../../src/webvowl/css/vowl.css"; + +fs.readFile(filePath, {encoding: "utf8"}, function (err, data) { + if (err) { + console.log(err); + } else { + console.log("// inline vowl styles"); + console.log(convertCssToD3Rules(data)); + console.log("\n// remove inline vowl styles"); + console.log(createInlineStyleRemoveCommand(data)); + } +}); + +function createInlineStyleRemoveCommand(cssText) { + var selectors = [], + obj = css.parse(cssText), + rules = obj.stylesheet.rules; + + rules.forEach(function (rule) { + if (rule.type === "rule") { + selectors = selectors.concat(rule.selectors); + } + }); + + return "d3.selectAll(\"".concat(selectors.join(", "), "\")"); +} + +function convertCssToD3Rules(cssText) { + var d3Rules = "", + obj = css.parse(cssText), + rules = obj.stylesheet.rules; + + + rules.forEach(function (rule) { + if (rule.type === "rule") { + var builder = d3RuleBuilder(), + selectors = rule.selectors, + declarations = rule.declarations, + declaration; + + builder.selectors(selectors); + for (var i = 0, l = declarations.length; i < l; i++) { + declaration = declarations[i]; + if (declaration.type === "declaration") { + builder.addRule(declaration.property, declaration.value); + } + } + + d3Rules = d3Rules.concat(builder.build(), "\n"); + } + }); + + return d3Rules; +} + +function d3RuleBuilder() { + var builder = {}, + selector = "", + rules = []; + + builder.selectors = function (selectors) { + if (!arguments.length) return selector; + + if (selectors instanceof Array) { + selector = selectors.join(", "); + } else { + selector = selectors; + } + + return builder; + }; + + builder.addRule = function (name, value) { + rules.push({name: name, value: value}); + return builder; + }; + + builder.build = function () { + var result = "setStyleSensitively(\"" + selector + "\", ["; + + for (var i = 0, l = rules.length; i < l; i++) { + if (i > 0) { + result = result.concat(", "); + } + var rule = rules[i]; + result = result.concat("{name:\"", rule.name, "\", value:\"", rule.value, "\"}"); + } + result = result.concat("]);"); + + return result; + }; + + return builder; +} diff --git a/util/VowlCssToD3RuleConverter/package.json b/util/VowlCssToD3RuleConverter/package.json new file mode 100644 index 0000000000000000000000000000000000000000..bc134b5445a866f879a9c4a315f940c41487c17c --- /dev/null +++ b/util/VowlCssToD3RuleConverter/package.json @@ -0,0 +1,12 @@ +{ + "private": true, + "name": "VowlCssToD3RuleConverter", + "version": "0.0.0", + "description": "", + "main": "code.js", + "author": "Vincent Link", + "license": "MIT", + "dependencies": { + "css": "^2.1.0" + } +} diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000000000000000000000000000000000000..f9e90ee950d9a8359cad72af4552176caaa2346b --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,37 @@ +var path = require("path"); +var webpack = require("webpack"); +var CopyWebpackPlugin = require("copy-webpack-plugin"); +var ExtractTextPlugin = require("extract-text-webpack-plugin"); + +module.exports = { + cache: true, + entry: { + webvowl: "./src/webvowl/js/entry.js", + "webvowl.app": "./src/app/js/entry.js" + }, + output: { + path: path.join(__dirname, "deploy/"), + publicPath: "", + filename: "js/[name].js", + chunkFilename: "js/[chunkhash].js", + libraryTarget: "assign", + library: "[name]" + }, + module: { + loaders: [ + {test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader")} + ] + }, + plugins: [ + new CopyWebpackPlugin([ + {context: "src/app", from: "data/**/*"} + ]), + new ExtractTextPlugin("css/[name].css"), + new webpack.ProvidePlugin({ + d3: "d3" + }) + ], + externals: { + "d3": "d3" + } +};