changeset 1:db013b2f3e10

added displayAttribute to show on individual nodes. pull all labels and add getLabelFilter to ignore labels (currently with underscore). added ismi-specific app-template and html file.
author Robert Casties <casties@mpiwg-berlin.mpg.de>
date Tue, 01 Sep 2015 16:56:31 +0200
parents 3b8b5aa8ab65
children 130beb4cabec
files .hgignore popoto/ismi.html popoto/js/app-ismi.js popoto/src/js/popoto.js
diffstat 4 files changed, 202 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Tue Sep 01 16:56:31 2015 +0200
@@ -0,0 +1,5 @@
+
+syntax: regexp
+^\.settings$
+syntax: regexp
+^\.project$
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/popoto/ismi.html	Tue Sep 01 16:56:31 2015 +0200
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    <meta http-equiv="Content-Type" content="text/html" charset="UTF-8">
+    <title>Popoto Search</title>
+    <link rel="stylesheet" href="css/popoto.min.css">
+</head>
+<body class="ppt-body">
+
+<header class="ppt-header">
+    <span class="ppt-header-span">POPOTO JS alpha version</span>
+</header>
+
+<section class="ppt-section-main">
+    <div class="ppt-section-header">
+        <span class="ppt-header-span">Graph</span> search
+    </div>
+
+    <div class="ppt-container-graph">
+        <nav id="popoto-taxonomy" class="ppt-taxo-nav">
+            <!-- Label/taxonomy filter will be generated here -->
+        </nav>
+        <div id="popoto-graph" class="ppt-div-graph">
+            <!-- Graph will be generated here-->
+        </div>
+    </div>
+
+    <div id="popoto-query" class="ppt-container-query">
+        <!-- Query viewer will be generated here -->
+    </div>
+
+    <!-- Cypher query viewer has been partially disabled for this alpha release and only display the query as text if enabled -->
+    <!--<div id="popoto-cypher" class="ppt-container-cypher">-->
+    <!--</div>-->
+
+    <div class="ppt-section-header">
+        <!-- The total results count is updated with a listener defined in app-template.js -->
+        RESULTS <span id="result-total-count" class="ppt-count"></span>
+    </div>
+
+    <div id="popoto-results" class="ppt-container-results">
+        <!-- Results will be generated here -->
+    </div>
+
+</section>
+
+<!---------------------->
+<!-- Required scripts -->
+
+<!-- Jquery is only used in popoto.js to send ajax POST request on Neo4j REST API -->
+<!-- This dependency will probably be removed in future releases -->
+<script src="js/jquery-2.1.0.min.js" charset="utf-8"></script>
+
+<script src="js/d3.v3.min.js" charset="utf-8"></script>
+<!-- <script src="js/popoto.min.js" charset="utf-8"></script> -->
+<script src="src/js/popoto.js" charset="utf-8"></script>
+
+<!-- You can modify the parameters defined in this script to customize this application template -->
+<script src="js/app-ismi.js" charset="utf-8"></script>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/popoto/js/app-ismi.js	Tue Sep 01 16:56:31 2015 +0200
@@ -0,0 +1,92 @@
+/**
+ * URL used to access Neo4j REST API to execute queries.
+ * Update this parameter to your running server instance.
+ *
+ * For more information on Neo4J REST API the documentation is available here: http://neo4j.com/docs/stable/rest-api-cypher.html
+ */
+popoto.rest.CYPHER_URL = "https://ismi-dev.mpiwg-berlin.mpg.de:7473/db/data/transaction/commit";
+//popoto.rest.CYPHER_URL = "http://localhost:7474/db/data/transaction/commit";
+
+/**
+ * Add this authorization property if your Neo4j server uses basic HTTP authentication.
+ * The value of this property must be "Basic <payload>", where "payload" is a base64 encoded string of "username:password".
+ *
+ * "btoa" is a JavaScript function that can be used to encode the user and password value in base64 but it is recommended to directly use the Base64 value.
+ *
+ *  For example Base64 encoding value of "neo4j:password" is "bmVvNGo6cGFzc3dvcmQ="
+ */
+popoto.rest.AUTHORIZATION = "Basic " + btoa("neo4j:neo5j");
+
+/**
+ * Define the Label provider you need for your application.
+ * This configuration is mandatory and should contain at least all the labels you could find in your graph model.
+ *
+ * In this alpha version only nodes with a label are supported.
+ *
+ * By default If no attributes are specified Neo4j internal ID will be used.
+ * These label provider configuration can be used to customize the node display in the graph.
+ * See www.popotojs.com or example for more details on available configuration options.
+ */
+popoto.provider.nodeProviders = {
+    "CODEX": {
+        "returnAttributes": ["label", "ismi_id", "identifier"],
+        "displayAttribute": "label"
+    },
+    "WITNESS": {
+        "returnAttributes": ["label", "ismi_id", "folios"],
+        "displayAttribute": "label"
+    },
+    "TEXT": {
+        "returnAttributes": ["label", "full_title", "ismi_id"],
+        "displayAttribute": "label"
+    },
+    "PERSON": {
+        "returnAttributes": ["label", "ismi_id", "death_date_text", "url"],
+        "displayAttribute": "label"
+    },
+    "REPOSITORY": {
+        "returnAttributes": ["label", "ismi_id"],
+        "displayAttribute": "label"
+    },
+    "FLORUIT_DATE": {
+    	"isSearchable": false
+    }
+};
+
+/**
+ * Here a listener is used to retrieve the total results count and update the page accordingly.
+ * This listener will be called on every graph modification.
+ */
+popoto.result.onTotalResultCount(function (count) {
+    document.getElementById("result-total-count").innerHTML = "(" + count + ")";
+});
+
+/**
+ * The number of results returned can be changed with the following parameter.
+ * Default value is 100.
+ *
+ * Note that in this current alpha version no pagination mechanism is available in displayed results
+ */
+popoto.query.RESULTS_PAGE_SIZE = 1000;
+
+
+/**
+ * For the alpha version, popoto.js has been generated with debug traces you can activate with the following properties:
+ * The value can be one in DEBUG, INFO, WARN, ERROR, NONE.
+ *
+ * With INFO level all the executed cypher query can be seen in the navigator console.
+ * Default is NONE
+ */
+popoto.logger.LEVEL = popoto.logger.LogLevels.INFO;
+
+/**
+ * Start popoto.js generation.
+ * The function requires the label to use as root element in the graph.
+ */
+popoto.start("PERSON");
+
+/* do not zoom with scroll wheel */
+popoto.graph.WHEEL_ZOOM_ENABLED = false;
+
+/* show source and target relations */
+popoto.query.USE_RELATION_DIRECTION = true;
--- a/popoto/src/js/popoto.js	Mon Aug 31 17:09:18 2015 +0200
+++ b/popoto/src/js/popoto.js	Tue Sep 01 16:56:31 2015 +0200
@@ -2012,13 +2012,16 @@
                                 ny = clickedNode.y + (100 * Math.sin((angleDeg * (Math.PI / 180)) - parentAngle));
 
                             var isGroupNode = popoto.provider.getIsGroup(d);
