After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.4 KiB |
@ -0,0 +1,82 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const canvas = document.querySelector('.vis-canvas')
|
||||
|
||||
const nodes = new vis.DataSet([])
|
||||
const edges = new vis.DataSet([])
|
||||
|
||||
const network = new vis.Network(canvas, {
|
||||
nodes: nodes,
|
||||
edges: edges
|
||||
}, {
|
||||
manipulation: true
|
||||
})
|
||||
|
||||
const instanceLabel = (inst, schema) => `${inst.name}\n${schema.name}`
|
||||
|
||||
const addNode = (toAdd) => {
|
||||
try {
|
||||
nodes.add({
|
||||
id: toAdd.uuid,
|
||||
label: instanceLabel(toAdd, toAdd.schema)
|
||||
})
|
||||
} catch(e) {
|
||||
console.debug(e)
|
||||
}
|
||||
}
|
||||
const addOutEdges = (fromId, toAdd) => {
|
||||
toAdd.forEach((inst) => {
|
||||
try {
|
||||
edges.add({
|
||||
from: fromId,
|
||||
to: inst.uuid,
|
||||
label: inst['link-name'],
|
||||
arrows: {
|
||||
to: {enabled: true}
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.debug(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
const addLinkedNodes = (toAdd) => {
|
||||
toAdd.forEach((inst) => {
|
||||
try {
|
||||
console.debug(inst.name)
|
||||
nodes.add({
|
||||
id: inst.uuid,
|
||||
label: instanceLabel(inst, inst.schema)
|
||||
})
|
||||
} catch (e) {
|
||||
console.debug(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const addInstance = (instance) => {
|
||||
addNode(instance)
|
||||
addLinkedNodes(instance['links-out'])
|
||||
addOutEdges(instance.uuid, instance['links-out'])
|
||||
}
|
||||
|
||||
fetch(canvas.getAttribute('data-instance-url'))
|
||||
.then((resp) => resp.json())
|
||||
.then((json) => {
|
||||
addInstance(json)
|
||||
})
|
||||
|
||||
const searchForm = document.querySelector('.search')
|
||||
const searchUrl = searchForm.getAttribute('action')
|
||||
searchForm.addEventListener('submit', (event) => {
|
||||
event.preventDefault()
|
||||
const term = searchForm.querySelector('[name=term]').value
|
||||
fetch(searchUrl + encodeURIComponent(term))
|
||||
.then((resp) => resp.json())
|
||||
.then((json) => {
|
||||
console.debug(json)
|
||||
json.forEach((inst) => {
|
||||
addInstance(inst)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
@ -1,10 +1,22 @@
|
||||
(ns wanijo.visualisation.view
|
||||
(:require [hiccup.page :refer [include-js]]
|
||||
(:require [hiccup.page :refer [include-js include-css]]
|
||||
[hiccup.form :as hform]
|
||||
[wanijo.framework.routing :refer [path]]
|
||||
[wanijo.framework.view :as view]))
|
||||
|
||||
(defn index [req]
|
||||
(defn index [instance-uuid req]
|
||||
(view/layout!
|
||||
:request req
|
||||
:head (list (include-css "/css/vis-network.min.css")
|
||||
(include-js "/js/vis-network.min.js"
|
||||
"/js/vis.js"))
|
||||
:content
|
||||
[[:h1 "Visualisation"]
|
||||
[:div#visualisation]]))
|
||||
[[:h1 "Explore"]
|
||||
[:form.search {:action (path :vis-search-instance {:term ""})}
|
||||
(hform/label "term" "Search Instance")
|
||||
(hform/text-field {:autofocus true} "term")
|
||||
[:input {:style "display: none" :type "submit"}]]
|
||||
[:div.vis-canvas {:data-instance-url (path :vis-get-instance
|
||||
{:uuid instance-uuid})}]
|
||||
[:p.flash--warn
|
||||
"Changes to the visualisation will not (yet) mirror to the actual database"]]))
|
||||
|