WebVOWL_work
Changes
src/app/css/toolstyle.css 64(+58 -6)
src/app/js/sidebar.js 389(+111 -278)
src/index.html 59(+6 -53)
Details
src/app/css/toolstyle.css 64(+58 -6)
diff --git a/src/app/css/toolstyle.css b/src/app/css/toolstyle.css
index 9caec37..2bddc81 100644
--- a/src/app/css/toolstyle.css
+++ b/src/app/css/toolstyle.css
@@ -965,15 +965,67 @@ main {
width: auto;
box-sizing: border-box;
height: 100%;
+ overflow-y: auto;
+ padding: 8px;
}
-#generalDetails span #about {
- border-bottom: solid 1px #34495e;
- display: block;
- padding: 10px;
- text-align: center;
- word-wrap: break-word;
+.panel-language {
+ padding: 6px 0 10px;
+ color: #ecf0f1;
+ font-size: 0.85em;
+}
+
+.panel-section-title {
+ color: #aac;
+ font-size: 0.8em;
+ font-weight: bold;
+ text-transform: uppercase;
+ letter-spacing: 0.08em;
+ margin: 12px 0 4px;
+ padding-bottom: 4px;
+ border-bottom: 1px solid #34495e;
+}
+
+.annotation-panel {
+ margin-bottom: 8px;
+}
+
+.annotation-row {
+ display: flex;
+ font-size: 0.82em;
+ line-height: 1.4;
+ padding: 2px 0;
+ border-bottom: 1px solid #1e2a35;
+ word-break: break-word;
+}
+
+.annotation-name {
+ flex: 0 0 38%;
+ color: #8ab;
+ padding-right: 6px;
+ font-weight: 600;
+}
+
+.annotation-value {
+ flex: 1;
+ color: #ecf0f1;
+ font-weight: 100;
+}
+
+.annotation-value a {
color: #69c;
+ text-decoration: none;
+}
+
+.annotation-value a:hover {
+ text-decoration: underline;
+}
+
+.no-selection-hint {
+ color: #8ab;
+ font-size: 0.82em;
+ font-style: italic;
+ padding: 4px 0;
}
#generalDetails h4 {
src/app/js/sidebar.js 389(+111 -278)
diff --git a/src/app/js/sidebar.js b/src/app/js/sidebar.js
index 1265ea5..e36a681 100644
--- a/src/app/js/sidebar.js
+++ b/src/app/js/sidebar.js
@@ -58,35 +58,8 @@ module.exports = function ( graph ){
}
sidebar.clearOntologyInformation = function (){
-
- d3.select("#title").text("No title available");
- d3.select("#about").attr("href", "#").attr("target", "_blank").text("not given");
- d3.select("#version").text("--");
- d3.select("#authors").text("--");
- d3.select("#description").text("No description available.");
- var container = d3.select("#ontology-metadata");
- container.selectAll("*").remove();
- d3.select("#classCount")
- .text("0");
- d3.select("#objectPropertyCount")
- .text("0");
- d3.select("#datatypePropertyCount")
- .text("0");
- d3.select("#individualCount")
- .text("0");
- d3.select("#nodeCount")
- .text("0");
- d3.select("#edgeCount")
- .text("0");
-
- // clear selectedNode info
- var isTriggerActive = d3.select("#selection-details-trigger").classed("accordion-trigger-active");
- if ( isTriggerActive ) {
- // close accordion
- d3.select("#selection-details-trigger").node().click();
- }
- showSelectionAdvice();
-
+ d3.select("#ontology-panel").selectAll("*").remove();
+ clearSelectedNodePanel();
};
/**
@@ -97,14 +70,35 @@ module.exports = function ( graph ){
sidebar.updateOntologyInformation = function ( data, statistics ){
data = data || {};
ontologyInfo = data.header || {};
-
- updateGraphInformation();
- displayGraphStatistics(undefined, statistics);
- displayMetadata(ontologyInfo.other);
-
- // Reset the sidebar selection
+
+ var panel = d3.select("#ontology-panel");
+ panel.selectAll("*").remove();
+
+ renderPair(panel, "IRI", ontologyInfo.iri, ontologyInfo.iri);
+ var title = languageTools.textInLanguage(ontologyInfo.title, graph.language());
+ renderPair(panel, "Title", title);
+ renderPair(panel, "Version", ontologyInfo.version);
+ var authors = ontologyInfo.author;
+ if ( authors instanceof Array ) authors = authors.join(", ");
+ renderPair(panel, "Author", authors);
+ var description = languageTools.textInLanguage(ontologyInfo.description, graph.language());
+ renderPair(panel, "Description", description);
+
+ var other = ontologyInfo.other || {};
+ for ( var key in other ) {
+ if ( other.hasOwnProperty(key) ) {
+ var ann = other[key][0];
+ if ( ann ) {
+ renderPair(panel, ann.identifier, ann.value, ann.type === "iri" ? ann.value : undefined);
+ }
+ }
+ }
+
+ if ( panel.selectAll(".annotation-row").size() === 0 ) {
+ panel.append("p").classed("no-selection-hint", true).text("No ontology information available.");
+ }
+
sidebar.updateSelectionInformation(undefined);
-
setLanguages(ontologyInfo.languages);
};
@@ -162,76 +156,18 @@ module.exports = function ( graph ){
return false;
}
- function updateGraphInformation(){
- var title = languageTools.textInLanguage(ontologyInfo.title, graph.language());
- d3.select("#title").text(title || "No title available");
- d3.select("#about").attr("href", ontologyInfo.iri).attr("target", "_blank").text(ontologyInfo.iri);
- d3.select("#version").text(ontologyInfo.version || "--");
- var authors = ontologyInfo.author;
- if ( typeof authors === "string" ) {
- // Stay compatible with author info as strings after change in january 2015
- d3.select("#authors").text(authors);
- } else if ( authors instanceof Array ) {
- d3.select("#authors").text(authors.join(", "));
- } else {
- d3.select("#authors").text("--");
- }
-
- var description = languageTools.textInLanguage(ontologyInfo.description, graph.language());
- d3.select("#description").text(description || "No description available.");
+ function renderPair( container, name, value, iri ){
+ if ( !value && value !== 0 ) return;
+ var row = container.append("div").classed("annotation-row", true);
+ row.append("span").classed("annotation-name", true).text(name);
+ var valSpan = row.append("span").classed("annotation-value", true);
+ appendIriLabel(valSpan, value, iri);
}
-
- function displayGraphStatistics( deliveredMetrics, statistics ){
- // Metrics are optional and may be undefined
- deliveredMetrics = deliveredMetrics || {};
-
- d3.select("#classCount")
- .text(deliveredMetrics.classCount || statistics.classCount());
- d3.select("#objectPropertyCount")
- .text(deliveredMetrics.objectPropertyCount || statistics.objectPropertyCount());
- d3.select("#datatypePropertyCount")
- .text(deliveredMetrics.datatypePropertyCount || statistics.datatypePropertyCount());
- d3.select("#individualCount")
- .text(deliveredMetrics.totalIndividualCount || statistics.totalIndividualCount());
- d3.select("#nodeCount")
- .text(statistics.nodeCount());
- d3.select("#edgeCount")
- .text(statistics.edgeCount());
- }
-
- function displayMetadata( metadata ){
- var container = d3.select("#ontology-metadata");
- container.selectAll("*").remove();
-
- listAnnotations(container, metadata);
-
- if ( container.selectAll(".annotation").size() <= 0 ) {
- container.append("p").text("No annotations available.");
- }
- }
-
- function listAnnotations( container, annotationObject ){
- annotationObject = annotationObject || {}; //todo
-
- // Collect the annotations in an array for simpler processing
- var annotations = [];
- for ( var annotation in annotationObject ) {
- if ( annotationObject.hasOwnProperty(annotation) ) {
- annotations.push(annotationObject[annotation][0]);
- }
- }
-
- container.selectAll(".annotation").remove();
- container.selectAll(".annotation").data(annotations).enter().append("p")
- .classed("annotation", true)
- .classed("statisticDetails", true)
- .text(function ( d ){
- return d.identifier + ":";
- })
- .append("span")
- .each(function ( d ){
- appendIriLabel(d3.select(this), d.value, d.type === "iri" ? d.value : undefined);
- });
+
+ function clearSelectedNodePanel(){
+ var panel = d3.select("#selected-node-panel");
+ panel.selectAll("*").remove();
+ panel.append("p").classed("no-selection-hint", true).text("Select an element in the visualization.");
}
/**
@@ -240,106 +176,78 @@ module.exports = function ( graph ){
*/
sidebar.updateSelectionInformation = function ( selectedElement ){
lastSelectedElement = selectedElement;
-
- // Click event was prevented when dragging
+
if ( d3.event && d3.event.defaultPrevented ) {
return;
}
-
- var isTriggerActive = d3.select("#selection-details-trigger").classed("accordion-trigger-active");
- if ( selectedElement && !isTriggerActive ) {
- d3.select("#selection-details-trigger").node().click();
- } else if ( !selectedElement && isTriggerActive ) {
- showSelectionAdvice();
+
+ if ( !selectedElement ) {
+ clearSelectedNodePanel();
return;
}
-
+
if ( elementTools.isProperty(selectedElement) ) {
displayPropertyInformation(selectedElement);
} else if ( elementTools.isNode(selectedElement) ) {
displayNodeInformation(selectedElement);
}
};
-
- function showSelectionAdvice(){
- setSelectionInformationVisibility(false, false, true);
- }
-
- function setSelectionInformationVisibility( showClasses, showProperties, showAdvice ){
- d3.select("#classSelectionInformation").classed("hidden", !showClasses);
- d3.select("#propertySelectionInformation").classed("hidden", !showProperties);
- d3.select("#noSelectionInformation").classed("hidden", !showAdvice);
- }
-
+
function displayPropertyInformation( property ){
- showPropertyInformations();
-
- setIriLabel(d3.select("#propname"), property.labelForCurrentLanguage(), property.iri());
- d3.select("#typeProp").text(property.type());
-
- if ( property.inverse() !== undefined ) {
- d3.select("#inverse").classed("hidden", false);
- setIriLabel(d3.select("#inverse span"), property.inverse().labelForCurrentLanguage(), property.inverse().iri());
- } else {
- d3.select("#inverse").classed("hidden", true);
- }
-
- var equivalentIriSpan = d3.select("#propEquivUri");
- listNodeArray(equivalentIriSpan, property.equivalents());
-
- listNodeArray(d3.select("#subproperties"), property.subproperties());
- listNodeArray(d3.select("#superproperties"), property.superproperties());
-
+ var panel = d3.select("#selected-node-panel");
+ panel.selectAll("*").remove();
+
+ renderPair(panel, "IRI", property.iri(), property.iri());
+ renderPair(panel, "Label", property.labelForCurrentLanguage());
+ renderPair(panel, "Type", property.type());
+
+ if ( property.domain() ) renderPair(panel, "Domain", property.domain().labelForCurrentLanguage(), property.domain().iri());
+ if ( property.range() ) renderPair(panel, "Range", property.range().labelForCurrentLanguage(), property.range().iri());
+ if ( property.inverse() ) renderPair(panel, "Inverse", property.inverse().labelForCurrentLanguage(), property.inverse().iri());
+
+ renderNodeArrayPairs(panel, "Equivalent", property.equivalents());
+ renderNodeArrayPairs(panel, "Subproperty", property.subproperties());
+ renderNodeArrayPairs(panel, "Superproperty", property.superproperties());
+
if ( property.minCardinality() !== undefined ) {
- d3.select("#infoCardinality").classed("hidden", true);
- d3.select("#minCardinality").classed("hidden", false);
- d3.select("#minCardinality span").text(property.minCardinality());
- d3.select("#maxCardinality").classed("hidden", false);
-
- if ( property.maxCardinality() !== undefined ) {
- d3.select("#maxCardinality span").text(property.maxCardinality());
- } else {
- d3.select("#maxCardinality span").text("*");
- }
-
+ renderPair(panel, "Min. cardinality", property.minCardinality());
+ renderPair(panel, "Max. cardinality", property.maxCardinality() !== undefined ? property.maxCardinality() : "*");
} else if ( property.cardinality() !== undefined ) {
- d3.select("#minCardinality").classed("hidden", true);
- d3.select("#maxCardinality").classed("hidden", true);
- d3.select("#infoCardinality").classed("hidden", false);
- d3.select("#infoCardinality span").text(property.cardinality());
- } else {
- d3.select("#infoCardinality").classed("hidden", true);
- d3.select("#minCardinality").classed("hidden", true);
- d3.select("#maxCardinality").classed("hidden", true);
+ renderPair(panel, "Cardinality", property.cardinality());
}
-
- setIriLabel(d3.select("#domain"), property.domain().labelForCurrentLanguage(), property.domain().iri());
- setIriLabel(d3.select("#range"), property.range().labelForCurrentLanguage(), property.range().iri());
-
- displayAttributes(property.attributes(), d3.select("#propAttributes"));
-
- setTextAndVisibility(d3.select("#propDescription"), property.descriptionForCurrentLanguage());
- setTextAndVisibility(d3.select("#propComment"), property.commentForCurrentLanguage());
-
- listAnnotations(d3.select("#propertySelectionInformation"), property.annotations());
+
+ var attrs = getAttributes(property.attributes());
+ if ( attrs ) renderPair(panel, "Characteristics", attrs);
+
+ renderPair(panel, "Description", property.descriptionForCurrentLanguage());
+ renderPair(panel, "Comment", property.commentForCurrentLanguage());
+
+ renderAnnotationPairs(panel, property.annotations());
}
- function showPropertyInformations(){
- setSelectionInformationVisibility(false, true, false);
+ function getAttributes( attributes ){
+ if ( !attributes || attributes.length === 0 ) return null;
+ var filtered = attributes.filter(function ( a ){ return a !== "object" && a !== "datatype" && a !== "rdf"; });
+ return filtered.length > 0 ? filtered.join(", ") : null;
}
-
- function setIriLabel( element, name, iri ){
- var parent = d3.select(element.node().parentNode);
-
- if ( name ) {
- element.selectAll("*").remove();
- appendIriLabel(element, name, iri);
- parent.classed("hidden", false);
- } else {
- parent.classed("hidden", true);
+
+ function renderNodeArrayPairs( panel, label, nodes ){
+ if ( !nodes || nodes.length === 0 ) return;
+ nodes.forEach(function ( el ){
+ renderPair(panel, label, el.labelForCurrentLanguage(), el.iri());
+ });
+ }
+
+ function renderAnnotationPairs( panel, annotationObject ){
+ annotationObject = annotationObject || {};
+ for ( var key in annotationObject ) {
+ if ( annotationObject.hasOwnProperty(key) ) {
+ var ann = annotationObject[key][0];
+ if ( ann ) renderPair(panel, ann.identifier, ann.value, ann.type === "iri" ? ann.value : undefined);
+ }
}
}
-
+
function appendIriLabel( element, name, iri ){
var tag;
@@ -354,100 +262,25 @@ module.exports = function ( graph ){
tag.text(name);
}
- function displayAttributes( attributes, textSpan ){
- var spanParent = d3.select(textSpan.node().parentNode);
-
- if ( attributes && attributes.length > 0 ) {
- // Remove redundant redundant attributes for sidebar
- removeElementFromArray("object", attributes);
- removeElementFromArray("datatype", attributes);
- removeElementFromArray("rdf", attributes);
- }
-
- if ( attributes && attributes.length > 0 ) {
- textSpan.text(attributes.join(", "));
-
- spanParent.classed("hidden", false);
- } else {
- spanParent.classed("hidden", true);
- }
- }
-
- function removeElementFromArray( element, array ){
- var index = array.indexOf(element);
- if ( index > -1 ) {
- array.splice(index, 1);
- }
- }
-
function displayNodeInformation( node ){
- showClassInformations();
-
- setIriLabel(d3.select("#name"), node.labelForCurrentLanguage(), node.iri());
-
- /* Equivalent stuff. */
- var equivalentIriSpan = d3.select("#classEquivUri");
- listNodeArray(equivalentIriSpan, node.equivalents());
-
- d3.select("#typeNode").text(node.type());
- listNodeArray(d3.select("#individuals"), node.individuals());
-
- /* Disjoint stuff. */
- var disjointNodes = d3.select("#disjointNodes");
- var disjointNodesParent = d3.select(disjointNodes.node().parentNode);
-
- if ( node.disjointWith() !== undefined ) {
- disjointNodes.selectAll("*").remove();
-
- node.disjointWith().forEach(function ( element, index ){
- if ( index > 0 ) {
- disjointNodes.append("span").text(", ");
- }
- appendIriLabel(disjointNodes, element.labelForCurrentLanguage(), element.iri());
- });
-
- disjointNodesParent.classed("hidden", false);
- } else {
- disjointNodesParent.classed("hidden", true);
- }
-
- displayAttributes(node.attributes(), d3.select("#classAttributes"));
-
- setTextAndVisibility(d3.select("#nodeDescription"), node.descriptionForCurrentLanguage());
- setTextAndVisibility(d3.select("#nodeComment"), node.commentForCurrentLanguage());
-
- listAnnotations(d3.select("#classSelectionInformation"), node.annotations());
- }
-
- function showClassInformations(){
- setSelectionInformationVisibility(true, false, false);
- }
-
- function listNodeArray( textSpan, nodes ){
- var spanParent = d3.select(textSpan.node().parentNode);
-
- if ( nodes && nodes.length ) {
- textSpan.selectAll("*").remove();
- nodes.forEach(function ( element, index ){
- if ( index > 0 ) {
- textSpan.append("span").text(", ");
- }
- appendIriLabel(textSpan, element.labelForCurrentLanguage(), element.iri());
- });
-
- spanParent.classed("hidden", false);
- } else {
- spanParent.classed("hidden", true);
- }
- }
-
- function setTextAndVisibility( label, value ){
- var parentNode = d3.select(label.node().parentNode);
- var hasValue = !!value;
- if ( value ) {
- label.text(value);
- }
- parentNode.classed("hidden", !hasValue);
+ var panel = d3.select("#selected-node-panel");
+ panel.selectAll("*").remove();
+
+ renderPair(panel, "IRI", node.iri(), node.iri());
+ renderPair(panel, "Label", node.labelForCurrentLanguage());
+ renderPair(panel, "Type", node.type());
+
+ renderNodeArrayPairs(panel, "Equivalent", node.equivalents());
+ renderNodeArrayPairs(panel, "Disjoint with", node.disjointWith());
+ renderNodeArrayPairs(panel, "Individual", node.individuals());
+
+ var attrs = getAttributes(node.attributes());
+ if ( attrs ) renderPair(panel, "Characteristics", attrs);
+
+ renderPair(panel, "Description", node.descriptionForCurrentLanguage());
+ renderPair(panel, "Comment", node.commentForCurrentLanguage());
+
+ renderAnnotationPairs(panel, node.annotations());
}
/** Collapsible Sidebar functions; **/
src/index.html 59(+6 -53)
diff --git a/src/index.html b/src/index.html
index 20f2ee8..6167b33 100644
--- a/src/index.html
+++ b/src/index.html
@@ -444,61 +444,14 @@
</section>
<section id="generalDetails" class="hidden">
- <h1 id="title"></h1>
- <span><a id="about" href=""></a></span>
- <h5>Version: <span id="version"></span></h5>
- <h5>Author(s): <span id="authors"></span></h5>
- <h5>
+ <div class="panel-language">
<label>Language: <select id="language" name="language" size="1"></select></label>
- </h5>
- <h3 class="accordion-trigger noselect accordion-trigger-active">Description</h3>
- <div class="accordion-container scrollable">
- <p id="description"></p>
</div>
- <h3 class="accordion-trigger noselect">Metadata</h3>
- <div id="ontology-metadata" class="accordion-container"></div>
- <h3 class="accordion-trigger noselect">Statistics</h3>
- <div class="accordion-container">
- <p class="statisticDetails">Classes: <span id="classCount"></span></p>
- <p class="statisticDetails">Object prop.: <span id="objectPropertyCount"></span></p>
- <p class="statisticDetails">Datatype prop.: <span id="datatypePropertyCount"></span></p>
- <div class="small-whitespace-separator"></div>
- <p class="statisticDetails">Individuals: <span id="individualCount"></span></p>
- <div class="small-whitespace-separator"></div>
- <p class="statisticDetails">Nodes: <span id="nodeCount"></span></p>
- <p class="statisticDetails">Edges: <span id="edgeCount"></span></p>
- </div>
- <h3 class="accordion-trigger noselect" id="selection-details-trigger">Selection Details</h3>
- <div class="accordion-container" id="selection-details">
- <div id="classSelectionInformation" class="hidden">
- <p class="propDetails">Name: <span id="name"></span></p>
- <p class="propDetails">Type: <span id="typeNode"></span></p>
- <p class="propDetails">Equiv.: <span id="classEquivUri"></span></p>
- <p class="propDetails">Disjoint: <span id="disjointNodes"></span></p>
- <p class="propDetails">Charac.: <span id="classAttributes"></span></p>
- <p class="propDetails">Individuals: <span id="individuals"></span></p>
- <p class="propDetails">Description: <span id="nodeDescription"></span></p>
- <p class="propDetails">Comment: <span id="nodeComment"></span></p>
- </div>
- <div id="propertySelectionInformation" class="hidden">
- <p class="propDetails">Name: <span id="propname"></span></p>
- <p class="propDetails">Type: <span id="typeProp"></span></p>
- <p id="inverse" class="propDetails">Inverse: <span></span></p>
- <p class="propDetails">Domain: <span id="domain"></span></p>
- <p class="propDetails">Range: <span id="range"></span></p>
- <p class="propDetails">Subprop.: <span id="subproperties"></span></p>
- <p class="propDetails">Superprop.: <span id="superproperties"></span></p>
- <p class="propDetails">Equiv.: <span id="propEquivUri"></span></p>
- <p id="infoCardinality" class="propDetails">Cardinality: <span></span></p>
- <p id="minCardinality" class="propDetails">Min. cardinality: <span></span></p>
- <p id="maxCardinality" class="propDetails">Max. cardinality: <span></span></p>
- <p class="propDetails">Charac.: <span id="propAttributes"></span></p>
- <p class="propDetails">Description: <span id="propDescription"></span></p>
- <p class="propDetails">Comment: <span id="propComment"></span></p>
- </div>
- <div id="noSelectionInformation">
- <p><span>Select an element in the visualization.</span></p>
- </div>
+ <h3 class="panel-section-title">Ontology</h3>
+ <div id="ontology-panel" class="annotation-panel"></div>
+ <h3 class="panel-section-title">Selected Node</h3>
+ <div id="selected-node-panel" class="annotation-panel">
+ <p class="no-selection-hint">Select an element in the visualization.</p>
</div>
</section>
</aside>