diff --git a/.settings/de.loskutov.FileSync.prefs b/.settings/de.loskutov.FileSync.prefs
index 57e799b..957dcbf 100644
--- a/.settings/de.loskutov.FileSync.prefs
+++ b/.settings/de.loskutov.FileSync.prefs
@@ -1,5 +1,5 @@
WARNING=DO NOT MODIFY THIS FILE IF YOU DON'T UNDERSTAND
-defaultDestination=C\:/Users/andy/Desktop/basex.9b/webapp
+defaultDestination=C\:/Users/andy/Desktop/basex.versions/webapp
defaultVariables=
eclipse.preferences.version=1
includeTeamPrivateFiles=false
diff --git a/README.md b/README.md
index 84900b8..a3407d4 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,8 @@ Includes:
* localforage for persistence
Edit via android
+## Bugs
+* requests not stopped after unload
## Settings
Global `settings` provides `getItem(name)` and `setItem(name.value)`
diff --git a/src/vue-poc/core.js b/src/vue-poc/core.js
index 4099fa3..e4686c6 100644
--- a/src/vue-poc/core.js
+++ b/src/vue-poc/core.js
@@ -28,6 +28,19 @@ const Auth={
};
Vue.use(Auth);
+//Notification Object
+const Notification={
+ messages:[],
+ add(msg){
+ this.messages.unshift({text: msg, index: this.messages.length})
+ },
+ install(Vue){
+ Object.defineProperty(Vue.prototype, '$notification', {
+ get () { return Notification }
+ }) }
+};
+Vue.use(Notification);
+
// Mimetype info
const MimeTypes={
"text/xml":"xml",
diff --git a/src/vue-poc/data/vue-poc/namespaces.xml b/src/vue-poc/data/vue-poc/namespaces.xml
index 774221b..9bfb222 100644
--- a/src/vue-poc/data/vue-poc/namespaces.xml
+++ b/src/vue-poc/data/vue-poc/namespaces.xml
@@ -22,6 +22,30 @@
+
+ Xpath math
+
+
+
+ Xpath map
+
+
+
+ Xpath array
+
+
+
+ Xpath errors
+
+
+
+ serialization parameters
+
+
XML Schema Part 1: Structures namespace.
@@ -38,6 +62,18 @@
+
+ XPath functions
+
+
+
+
+ Xquery functions
+
+
+
Scalable Vector Graphics namespace
@@ -68,6 +104,11 @@
+
+ GML
+
+
+
XProc
@@ -77,8 +118,9 @@
-
+
EXpath packaging
+
\ No newline at end of file
diff --git a/src/vue-poc/features/collection/files.vue b/src/vue-poc/features/collection/files.vue
index 4210b3e..edae9e5 100644
--- a/src/vue-poc/features/collection/files.vue
+++ b/src/vue-poc/features/collection/files.vue
@@ -120,7 +120,11 @@
-
+
+
+
+
+
{{ selection[0] && selection[0].name }}
@@ -133,10 +137,8 @@
-
-
-
+
diff --git a/src/vue-poc/features/eval/eval.xqm b/src/vue-poc/features/eval/eval.xqm
index 67b5737..96369e6 100644
--- a/src/vue-poc/features/eval/eval.xqm
+++ b/src/vue-poc/features/eval/eval.xqm
@@ -8,22 +8,58 @@ import module namespace rest = "http://exquery.org/ns/restxq";
import module namespace util = 'vue-poc/util' at "../../lib/util.xqm";
import module namespace ufile = 'vue-poc/file' at "../../lib/file.xqm";
+declare variable $vue-api:db as xs:string:="vue-poc";
+declare variable $vue-api:id as element(last-id):=db:open("vue-poc","/state.xml")/state/last-id;
+
(:~
: eval
:)
declare
+%updating
%rest:POST %rest:path("/vue-poc/api/eval/execute")
%rest:form-param("xq", "{$xq}")
%output:method("json")
function vue-api:eval($xq )
{
- let $x:=fn:trace($xq,"task: ")
let $r:=util:query($xq,())
- return
- {$r}
-
+ return vue-api:response($r)
};
+(:~
+ : return id and return
+ :)
+declare
+%updating
+function vue-api:response($r)
+{
+ let $id:=$vue-api:id + 1
+ let $out:=
+ { $id }
+ {$r}
+
+ return (
+ replace value of node $vue-api:id with $id,
+ db:output($out)
+ )
+};
+
+(:~
+ : submit a simple job
+ :)
+declare
+%updating
+%rest:POST %rest:path("/vue-poc/api/eval/submit")
+%rest:form-param("xq", "{$xq}")
+%output:method("json")
+function vue-api:submit($xq )
+{
+ let $bindings:=map{}
+ let $opts:=map{"cache":true()}
+ let $r:=jobs:eval($xq,$bindings,$opts)
+ return vue-api:response($r)
+};
+
+
(:~
: query plan
:)
@@ -40,22 +76,6 @@ function vue-api:plan($xq )
};
-(:~
- : submit a simple job
- :)
-declare
-%rest:POST %rest:path("/vue-poc/api/eval/submit")
-%rest:form-param("xq", "{$xq}")
-%output:method("json")
-function vue-api:submit($xq )
-{
- let $bindings:=map{}
- let $opts:=map{"cache":true()}
- let $r:=jobs:eval($xq,$bindings,$opts)
- return
- {$r}
-
-};
(:~
: submit a simple job from path
@@ -93,6 +113,9 @@ let $n:='import module namespace fw="quodatum:file.walker";'
};
+(:~
+ : get result for job with $id
+ :)
declare
%rest:POST %rest:path('/vue-poc/api/eval/result/{$id}')
%output:method("json")
diff --git a/src/vue-poc/features/images/images.vue b/src/vue-poc/features/images/images.vue
index 303e43f..3c732b9 100644
--- a/src/vue-poc/features/images/images.vue
+++ b/src/vue-poc/features/images/images.vue
@@ -6,7 +6,7 @@
-
+
search
{{ qtext }}
@@ -15,19 +15,43 @@
clear
Clear search
-
+
+
+
+ refresh
+
+
- {{ total }} in {{ elapsed | round(2) }} secs
-
- Page:{{ query.page+1 }}
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
arrow_back
+
-
+
+
arrow_forward
+
-
+
+
@@ -37,32 +61,18 @@
v-for="image in images"
:key="image.name"
>
-
-
-
+
+
+ #{{image.keywords}}
+
+ place
+
-
-
-
- info
-
-
-
- #{{image.keywords}}
-
- place
-
-
-
-
- share
-
-
-
+
check_circle
@@ -70,7 +80,7 @@
-
+
Show images with...
@@ -162,14 +172,20 @@
-
+
- {{selitem.name}}
+ {{selection.length}} selected
highlight_off
- blah blah
+
+
+ -
+ {{sel.name}} {{sel.path}}
+
+
+
@@ -177,8 +193,10 @@
-
diff --git a/src/vue-poc/features/images/keywords.vue b/src/vue-poc/features/images/keywords.vue
index e71bdf9..2fd1a19 100644
--- a/src/vue-poc/features/images/keywords.vue
+++ b/src/vue-poc/features/images/keywords.vue
@@ -13,7 +13,9 @@
-
+
@@ -44,7 +46,8 @@
busy: false,
total: 0,
items: [],
- elapsed: null
+ elapsed: null,
+ q:""
}),
methods:{
@@ -62,6 +65,9 @@
},
show(keyword){
this.$router.push({ name: 'images', query: { keyword: keyword.text }})
+ },
+ setfilter(){
+ alert("not yet")
}
},
created:function(){
diff --git a/src/vue-poc/features/images/pics-01-store-directory.xq b/src/vue-poc/features/images/tasks/pics-01-store-directory.xq
similarity index 96%
rename from src/vue-poc/features/images/pics-01-store-directory.xq
rename to src/vue-poc/features/images/tasks/pics-01-store-directory.xq
index 0ef1421..6fce9b1 100644
--- a/src/vue-poc/features/images/pics-01-store-directory.xq
+++ b/src/vue-poc/features/images/tasks/pics-01-store-directory.xq
@@ -1,7 +1,7 @@
(:~
: create xml file list by scanning $SRC and write to vue-poc
:)
-import module namespace cfg = "quodatum:media.image.configure" at "config.xqm";
+import module namespace cfg = "quodatum:media.image.configure" at "../config.xqm";
import module namespace fw="quodatum:file.walker";
declare namespace c="http://www.w3.org/ns/xproc-step";
diff --git a/src/vue-poc/features/images/pics-02-store-meta.xq b/src/vue-poc/features/images/tasks/pics-02-store-meta.xq
similarity index 98%
rename from src/vue-poc/features/images/pics-02-store-meta.xq
rename to src/vue-poc/features/images/tasks/pics-02-store-meta.xq
index 04f2f2a..c32af56 100644
--- a/src/vue-poc/features/images/pics-02-store-meta.xq
+++ b/src/vue-poc/features/images/tasks/pics-02-store-meta.xq
@@ -3,7 +3,7 @@
: done in batches of 1000
: @return initial number of missing docs
:)
-import module namespace cfg = "quodatum:media.image.configure" at "config.xqm";
+import module namespace cfg = "quodatum:media.image.configure" at "../config.xqm";
import module namespace imgmeta = "expkg-zone58:image.metadata" ;
declare namespace c="http://www.w3.org/ns/xproc-step";
diff --git a/src/vue-poc/features/images/pics-03-store-image.xq b/src/vue-poc/features/images/tasks/pics-03-store-image.xq
similarity index 97%
rename from src/vue-poc/features/images/pics-03-store-image.xq
rename to src/vue-poc/features/images/tasks/pics-03-store-image.xq
index 83ec7d3..17725b5 100644
--- a/src/vue-poc/features/images/pics-03-store-image.xq
+++ b/src/vue-poc/features/images/tasks/pics-03-store-image.xq
@@ -3,7 +3,7 @@
: ->
:)
import module namespace metadata = 'expkg-zone58:image.metadata';
-import module namespace cfg = "quodatum:media.image.configure" at "config.xqm";
+import module namespace cfg = "quodatum:media.image.configure" at "../config.xqm";
for $meta in collection($cfg:DB-IMAGE || "/meta")/metadata
let $loc:=db:path($meta)=>tokenize("/")
let $name:=$loc[count($loc)-1]
diff --git a/src/vue-poc/features/images/pics-04-store-thumbs.xq b/src/vue-poc/features/images/tasks/pics-04-store-thumbs.xq
similarity index 98%
rename from src/vue-poc/features/images/pics-04-store-thumbs.xq
rename to src/vue-poc/features/images/tasks/pics-04-store-thumbs.xq
index 7ea1d3c..9083205 100644
--- a/src/vue-poc/features/images/pics-04-store-thumbs.xq
+++ b/src/vue-poc/features/images/tasks/pics-04-store-thumbs.xq
@@ -3,7 +3,7 @@
: @return initial number of missing docs
:)
import module namespace t="expkg-zone58:image.thumbnailator";
-import module namespace cfg = "quodatum:media.image.configure" at "config.xqm";
+import module namespace cfg = "quodatum:media.image.configure" at "../config.xqm";
declare namespace c="http://www.w3.org/ns/xproc-step";
declare variable $CHUNK:=1000;
diff --git a/src/vue-poc/features/images/pics-05-set-original.xq b/src/vue-poc/features/images/tasks/pics-05-set-original.xq
similarity index 92%
rename from src/vue-poc/features/images/pics-05-set-original.xq
rename to src/vue-poc/features/images/tasks/pics-05-set-original.xq
index f4aa4d0..0e1455f 100644
--- a/src/vue-poc/features/images/pics-05-set-original.xq
+++ b/src/vue-poc/features/images/tasks/pics-05-set-original.xq
@@ -1,5 +1,5 @@
(:~ set original:)
-import module namespace cfg = "quodatum:media.image.configure" at "config.xqm";
+import module namespace cfg = "quodatum:media.image.configure" at "../config.xqm";
for $i in collection($cfg:DB-IMAGE || "/image")/image
where $i[file/@path=>contains('original')]
diff --git a/src/vue-poc/features/images/pics-06-keywords.xq b/src/vue-poc/features/images/tasks/pics-06-keywords.xq
similarity index 98%
rename from src/vue-poc/features/images/pics-06-keywords.xq
rename to src/vue-poc/features/images/tasks/pics-06-keywords.xq
index 2347b1e..c2fcd52 100644
--- a/src/vue-poc/features/images/pics-06-keywords.xq
+++ b/src/vue-poc/features/images/tasks/pics-06-keywords.xq
@@ -4,7 +4,7 @@
: 14569796 14569818
:
:)
-import module namespace cfg = "quodatum:media.image.configure" at "config.xqm";
+import module namespace cfg = "quodatum:media.image.configure" at "../config.xqm";
declare %updating function local:put($data,$path){
db:replace($cfg:DB-IMAGE,$path,$data)
};
diff --git a/src/vue-poc/features/images/pics-07-datetaken.xq b/src/vue-poc/features/images/tasks/pics-07-datetaken.xq
similarity index 97%
rename from src/vue-poc/features/images/pics-07-datetaken.xq
rename to src/vue-poc/features/images/tasks/pics-07-datetaken.xq
index 9b473fc..3f8ca9c 100644
--- a/src/vue-poc/features/images/pics-07-datetaken.xq
+++ b/src/vue-poc/features/images/tasks/pics-07-datetaken.xq
@@ -4,11 +4,12 @@
: 14569796 14569818
:
:)
-import module namespace cfg = "quodatum:media.image.configure" at "config.xqm";
+import module namespace cfg = "quodatum:media.image.configure" at "../config.xqm";
declare %updating function local:put($data,$path){
db:replace($cfg:DB-IMAGE,$path,$data)
};
declare variable $DEST:="/datetaken.xml";
+
let $dates:={
for $image in collection($cfg:DB-IMAGE || "/image")/image[not(@original)]
let $year:=substring($image/datetaken,1,4)
diff --git a/src/vue-poc/features/job/jobs.vue b/src/vue-poc/features/job/jobs.vue
index 2ba2418..1dc61ae 100644
--- a/src/vue-poc/features/job/jobs.vue
+++ b/src/vue-poc/features/job/jobs.vue
@@ -14,7 +14,8 @@
single-line
hide-details
v-model="search"
- >
+ >
+ add
-
+
@@ -22,6 +22,15 @@
marker: L.latLng(54.320498718, -2.739663708)
}
},
+ methods:{
+ onResize(){
+ var el=this.$refs["page"]
+ console.log("top",el.offsetTop)
+ var h=Math.max(1,window.innerHeight - el.offsetTop)-60
+ console.log("h",h)
+ el.style.height=h +"px"
+ }
+ },
created:function(){
console.log("map")
}
diff --git a/src/vue-poc/features/svg.vue b/src/vue-poc/features/svg.vue
index 066b69e..1bc3edd 100644
--- a/src/vue-poc/features/svg.vue
+++ b/src/vue-poc/features/svg.vue
@@ -1,7 +1,8 @@
-svg
+
+
diff --git a/src/vue-poc/features/tabs.vue b/src/vue-poc/features/tabs.vue
index d7bf69a..7cb87ec 100644
--- a/src/vue-poc/features/tabs.vue
+++ b/src/vue-poc/features/tabs.vue
@@ -1,21 +1,7 @@
-
-
-
-
- menu
-
- Page Title
-
-
- search
-
-
- more_vert
-
-
-
+
+
close
+
+ menu
+
-
+
+
+
+ menu
+
+ Page Title
+
+
+ search
+
+
+ more_vert
+
+
+
-
+
diff --git a/src/vue-poc/lib/file.xqm b/src/vue-poc/lib/file.xqm
index 444f486..891e702 100644
--- a/src/vue-poc/lib/file.xqm
+++ b/src/vue-poc/lib/file.xqm
@@ -16,7 +16,7 @@ as xs:string
let $file:=if(starts-with($file,"/")) then
substring($file,2)
else
- error(xs:QName('vue-api:badpath'),"leading slash")
+ error(xs:QName('ufile:badpath'),"leading slash")
let $webroot:=db:system()/globaloptions/webpath/concat(.,"/")
return file:resolve-path($file,$webroot)
@@ -25,7 +25,7 @@ as xs:string
declare function ufile:webfile($url as xs:string)
as element(c:directory)
{
- let $path := ufile:web( $url)=>trace("vue-api:web ")
+ let $path := ufile:web( $url)=>trace("ufile:web ")
return if( file:exists($path))then
fw:directory-list($path,map{"max-depth":1,"include-info":true()})
else
diff --git a/src/vue-poc/lib/pipeline.xqm b/src/vue-poc/lib/pipeline.xqm
new file mode 100644
index 0000000..3114011
--- /dev/null
+++ b/src/vue-poc/lib/pipeline.xqm
@@ -0,0 +1,157 @@
+(:~
+ : pipeline library
+ : @author Andy Bunce
+ : @version 0.2
+ : @date nov 2017
+:)
+module namespace qipe='http://quodatum.com/ns/pipeline';
+import module namespace schematron = "http://github.com/Schematron/schematron-basex";
+
+declare variable $qipe:DEBUG:=false(); (: currently unused :)
+
+(:~ run a pipeline
+ : @param $pipe the pipeline document
+ : @param $initial starting data as sequence
+ : @result
+ :)
+declare function qipe:run($pipe as document-node(),$initial as item()* )
+as item()*
+{
+ let $steps:=$pipe/*/qipe:*
+ return fold-left($steps,$initial,qipe:step#2)
+};
+
+(:~ check pipeline is valid against schema :)
+declare function qipe:validate-pipeline($pipe as document-node() )
+as document-node()
+{
+ validate:rng($pipe , "schemas/pipeline.rnc",true()),$pipe
+};
+
+(:~ run a step
+ : @param $acc current state
+ : @param $this current step as qipe:* element
+ :)
+declare function qipe:step($acc,$this as element(*))
+{
+ typeswitch($this)
+ case element(qipe:validate) return qipe:validate($acc,$this)
+ case element(qipe:xquery) return qipe:xquery($acc,$this)
+ case element(qipe:xslt) return qipe:xslt($acc,$this)
+ case element(qipe:load) return qipe:load($acc,$this)
+ case element(qipe:store) return qipe:store($acc,$this)
+ default return error(xs:QName('qipe'), 'unknown step:' || name($this))
+};
+
+(:~ run validate step based on @type
+:)
+declare function qipe:validate($acc,$this as element(qipe:validate))
+{
+ let $href:=qipe:resolve($this/@href)
+ let $failOnError:=boolean($this/@failOnError)
+ let $fn:= switch ($this/@type/string())
+ case "relax-ng" return qipe:relax-ng(?,$href )
+ case "schematron" return qipe:schematron(?,$href )
+ case "xml-schema" return qipe:validate-xsd(?,$href )
+ default return error(xs:QName('qipe'), 'unknown validation type: ' || $this/@type/string() )
+ for $doc in $acc
+ let $report:=$fn($doc)
+ return
+ if($report/status = "valid") then
+ $doc
+ else
+ let $_:=trace($report,"validation errors")
+ return if($failOnError) then
+ error(xs:QName('qipe'), ' validation fails: ' || base-uri($doc))
+ else
+ $doc
+};
+
+(:~
+ : run xquery referenced by @href and append result sequence to accumulator
+ :)
+declare function qipe:xquery($acc,$this as element(qipe:xquery))
+{
+ let $href:=$this/@href/string()
+ let $result:=xquery:invoke($href)
+ return ($acc,$result)
+};
+
+(:~
+ : apply XSLT transform to each item in accumulator
+ :)
+declare function qipe:xslt($acc,$this as element(qipe:xslt))
+{
+ let $href:=qipe:resolve($this/@href)
+ let $result:=$acc!xslt:transform(., $href)
+ return $result
+};
+
+(:~
+ : store each item in accumulator at computed path
+ :)
+declare function qipe:store($acc,$this as element(qipe:store))
+{
+ let $href:=qipe:resolve($this/@base)
+ let $dated:=boolean($this/@dated)
+ let $name:=$this/@fileExpression/string()
+ let $href:=$href || (if( $dated) then format-date(current-date(),"/[Y0001][M01][D01]") else ())
+
+ return ($acc,
+ if(file:exists($href)) then () else file:create-dir($href),
+ for $item in $acc
+ let $name:=xquery:eval($name,map{"":$item}) (:eval against doc:)
+ let $dest:=$href || "/" || $name
+ return file:write($dest,$item)
+ )
+};
+
+(:~ validate with xml-schema :)
+declare function qipe:validate-xsd($doc,$xsd )
+as element(report)
+{
+ validate:xsd-report($doc,$xsd)
+};
+
+(:~ validate with relax-ng :)
+declare function qipe:relax-ng($doc,$rng )
+as element(report)
+{
+ let $compact:=matches($rng,".*\.rnc")
+ return validate:rng-report($doc,$rng,$compact)
+};
+
+
+(:~
+ : validate with schematron
+ : NOTE: relative paths in doc() references in schematron may cause issues
+ :)
+declare function qipe:schematron($doc,$uri-sch )
+as element(report)
+{
+ let $sch := schematron:compile(doc($uri-sch))
+ let $svrl := schematron:validate($doc, $sch)
+ return
+ {
+ if(schematron:is-valid($svrl)) then 'valid' else 'invalid'
+ }
+ {$svrl}
+
+};
+
+(:~ load from file system :)
+declare function qipe:load($acc,$this )
+{
+ let $href:=qipe:resolve($this/@href)=>trace("load")
+ let $new:=if(file:is-dir($href)) then
+ error(xs:QName('qipe'), 'dir loading not implemented') (: @TODO load all:)
+ else
+ doc($href)
+ return ($acc,$new)
+};
+
+(:~ resolve locations relative to this document typically from @href :)
+declare function qipe:resolve($href as node()? )
+{
+ resolve-uri( $href,base-uri($href))
+};
diff --git a/src/vue-poc/lib/util.xqm b/src/vue-poc/lib/util.xqm
index 29f750a..73aee4a 100644
--- a/src/vue-poc/lib/util.xqm
+++ b/src/vue-poc/lib/util.xqm
@@ -38,7 +38,7 @@ as xs:string
declare %updating function util:update-query(
$query as xs:string?
) {
- xquery:update($query, map { }, util:query-options())
+ xquery:eval-update($query, map { }, util:query-options())
};
(:~
diff --git a/src/vue-poc/lib/webutils.xqm b/src/vue-poc/lib/webutils.xqm
index 4b62751..df2a4b5 100644
--- a/src/vue-poc/lib/webutils.xqm
+++ b/src/vue-poc/lib/webutils.xqm
@@ -54,14 +54,14 @@ declare function http-created($location,$response){
(:~ CORS header with download option :)
declare function headers($attachment,$response){
-(
+(
{if($attachment)
then
else ()}
-, $response)
+, $response)
};
(:~ download as zip file :)
@@ -71,24 +71,24 @@ declare function zip-download($zipname,$data){
(:~ headers for download :)
declare function method($method as xs:string){
-
+
-
+
};
(:~ headers for download :)
declare function download-response($method,$filename){
-
+
-
+
};
(:~
diff --git a/src/vue-poc/lib/xqdoc/html-index.xsl b/src/vue-poc/lib/xqdoc/html-index.xsl
index dcd1395..5c70cf1 100644
--- a/src/vue-poc/lib/xqdoc/html-index.xsl
+++ b/src/vue-poc/lib/xqdoc/html-index.xsl
@@ -9,7 +9,7 @@
-
+
@@ -57,9 +57,11 @@
-
+
+
+
diff --git a/src/vue-poc/lib/xqdoc/html-module.xsl b/src/vue-poc/lib/xqdoc/html-module.xsl
index 6d90aa5..28f542d 100644
--- a/src/vue-poc/lib/xqdoc/html-module.xsl
+++ b/src/vue-poc/lib/xqdoc/html-module.xsl
@@ -89,11 +89,12 @@
-
- module
+
+
+ module
diff --git a/src/vue-poc/lib/xqdoc/xqdoc-proj.xqm b/src/vue-poc/lib/xqdoc/xqdoc-proj.xqm
index 3b85c30..4798003 100644
--- a/src/vue-poc/lib/xqdoc/xqdoc-proj.xqm
+++ b/src/vue-poc/lib/xqdoc/xqdoc-proj.xqm
@@ -1,5 +1,5 @@
(:~
- : Genrate html xquery documntation
+ : Generate XQuery documentation in html
: using file:///C:/Users/andy/workspace/app-doc/src/doc/data/doc/models
: $efolder:="file:///C:/Users/andy/workspace/app-doc/src/doc/data/doc/models"
: $target:="file:///C:/Users/andy/workspace/app-doc/src/doc/generated/models.xqm"
@@ -14,6 +14,9 @@ declare variable $xqd:XML:=map{"indent": "no"};
declare variable $xqd:mod-xslt external :="html-module.xsl";
declare variable $xqd:index-xslt external :="html-index.xsl";
+(:~ save documentation for files to target
+ :
+ :)
declare function xqd:save-xq($files,$target)
{
let $params:=map{
@@ -21,7 +24,7 @@ let $params:=map{
let $f:= document{$files} transform with { delete node //c:directory[not(.//c:file)]}
return (
- $files//c:file!xqd:gendoc(.,$target,$params),
+ $files//c:file!xqd:gendoc(.,"F" || position(),$target,$params),
$f=>xqd:store($target || "/files.xml",$xqd:XML),
$f=>xqd:index-html($params)=>xqd:store($target || "/index.html",$xqd:HTML5),
xqd:export-resources($target)
@@ -32,10 +35,12 @@ return (
: save xqdoc and html for source file $f
: @param $f
: @param $target destination folder
- : @params map
+ : @param map
+ : @param
:)
declare function xqd:gendoc(
$f as element(c:file),
+ $op as xs:string,
$target as xs:string,
$params as map(*)
)
@@ -43,7 +48,6 @@ declare function xqd:gendoc(
let $_:= if(file:is-dir($target)) then () else file:create-dir($target)
let $target:= file:path-to-native($target)
let $ip:= $f/@name/resolve-uri(.,base-uri(.))
- let $op:= $f/ancestor-or-self::*/@name=>tail()=>string-join("/")
let $dest:= file:resolve-path($op,$target)
let $xqdoc:= xqd:xqdoc($ip,map{})
diff --git a/src/vue-poc/router.js b/src/vue-poc/router.js
index e3fd327..470a957 100644
--- a/src/vue-poc/router.js
+++ b/src/vue-poc/router.js
@@ -1,6 +1,18 @@
+// vue-poc application routes
const router = new VueRouter({
base:"/vue-poc/ui/",
mode: 'history',
+ //
+ scrollBehavior (to, from, savedPosition) {
+ if (savedPosition) {
+ return savedPosition
+ } else if (to.hash) {
+ return { selector: to.hash, behavior: 'smooth' }
+
+ } else {
+ return { x: 0, y: 0 }
+ }
+ },
routes: [
{ path: '/', component: Home, meta:{title:"Home"} },
{ path: '/session', component: Session ,meta: {title:"Session"}},
diff --git a/src/vue-poc/static/ace-workers/worker-xquery.js b/src/vue-poc/static/ace-workers/worker-xquery.js
index f34778a..e652bac 100644
--- a/src/vue-poc/static/ace-workers/worker-xquery.js
+++ b/src/vue-poc/static/ace-workers/worker-xquery.js
@@ -6275,24 +6275,14 @@ exports.StaticContext = function (parent, pos) {
type: 'module',
override: true
};
- namespaces['http://expath.org/ns/file'] = {
- prefixes: ['file'],
- pos: emptyPos,
- type: 'module',
- override: true
- };
- namespaces['http://expath.org/ns/http-client'] = {
- prefixes: ['http'],
- pos: emptyPos,
- type: 'module',
- override: true
- };
+
namespaces['http://basex.org/modules/archive'] = {
prefixes: ['archive'],
pos: emptyPos,
type: 'module',
override: true
};
+
namespaces['http://basex.org/modules/client'] = {
prefixes: ['client'],
pos: emptyPos,
@@ -6323,6 +6313,12 @@ exports.StaticContext = function (parent, pos) {
type: 'module',
override: true
};
+ namespaces['http://basex.org/modules/db'] = {
+ prefixes: ['db'],
+ pos: emptyPos,
+ type: 'module',
+ override: true
+ };
namespaces['http://basex.org/modules/web'] = {
prefixes: ['web'],
pos: emptyPos,
@@ -6374,30 +6370,26 @@ exports.StaticContext = function (parent, pos) {
pos: emptyPos,
type: 'declare'
};
- namespaces['http://zorba.io/annotations'] = {
- prefixes: ['an'],
+ namespaces['http://expath.org/ns/file'] = {
+ prefixes: ['file'],
pos: emptyPos,
- type: 'declare',
+ type: 'module',
override: true
};
- namespaces['http://www.28msec.com/annotations/rest'] = {
- prefixes: ['rest'],
+ namespaces['http://expath.org/ns/http-client'] = {
+ prefixes: ['http'],
pos: emptyPos,
- type: 'declare',
+ type: 'module',
override: true
};
+
namespaces['http://www.w3.org/2005/xqt-errors'] = {
prefixes: ['err'],
pos: emptyPos,
type: 'declare',
override: true
};
- namespaces['http://zorba.io/errors'] = {
- prefixes: ['zerr'],
- pos: emptyPos,
- type: 'declare',
- override: true
- };
+
}
var s = {
diff --git a/src/vue-poc/static/app-gen.js b/src/vue-poc/static/app-gen.js
index eb8c45b..9e49a26 100644
--- a/src/vue-poc/static/app-gen.js
+++ b/src/vue-poc/static/app-gen.js
@@ -1,4 +1,4 @@
-// generated 2017-10-26T21:35:41.214+01:00
+// generated 2017-12-03T22:15:08.778Z
Vue.component('qd-confirm',{template:`
@@ -625,7 +625,11 @@ Vue.filter('round', function(value, decimals) {
-
+
+
+
+
+
{{ selection[0] && selection[0].name }}
@@ -638,10 +642,8 @@ Vue.filter('round', function(value, decimals) {
-
-
-
+
`,
@@ -658,7 +660,6 @@ Vue.filter('round', function(value, decimals) {
buttons: [
{method: this.todo, icon: "view_quilt"},
{method: this.add, icon: "add"},
- {method: this.load, icon: "refresh"},
{method: this.todo, icon: "sort"},
{method: this.selectAll, icon: "select_all"}
],
@@ -846,16 +847,15 @@ Vue.filter('round', function(value, decimals) {
{{ path.join('/') }}
-
- {{ name }}
-
-
-
- *
-.
-
-Changed?
-
+
+
+ *
+ {{ name }}
+
+
+ file_upload
+
+
{{ mode }}
@@ -879,7 +879,7 @@ Vue.filter('round', function(value, decimals) {
- star
+ label_outline
@@ -891,9 +891,7 @@ Vue.filter('round', function(value, decimals) {
wrap_text
-
- file_upload
-
+
format_align_center
@@ -901,35 +899,26 @@ Vue.filter('round', function(value, decimals) {
delete
-
-
- help
-
-
-
-
- settings
-
- Show settings
-
-
-
-
- keyboard
-
- Show keyboard commands
-
-
-
+
more_vert
-
-
-
+
+
+ settings
+
+ Show ACE settings
+
+
+
+
+ keyboard
+
+ Show ACE keyboard shortcuts
+
@@ -1129,44 +1118,58 @@ Entities
const Eval=Vue.extend({template:`
-
-
+
-
-
-
- play_circle_outline
- Run
-
-
- Submit
-
-
-
- Run
-
-
- Show query plan
-
-
-
+
+
+ label_outline
+
+
+ Outline here
+
-
-
+
+
+
+ add_circle
+
+
+
library_books
Imports
label
Namespaces
-
- more_vert
+
+
+
+
+ play_circle_outlinejobs:run
+
+
+
+ more_vert
+
- Show query plan
+ More actions...
+
+
+
+ xquery:eval
+
+
+
+ Show query plan
+
+
+
+ Test large result.
+
-
- hit me
-
-
+
+
+
+
@@ -1178,7 +1181,7 @@ Entities
- {{jobId}}
+ {{job.result}}
lockW
@@ -1214,10 +1217,11 @@ Entities
result:'',
elapsed: null,
show: false,
- showError: false, //unused
+ showError: false,
showResult: false, //
- jobId: null,
+ job: {}, // {id:"12",result:"job13"}
waiting: false,
+ destroyed: false,
start: null,
jobState: {},
aceSettings:{}
@@ -1253,7 +1257,7 @@ Entities
HTTPNE.post("eval/submit",Qs.stringify({xq:this.xq}))
.then(r=>{
this.elapsed=Math.floor(performance.now() - this.start);
- this.jobId=r.data.job
+ this.job=r.data
this.show=true
this.pollState()
@@ -1261,14 +1265,15 @@ Entities
.catch(r=> {
alert("catch")
console.log("error",r)
- this.jobId=r.response.job
+ this.job=r.response.job
this.showError=true;
});
},
pollState(){
+ if(this.destroyed)return;
this.waiting=true;
- HTTP.get("job/"+this.jobId)
+ HTTP.get("job/"+this.job.result)
.then(r=>{
this.jobState=r.data
this.waiting=r.data.state!="cached";
@@ -1282,7 +1287,7 @@ Entities
},
getResult(){
this.awaitResult(true)
- HTTPNE.post("eval/result/"+this.jobId)
+ HTTPNE.post("eval/result/"+this.job.result)
.then(r=>{
this.result=r.data.result+" "
}).catch(r=> {
@@ -1305,7 +1310,7 @@ Entities
alert("@TODO namespaces")
},
plan(){
- this.awaitResult(false)
+ this.awaitResult(true)
HTTPNE.post("eval/plan",Qs.stringify({xq:this.xq}))
.then(r=>{
this.result=r.data.result
@@ -1335,8 +1340,13 @@ Entities
})})
},
created:function(){
+ console.log("eval: creatd");
localforage.getItem('eval/xq').then((value) => { this.xq=value || this.xq});
- }
+ },
+ beforeDestroy:function(){
+ this.destroyed=true;
+ console.log("eval: before destroy");
+}
}
);
@@ -1513,7 +1523,7 @@ Entities
const Images=Vue.extend({template:`
-
+
search
{{ qtext }}
@@ -1521,56 +1531,66 @@ Entities
clear
Clear search
-
+
+
+
+ refresh
+
+
- {{ total }} in {{ elapsed | round(2) }} secs
-
- Page:{{ query.page+1 }}
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
arrow_back
+
-
+
+
arrow_forward
+
-
+
+
-
-
-
+
+
+ #{{image.keywords}}
+
+ place
+
-
-
-
- info
-
-
-
- #{{image.keywords}}
-
- place
-
-
-
-
- share
-
-
-
+
check_circle
-
+
Show images with...
@@ -1627,22 +1647,30 @@ Entities
-
+
- {{selitem.name}}
+ {{selection.length}} selected
highlight_off
- blah blah
+
+
+ -
+ {{sel.name}} {{sel.path}}
+
+
+
`,
-
- data: () => ({
+
+
+ data(){
+ return {
images:[],
query: {page:0, // current page
from:null,
@@ -1658,8 +1686,18 @@ Entities
keywords: [],
showInfo: false,
selitem: "TODO",
- location: {use:false,value:true}
- }),
+ location: {use:false,value:true},
+ buttons: [
+
+ {method: this.selectAll, icon: "select_all"}
+ ],
+ selopts: [
+ {method: this.selectNone, icon: "select_all"},
+ {method: ()=>{this.showInfo= ! this.showInfo}, icon: "info"},
+ {method: this.share, icon: "share"}
+ ]
+ }
+ },
methods:{
src(item){
return "data:image/jpeg;base64,"+item.data
@@ -1676,19 +1714,36 @@ Entities
this.total=r.data.total
this.images=r.data.items
var t1 = performance.now();
- this.elapsed= 0.001 *(t1 - t0)
+ var elapsed= 0.001 *(t1 - t0);
+ var round = Vue.filter('round');
+ this.$notification.add("Found " + this.total + " in : "+ round(elapsed,1) +" secs");
})
},
+ slideShow(){
+ alert("slideshow not yet");
+ },
clear(){
this.query.from=null;
this.query.until=null;
this.query.keyword=null;
this.query.page=0;
},
+ selectAll(){
+ this.images.forEach(item=>{item.selected=true})
+ },
+ selectNone(){
+ this.images.forEach(item=>{item.selected=false})
+ },
selected(image){
this.selitem=image;
this.showInfo=true;
},
+ action(b){
+ b.method(b.icon)
+ },
+ share(){
+ alert("sHARE: "+ this.selection.length);
+ },
isChanged(vnew,vold){
if(vnew.keyword != vold.keyword) return true
if(vnew.from != vold.from) return true
@@ -1711,6 +1766,9 @@ Entities
var k=this.query.keyword,f=this.query.from, u=this.query.until
var t= (k?" keyword:'"+k+"'":"")+ (f?" from:" + f:"")+ (u?" until:" + u:"")
return t?t:"(All)"
+ },
+ selection(){
+ return this.images.filter(item=>{return item.selected} )
}
},
watch:{
@@ -1765,14 +1823,34 @@ Entities
-
-body
-
+
+
`,
-
-
+
+ data: ()=>({
+ busy: false,
+ report: null,
+ elapsed: null
+ }),
+ methods:{
+ get(){
+ this.busy=true
+ var t0 = performance.now();
+ HTTP.get("images/report")
+ .then(r=>{
+ this.busy=false
+ this.report=r.data
+ var t1 = performance.now();
+ this.elapsed= 0.001 *(t1 - t0)
+ })
+ }
+ },
+ created:function(){
+ console.log("reports")
+ this.get()
+ }
}
);
@@ -1786,7 +1864,7 @@ body
-
+
@@ -1812,7 +1890,8 @@ body
busy: false,
total: 0,
items: [],
- elapsed: null
+ elapsed: null,
+ q:""
}),
methods:{
@@ -1830,6 +1909,9 @@ body
},
show(keyword){
this.$router.push({ name: 'images', query: { keyword: keyword.text }})
+ },
+ setfilter(){
+ alert("not yet")
}
},
created:function(){
@@ -1945,7 +2027,8 @@ people
Stop
-
+
+ add
@@ -2089,7 +2172,7 @@ people
const Map=Vue.extend({template:`
-
+
@@ -2108,6 +2191,15 @@ people
marker: L.latLng(54.320498718, -2.739663708)
}
},
+ methods:{
+ onResize(){
+ var el=this.$refs["page"]
+ console.log("top",el.offsetTop)
+ var h=Math.max(1,window.innerHeight - el.offsetTop)-60
+ console.log("h",h)
+ el.style.height=h +"px"
+ }
+ },
created:function(){
console.log("map")
}
@@ -2814,7 +2906,8 @@ namespaces
);
const Svg=Vue.extend({template:`
-svg
+
+
`,
@@ -2830,8 +2923,25 @@ svg
);
const Tabs=Vue.extend({template:`
-
-
+
+
+
+
+
+
+ favorite
+ Item {{ i }} more
+
+
+ close
+
+
+
+ menu
+
+
+
+
menu
@@ -2846,20 +2956,6 @@ svg
-
-
-
-
- favorite
- Item {{ i }} more
-
-
- close
-
-
-
-
-
@@ -3397,7 +3493,7 @@ created(){
-
+
@@ -3490,9 +3586,21 @@ created(){
}
);
- const router = new VueRouter({
+ // vue-poc application routes
+const router = new VueRouter({
base:"/vue-poc/ui/",
mode: 'history',
+ //
+ scrollBehavior (to, from, savedPosition) {
+ if (savedPosition) {
+ return savedPosition
+ } else if (to.hash) {
+ return { selector: to.hash, behavior: 'smooth' }
+
+ } else {
+ return { x: 0, y: 0 }
+ }
+ },
routes: [
{ path: '/', component: Home, meta:{title:"Home"} },
{ path: '/session', component: Session ,meta: {title:"Session"}},
@@ -3560,19 +3668,23 @@ router.beforeEach((to, from, next) => {
}
});const Vuepoc=Vue.extend({template:`
-
+
-
- Notifications
+
+ Notifications
- close
+ close
-
- TODO
+
+
-
+
@@ -3598,11 +3710,12 @@ router.beforeEach((to, from, next) => {
{{$route.meta.title}}
-
+
+
star_border
-
-
-
+
+
+
Bookmark this page
@@ -3613,11 +3726,12 @@ router.beforeEach((to, from, next) => {
- Save
+
Cancel
+ Save
-
+
@@ -3639,11 +3753,11 @@ router.beforeEach((to, from, next) => {
-
+
notifications
-
+
{{ alert.msg }}
@@ -3652,7 +3766,7 @@ router.beforeEach((to, from, next) => {
-
+
`,
@@ -3661,7 +3775,7 @@ router.beforeEach((to, from, next) => {
q: "",
status: {},
drawer: true,
- drawerRight: false,
+ showNotifications: false,
mini: false,
dark: false,
alert: {show:false,msg:"Hello"},
@@ -3767,9 +3881,6 @@ router.beforeEach((to, from, next) => {
},
favorite(){
alert("@TODO")
- },
- notifications(){
- this.drawerRight=true
}
},
@@ -3844,6 +3955,19 @@ const Auth={
};
Vue.use(Auth);
+//Notification Object
+const Notification={
+ messages:[],
+ add(msg){
+ this.messages.unshift({text: msg, index: this.messages.length})
+ },
+ install(Vue){
+ Object.defineProperty(Vue.prototype, '$notification', {
+ get () { return Notification }
+ }) }
+};
+Vue.use(Notification);
+
// Mimetype info
const MimeTypes={
"text/xml":"xml",
diff --git a/src/vue-poc/static/app.css b/src/vue-poc/static/app.css
index 8219aec..08b0cfd 100644
--- a/src/vue-poc/static/app.css
+++ b/src/vue-poc/static/app.css
@@ -123,4 +123,35 @@ height: 100%;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
-}
\ No newline at end of file
+}
+.canvas {
+ overflow: hidden;
+}
+.canvas .wrapper.outer > .background {
+ fill: #000000;
+}
+.canvas .wrapper.inner > .background {
+ fill: #CCCCCC;
+ cursor: move;
+}
+.canvas .background {
+ fill: #F6F6F6;
+ stroke: #333333;
+ cursor: move;
+}
+.canvas .panCanvas {
+ cursor: move;
+}
+
+.canvas .minimap .frame {
+ pointer-events: all;
+}
+.canvas .minimap .frame .background {
+ stroke: #111111;
+ stroke-width: 4px;
+ fill-opacity: 0.1;
+ fill: #000000;
+ fill: url(#minimapGradient_qwpyza);
+ filter: url(#minimapDropShadow_qwpyza);
+ cursor: move;
+}
\ No newline at end of file
diff --git a/src/vue-poc/static/app.html b/src/vue-poc/static/app.html
index f290dc3..fbc2f7f 100644
--- a/src/vue-poc/static/app.html
+++ b/src/vue-poc/static/app.html
@@ -7,25 +7,22 @@
Vue Router Test
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
vue-poc (v0.2.??)
+
vue-poc (v0.3.??)
-
+
-
+
-
+
-
+
+
-
+
diff --git a/src/vue-poc/static/svg-pan-zoom.css b/src/vue-poc/static/svg-pan-zoom.css
index 612011b..cbd4d1b 100644
--- a/src/vue-poc/static/svg-pan-zoom.css
+++ b/src/vue-poc/static/svg-pan-zoom.css
@@ -1,13 +1,5 @@
-html, body {
- font-family: Arial, sans-serif;
-}
-
-.title {
- font-size: 12px;
-}
.canvas {
overflow: hidden;
- fill: #808040;
}
.canvas .wrapper.outer > .background {
fill: #000000;
@@ -25,12 +17,15 @@ html, body {
cursor: move;
}
+.canvas .minimap .frame {
+ pointer-events: all;
+}
.canvas .minimap .frame .background {
stroke: #111111;
stroke-width: 4px;
- fill-opacity: 0.4;
+ fill-opacity: 0.1;
fill: #000000;
fill: url(#minimapGradient_qwpyza);
- xfilter: url(#minimapDropShadow_qwpyza);
+ filter: url(#minimapDropShadow_qwpyza);
cursor: move;
}
\ No newline at end of file
diff --git a/src/vue-poc/static/svg-pan-zoom.js b/src/vue-poc/static/svg-pan-zoom.js
index 20c2e8c..e4a1a3b 100644
--- a/src/vue-poc/static/svg-pan-zoom.js
+++ b/src/vue-poc/static/svg-pan-zoom.js
@@ -1,436 +1,419 @@
-// http://www.billdwhite.com/wordpress/2013/11/26/d3-minimap-pan-and-zoom-demo/
+// http://www.billdwhite.com/wordpress/2017/09/12/d3-v4-zooming-understanding-zoombehavior-in-the-pan-and-zoom-minimap/
d3.demo = {};
- /** CANVAS **/
- d3.demo.canvas = function() {
+/** CANVAS **/
+d3.demo.canvas = function() {
- "use strict";
+ "use strict";
- var width = 500,
- height = 500,
- zoomEnabled = true,
- dragEnabled = true,
- scale = 1,
- translation = [0,0],
- base = null,
- wrapperBorder = 2,
- minimap = null,
- minimapPadding = 20,
- minimapScale = 0.25;
+ var width = 500,
+ height = 500,
+ base = null,
+ wrapperBorder = 0,
+ minimap = null,
+ minimapPadding = 10,
+ minimapScale = 0.25;
- function canvas(selection) {
+ function canvas(selection) {
- base = selection;
+ base = selection;
+
+ var svgWidth = (width + (wrapperBorder*2) + minimapPadding*2 + (width*minimapScale));
+ var svgHeight = (height + (wrapperBorder*2) + minimapPadding*2);
+ var svg = selection.append("svg")
+ .attr("class", "svg canvas")
+ .attr("width", svgWidth)
+ .attr("height", svgHeight)
+ .attr("shape-rendering", "auto");
- var xScale = d3.scale.linear()
- .domain([-width / 2, width / 2])
- .range([0, width]);
+ var svgDefs = svg.append("defs");
+ svgDefs.append("clipPath")
+ .attr("id", "wrapperClipPath_qwpyza")
+ .attr("class", "wrapper clipPath")
+ .append("rect")
+ .attr("class", "background")
+ .attr("width", width)
+ .attr("height", height);
+ svgDefs.append("clipPath")
+ .attr("id", "minimapClipPath_qwpyza")
+ .attr("class", "minimap clipPath")
+ .attr("width", width)
+ .attr("height", height)
+ .append("rect")
+ .attr("class", "background")
+ .attr("width", width)
+ .attr("height", height);
- var yScale = d3.scale.linear()
- .domain([-height / 2, height / 2])
- .range([height, 0]);
+ var filter = svgDefs.append("svg:filter")
+ .attr("id", "minimapDropShadow_qwpyza")
+ .attr("x", "-20%")
+ .attr("y", "-20%")
+ .attr("width", "150%")
+ .attr("height", "150%");
+ filter.append("svg:feOffset")
+ .attr("result", "offOut")
+ .attr("in", "SourceGraphic")
+ .attr("dx", "1")
+ .attr("dy", "1");
+ filter.append("svg:feColorMatrix")
+ .attr("result", "matrixOut")
+ .attr("in", "offOut")
+ .attr("type", "matrix")
+ .attr("values", "0.1 0 0 0 0 0 0.1 0 0 0 0 0 0.1 0 0 0 0 0 0.5 0");
+ filter.append("svg:feGaussianBlur")
+ .attr("result", "blurOut")
+ .attr("in", "matrixOut")
+ .attr("stdDeviation", "10");
+ filter.append("svg:feBlend")
+ .attr("in", "SourceGraphic")
+ .attr("in2", "blurOut")
+ .attr("mode", "normal");
- var zoomHandler = function(newScale) {
- if (!zoomEnabled) { return; }
- if (d3.event) {
- scale = d3.event.scale;
- } else {
- scale = newScale;
- }
- if (dragEnabled) {
- var tbound = -height * scale,
- bbound = height * scale,
- lbound = -width * scale,
- rbound = width * scale;
- // limit translation to thresholds
- translation = d3.event ? d3.event.translate : [0, 0];
- translation = [
- Math.max(Math.min(translation[0], rbound), lbound),
- Math.max(Math.min(translation[1], bbound), tbound)
- ];
- }
+ var minimapRadialFill = svgDefs.append("radialGradient")
+ .attr('id', "minimapGradient")
+ .attr('gradientUnits', "userSpaceOnUse")
+ .attr('cx', "500")
+ .attr('cy', "500")
+ .attr('r', "400")
+ .attr('fx', "500")
+ .attr('fy', "500");
+ minimapRadialFill.append("stop")
+ .attr("offset", "0%")
+ .attr("stop-color", "#FFFFFF");
+ minimapRadialFill.append("stop")
+ .attr("offset", "40%")
+ .attr("stop-color", "#EEEEEE")
+ minimapRadialFill.append("stop")
+ .attr("offset", "100%")
+ .attr("stop-color", "#E0E0E0");
- d3.select(".panCanvas, .panCanvas .bg")
- .attr("transform", "translate(" + translation + ")" + " scale(" + scale + ")");
+ var outerWrapper = svg.append("g")
+ .attr("class", "wrapper outer")
+ .attr("transform", "translate(0, " + minimapPadding + ")");
+ outerWrapper.append("rect")
+ .attr("class", "background")
+ .attr("width", width + wrapperBorder*2)
+ .attr("height", height + wrapperBorder*2);
+
+ var innerWrapper = outerWrapper.append("g")
+ .attr("class", "wrapper inner")
+ .attr("clip-path", "url(#wrapperClipPath_qwpyza)")
+ .attr("transform", "translate(" + (wrapperBorder) + "," + (wrapperBorder) + ")");
- minimap.scale(scale).render();
- }; // startoff zoomed in a bit to show pan/zoom rectangle
+ innerWrapper.append("rect")
+ .attr("class", "background")
+ .attr("width", width)
+ .attr("height", height);
- var zoom = d3.behavior.zoom()
- .x(xScale)
- .y(yScale)
- .scaleExtent([0.1, 10])
- .on("zoom.canvas", zoomHandler);
- var w=width + (wrapperBorder*2) + minimapPadding*2 + (width*minimapScale);
- var h=height + (wrapperBorder*2);
- var svg = selection.append("svg")
- .attr("class", "svg canvas")
- .attr("width", "100%")
- .attr("height", "100%")
- .attr("viewBox", "0 0 "+w + " "+h)
- .attr("shape-rendering", "auto");
+ var panCanvas = innerWrapper.append("g")
+ .attr("class", "panCanvas")
+ .attr("width", width)
+ .attr("height", height)
+ .attr("transform", "translate(0,0)");
- var svgDefs = svg.append("defs");
+ panCanvas.append("rect")
+ .attr("class", "background")
+ .attr("width", width)
+ .attr("height", height);
+
+ var zoom = d3.zoom()
+ .scaleExtent([0.5, 5]);
- svgDefs.append("clipPath")
- .attr("id", "wrapperClipPath_qwpyza")
- .attr("class", "wrapper clipPath")
- .append("rect")
- .attr("class", "background")
+ // updates the zoom boundaries based on the current size and scale
+ var updateCanvasZoomExtents = function() {
+ var scale = innerWrapper.property("__zoom").k;
+ var targetWidth = svgWidth;
+ var targetHeight = svgHeight;
+ var viewportWidth = width;
+ var viewportHeight = height;
+ zoom.translateExtent([
+ [-viewportWidth/scale, -viewportHeight/scale],
+ [(viewportWidth/scale + targetWidth), (viewportHeight/scale + targetHeight)]
+ ]);
+ };
+
+ var zoomHandler = function() {
+ panCanvas.attr("transform", d3.event.transform);
+ // here we filter out the emitting of events that originated outside of the normal ZoomBehavior; this prevents an infinite loop
+ // between the host and the minimap
+ if (d3.event.sourceEvent instanceof MouseEvent || d3.event.sourceEvent instanceof WheelEvent) {
+ minimap.update(d3.event.transform);
+ }
+ updateCanvasZoomExtents();
+ };
+
+ zoom.on("zoom", zoomHandler);
+
+ innerWrapper.call(zoom);
+
+ // initialize the minimap, passing needed references
+ minimap = d3.demo.minimap()
+ .host(canvas)
+ .target(panCanvas)
+ .minimapScale(minimapScale)
+ .x(width + minimapPadding)
+ .y(minimapPadding);
+
+ svg.call(minimap);
+
+ /** ADD SHAPE **/
+ canvas.addItem = function(item) {
+ panCanvas.node().appendChild(item.node());
+ minimap.render();
+ };
+
+ /** RENDER **/
+ canvas.render = function() {
+ svgDefs
+ .select(".clipPath .background")
.attr("width", width)
.attr("height", height);
- svgDefs.append("clipPath")
- .attr("id", "minimapClipPath_qwpyza")
- .attr("class", "minimap clipPath")
- .attr("width", width)
- .attr("height", height)
- //.attr("transform", "translate(" + (width + minimapPadding) + "," + (minimapPadding/2) + ")")
- .append("rect")
- .attr("class", "background")
- .attr("width", width)
- .attr("height", height);
+ svg
+ .attr("width", width + (wrapperBorder*2) + minimapPadding*2 + (width*minimapScale))
+ .attr("height", height + (wrapperBorder*2));
- var filter = svgDefs.append("svg:filter")
- .attr("id", "minimapDropShadow_qwpyza")
- .attr("x", "-20%")
- .attr("y", "-20%")
- .attr("width", "150%")
- .attr("height", "150%");
-
- filter.append("svg:feOffset")
- .attr("result", "offOut")
- .attr("in", "SourceGraphic")
- .attr("dx", "1")
- .attr("dy", "1");
-
- filter.append("svg:feColorMatrix")
- .attr("result", "matrixOut")
- .attr("in", "offOut")
- .attr("type", "matrix")
- .attr("values", "0.1 0 0 0 0 0 0.1 0 0 0 0 0 0.1 0 0 0 0 0 0.5 0");
-
- filter.append("svg:feGaussianBlur")
- .attr("result", "blurOut")
- .attr("in", "matrixOut")
- .attr("stdDeviation", "10");
-
- filter.append("svg:feBlend")
- .attr("in", "SourceGraphic")
- .attr("in2", "blurOut")
- .attr("mode", "normal");
-
- var minimapRadialFill = svgDefs.append("radialGradient")
- .attr({
- id:"minimapGradient_qwpyza",
- gradientUnits:"userSpaceOnUse",
- cx:"500",
- cy:"500",
- r:"400",
- fx:"500",
- fy:"500"
- });
- minimapRadialFill.append("stop")
- .attr("offset", "0%")
- .attr("stop-color", "#FFFFFF");
- minimapRadialFill.append("stop")
- .attr("offset", "40%")
- .attr("stop-color", "#EEEEEE");
- minimapRadialFill.append("stop")
- .attr("offset", "100%")
- .attr("stop-color", "#E0E0E0");
-
- var outerWrapper = svg.append("g")
- .attr("class", "wrapper outer")
- .attr("transform", "translate(0, " + minimapPadding + ")");
-
- outerWrapper.append("rect")
- .attr("class", "background")
+ outerWrapper
+ .select(".background")
.attr("width", width + wrapperBorder*2)
.attr("height", height + wrapperBorder*2);
- var innerWrapper = outerWrapper.append("g")
- .attr("class", "wrapper inner")
- .attr("clip-path", "url(#wrapperClipPath_qwpyza)")
+ innerWrapper
.attr("transform", "translate(" + (wrapperBorder) + "," + (wrapperBorder) + ")")
- .call(zoom);
-
- innerWrapper.append("rect")
- .attr("class", "background")
+ .select(".background")
.attr("width", width)
.attr("height", height);
- var panCanvas = innerWrapper.append("g")
- .attr("class", "panCanvas")
+ panCanvas
.attr("width", width)
.attr("height", height)
- .attr("transform", "translate(0,0)");
-
- panCanvas.append("rect")
- .attr("class", "background")
+ .select(".background")
.attr("width", width)
.attr("height", height);
- minimap = d3.demo.minimap()
- .zoom(zoom)
- .target(panCanvas)
- .minimapScale(minimapScale)
+ minimap
.x(width + minimapPadding)
- .y(minimapPadding);
-
- svg.call(minimap);
-
- // startoff zoomed in a bit to show pan/zoom rectangle
- zoom.scale(1.75);
- zoomHandler(1.75);
-
- /** ADD SHAPE **/
- canvas.addItem = function(item) {
- panCanvas.node().appendChild(item.node());
- minimap.render();
- };
- canvas.clear = function() {
- var node=panCanvas.node();
- while (node.hasChildNodes()) {
- node.removeChild(node.lastChild);
- };
- };
- /** RENDER **/
- canvas.render = function() {
- svgDefs
- .select(".clipPath .background")
- .attr("width", width)
- .attr("height", height);
- var w=width + (wrapperBorder*2) + minimapPadding*2 + (width*minimapScale);
- var h=height + (wrapperBorder*2);
- svg
- .attr("width", "100%")
- .attr("height", "100%")
- .attr("viewBox", "0 0 "+w + " "+h);
- outerWrapper
- .select(".background")
- .attr("width", width + wrapperBorder*2)
- .attr("height", height + wrapperBorder*2);
-
- innerWrapper
- .attr("transform", "translate(" + (wrapperBorder) + "," + (wrapperBorder) + ")")
- .select(".background")
- .attr("width", width)
- .attr("height", height);
-
- panCanvas
- .attr("width", width)
- .attr("height", height)
- .select(".background")
- .attr("width", width)
- .attr("height", height);
-
- minimap
- .x(width + minimapPadding)
- .y(minimapPadding)
- .render();
- };
-
- canvas.zoomEnabled = function(isEnabled) {
- if (!arguments.length) { return zoomEnabled }
- zoomEnabled = isEnabled;
- };
-
- canvas.dragEnabled = function(isEnabled) {
- if (!arguments.length) { return dragEnabled }
- dragEnabled = isEnabled;
- };
-
- canvas.reset = function() {
- svg.call(zoom.event);
- zoom.scale(1);
- zoom.translate([0,0]);
- svg.transition().duration(750).call(zoom.event);
- };
- }
-
-
- //============================================================
- // Accessors
- //============================================================
-
- canvas.width = function(value) {
- if (!arguments.length) return width;
- width = parseInt(value, 10);
- return this;
+ .y(minimapPadding)
+ .render();
};
- canvas.height = function(value) {
- if (!arguments.length) return height;
- height = parseInt(value, 10);
- return this;
+ canvas.reset = function() {
+ //svg.call(zoom.event);
+ //svg.transition().duration(750).call(zoom.event);
+ zoom.transform(panCanvas, d3.zoomIdentity);
+ svg.property("__zoom", d3.zoomIdentity);
+ minimap.update(d3.zoomIdentity);
};
-
- canvas.scale = function(value) {
- if (!arguments.length) { return scale; }
- scale = value;
- return this;
+
+ canvas.update = function(minimapZoomTransform) {
+ zoom.transform(panCanvas, minimapZoomTransform);
+ // update the '__zoom' property with the new transform on the rootGroup which is where the zoomBehavior stores it since it was the
+ // call target during initialization
+ innerWrapper.property("__zoom", minimapZoomTransform);
+
+ updateCanvasZoomExtents();
};
+
+ updateCanvasZoomExtents();
+ }
- return canvas;
+
+ //============================================================
+ // Accessors
+ //============================================================
+
+ canvas.width = function(value) {
+ if (!arguments.length) return width;
+ width = parseInt(value, 10);
+ return this;
};
+ canvas.height = function(value) {
+ if (!arguments.length) return height;
+ height = parseInt(value, 10);
+ return this;
+ };
+
+ return canvas;
+};
- /** MINIMAP **/
- d3.demo.minimap = function() {
- "use strict";
+/** MINIMAP **/
+d3.demo.minimap = function() {
- var minimapScale = 0.15,
- scale = 1,
- zoom = null,
- base = null,
- target = null,
- width = 0,
- height = 0,
- x = 0,
- y = 0,
- frameX = 0,
- frameY = 0;
+ "use strict";
- function minimap(selection) {
+ var minimapScale = 0.15,
+ host = null,
+ base = null,
+ target = null,
+ width = 0,
+ height = 0,
+ x = 0,
+ y = 0;
- base = selection;
+ function minimap(selection) {
- var container = selection.append("g")
- .attr("class", "minimap")
- .call(zoom);
+ base = selection;
+
+ var zoom = d3.zoom()
+ .scaleExtent([0.5, 5]);
- zoom.on("zoom.minimap", function() {
- scale = d3.event.scale;
- });
+ // updates the zoom boundaries based on the current size and scale
+ var updateMinimapZoomExtents = function() {
+ var scale = container.property("__zoom").k;
+ var targetWidth = parseInt(target.attr("width"));
+ var targetHeight = parseInt(target.attr("height"));
+ var viewportWidth = host.width();
+ var viewportHeight = host.height();
+ zoom.translateExtent([
+ [-viewportWidth/scale, -viewportHeight/scale],
+ [(viewportWidth/scale + targetWidth), (viewportHeight/scale + targetHeight)]
+ ]);
+ };
+ var zoomHandler = function() {
+ frame.attr("transform", d3.event.transform);
+ // here we filter out the emitting of events that originated outside of the normal ZoomBehavior; this prevents an infinite loop
+ // between the host and the minimap
+ if (d3.event.sourceEvent instanceof MouseEvent || d3.event.sourceEvent instanceof WheelEvent) {
+ // invert the outgoing transform and apply it to the host
+ var transform = d3.event.transform;
+ // ordering matters here! you have to scale() before you translate()
+ var modifiedTransform = d3.zoomIdentity.scale(1/transform.k).translate(-transform.x, -transform.y);
+ host.update(modifiedTransform);
+ }
+
+ updateMinimapZoomExtents();
+ };
+
+ zoom.on("zoom", zoomHandler);
- minimap.node = container.node();
+ var container = selection.append("g")
+ .attr("class", "minimap");
- var frame = container.append("g")
- .attr("class", "frame")
+ container.call(zoom);
- frame.append("rect")
- .attr("class", "background")
+ minimap.node = container.node();
+
+ var frame = container.append("g")
+ .attr("class", "frame")
+
+ frame.append("rect")
+ .attr("class", "background")
+ .attr("width", width)
+ .attr("height", height)
+ .attr("filter", "url(#minimapDropShadow_qPWKOg)");
+
+
+ minimap.update = function(hostTransform) {
+ // invert the incoming zoomTransform; ordering matters here! you have to scale() before you translate()
+ var modifiedTransform = d3.zoomIdentity.scale((1/hostTransform.k)).translate(-hostTransform.x, -hostTransform.y);
+ // call this.zoom.transform which will reuse the handleZoom method below
+ zoom.transform(frame, modifiedTransform);
+ // update the new transform onto the minimapCanvas which is where the zoomBehavior stores it since it was the call target during initialization
+ container.property("__zoom", modifiedTransform);
+
+ updateMinimapZoomExtents();
+ };
+
+
+ /** RENDER **/
+ minimap.render = function() {
+ // update the placement of the minimap
+ container.attr("transform", "translate(" + x + "," + y + ")scale(" + minimapScale + ")");
+ // update the visualization being shown by the minimap in case its appearance has changed
+ var node = target.node().cloneNode(true);
+ node.removeAttribute("id");
+ base.selectAll(".minimap .panCanvas").remove();
+ minimap.node.appendChild(node); // minimap node is the container's node
+ d3.select(node).attr("transform", "translate(0,0)");
+ // keep the minimap's viewport (frame) sized to match the current visualization viewport dimensions
+ frame.select(".background")
.attr("width", width)
- .attr("height", height)
- .attr("filter", "url(#minimapDropShadow_qwpyza)");
-
- var drag = d3.behavior.drag()
- .on("dragstart.minimap", function() {
- var frameTranslate = d3.demo.util.getXYFromTranslate(frame.attr("transform"));
- frameX = frameTranslate[0];
- frameY = frameTranslate[1];
- })
- .on("drag.minimap", function() {
- d3.event.sourceEvent.stopImmediatePropagation();
- frameX += d3.event.dx;
- frameY += d3.event.dy;
- frame.attr("transform", "translate(" + frameX + "," + frameY + ")");
- var translate = [(-frameX*scale),(-frameY*scale)];
- target.attr("transform", "translate(" + translate + ")scale(" + scale + ")");
- zoom.translate(translate);
- });
-
- frame.call(drag);
-
- /** RENDER **/
- minimap.render = function() {
- scale = zoom.scale();
- container.attr("transform", "translate(" + x + "," + y + ")scale(" + minimapScale + ")");
- var node = target.node().cloneNode(true);
- node.removeAttribute("id");
- base.selectAll(".minimap .panCanvas").remove();
- minimap.node.appendChild(node);
- var targetTransform = d3.demo.util.getXYFromTranslate(target.attr("transform"));
- frame.attr("transform", "translate(" + (-targetTransform[0]/scale) + "," + (-targetTransform[1]/scale) + ")")
- .select(".background")
- .attr("width", width/scale)
- .attr("height", height/scale);
- frame.node().parentNode.appendChild(frame.node());
- d3.select(node).attr("transform", "translate(1,1)");
- };
- }
-
-
- //============================================================
- // Accessors
- //============================================================
-
-
- minimap.width = function(value) {
- if (!arguments.length) return width;
- width = parseInt(value, 10);
- return this;
+ .attr("height", height);
+ frame.node().parentNode.appendChild(frame.node());
};
-
- minimap.height = function(value) {
- if (!arguments.length) return height;
- height = parseInt(value, 10);
- return this;
- };
+ updateMinimapZoomExtents();
+ }
- minimap.x = function(value) {
- if (!arguments.length) return x;
- x = parseInt(value, 10);
- return this;
- };
+ //============================================================
+ // Accessors
+ //============================================================
- minimap.y = function(value) {
- if (!arguments.length) return y;
- y = parseInt(value, 10);
- return this;
- };
-
-
- minimap.scale = function(value) {
- if (!arguments.length) { return scale; }
- scale = value;
- return this;
- };
-
-
- minimap.minimapScale = function(value) {
- if (!arguments.length) { return minimapScale; }
- minimapScale = value;
- return this;
- };
-
-
- minimap.zoom = function(value) {
- if (!arguments.length) return zoom;
- zoom = value;
- return this;
- };
-
-
- minimap.target = function(value) {
- if (!arguments.length) { return target; }
- target = value;
- width = parseInt(target.attr("width"), 10);
- height = parseInt(target.attr("height"), 10);
- return this;
- };
-
- return minimap;
+ minimap.width = function(value) {
+ if (!arguments.length) return width;
+ width = parseInt(value, 10);
+ return this;
};
- /** UTILS **/
- d3.demo.util = {};
- d3.demo.util.getXYFromTranslate = function(translateString) {
- var currentTransform = d3.transform(translateString);
- currentX = currentTransform.translate[0];
- currentY = currentTransform.translate[1];
- return [currentX, currentY];
+ minimap.height = function(value) {
+ if (!arguments.length) return height;
+ height = parseInt(value, 10);
+ return this;
};
- /** RUN SCRIPT **/
-
-
\ No newline at end of file
+ minimap.x = function(value) {
+ if (!arguments.length) return x;
+ x = parseInt(value, 10);
+ return this;
+ };
+
+
+ minimap.y = function(value) {
+ if (!arguments.length) return y;
+ y = parseInt(value, 10);
+ return this;
+ };
+
+
+ minimap.host = function(value) {
+ if (!arguments.length) { return host;}
+ host = value;
+ return this;
+ }
+
+
+ minimap.minimapScale = function(value) {
+ if (!arguments.length) { return minimapScale; }
+ minimapScale = value;
+ return this;
+ };
+
+
+ minimap.target = function(value) {
+ if (!arguments.length) { return target; }
+ target = value;
+ width = parseInt(target.attr("width"), 10);
+ height = parseInt(target.attr("height"), 10);
+ return this;
+ };
+
+ return minimap;
+};
+
+/** RUN SCRIPT **/
+var canvasWidth = 800;
+
+var canvas = d3.demo.canvas().width(435).height(400);
+d3.select("#canvasqPWKOg").call(canvas);
+
+d3.select("#resetButtonqPWKOg").on("click", function() {
+ canvas.reset();
+});
+
+//d3.xml("https://upload.wikimedia.org/wikipedia/en/1/15/Logo_D3.svg",function(error, xml) {
+ d3.xml("https://gist.githubusercontent.com/billdwhite/496a140e7ab26cef02635449b3563e54/raw/50a49bfbcafbe1005cba39a118e8b609c4d4ca29/butterfly.svg",function(error, xml) {
+ if (error) throw error;
+ addItem(xml.documentElement);
+});
+
+function addItem(item) {
+ canvas.addItem(d3.select(item));
+}
diff --git a/src/vue-poc/vue-poc.vue b/src/vue-poc/vue-poc.vue
index 0520677..43d1e80 100644
--- a/src/vue-poc/vue-poc.vue
+++ b/src/vue-poc/vue-poc.vue
@@ -2,25 +2,29 @@
-
- Notifications
+
+ Notifications
- close
+ close
-
- TODO
+
+
-
@@ -47,11 +51,17 @@
{{$route.meta.title}}
-
+
+
star_border
-
-
-
+
+
+
Bookmark this page
@@ -68,11 +78,12 @@
>
- Save
+
Cancel
+ Save
-
+
@@ -95,11 +106,11 @@
-
+
notifications
-
+
{{ alert.msg }}
@@ -108,7 +119,7 @@
-
+
@@ -118,7 +129,7 @@
q: "",
status: {},
drawer: true,
- drawerRight: false,
+ showNotifications: false,
mini: false,
dark: false,
alert: {show:false,msg:"Hello"},
@@ -224,9 +235,6 @@
},
favorite(){
alert("@TODO")
- },
- notifications(){
- this.drawerRight=true
}
},