vuetify 0.17.3
This commit is contained in:
parent
2cdc2c50c1
commit
929f7c3ea0
39 changed files with 1320 additions and 807 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)`
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,30 @@
|
|||
</description>
|
||||
</namespace>
|
||||
|
||||
<namespace uri="http://www.w3.org/2005/xpath-functions/math"
|
||||
prefix="math">
|
||||
<description>Xpath math </description>
|
||||
</namespace>
|
||||
|
||||
<namespace uri="http://www.w3.org/2005/xpath-functions/map"
|
||||
prefix="map">
|
||||
<description>Xpath map </description>
|
||||
</namespace>
|
||||
|
||||
<namespace uri="http://www.w3.org/2005/xpath-functions/array"
|
||||
prefix="array">
|
||||
<description>Xpath array </description>
|
||||
</namespace>
|
||||
|
||||
<namespace uri="http://www.w3.org/2005/xqt-errors" prefix="err">
|
||||
<description>Xpath errors </description>
|
||||
</namespace>
|
||||
|
||||
<namespace uri="http://www.w3.org/2010/xslt-xquery-serialization"
|
||||
prefix="output">
|
||||
<description>serialization parameters </description>
|
||||
</namespace>
|
||||
|
||||
<namespace uri="http://www.w3.org/2001/XMLSchema" prefix="xsd">
|
||||
<description>XML Schema Part 1: Structures namespace. </description>
|
||||
</namespace>
|
||||
|
|
@ -38,6 +62,18 @@
|
|||
</description>
|
||||
</namespace>
|
||||
|
||||
<namespace uri="http://www.w3.org/2005/xpath-functions"
|
||||
prefix="fn">
|
||||
<description>XPath functions
|
||||
</description>
|
||||
</namespace>
|
||||
|
||||
<namespace uri="http://www.w3.org/2005/xquery-local-functions"
|
||||
prefix="local">
|
||||
<description>Xquery functions
|
||||
</description>
|
||||
</namespace>
|
||||
|
||||
<namespace uri="http://www.w3.org/2000/svg" prefix="svg">
|
||||
<description>Scalable Vector Graphics namespace
|
||||
</description>
|
||||
|
|
@ -68,6 +104,11 @@
|
|||
</description>
|
||||
</namespace>
|
||||
|
||||
<namespace uri="http://www.opengis.net/gml" prefix="gml">
|
||||
<description>GML
|
||||
</description>
|
||||
</namespace>
|
||||
|
||||
<namespace uri="http://www.w3.org/ns/xproc" prefix="xproc">
|
||||
<description>XProc
|
||||
</description>
|
||||
|
|
@ -77,8 +118,9 @@
|
|||
</description>
|
||||
</namespace>
|
||||
|
||||
<namespace uri="http://www.w3.org/ns/xproc-step" prefix="pkg">
|
||||
<namespace uri="http://expath.org/ns/pkg" prefix="pkg">
|
||||
<description>EXpath packaging
|
||||
</description>
|
||||
</namespace>
|
||||
|
||||
</namespaces>
|
||||
|
|
@ -120,7 +120,11 @@
|
|||
|
||||
</v-layout>
|
||||
|
||||
<v-navigation-drawer left persistent v-model="showInfo" :disable-route-watcher="true">
|
||||
|
||||
|
||||
</v-card>
|
||||
<v-progress-linear v-if="busy" v-bind:indeterminate="true" height="2"></v-progress-linear>
|
||||
<v-navigation-drawer left absolute v-model="showInfo" :disable-route-watcher="true">
|
||||
<v-card flat tile>
|
||||
<v-toolbar >
|
||||
<v-card-title >{{ selection[0] && selection[0].name }}</v-card-title>
|
||||
|
|
@ -133,10 +137,8 @@
|
|||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-navigation-drawer>
|
||||
|
||||
</v-card>
|
||||
<v-progress-linear v-if="busy" v-bind:indeterminate="true" height="2"></v-progress-linear>
|
||||
</v-container>
|
||||
|
||||
</template>
|
||||
|
||||
<script>{
|
||||
|
|
@ -154,7 +156,6 @@
|
|||
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"}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -22,16 +22,15 @@
|
|||
</v-menu>
|
||||
<span>{{ path.join('/') }}</span>
|
||||
</v-tooltip>
|
||||
<v-toolbar-title >
|
||||
<span >{{ name }}</span>
|
||||
</v-toolbar-title>
|
||||
<v-tooltip top>
|
||||
<span slot="activator">
|
||||
<v-chip v-if="dirty" label small class="red white--text">*</v-chip>
|
||||
<v-chip v-if="!dirty" label small class="green white--text">.</v-chip>
|
||||
</span>
|
||||
<span>Changed?</span>
|
||||
</v-tooltip>
|
||||
|
||||
<v-badge right v-model="dirty" >
|
||||
<span slot="badge" >*</span>
|
||||
<v-toolbar-title >{{ name }}</v-toolbar-title>
|
||||
</v-badge>
|
||||
<v-btn v-if="dirty" icon @click="save()">
|
||||
<v-icon>file_upload</v-icon>
|
||||
</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-menu left transition="v-fade-transition" >
|
||||
<v-chip label small slot="activator" >{{ mode }}</v-chip>
|
||||
|
|
@ -55,7 +54,7 @@
|
|||
</v-tooltip>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="acecmd('outline')" title="outline -todo">
|
||||
<v-icon>star</v-icon>
|
||||
<v-icon>label_outline</v-icon>
|
||||
</v-btn>
|
||||
|
||||
|
||||
|
|
@ -67,9 +66,7 @@
|
|||
<v-icon>wrap_text</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-btn icon @click="save()">
|
||||
<v-icon>file_upload</v-icon>
|
||||
</v-btn>
|
||||
|
||||
|
||||
<v-btn icon @click="beautify()">
|
||||
<v-icon>format_align_center</v-icon>
|
||||
|
|
@ -77,34 +74,25 @@
|
|||
<v-btn icon @click="clearDialog = true">
|
||||
<v-icon>delete</v-icon>
|
||||
</v-btn>
|
||||
<v-menu left transition="v-fade-transition">
|
||||
<v-btn icon slot="activator">
|
||||
<v-icon>help</v-icon>
|
||||
</v-btn>
|
||||
<v-list>
|
||||
<v-list-tile @click="acecmd('showSettingsMenu')" avatar >
|
||||
<v-list-tile-avatar>
|
||||
<v-icon >settings</v-icon>
|
||||
</v-list-tile-avatar>
|
||||
<v-list-tile-title @click="acecmd('showSettingsMenu')" >Show settings</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
|
||||
<v-list-tile @click="acecmd('showKeyboardShortcuts')" avatar>
|
||||
<v-list-tile-avatar>
|
||||
<v-icon >keyboard</v-icon>
|
||||
</v-list-tile-avatar>
|
||||
<v-list-tile-title @click="acecmd('showKeyboardShortcuts')" >Show keyboard commands</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
<v-menu left transition="v-fade-transition">
|
||||
<v-btn icon slot="activator">
|
||||
<v-icon>more_vert</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-list dense>
|
||||
<v-list-tile v-for="t in mimeTypes" :key="t">
|
||||
<v-list-tile-title v-text="t" @click="setMode(t)"></v-list-tile-title>
|
||||
<v-list-tile @click="acecmd('showSettingsMenu')" avatar >
|
||||
<v-list-tile-avatar>
|
||||
<v-icon >settings</v-icon>
|
||||
</v-list-tile-avatar>
|
||||
<v-list-tile-title @click="acecmd('showSettingsMenu')" >Show ACE settings</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
|
||||
<v-list-tile @click="acecmd('showKeyboardShortcuts')" avatar>
|
||||
<v-list-tile-avatar>
|
||||
<v-icon >keyboard</v-icon>
|
||||
</v-list-tile-avatar>
|
||||
<v-list-tile-title @click="acecmd('showKeyboardShortcuts')" >Show ACE keyboard shortcuts</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,44 +2,58 @@
|
|||
<template id="eval">
|
||||
<v-container fluid>
|
||||
<v-card >
|
||||
<v-toolbar dense>
|
||||
|
||||
<v-toolbar>
|
||||
|
||||
|
||||
<v-menu offset-y>
|
||||
<v-btn slot="activator">
|
||||
<v-icon>play_circle_outline</v-icon>
|
||||
Run</v-btn>
|
||||
<v-list>
|
||||
<v-list-tile @click="submit">
|
||||
<v-list-tile-title>Submit</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-divider></v-divider>
|
||||
<v-list-tile @click="run">
|
||||
<v-list-tile-title>Run</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-list-tile @click="plan">
|
||||
<v-list-tile-title>Show query plan</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
|
||||
</v-list>
|
||||
<v-menu offset-x>
|
||||
<v-btn slot="activator" flat icon color="pink">
|
||||
<v-icon>label_outline</v-icon>
|
||||
</v-btn>
|
||||
<v-card>
|
||||
<v-card-title>Outline here</v-card-title>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-menu offset-x>
|
||||
<v-btn slot="activator" flat icon color="pink">
|
||||
<v-icon>add_circle</v-icon>
|
||||
</v-btn>
|
||||
<v-card>
|
||||
<v-btn @click="imports">
|
||||
<v-icon>library_books</v-icon>
|
||||
Imports</v-btn>
|
||||
<v-btn @click="namespaces">
|
||||
<v-icon>label</v-icon>
|
||||
Namespaces</v-btn>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn @click="submit">
|
||||
<v-icon>play_circle_outline</v-icon>jobs:run
|
||||
</v-btn>
|
||||
<v-menu offset-y>
|
||||
<v-btn icon color="primary" slot="activator"> <v-icon>more_vert</v-icon></v-btn>
|
||||
<v-btn slot="activator" flat icon>
|
||||
<v-icon>more_vert</v-icon>
|
||||
</v-btn>
|
||||
<v-list dense>
|
||||
<v-list-tile @click="plan">Show query plan</v-list-tile>
|
||||
</v-list>
|
||||
<v-list>
|
||||
<v-list-tile @click="hitme">hit me</v-list-tile>
|
||||
<v-subheader>More actions...</v-subheader>
|
||||
<v-divider></v-divider>
|
||||
|
||||
<v-list-tile @click="run">
|
||||
<v-list-tile-title>xquery:eval</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
|
||||
<v-list-tile @click="plan">
|
||||
<v-list-tile-title>Show query plan</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
|
||||
<v-list-tile @click="hitme">
|
||||
<v-list-tile-title>Test large result.</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
|
||||
|
||||
|
||||
</v-toolbar>
|
||||
|
||||
|
||||
|
|
@ -53,7 +67,7 @@
|
|||
|
||||
<v-card-actions v-if="show" >
|
||||
|
||||
<v-chip class="primary white--text">{{jobId}}</v-chip>
|
||||
<v-chip class="primary white--text">{{job.result}}</v-chip>
|
||||
|
||||
<v-chip label class="grey white--text">
|
||||
<v-avatar class="red"> <v-icon>lock</v-icon>W</v-avatar>
|
||||
|
|
@ -91,10 +105,11 @@
|
|||
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:{}
|
||||
|
|
@ -130,7 +145,7 @@
|
|||
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()
|
||||
|
||||
|
|
@ -138,14 +153,15 @@
|
|||
.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";
|
||||
|
|
@ -159,7 +175,7 @@
|
|||
},
|
||||
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=> {
|
||||
|
|
@ -182,7 +198,7 @@
|
|||
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
|
||||
|
|
@ -212,7 +228,12 @@
|
|||
})})
|
||||
},
|
||||
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");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -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 <json type="object" >
|
||||
return vue-api:response($r)
|
||||
};
|
||||
|
||||
(:~
|
||||
: return id and return
|
||||
:)
|
||||
declare
|
||||
%updating
|
||||
function vue-api:response($r)
|
||||
{
|
||||
let $id:=$vue-api:id + 1
|
||||
let $out:= <json type="object" >
|
||||
<id>{ $id }</id>
|
||||
<result>{$r}</result>
|
||||
</json>
|
||||
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 )
|
|||
</json>
|
||||
};
|
||||
|
||||
(:~
|
||||
: 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 <json type="object" >
|
||||
<job>{$r}</job>
|
||||
</json>
|
||||
};
|
||||
|
||||
(:~
|
||||
: submit a simple job from path
|
||||
|
|
@ -93,6 +113,9 @@ let $n:='import module namespace fw="quodatum:file.walker";'
|
|||
</json>
|
||||
};
|
||||
|
||||
(:~
|
||||
: get result for job with $id
|
||||
:)
|
||||
declare
|
||||
%rest:POST %rest:path('/vue-poc/api/eval/result/{$id}')
|
||||
%output:method("json")
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<template id="images">
|
||||
|
||||
<v-card>
|
||||
<v-toolbar class="green white--text">
|
||||
<v-toolbar dense >
|
||||
<v-btn @click.stop="showFilter = true" icon><v-icon>search</v-icon></v-btn>
|
||||
<v-toolbar-title>{{ qtext }}</v-toolbar-title>
|
||||
<v-tooltip top v-if="query.keyword || query.from || query.until">
|
||||
|
|
@ -16,18 +16,42 @@
|
|||
</v-btn>
|
||||
<span>Clear search</span>
|
||||
</v-tooltip>
|
||||
<v-btn icon @click="getImages">
|
||||
<v-avatar>
|
||||
<v-icon >refresh</v-icon>
|
||||
</v-avatar>
|
||||
</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
<span v-if="!busy">
|
||||
<v-chip class="primary white--text">{{ total }} in {{ elapsed | round(2) }} secs </v-chip>
|
||||
|
||||
Page:{{ query.page+1 }}
|
||||
<v-btn @click.stop="pageBack()" :disabled="query.page==0" icon color="primary">
|
||||
<v-icon>arrow_back</v-icon>
|
||||
<v-toolbar-items v-if="!selection.length">
|
||||
<v-btn icon v-for="b in buttons" :key="b.icon" @click="action(b)">
|
||||
<v-avatar>
|
||||
<v-icon v-text="b.icon"></v-icon>
|
||||
</v-avatar>
|
||||
</v-btn>
|
||||
<v-btn @click.stop="pageNext()" icon color="primary">
|
||||
<v-icon>arrow_forward</v-icon>
|
||||
</v-toolbar-items>
|
||||
<v-toolbar-items v-if="selection.length">
|
||||
<v-btn icon v-for="b in selopts" :key="b.icon" @click="action(b)">
|
||||
<v-avatar>
|
||||
<v-icon v-text="b.icon"></v-icon>
|
||||
</v-avatar>
|
||||
</v-btn>
|
||||
</v-toolbar-items>
|
||||
</span>
|
||||
<v-spacer></v-spacer>
|
||||
<v-toolbar-items>
|
||||
<v-btn @click.stop="pageBack()" :disabled="query.page==0" icon >
|
||||
<v-avatar>
|
||||
<v-icon>arrow_back</v-icon>
|
||||
</v-avatar>
|
||||
</v-btn>
|
||||
<v-btn @click.stop="pageNext()" icon >
|
||||
<v-avatar>
|
||||
<v-icon>arrow_forward</v-icon>
|
||||
</v-avatar>
|
||||
</v-btn>
|
||||
</v-toolbar-items>
|
||||
|
||||
</v-toolbar>
|
||||
<v-progress-linear v-if="busy" v-bind:indeterminate="true" ></v-progress-linear>
|
||||
<v-container v-if="!busy" fluid grid-list-md>
|
||||
|
|
@ -37,32 +61,18 @@
|
|||
v-for="image in images"
|
||||
:key="image.name"
|
||||
>
|
||||
<v-card class="grey lighten-2 pt-1">
|
||||
<v-card-media :src="src(image)" @dblclick="go(image)"
|
||||
height="80px" contain>
|
||||
|
||||
<v-card flat tile class="grey lighten-2 pa-1" >
|
||||
<v-card-media :src="src(image)" @dblclick="go(image)" @click.prevent.stop="image.selected =! image.selected "
|
||||
height="100px" contain>
|
||||
<span v-if="image.keywords >0 ">#{{image.keywords}}</span>
|
||||
<v-avatar icon small v-if="image.geo">
|
||||
<v-icon>place</v-icon>
|
||||
</v-avatar>
|
||||
|
||||
|
||||
</v-card-media>
|
||||
|
||||
<v-card-actions >
|
||||
<v-tooltip bottom >
|
||||
<v-btn icon small slot="activator">
|
||||
<v-icon>info</v-icon>
|
||||
</v-btn>
|
||||
<span v-text="image.path"></span>
|
||||
</v-tooltip>
|
||||
<span v-if="image.keywords >0 ">#{{image.keywords}}</span>
|
||||
<v-btn icon small v-if="image.geo">
|
||||
<v-icon>place</v-icon>
|
||||
</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-btn icon small @click="selected(image)">
|
||||
<v-icon>share</v-icon>
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
<div style="position:absolute;right:0;top:0" >
|
||||
<div v-if="image.selected" style="position:absolute;right:0;top:0" >
|
||||
<v-icon class="white primary--text">check_circle</v-icon>
|
||||
</div
|
||||
</v-card>
|
||||
|
|
@ -70,7 +80,7 @@
|
|||
</v-layout>
|
||||
</v-container>
|
||||
|
||||
<v-navigation-drawer left persistent v-model="showFilter" :disable-route-watcher="true">
|
||||
<v-navigation-drawer left fixed v-model="showFilter" :disable-route-watcher="true">
|
||||
<v-card>
|
||||
<v-toolbar class="green white--text">
|
||||
<v-toolbar-title >Show images with...</v-toolbar-title>
|
||||
|
|
@ -162,14 +172,20 @@
|
|||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-navigation-drawer>
|
||||
<v-navigation-drawer left persistent v-model="showInfo" :disable-route-watcher="true">
|
||||
<v-navigation-drawer left fixed v-model="showInfo" :disable-route-watcher="true">
|
||||
<v-card>
|
||||
<v-toolbar class="green white--text">
|
||||
<v-toolbar-title >{{selitem.name}}</v-toolbar-title>
|
||||
<v-toolbar-title >{{selection.length}} selected</v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn flat icon @click="showInfo = false"><v-icon>highlight_off</v-icon></v-btn>
|
||||
</v-toolbar>
|
||||
<v-card-text> blah blah </v-card-text>
|
||||
<v-card-text>
|
||||
<ul>
|
||||
<li v-for="sel in selection" :key="sel.name">
|
||||
{{sel.name}} {{sel.path}}
|
||||
</li>
|
||||
</ul>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-navigation-drawer>
|
||||
|
||||
|
|
@ -178,7 +194,9 @@
|
|||
</template>
|
||||
|
||||
<script>{
|
||||
data: () => ({
|
||||
|
||||
data(){
|
||||
return {
|
||||
images:[],
|
||||
query: {page:0, // current page
|
||||
from:null,
|
||||
|
|
@ -194,8 +212,18 @@
|
|||
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
|
||||
|
|
@ -212,19 +240,36 @@
|
|||
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
|
||||
|
|
@ -247,6 +292,9 @@
|
|||
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:{
|
||||
|
|
|
|||
|
|
@ -25,6 +25,30 @@ function vue-api:id( $id as xs:integer)
|
|||
{ vue-api:get-image($image) }
|
||||
</json>
|
||||
};
|
||||
|
||||
(:~
|
||||
: get report
|
||||
:)
|
||||
declare
|
||||
%rest:GET %rest:path("/vue-poc/api/images/report")
|
||||
%output:method("html") %output:version("5.0")
|
||||
function vue-api:report()
|
||||
{
|
||||
<div>
|
||||
something
|
||||
<ol>
|
||||
<li>$cfg:IMAGEDIR: <code>{ $cfg:IMAGEDIR }</code> </li>
|
||||
<li>$cfg:THUMBDIR: <code>{ $cfg:THUMBDIR }</code> </li>
|
||||
<li><a href="#A30">A30</a></li>
|
||||
<li><a href="#A50">A50</a></li>
|
||||
</ol>
|
||||
{for $i in 1 to 50 return <p>{$i}:
|
||||
<a name="A{$i}">Lorem ipsum</a> dolor sit amet, consectetur adipiscing elit. Morbi aliquam sodales justo, aliquet eleifend ex bibendum eget. Nullam vitae maximus ipsum. Sed maximus felis in interdum maximus. Vestibulum quis urna vel dolor placerat iaculis non at metus. Curabitur nec dictum mauris. Duis placerat magna non pellentesque pulvinar. Nam a eleifend sapien. Suspendisse potenti. Vestibulum nunc massa, eleifend a dolor quis, feugiat condimentum est. Integer diam eros, blandit in purus in, euismod ultrices felis. Donec ipsum magna, elementum non lacus vel, rutrum ornare ante. Integer egestas sapien quam, ut posuere nisi rhoncus nec. Etiam ornare enim eu tellus laoreet, in laoreet urna sodales. Donec interdum, augue non lobortis sodales, leo elit tincidunt mi, vitae varius augue libero vel lectus. Cras imperdiet quis dolor nec gravida.
|
||||
<a href="#A1">top</a></p>
|
||||
}
|
||||
</div>
|
||||
};
|
||||
|
||||
(:~
|
||||
: get set of thumbnails matching search
|
||||
:)
|
||||
|
|
@ -146,12 +170,15 @@ let $geo:=$vue-api:entity?json?geo($image)
|
|||
let $keywords:=$vue-api:entity?json?keywords($image)
|
||||
let $thumb:= $cfg:THUMBDIR || $path
|
||||
let $thumb:=if(file:exists($thumb)) then $thumb else $cfg:THUMBDIR || "missing.jpg"
|
||||
return ( <id>{$id}</id>
|
||||
return (
|
||||
<id>{$id}</id>
|
||||
,<name>{$name}</name>
|
||||
,<path>{$path}</path>
|
||||
,$geo,$keywords
|
||||
,<data>{fetch:binary($thumb)}</data>
|
||||
,<mime>{fetch:content-type($thumb)}</mime>)
|
||||
,<mime>{fetch:content-type($thumb)}</mime>
|
||||
,<selected type="boolean">false</selected>
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -15,14 +15,34 @@
|
|||
<v-spacer></v-spacer>
|
||||
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
body
|
||||
</v-card-text>
|
||||
<v-progress-linear v-if="busy" v-bind:indeterminate="true" ></v-progress-linear>
|
||||
<v-card-text v-if="!busy" v-html="report"></v-card-text>
|
||||
</v-card>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>{
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@
|
|||
</v-card-title>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-text-field prepend-icon="search" label="Filter..." v-model="q" type="search"
|
||||
hide-details single-line @keyup.enter="setfilter"
|
||||
:append-icon="this.q?'clear':''" :append-icon-cb="e=>this.q=''"></v-text-field>
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
<v-progress-linear v-if="busy" v-bind:indeterminate="true" ></v-progress-linear>
|
||||
|
|
@ -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(){
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
@ -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";
|
||||
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
: <metadata/> -> <image/>
|
||||
:)
|
||||
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]
|
||||
|
|
@ -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;
|
||||
|
|
@ -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')]
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
: <idref>14569796 14569818 </idref>
|
||||
: </keyword>
|
||||
:)
|
||||
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)
|
||||
};
|
||||
|
|
@ -4,11 +4,12 @@
|
|||
: <idref>14569796 14569818 </idref>
|
||||
: </keyword>
|
||||
:)
|
||||
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:=<dates date="{current-dateTime()}">{
|
||||
for $image in collection($cfg:DB-IMAGE || "/image")/image[not(@original)]
|
||||
let $year:=substring($image/datetaken,1,4)
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
hide-details
|
||||
v-model="search"
|
||||
></v-text-field>
|
||||
<v-btn icon ><v-icon>add</v-icon></v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-btn
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<template id="map">
|
||||
<v-container fluid>
|
||||
<v-layout row wrap>
|
||||
<v-flex xs12 style="height:400px">
|
||||
<v-flex xs12 ref="page" v-resize="onResize" style="height:400px">
|
||||
<v-map :zoom="zoom" :center="center" >
|
||||
<v-tilelayer :url="url" :attribution="attribution"></v-tilelayer>
|
||||
<v-marker :lat-lng="marker"></v-marker>
|
||||
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<template id="svg">
|
||||
<v-container fluid>
|
||||
svg
|
||||
<div id="canvasqPWKOg" class="canvas"></div>
|
||||
<button id="resetButtonqPWKOg">Reset</button>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<template id="tabs">
|
||||
<v-tabs scroll-bars >
|
||||
<v-card >
|
||||
<v-card-actions>
|
||||
<v-btn icon >
|
||||
<v-icon>menu</v-icon>
|
||||
</v-btn>
|
||||
<v-card-title>Page Title</v-card-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon >
|
||||
<v-icon>search</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon >
|
||||
<v-icon>more_vert</v-icon>
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
<v-tabs scroll-bars fixed>
|
||||
|
||||
|
||||
<v-tabs-bar class="grey lighten-3" dense>
|
||||
<v-tabs-item
|
||||
|
|
@ -31,9 +17,26 @@
|
|||
<v-icon>close</v-icon>
|
||||
</v-btn>
|
||||
</v-tabs-item>
|
||||
<v-btn icon >
|
||||
<v-icon>menu</v-icon>
|
||||
</v-btn>
|
||||
<v-tabs-slider class="primary"></v-tabs-slider>
|
||||
</v-tabs-bar>
|
||||
|
||||
<v-card >
|
||||
<v-card-actions>
|
||||
<v-btn icon >
|
||||
<v-icon>menu</v-icon>
|
||||
</v-btn>
|
||||
<v-card-title>Page Title</v-card-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon >
|
||||
<v-icon>search</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon >
|
||||
<v-icon>more_vert</v-icon>
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
<v-tabs-items>
|
||||
<v-tabs-content v-for="i in 13"
|
||||
:key="i"
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
</v-card>
|
||||
</v-menu>
|
||||
</v-toolbar>
|
||||
<v-card-text v-resize="onResize" style="height:400px; " class="amber" ref="page">
|
||||
<v-card-text ref="page" v-resize="onResize" style="height:400px; " class="amber" >
|
||||
|
||||
<v-layout v-if="showOptions.includes('result')" style="height:100%" fill-height >
|
||||
<v-flex >
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
157
src/vue-poc/lib/pipeline.xqm
Normal file
157
src/vue-poc/lib/pipeline.xqm
Normal file
|
|
@ -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 <report>
|
||||
<status>{
|
||||
if(schematron:is-valid($svrl)) then 'valid' else 'invalid'
|
||||
}</status>
|
||||
{$svrl}
|
||||
</report>
|
||||
};
|
||||
|
||||
(:~ 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))
|
||||
};
|
||||
|
|
@ -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())
|
||||
};
|
||||
|
||||
(:~
|
||||
|
|
|
|||
|
|
@ -54,14 +54,14 @@ declare function http-created($location,$response){
|
|||
|
||||
(:~ CORS header with download option :)
|
||||
declare function headers($attachment,$response){
|
||||
(<restxq:response>
|
||||
(<rest:response>
|
||||
<http:response>
|
||||
<http:header name="Access-Control-Allow-Origin" value="*"/>
|
||||
{if($attachment)
|
||||
then <http:header name="Content-Disposition" value='attachment;filename="{$attachment}"'/>
|
||||
else ()}
|
||||
</http:response>
|
||||
</restxq:response>, $response)
|
||||
</rest: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){
|
||||
<restxq:response>
|
||||
<rest:response>
|
||||
<output:serialization-parameters>
|
||||
<output:method value="{$method}"/>
|
||||
</output:serialization-parameters>
|
||||
</restxq:response>
|
||||
</rest:response>
|
||||
};
|
||||
|
||||
(:~ headers for download :)
|
||||
declare function download-response($method,$filename){
|
||||
|
||||
<restxq:response>
|
||||
<rest:response>
|
||||
<output:serialization-parameters>
|
||||
<output:method value="{$method}"/>
|
||||
</output:serialization-parameters>
|
||||
<http:response>
|
||||
<http:header name="Content-Disposition" value='attachment;filename="{$filename}"'/>
|
||||
</http:response>
|
||||
</restxq:response>
|
||||
</rest:response>
|
||||
};
|
||||
|
||||
(:~
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
<xsl:param name="resources" as="xs:string" select="'resources/'" />
|
||||
|
||||
<xsl:variable name="css" select="'resources/base.css'" />
|
||||
<xsl:variable name="css" select="concat($resources,'base.css')" />
|
||||
|
||||
<xsl:template match="/">
|
||||
<html>
|
||||
|
|
@ -57,9 +57,11 @@
|
|||
|
||||
<xsl:template match="c:file">
|
||||
<li>
|
||||
<a href="{@name}/index.html">
|
||||
<a href="F{position()}/index.html">
|
||||
<xsl:value-of select="@name" />
|
||||
|
||||
</a>
|
||||
<xsl:value-of select="position()" />
|
||||
</li>
|
||||
</xsl:template>
|
||||
|
||||
|
|
|
|||
|
|
@ -89,11 +89,12 @@
|
|||
|
||||
<xsl:template match="doc:module">
|
||||
<h1>
|
||||
<xsl:value-of select="@type" />
|
||||
module 
|
||||
|
||||
<span class="namespace">
|
||||
<xsl:value-of select="doc:uri" />
|
||||
</span>
|
||||
 <xsl:value-of select="@type" />
|
||||
module
|
||||
</h1>
|
||||
<dl>
|
||||
<xsl:apply-templates select="doc:comment/doc:description" />
|
||||
|
|
|
|||
|
|
@ -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 <c:file/>
|
||||
: @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{})
|
||||
|
|
|
|||
|
|
@ -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"}},
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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:`
|
||||
<v-dialog v-model="value">
|
||||
<v-card>
|
||||
|
|
@ -625,7 +625,11 @@ Vue.filter('round', function(value, decimals) {
|
|||
|
||||
</v-layout>
|
||||
|
||||
<v-navigation-drawer left="" persistent="" v-model="showInfo" :disable-route-watcher="true">
|
||||
|
||||
|
||||
</v-card>
|
||||
<v-progress-linear v-if="busy" v-bind:indeterminate="true" height="2"></v-progress-linear>
|
||||
<v-navigation-drawer left="" absolute="" v-model="showInfo" :disable-route-watcher="true">
|
||||
<v-card flat="" tile="">
|
||||
<v-toolbar>
|
||||
<v-card-title>{{ selection[0] && selection[0].name }}</v-card-title>
|
||||
|
|
@ -638,10 +642,8 @@ Vue.filter('round', function(value, decimals) {
|
|||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-navigation-drawer>
|
||||
|
||||
</v-card>
|
||||
<v-progress-linear v-if="busy" v-bind:indeterminate="true" height="2"></v-progress-linear>
|
||||
</v-container>
|
||||
|
||||
`,
|
||||
|
||||
|
||||
|
|
@ -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) {
|
|||
</v-menu>
|
||||
<span>{{ path.join('/') }}</span>
|
||||
</v-tooltip>
|
||||
<v-toolbar-title>
|
||||
<span>{{ name }}</span>
|
||||
</v-toolbar-title>
|
||||
<v-tooltip top="">
|
||||
<span slot="activator">
|
||||
<v-chip v-if="dirty" label="" small="" class="red white--text">*</v-chip>
|
||||
<v-chip v-if="!dirty" label="" small="" class="green white--text">.</v-chip>
|
||||
</span>
|
||||
<span>Changed?</span>
|
||||
</v-tooltip>
|
||||
|
||||
<v-badge right="" v-model="dirty">
|
||||
<span slot="badge">*</span>
|
||||
<v-toolbar-title>{{ name }}</v-toolbar-title>
|
||||
</v-badge>
|
||||
<v-btn v-if="dirty" icon="" @click="save()">
|
||||
<v-icon>file_upload</v-icon>
|
||||
</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-menu left="" transition="v-fade-transition">
|
||||
<v-chip label="" small="" slot="activator">{{ mode }}</v-chip>
|
||||
|
|
@ -879,7 +879,7 @@ Vue.filter('round', function(value, decimals) {
|
|||
</v-tooltip>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon="" @click="acecmd('outline')" title="outline -todo">
|
||||
<v-icon>star</v-icon>
|
||||
<v-icon>label_outline</v-icon>
|
||||
</v-btn>
|
||||
|
||||
|
||||
|
|
@ -891,9 +891,7 @@ Vue.filter('round', function(value, decimals) {
|
|||
<v-icon>wrap_text</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-btn icon="" @click="save()">
|
||||
<v-icon>file_upload</v-icon>
|
||||
</v-btn>
|
||||
|
||||
|
||||
<v-btn icon="" @click="beautify()">
|
||||
<v-icon>format_align_center</v-icon>
|
||||
|
|
@ -901,34 +899,25 @@ Vue.filter('round', function(value, decimals) {
|
|||
<v-btn icon="" @click="clearDialog = true">
|
||||
<v-icon>delete</v-icon>
|
||||
</v-btn>
|
||||
<v-menu left="" transition="v-fade-transition">
|
||||
<v-btn icon="" slot="activator">
|
||||
<v-icon>help</v-icon>
|
||||
</v-btn>
|
||||
<v-list>
|
||||
<v-list-tile @click="acecmd('showSettingsMenu')" avatar="">
|
||||
<v-list-tile-avatar>
|
||||
<v-icon>settings</v-icon>
|
||||
</v-list-tile-avatar>
|
||||
<v-list-tile-title @click="acecmd('showSettingsMenu')">Show settings</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
|
||||
<v-list-tile @click="acecmd('showKeyboardShortcuts')" avatar="">
|
||||
<v-list-tile-avatar>
|
||||
<v-icon>keyboard</v-icon>
|
||||
</v-list-tile-avatar>
|
||||
<v-list-tile-title @click="acecmd('showKeyboardShortcuts')">Show keyboard commands</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
<v-menu left="" transition="v-fade-transition">
|
||||
<v-btn icon="" slot="activator">
|
||||
<v-icon>more_vert</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-list dense="">
|
||||
<v-list-tile v-for="t in mimeTypes" :key="t">
|
||||
<v-list-tile-title v-text="t" @click="setMode(t)"></v-list-tile-title>
|
||||
<v-list-tile @click="acecmd('showSettingsMenu')" avatar="">
|
||||
<v-list-tile-avatar>
|
||||
<v-icon>settings</v-icon>
|
||||
</v-list-tile-avatar>
|
||||
<v-list-tile-title @click="acecmd('showSettingsMenu')">Show ACE settings</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
|
||||
<v-list-tile @click="acecmd('showKeyboardShortcuts')" avatar="">
|
||||
<v-list-tile-avatar>
|
||||
<v-icon>keyboard</v-icon>
|
||||
</v-list-tile-avatar>
|
||||
<v-list-tile-title @click="acecmd('showKeyboardShortcuts')">Show ACE keyboard shortcuts</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
|
||||
|
|
@ -1129,44 +1118,58 @@ Entities
|
|||
const Eval=Vue.extend({template:`
|
||||
<v-container fluid="">
|
||||
<v-card>
|
||||
<v-toolbar dense="">
|
||||
|
||||
<v-toolbar>
|
||||
|
||||
|
||||
<v-menu offset-y="">
|
||||
<v-btn slot="activator">
|
||||
<v-icon>play_circle_outline</v-icon>
|
||||
Run</v-btn>
|
||||
<v-list>
|
||||
<v-list-tile @click="submit">
|
||||
<v-list-tile-title>Submit</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-divider></v-divider>
|
||||
<v-list-tile @click="run">
|
||||
<v-list-tile-title>Run</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-list-tile @click="plan">
|
||||
<v-list-tile-title>Show query plan</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
|
||||
</v-list>
|
||||
<v-menu offset-x="">
|
||||
<v-btn slot="activator" flat="" icon="" color="pink">
|
||||
<v-icon>label_outline</v-icon>
|
||||
</v-btn>
|
||||
<v-card>
|
||||
<v-card-title>Outline here</v-card-title>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-menu offset-x="">
|
||||
<v-btn slot="activator" flat="" icon="" color="pink">
|
||||
<v-icon>add_circle</v-icon>
|
||||
</v-btn>
|
||||
<v-card>
|
||||
<v-btn @click="imports">
|
||||
<v-icon>library_books</v-icon>
|
||||
Imports</v-btn>
|
||||
<v-btn @click="namespaces">
|
||||
<v-icon>label</v-icon>
|
||||
Namespaces</v-btn>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn @click="submit">
|
||||
<v-icon>play_circle_outline</v-icon>jobs:run
|
||||
</v-btn>
|
||||
<v-menu offset-y="">
|
||||
<v-btn icon="" color="primary" slot="activator"> <v-icon>more_vert</v-icon></v-btn>
|
||||
<v-btn slot="activator" flat="" icon="">
|
||||
<v-icon>more_vert</v-icon>
|
||||
</v-btn>
|
||||
<v-list dense="">
|
||||
<v-list-tile @click="plan">Show query plan</v-list-tile>
|
||||
</v-list>
|
||||
<v-list>
|
||||
<v-list-tile @click="hitme">hit me</v-list-tile>
|
||||
<v-subheader>More actions...</v-subheader>
|
||||
<v-divider></v-divider>
|
||||
|
||||
<v-list-tile @click="run">
|
||||
<v-list-tile-title>xquery:eval</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
|
||||
<v-list-tile @click="plan">
|
||||
<v-list-tile-title>Show query plan</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
|
||||
<v-list-tile @click="hitme">
|
||||
<v-list-tile-title>Test large result.</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
|
||||
|
||||
|
||||
</v-toolbar>
|
||||
|
||||
|
||||
|
|
@ -1178,7 +1181,7 @@ Entities
|
|||
|
||||
<v-card-actions v-if="show">
|
||||
|
||||
<v-chip class="primary white--text">{{jobId}}</v-chip>
|
||||
<v-chip class="primary white--text">{{job.result}}</v-chip>
|
||||
|
||||
<v-chip label="" class="grey white--text">
|
||||
<v-avatar class="red"> <v-icon>lock</v-icon>W</v-avatar>
|
||||
|
|
@ -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:`
|
||||
|
||||
<v-card>
|
||||
<v-toolbar class="green white--text">
|
||||
<v-toolbar dense="">
|
||||
<v-btn @click.stop="showFilter = true" icon=""><v-icon>search</v-icon></v-btn>
|
||||
<v-toolbar-title>{{ qtext }}</v-toolbar-title>
|
||||
<v-tooltip top="" v-if="query.keyword || query.from || query.until">
|
||||
|
|
@ -1522,55 +1532,65 @@ Entities
|
|||
</v-btn>
|
||||
<span>Clear search</span>
|
||||
</v-tooltip>
|
||||
<v-btn icon="" @click="getImages">
|
||||
<v-avatar>
|
||||
<v-icon>refresh</v-icon>
|
||||
</v-avatar>
|
||||
</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
<span v-if="!busy">
|
||||
<v-chip class="primary white--text">{{ total }} in {{ elapsed | round(2) }} secs </v-chip>
|
||||
|
||||
Page:{{ query.page+1 }}
|
||||
<v-btn @click.stop="pageBack()" :disabled="query.page==0" icon="" color="primary">
|
||||
<v-icon>arrow_back</v-icon>
|
||||
<v-toolbar-items v-if="!selection.length">
|
||||
<v-btn icon="" v-for="b in buttons" :key="b.icon" @click="action(b)">
|
||||
<v-avatar>
|
||||
<v-icon v-text="b.icon"></v-icon>
|
||||
</v-avatar>
|
||||
</v-btn>
|
||||
<v-btn @click.stop="pageNext()" icon="" color="primary">
|
||||
<v-icon>arrow_forward</v-icon>
|
||||
</v-toolbar-items>
|
||||
<v-toolbar-items v-if="selection.length">
|
||||
<v-btn icon="" v-for="b in selopts" :key="b.icon" @click="action(b)">
|
||||
<v-avatar>
|
||||
<v-icon v-text="b.icon"></v-icon>
|
||||
</v-avatar>
|
||||
</v-btn>
|
||||
</v-toolbar-items>
|
||||
</span>
|
||||
<v-spacer></v-spacer>
|
||||
<v-toolbar-items>
|
||||
<v-btn @click.stop="pageBack()" :disabled="query.page==0" icon="">
|
||||
<v-avatar>
|
||||
<v-icon>arrow_back</v-icon>
|
||||
</v-avatar>
|
||||
</v-btn>
|
||||
<v-btn @click.stop="pageNext()" icon="">
|
||||
<v-avatar>
|
||||
<v-icon>arrow_forward</v-icon>
|
||||
</v-avatar>
|
||||
</v-btn>
|
||||
</v-toolbar-items>
|
||||
|
||||
</v-toolbar>
|
||||
<v-progress-linear v-if="busy" v-bind:indeterminate="true"></v-progress-linear>
|
||||
<v-container v-if="!busy" fluid="" grid-list-md="">
|
||||
<v-layout row="" wrap="" v-touch="{ left: () => pageNext(), right: () => pageBack()}">
|
||||
<v-flex height="80px" xs2="" v-for="image in images" :key="image.name">
|
||||
<v-card class="grey lighten-2 pt-1">
|
||||
<v-card-media :src="src(image)" @dblclick="go(image)" height="80px" contain="">
|
||||
|
||||
<v-card flat="" tile="" class="grey lighten-2 pa-1">
|
||||
<v-card-media :src="src(image)" @dblclick="go(image)" @click.prevent.stop="image.selected =! image.selected " height="100px" contain="">
|
||||
<span v-if="image.keywords >0 ">#{{image.keywords}}</span>
|
||||
<v-avatar icon="" small="" v-if="image.geo">
|
||||
<v-icon>place</v-icon>
|
||||
</v-avatar>
|
||||
|
||||
|
||||
</v-card-media>
|
||||
|
||||
<v-card-actions>
|
||||
<v-tooltip bottom="">
|
||||
<v-btn icon="" small="" slot="activator">
|
||||
<v-icon>info</v-icon>
|
||||
</v-btn>
|
||||
<span v-text="image.path"></span>
|
||||
</v-tooltip>
|
||||
<span v-if="image.keywords >0 ">#{{image.keywords}}</span>
|
||||
<v-btn icon="" small="" v-if="image.geo">
|
||||
<v-icon>place</v-icon>
|
||||
</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-btn icon="" small="" @click="selected(image)">
|
||||
<v-icon>share</v-icon>
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
<div style="position:absolute;right:0;top:0">
|
||||
<div v-if="image.selected" style="position:absolute;right:0;top:0">
|
||||
<v-icon class="white primary--text">check_circle</v-icon>
|
||||
</div>
|
||||
</v-card></v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
|
||||
<v-navigation-drawer left="" persistent="" v-model="showFilter" :disable-route-watcher="true">
|
||||
<v-navigation-drawer left="" fixed="" v-model="showFilter" :disable-route-watcher="true">
|
||||
<v-card>
|
||||
<v-toolbar class="green white--text">
|
||||
<v-toolbar-title>Show images with...</v-toolbar-title>
|
||||
|
|
@ -1627,14 +1647,20 @@ Entities
|
|||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-navigation-drawer>
|
||||
<v-navigation-drawer left="" persistent="" v-model="showInfo" :disable-route-watcher="true">
|
||||
<v-navigation-drawer left="" fixed="" v-model="showInfo" :disable-route-watcher="true">
|
||||
<v-card>
|
||||
<v-toolbar class="green white--text">
|
||||
<v-toolbar-title>{{selitem.name}}</v-toolbar-title>
|
||||
<v-toolbar-title>{{selection.length}} selected</v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn flat="" icon="" @click="showInfo = false"><v-icon>highlight_off</v-icon></v-btn>
|
||||
</v-toolbar>
|
||||
<v-card-text> blah blah </v-card-text>
|
||||
<v-card-text>
|
||||
<ul>
|
||||
<li v-for="sel in selection" :key="sel.name">
|
||||
{{sel.name}} {{sel.path}}
|
||||
</li>
|
||||
</ul>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-navigation-drawer>
|
||||
|
||||
|
|
@ -1642,7 +1668,9 @@ Entities
|
|||
|
||||
`,
|
||||
|
||||
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
|
|||
<v-spacer></v-spacer>
|
||||
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
body
|
||||
</v-card-text>
|
||||
<v-progress-linear v-if="busy" v-bind:indeterminate="true"></v-progress-linear>
|
||||
<v-card-text v-if="!busy" v-html="report"></v-card-text>
|
||||
</v-card>
|
||||
</v-container>
|
||||
`,
|
||||
|
||||
|
||||
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
|
|||
</v-card-title>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-text-field prepend-icon="search" label="Filter..." v-model="q" type="search" hide-details="" single-line="" @keyup.enter="setfilter" :append-icon="this.q?'clear':''" :append-icon-cb="e=>this.q=''"></v-text-field>
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
<v-progress-linear v-if="busy" v-bind:indeterminate="true"></v-progress-linear>
|
||||
|
|
@ -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(){
|
||||
|
|
@ -1946,6 +2028,7 @@ people
|
|||
|
||||
<v-btn @click="stop()" :disabled="noSelection">Stop</v-btn>
|
||||
<v-text-field append-icon="search" label="Filter jobs" single-line="" hide-details="" v-model="search"></v-text-field>
|
||||
<v-btn icon=""><v-icon>add</v-icon></v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-btn icon="" :loading="loading" @click="getJobs()" @dblclick="autorefresh = !autorefresh" :disabled="loading">
|
||||
|
|
@ -2089,7 +2172,7 @@ people
|
|||
const Map=Vue.extend({template:`
|
||||
<v-container fluid="">
|
||||
<v-layout row="" wrap="">
|
||||
<v-flex xs12="" style="height:400px">
|
||||
<v-flex xs12="" ref="page" v-resize="onResize" style="height:400px">
|
||||
<v-map :zoom="zoom" :center="center">
|
||||
<v-tilelayer :url="url" :attribution="attribution"></v-tilelayer>
|
||||
<v-marker :lat-lng="marker"></v-marker>
|
||||
|
|
@ -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:`
|
||||
<v-container fluid="">
|
||||
svg
|
||||
<div id="canvasqPWKOg" class="canvas"></div>
|
||||
<button id="resetButtonqPWKOg">Reset</button>
|
||||
</v-container>
|
||||
`,
|
||||
|
||||
|
|
@ -2830,7 +2923,24 @@ svg
|
|||
|
||||
);
|
||||
const Tabs=Vue.extend({template:`
|
||||
<v-tabs scroll-bars="">
|
||||
<v-tabs scroll-bars="" fixed="">
|
||||
|
||||
|
||||
<v-tabs-bar class="grey lighten-3" dense="">
|
||||
<v-tabs-item v-for="i in 13" :key="i" :href="'#mobile-tabs-6-' + i">
|
||||
|
||||
<v-icon>favorite</v-icon>
|
||||
<span>Item {{ i }} more</span>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn small="" icon="" class="grey">
|
||||
<v-icon>close</v-icon>
|
||||
</v-btn>
|
||||
</v-tabs-item>
|
||||
<v-btn icon="">
|
||||
<v-icon>menu</v-icon>
|
||||
</v-btn>
|
||||
<v-tabs-slider class="primary"></v-tabs-slider>
|
||||
</v-tabs-bar>
|
||||
<v-card>
|
||||
<v-card-actions>
|
||||
<v-btn icon="">
|
||||
|
|
@ -2846,20 +2956,6 @@ svg
|
|||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
|
||||
<v-tabs-bar class="grey lighten-3">
|
||||
<v-tabs-item v-for="i in 13" :key="i" :href="'#mobile-tabs-6-' + i">
|
||||
|
||||
<v-icon>favorite</v-icon>
|
||||
<span>Item {{ i }} more</span>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn small="" icon="" class="grey">
|
||||
<v-icon>close</v-icon>
|
||||
</v-btn>
|
||||
</v-tabs-item>
|
||||
<v-tabs-slider class="primary"></v-tabs-slider>
|
||||
</v-tabs-bar>
|
||||
|
||||
<v-tabs-items>
|
||||
<v-tabs-content v-for="i in 13" :key="i" :id="'mobile-tabs-6-' + i">
|
||||
<v-card flat="">
|
||||
|
|
@ -3397,7 +3493,7 @@ created(){
|
|||
</v-card>
|
||||
</v-menu>
|
||||
</v-toolbar>
|
||||
<v-card-text v-resize="onResize" style="height:400px; " class="amber" ref="page">
|
||||
<v-card-text ref="page" v-resize="onResize" style="height:400px; " class="amber">
|
||||
|
||||
<v-layout v-if="showOptions.includes('result')" style="height:100%" fill-height="">
|
||||
<v-flex>
|
||||
|
|
@ -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:`
|
||||
<v-app id="app" :dark="dark">
|
||||
<v-navigation-drawer persistent="" v-model="drawerRight" right="" clipped="" :disable-route-watcher="true" app="">
|
||||
<v-navigation-drawer absolute="" v-model="showNotifications" right="" clipped="" :disable-route-watcher="true" app="">
|
||||
<v-card>
|
||||
<v-toolbar class="teal white--text">
|
||||
<v-toolbar-title>Notifications</v-toolbar-title>
|
||||
<v-toolbar-title>Notifications </v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn @click="drawerRight = false" icon=""><v-icon>close</v-icon></v-btn>
|
||||
<v-btn @click="showNotifications = false" icon=""><v-icon>close</v-icon></v-btn>
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
TODO
|
||||
<ul>
|
||||
<li v-for="msg in $notification.messages" :key="msg.index">
|
||||
{{msg.text}}
|
||||
</li>
|
||||
</ul>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-navigation-drawer>
|
||||
<v-navigation-drawer persistent="" app="" :mini-variant.sync="mini" v-model="drawer" :disable-route-watcher="true" :enable-resize-watcher="true">
|
||||
<v-navigation-drawer app="" :mini-variant.sync="mini" v-model="drawer" absolute="" :disable-route-watcher="true" :enable-resize-watcher="true">
|
||||
<v-list class="pa-0">
|
||||
|
||||
<v-list-tile avatar="" tag="div">
|
||||
|
|
@ -3598,11 +3710,12 @@ router.beforeEach((to, from, next) => {
|
|||
<v-toolbar class="indigo" app="" dark="">
|
||||
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
|
||||
<v-toolbar-title class="hidden-sm-and-down">{{$route.meta.title}}</v-toolbar-title>
|
||||
<v-btn @click="frmFav = !frmFav" icon="" flat="" title="Bookmark this page">
|
||||
<v-menu offset-x="" :close-on-content-click="false" :nudge-width="200" v-model="frmFav">
|
||||
<v-btn slot="activator" @click="frmFav = !frmFav" icon="" flat="" title="Bookmark this page">
|
||||
<v-icon>star_border</v-icon>
|
||||
</v-btn>
|
||||
<v-dialog v-model="frmFav">
|
||||
<v-card>
|
||||
|
||||
<v-card style="width:400px;">
|
||||
<v-toolbar class="amber">
|
||||
<v-card-title>
|
||||
Bookmark this page
|
||||
|
|
@ -3613,11 +3726,12 @@ router.beforeEach((to, from, next) => {
|
|||
<v-select v-model="tags" label="tags" chips="" tags="" :items="taglist"></v-select>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn color="primary" flat="" @click.stop="frmFav=false">Save</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="primary" flat="" @click.stop="frmFav=false">Cancel</v-btn>
|
||||
<v-btn color="primary" flat="" @click.stop="favorite();frmFav=false">Save</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-menu>
|
||||
<v-spacer></v-spacer>
|
||||
<v-text-field prepend-icon="search" label="Search..." v-model="q" hide-details="" single-line="" dark="" @keyup.enter="search"></v-text-field>
|
||||
<v-spacer></v-spacer>
|
||||
|
|
@ -3639,11 +3753,11 @@ router.beforeEach((to, from, next) => {
|
|||
</v-list>
|
||||
</v-menu>
|
||||
<qd-fullscreen></qd-fullscreen>
|
||||
<v-btn @click="notifications" icon="" flat="" title="Notifications">
|
||||
<v-btn @click="showNotifications = ! showNotifications" icon="" flat="" title="Notifications">
|
||||
<v-icon>notifications</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar>
|
||||
<main>
|
||||
|
||||
<v-content>
|
||||
<v-alert color="error" value="true" dismissible="" v-model="alert.show">
|
||||
<pre style="overflow:auto;">{{ alert.msg }}</pre>
|
||||
|
|
@ -3652,7 +3766,7 @@ router.beforeEach((to, from, next) => {
|
|||
<router-view class="view ma-3"></router-view>
|
||||
</transition>
|
||||
</v-content>
|
||||
</main>
|
||||
|
||||
</v-app>
|
||||
`,
|
||||
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -124,3 +124,34 @@ height: 100%;
|
|||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
|
|
@ -7,25 +7,22 @@
|
|||
<meta name="description" content="Vue poc" />
|
||||
<meta name="author" content="andy bunce." />
|
||||
<title>Vue Router Test</title>
|
||||
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic">
|
||||
<link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons">
|
||||
<link href="https://unpkg.com/vuetify@0.16.9/dist/vuetify.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="https://unpkg.com/vue-multiselect@2.0.0-beta.15/dist/vue-multiselect.min.css" rel="stylesheet" type="text/css">
|
||||
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic"/>
|
||||
<link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons"/>
|
||||
<link href="https://unpkg.com/vuetify@0.17.3/dist/vuetify.min.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="https://unpkg.com/vue-multiselect@2.0.0-beta.15/dist/vue-multiselect.min.css" rel="stylesheet" type="text/css"/>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css"
|
||||
integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ=="
|
||||
crossorigin=""/>
|
||||
<link href="/vue-poc/ui/app.css" rel="stylesheet" type="text/css">
|
||||
<link href="/vue-poc/ui/svg-pan-zoom.css" rel="stylesheet" type="text/css">
|
||||
<link href="/vue-poc/ui/app.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="/vue-poc/ui/svg-pan-zoom.css" rel="stylesheet" type="text/css"/>
|
||||
<link rel="shortcut icon" href="/vue-poc/ui/icon.png"/>
|
||||
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis-timeline-graph2d.min.css" />
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<h3><code>vue-poc</code> <small>(v0.2.??)</small> </h3>
|
||||
<h3><code>vue-poc</code> <small>(v0.3.??)</small> </h3>
|
||||
|
||||
<div class="spinner">
|
||||
<div class="rect1"></div>
|
||||
|
|
@ -37,26 +34,27 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.1/vue-router.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.1/axios.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.17.1/axios.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/qs/6.4.0/qs.js"></script>
|
||||
<script src="https://unpkg.com/vuetify@0.16.9/dist/vuetify.min.js"></script>
|
||||
<script src="https://unpkg.com/vuetify@0.17.3/dist/vuetify.min.js"></script>
|
||||
<script src="https://unpkg.com/vue-multiselect@2.0.0-beta.15/dist/vue-multiselect.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.9/ace.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.9/ext-language_tools.js"></script>
|
||||
<script src="https://d3js.org/d3.v3.min.js"></script>
|
||||
<script src="https://d3js.org/d3.v4.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.12/beautify.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.12/beautify-css.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.12/beautify-html.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/localforage/1.5.1/localforage.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis-timeline-graph2d.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/brutusin/json-forms@1.6.3/dist/js/brutusin-json-forms.js"></script>
|
||||
<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"
|
||||
integrity="sha512-lInM/apFSqyy1o6s89K4iQUKg6ppXEgsVxT35HbzUupEVRh2Eu9Wdl4tHj7dZO0s1uvplcYGmt3498TtHq+log=="
|
||||
crossorigin=""></script>
|
||||
<script src="https://unpkg.com/vue2-leaflet@0.0.55/dist/vue2-leaflet.js"></script>
|
||||
<script src="/vue-poc/ui/svg=pan-zoom.js"></script>
|
||||
<script src="/vue-poc/ui/svg-pan-zoom.js"></script>
|
||||
<script src="/vue-poc/ui/perf-stat.js"></script>
|
||||
<script src="/vue-poc/ui/app-gen.js"></script>
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1,77 +1,32 @@
|
|||
// 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";
|
||||
|
||||
var width = 500,
|
||||
height = 500,
|
||||
zoomEnabled = true,
|
||||
dragEnabled = true,
|
||||
scale = 1,
|
||||
translation = [0,0],
|
||||
base = null,
|
||||
wrapperBorder = 2,
|
||||
wrapperBorder = 0,
|
||||
minimap = null,
|
||||
minimapPadding = 20,
|
||||
minimapPadding = 10,
|
||||
minimapScale = 0.25;
|
||||
|
||||
function canvas(selection) {
|
||||
|
||||
base = selection;
|
||||
|
||||
var xScale = d3.scale.linear()
|
||||
.domain([-width / 2, width / 2])
|
||||
.range([0, width]);
|
||||
|
||||
var yScale = d3.scale.linear()
|
||||
.domain([-height / 2, height / 2])
|
||||
.range([height, 0]);
|
||||
|
||||
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)
|
||||
];
|
||||
}
|
||||
|
||||
d3.select(".panCanvas, .panCanvas .bg")
|
||||
.attr("transform", "translate(" + translation + ")" + " scale(" + scale + ")");
|
||||
|
||||
minimap.scale(scale).render();
|
||||
}; // startoff zoomed in a bit to show pan/zoom rectangle
|
||||
|
||||
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 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", "100%")
|
||||
.attr("height", "100%")
|
||||
.attr("viewBox", "0 0 "+w + " "+h)
|
||||
.attr("width", svgWidth)
|
||||
.attr("height", svgHeight)
|
||||
.attr("shape-rendering", "auto");
|
||||
|
||||
var svgDefs = svg.append("defs");
|
||||
|
||||
svgDefs.append("clipPath")
|
||||
.attr("id", "wrapperClipPath_qwpyza")
|
||||
.attr("class", "wrapper clipPath")
|
||||
|
|
@ -79,13 +34,11 @@ d3.demo = {};
|
|||
.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)
|
||||
//.attr("transform", "translate(" + (width + minimapPadding) + "," + (minimapPadding/2) + ")")
|
||||
.append("rect")
|
||||
.attr("class", "background")
|
||||
.attr("width", width)
|
||||
|
|
@ -97,45 +50,39 @@ d3.demo = {};
|
|||
.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"
|
||||
});
|
||||
.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");
|
||||
.attr("stop-color", "#EEEEEE")
|
||||
minimapRadialFill.append("stop")
|
||||
.attr("offset", "100%")
|
||||
.attr("stop-color", "#E0E0E0");
|
||||
|
|
@ -143,7 +90,6 @@ d3.demo = {};
|
|||
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)
|
||||
|
|
@ -152,8 +98,7 @@ d3.demo = {};
|
|||
var innerWrapper = outerWrapper.append("g")
|
||||
.attr("class", "wrapper inner")
|
||||
.attr("clip-path", "url(#wrapperClipPath_qwpyza)")
|
||||
.attr("transform", "translate(" + (wrapperBorder) + "," + (wrapperBorder) + ")")
|
||||
.call(zoom);
|
||||
.attr("transform", "translate(" + (wrapperBorder) + "," + (wrapperBorder) + ")");
|
||||
|
||||
innerWrapper.append("rect")
|
||||
.attr("class", "background")
|
||||
|
|
@ -171,8 +116,39 @@ d3.demo = {};
|
|||
.attr("width", width)
|
||||
.attr("height", height);
|
||||
|
||||
var zoom = d3.zoom()
|
||||
.scaleExtent([0.5, 5]);
|
||||
|
||||
// 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()
|
||||
.zoom(zoom)
|
||||
.host(canvas)
|
||||
.target(panCanvas)
|
||||
.minimapScale(minimapScale)
|
||||
.x(width + minimapPadding)
|
||||
|
|
@ -180,33 +156,23 @@ d3.demo = {};
|
|||
|
||||
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);
|
||||
.attr("width", width + (wrapperBorder*2) + minimapPadding*2 + (width*minimapScale))
|
||||
.attr("height", height + (wrapperBorder*2));
|
||||
|
||||
outerWrapper
|
||||
.select(".background")
|
||||
.attr("width", width + wrapperBorder*2)
|
||||
|
|
@ -231,22 +197,24 @@ d3.demo = {};
|
|||
.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);
|
||||
//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.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();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -266,46 +234,66 @@ d3.demo = {};
|
|||
return this;
|
||||
};
|
||||
|
||||
canvas.scale = function(value) {
|
||||
if (!arguments.length) { return scale; }
|
||||
scale = value;
|
||||
return this;
|
||||
};
|
||||
|
||||
return canvas;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** MINIMAP **/
|
||||
d3.demo.minimap = function() {
|
||||
/** MINIMAP **/
|
||||
d3.demo.minimap = function() {
|
||||
|
||||
"use strict";
|
||||
|
||||
var minimapScale = 0.15,
|
||||
scale = 1,
|
||||
zoom = null,
|
||||
host = null,
|
||||
base = null,
|
||||
target = null,
|
||||
width = 0,
|
||||
height = 0,
|
||||
x = 0,
|
||||
y = 0,
|
||||
frameX = 0,
|
||||
frameY = 0;
|
||||
y = 0;
|
||||
|
||||
function minimap(selection) {
|
||||
|
||||
base = selection;
|
||||
|
||||
var zoom = d3.zoom()
|
||||
.scaleExtent([0.5, 5]);
|
||||
|
||||
// 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);
|
||||
|
||||
var container = selection.append("g")
|
||||
.attr("class", "minimap")
|
||||
.call(zoom);
|
||||
|
||||
zoom.on("zoom.minimap", function() {
|
||||
scale = d3.event.scale;
|
||||
});
|
||||
.attr("class", "minimap");
|
||||
|
||||
container.call(zoom);
|
||||
|
||||
minimap.node = container.node();
|
||||
|
||||
|
|
@ -316,42 +304,39 @@ d3.demo = {};
|
|||
.attr("class", "background")
|
||||
.attr("width", width)
|
||||
.attr("height", height)
|
||||
.attr("filter", "url(#minimapDropShadow_qwpyza)");
|
||||
.attr("filter", "url(#minimapDropShadow_qPWKOg)");
|
||||
|
||||
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);
|
||||
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() {
|
||||
scale = zoom.scale();
|
||||
// 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);
|
||||
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);
|
||||
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);
|
||||
frame.node().parentNode.appendChild(frame.node());
|
||||
d3.select(node).attr("transform", "translate(1,1)");
|
||||
};
|
||||
|
||||
updateMinimapZoomExtents();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -388,11 +373,11 @@ d3.demo = {};
|
|||
};
|
||||
|
||||
|
||||
minimap.scale = function(value) {
|
||||
if (!arguments.length) { return scale; }
|
||||
scale = value;
|
||||
minimap.host = function(value) {
|
||||
if (!arguments.length) { return host;}
|
||||
host = value;
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
minimap.minimapScale = function(value) {
|
||||
|
|
@ -402,13 +387,6 @@ d3.demo = {};
|
|||
};
|
||||
|
||||
|
||||
minimap.zoom = function(value) {
|
||||
if (!arguments.length) return zoom;
|
||||
zoom = value;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
minimap.target = function(value) {
|
||||
if (!arguments.length) { return target; }
|
||||
target = value;
|
||||
|
|
@ -418,19 +396,24 @@ d3.demo = {};
|
|||
};
|
||||
|
||||
return minimap;
|
||||
};
|
||||
};
|
||||
|
||||
/** RUN SCRIPT **/
|
||||
var canvasWidth = 800;
|
||||
|
||||
/** 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];
|
||||
};
|
||||
var canvas = d3.demo.canvas().width(435).height(400);
|
||||
d3.select("#canvasqPWKOg").call(canvas);
|
||||
|
||||
d3.select("#resetButtonqPWKOg").on("click", function() {
|
||||
canvas.reset();
|
||||
});
|
||||
|
||||
/** RUN SCRIPT **/
|
||||
|
||||
//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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
<template id="vuepoc">
|
||||
<v-app id="app" :dark="dark" >
|
||||
<v-navigation-drawer
|
||||
persistent
|
||||
v-model="drawerRight"
|
||||
absolute
|
||||
v-model="showNotifications"
|
||||
right
|
||||
clipped
|
||||
:disable-route-watcher="true"
|
||||
|
|
@ -11,16 +11,20 @@
|
|||
>
|
||||
<v-card>
|
||||
<v-toolbar class="teal white--text">
|
||||
<v-toolbar-title >Notifications</v-toolbar-title>
|
||||
<v-toolbar-title >Notifications </v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn @click="drawerRight = false" icon><v-icon>close</v-icon></v-btn>
|
||||
<v-btn @click="showNotifications = false" icon><v-icon>close</v-icon></v-btn>
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
TODO
|
||||
<ul>
|
||||
<li v-for="msg in $notification.messages" :key="msg.index">
|
||||
{{msg.text}}
|
||||
</li>
|
||||
</ul>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-navigation-drawer>
|
||||
<v-navigation-drawer persistent app :mini-variant.sync="mini" v-model="drawer"
|
||||
<v-navigation-drawer app :mini-variant.sync="mini" v-model="drawer" absolute
|
||||
:disable-route-watcher="true" :enable-resize-watcher="true">
|
||||
<v-list class="pa-0">
|
||||
|
||||
|
|
@ -47,11 +51,17 @@
|
|||
<v-toolbar class="indigo" app dark >
|
||||
<v-toolbar-side-icon @click.stop="drawer = !drawer" ></v-toolbar-side-icon>
|
||||
<v-toolbar-title class="hidden-sm-and-down" >{{$route.meta.title}}</v-toolbar-title>
|
||||
<v-btn @click="frmFav = !frmFav" icon flat title="Bookmark this page">
|
||||
<v-menu
|
||||
offset-x
|
||||
:close-on-content-click="false"
|
||||
:nudge-width="200"
|
||||
v-model="frmFav"
|
||||
>
|
||||
<v-btn slot="activator" @click="frmFav = !frmFav" icon flat title="Bookmark this page">
|
||||
<v-icon>star_border</v-icon>
|
||||
</v-btn>
|
||||
<v-dialog v-model="frmFav">
|
||||
<v-card>
|
||||
|
||||
<v-card style="width:400px;">
|
||||
<v-toolbar class="amber">
|
||||
<v-card-title>
|
||||
Bookmark this page
|
||||
|
|
@ -68,11 +78,12 @@
|
|||
></v-select>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn color="primary" flat @click.stop="frmFav=false">Save</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="primary" flat @click.stop="frmFav=false">Cancel</v-btn>
|
||||
<v-btn color="primary" flat @click.stop="favorite();frmFav=false">Save</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-menu>
|
||||
<v-spacer></v-spacer>
|
||||
<v-text-field prepend-icon="search" label="Search..." v-model="q"
|
||||
hide-details single-line dark @keyup.enter="search"></v-text-field>
|
||||
|
|
@ -95,11 +106,11 @@
|
|||
</v-list>
|
||||
</v-menu>
|
||||
<qd-fullscreen></qd-fullscreen>
|
||||
<v-btn @click="notifications" icon flat title="Notifications">
|
||||
<v-btn @click="showNotifications = ! showNotifications" icon flat title="Notifications">
|
||||
<v-icon>notifications</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar>
|
||||
<main>
|
||||
|
||||
<v-content>
|
||||
<v-alert color="error" value="true" dismissible v-model="alert.show">
|
||||
<pre style="overflow:auto;">{{ alert.msg }}</pre>
|
||||
|
|
@ -108,7 +119,7 @@
|
|||
<router-view class="view ma-3"></router-view>
|
||||
</transition>
|
||||
</v-content>
|
||||
</main>
|
||||
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
|
|
@ -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
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue