diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000000000000000000000000000000000000..812cc42671d1fcdb02d6329a030669a865a8d5dd --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,14 @@ +{ + "env": { + "es6": true, + "browser": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": 8, + "sourceType": "module" + }, + "rules": { + "no-console": 0 + } +} \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..b6c56942faaca59907e27596ea3154ff66cdd949 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "tabWidth": 4 +} \ No newline at end of file diff --git a/config.js b/config.js index a1070ec12f399bbff7b84eacdf5b2b56a55fe2af..9d779cef924c92582868a1ea46762df72293bdcc 100644 --- a/config.js +++ b/config.js @@ -1,9 +1,9 @@ -const COLOR_PALETTE = [ - 'rgb(104, 169, 77)', - 'rgb(102, 75, 154)', - 'rgb(41, 171, 226)', - 'rgb(224, 133, 35)', - 'rgb(214, 207, 126)', - 'rgb(239, 65, 35)', - 'rgb(255, 255, 255)' -]; \ No newline at end of file +export const COLOR_PALETTE = [ + "rgb(104, 169, 77)", + "rgb(102, 75, 154)", + "rgb(41, 171, 226)", + "rgb(224, 133, 35)", + "rgb(214, 207, 126)", + "rgb(239, 65, 35)", + "rgb(255, 255, 255)", +]; diff --git a/display/graph.js b/display/graph.js index da72f0be68e505982f9f36b3878aabea8b895ba0..e6eb010be832a762356216a257a81e511ce02785 100644 --- a/display/graph.js +++ b/display/graph.js @@ -1,3 +1,13 @@ +import * as Config from "../config"; +import * as Helpers from "./helpers"; +import { InfoOverlay } from "./infooverlay"; +import { LinkOverlay } from "./linkoverlay"; + +import * as THREE from 'three'; +import ForceGraph3D from '3d-force-graph'; + +import { CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer.js' +import { CSS3DRenderer, CSS3DSprite } from 'three/examples/jsm/renderers/CSS3DRenderer.js' class Graph { constructor(dataUrl) { @@ -16,34 +26,37 @@ class Graph { this.edgeTypeVisibility = {}; this.loadGraph(dataUrl); - } async loadGraph(dataUrl) { - this.gData = await fetch(dataUrl).then(res => res.json()) - this.graph = ForceGraph3D({extraRenderers: [new THREE.CSS2DRenderer(), new THREE.CSS3DRenderer()]}) - (document.getElementById('3d-graph')) + this.gData = await fetch(dataUrl).then((res) => res.json()); + this.graph = ForceGraph3D({ + extraRenderers: [ + new CSS2DRenderer(), + new CSS3DRenderer(), + ], + })(document.getElementById("3d-graph")) .graphData(this.gData) - .nodeLabel('id') - .nodeAutoColorBy('group') - .nodeColor(node => this.getNodeColor(node)) - .linkWidth(link => this.getLinkWidth(link)) - .onNodeClick(node => { + .nodeLabel("id") + .nodeAutoColorBy("group") + .nodeColor((node) => this.getNodeColor(node)) + .linkWidth((link) => this.getLinkWidth(link)) + .onNodeClick((node) => { this.focusOnNode(node); this.infooverlay.updateInfoOverlay(node); }) - .onNodeHover(node => { + .onNodeHover((node) => { this.onNodeHover(node); this.updateHighlight(); }) - .onLinkHover(link => this.onLinkHover(link)) - .linkColor(link => this.getLinkColor(link)) + .onLinkHover((link) => this.onLinkHover(link)) + .linkColor((link) => this.getLinkColor(link)) .linkOpacity(0.8) .nodeThreeObjectExtend(false) - .nodeThreeObject(node => this.drawNode(node)) + .nodeThreeObject((node) => this.drawNode(node)) .onEngineTick(() => this.initializeModel()) - .width(getWidth()) - .height(getHeight()); + .width(Helpers.getWidth()) + .height(Helpers.getHeight()); } initializeModel() { @@ -59,20 +72,26 @@ class Graph { document.addEventListener("fullscreenchange", () => this.resize()); window.addEventListener("resize", () => this.resize()); - this.getLinkClasses().forEach(item => this.edgeTypeVisibility[item] = true); + this.getLinkClasses().forEach( + (item) => (this.edgeTypeVisibility[item] = true) + ); this.firstTick = false; } } getNodeColor(node) { - return this.highlightNodes.has(node) ? node === hoverNode ? 'rgb(255,0,0,1)' : 'rgba(255,160,0,0.8)' : 'rgba(0,255,255,0.6)'; + return this.highlightNodes.has(node) + ? node === hoverNode + ? "rgb(255,0,0,1)" + : "rgba(255,160,0,0.8)" + : "rgba(0,255,255,0.6)"; } getLinkColor(link) { - if ('type' in link) { - return this.edgeColors[link.type] + if ("type" in link) { + return this.edgeColors[link.type]; } - return 'rgb(255, 255, 255)' + return "rgb(255, 255, 255)"; } getLinkWidth(link) { @@ -81,20 +100,28 @@ class Graph { getLinkClasses() { const linkClasses = []; - this.graph.graphData().links.forEach(link => linkClasses.push(link.type)); - return [... new Set(linkClasses)]; + this.graph + .graphData() + .links.forEach((link) => linkClasses.push(link.type)); + return [...new Set(linkClasses)]; } onNodeHover(node) { // no state change - if ((!node && !this.highlightNodes.size) || (node && this.hoverNode === node)) return; + if ( + (!node && !this.highlightNodes.size) || + (node && this.hoverNode === node) + ) + return; this.highlightNodes.clear(); this.highlightLinks.clear(); if (node) { this.highlightNodes.add(node); - node.neighbors.forEach(neighbor => this.highlightNodes.add(neighbor)); - node.links.forEach(link => this.highlightLinks.add(link)); + node.neighbors.forEach((neighbor) => + this.highlightNodes.add(neighbor) + ); + node.links.forEach((link) => this.highlightLinks.add(link)); } this.hoverNode = node || null; @@ -120,12 +147,16 @@ class Graph { // Aim at node from outside it const distance = 250; - const distRatio = 1 + distance/Math.hypot(node.x, node.y, node.z); + const distRatio = 1 + distance / Math.hypot(node.x, node.y, node.z); this.graph.cameraPosition( - { x: node.x * distRatio, y: node.y * distRatio, z: node.z * distRatio }, // new position + { + x: node.x * distRatio, + y: node.y * distRatio, + z: node.z * distRatio, + }, // new position node, // lookAt ({ x, y, z }) - 1000 // ms transition duration + 1000 // ms transition duration ); } @@ -153,10 +184,10 @@ class Graph { removeFloatingNodes() { const gData = this.graph.graphData(); - const nodes = gData.nodes.filter(node => node.neighbors.length > 0); + const nodes = gData.nodes.filter((node) => node.neighbors.length > 0); const data = { nodes: nodes, - links: gData.links + links: gData.links, }; this.graph.graphData(data); } @@ -164,7 +195,9 @@ class Graph { updateGraphData() { const data = { nodes: this.gData.nodes, - links: this.gData.links.filter(l => this.edgeTypeVisibility[l.type]) + links: this.gData.links.filter( + (l) => this.edgeTypeVisibility[l.type] + ), }; this.graph.graphData(data); } @@ -182,7 +215,7 @@ class Graph { // cross-link node objects this.resetNodeData(); - gData.links.forEach(link => { + gData.links.forEach((link) => { const a = link.source; const b = link.target; a.neighbors.push(b); @@ -190,7 +223,7 @@ class Graph { a.links.push(link); b.links.push(link); }); - this.graph.graphData(gData) + this.graph.graphData(gData); } updateHighlight() { @@ -203,18 +236,18 @@ class Graph { updateNodeMap() { const gData = this.graph.graphData(); - gData.nodes.forEach(node => { + gData.nodes.forEach((node) => { this.idToNode[node.id] = node; - }) + }); } resize() { - if(document.fullscreenElement == getCanvasDivNode()) { + if (document.fullscreenElement == Helpers.getCanvasDivNode()) { this.graph.height(screen.height); this.graph.width(screen.width); } else { this.graph.height(window.innerHeight - 200); - this.graph.width(getWidth()); + this.graph.width(Helpers.getWidth()); } } @@ -223,7 +256,10 @@ class Graph { //const planeGeometry = new THREE.PlaneGeometry(1000, 1000, 1, 1); const loader = new THREE.TextureLoader(); //const planeMaterial = new THREE.MeshLambertMaterial({color: 0xFF0000, side: THREE.DoubleSide}); //THREE.BackSide - const planeMaterial = new THREE.MeshBasicMaterial({map: loader.load(plugin_path + 'backgrounds/background_4.jpg'), side: THREE.DoubleSide}); //THREE.BackSide + const planeMaterial = new THREE.MeshBasicMaterial({ + map: loader.load(plugin_path + "backgrounds/background_4.jpg"), + side: THREE.DoubleSide, + }); //THREE.BackSide const mesh = new THREE.Mesh(sphereGeometry, planeMaterial); mesh.position.set(0, 0, 0); //mesh.rotation.set(0.5 * Math.PI, 0, 0); @@ -232,55 +268,67 @@ class Graph { } mapEdgeColors() { - const linkClasses = this.getLinkClasses() + const linkClasses = this.getLinkClasses(); for (let i = 0; i < linkClasses.length; i++) { - this.edgeColors[linkClasses[i]] = COLOR_PALETTE[i % COLOR_PALETTE.length] + this.edgeColors[linkClasses[i]] = + Config.COLOR_PALETTE[i % Config.COLOR_PALETTE.length]; } } drawNode(node) { // Draw node as label + image - const nodeDiv = document.createElement('div'); + const nodeDiv = document.createElement("div"); const group = new THREE.Group(); - const labelDiv = document.createElement('div') + const labelDiv = document.createElement("div"); labelDiv.textContent = node.name; labelDiv.style.color = node.color; - labelDiv.className = 'node-label'; + labelDiv.className = "node-label"; nodeDiv.appendChild(labelDiv); - const cssobj = new THREE.CSS3DSprite(nodeDiv); + const cssobj = new CSS3DSprite(nodeDiv); cssobj.scale.set(0.25, 0.25, 0.25); cssobj.position.set(0, -6, 0); - group.add(cssobj) + group.add(cssobj); // Draw node circle image const textureLoader = new THREE.TextureLoader(); - const imageAlpha = textureLoader.load(plugin_path + 'datasets/images/alpha.png'); + const imageAlpha = textureLoader.load( + plugin_path + "datasets/images/alpha.png" + ); let imageTexture = null; - if ('image' in node) { - imageTexture = textureLoader.load(plugin_path + 'datasets/images/' + node.image); + if ("image" in node) { + imageTexture = textureLoader.load( + plugin_path + "datasets/images/" + node.image + ); } else { - imageTexture = textureLoader.load(plugin_path + 'datasets/images/default.jpg'); + imageTexture = textureLoader.load( + plugin_path + "datasets/images/default.jpg" + ); } - const material = new THREE.SpriteMaterial({map: imageTexture, alphaMap: imageAlpha, transparent: true, - alphaTest: 0.2, depthWrite:false, depthTest: false}); + const material = new THREE.SpriteMaterial({ + map: imageTexture, + alphaMap: imageAlpha, + transparent: true, + alphaTest: 0.2, + depthWrite: false, + depthTest: false, + }); const sprite = new THREE.Sprite(material); sprite.renderOrder = 999; // This may not be optimal. But it allows us to render the sprite on top of everything else. - if ('image' in node) { + if ("image" in node) { sprite.scale.set(20, 20); } else { sprite.scale.set(5, 5); } - group.add(sprite) + group.add(sprite); return group; } - } function loadComponents() { @@ -289,15 +337,14 @@ function loadComponents() { createFullScreenButton(); } - function createFullScreenButton() { - const sceneNode = getCanvasDivNode(); - const overlayNode = document.createElement('div'); - overlayNode.className = 'fullscreen-button'; - overlayNode.innerHTML = '<p>⤢</p>'; + const sceneNode = Helpers.getCanvasDivNode(); + const overlayNode = document.createElement("div"); + overlayNode.className = "fullscreen-button"; + overlayNode.innerHTML = "<p>⤢</p>"; overlayNode.addEventListener("click", function () { if (!document.fullscreenElement) { - getCanvasDivNode().requestFullscreen(); + Helpers.getCanvasDivNode().requestFullscreen(); } else { document.exitFullscreen(); } @@ -306,7 +353,7 @@ function createFullScreenButton() { sceneNode.appendChild(overlayNode); } -const dataUrl = plugin_path + 'datasets/aud1.json' +const dataUrl = plugin_path + "datasets/aud1.json"; G = new Graph(dataUrl); linkoverlay = new LinkOverlay(G); infooverlay = new InfoOverlay(G); diff --git a/display/helpers.js b/display/helpers.js index 38d9e76fa057a026edd98b7d57531f8bf90dbaac..e4b7d94dad5b92cb32db57a415b60989ee314771 100644 --- a/display/helpers.js +++ b/display/helpers.js @@ -1,15 +1,15 @@ +export {getWidth, getHeight, getCanvasDivNode} + function getWidth() { - return document.getElementById('3d-graph').offsetWidth; + return document.getElementById("3d-graph").offsetWidth; } - function getHeight() { - return window.innerHeight - 200 + return window.innerHeight - 200; } - function getCanvasDivNode() { - const domNode = document.getElementById('3d-graph'); + const domNode = document.getElementById("3d-graph"); return domNode.firstChild.firstChild.firstChild; -} \ No newline at end of file +} diff --git a/display/infooverlay.js b/display/infooverlay.js index 3f8598f63864602777fa131e64cb753aa2b02ae5..d0a3c7d96d97b7f536a950dfdd05757ce3fac68b 100644 --- a/display/infooverlay.js +++ b/display/infooverlay.js @@ -1,4 +1,6 @@ +import * as Helpers from "./helpers"; +export { InfoOverlay }; class InfoOverlay { constructor(graph) { @@ -13,40 +15,36 @@ class InfoOverlay { create() { const overlayDiv = this.createOverlayMainDiv(); this.createOverlayElements(overlayDiv); - this.createBottomMenu(overlayDiv) + this.createBottomMenu(overlayDiv); - jQuery('#infoOverlayCloseButton').click(function () { - jQuery('#infoOverlay').slideUp('fast'); + jQuery("#infoOverlayCloseButton").click(function () { + jQuery("#infoOverlay").slideUp("fast"); }); - } createBottomMenu(overlayNode) { - - const bottomContainerDiv = document.createElement('div'); - bottomContainerDiv.className = 'bottom-container'; + const bottomContainerDiv = document.createElement("div"); + bottomContainerDiv.className = "bottom-container"; overlayNode.appendChild(bottomContainerDiv); - const bottomContainerNavDiv = document.createElement('div'); - bottomContainerNavDiv.className = 'bottom-container-nav'; + const bottomContainerNavDiv = document.createElement("div"); + bottomContainerNavDiv.className = "bottom-container-nav"; bottomContainerDiv.appendChild(bottomContainerNavDiv); - const bottomContainerLinkDiv = document.createElement('div'); - bottomContainerLinkDiv.className = 'bottom-container-links'; + const bottomContainerLinkDiv = document.createElement("div"); + bottomContainerLinkDiv.className = "bottom-container-links"; bottomContainerDiv.appendChild(bottomContainerLinkDiv); - for(const [cls, color] of Object.entries(this.graph.edgeColors)) { - - const navTab = document.createElement('div'); - navTab.className = 'bottom-container-nav-tab'; + for (const [cls, color] of Object.entries(this.graph.edgeColors)) { + const navTab = document.createElement("div"); + navTab.className = "bottom-container-nav-tab"; navTab.innerText = cls.slice(0, 3); navTab.style = "background-color: " + color; navTab.edgeType = cls; - //tablink.setAttribute("onclick", "openTab(event, " + linkType + "_id)"); //unusual function call bottomContainerNavDiv.appendChild(navTab); - jQuery(navTab).click(event => this.openTab(event)) + jQuery(navTab).click((event) => this.openTab(event)); - const tabContent = document.createElement('div'); + const tabContent = document.createElement("div"); tabContent.className = "bottom-container-tab-content"; tabContent.id = cls + "_id_content"; tabContent.style = "background-color: " + color; @@ -60,7 +58,6 @@ class InfoOverlay { this.activeTabContent.classList.add("active-tab-content"); this.activeTabNav.classList.add("active-tab-nav"); this.activeTabNav.innerText = this.activeTabNav.edgeType; - } openTab(event) { @@ -80,70 +77,76 @@ class InfoOverlay { } createOverlayMainDiv() { - const sceneNode = getCanvasDivNode(); - const overlayNode = document.createElement('div'); - overlayNode.id = 'infoOverlay' - overlayNode.className = 'detail-view'; + const sceneNode = Helpers.getCanvasDivNode(); + const overlayNode = document.createElement("div"); + overlayNode.id = "infoOverlay"; + overlayNode.className = "detail-view"; //overlayNode.innerText = 'Hello there!'; sceneNode.insertBefore(overlayNode, sceneNode.childNodes[2]); return overlayNode; } createOverlayElements(overlayNode) { - const close = document.createElement('div'); - close.innerHTML = '<p>✖</p>'; - close.id = 'infoOverlayCloseButton'; - close.className = 'close-button'; + const close = document.createElement("div"); + close.innerHTML = "<p>✖</p>"; + close.id = "infoOverlayCloseButton"; + close.className = "close-button"; overlayNode.appendChild(close); - const infoArea = document.createElement('div'); - infoArea.className = 'detail-view-info-area'; + const infoArea = document.createElement("div"); + infoArea.className = "detail-view-info-area"; overlayNode.appendChild(infoArea); - const topArea = document.createElement('div'); - topArea.className = 'detail-view-top-area'; + const topArea = document.createElement("div"); + topArea.className = "detail-view-top-area"; infoArea.appendChild(topArea); - const nodeImage = document.createElement('img'); - nodeImage.id = 'infoOverlayImage'; - nodeImage.src = plugin_path + 'datasets/images/default.jpg'; - nodeImage.className = 'detail-view-image'; + const nodeImage = document.createElement("img"); + nodeImage.id = "infoOverlayImage"; + nodeImage.src = plugin_path + "datasets/images/default.jpg"; + nodeImage.className = "detail-view-image"; topArea.appendChild(nodeImage); - const headline = document.createElement('h2'); - headline.id = 'infoOverlayHeadline'; - headline.innerText = 'Default Text'; - headline.className = 'detail-view-headline'; + const headline = document.createElement("h2"); + headline.id = "infoOverlayHeadline"; + headline.innerText = "Default Text"; + headline.className = "detail-view-headline"; topArea.appendChild(headline); - const textArea = document.createElement('div'); - textArea.className = 'detail-view-text-area'; + const textArea = document.createElement("div"); + textArea.className = "detail-view-text-area"; infoArea.appendChild(textArea); - const description = document.createElement('p'); - description.id = 'infoOverlayDescription'; - description.innerText = 'Default Text' + const description = document.createElement("p"); + description.id = "infoOverlayDescription"; + description.innerText = "Default Text"; description.setAttribute("overflow-y", "scroll"); textArea.appendChild(description); } updateInfoOverlay(node) { - jQuery('#infoOverlayHeadline').text(node.name); - if ('image' in node) { - jQuery('#infoOverlayImage').attr('src', plugin_path + 'datasets/images/' + node.image); + jQuery("#infoOverlayHeadline").text(node.name); + if ("image" in node) { + jQuery("#infoOverlayImage").attr( + "src", + plugin_path + "datasets/images/" + node.image + ); } else { - jQuery('#infoOverlayImage').attr('src', plugin_path + 'datasets/images/default.jpg'); + jQuery("#infoOverlayImage").attr( + "src", + plugin_path + "datasets/images/default.jpg" + ); } - if ('description' in node) { - jQuery('#infoOverlayDescription').text(node.description); + if ("description" in node) { + jQuery("#infoOverlayDescription").text(node.description); } else { - jQuery('#infoOverlayDescription').text('Default Text'); + jQuery("#infoOverlayDescription").text("Default Text"); } this.updateTabs(node); - jQuery('#infoOverlay').slideDown('fast'); + jQuery("#infoOverlay").slideDown("fast"); } clearTabContentPages() { @@ -153,23 +156,23 @@ class InfoOverlay { } createReference(target) { - const linkDiv = document.createElement('div'); //and if so a new element is created + const linkDiv = document.createElement("div"); linkDiv.className = "link-img"; - if ('image' in target) { - const linkImage = document.createElement('img'); - linkImage.src = plugin_path + 'datasets/images/' + target.image; + if ("image" in target) { + const linkImage = document.createElement("img"); + linkImage.src = plugin_path + "datasets/images/" + target.image; linkDiv.appendChild(linkImage); } - jQuery(linkDiv).on('click', () => { + jQuery(linkDiv).on("click", () => { this.graph.focusOnNode(target); this.updateInfoOverlay(target); }); return linkDiv; } - updateTabs(node){ + updateTabs(node) { this.clearTabContentPages(); for (const link of node.links) { @@ -178,5 +181,4 @@ class InfoOverlay { this.tabContentPages[link.type].appendChild(reference); } } - -} \ No newline at end of file +} diff --git a/display/linkoverlay.js b/display/linkoverlay.js index 5d0f084400dc0f735e24c395a5a66ee364ac0c6b..18e3912a1900af3f5ef3eec07c99ab39c87f044a 100644 --- a/display/linkoverlay.js +++ b/display/linkoverlay.js @@ -1,43 +1,54 @@ +import * as Helpers from "./helpers"; +export { LinkOverlay }; class LinkOverlay { constructor(graph) { - this.graph = graph + this.graph = graph; } create() { - const sceneNode = getCanvasDivNode(); - const overlayNode = document.createElement('div'); - overlayNode.className = 'link-overlay'; + const sceneNode = Helpers.getCanvasDivNode(); + const overlayNode = document.createElement("div"); + overlayNode.className = "link-overlay"; //overlayNode.innerText = 'Hello there!'; - sceneNode.insertBefore(overlayNode, sceneNode.childNodes[2]) + sceneNode.insertBefore(overlayNode, sceneNode.childNodes[2]); const linkClasses = this.graph.getLinkClasses(); - const chars = Math.max.apply(Math, linkClasses.map(function (c) { return c.length; })); + const chars = Math.max.apply( + Math, + linkClasses.map(function (c) { + return c.length; + }) + ); for (const link of linkClasses) { - const relation = document.createElement('div'); - relation.className = 'relation'; + const relation = document.createElement("div"); + relation.className = "relation"; relation.edgeType = link; relation.innerHTML = "<p>" + link + "</p>"; jQuery(relation).click((event) => this.toggleLinkVisibility(event)); overlayNode.appendChild(relation); - const colorStrip = document.createElement('div'); - colorStrip.className = 'rel-container'; - colorStrip.style = "background-color: " + this.graph.edgeColors[link] + "; width: " + 10 * chars + "px;"; + const colorStrip = document.createElement("div"); + colorStrip.className = "rel-container"; + colorStrip.style = + "background-color: " + + this.graph.edgeColors[link] + + "; width: " + + 10 * chars + + "px;"; relation.appendChild(colorStrip); } } toggleLinkVisibility(event) { const target = event.currentTarget; - this.graph.toggleLinkVisibility(target.edgeType) + this.graph.toggleLinkVisibility(target.edgeType); if (getComputedStyle(target).opacity == 1.0) { target.style.opacity = 0.4; } else { target.style.opacity = 1.0; } } - -} \ No newline at end of file +} diff --git a/index.js b/index.js new file mode 100644 index 0000000000000000000000000000000000000000..b9e98c56c957c974ebd8daa1b3d843db081de6cc --- /dev/null +++ b/index.js @@ -0,0 +1,3 @@ +import "./kg-style.css"; + +import "./display/graph"; diff --git a/kg-style.css b/kg-style.css index 3549aebf369d41669da21aeaeaf5631d97e2d2e7..58f0b450ed1cdad72c543cdd46c3be100514c207 100644 --- a/kg-style.css +++ b/kg-style.css @@ -4,12 +4,12 @@ .detail-view-info-area::-webkit-scrollbar { width: 6px; - background-color: #F5F5F5; + background-color: #f5f5f5; } .detail-view-info-area::-webkit-scrollbar-track { - -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); - background-color: #F5F5F5; + -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); + background-color: #f5f5f5; } .detail-view-info-area::-webkit-scrollbar-thumb { @@ -19,12 +19,12 @@ .bottom-container-tab-content::-webkit-scrollbar { width: 6px; height: 8px; - background-color: #F5F5F5; + background-color: #f5f5f5; } .bottom-container-tab-content::-webkit-scrollbar-track { - -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); - background-color: #F5F5F5; + -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); + background-color: #f5f5f5; } .bottom-container-tab-content::-webkit-scrollbar-thumb { @@ -38,7 +38,7 @@ /*text-align: center;*/ padding: 1px 4px; border-radius: 4px; - background-color: rgba(0,0,0,0.7); + background-color: rgba(0, 0, 0, 0.7); user-select: none; z-index: 1; } @@ -109,13 +109,12 @@ .detail-view-headline { font-weight: bold; /*text-align: center;*/ - font-family: CuratorRegular,Helvetica Neue,Helvetica,Arial,sans-serif; + font-family: CuratorRegular, Helvetica Neue, Helvetica, Arial, sans-serif; word-wrap: break-word; hyphens: auto; - font-size: 2.0vw; + font-size: 2vw; } - .link-overlay { position: absolute; bottom: 0; @@ -125,7 +124,7 @@ padding: 10px; left: 0; display: block; - background-color: rgba(0,0,0,.6); + background-color: rgba(0, 0, 0, 0.6); } .relation { @@ -134,14 +133,14 @@ color: #fff; font-size: 13px; line-height: 20px; - font-family: CuratorRegular,Helvetica Neue,Helvetica,Arial,sans-serif; + font-family: CuratorRegular, Helvetica Neue, Helvetica, Arial, sans-serif; text-transform: uppercase; margin-bottom: 6px; height: 17px; z-index: 100; cursor: pointer; pointer-events: all; - opacity: 1.0; + opacity: 1; } .rel-container { @@ -192,7 +191,6 @@ display: block; } - .link-img { min-width: 70px; width: 70px; diff --git a/knowledge-space.php b/knowledge-space.php index a620ae4fbc996421d82f9024da1cafd9e3f3ebd3..a7299cf60d5d75c863c248ce54d332476a88ba90 100644 --- a/knowledge-space.php +++ b/knowledge-space.php @@ -7,12 +7,10 @@ Version: 1.0 Author: Matthias Konitzny */ +$GLOBALS['build'] = 'debug'; + function ks_add_graph(): string { - $graph = '<script src="//unpkg.com/3d-force-graph"></script>'; - $three = '<script src="//unpkg.com/three@0.130.0"></script>'; - $renderer = '<script src="//unpkg.com/three@0.130.0/examples/js/renderers/CSS2DRenderer.js"></script>'; - $renderer2 = '<script src="//unpkg.com/three@0.130.0/examples/js/renderers/CSS3DRenderer.js"></script>'; $div = '<div id="3d-graph"></div>'; $plugin_dir = plugin_dir_url(__FILE__); //$dataset = $plugin_dir.'datasets/miserables.json'; @@ -20,22 +18,11 @@ function ks_add_graph(): string var plugin_path = '$plugin_dir'; </script>"; - // Yeah this is pretty ugly - need packaging asap. - - $script_path0 = $plugin_dir.'config.js'; - $script_path1 = $plugin_dir.'display'.DIRECTORY_SEPARATOR.'helpers.js'; - $script_path2 = $plugin_dir.'display'.DIRECTORY_SEPARATOR.'infooverlay.js'; - $script_path3 = $plugin_dir.'display'.DIRECTORY_SEPARATOR.'linkoverlay.js'; - $script_path4 = $plugin_dir.'display'.DIRECTORY_SEPARATOR.'graph.js'; - - $script0 = "<script src='$script_path0'></script>"; - $script1 = "<script src='$script_path1'></script>"; - $script2 = "<script src='$script_path2'></script>"; - $script3 = "<script src='$script_path3'></script>"; - $script4 = "<script src='$script_path4'></script>"; - - - return $three . $renderer . $renderer2 . $graph . $div . $variables . $script0 . $script1 . $script2 . $script3 . $script4; + $script_path = $plugin_dir.'build'.DIRECTORY_SEPARATOR.$GLOBALS['build'].DIRECTORY_SEPARATOR.'graph.js'; + $script = "<script src='$script_path'></script>"; + //wp_enqueue_script('kg-script', $script_path); + + return $div . $variables. $script; } function ks_add_editor() @@ -72,14 +59,14 @@ function ks_enqueue_script($relative_path, $dependencies = array()) $type = "script"; $script_name = end(explode("/", $relative_path)); $script_name = explode(".", $script_name)[0]; - + for ($i = 0; $i < sizeof($dependencies); $i++) { $dependencies[$i] = $prefix . "-" . $dependencies[$i] . "-" . $type; } - + // Source: https://developer.wordpress.org/reference/functions/wp_enqueue_script/ a comment from Andrija Naglic // $file_version = date("ymd-Gis", filemtime(plugin_dir_path(__FILE__) . $relative_path)); - + wp_enqueue_script($prefix . "-" . $script_name . "-" . $type, plugins_url($relative_path, __FILE__), $dependencies, false); } @@ -89,21 +76,21 @@ function ks_enqueue_style($relative_path, $dependencies = array()) $type = "style"; $style_name = end(explode("/", $relative_path)); $style_name = explode(".", $style_name)[0]; - + for ($i = 0; $i < sizeof($dependencies); $i++) { $dependencies[$i] = $prefix . "-" . $dependencies[$i] . "-" . $type; } - + // Source: https://developer.wordpress.org/reference/functions/wp_enqueue_script/ a comment from Andrija Naglic $file_version = date("ymd-Gis", filemtime(plugin_dir_path(__FILE__) . $relative_path)); - + wp_enqueue_style($prefix . "-" . $style_name . "-" . $type, plugins_url($relative_path, __FILE__), $dependencies, $file_version); } function kg_load_css() { $plugin_dir = plugin_dir_url(__FILE__); - wp_enqueue_style('kg-style', $plugin_dir . 'kg-style.css'); + wp_enqueue_style('kg-style', $plugin_dir.'kg-style.css'); } add_action('wp_enqueue_scripts', 'kg_load_css'); diff --git a/package.json b/package.json new file mode 100644 index 0000000000000000000000000000000000000000..072b05efff2fb956a8502d7202b4fc7bd71013a1 --- /dev/null +++ b/package.json @@ -0,0 +1,44 @@ +{ + "name": "knowledge-space", + "version": "1.0.0", + "description": "A Wordpress-Plugin to display knowledge in a graph-structured way.", + "main": "index.js", + "debug": "build/debug/graph.js", + "release": "build/debug/graph.js", + "targets": { + "main": false, + "debug": { + "distDir": "build/debug/" + }, + "release": { + "distDir": "build/release/" + } + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "watch": "parcel watch index.js" + }, + "repository": { + "type": "git", + "url": "https://gitlab.ibr.cs.tu-bs.de/alg/knowledge-space-wp-plugin.git" + }, + "keywords": [ + "Knowledge", + "Graph", + "Wordpress", + "Plugin" + ], + "author": "", + "license": "ISC", + "devDependencies": { + "@babel/core": "^7.14.8", + "@babel/eslint-parser": "^7.14.9", + "eslint": "^7.32.0", + "parcel": "^2.0.0-rc.0", + "prettier": "^2.3.2" + }, + "dependencies": { + "3d-force-graph": "^1.70.5", + "three": "^0.131.2" + } +}