+                            // filter multiple labels
+                            var nodeLabel = popoto.provider.getLabelFilter(d.label);
+
                             var node = {
                                 "id": "" + (++popoto.graph.node.idgen),
                                 "parent": clickedNode,
                                 "type": (isGroupNode) ? popoto.graph.node.NodeTypes.GROUP : popoto.graph.node.NodeTypes.CHOOSE,
-                                "label": d.label,
+                                "label": nodeLabel,
                                 "fixed": false,
-                                "internalLabel": popoto.graph.node.generateInternalLabel(d.label),
+                                "internalLabel": popoto.graph.node.generateInternalLabel(nodeLabel),
                                 "x": nx,
                                 "y": ny
                             };
@@ -2651,7 +2654,8 @@
         if (popoto.query.USE_PARENT_RELATION) {
             returnElements.push("head(labels(x)) AS label");
         } else {
-            returnElements.push("last(labels(x)) AS label");
+            //returnElements.push("last(labels(x)) AS label");
+            returnElements.push("labels(x) AS label");
         }
         returnElements.push("count(r) AS count");
         endElements.push("ORDER BY count(r) DESC");
@@ -3438,6 +3442,25 @@
     };
 
     /**
+     * Select the label if there is more than one.
+     * 
+     * Discards the label with an underscore.
+     */
+    popoto.provider.getLabelFilter = function (nodeLabel) {
+        if (Array.isArray(nodeLabel)) {
+            // use last label
+            var label = nodeLabel[nodeLabel.length - 1];
+            if (label.indexOf('_') == -1 && nodeLabel.length > 1) {
+                // skip if wrong label
+                label = nodeLabel[nodeLabel.length - 2];
+            }
+            // replace array with string
+            nodeLabel = label;
+        }
+        return nodeLabel;
+    }
+    
+    /**
      * Label provider used by default if none have been defined for a label.
      * This provider can be changed if needed to customize default behavior.
      * If some properties are not found in user customized providers, default values will be extracted from this provider.
@@ -3507,6 +3530,13 @@
             "constraintAttribute": popoto.query.NEO4J_INTERNAL_ID,
 
             /**
+             * Defines the attribute of the node to display as a text identifying the node.
+             * 
+             * The default value is the Neo4j internal id.
+             */
+            "displayAttribute": popoto.query.NEO4J_INTERNAL_ID,
+            
+            /**
              * Return the list of predefined constraints to add for the given label.
              * These constraints will be added in every generated Cypher query.
              *
@@ -3591,21 +3621,21 @@
              */
             "getTextValue": function (node) {
                 var text;
-                var constraintAttr = popoto.provider.getProperty(node.label, "constraintAttribute");
+                var textAttr = popoto.provider.getProperty(node.label, "displayAttribute");
                 if (node.type === popoto.graph.node.NodeTypes.VALUE) {
-                    if (constraintAttr === popoto.query.NEO4J_INTERNAL_ID) {
+                    if (textAttr === popoto.query.NEO4J_INTERNAL_ID) {
                         text = "" + node.internalID;
                     } else {
-                        text = "" + node.attributes[constraintAttr];
+                        text = "" + node.attributes[textAttr];
                     }
                 } else {
                     if (node.value === undefined) {
                         text = node.label;
                     } else {
-                        if (constraintAttr === popoto.query.NEO4J_INTERNAL_ID) {
+                        if (textAttr === popoto.query.NEO4J_INTERNAL_ID) {
                             text = "" + node.value.internalID;
                         } else {
-                            text = "" + node.value.attributes[constraintAttr];
+                            text = "" + node.value.attributes[textAttr];
                         }
                     }
                 }
@@ -3625,21 +3655,21 @@
              */
             "getSemanticValue": function (node) {
                 var text;
-                var constraintAttr = popoto.provider.getProperty(node.label, "constraintAttribute");
+                var textAttr = popoto.provider.getProperty(node.label, "displayAttribute");
                 if (node.type === popoto.graph.node.NodeTypes.VALUE) {
-                    if (constraintAttr === popoto.query.NEO4J_INTERNAL_ID) {
+                    if (textAttr === popoto.query.NEO4J_INTERNAL_ID) {
                         text = "" + node.internalID;
                     } else {
-                        text = "" + node.attributes[constraintAttr];
+                        text = "" + node.attributes[textAttr];
                     }
                 } else {
                     if (node.value === undefined) {
                         text = node.label;
                     } else {
-                        if (constraintAttr === popoto.query.NEO4J_INTERNAL_ID) {
+                        if (textAttr === popoto.query.NEO4J_INTERNAL_ID) {
                             text = "" + node.value.internalID;
                         } else {
-                            text = "" + node.value.attributes[constraintAttr];
+                            text = "" + node.value.attributes[textAttr];
                         }
                     }
                 }