├── LICENSE ├── R-logo.png ├── README.md ├── bower.json ├── build.sh ├── dist ├── img │ ├── ajax-loader-big.gif │ ├── ajax-loader.gif │ ├── blank.gif │ ├── flags.png │ ├── hint.svg │ ├── hint1.png │ ├── hint2.png │ ├── hint3.png │ ├── poster.jpg │ └── transparent.gif ├── squebi.css ├── squebi.js └── template │ ├── basic.html │ ├── browse.html │ ├── data.html │ ├── image.html │ ├── media.html │ ├── pie.html │ └── rdfdot.html ├── index.html ├── main.js ├── pom.xml ├── r.js └── squebi ├── css ├── code.scss ├── flags.css ├── main.css ├── style.css ├── style.css.map └── style.scss ├── img ├── ajax-loader-big.gif ├── ajax-loader.gif ├── blank.gif ├── flags.png ├── hint.svg ├── hint1.png ├── hint2.png ├── hint3.png ├── poster.jpg └── transparent.gif ├── js ├── squebi.js └── writer │ ├── squebi.browse.js │ ├── squebi.csv.js │ ├── squebi.image.js │ ├── squebi.json.js │ ├── squebi.media.js │ ├── squebi.pie.js │ ├── squebi.rdfdot.js │ └── squebi.xml.js └── template ├── basic.html ├── browse.html ├── data.html ├── image.html ├── media.html ├── pie.html └── rdfdot.html /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /R-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/R-logo.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Squebi 2 | ====== 3 | 4 | Squebi is a SPARQL editor and SPARQL result visualizer with some nice features: 5 | 6 | * customization of SPARQL result visualization 7 | * support for SPARQL 1.1 (update and select) 8 | * bookmarkable uris that define queries and the visualization type 9 | * support for SPARQL query editing (URIs, ontologies and prefixes) 10 | * fast backend switch (quite useful for demo) 11 | * nice GUI 12 | 13 | Squebi is in use in the following projects and products: 14 | 15 | * [Apache Marmotta](http://marmotta.apache.org) 16 | * [Redlink Dashboard](http://redlink.co) 17 | * [MICO - Media in Context](http://mico-project.eu) 18 | * [Salzburgerland Data Hub](http://data.salzburgerland.com/dataset/events) 19 | 20 | Installation 21 | ------------ 22 | 23 | Squeby uses [bower](http://bower.io/) for dependency management. To get all dependencies, execute `bower install`. 24 | The current version is v1.0.1. 25 | 26 | Configuration 27 | ------------- 28 | 29 | For configuration set your SPARQL endpoints (and additional parameters) by script and include it before the requirejs. 30 | 31 | ### selectService : String (required) 32 | The URI of the SPARQL select webservice (used via POST). 33 | 34 | ### updateService : String (required) 35 | The URI of the SPARQL update webservice (used via POST). 36 | 37 | ### configurable : Boolean 38 | If squebi allows dynamic changes of SPARQL endpoints. 39 | 40 | **default: false** 41 | 42 | ### automaticQuery : Boolean 43 | If squebi automatically sends the current query after the page is loaded. 44 | 45 | **default: true** 46 | 47 | ### queryParams : Object 48 | Additional query parameters as property:'value' pairs. 49 | 50 | ### updateAllowed : Boolean 51 | If UI allows SPARQL update queries. 52 | 53 | **default: true** 54 | 55 | ### namespaces : Object 56 | Namespace prefixes as path:'prefix' pairs. Als prefixes that are not defined here will be looked up on prefix.cc. 57 | 58 | ### container : String 59 | The identifier (#id or .class) for the container that should be used for the application. 60 | 61 | **default: '#squebi'** 62 | 63 | ### appLoader : String 64 | The identifier (#id or .class) for the container that is shown before the app is loaded completely. This container is hided on app startup complete. 65 | 66 | **default: '#appLoader'** 67 | 68 | ### app : String 69 | The uri of the squebi app. 70 | 71 | **default: '.'** 72 | 73 | ### bower : String 74 | The uri of the bower dependencies. 75 | 76 | **default: 'bower_components'** 77 | 78 | ### responseMessage : Object 79 | Custom response messages based on http response as 'number':'message' pairs. If no response message is defined, the server response is used for display. 80 | 81 | ### samples : List 82 | A List if sample objects with properties 'name' (what is displayd), 'query', and 'type' (the id of the writer). 83 | 84 | ## writers : List 85 | A list that includes the ids of the writers which are enabled. 86 | 87 | ## Sample Configuration 88 | 89 | ```javascript 90 | SQUEBI = { 91 | selectService : "https://api.redlink.io/1.0-BETA/data/example/sparql/select", 92 | updateService : "https://api.redlink.io/1.0-BETA/data/example/sparql/update", 93 | queryParams : { 94 | key : "mykeyasadditionalqueryparameter" 95 | } 96 | }; 97 | ``` 98 | 99 | ## Use Squebi as Webjar 100 | You can use squebi in version 1.0.1 as webjar, too. The webjar is hosted on Maven Central. Put this dependencies to your pom 101 | 102 | ```xml 103 | 104 | com.github.tkurz.webjars 105 | squebi 106 | 1.0.1 107 | 108 | ``` 109 | 110 | Important: If you want to build your own webjar, please download the required bower dependencies first into the folder `bower_components`. 111 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Squebi", 3 | "version": "1.0.4-SNAPSHOT", 4 | "main": ["main.js"], 5 | "dependencies": { 6 | "requirejs":"2.1.11", 7 | "requirejs-plugins": "1.0.2", 8 | "jquery": "2.1.0", 9 | "angular": "1.2.14", 10 | "bootstrap":"3.1.1", 11 | "codemirror":"3.19", 12 | "angular-ui-codemirror": "0.1.0", 13 | "angular-bootstrap":"0.9.0", 14 | "require-css":"0.1.2", 15 | "angular-local-storage":"0.0.1" 16 | }, 17 | "ignore": [ 18 | "pom.xml", 19 | "R-logo.png", 20 | "bower_components", 21 | "target", 22 | ".gitignore" 23 | ] 24 | 25 | } -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo Deleting old dist 3 | rm -R dist 4 | 5 | echo Merge css files into dist/squebi.css 6 | node r.js -o optimizeCss=standard.keepLines.keepWhitespace cssIn=squebi/css/main.css out=squebi.css 7 | 8 | echo Merge and uglify javascript files into squebi.js 9 | node r.js -o baseUrl=. mainConfigFile=main.js name=main out=squebi.js optimize=none 10 | 11 | #echo Move to dist 12 | mkdir dist 13 | mv squebi.js dist/squebi.js 14 | mv squebi.css dist/squebi.css 15 | cp -R squebi/template dist/template 16 | cp -R squebi/img dist/img 17 | -------------------------------------------------------------------------------- /dist/img/ajax-loader-big.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/dist/img/ajax-loader-big.gif -------------------------------------------------------------------------------- /dist/img/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/dist/img/ajax-loader.gif -------------------------------------------------------------------------------- /dist/img/blank.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/dist/img/blank.gif -------------------------------------------------------------------------------- /dist/img/flags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/dist/img/flags.png -------------------------------------------------------------------------------- /dist/img/hint.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 20 | 27 | 32 | 33 | 34 | 52 | 54 | 55 | 57 | image/svg+xml 58 | 60 | 61 | 62 | 63 | 64 | 68 | Insert your queryhere. Use automaticprefix substitution 94 | 102 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /dist/img/hint1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/dist/img/hint1.png -------------------------------------------------------------------------------- /dist/img/hint2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/dist/img/hint2.png -------------------------------------------------------------------------------- /dist/img/hint3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/dist/img/hint3.png -------------------------------------------------------------------------------- /dist/img/poster.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/dist/img/poster.jpg -------------------------------------------------------------------------------- /dist/img/transparent.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/dist/img/transparent.gif -------------------------------------------------------------------------------- /dist/template/basic.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/template/browse.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
Rows {{firstItem}} to {{lastItem}} of overall {{resultSize}}
4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 23 | 24 |
{{header}}
12 |
13 | {{getDisplayName(binding[name].value)}} 14 | 15 |
16 | {{binding[name].value}} 17 | 18 | @{{binding[name]['xml:lang']}} 19 | ^^{{getDatatypeForBinding(binding[name])}} 20 | 21 | _:{{binding[name].value}} 22 |
25 |
No results
26 |
27 | 28 |
Rows {{firstItem}} to {{lastItem}} of overall {{resultSize}}
29 | 30 |
31 | 32 | -------------------------------------------------------------------------------- /dist/template/data.html: -------------------------------------------------------------------------------- 1 | Download 2 |
{{data}}
-------------------------------------------------------------------------------- /dist/template/image.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
No results
-------------------------------------------------------------------------------- /dist/template/media.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | No results. 4 |
5 |
6 | 7 |
8 |
Start: {{item.fragment.t.start}}s End: {{item.fragment.t.end}}s
9 |
Region: {{item.fragment.xywh.x}}%, {{item.fragment.xywh.y}}%, {{item.fragment.xywh.w}}%, {{item.fragment.xywh.h}}%
10 |
11 |
12 |
13 |
14 | 15 |
16 |
17 | 18 | 19 |
-------------------------------------------------------------------------------- /dist/template/pie.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /dist/template/rdfdot.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | created with rdf.dot 4 |
-------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | 33 | 38 | 39 | 47 | 48 | 49 |
50 | 51 |
52 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "paths": { 3 | //"async" : "bower_components/requirejs-plugins/src/async", 4 | //"propertyParser" : "bower_components/requirejs-plugins/src/propertyParser", 5 | //goog : "bower_components/requirejs-plugins/src/goog", 6 | "jquery" : "bower_components/jquery/dist/jquery.min", 7 | "angular" : "bower_components/angular/angular.min", 8 | "angularLocalStorage" : "bower_components/angular-local-storage/angular-local-storage.min", 9 | "_bootstrap" : "bower_components/bootstrap/dist/js/bootstrap.min", 10 | "bootstrapUI" : "bower_components/angular-bootstrap/ui-bootstrap.min", 11 | "uiBootstrapTpls": "bower_components/angular-bootstrap/ui-bootstrap-tpls.min", 12 | "_codemirror" : "bower_components/codemirror/lib/codemirror", 13 | "codemirrorSparql" : "bower_components/codemirror/mode/sparql/sparql", 14 | "codemirrorUI" : "bower_components/angular-ui-codemirror/ui-codemirror.min", 15 | "codemirrorHint" : "bower_components/codemirror/addon/hint/show-hint", 16 | "_squebi" : "squebi/js/squebi", 17 | "squebiBrowse" : "squebi/js/writer/squebi.browse", 18 | "squebiJson" : "squebi/js/writer/squebi.json", 19 | "squebiXml" : "squebi/js/writer/squebi.xml", 20 | "squebiCsv" : "squebi/js/writer/squebi.csv", 21 | //"squebiPie": "squebi/js/writer/squebi.pie", 22 | "squebiRdfdot": "squebi/js/writer/squebi.rdfdot", 23 | "squebiImage": "squebi/js/writer/squebi.image" 24 | //"squebiMedia" : "squebi/js/writer/squebi.media" 25 | //rdfstoreJs: "bower_components/rdfstore-js/dist/browser/rdf_store" 26 | }, 27 | "shim": { 28 | //'goog': ['async','propertyParser'], 29 | 'angular' : ['jquery'], 30 | '_bootstrap' : ['jquery'], 31 | 'bootstrapUI' : ['angular','_bootstrap'], 32 | 'angularLocalStorage' : ['angular'], 33 | 'uiBootstrapTpls' : ['bootstrapUI'], 34 | 'codemirrorSparql' : ['_codemirror'], 35 | 'codemirrorUI' : ['_codemirror','bootstrapUI'], 36 | 'codemirrorHint' : ['_codemirror'], 37 | '_squebi' : ['codemirrorHint','codemirrorUI','codemirrorSparql','bootstrapUI','uiBootstrapTpls','angularLocalStorage'],//,'rdfstoreJs' 38 | 'squebiBrowse' : ['_squebi'], 39 | 'squebiJson' : ['_squebi'], 40 | 'squebiXml' : ['_squebi'], 41 | 'squebiCsv' : ['_squebi'], 42 | 'squebiRdfdot' : ['_squebi'], 43 | 'squebiImage' : ['_squebi'] 44 | //'squebiPie' : ['_squebi'], 45 | //'squebiMedia' : ['_squebi'] 46 | } 47 | }); 48 | 49 | require([ 50 | "squebiBrowse", 51 | "squebiJson", 52 | "squebiXml", 53 | "squebiCsv", 54 | "squebiRdfdot", 55 | "squebiImage" 56 | //"squebiMedia" 57 | //'goog!visualization,1,packages:[corechart]', 58 | //"squebiPie" 59 | ], function() { 60 | 61 | angular.element(document).ready(function() { 62 | 63 | var SQUEBI = window.SQUEBI != undefined ? window.SQUEBI : {}; 64 | 65 | SQUEBI.home = SQUEBI.home || "squebi"; 66 | SQUEBI.container = SQUEBI.container || "#squebi"; 67 | SQUEBI.appLoader = SQUEBI.appLoader || "#appLoader"; 68 | 69 | var defaultConfig = { 70 | "configurable" : false, 71 | "selectService": "http://example.org/sparql/select", 72 | "updateService": "http://example.org/sparql/update", 73 | "automaticQuery": true, 74 | "pageSize":10, 75 | "samples": [ 76 | {"name":"Select first 20 triples", "value":"SELECT * WHERE {\n ?subject ?property ?object\n} LIMIT 20","type":"browse"}, 77 | {"name":"List types", "value":"SELECT DISTINCT ?type WHERE {\n [] a ?type\n}\nORDER BY ?type\nLIMIT 20","type":"browse"}, 78 | {"name":"List properties", "value":"SELECT DISTINCT ?property WHERE {\n [] ?property []\n}\nORDER BY ?property\nLIMIT 20","type":"browse"}, 79 | //{"name":"List classes and count their usage as pie chart", "value":"SELECT ?class (COUNT (?s) AS ?count) WHERE {\n ?s a ?class\n}\nGROUP BY ?class\nORDER BY DESC(?count)","type":"piechart"}, 80 | {"name":"Draw a graph from data", "value":"CONSTRUCT {?a ?b ?c} WHERE {?a ?b ?c} LIMIT 5", "type":"rdfdot"}, 81 | //{"name":"Show me the video fragments where T. Gilkz shows a Backflip after a Backflip Heelclicker", "value":"PREFIX mm: \nPREFIX ma: \nPREFIX dct: \n\nSELECT (mm:boundingBox(?l3,?l2) AS ?result) WHERE {\n\t?f1 ma:locator ?l1; dct:subject .\n\t?f2 ma:locator ?l2; dct:subject .\n\t?f3 ma:locator ?l3; dct:subject .\n\n\tFILTER mm:temporalContains(?l1,?l2)\n\tFILTER mm:temporalContains(?l1,?l3)\nFILTER mm:after(?l2,?l3)} LIMIT 10", "type":"media"}, 82 | //{"name":"Show me a fragment that shows Connor Macfarlane", "value":'PREFIX foaf: \nPREFIX ma: \nPREFIX dct: \n\nSELECT ?l2 WHERE {\n\t?f2 ma:locator ?l2; dct:subject ?p2.\n\t?p2 foaf:name "Connor Macfarlane".\n}', "type":"media"}, 83 | //{"name":"Show me the tempo-regional fragments where Lewis Jones is right beside Connor Macfarlane", "value":'PREFIX foaf: \nPREFIX mm: \nPREFIX ma: \nPREFIX dct: \n\nSELECT (mm:boundingBox(?l1,?l2) AS ?left_right) WHERE {\n\t?f1 ma:locator ?l1; dct:subject ?p1.\n\t?p1 foaf:name "Lewis Jones".\n\t?f2 ma:locator ?l2; dct:subject ?p2.\n\t?p2 foaf:name "Connor Macfarlane".\n\n\tFILTER mm:rightBeside(?l1,?l2)\n\tFILTER mm:temporalOverlaps(?l1,?l2)\n}', "type":"media"}, 84 | {"name":"Insert a new book to the bookstore","value":"PREFIX dc: \nINSERT DATA {\n dc:title \"Faust I\"@de ;\n a ;\n dc:creator .\n}"}, 85 | {"name":"List all books","value":"SELECT ?book WHERE {?book a }","type":"browse"} 86 | ], 87 | "hints": [ 88 | {"container":"samples","content":"","position":2,"dimension":{"width":100,"height":100},"css":"margin-top:-5px;margin-left:-10px"}, 89 | {"container":"query-container","content":"","dimension":{"width":100,"height":100},"css":"margin-top:120px;margin-left:-210px"}, 90 | {"container":"writers","content":"","dimension":{"width":100,"height":100},"css":"margin-top:-30px;margin-left:-400px","position":2} 91 | ], 92 | "namespaces": { 93 | "http://www.w3.org/2000/01/rdf-schema#":"rdfs", 94 | "http://www.w3.org/1999/02/22-rdf-syntax-ns#":"rdf", 95 | "http://www.w3.org/2004/02/skos/core#":"skos", 96 | "http://xmlns.com/foaf/0.1/":"foaf", 97 | "http://purl.org/dc/terms/":"dct", 98 | "http://www.w3.org/ns/ma-ont#":"ma", 99 | "http://purl.org/dc/elements/1.1/":"dc", 100 | "http://www.w3.org/2001/XMLSchema#":"xsd" 101 | }, 102 | "updateAllowed": true, 103 | "responseMessage": { 104 | "404": "The service was not found or requires payment. Check your path and key in configuration.", 105 | "500": "The query did not work. Maybe you little SPARQL mistake... :)" 106 | }, 107 | "writers":["browse","xml","json","csv","rdfdot","image"], 108 | "downloadEnabled":true, 109 | "outputQueryParam":"out" 110 | }; 111 | 112 | jQuery.extend(defaultConfig, SQUEBI); 113 | jQuery(SQUEBI.appLoader).hide(); 114 | jQuery(SQUEBI.container).show(); 115 | squebi.constant('SQUEBI', defaultConfig); 116 | angular.bootstrap(SQUEBI.container, ['Squebi']); 117 | 118 | }); 119 | }); -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.sonatype.oss 7 | oss-parent 8 | 7 9 | 10 | 11 | jar 12 | com.github.tkurz.webjars 13 | squebi 14 | 1.0.4-SNAPSHOT 15 | squebi 16 | WebJar for Squebi 17 | https://github.com/tkurz/squebi 18 | 19 | 20 | 21 | tkurz 22 | Thomas Kurz 23 | th.kurz@gmail.com 24 | 25 | 26 | 27 | 28 | 29 | Apache Version 2.0 30 | http://www.apache.org/licenses/LICENSE-2.0 31 | repo 32 | 33 | 34 | 35 | 36 | https://github.com/tkurz/squebi.git 37 | scm:git:git@github.com:tkurz/squebi.git 38 | scm:git:git@github.com:tkurz/squebi.git 39 | HEAD 40 | 41 | 42 | 43 | UTF-8 44 | ${project.build.outputDirectory}/META-INF/resources/webjars/${project.artifactId}/${project.version} 45 | 46 | 47 | 48 | 49 | 50 | 51 | org.apache.maven.plugins 52 | maven-release-plugin 53 | 2.5 54 | 55 | 56 | 57 | 58 | 59 | ${project.basedir}/dist 60 | ${destDir} 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /squebi/css/code.scss: -------------------------------------------------------------------------------- 1 | /* CODE MIRROR */ 2 | .CodeMirror { 3 | height: auto; 4 | margin: 0 auto; 5 | text-align: left; 6 | line-height: 18px; 7 | } 8 | 9 | .cm-s-mdn-like.CodeMirror { 10 | color: $color6; 11 | } 12 | 13 | .cm-s-sparql-mm .cm-keyword { 14 | color: $color1; 15 | } 16 | 17 | .cm-s-sparql-mm .CodeMirror-gutters { 18 | border-left: 0; 19 | } 20 | 21 | .cm-s-mdn-like .CodeMirror-selected { 22 | background: $color3 !important; 23 | opacity: 0.15; 24 | } 25 | 26 | .cm-s-sparql-mm .cm-atom { 27 | color: $color6; 28 | } 29 | 30 | .cm-s-mdn-like .cm-variable { 31 | color: $color10; 32 | } 33 | 34 | .cm-s-mdn-like span.cm-variable-2, .cm-s-mdn-like span.cm-tag { 35 | color: $color3; 36 | } 37 | 38 | .CodeMirror-wrap .CodeMirror-scroll { 39 | overflow-y: hidden; 40 | overflow-x: auto; 41 | height: auto; 42 | min-height: 150px; 43 | } 44 | 45 | .cm-s-mdn-like .CodeMirror-linenumber { 46 | margin-left: -5px; 47 | } 48 | 49 | .CodeMirror-hint { 50 | background: $color9; 51 | max-width: 1000px; 52 | padding: 2px 10px; 53 | } 54 | 55 | .CodeMirror-hint-active { 56 | background: $color1; 57 | } -------------------------------------------------------------------------------- /squebi/css/main.css: -------------------------------------------------------------------------------- 1 | @import url("flags.css"); 2 | @import url("../../bower_components/bootstrap/dist/css/bootstrap.css"); 3 | @import url("../../bower_components/codemirror/lib/codemirror.css"); 4 | @import url("../../bower_components/codemirror/theme/neat.css"); 5 | @import url("../../bower_components/codemirror/addon/hint/show-hint.css"); 6 | @import url("style.css"); -------------------------------------------------------------------------------- /squebi/css/style.css: -------------------------------------------------------------------------------- 1 | /* SCSS */ 2 | body { 3 | font: 14px Helvetica, sans-serif; 4 | color: #666; 5 | padding-bottom: 20px; } 6 | 7 | /* Everything but the jumbotron gets side spacing for mobile first views */ 8 | .header, 9 | .marketing, 10 | .footer { 11 | padding-right: 15px; 12 | padding-left: 15px; } 13 | 14 | /* Make the masthead heading the same height as the navigation */ 15 | .header h3 { 16 | padding-bottom: 0; 17 | margin-top: 0; 18 | margin-bottom: 0; 19 | line-height: 40px; 20 | color: #0A82C7; 21 | font-size: 26px; } 22 | 23 | .header a { 24 | color: #666666; } 25 | 26 | .header li a:hover { 27 | color: #666; } 28 | 29 | .header h4 { 30 | margin: 0; 31 | font-size: 14px; 32 | color: #666; 33 | font-weight: normal; } 34 | 35 | /* Custom page footer */ 36 | .footer { 37 | padding-top: 19px; 38 | color: color1; 39 | border-top: 1px solid #666; } 40 | 41 | /* Customize container */ 42 | @media (min-width: 868px) { 43 | .container { 44 | max-width: 830px; } 45 | .container .jumbotron { 46 | padding: 24px 34px; 47 | text-align: center; 48 | border-bottom: 1px solid #e5e5e5; 49 | -moz-box-shadow: 3px 3px 10px 1px #aaa; 50 | -webkit-box-shadow: 3px 3px 10px 1px #aaa; 51 | box-shadow: 3px 3px 10px 1px #aaa; } 52 | .container .btn-run { 53 | margin-top: 20px; 54 | padding: 10px 20px; 55 | font-size: 21px; } } 56 | .container-narrow > hr { 57 | margin: 30px 0; } 58 | 59 | /* Supporting marketing content */ 60 | .result { 61 | margin: 40px 0; } 62 | 63 | li.menuitem a { 64 | cursor: pointer; } 65 | li.menuitem a ul > li > a { 66 | cursor: pointer; } 67 | 68 | /* Responsive: Portrait tablets and up */ 69 | @media screen and (min-width: 868px) { 70 | /* Remove the padding we set earlier */ 71 | .header, 72 | .result, 73 | .footer { 74 | padding-right: 0; 75 | padding-left: 0; } 76 | 77 | /* Space out the masthead */ 78 | .header { 79 | margin-bottom: 30px; } 80 | 81 | /* Remove the bottom border on the jumbotron for visual effect */ 82 | .jumbotron { 83 | border-bottom: 0; } } 84 | #query-container { 85 | border: 1px solid #aaa; 86 | -webkit-border-radius: 10px; 87 | -moz-border-radius: 10px; 88 | -ms-border-radius: 10px; 89 | -o-border-radius: 10px; 90 | border-radius: 10px; 91 | height: auto; 92 | width: 100%; 93 | overflow: hidden; } 94 | 95 | .dropdown-menu > li > a, .dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus { 96 | color: #666; } 97 | 98 | .alert h2 { 99 | margin: 0 0 10px 0; 100 | font-size: 20px; } 101 | 102 | .uri { 103 | color: #F2940A; 104 | cursor: pointer; 105 | text-decoration: underline; } 106 | 107 | .bnode { 108 | color: #47a447; } 109 | 110 | .browser-header { 111 | color: #2B2B2B; } 112 | 113 | .download-button { 114 | position: absolute; 115 | margin-top: 5px !important; 116 | margin-left: 710px; 117 | font-size: 14px !important; 118 | padding: 10px !important; } 119 | 120 | .loader { 121 | text-align: center; } 122 | 123 | .external-link { 124 | margin-left: 2px; 125 | color: #666; 126 | font-size: 12px; } 127 | 128 | .video { 129 | width: 900; } 130 | 131 | .video-item { 132 | width: 270px; 133 | height: 200px; 134 | padding: 10px; 135 | float: left; 136 | position: relative; } 137 | 138 | .video-item video { 139 | width: 100%; 140 | cursor: pointer; } 141 | 142 | .video-overlay { 143 | padding: 3px; 144 | position: relative; 145 | background-color: #2B2B2B; 146 | color: white; } 147 | 148 | .video-single-back { 149 | position: fixed; 150 | width: 100%; 151 | height: 100%; 152 | background-color: black; 153 | top: 0; 154 | left: 0; 155 | z-index: 100; 156 | opacity: 0.9; } 157 | 158 | .video-single { 159 | position: fixed; 160 | width: 600px; 161 | top: 100px; 162 | left: 50%; 163 | margin-left: -300px; 164 | z-index: 101; 165 | border: 1px solid #e5e5e5; 166 | -moz-box-shadow: 0 0 15px 1px #e5e5e5; 167 | -webkit-box-shadow: 0 0 15px 1px #e5e5e5; 168 | box-shadow: 0 0 15px 1px #e5e5e5; 169 | -webkit-border-radius: 5px; 170 | -moz-border-radius: 5px; 171 | -ms-border-radius: 5px; 172 | -o-border-radius: 5px; 173 | border-radius: 5px; } 174 | 175 | .video-single video { 176 | width: 100%; } 177 | 178 | .video-closer { 179 | color: white; 180 | position: fixed; 181 | top: 70px; 182 | left: 50%; 183 | margin-left: 310px; 184 | width: 20px; 185 | height: 20px; 186 | z-index: 102; 187 | font-size: 30px; 188 | cursor: pointer; } 189 | 190 | .region-overlay { 191 | position: fixed; 192 | z-index: 102; 193 | left: 50%; 194 | border: 3px double #A9FF00; 195 | -moz-box-shadow: 0 0 15px 1px #e5e5e5; 196 | -webkit-box-shadow: 0 0 15px 1px #e5e5e5; 197 | box-shadow: 0 0 15px 1px #e5e5e5; } 198 | 199 | .hint-overlay { 200 | top: 0; 201 | left: 0; 202 | position: fixed; 203 | width: 100%; 204 | height: 100%; 205 | z-index: 1000; } 206 | 207 | .hint { 208 | position: absolute; 209 | z-index: 999; } 210 | 211 | .literal .lang { 212 | color: #0A82C7; } 213 | 214 | .literal .type { 215 | color: #40b5c7; } 216 | 217 | .modal-table { 218 | width: 100%; } 219 | 220 | .modal-table tr td:first-child { 221 | width: 160px; 222 | font-weight: bold; } 223 | 224 | .modal-table tr td { 225 | padding-bottom: 5px; 226 | vertical-align: top; } 227 | 228 | .modal-table input { 229 | width: 100%; } 230 | 231 | .modal-body h3 { 232 | color: #0A82C7; 233 | font-weight: bold; } 234 | 235 | .video { 236 | width: 900; } 237 | 238 | .video-item { 239 | width: 270px; 240 | height: 200px; 241 | padding: 10px; 242 | float: left; 243 | position: relative; } 244 | 245 | .video-item video { 246 | width: 100%; 247 | cursor: pointer; } 248 | 249 | .video-overlay { 250 | padding: 3px; 251 | position: relative; 252 | background-color: #2b2b2b; 253 | color: white; } 254 | 255 | .video-single-back { 256 | position: fixed; 257 | width: 100%; 258 | height: 100%; 259 | background-color: black; 260 | top: 0; 261 | left: 0; 262 | z-index: 100; 263 | opacity: 0.9; } 264 | 265 | .video-single { 266 | position: fixed; 267 | width: 600px; 268 | top: 100px; 269 | left: 50%; 270 | margin-left: -300px; 271 | z-index: 101; 272 | border: 1px solid #e5e5e5; 273 | -moz-box-shadow: 0 0 15px 1px #e5e5e5; 274 | -webkit-box-shadow: 0 0 15px 1px #e5e5e5; 275 | box-shadow: 0 0 15px 1px #e5e5e5; 276 | -webkit-border-radius: 5px; 277 | -moz-border-radius: 5px; 278 | -ms-border-radius: 5px; 279 | -o-border-radius: 5px; 280 | border-radius: 5px; } 281 | 282 | .video-single video { 283 | width: 100%; } 284 | 285 | .video-closer { 286 | color: white; 287 | position: fixed; 288 | top: 70px; 289 | left: 50%; 290 | margin-left: 310px; 291 | width: 20px; 292 | height: 20px; 293 | z-index: 102; 294 | font-size: 30px; 295 | cursor: pointer; } 296 | 297 | .region-overlay { 298 | position: fixed; 299 | z-index: 102; 300 | left: 50%; 301 | border: 3px double #A9FF00; 302 | -moz-box-shadow: 0 0 15px 1px #e5e5e5; 303 | -webkit-box-shadow: 0 0 15px 1px #e5e5e5; 304 | box-shadow: 0 0 15px 1px #e5e5e5; } 305 | 306 | .table-browse { 307 | background-color: white; } 308 | 309 | .paging { 310 | text-align: center; 311 | margin-bottom: 20px; } 312 | 313 | .paging div { 314 | display: inline; 315 | margin: 5px 30px; 316 | font-size: 18px; } 317 | 318 | /* CODE MIRROR */ 319 | .CodeMirror { 320 | height: auto; 321 | margin: 0 auto; 322 | text-align: left; 323 | line-height: 18px; } 324 | 325 | .cm-s-mdn-like.CodeMirror { 326 | color: #666; } 327 | 328 | .cm-s-sparql-mm .cm-keyword { 329 | color: #F2940A; } 330 | 331 | .cm-s-sparql-mm .CodeMirror-gutters { 332 | border-left: 0; } 333 | 334 | .cm-s-mdn-like .CodeMirror-selected { 335 | background: #0A82C7 !important; 336 | opacity: 0.15; } 337 | 338 | .cm-s-sparql-mm .cm-atom { 339 | color: #666; } 340 | 341 | .cm-s-mdn-like .cm-variable { 342 | color: #fa3300; } 343 | 344 | .cm-s-mdn-like span.cm-variable-2, .cm-s-mdn-like span.cm-tag { 345 | color: #0A82C7; } 346 | 347 | .CodeMirror-wrap .CodeMirror-scroll { 348 | overflow-y: hidden; 349 | overflow-x: auto; 350 | height: auto; 351 | min-height: 150px; } 352 | 353 | .cm-s-mdn-like .CodeMirror-linenumber { 354 | margin-left: -5px; } 355 | 356 | .CodeMirror-hint { 357 | background: white; 358 | max-width: 1000px; 359 | padding: 2px 10px; } 360 | 361 | .CodeMirror-hint-active { 362 | background: #F2940A; } 363 | 364 | /*# sourceMappingURL=style.css.map */ 365 | -------------------------------------------------------------------------------- /squebi/css/style.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "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", 4 | "sources": ["style.scss","code.scss"], 5 | "names": [], 6 | "file": "style.css" 7 | } -------------------------------------------------------------------------------- /squebi/css/style.scss: -------------------------------------------------------------------------------- 1 | /* SCSS */ 2 | $font-stack: Helvetica, sans-serif; 3 | 4 | $color1: #F2940A; 5 | $color2: #47a447; 6 | $color3: #0A82C7; 7 | $color4: #db0a40; 8 | $color5: #2B2B2B; 9 | $color6: #666; 10 | $color7: #aaa; 11 | $color8: #e5e5e5; 12 | $color9: white; 13 | $color10: #fa3300; 14 | $color11: #40b5c7; 15 | 16 | $width: 830px; 17 | 18 | @mixin border-radius($radius) { 19 | -webkit-border-radius: $radius; 20 | -moz-border-radius: $radius; 21 | -ms-border-radius: $radius; 22 | -o-border-radius: $radius; 23 | border-radius: $radius; 24 | } 25 | 26 | @mixin box-shadow($value) { 27 | -moz-box-shadow: $value; 28 | -webkit-box-shadow: $value; 29 | box-shadow: $value; 30 | } 31 | 32 | body { 33 | font: 14px $font-stack; 34 | color: $color6; 35 | padding-bottom: 20px; 36 | } 37 | 38 | /* Everything but the jumbotron gets side spacing for mobile first views */ 39 | .header, 40 | .marketing, 41 | .footer { 42 | padding-right: 15px; 43 | padding-left: 15px; 44 | } 45 | 46 | /* Make the masthead heading the same height as the navigation */ 47 | .header h3 { 48 | padding-bottom: 0; 49 | margin-top: 0; 50 | margin-bottom: 0; 51 | line-height: 40px; 52 | color: $color3; 53 | font-size: 26px; 54 | } 55 | 56 | .header a { 57 | color: #666666; } 58 | 59 | .header li a:hover { 60 | color: $color6; 61 | } 62 | 63 | .header h4 { 64 | margin: 0; 65 | font-size: 14px; 66 | color: $color6; 67 | font-weight: normal; 68 | } 69 | 70 | /* Custom page footer */ 71 | .footer { 72 | padding-top: 19px; 73 | color: color1; 74 | border-top: 1px solid $color6; 75 | } 76 | 77 | /* Customize container */ 78 | @media (min-width: $width +38) { 79 | .container { 80 | max-width: $width; 81 | .jumbotron { 82 | padding: 24px 34px; 83 | text-align: center; 84 | border-bottom: 1px solid $color8; 85 | @include box-shadow(3px 3px 10px 1px $color7); 86 | } 87 | .btn-run { 88 | margin-top: 20px; 89 | padding: 10px 20px; 90 | font-size: 21px; 91 | } 92 | } 93 | } 94 | 95 | .container-narrow > hr { 96 | margin: 30px 0; 97 | } 98 | 99 | /* Supporting marketing content */ 100 | .result { 101 | margin: 40px 0; 102 | } 103 | 104 | li.menuitem { 105 | a { 106 | cursor: pointer; 107 | ul > li > a { 108 | cursor: pointer; 109 | } 110 | } 111 | } 112 | 113 | /* Responsive: Portrait tablets and up */ 114 | @media screen and (min-width: $width + 38) { 115 | /* Remove the padding we set earlier */ 116 | .header, 117 | .result, 118 | .footer { 119 | padding-right: 0; 120 | padding-left: 0; 121 | } 122 | /* Space out the masthead */ 123 | .header { 124 | margin-bottom: 30px; 125 | } 126 | /* Remove the bottom border on the jumbotron for visual effect */ 127 | .jumbotron { 128 | border-bottom: 0; 129 | } 130 | } 131 | 132 | #query-container { 133 | border: 1px solid $color7; 134 | @include border-radius(10px); 135 | height: auto; 136 | width: 100%; 137 | overflow: hidden; 138 | } 139 | 140 | .dropdown-menu>li>a, .dropdown-menu>li>a:hover, .dropdown-menu>li>a:focus { 141 | color: $color6 142 | } 143 | 144 | .alert h2 { 145 | margin: 0 0 10px 0; 146 | font-size: 20px; 147 | } 148 | 149 | .uri { 150 | color: $color1; 151 | cursor: pointer; 152 | text-decoration: underline; 153 | } 154 | 155 | .bnode { 156 | color: $color2; 157 | } 158 | 159 | .browser-header { 160 | color: $color5; 161 | } 162 | 163 | .download-button { 164 | position: absolute; 165 | margin-top: 5px !important; 166 | margin-left: $width - 120; 167 | font-size: 14px !important; 168 | padding: 10px !important; 169 | } 170 | 171 | .loader { 172 | text-align: center; 173 | } 174 | 175 | .external-link { 176 | margin-left: 2px; 177 | color: $color6; 178 | font-size: 12px; 179 | } 180 | 181 | .video { 182 | width: 900; 183 | } 184 | 185 | .video-item { 186 | width: ($width - 20)/3; 187 | height: 200px; 188 | padding: 10px; 189 | float: left; 190 | position: relative; 191 | } 192 | 193 | .video-item video { 194 | width: 100%; 195 | cursor: pointer; 196 | } 197 | 198 | .video-overlay { 199 | padding: 3px; 200 | position: relative; 201 | background-color: $color5; 202 | color:white; 203 | } 204 | 205 | .video-single-back { 206 | position: fixed; 207 | width: 100%; 208 | height: 100%; 209 | background-color: black; 210 | top: 0; 211 | left: 0; 212 | z-index: 100; 213 | opacity: 0.9; 214 | } 215 | 216 | .video-single { 217 | position: fixed; 218 | width: 600px; 219 | top: 100px; 220 | left: 50%; 221 | margin-left: -300px; 222 | z-index: 101; 223 | border: 1px solid $color8; 224 | @include box-shadow(0 0 15px 1px $color8); 225 | @include border-radius(5px); 226 | } 227 | 228 | .video-single video { 229 | width: 100%; 230 | } 231 | 232 | .video-closer { 233 | color: $color9; 234 | position: fixed; 235 | top: 70px; 236 | left: 50%; 237 | margin-left: 310px; 238 | width: 20px; 239 | height: 20px; 240 | z-index: 102; 241 | font-size: 30px; 242 | cursor: pointer; 243 | } 244 | 245 | .region-overlay { 246 | position: fixed; 247 | z-index: 102; 248 | left: 50%; 249 | border: 3px double #A9FF00; 250 | @include box-shadow(0 0 15px 1px $color8); 251 | } 252 | 253 | .hint-overlay { 254 | top: 0; 255 | left: 0; 256 | position: fixed; 257 | width: 100%; 258 | height: 100%; 259 | z-index: 1000; 260 | } 261 | 262 | .hint { 263 | position: absolute; 264 | z-index: 999; 265 | } 266 | 267 | .literal .lang { 268 | color: $color3; 269 | } 270 | 271 | .literal .type { 272 | color: $color11; 273 | } 274 | 275 | .modal-table { 276 | width: 100%; 277 | } 278 | 279 | .modal-table tr td:first-child { 280 | width: 160px; 281 | font-weight: bold; 282 | } 283 | 284 | .modal-table tr td { 285 | padding-bottom: 5px; 286 | vertical-align: top; 287 | } 288 | 289 | .modal-table input { 290 | width: 100%; 291 | } 292 | 293 | .modal-body h3 { 294 | color: $color3; 295 | font-weight: bold; 296 | } 297 | 298 | .video { 299 | width: 900; } 300 | 301 | .video-item { 302 | width: 270px; 303 | height: 200px; 304 | padding: 10px; 305 | float: left; 306 | position: relative; } 307 | 308 | .video-item video { 309 | width: 100%; 310 | cursor: pointer; } 311 | 312 | .video-overlay { 313 | padding: 3px; 314 | position: relative; 315 | background-color: #2b2b2b; 316 | color: white; } 317 | 318 | .video-single-back { 319 | position: fixed; 320 | width: 100%; 321 | height: 100%; 322 | background-color: black; 323 | top: 0; 324 | left: 0; 325 | z-index: 100; 326 | opacity: 0.9; } 327 | 328 | .video-single { 329 | position: fixed; 330 | width: 600px; 331 | top: 100px; 332 | left: 50%; 333 | margin-left: -300px; 334 | z-index: 101; 335 | border: 1px solid #e5e5e5; 336 | -moz-box-shadow: 0 0 15px 1px #e5e5e5; 337 | -webkit-box-shadow: 0 0 15px 1px #e5e5e5; 338 | box-shadow: 0 0 15px 1px #e5e5e5; 339 | -webkit-border-radius: 5px; 340 | -moz-border-radius: 5px; 341 | -ms-border-radius: 5px; 342 | -o-border-radius: 5px; 343 | border-radius: 5px; } 344 | 345 | .video-single video { 346 | width: 100%; } 347 | 348 | .video-closer { 349 | color: white; 350 | position: fixed; 351 | top: 70px; 352 | left: 50%; 353 | margin-left: 310px; 354 | width: 20px; 355 | height: 20px; 356 | z-index: 102; 357 | font-size: 30px; 358 | cursor: pointer; } 359 | 360 | .region-overlay { 361 | position: fixed; 362 | z-index: 102; 363 | left: 50%; 364 | border: 3px double #A9FF00; 365 | -moz-box-shadow: 0 0 15px 1px #e5e5e5; 366 | -webkit-box-shadow: 0 0 15px 1px #e5e5e5; 367 | box-shadow: 0 0 15px 1px #e5e5e5; } 368 | 369 | .table-browse { 370 | background-color: white; 371 | } 372 | 373 | .paging { 374 | text-align: center; 375 | margin-bottom: 20px; 376 | } 377 | .paging div { 378 | display: inline; 379 | margin: 5px 30px; 380 | font-size: 18px; 381 | } 382 | 383 | @import 'code'; -------------------------------------------------------------------------------- /squebi/img/ajax-loader-big.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/squebi/img/ajax-loader-big.gif -------------------------------------------------------------------------------- /squebi/img/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/squebi/img/ajax-loader.gif -------------------------------------------------------------------------------- /squebi/img/blank.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/squebi/img/blank.gif -------------------------------------------------------------------------------- /squebi/img/flags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/squebi/img/flags.png -------------------------------------------------------------------------------- /squebi/img/hint.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 20 | 27 | 32 | 33 | 34 | 52 | 54 | 55 | 57 | image/svg+xml 58 | 60 | 61 | 62 | 63 | 64 | 68 | Insert your queryhere. Use automaticprefix substitution 94 | 102 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /squebi/img/hint1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/squebi/img/hint1.png -------------------------------------------------------------------------------- /squebi/img/hint2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/squebi/img/hint2.png -------------------------------------------------------------------------------- /squebi/img/hint3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/squebi/img/hint3.png -------------------------------------------------------------------------------- /squebi/img/poster.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/squebi/img/poster.jpg -------------------------------------------------------------------------------- /squebi/img/transparent.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkurz/squebi/44efa5e31e5e93a0454be807246c42b38df33cbe/squebi/img/transparent.gif -------------------------------------------------------------------------------- /squebi/js/squebi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * the app 3 | * @type {module|*} 4 | */ 5 | var squebi = angular.module( 'Squebi',[ 6 | 'ui.codemirror', 7 | 'ui.bootstrap', 8 | 'LocalStorageModule' 9 | ]); 10 | 11 | squebi.config(['localStorageServiceProvider', '$logProvider', function(localStorageServiceProvider, $logProvider){ 12 | $logProvider.debugEnabled(false); 13 | localStorageServiceProvider.setPrefix('squebi.'); 14 | }]); 15 | 16 | /** 17 | * To register 18 | */ 19 | squebi.service("$extension", ['$rootScope','SQUEBI', function ($rootScope, SQUEBI) { 20 | 21 | var extension = { 22 | resultWriter : [] 23 | }; 24 | 25 | function ResultWriter(id,label,format,description,onsuccess,onfailure) { 26 | this.position = -1; 27 | this.id = id; 28 | this.label = label; 29 | this.description = description; 30 | this.format = format; 31 | this.onsuccess = onsuccess; 32 | this.onfailure = function($scope,data){ 33 | $rootScope.alerts.push(data); 34 | $scope.template = SQUEBI.home + '/template/basic.html'; 35 | if(onfailure) onfailure($scope,data); 36 | }; 37 | } 38 | 39 | this.createResultWriter = function(label,type,description,onsuccess,onfailure) { 40 | var resultWriter = new ResultWriter(label,type,description,onsuccess,onfailure); 41 | extension.resultWriter.push(resultWriter); 42 | return resultWriter; 43 | }; 44 | 45 | this.listResultWriters = function() { 46 | //order 47 | extension.resultWriter = extension.resultWriter.sort(function(a,b) { 48 | return a.position <= b.position ? -1 : 1; 49 | }); 50 | 51 | //filter out id they are not set 52 | var filtered = []; 53 | 54 | if(SQUEBI.writers) { 55 | for(var i = 0; i < extension.resultWriter.length; i++) { 56 | for(var j = 0; j < SQUEBI.writers.length; j++) { 57 | if(SQUEBI.writers[j] == extension.resultWriter[i].id) { 58 | filtered.push(extension.resultWriter[i]); 59 | } 60 | } 61 | } 62 | return filtered; 63 | } else return extension.resultWriter; 64 | }; 65 | 66 | this.selectResultWriter = function(writer) { 67 | $rootScope.writer = writer; 68 | }; 69 | 70 | this.selectResultWriterById = function(id) { 71 | for(var i in extension.resultWriter) { 72 | if(extension.resultWriter[i].id == id) { 73 | $rootScope.writer = extension.resultWriter[i]; 74 | break; 75 | } 76 | } //TODO should throw an exception? 77 | } 78 | 79 | }]); 80 | 81 | /** 82 | * a service for sparql endpoints 83 | */ 84 | squebi.service("$sparql", [ '$http', 'SQUEBI', function ($http, SQUEBI) { 85 | 86 | this.query = function(query, options, onsuccess, onfailure) { 87 | 88 | $http({ 89 | url: SQUEBI.selectService, 90 | method: "POST", 91 | data: query, 92 | params: SQUEBI.queryParams, 93 | headers: { 94 | 'Content-Type': 'application/sparql-query' + (document.charset ? (";charset=" + document.charset) : ""), 95 | 'Accept': options.acceptType, 96 | 'X-Auth-Token': SQUEBI.token 97 | } 98 | }) 99 | .success(function(data, status, headers, config) { 100 | onsuccess(data,status, headers, config); 101 | }). 102 | error(function(data, status, headers, config) { 103 | onfailure(data,status, headers, config); 104 | }); 105 | }; 106 | 107 | this.update = function(query, options, onsuccess, onfailure) { 108 | $http({ 109 | url: SQUEBI.updateService, 110 | method: "POST", 111 | data: query, 112 | params: SQUEBI.queryParams, 113 | headers: { 114 | 'Content-Type': 'application/sparql-update' + (document.charset ? (";charset=" + document.charset) : ""), 115 | 'X-Auth-Token': SQUEBI.token 116 | } 117 | }) 118 | .success(function(data, status, headers, config) { 119 | onsuccess(data, status, headers, config); 120 | }). 121 | error(function(data, status, headers, config) { 122 | onfailure(data, status, headers, config); 123 | }); 124 | } 125 | }]); 126 | 127 | /** 128 | * A controller to load sample queries from configuration 129 | */ 130 | squebi.controller( 'SampleCtrl', ['SQUEBI', '$rootScope', '$sparql', '$http', '$scope', '$sce', function( SQUEBI, $rootScope, $sparql, $http, $scope, $sce ) { 131 | 132 | $scope.showHint = false; 133 | $scope.configurable = SQUEBI.configurable; 134 | $scope.hint = SQUEBI.hints && SQUEBI.hints.length > 0; 135 | $scope.hints = []; 136 | 137 | function buildHint(hint) { 138 | var div = jQuery("#"+hint.container); 139 | 140 | switch(hint.position) { 141 | case 1: hint.style = "top:" + (div.offset().top - hint.dimension.height) + "px;left:" + (div.offset().left + div.width()) + ";";break; 142 | case 2: hint.style = "top:" + (div.offset().top + div.height()) + "px;left:" + (div.offset().left + div.width()) + ";";break; 143 | case 3: hint.style = "top:" + (div.offset().top + div.height()) + "px;left:" + (div.offset().left - hint.dimension.width) + ";";break; 144 | default : hint.style = "top:" + (div.offset().top - hint.dimension.height) + "px;left:" + (div.offset().left - hint.dimension.width) + ";"; 145 | } 146 | 147 | hint.style += "width:" + hint.dimension.width + "px;"; 148 | hint.style += "height:" + hint.dimension.height + "px;"; 149 | 150 | if(hint.css) hint.style += hint.css; 151 | 152 | hint.trusted_content = $sce.trustAsHtml(hint.content); 153 | 154 | return hint; 155 | } 156 | 157 | $scope.showHints = function() { 158 | 159 | $scope.hints = []; 160 | 161 | //prepare hints 162 | for(var i in SQUEBI.hints) { 163 | $scope.hints.push(buildHint(SQUEBI.hints[i])); 164 | } 165 | 166 | $scope.showHint = true; 167 | }; 168 | 169 | $scope.samples = SQUEBI.samples; 170 | 171 | $rootScope.sample = $scope.samples[0].value; 172 | 173 | $scope.selectSample = function(sample) { 174 | if(sample.type) { 175 | $rootScope.$emit('setQueryAndWriter', sample.value, sample.type); 176 | } else { 177 | $rootScope.$emit('setQuery', sample.value); 178 | } 179 | } 180 | }]); 181 | 182 | 183 | squebi.controller( 'FormatCtrl', ['SQUEBI', '$extension', '$rootScope', '$sparql', '$http', '$scope', function( SQUEBI, $extension, $rootScope, $sparql, $http, $scope ) { 184 | 185 | $scope.writers = $extension.listResultWriters(); 186 | 187 | $rootScope.writer = $rootScope.writer || $scope.writers[0]; 188 | 189 | $scope.getClass = function(writer) { 190 | if(writer == $rootScope.writer) return 'active'; 191 | }; 192 | 193 | $scope.selectWriter = function($event,writer) { 194 | $rootScope.$emit('setWriter',writer.id); 195 | $event.preventDefault(); 196 | } 197 | }]); 198 | 199 | /** 200 | * A controller that issues the query 201 | */ 202 | squebi.controller( 'QueryCtrl', [ 'SQUEBI', '$rootScope', '$sparql', '$http', '$scope', '$location', '$extension', '$log', function( SQUEBI, $rootScope, $sparql, $http, $scope, $location, $extension, $log ) { 203 | 204 | $scope.query = $rootScope.sample; 205 | 206 | $rootScope.showResults = true; 207 | 208 | var suggestRegex = new RegExp("\\s+([A-Za-z]+):([A-Za-z]+)$",'ig'); 209 | 210 | function checkSuggestion(cm) { 211 | var c = cm.getCursor(); 212 | var line = cm.getRange({'line': c.line, 'ch': 0},{'line': c.line, 'ch': c.ch}); 213 | var match = suggestRegex.exec(line); 214 | if(match) { 215 | 216 | function replace(replacement,from,to,uri,prefix) { 217 | cm.setSelection(from, cm.getCursor()); 218 | cm.replaceSelection(replacement); 219 | c.ch = c.ch + replacement.length; 220 | cm.setCursor(c); 221 | 222 | var regex = new RegExp("PREFIX\\s+" + prefix + ":\\s*<",'ig'); 223 | 224 | //if prefix is not yet defined 225 | if(!cm.getValue().match(regex)) { 226 | c.line = c.line + 1; 227 | cm.setValue("PREFIX " + prefix + ": <" + uri+">\n" + cm.getValue()); 228 | cm.setCursor(c); 229 | } 230 | } 231 | 232 | function showHint(from, to, list) { 233 | CodeMirror.showHint(cm, function(cm, self, data) { 234 | return { 235 | list: list, 236 | from: from, 237 | to: to 238 | } 239 | },{ 240 | completeSingle: false 241 | }); 242 | } 243 | 244 | //check if is in the local store 245 | var result; 246 | 247 | //check if it is in static 248 | for(var property in SQUEBI.namespaces) { 249 | if(SQUEBI.namespaces[property] == match[1]) { 250 | result = property; 251 | break; 252 | } 253 | } 254 | 255 | if(result == undefined) return; 256 | 257 | var query = result+match[2]; 258 | 259 | jQuery.ajax("http://lov.okfn.org/dataset/lov/api/v2/autocomplete/terms?q=" + encodeURIComponent(query), { 260 | async: false, 261 | dataType: "json", 262 | success: function(data) { 263 | 264 | var list = []; 265 | 266 | var from = {line: c.line, ch: c.ch - match[0].length}; 267 | var to = {line: c.line, ch: c.ch}; 268 | 269 | for(var i = 0; i < data.results.length; i++) { 270 | var r = match[1]+":"+data.results[i].localName; 271 | 272 | if(query == r) { 273 | list = []; 274 | break; 275 | } 276 | 277 | (function(r){ 278 | list.push({ 279 | text: r, 280 | hint: function() { 281 | replace(" "+r+" ",from, to, result,match[1]); 282 | } 283 | }); 284 | }(r)) 285 | } 286 | 287 | showHint(from, to, list); 288 | } 289 | }); 290 | } 291 | } 292 | 293 | /** 294 | * Autocompletion using prefix.cc 295 | * @param cm 296 | */ 297 | function checkAutocomplete(cm) { 298 | 299 | var c = cm.getCursor(); 300 | var line = cm.getRange({'line': c.line, 'ch': 0},{'line': c.line, 'ch': c.ch}); 301 | if(line[line.length - 1] == ':') { 302 | //get prefix 303 | var prefix = /.*[\s.,;\{\}]([^:]+):$/g.exec(line)[1]; 304 | 305 | var text = cm.getValue(); 306 | 307 | var regex = new RegExp("PREFIX\\s+" + prefix + ":\\s*<",'ig'); 308 | 309 | //if prefix is not yet defined 310 | if(!text.match(regex)) { 311 | 312 | CodeMirror.showHint(cm, function(cm, self, data) { 313 | 314 | var result; 315 | 316 | //check if it is in static 317 | for(var property in SQUEBI.namespaces) { 318 | if(SQUEBI.namespaces[property] == prefix) { 319 | result = property; 320 | break; 321 | } 322 | } 323 | 324 | if(result == undefined) { 325 | try { 326 | jQuery.ajax('http://prefix.cc/' + prefix + '.file.json', { 327 | async: false, 328 | success: function(data) { 329 | result = data[prefix]; 330 | SQUEBI.namespaces[result] = prefix; 331 | }, 332 | dataType: "json" 333 | }); 334 | } catch (e) {} 335 | } 336 | 337 | if (result !== undefined) { 338 | return { 339 | list: [{ 340 | text: "add prefix " + prefix + ": <" + result + ">", 341 | hint: function() { 342 | 343 | var regex = new RegExp(".*(PREFIX\\s+" + prefix + ":)$",'ig'); 344 | 345 | if( line.match(regex) ) { 346 | var replacement = " <" + result + ">"; 347 | cm.replaceSelection(replacement); 348 | c.ch = c.ch + replacement.length; 349 | cm.setCursor(c); 350 | } else { 351 | c.line = c.line + 1; 352 | cm.setValue("PREFIX " + prefix + ": <" + result+">\n" + cm.getValue()); 353 | cm.setCursor(c); 354 | } 355 | } 356 | 357 | }], 358 | from: {line: c.line, ch: c.ch - prefix.length}, 359 | to: {line: c.line, ch: c.ch} 360 | } 361 | } 362 | 363 | },{ 364 | completeSingle: false 365 | }); 366 | } else { 367 | //get suggestions for prefix 368 | 369 | 370 | /*for(var property in SQUEBI.namespaces) { 371 | if(SQUEBI.namespaces[property] == prefix) { 372 | getSuggestions(property); 373 | } 374 | }*/ 375 | } 376 | } 377 | } 378 | 379 | //codemirror 380 | $scope.editorOptions = { 381 | lineWrapping : true, 382 | viewportMargin: 2000, 383 | lineNumbers: true, 384 | mode: 'sparql', 385 | theme: 'mdn-like sparql-mm', 386 | //extraKeys: {"Ctrl-Space": "autocomplete"}, 387 | onKeyEvent: function(i, e) { 388 | if(e.type == 'keyup') { 389 | if(e.keyCode == 16) { 390 | checkAutocomplete(i); 391 | } else { 392 | if(e.keyCode == 37 || e.keyCode == 38|| e.keyCode == 39 || e.keyCode == 40) return; 393 | checkSuggestion(i); 394 | } 395 | } 396 | }, 397 | onLoad: function(editor) { 398 | $rootScope.editor = editor; 399 | } 400 | 401 | }; 402 | 403 | /** 404 | * A regex used for query type evaluation 405 | * @type {RegExp} 406 | */ 407 | var query_regex = /(DROP)|(INSERT)|(DELETE)|(ASK)|(SELECT)|(CONSTRUCT)|(DESCRIBE)\s/i; 408 | 409 | /** 410 | * returns the query type if it can be evaluated, undefined otherwise 411 | * @param query 412 | * @returns {string} 413 | */ 414 | function getQueryType(query) { 415 | var match = query_regex.exec(query); 416 | return match != undefined ? match[0].toLowerCase() : undefined; 417 | } 418 | 419 | var firstLoad = true; 420 | 421 | /** 422 | * run the query 423 | */ 424 | $scope.runQuery = function() { 425 | 426 | if(firstLoad && !SQUEBI.automaticQuery) { 427 | firstLoad = false; return; 428 | } 429 | 430 | $rootScope.alerts = []; 431 | 432 | var type = getQueryType($scope.query.trim()); 433 | 434 | $log.debug("run " + type + " query " + $scope.query.trim()); 435 | 436 | $rootScope.loader = true; 437 | 438 | switch (type.trim()) { 439 | case 'insert': 440 | case 'delete': 441 | case 'drop': 442 | 443 | $rootScope.showResults = false; 444 | 445 | if(!SQUEBI.updateAllowed) { 446 | $rootScope.alerts.push({type: 'info', msg: 'Update queries are not allowed'}); 447 | break; 448 | } 449 | 450 | $sparql.update( 451 | $scope.query.trim(), 452 | {}, 453 | function(){ 454 | $rootScope.$emit('querySuccess',{type:type.trim(), data:{type: 'info', msg: 'Query performed successful'}}); 455 | }, function(data){ 456 | $rootScope.$emit('queryFailure',{type: 'danger', msg: data instanceof Object ? data.message : data}); 457 | } 458 | ); 459 | break; 460 | case 'ask': 461 | case 'select': 462 | case 'construct': 463 | case 'describe': 464 | 465 | var format = undefined; 466 | if(typeof($rootScope.writer.format) === "string") { //because of backwards compatibility 467 | format = type.trim() == 'select' ? 'application/sparql-results+' + $rootScope.writer.format : 'application/' + $rootScope.writer.format; 468 | } else { 469 | if($rootScope.writer.format[type.trim()] == undefined) { 470 | $rootScope.alerts.push({type: 'warning', msg: 'Query is not supported'}); 471 | $rootScope.loader = false; 472 | break; 473 | } else { 474 | format = $rootScope.writer.format[type.trim()]; 475 | } 476 | } 477 | 478 | 479 | $rootScope.showResults = true; 480 | 481 | $sparql.query( 482 | $scope.query.trim(), 483 | {acceptType: format}, 484 | function(data){ 485 | $rootScope.$emit('querySuccess',{type:type.trim(), data:data, query:$scope.query.trim()}); 486 | }, function(data, status, headers, config){ 487 | var m = data instanceof Object ? data.message : data; 488 | if(SQUEBI.responseMessage && SQUEBI.responseMessage[status]) { 489 | m = SQUEBI.responseMessage[status]; 490 | } 491 | $rootScope.$emit('queryFailure',{type: 'danger', msg: m}); 492 | } 493 | ); 494 | break; 495 | 496 | default : 497 | $rootScope.alerts.push({type: 'warning', msg: 'The type of query is not supported'}); 498 | $rootScope.loader = false; 499 | } 500 | }; 501 | 502 | // TODO workaround for codemirror bug 503 | var query = angular.copy($scope.query); 504 | $scope.$watch('query',function(a,b){ 505 | if(a!="") query = a; 506 | }); 507 | 508 | $scope.triggerQuery = function() { 509 | if($location.search().query == query) { 510 | $scope.runQuery(); 511 | } else $location.search("query",query); 512 | }; 513 | 514 | $scope.$on('$locationChangeSuccess', function () { 515 | 516 | if($location.search().query == undefined || $location.search().writer == undefined) { 517 | $location.search({ 518 | query: $location.search().query ? $location.search().query : $scope.query, 519 | writer: $location.search().writer ? $location.search().writer : $rootScope.writer.id 520 | }); 521 | } else { 522 | $scope.query = $location.search().query; 523 | $extension.selectResultWriterById($location.search().writer); 524 | $scope.runQuery(); 525 | } 526 | }); 527 | 528 | $rootScope.$on('setQuery', function(e,data) { 529 | $location.search("query",data); 530 | }); 531 | 532 | $rootScope.$on('setQueryAndWriter', function(e,query,writer) { 533 | $location.search({ 534 | "query": query, 535 | "writer": writer 536 | }); 537 | }); 538 | 539 | $rootScope.$on('setWriter', function(e,data) { 540 | $location.search("writer",data); 541 | }); 542 | 543 | }]); 544 | 545 | /** 546 | * A controller to support alert messages 547 | */ 548 | squebi.controller( 'AlertCtrl', [ 'SQUEBI', '$timeout', '$rootScope', '$scope', function( SQUEBI, $timeout, $rootScope, $scope ) { 549 | 550 | $rootScope.alerts = []; 551 | 552 | /** 553 | * remove alert 554 | * @param alert 555 | */ 556 | $scope.remove = function(alert) { 557 | var index = $rootScope.alerts.indexOf(alert); 558 | if(index != -1) $rootScope.alerts.splice(index,1); 559 | }; 560 | }]); 561 | 562 | squebi.controller( 'ResultCtrl', [ 'SQUEBI', '$timeout', '$rootScope', '$scope', function( SQUEBI, $timeout, $rootScope, $scope ) { 563 | 564 | $scope.template = SQUEBI.home + '/template/basic.html'; 565 | 566 | $rootScope.$on('querySuccess', function(e,data) { 567 | $rootScope.alerts = []; 568 | $rootScope.writer.onsuccess($scope,data,$rootScope); 569 | $rootScope.loader = false; 570 | }); 571 | 572 | $rootScope.$on('queryFailure', function(e,data) { 573 | $rootScope.alerts = []; 574 | $rootScope.writer.onfailure($scope,data,$rootScope); 575 | $rootScope.loader = false; 576 | }); 577 | 578 | }]); 579 | 580 | squebi.controller('ModalInstanceCtrl', ['$scope' ,'$modalInstance', 'data', function ($scope, $modalInstance, data) { 581 | $scope.data = data; 582 | 583 | $scope.cancel = function () { 584 | $modalInstance.dismiss(); 585 | }; 586 | 587 | $scope.store = function () { 588 | $modalInstance.close($scope.data); 589 | }; 590 | 591 | $scope.reset = function() { 592 | $modalInstance.close(); 593 | } 594 | }]); 595 | 596 | squebi.controller( 'ConfigurationCtrl', [ '$scope', '$modal', 'SQUEBI', 'localStorageService', function ($scope, $modal, SQUEBI, localStorageService) { 597 | 598 | var queryParams = []; 599 | 600 | for(var property in SQUEBI.queryParams) { 601 | queryParams.push({name:property,value:SQUEBI.queryParams[property]}); 602 | } 603 | 604 | $scope.data = { 605 | updateService: SQUEBI.updateService, 606 | selectService: SQUEBI.selectService, 607 | queryParams : queryParams 608 | }; 609 | 610 | $scope.open = function () { 611 | 612 | $modal.open({ 613 | templateUrl: 'configuration.html', 614 | controller: 'ModalInstanceCtrl', 615 | resolve: { 616 | data: function () { 617 | return $scope.data; 618 | } 619 | } 620 | }).result.then(function(data){ 621 | 622 | if(data == undefined) { 623 | 624 | localStorageService.clearAll(); 625 | window.location.reload(false); 626 | 627 | } else { 628 | 629 | SQUEBI.updateService = data.updateService; 630 | localStorageService.set('updateService', data.updateService); 631 | 632 | SQUEBI.selectService = data.selectService; 633 | localStorageService.set('selectService', data.selectService); 634 | 635 | SQUEBI.queryParams = {}; 636 | for(var i in data.queryParams) { 637 | SQUEBI.queryParams[data.queryParams[i].name] = data.queryParams[i].value; 638 | } 639 | localStorageService.set('queryParams', SQUEBI.queryParams); 640 | } 641 | }); 642 | }; 643 | }]); 644 | 645 | squebi.run(['$rootScope','localStorageService', 'SQUEBI', '$location', function($rootScope, localStorageService, SQUEBI, $location) { 646 | if(localStorageService.get('updateService')) SQUEBI.updateService = localStorageService.get('updateService'); 647 | if(localStorageService.get('selectService')) SQUEBI.selectService = localStorageService.get('selectService'); 648 | if(localStorageService.get('queryParams')) SQUEBI.queryParams = localStorageService.get('queryParams'); 649 | $rootScope.downloadEnabled = SQUEBI.downloadEnabled; 650 | 651 | var app = { 652 | getQuery : function() { 653 | return $rootScope.editor ? $rootScope.editor.getValue() : new Error("editor is not yet initialized"); 654 | } 655 | }; 656 | 657 | window.SQUEBI.getApp = function() { 658 | return app; 659 | }; 660 | 661 | if(window.SQUEBI.onload && window.SQUEBI.onload instanceof Function) { 662 | window.SQUEBI.onload(app); 663 | } 664 | 665 | $rootScope.githubPages = $location.host == 'tkurz.github.io'; 666 | 667 | }]); 668 | 669 | -------------------------------------------------------------------------------- /squebi/js/writer/squebi.browse.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Browsable 3 | */ 4 | squebi.run(['$extension','SQUEBI','$anchorScroll', function($extension,SQUEBI,$anchorScroll) { 5 | 6 | var config = { 7 | showFlags : false 8 | }; 9 | 10 | if(SQUEBI.browse) jQuery.extend(config, SQUEBI.browse); 11 | 12 | //var query_for_resource = "PREFIX ###NAME###: <###NSP###>\n\nSELECT DISTINCT ?property ?hasValue ?isValueOf WHERE {\n { ###URI### ?property ?hasValue }\nUNION\n { ?isValueOf ?property ###URI### }\n} ORDER BY (!BOUND(?hasValue)) ?property ?hasValue ?isValueOf"; 13 | //var query_for_property = "PREFIX ###NAME###: <###NSP###>\n\nSELECT DISTINCT ?resource ?value WHERE {\n ?resource ###URI### ?value\n} ORDER BY ?resource ?value"; 14 | //var query_for_class = "PREFIX ###NAME###: <###NSP###>\n\nSELECT DISTINCT ?instance WHERE {\n ?instance a ###URI###\n} ORDER BY ?instance"; 15 | 16 | var query_for_resource = "SELECT DISTINCT ?property ?hasValue ?isValueOf WHERE {\n { ###URI### ?property ?hasValue }\nUNION\n { ?isValueOf ?property ###URI### }\n}\nORDER BY ?property ?hasValue ?isValueOf\nLIMIT 1000"; 17 | var query_for_property = "SELECT DISTINCT ?resource ?value WHERE {\n ?resource ###URI### ?value\n}\nORDER BY ?resource ?value\nLIMIT 1000"; 18 | var query_for_class = "SELECT DISTINCT ?instance WHERE {\n ?instance a ###URI###\n}\nORDER BY ?instance\nLIMIT 1000"; 19 | 20 | function getQuery(uri,name) { 21 | 22 | /* 23 | var namespaceIndex = Math.max(uri.lastIndexOf("/"),uri.lastIndexOf("#")) +1; 24 | var namespace = uri.substring(0, namespaceIndex); 25 | var ns_name = namespace in SQUEBI.namespaces ? SQUEBI.namespaces[namespace] : "nsp"; 26 | var ns_uri = ns_name + ":" + uri.substring(namespaceIndex); 27 | */ 28 | 29 | var ns_uri = "<"+uri+">"; 30 | 31 | switch(name) { 32 | case 'property': return query_for_property.replace(/###URI###/g,ns_uri);//.replace(/###NSP###/g,namespace).replace(/###NAME###/g,ns_name); 33 | case 'class': return query_for_class.replace(/###URI###/g,ns_uri);//.replace(/###NSP###/g,namespace).replace(/###NAME###/g,ns_name); 34 | case 'type': return query_for_class.replace(/###URI###/g,ns_uri);//.replace(/###NSP###/g,namespace).replace(/###NAME###/g,ns_name); 35 | default : return query_for_resource.replace(/###URI###/g,ns_uri);//.replace(/###NSP###/g,namespace).replace(/###NAME###/g,ns_name); 36 | } 37 | 38 | } 39 | 40 | var getDisplayName = function(uri) { 41 | 42 | if(!uri) return ""; 43 | 44 | var namespaceIndex = Math.max(uri.lastIndexOf("/"),uri.lastIndexOf("#")) +1; 45 | var namespace = uri.substring(0, namespaceIndex); 46 | 47 | if(namespace in SQUEBI.namespaces) { 48 | return SQUEBI.namespaces[namespace] + ":" + uri.substring(namespaceIndex); 49 | } else { 50 | return uri; 51 | } 52 | }; 53 | 54 | var getDatatypeForBinding = function(binding) { 55 | if(binding && binding.datatype) { 56 | return getDisplayName(binding.datatype); 57 | } 58 | }; 59 | 60 | var getTitleForBinding = function(binding) { 61 | return binding.value + (binding['xml:lang'] ? '@'+binding['xml:lang'] : '') + (binding.datatype ? '^^'+binding.datatype : ""); 62 | }; 63 | 64 | var bindings; 65 | var offset; 66 | 67 | function drawData($scope) { 68 | 69 | var showBindings = bindings.slice(offset,offset+SQUEBI.pageSize); 70 | 71 | $scope.firstItem = offset+1; 72 | $scope.lastItem = offset+showBindings.length; 73 | 74 | $scope.showPrev = offset > 0; 75 | $scope.showNext = offset + showBindings.length < bindings.length; 76 | 77 | //$anchorScroll(); 78 | 79 | $scope.bindings = showBindings; 80 | $scope.template = SQUEBI.home + '/template/browse.html'; 81 | } 82 | 83 | var onsuccess = function($scope,data,$rootScope) { 84 | 85 | if($.inArray(data.type, ["drop", "insert", "delete"]) != -1) { 86 | 87 | $scope.template = SQUEBI.home + '/template/basic.html'; 88 | $rootScope.alerts.push(data.data); 89 | 90 | } else if(data.type == 'construct') { 91 | $scope.template = SQUEBI.home + '/template/basic.html'; 92 | $rootScope.alerts.push({type:"warning",msg:"Data Browser does not support 'Construct' queries. Use a different result writer!"}); 93 | } else if(data.type == 'describe') { 94 | $scope.template = SQUEBI.home + '/template/basic.html'; 95 | $rootScope.alerts.push({type:"warning",msg:"Data Browser does not support 'Describe' queries. Use a different result writer!"}); 96 | } else if(data.type == 'ask') { 97 | $scope.template = SQUEBI.home + '/template/basic.html'; 98 | if(data.data.boolean) { 99 | $rootScope.alerts.push({type:"success",msg:"The answer is YES."}); 100 | } else { 101 | $rootScope.alerts.push({type:"success",msg:"The answer is NO."}); 102 | } 103 | } else { 104 | 105 | 106 | $scope.getDisplayName = getDisplayName; 107 | 108 | $scope.transparent = SQUEBI.home + '/img/transparent.gif'; 109 | 110 | $scope.headers = data.data.head.vars; 111 | bindings = data.data.results.bindings; 112 | 113 | $scope.showFlags = config.showFlags; 114 | 115 | $scope.selectURI = function(uri,name) { 116 | var query = getQuery(uri,name); 117 | $rootScope.$emit('setQuery',query); 118 | }; 119 | 120 | $scope.prev = function() { 121 | offset = Math.max(0, offset-SQUEBI.pageSize); 122 | drawData($scope); 123 | }; 124 | 125 | $scope.next = function() { 126 | offset = offset+SQUEBI.pageSize < $scope.resultSize ? offset+SQUEBI.pageSize : offset; 127 | drawData($scope); 128 | }; 129 | 130 | $scope.getTitleForBinding = getTitleForBinding; 131 | 132 | $scope.getDatatypeForBinding = getDatatypeForBinding; 133 | 134 | $scope.resultSize = bindings.length; 135 | 136 | offset = 0; 137 | 138 | drawData($scope); 139 | } 140 | }; 141 | 142 | var writer = $extension.createResultWriter("browse","Browse", "json", "Displays browsable SPARQL result", onsuccess); 143 | writer.position = 1; 144 | $extension.selectResultWriter(writer); 145 | }]); -------------------------------------------------------------------------------- /squebi/js/writer/squebi.csv.js: -------------------------------------------------------------------------------- 1 | /** 2 | * CSV Writer 3 | */ 4 | squebi.run( ['$extension','SQUEBI', function($extension,SQUEBI){ 5 | 6 | function buildLink(query) { 7 | var query = SQUEBI.selectService + "?query=" + encodeURIComponent(query) + "&" + SQUEBI.outputQueryParam + "=csv"; 8 | if(SQUEBI.queryParams) { 9 | for(var property in SQUEBI.queryParams) { 10 | query += "&" + property + "=" + SQUEBI.queryParams[property]; 11 | } 12 | } 13 | return query; 14 | } 15 | 16 | var onsuccess = function($scope,data,$rootScope) { 17 | 18 | if($.inArray(data.type, ["drop", "insert", "delete"]) != -1) { 19 | $scope.template = SQUEBI.home + '/template/basic.html'; 20 | $rootScope.alerts.push(data.data); 21 | 22 | } else { 23 | $scope.data = data.data, true; 24 | $scope.href = buildLink(data.query); 25 | 26 | $scope.template = SQUEBI.home + '/template/data.html'; 27 | } 28 | 29 | }; 30 | 31 | var onfailure = function($scope,data,$rootScope) { 32 | $scope.template = SQUEBI.home + '/template/basic.html'; 33 | }; 34 | 35 | var writer = $extension.createResultWriter("csv","CSV", {select:"text/csv"}, "Displays SPARQL result as CSV", onsuccess, onfailure); 36 | writer.position = 4; 37 | }]); -------------------------------------------------------------------------------- /squebi/js/writer/squebi.image.js: -------------------------------------------------------------------------------- 1 | squebi.run( ["$extension","SQUEBI", function($extension,SQUEBI){ 2 | 3 | function buildLink(query) { 4 | var query = SQUEBI.selectService + "?query=" + encodeURIComponent(query) + "&out=json"; 5 | if(SQUEBI.queryParams) { 6 | for(var property in SQUEBI.queryParams) { 7 | query += "&" + property + "=" + SQUEBI.queryParams[property]; 8 | } 9 | } 10 | return query; 11 | } 12 | 13 | var onsuccess = function($scope,data,$rootScope) { 14 | 15 | if(data.type != 'select') { 16 | $scope.template = SQUEBI.home + '/template/basic.html'; 17 | alert("error"); 18 | return; 19 | 20 | } else { 21 | $scope.images = []; 22 | var name = data.data.head.vars[0]; 23 | for(var i in data.data.results.bindings) { 24 | if(data.data.results.bindings[i][name]) $scope.images.push(data.data.results.bindings[i][name].value); 25 | } 26 | $scope.template = SQUEBI.home + '/template/image.html' 27 | } 28 | 29 | }; 30 | 31 | var onfailure = function($scope,data,$rootScope) { 32 | $scope.template = SQUEBI.home + '/template/basic.html'; 33 | }; 34 | 35 | var writer = $extension.createResultWriter("image","Image", "json", "Displays SPARQL result as Image", onsuccess, onfailure); 36 | writer.position = 5; 37 | }]); -------------------------------------------------------------------------------- /squebi/js/writer/squebi.json.js: -------------------------------------------------------------------------------- 1 | /** 2 | * JSON Writer 3 | */ 4 | squebi.run(['$extension','SQUEBI', function($extension,SQUEBI){ 5 | 6 | function buildLink(query) { 7 | var query = SQUEBI.selectService + "?query=" + encodeURIComponent(query) + "&" + SQUEBI.outputQueryParam + "=json"; 8 | if(SQUEBI.queryParams) { 9 | for(var property in SQUEBI.queryParams) { 10 | query += "&" + property + "=" + SQUEBI.queryParams[property]; 11 | } 12 | } 13 | return query; 14 | } 15 | 16 | var onsuccess = function($scope,data,$rootScope) { 17 | 18 | if($.inArray(data.type, ["drop", "insert", "delete"]) != -1) { 19 | $scope.template = SQUEBI.home + '/template/basic.html'; 20 | $rootScope.alerts.push(data.data); 21 | 22 | } else { 23 | $scope.data = angular.toJson(data.data, true); 24 | $scope.href = buildLink(data.query); 25 | 26 | $scope.template = SQUEBI.home + '/template/data.html'; 27 | } 28 | 29 | }; 30 | 31 | var onfailure = function($scope,data,$rootScope) { 32 | $scope.template = SQUEBI.home + '/template/basic.html'; 33 | }; 34 | 35 | var writer = $extension.createResultWriter("json","JSON", "json", "Displays SPARQL result as JSON", onsuccess, onfailure); 36 | writer.position = 3; 37 | }]); -------------------------------------------------------------------------------- /squebi/js/writer/squebi.media.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Media Writer 3 | */ 4 | squebi.config(['$sceDelegateProvider', function($sceDelegateProvider) { 5 | $sceDelegateProvider.resourceUrlWhitelist([ 6 | // Allow same origin resource loads. 7 | 'self', 8 | // Allow loading from our assets domain. Notice the difference between * and **. 9 | 'http://localhost:8080/DATA/**']); 10 | }]); 11 | 12 | squebi.run(['$extension','SQUEBI','$timeout', function($extension,SQUEBI,$timeout){ 13 | 14 | function buildLink(query) { 15 | return SQUEBI.serviceURL.select + "?query=" + encodeURIComponent(query) + "&output=json"; 16 | } 17 | 18 | function getStyle(xywh) { 19 | var _w = Math.floor(600*(xywh[2]/100)); 20 | var _h = Math.floor(340*(xywh[3]/100)); 21 | var _l = -300 + 600*xywh[0]/100; 22 | var _t = 100 + 340*xywh[1]/100; 23 | return "width:"+_w+"px;height:"+_h+"px;margin-left:"+_l+"px;top:"+_t+"px"; 24 | } 25 | 26 | function parseFragment(uri) { 27 | var fragment = {}; 28 | 29 | if(uri.indexOf("#") == -1) return fragment; 30 | 31 | var hash = uri.substring(uri.lastIndexOf("#")+1); 32 | var values = hash.split("&"); 33 | 34 | for(var i in values) { 35 | var nv = values[i].split("="); 36 | if(nv[0] == "t") { 37 | var se = nv[1].split(","); 38 | fragment.t = { 39 | start: se[0], 40 | end: se[1] 41 | } 42 | } else if(nv[0] == "xywh") { 43 | var xywh = nv[1].substring(8,nv[1].length).split(","); 44 | fragment.xywh = { 45 | x:xywh[0], 46 | y:xywh[1], 47 | w:xywh[2], 48 | h:xywh[3], 49 | style: getStyle(xywh) 50 | } 51 | } 52 | } 53 | return fragment; 54 | } 55 | 56 | function transformData(data) { 57 | 58 | if(data.head.vars.length != 1) throw new Error("This result view only supports exact one binding"); 59 | 60 | var assets = []; 61 | for(var i in data.results.bindings) { 62 | 63 | if(data.results.bindings[i][data.head.vars[0]].type != 'uri') throw new Error("Result set may only contain URIs"); 64 | 65 | var uri = data.results.bindings[i][data.head.vars[0]].value; 66 | 67 | var type = undefined; 68 | 69 | if(uri.indexOf(".mp4") != -1 || uri.indexOf(".ogv") != -1 || uri.indexOf(".avi") != -1) { 70 | type = 'video' 71 | } else if(uri.indexOf(".png") != -1 || uri.indexOf(".jpg") != -1 || uri.indexOf(".gif") != -1) { 72 | type = 'image' 73 | } 74 | 75 | if(type == undefined) throw new Error("Result set may only contain Media URIs"); 76 | 77 | var fragment = parseFragment(uri); 78 | assets.push({src:uri,type:type,fragment:fragment}); 79 | } 80 | return assets; 81 | } 82 | 83 | var onsuccess = function($scope,data,$rootScope) { 84 | $scope.template = 'template/basic.html'; 85 | if($.inArray(data.type, ["drop", "insert", "delete"]) != -1) { 86 | $rootScope.alerts.push(data.data); 87 | 88 | } else if($.inArray(data.type, ["select"]) == -1) { 89 | $rootScope.alerts.push({type:"warning",msg:"Query type is not supported"}); 90 | 91 | } else { 92 | try { 93 | //check browser 94 | if(window.navigator.vendor != "Google Inc.") { 95 | $rootScope.alerts.push({type:"warning",msg:"Demo is maybe not fully supported by your browser. It uses .mp4 videos and was tested for Google Chrome."}); 96 | } 97 | 98 | $scope.data = transformData(data.data); 99 | $scope.singlevideo = false; 100 | $scope.selectVideo = function(video) { 101 | $scope.singlevideo = video; 102 | }; 103 | $scope.closeVideo = function() { 104 | $scope.singlevideo = false; 105 | }; 106 | $scope.template = SQUEBI.home + '/template/media.html'; 107 | } catch(error) { 108 | $rootScope.alerts.push({type:"danger",msg:error.message}); 109 | } 110 | 111 | } 112 | 113 | }; 114 | 115 | var writer = $extension.createResultWriter("media","Media", "json", "Displays result as Media Asset List", onsuccess); 116 | writer.position = 6; 117 | }]); -------------------------------------------------------------------------------- /squebi/js/writer/squebi.pie.js: -------------------------------------------------------------------------------- 1 | /** 2 | * PIE Chart Writer 3 | */ 4 | 5 | squebi.directive('piechart', ['$location',function ($location) { 6 | 7 | var query = "SELECT DISTINCT ?property ?hasValue ?isValueOf WHERE {\n { ###URI### ?property ?hasValue }\nUNION\n { ?isValueOf ?property ###URI### }\n} ORDER BY (!BOUND(?hasValue)) ?property ?hasValue ?isValueOf"; 8 | 9 | return { 10 | restrict: 'A', 11 | link: function (scope, elem, attrs) { 12 | 13 | var data = undefined; 14 | 15 | var options = { 16 | title: attrs.title ? attrs.title : undefined, 17 | width: attrs.width ? attrs.width : 900, 18 | height:attrs.height ? attrs.height : 500 19 | }; 20 | 21 | var chart = new google.visualization.PieChart(elem[0]); 22 | 23 | scope.$watch("data",function(d){ 24 | if(d != undefined) { 25 | data = d; 26 | chart.draw(data,options); 27 | } 28 | }); 29 | 30 | google.visualization.events.addListener(chart, 'select', function() { 31 | scope.$apply(function(){ 32 | $location.search({ 33 | query:query.replace(/###URI###/g,"<"+data.getValue(chart.getSelection()[0].row, 0)+">"), 34 | writer:'browse' 35 | }) 36 | }) 37 | }); 38 | } 39 | } 40 | }]); 41 | 42 | squebi.run(['$extension','SQUEBI',function($extension,SQUEBI) { 43 | 44 | function transformData(d) { 45 | 46 | if(d.head.vars.length != 2) throw new Error("Cannot transform data: result must contain exact 2 bindings!"); 47 | 48 | var data = []; 49 | data.push(d.head.vars); 50 | 51 | if(d.results.bindings.length == 0 || d.results.bindings.length == 1 && d.results.bindings[0][d.head.vars[1]] && d.results.bindings[0][d.head.vars[1]].value == "0") { 52 | return undefined; 53 | } 54 | 55 | for(var i in d.results.bindings) { 56 | var binding = d.results.bindings[i]; 57 | var v1 = binding[d.head.vars[0]].value; 58 | var v2 = binding[d.head.vars[1]].value; 59 | 60 | if(v2 > 0) { 61 | var f = parseFloat(v2); 62 | data.push([v1,f]); 63 | } else throw new Error("Cannot transform data: second binding has to be a positive number!"); 64 | } 65 | 66 | data = google.visualization.arrayToDataTable(data); 67 | 68 | return data; 69 | } 70 | 71 | var query_for_resource = "SELECT DISTINCT ?property ?hasValue ?isValueOf WHERE {\n { <###URI###> ?property ?hasValue }\nUNION\n { ?isValueOf ?property <###URI###> }\n} ORDER BY (!BOUND(?hasValue)) ?property ?hasValue ?isValueOf"; 72 | 73 | var onsuccess = function($scope,data,$rootScope) { 74 | 75 | $scope.template = SQUEBI.home + '/template/basic.html'; 76 | 77 | if(data.type != 'select') { 78 | $rootScope.alerts.push({type:"warning",msg: "Query type is not supported!"}); 79 | return; 80 | } 81 | 82 | try { 83 | $scope.data = transformData(data.data); 84 | //$scope.selected = undefined; 85 | 86 | if($scope.data == undefined) { 87 | $rootScope.alerts.push({type:"info",msg: "Result contains 0 data sets!"}); 88 | } else { 89 | 90 | /*TODO $scope.$watch("selected",function(sel) { 91 | if(sel != undefined) { 92 | $rootScope.$emit('setQueryAndWriter',query_for_resource.replaceAll("###URI###", sel),'browse'); 93 | } 94 | })*/ 95 | 96 | $scope.template = SQUEBI.home + '/template/pie.html'; 97 | } 98 | } catch(e) { 99 | $rootScope.alerts.push({type:"danger",msg: e.message}); 100 | } 101 | 102 | }; 103 | 104 | var onfailure = function($scope,data,$rootScope) { 105 | $scope.template = SQUEBI.home + '/template/basic.html'; 106 | }; 107 | 108 | var writer = $extension.createResultWriter("piechart","Piechart", "json", "Displays SPARQL result as Pie Chart", onsuccess, onfailure); 109 | writer.position = 5; 110 | }]); -------------------------------------------------------------------------------- /squebi/js/writer/squebi.rdfdot.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by tkurz on 28.03.14. 3 | */ 4 | /** 5 | * RDF Dot Writer 6 | */ 7 | squebi.run( ['$extension','$http','SQUEBI','$log', function($extension,$http,SQUEBI,$log){ 8 | 9 | function getImage(data, scope, rootScope) { 10 | $http({ 11 | url: "http://demo4.newmedialab.at/rdfdot/render", 12 | method: "POST", 13 | data: data.data, 14 | params: {'output':'png', 'input':'xml', 'base64':true} 15 | }) 16 | .success(function(data, status, headers, config) { 17 | rootScope.loader = false; 18 | scope.image = data; 19 | }). 20 | error(function(data, status, headers, config) { 21 | rootScope.loader = false; 22 | if(status==404) { 23 | rootScope.alerts.push({type:"danger",msg:"No response from server. Server down or no internet connection"}); 24 | } else { 25 | rootScope.alerts.push({type:"warning",msg:"Could not render image"}); 26 | } 27 | }); 28 | } 29 | 30 | var onsuccess = function($scope,data,$rootScope) { 31 | 32 | if($.inArray(data.type, ["construct", "describe"]) != -1) { 33 | $scope.image = null; 34 | $rootScope.loader = true; 35 | 36 | $scope.template = SQUEBI.home + '/template/rdfdot.html'; 37 | 38 | getImage(data, $scope, $rootScope); 39 | 40 | } else { 41 | $scope.template = SQUEBI.home + '/template/basic.html'; 42 | $rootScope.alerts.push({type:"warning",msg:"Only Construct and Describe queries allowed"}); 43 | } 44 | 45 | }; 46 | 47 | var onfailure = function($scope,data,$rootScope) { 48 | $scope.template = SQUEBI.home + '/template/basic.html'; 49 | }; 50 | 51 | var writer = $extension.createResultWriter("rdfdot","RDF.dot", "xml", "Displays SPARQL Construct query as graph image", onsuccess, onfailure); 52 | writer.position = 6; 53 | }]); -------------------------------------------------------------------------------- /squebi/js/writer/squebi.xml.js: -------------------------------------------------------------------------------- 1 | /** 2 | * XML Writer 3 | */ 4 | squebi.run( ['$extension','SQUEBI',function($extension,SQUEBI){ 5 | 6 | function buildLink(query) { 7 | var query = SQUEBI.selectService + "?query=" + encodeURIComponent(query) + "&" + SQUEBI.outputQueryParam + "=xml"; 8 | if(SQUEBI.queryParams) { 9 | for(var property in SQUEBI.queryParams) { 10 | query += "&" + property + "=" + SQUEBI.queryParams[property]; 11 | } 12 | } 13 | return query; 14 | } 15 | 16 | var onsuccess = function($scope,data,$rootScope) { 17 | 18 | if($.inArray(data.type, ["drop", "insert","delete"]) != -1) { 19 | $scope.template = SQUEBI.home + '/template/basic.html'; 20 | $rootScope.alerts.push(data.data); 21 | 22 | } else { 23 | $scope.data = data.data; 24 | $scope.href = buildLink(data.query); 25 | 26 | $scope.template = SQUEBI.home + '/template/data.html'; 27 | } 28 | 29 | }; 30 | 31 | var onfailure = function($scope,data,$rootScope) { 32 | $scope.template = SQUEBI.home + '/template/basic.html'; 33 | }; 34 | 35 | var writer = $extension.createResultWriter("xml","XML", "xml", "Displays SPARQL result as XML", onsuccess, onfailure); 36 | writer.position = 2; 37 | }]); -------------------------------------------------------------------------------- /squebi/template/basic.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /squebi/template/browse.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
Rows {{firstItem}} to {{lastItem}} of overall {{resultSize}}
4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 23 | 24 |
{{header}}
12 |
13 | {{getDisplayName(binding[name].value)}} 14 | 15 |
16 | {{binding[name].value}} 17 | 18 | @{{binding[name]['xml:lang']}} 19 | ^^{{getDatatypeForBinding(binding[name])}} 20 | 21 | _:{{binding[name].value}} 22 |
25 |
No results
26 |
27 | 28 |
Rows {{firstItem}} to {{lastItem}} of overall {{resultSize}}
29 | 30 |
31 | 32 | -------------------------------------------------------------------------------- /squebi/template/data.html: -------------------------------------------------------------------------------- 1 | Download 2 |
{{data}}
-------------------------------------------------------------------------------- /squebi/template/image.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
No results
-------------------------------------------------------------------------------- /squebi/template/media.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | No results. 4 |
5 |
6 | 7 |
8 |
Start: {{item.fragment.t.start}}s End: {{item.fragment.t.end}}s
9 |
Region: {{item.fragment.xywh.x}}%, {{item.fragment.xywh.y}}%, {{item.fragment.xywh.w}}%, {{item.fragment.xywh.h}}%
10 |
11 |
12 |
13 |
14 | 15 |
16 |
17 | 18 | 19 |
-------------------------------------------------------------------------------- /squebi/template/pie.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /squebi/template/rdfdot.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | created with rdf.dot 4 |
--------------------------------------------------------------------------------