diff --git a/conf/zeppelin-site.xml.template b/conf/zeppelin-site.xml.template index abaff304b2d..1465102b62a 100755 --- a/conf/zeppelin-site.xml.template +++ b/conf/zeppelin-site.xml.template @@ -208,7 +208,7 @@ zeppelin.interpreters - org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.rinterpreter.RRepl,org.apache.zeppelin.rinterpreter.KnitR,org.apache.zeppelin.spark.SparkRInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.file.HDFSFileInterpreter,org.apache.zeppelin.flink.FlinkInterpreter,,org.apache.zeppelin.python.PythonInterpreter,org.apache.zeppelin.python.PythonInterpreterPandasSql,org.apache.zeppelin.python.PythonCondaInterpreter,org.apache.zeppelin.python.PythonDockerInterpreter,org.apache.zeppelin.lens.LensInterpreter,org.apache.zeppelin.ignite.IgniteInterpreter,org.apache.zeppelin.ignite.IgniteSqlInterpreter,org.apache.zeppelin.cassandra.CassandraInterpreter,org.apache.zeppelin.geode.GeodeOqlInterpreter,org.apache.zeppelin.jdbc.JDBCInterpreter,org.apache.zeppelin.kylin.KylinInterpreter,org.apache.zeppelin.elasticsearch.ElasticsearchInterpreter,org.apache.zeppelin.scalding.ScaldingInterpreter,org.apache.zeppelin.alluxio.AlluxioInterpreter,org.apache.zeppelin.hbase.HbaseInterpreter,org.apache.zeppelin.livy.LivySparkInterpreter,org.apache.zeppelin.livy.LivyPySparkInterpreter,org.apache.zeppelin.livy.LivyPySpark3Interpreter,org.apache.zeppelin.livy.LivySparkRInterpreter,org.apache.zeppelin.livy.LivySparkSQLInterpreter,org.apache.zeppelin.bigquery.BigQueryInterpreter,org.apache.zeppelin.beam.BeamInterpreter,org.apache.zeppelin.pig.PigInterpreter,org.apache.zeppelin.pig.PigQueryInterpreter,org.apache.zeppelin.scio.ScioInterpreter + org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.rinterpreter.RRepl,org.apache.zeppelin.rinterpreter.KnitR,org.apache.zeppelin.spark.SparkRInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.file.HDFSFileInterpreter,org.apache.zeppelin.flink.FlinkInterpreter,,org.apache.zeppelin.python.PythonInterpreter,org.apache.zeppelin.python.PythonInterpreterPandasSql,org.apache.zeppelin.python.PythonCondaInterpreter,org.apache.zeppelin.python.PythonDockerInterpreter,org.apache.zeppelin.lens.LensInterpreter,org.apache.zeppelin.ignite.IgniteInterpreter,org.apache.zeppelin.ignite.IgniteSqlInterpreter,org.apache.zeppelin.cassandra.CassandraInterpreter,org.apache.zeppelin.geode.GeodeOqlInterpreter,org.apache.zeppelin.jdbc.JDBCInterpreter,org.apache.zeppelin.kylin.KylinInterpreter,org.apache.zeppelin.elasticsearch.ElasticsearchInterpreter,org.apache.zeppelin.scalding.ScaldingInterpreter,org.apache.zeppelin.alluxio.AlluxioInterpreter,org.apache.zeppelin.hbase.HbaseInterpreter,org.apache.zeppelin.livy.LivySparkInterpreter,org.apache.zeppelin.livy.LivyPySparkInterpreter,org.apache.zeppelin.livy.LivyPySpark3Interpreter,org.apache.zeppelin.livy.LivySparkRInterpreter,org.apache.zeppelin.livy.LivySparkSQLInterpreter,org.apache.zeppelin.bigquery.BigQueryInterpreter,org.apache.zeppelin.beam.BeamInterpreter,org.apache.zeppelin.pig.PigInterpreter,org.apache.zeppelin.pig.PigQueryInterpreter,org.apache.zeppelin.scio.ScioInterpreter,org.apache.zeppelin.graph.neo4j.Neo4jCypherInterpreter Comma separated interpreter configurations. First interpreter become a default @@ -319,3 +319,4 @@ + diff --git a/docs/_includes/themes/zeppelin/_navigation.html b/docs/_includes/themes/zeppelin/_navigation.html index b13ef68542d..02d679f8484 100644 --- a/docs/_includes/themes/zeppelin/_navigation.html +++ b/docs/_includes/themes/zeppelin/_navigation.html @@ -66,6 +66,7 @@
  • Lens
  • Livy
  • Markdown
  • +
  • Neo4j
  • Pig
  • Python
  • Postgresql, HAWQ
  • diff --git a/docs/assets/themes/zeppelin/img/docs-img/neo4j-chart-result.png b/docs/assets/themes/zeppelin/img/docs-img/neo4j-chart-result.png new file mode 100644 index 00000000000..d9dd8219191 Binary files /dev/null and b/docs/assets/themes/zeppelin/img/docs-img/neo4j-chart-result.png differ diff --git a/docs/assets/themes/zeppelin/img/docs-img/neo4j-network-result.png b/docs/assets/themes/zeppelin/img/docs-img/neo4j-network-result.png new file mode 100644 index 00000000000..2313d7698a6 Binary files /dev/null and b/docs/assets/themes/zeppelin/img/docs-img/neo4j-network-result.png differ diff --git a/docs/assets/themes/zeppelin/img/docs-img/neo4j-tabular-result.png b/docs/assets/themes/zeppelin/img/docs-img/neo4j-tabular-result.png new file mode 100644 index 00000000000..247740bfdb4 Binary files /dev/null and b/docs/assets/themes/zeppelin/img/docs-img/neo4j-tabular-result.png differ diff --git a/docs/assets/themes/zeppelin/img/docs-img/neo4j-zeppelin-form-select.png b/docs/assets/themes/zeppelin/img/docs-img/neo4j-zeppelin-form-select.png new file mode 100644 index 00000000000..4b3893bb66f Binary files /dev/null and b/docs/assets/themes/zeppelin/img/docs-img/neo4j-zeppelin-form-select.png differ diff --git a/docs/assets/themes/zeppelin/img/docs-img/neo4j-zeppelin-form-text-input.png b/docs/assets/themes/zeppelin/img/docs-img/neo4j-zeppelin-form-text-input.png new file mode 100644 index 00000000000..55976603640 Binary files /dev/null and b/docs/assets/themes/zeppelin/img/docs-img/neo4j-zeppelin-form-text-input.png differ diff --git a/docs/assets/themes/zeppelin/img/docs-img/zeppelin-network-display-customization.png b/docs/assets/themes/zeppelin/img/docs-img/zeppelin-network-display-customization.png new file mode 100644 index 00000000000..e7aab5c7655 Binary files /dev/null and b/docs/assets/themes/zeppelin/img/docs-img/zeppelin-network-display-customization.png differ diff --git a/docs/assets/themes/zeppelin/img/docs-img/zeppelin-switch-chart-network.png b/docs/assets/themes/zeppelin/img/docs-img/zeppelin-switch-chart-network.png new file mode 100644 index 00000000000..c439dbf4c46 Binary files /dev/null and b/docs/assets/themes/zeppelin/img/docs-img/zeppelin-switch-chart-network.png differ diff --git a/docs/assets/themes/zeppelin/img/screenshots/display_network.png b/docs/assets/themes/zeppelin/img/screenshots/display_network.png new file mode 100644 index 00000000000..5804a97f126 Binary files /dev/null and b/docs/assets/themes/zeppelin/img/screenshots/display_network.png differ diff --git a/docs/assets/themes/zeppelin/img/screenshots/display_network1.png b/docs/assets/themes/zeppelin/img/screenshots/display_network1.png new file mode 100644 index 00000000000..50e021fd637 Binary files /dev/null and b/docs/assets/themes/zeppelin/img/screenshots/display_network1.png differ diff --git a/docs/assets/themes/zeppelin/img/screenshots/display_network2.png b/docs/assets/themes/zeppelin/img/screenshots/display_network2.png new file mode 100644 index 00000000000..92e5c869c55 Binary files /dev/null and b/docs/assets/themes/zeppelin/img/screenshots/display_network2.png differ diff --git a/docs/displaysystem/basicdisplaysystem.md b/docs/displaysystem/basicdisplaysystem.md index 7c4243208e4..7762dc1f9ab 100644 --- a/docs/displaysystem/basicdisplaysystem.md +++ b/docs/displaysystem/basicdisplaysystem.md @@ -60,4 +60,98 @@ If table contents start with `%html`, it is interpreted as an HTML. +## Network + +Zeppelin can render a network following this sample json structure: + +```json +{"nodes" : [{"id" : 1}, {"id" : 2}], "edges" : [{"source" : 2, "target" : 1, "id" : 1 }]} +``` + +You can leverage this visualization by using the `%network` directive + + + + + +The network visualization can also leverage the Property Graph with a json structure like this: + +```json +{ + "nodes": [ + { + "id": 1, + "label": "User", + "data": {"fullname": "Andrea Santurbano"} + }, + { + "id": 2, + "label": "User", + "data": {"fullname": "Moon soo Lee"} + } + ], + "edges": [ + { + "source": 2, + "target": 1, + "id": 1, + "label": "HELPS", + "data": { + "project" : "Zeppelin", + "githubUrl": "https://github.com/apache/zeppelin/pull/1582" + } + } + ] +} +``` + + + +## Network + +Zeppelin can render a network following this sample json structure: + +```json +{"nodes" : [{"id" : 1}, {"id" : 2}], "edges" : [{"source" : 2, "target" : 1, "id" : 1 }]} +``` + +You can leverage this visualization by using the `%network` directive + + + + + +The network visualization can also leverage the Property Graph with a json structure like this: + +```json +{ + "nodes": [ + { + "id": 1, + "label": "User", + "data": {"fullname": "Andrea Santurbano"} + }, + { + "id": 2, + "label": "User", + "data": {"fullname": "Moon soo Lee"} + } + ], + "edges": [ + { + "source": 2, + "target": 1, + "id": 1, + "label": "HELPS", + "data": { + "project" : "Zeppelin", + "githubUrl": "https://github.com/apache/zeppelin/pull/1582" + } + } + ] +} +``` + + + > **Note :** Display system is backend independent. diff --git a/docs/interpreter/neo4j.md b/docs/interpreter/neo4j.md new file mode 100644 index 00000000000..adb5dca308b --- /dev/null +++ b/docs/interpreter/neo4j.md @@ -0,0 +1,108 @@ +--- +layout: page +title: "Neo4j Interpreter for Apache Zeppelin" +description: "Neo4j is a highly scalable, native graph database purpose-built to leverage not only data but also its relationships." +group: interpreter +--- + +{% include JB/setup %} + +# Neo4j Interpreter for Apache Zeppelin + +
    + +## Overview +[Neo4j](https://neo4j.com/) is a highly scalable, native graph database purpose-built to leverage not only data but also its relationships. +Neo4j's native graph storage and processing engine deliver constant, real-time performance, helping enterprises build intelligent applications to meet today’s evolving data challenges. + + + + + + + + + + + + +
    NameClassDescription
    %neo4jNeo4jCypherInterpreterEnable the Neo4j intepreter
    + +## Configuration +The Neo4j interpreter can be configured with properties provided by Zeppelin. + + + + + + + + + + + + + + + + + + + + + + + + + + +
    PropertyDefaultDescription
    neo4j.urlbolt://localhost:7687The Neo4j's BOLT url.
    neo4j.userneo4jThe Neo4j user name.
    neo4j.passwordneo4jThe Neo4j user password.
    neo4j.max.concurrency50Max concurrency call to Neo4j server.
    + +## Enabling the Neo4j Interpreter +In a notebook, to enable the **Neo4j** interpreter, click the **Gear** icon and select **neo4j**. + +## Using the Neo4j Interpreter +In a paragraph, use `%neo4j` to select the Neo4j interpreter and then write your cypher query. + +```cypher +MATCH (u:User)-[p:POSTS]->(t:Tweet) RETURN u, p, t; +``` + +The default visualization show the query result as a table. In the tabular result if nodes and relationships are return from the query, they will show together as rows +![Simple cypher query tabular visualization](../assets/themes/zeppelin/img/docs-img/neo4j-tabular-result.png) + +If the query result has almost a node the **Network** button will be enabled so you can switch to the graph visualization +![Network button on chart bar](../assets/themes/zeppelin/img/docs-img/zeppelin-switch-chart-network.png) + +![Simple cypher query network visualization](../assets/themes/zeppelin/img/docs-img/neo4j-network-result.png) + +You can still use the other visualization charts provided by zeppelin +![Simple cypher query Chart visualization](../assets/themes/zeppelin/img/docs-img/neo4j-chart-result.png) + +Leveraging the **settings** button you can customize your graph visualization, a list of nodes will be displayed and by click on each one you can set the property which will be used as node label. +![Simple cypher query network visualization](../assets/themes/zeppelin/img/docs-img/zeppelin-network-display-customization.png) + +### Apply Zeppelin Dynamic Forms +You can leverage [Zeppelin Dynamic Form](../manual/dynamicform.html) inside your queries. You can use both the `text input` and `select form` parameterization features. + +```cypher +match (n:User{screen_name: '${user_name}'})-[r]-(m:Tweet) return n, r, m limit 10 +``` +![Example of query with text input](../assets/themes/zeppelin/img/docs-img/neo4j-zeppelin-form-text-input.png) + +```cypher +match (n:User{screen_name: '${user_name=santand84,santand84|individue|maurofer79}'})-[r]-(m:Tweet) return n, r, m limit 10 +``` +![Example of query with select box](../assets/themes/zeppelin/img/docs-img/neo4j-zeppelin-form-select.png) diff --git a/neo4j/pom.xml b/neo4j/pom.xml new file mode 100644 index 00000000000..c97ecefd580 --- /dev/null +++ b/neo4j/pom.xml @@ -0,0 +1,137 @@ + + + + + 4.0.0 + + + zeppelin + org.apache.zeppelin + 0.8.0-SNAPSHOT + .. + + + org.apache.zeppelin + zeppelin-neo4j + jar + 0.8.0-SNAPSHOT + Zeppelin: Neo4j interpreter + + + 1.0.4 + 3.0.4 + 3.0.4 + + + + + ${project.groupId} + zeppelin-interpreter + ${project.version} + provided + + + + org.neo4j.driver + neo4j-java-driver + ${neo4j.driver.version} + + + + org.slf4j + slf4j-api + + + + org.slf4j + slf4j-log4j12 + + + + junit + junit + test + + + + org.neo4j.test + neo4j-harness + ${neo4j.version} + test + + + + + + + maven-enforcer-plugin + 1.3.1 + + + enforce + none + + + + + + maven-dependency-plugin + 2.8 + + + copy-dependencies + package + + copy-dependencies + + + ${project.build.directory}/../../interpreter/neo4j + false + false + true + runtime + + + + copy-artifact + package + + copy + + + ${project.build.directory}/../../interpreter/neo4j + false + false + true + runtime + + + ${project.groupId} + ${project.artifactId} + ${project.version} + ${project.packaging} + + + + + + + + + + diff --git a/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreter.java b/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreter.java new file mode 100644 index 00000000000..efbb42bcb38 --- /dev/null +++ b/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreter.java @@ -0,0 +1,295 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zeppelin.graph.neo4j; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang.StringUtils; +import org.apache.zeppelin.graph.neo4j.utils.Neo4jConversionUtils; +import org.apache.zeppelin.interpreter.Interpreter; +import org.apache.zeppelin.interpreter.InterpreterContext; +import org.apache.zeppelin.interpreter.InterpreterResult; +import org.apache.zeppelin.interpreter.InterpreterResult.Code; +import org.apache.zeppelin.interpreter.graph.GraphResult; +import org.apache.zeppelin.interpreter.graph.GraphUtils; +import org.apache.zeppelin.interpreter.graph.Relationship.Type; +import org.apache.zeppelin.resource.Resource; +import org.apache.zeppelin.resource.ResourcePool; +import org.apache.zeppelin.scheduler.Scheduler; +import org.apache.zeppelin.scheduler.SchedulerFactory; +import org.neo4j.driver.internal.InternalNode; +import org.neo4j.driver.internal.InternalPath; +import org.neo4j.driver.internal.InternalRelationship; +import org.neo4j.driver.internal.util.Iterables; +import org.neo4j.driver.internal.value.ListValue; +import org.neo4j.driver.internal.value.NodeValue; +import org.neo4j.driver.internal.value.PathValue; +import org.neo4j.driver.internal.value.RelationshipValue; +import org.neo4j.driver.v1.AuthTokens; +import org.neo4j.driver.v1.Config; +import org.neo4j.driver.v1.Driver; +import org.neo4j.driver.v1.GraphDatabase; +import org.neo4j.driver.v1.Record; +import org.neo4j.driver.v1.Session; +import org.neo4j.driver.v1.StatementResult; +import org.neo4j.driver.v1.types.Node; +import org.neo4j.driver.v1.types.Relationship; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Neo4j interpreter for Zeppelin. + */ +public class Neo4jCypherInterpreter extends Interpreter { + static final Logger LOGGER = LoggerFactory.getLogger(Neo4jCypherInterpreter.class); + + public static final String NEO4J_SERVER_URL = "neo4j.url"; + public static final String NEO4J_SERVER_USER = "neo4j.user"; + public static final String NEO4J_SERVER_PASSWORD = "neo4j.password"; + public static final String NEO4J_MAX_CONCURRENCY = "neo4j.max.concurrency"; + + private static final String TABLE = "%table"; + private static final String NEW_LINE = "\n"; + private static final String TAB = "\t"; + + private static final Pattern PROPERTY_PATTERN = Pattern.compile("\\{\\w+\\}"); + private static final String REPLACE_CURLY_BRACKETS = "\\{|\\}"; + + private Driver driver = null; + + private Map labels; + + private Set types; + + public Neo4jCypherInterpreter(Properties properties) { + super(properties); + } + + private Driver getDriver() { + if (driver == null) { + Config config = Config.build().withEncryptionLevel(Config.EncryptionLevel.NONE).toConfig(); + driver = GraphDatabase.driver(getProperty(NEO4J_SERVER_URL), + AuthTokens.basic(getProperty(NEO4J_SERVER_USER), + getProperty(NEO4J_SERVER_PASSWORD)), config); + } + return driver; + } + + @Override + public void open() { + getDriver(); + } + + @Override + public void close() { + getDriver().close(); + } + + public Map getLabels(boolean refresh) { + if (labels == null || refresh) { + Map old = labels == null ? + new LinkedHashMap() : new LinkedHashMap<>(labels); + labels = new LinkedHashMap<>(); + try (Session session = getDriver().session()) { + StatementResult result = session.run("CALL db.labels()"); + Set colors = new HashSet<>(); + while (result.hasNext()) { + Record record = result.next(); + String label = record.get("label").asString(); + String color = old.get(label); + while (color == null || colors.contains(color)) { + color = GraphUtils.getRandomColor(); + } + colors.add(color); + labels.put(label, color); + } + } + } + return labels; + } + + private Set getTypes(boolean refresh) { + if (types == null || refresh) { + types = new HashSet<>(); + try (Session session = getDriver().session()) { + StatementResult result = session.run("CALL db.relationshipTypes()"); + while (result.hasNext()) { + Record record = result.next(); + types.add(record.get("relationshipType").asString()); + } + } + } + return types; + } + + private void setResultValue(Object value, Set nodes, Set relationships, + List line) { + if (value instanceof NodeValue + || value instanceof InternalNode) { + NodeValue nodeVal = value instanceof NodeValue ? + (NodeValue) value : (NodeValue) ((InternalNode) value).asValue(); + nodes.add(nodeVal.asNode()); + } else if (value instanceof RelationshipValue + || value instanceof InternalRelationship) { + RelationshipValue relVal = value instanceof RelationshipValue ? + (RelationshipValue) value : (RelationshipValue) ((InternalRelationship) value).asValue(); + relationships.add(relVal.asRelationship()); + } else if (value instanceof PathValue + || value instanceof InternalPath) { + PathValue pathVal = value instanceof PathValue ? + (PathValue) value : (PathValue) ((InternalPath) value).asValue(); + nodes.addAll(Iterables.asList(pathVal.asPath().nodes())); + relationships.addAll(Iterables.asList(pathVal.asPath().relationships())); + } else if (value instanceof ListValue) { + ListValue listValues = (ListValue) value; + List listObject = listValues.asList(); + for (Object val : listObject) { + setResultValue(val, nodes, relationships, line); + } + } else { + line.add(String.valueOf(value)); + } + } + + @Override + public InterpreterResult interpret(String cypherQuery, InterpreterContext interpreterContext) { + logger.info("Opening session"); + if (StringUtils.isEmpty(cypherQuery)) { + return new InterpreterResult(Code.ERROR, "Cypher query is Empty"); + } + try (Session session = getDriver().session()){ + StatementResult result = execute(session, cypherQuery, interpreterContext); + Set cols = new HashSet<>(); + List> lines = new ArrayList<>(); + Set nodes = new HashSet<>(); + Set relationships = new HashSet<>(); + while (result.hasNext()) { + Record record = result.next(); + if (cols.isEmpty()) { + cols.addAll(record.keys()); + } + List line = new ArrayList<>(); + for (String col : cols) { + Object value = record.get(col); + setResultValue(value, nodes, relationships, line); + } + if (!line.isEmpty()) { + lines.add(line); + } + } + if (!nodes.isEmpty()) { + return renderGraph(nodes, relationships); + } else { + return renderTable(cols, lines); + } + } catch (Exception e) { + logger.error("Exception while interpreting cypher query", e); + return new InterpreterResult(Code.ERROR, e.getMessage()); + } + } + + private StatementResult execute(Session session, String cypherQuery, + InterpreterContext interpreterContext) { + Matcher matcher = PROPERTY_PATTERN.matcher(cypherQuery); + Map params = new HashMap<>(); + ResourcePool resourcePool = interpreterContext.getResourcePool(); + while (matcher.find()) { + String key = matcher.group().replaceAll(REPLACE_CURLY_BRACKETS, StringUtils.EMPTY); + Resource resource = resourcePool.get(key); + if (resource != null) { + params.put(key, resource.get()); + } + } + logger.info("Executing cypher query {} with params {}", cypherQuery, params); + return params.isEmpty() ? session.run(cypherQuery) : session.run(cypherQuery, params); + } + + private InterpreterResult renderTable(Set cols, List> lines) { + logger.info("Executing renderTable method"); + StringBuilder msg = new StringBuilder(TABLE); + msg.append(NEW_LINE); + msg.append(StringUtils.join(cols, TAB)); + msg.append(NEW_LINE); + for (List line : lines) { + msg.append(StringUtils.join(line, TAB)); + msg.append(NEW_LINE); + } + return new InterpreterResult(Code.SUCCESS, msg.toString()); + } + + private InterpreterResult renderGraph(Set nodes, + Set relationships) { + logger.info("Executing renderGraph method"); + List nodesList = new ArrayList<>(); + List relsList = new ArrayList<>(); + Map relCount = new HashMap<>(); + for (Relationship rel : relationships) { + Type type = null; + String keyStartEnd = String.format("%s-%s", rel.startNodeId(), rel.endNodeId()); + String keyEndStart = String.format("%s-%s", rel.endNodeId(), rel.startNodeId()); + if (!relCount.containsKey(keyStartEnd) && !relCount.containsKey(keyEndStart)) { + type = Type.arrow; + } else { + type = Type.curvedArrow; + } + if (!relCount.containsKey(keyStartEnd)) { + relCount.put(keyStartEnd, 0); + } + Integer count = relCount.get(keyStartEnd); + relCount.put(keyStartEnd, ++count); + relsList.add(Neo4jConversionUtils.toZeppelinRelationship(rel, type, count)); + } + Map labels = getLabels(true); + for (Node node : nodes) { + nodesList.add(Neo4jConversionUtils.toZeppelinNode(node, labels)); + } + return new GraphResult(Code.SUCCESS, + new GraphResult.Graph(nodesList, relsList, labels, getTypes(true))); + } + + @Override + public Scheduler getScheduler() { + return SchedulerFactory.singleton() + .createOrGetParallelScheduler(Neo4jCypherInterpreter.class.getName() + this.hashCode(), + Integer.parseInt(getProperty(NEO4J_MAX_CONCURRENCY))); + } + + @Override + public int getProgress(InterpreterContext context) { + return 0; + } + + @Override + public FormType getFormType() { + return FormType.SIMPLE; + } + + @Override + public void cancel(InterpreterContext context) { + } + +} diff --git a/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/utils/Neo4jConversionUtils.java b/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/utils/Neo4jConversionUtils.java new file mode 100644 index 00000000000..ac4bebfb45d --- /dev/null +++ b/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/utils/Neo4jConversionUtils.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zeppelin.graph.neo4j.utils; + +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.zeppelin.interpreter.graph.Relationship.Type; +import org.neo4j.driver.v1.types.Node; +import org.neo4j.driver.v1.types.Relationship; + +/** + * Neo4jConversionUtils + */ +public class Neo4jConversionUtils { + private Neo4jConversionUtils() {} + + public static org.apache.zeppelin.interpreter.graph.Node toZeppelinNode(Node n, + Map graphLabels) { + Set labels = new LinkedHashSet<>(); + String firstLabel = null; + for (String label : n.labels()) { + if (firstLabel == null) { + firstLabel = label; + } + labels.add(label); + } + String color = graphLabels.get(firstLabel); + return new org.apache.zeppelin.interpreter.graph.Node(n.id(), n.asMap(), + labels, color); + } + + public static org.apache.zeppelin.interpreter.graph.Relationship + toZeppelinRelationship(Relationship r, Type type, int count) { + return new org.apache.zeppelin.interpreter.graph.Relationship(r.id(), r.asMap(), + r.startNodeId(), r.endNodeId(), r.type(), type, count); + } + +} diff --git a/neo4j/src/main/resources/interpreter-setting.json b/neo4j/src/main/resources/interpreter-setting.json new file mode 100644 index 00000000000..991781710b9 --- /dev/null +++ b/neo4j/src/main/resources/interpreter-setting.json @@ -0,0 +1,37 @@ +[ + { + "group": "neo4j", + "name": "neo4j", + "className": "org.apache.zeppelin.graph.neo4j.Neo4jCypherInterpreter", + "properties": { + "neo4j.url": { + "envName": null, + "propertyName": "neo4j.url", + "defaultValue": "bolt://localhost:7687", + "description": "The Neo4j's BOLT url." + }, + "neo4j.user": { + "envName": null, + "propertyName": "neo4j.user", + "defaultValue": "neo4j", + "description": "The Neo4j user name." + }, + "neo4j.password": { + "envName": null, + "propertyName": "neo4j.password", + "defaultValue": "neo4j", + "description": "The Neo4j user password." + }, + "neo4j.max.concurrency": { + "envName": null, + "propertyName": "neo4j.max.concurrency", + "defaultValue": "50", + "description": "Max concurrency call from Zeppelin to Neo4j server." + } + }, + "editor": { + "language": "cypher", + "editOnDblClick": false + } + } +] diff --git a/neo4j/src/test/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreterTest.java b/neo4j/src/test/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreterTest.java new file mode 100644 index 00000000000..1b51ad7d73a --- /dev/null +++ b/neo4j/src/test/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreterTest.java @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zeppelin.graph.neo4j; + +import static org.junit.Assert.assertEquals; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Properties; + +import org.apache.zeppelin.display.AngularObjectRegistry; +import org.apache.zeppelin.display.GUI; +import org.apache.zeppelin.interpreter.InterpreterContext; +import org.apache.zeppelin.interpreter.InterpreterContextRunner; +import org.apache.zeppelin.interpreter.InterpreterGroup; +import org.apache.zeppelin.interpreter.InterpreterOutput; +import org.apache.zeppelin.interpreter.InterpreterResult; +import org.apache.zeppelin.interpreter.InterpreterResult.Code; +import org.apache.zeppelin.interpreter.graph.GraphResult; +import org.apache.zeppelin.resource.LocalResourcePool; +import org.apache.zeppelin.user.AuthenticationInfo; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.neo4j.harness.ServerControls; +import org.neo4j.harness.TestServerBuilders; + +import com.google.gson.Gson; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class Neo4jCypherInterpreterTest { + + private Neo4jCypherInterpreter interpreter; + + private InterpreterContext context; + + private static ServerControls server; + + private static final Gson gson = new Gson(); + + private static final String LABEL_PERSON = "Person"; + private static final String REL_KNOWS = "KNOWS"; + + private static final String CYPHER_FOREACH = "FOREACH (x in range(1,1000) | CREATE (:%s{name: \"name\" + x, age: %s}))"; + private static final String CHPHER_UNWIND = "UNWIND range(1,1000) as x " + + "MATCH (n), (m) WHERE id(n) = x AND id(m) = toInt(rand() * 1000) " + + "CREATE (n)-[:%s]->(m)"; + + + private static final String EXPECTED_TABLE = "name\tage\n\"name1\"\t1\n"; + + @BeforeClass + public static void setUpNeo4jServer() throws Exception { + server = TestServerBuilders.newInProcessBuilder() + .withConfig("dbms.security.auth_enabled","false") + .withFixture(String.format(CYPHER_FOREACH, LABEL_PERSON, "x % 10")) + .withFixture(String.format(CHPHER_UNWIND, REL_KNOWS)) + .newServer(); + } + + @AfterClass + public static void tearDownNeo4jServer() throws Exception { + server.close(); + } + + @Before + public void setUpZeppelin() { + Properties p = new Properties(); + p.setProperty(Neo4jCypherInterpreter.NEO4J_SERVER_URL, server.boltURI().toString()); + interpreter = new Neo4jCypherInterpreter(p); + context = new InterpreterContext("note", "id", null, "title", "text", + new AuthenticationInfo(), + new HashMap(), + new GUI(), + new AngularObjectRegistry(new InterpreterGroup().getId(), null), + new LocalResourcePool("id"), + new LinkedList(), + new InterpreterOutput(null)); + } + + @After + public void tearDownZeppelin() throws Exception { + interpreter.close(); + } + + @Test + public void testRenderTable() { + interpreter.open(); + InterpreterResult result = interpreter.interpret("MATCH (n:Person{name: 'name1'}) RETURN n.name AS name, n.age AS age", context); + assertEquals(EXPECTED_TABLE, result.toString().replace("%table ", "")); + assertEquals(Code.SUCCESS, result.code()); + } + + @Test + public void testRenderNetwork() { + interpreter.open(); + InterpreterResult result = interpreter.interpret("MATCH (n)-[r:KNOWS]-(m) RETURN n, r, m LIMIT 1", context); + GraphResult.Graph graph = gson.fromJson(result.toString().replace("%network ", ""), GraphResult.Graph.class); + assertEquals(2, graph.getNodes().size()); + assertEquals(true, graph.getNodes().iterator().next().getLabel().equals(LABEL_PERSON)); + assertEquals(1, graph.getEdges().size()); + assertEquals(true, graph.getEdges().iterator().next().getLabel().equals(REL_KNOWS)); + assertEquals(1, graph.getLabels().size()); + assertEquals(1, graph.getTypes().size()); + assertEquals(true, graph.getLabels().containsKey(LABEL_PERSON)); + assertEquals(REL_KNOWS, graph.getTypes().iterator().next()); + assertEquals(Code.SUCCESS, result.code()); + } + + @Test + public void testFallingQuery() { + interpreter.open(); + final String ERROR_MSG_EMPTY = "%text Cypher query is Empty"; + InterpreterResult result = interpreter.interpret("", context); + assertEquals(Code.ERROR, result.code()); + assertEquals(ERROR_MSG_EMPTY, result.toString()); + + result = interpreter.interpret(null, context); + assertEquals(Code.ERROR, result.code()); + assertEquals(ERROR_MSG_EMPTY, result.toString()); + + result = interpreter.interpret("MATCH (n:Person{name: }) RETURN n.name AS name, n.age AS age", context); + assertEquals(Code.ERROR, result.code()); + } + +} diff --git a/neo4j/src/test/java/org/apache/zeppelin/graph/utils/GraphUtilsTest.java b/neo4j/src/test/java/org/apache/zeppelin/graph/utils/GraphUtilsTest.java new file mode 100644 index 00000000000..edf591af9ef --- /dev/null +++ b/neo4j/src/test/java/org/apache/zeppelin/graph/utils/GraphUtilsTest.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zeppelin.graph.utils; + +import static org.junit.Assert.assertEquals; + +import java.util.regex.Pattern; + +import org.apache.zeppelin.interpreter.graph.GraphUtils; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +/** + * + * @author a.santurbano + * + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class GraphUtilsTest { + + private static final Pattern HEX_PATTERN = Pattern.compile("^#([A-F0-9]{6}|[A-F0-9]{3})$"); + + @Test + public void testGetRandomColor() { + assertEquals(true, HEX_PATTERN.matcher(GraphUtils.getRandomColor()).matches()); + } +} diff --git a/notebook/2BYEZ5EVK/note.json b/notebook/2BYEZ5EVK/note.json index 83a79135f7e..7867c0d9042 100644 --- a/notebook/2BYEZ5EVK/note.json +++ b/notebook/2BYEZ5EVK/note.json @@ -784,104 +784,4 @@ "msg": [ { "type": "HTML", - "data": "\u003cp\u003e\u003cimg src\u003d\"data:image/png;base64,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\u003d\u003d\" alt\u003d\"plot of chunk unnamed-chunk-1\" width\u003d\"400px\" /\u003e\u003c/p\u003e" - } - ] - }, - "dateCreated": "Sep 27, 2016 6:44:04 AM", - "dateStarted": "Sep 28, 2016 1:52:10 PM", - "dateFinished": "Sep 28, 2016 1:52:10 PM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "text": "%md\n\n**NOTE** To install `scatterplot3d` on Ubuntu use:\n\n```sh\nsudo apt-get install r-cran-scatterplot3d\n```\n\n", - "dateUpdated": "Sep 28, 2016 1:54:37 PM", - "config": { - "colWidth": 6.0, - "enabled": true, - "editorMode": "ace/mode/markdown", - "editorHide": true, - "results": [ - { - "graph": { - "mode": "table", - "height": 300.0, - "optionOpen": false, - "keys": [], - "values": [], - "groups": [], - "scatter": {}, - "map": { - "baseMapType": "Streets", - "isOnline": true, - "pinCols": [] - } - } - } - ] - }, - "settings": { - "params": {}, - "forms": {} - }, - "apps": [], - "jobName": "paragraph_1475091302527_1223653372", - "id": "20160928-133502_1743267136", - "results": { - "code": "SUCCESS", - "msg": [ - { - "type": "HTML", - "data": "\u003cp\u003e\u003cstrong\u003eNOTE\u003c/strong\u003e To install \u003ccode\u003escatterplot3d\u003c/code\u003e on Ubuntu use:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class\u003d\"sh\"\u003esudo apt-get install r-cran-scatterplot3d\n\u003c/code\u003e\u003c/pre\u003e\n" - } - ] - }, - "dateCreated": "Sep 28, 2016 1:35:02 AM", - "dateStarted": "Sep 28, 2016 1:54:32 PM", - "dateFinished": "Sep 28, 2016 1:54:33 PM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "text": "%md\n", - "dateUpdated": "Sep 28, 2016 1:54:32 PM", - "config": {}, - "settings": { - "params": {}, - "forms": {} - }, - "apps": [], - "jobName": "paragraph_1475092472681_-955530461", - "id": "20160928-135432_2099340527", - "dateCreated": "Sep 28, 2016 1:54:32 PM", - "status": "READY", - "progressUpdateIntervalMs": 500 - } - ], - "name": "Zeppelin Tutorial/Using Mahout", - "id": "2BYEZ5EVK", - "angularObjects": { - "2C6WUGPNH:shared_process": [], - "2C4A8RJNB:shared_process": [], - "2C4DTK2ZT:shared_process": [], - "2C6XKJWBR:shared_process": [], - "2C6AHZPMK:shared_process": [], - "2C5SU66WQ:shared_process": [], - "2C6AMJ98Q:shared_process": [], - "2C4AJZK72:shared_process": [], - "2C3STPSD7:shared_process": [], - "2C4FJN9CK:shared_process": [], - "2C3CW6JBY:shared_process": [], - "2C5UPQX6Q:shared_process": [], - "2C5873KN4:shared_process": [], - "2C5719XN4:shared_process": [], - "2C52DE5G3:shared_process": [], - "2C4G28E63:shared_process": [], - "2C6CU96BC:shared_process": [], - "2C49A6WY3:shared_process": [], - "2C3NE73HG:shared_process": [] - }, - "config": {}, - "info": {} -} + "data": "\u003cp\u003e\u003cimg src\u003d\"data:image/png;base64,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 diff --git a/notebook/2C99MFRM2/note.json b/notebook/2C99MFRM2/note.json new file mode 100644 index 00000000000..4e76e27ba98 --- /dev/null +++ b/notebook/2C99MFRM2/note.json @@ -0,0 +1,648 @@ +{ + "paragraphs": [ + { + "text": "%md\n\n### This notebook explains how to use the [Neo4j](https://neo4j.com/)™ interpreter and the new NETWORK visualization leveraging the Labelled Property Graph Model.\n\n#### What is Neo4j?\n\nNeo4j is a highly scalable native graph database that leverages data relationships as first-class entities, helping enterprises build intelligent applications to meet today’s evolving data challenges.\n\n#### What is the Labelled Property Graph Model?\n\nA [Property Graph](https://github.com/tinkerpop/gremlin/wiki/Defining-a-Property-Graph) is a graph that has these elements:\n\n* a set of vertices\n * each vertex has a unique identifier.\n * each vertex has a set of outgoing edges.\n * each vertex has a set of incoming edges.\n * each vertex has a collection of properties defined by a map from key to value\n* a set of edges\n * each edge has a unique identifier.\n * each edge has an outgoing tail vertex.\n * each edge has an incoming head vertex.\n * each edge has a label that denotes the type of relationship between its two vertices.\n * each edge has a collection of properties defined by a map from key to value.\n\n![Property Graph](https://github.com/tinkerpop/gremlin/raw/master/doc/images/graph-example-1.jpg)\n\nA [Labelled Property Graph](https://neo4j.com/developer/graph-database/#property-graph) is a Property Graph where the nodes can be tagged with **labels** representing their different roles in the graph model\n\n![Labelled Property Graph](http://s3.amazonaws.com/dev.assets.neo4j.com/wp-content/uploads/property_graph_model.png)\n\nThis kind of graph can be easily *flatten* in order to support other visualization formats provided by Zeppelin.\n\nTo getting started you need a *running instance* of Neo4j then all you have to do is write your [Cypher](https://neo4j.com/developer/cypher-query-language/) queries.\n\nUse the mouse wheel to zoom-in/out and show the node and edge labels.", + "user": "anonymous", + "dateUpdated": "Jan 15, 2017 8:05:52 PM", + "config": { + "tableHide": false, + "editorSetting": { + "language": "markdown", + "editOnDblClick": true + }, + "colWidth": 12.0, + "editorMode": "ace/mode/markdown", + "editorHide": true, + "results": {}, + "enabled": true + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "HTML", + "data": "\u003cdiv class\u003d\"markdown-body\"\u003e\n\u003ch3\u003eThis notebook explains how to use the \u003ca href\u003d\"https://neo4j.com/\"\u003eNeo4j\u003c/a\u003e™ interpreter and the new NETWORK visualization leveraging the Labelled Property Graph Model.\u003c/h3\u003e\n\u003ch4\u003eWhat is Neo4j?\u003c/h4\u003e\n\u003cp\u003eNeo4j is a highly scalable native graph database that leverages data relationships as first-class entities, helping enterprises build intelligent applications to meet today’s evolving data challenges.\u003c/p\u003e\n\u003ch4\u003eWhat is the Labelled Property Graph Model?\u003c/h4\u003e\n\u003cp\u003eA \u003ca href\u003d\"https://github.com/tinkerpop/gremlin/wiki/Defining-a-Property-Graph\"\u003eProperty Graph\u003c/a\u003e is a graph that has these elements:\u003c/p\u003e\n\u003cul\u003e\n \u003cli\u003ea set of vertices\n \u003cul\u003e\n \u003cli\u003eeach vertex has a unique identifier.\u003c/li\u003e\n \u003cli\u003eeach vertex has a set of outgoing edges.\u003c/li\u003e\n \u003cli\u003eeach vertex has a set of incoming edges.\u003c/li\u003e\n \u003cli\u003eeach vertex has a collection of properties defined by a map from key to value\u003c/li\u003e\n \u003c/ul\u003e\n \u003c/li\u003e\n \u003cli\u003ea set of edges\n \u003cul\u003e\n \u003cli\u003eeach edge has a unique identifier.\u003c/li\u003e\n \u003cli\u003eeach edge has an outgoing tail vertex.\u003c/li\u003e\n \u003cli\u003eeach edge has an incoming head vertex.\u003c/li\u003e\n \u003cli\u003eeach edge has a label that denotes the type of relationship between its two vertices.\u003c/li\u003e\n \u003cli\u003eeach edge has a collection of properties defined by a map from key to value.\u003c/li\u003e\n \u003c/ul\u003e\n \u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg src\u003d\"https://github.com/tinkerpop/gremlin/raw/master/doc/images/graph-example-1.jpg\" alt\u003d\"Property Graph\" /\u003e\u003c/p\u003e\n\u003cp\u003eA \u003ca href\u003d\"https://neo4j.com/developer/graph-database/#property-graph\"\u003eLabelled Property Graph\u003c/a\u003e is a Property Graph where the nodes can be tagged with \u003cstrong\u003elabels\u003c/strong\u003e representing their different roles in the graph model\u003c/p\u003e\n\u003cp\u003e\u003cimg src\u003d\"http://s3.amazonaws.com/dev.assets.neo4j.com/wp-content/uploads/property_graph_model.png\" alt\u003d\"Labelled Property Graph\" /\u003e\u003c/p\u003e\n\u003cp\u003eThis kind of graph can be easily \u003cem\u003eflatten\u003c/em\u003e in order to support other visualization formats provided by Zeppelin.\u003c/p\u003e\n\u003cp\u003eTo getting started you need a \u003cem\u003erunning instance\u003c/em\u003e of Neo4j then all you have to do is write your \u003ca href\u003d\"https://neo4j.com/developer/cypher-query-language/\"\u003eCypher\u003c/a\u003e queries.\u003c/p\u003e\n\u003cp\u003eUse the mouse wheel to zoom-in/out and show the node and edge labels.\u003c/p\u003e\n\u003c/div\u003e" + } + ] + }, + "apps": [], + "jobName": "paragraph_1484489321698_1691467184", + "id": "20170109-185734_1552998102", + "dateCreated": "Jan 15, 2017 3:08:41 PM", + "dateStarted": "Jan 15, 2017 8:05:52 PM", + "dateFinished": "Jan 15, 2017 8:05:52 PM", + "status": "FINISHED", + "progressUpdateIntervalMs": 500 + }, + { + "text": "%md\n### Tutorial\nThis tutorial is based on [Rik Van Bruggen\u0027s Blog](http://blog.bruggen.com/) post [\"The Neo4j Knowledge Graph\"](http://blog.bruggen.com/2016/03/the-neo4j-knowledge-graph.html) which is a great start to understand the power of graph analytics to get insights from data.\nThere are two basic steps in this tutorial:\n\n1. Import the data into Neo4j from a csv file\n2. Query the data via Cypher queries\n\nThe graph model of our imported dataset looks like:", + "user": "anonymous", + "dateUpdated": "Jan 15, 2017 7:50:15 PM", + "config": { + "colWidth": 12.0, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "markdown", + "editOnDblClick": true + }, + "editorMode": "ace/mode/markdown", + "editorHide": true, + "tableHide": false + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "HTML", + "data": "\u003cdiv class\u003d\"markdown-body\"\u003e\n\u003ch3\u003eTutorial\u003c/h3\u003e\n\u003cp\u003eThis tutorial is based on \u003ca href\u003d\"http://blog.bruggen.com/\"\u003eRik Van Bruggen\u0026rsquo;s Blog\u003c/a\u003e post \u003ca href\u003d\"http://blog.bruggen.com/2016/03/the-neo4j-knowledge-graph.html\"\u003e\u0026ldquo;The Neo4j Knowledge Graph\u0026rdquo;\u003c/a\u003e which is a great start to understand the power of graph analytics to get insights from data.\u003cbr/\u003eThere are two basic steps in this tutorial:\u003c/p\u003e\n\u003col\u003e\n \u003cli\u003eImport the data into Neo4j from a csv file\u003c/li\u003e\n \u003cli\u003eQuery the data via Cypher queries\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eThe graph model of our imported dataset looks like:\u003c/p\u003e\n\u003c/div\u003e" + } + ] + }, + "apps": [], + "jobName": "paragraph_1484489548844_-369527049", + "id": "20170115-151228_289298576", + "dateCreated": "Jan 15, 2017 3:12:28 PM", + "dateStarted": "Jan 15, 2017 6:33:37 PM", + "dateFinished": "Jan 15, 2017 6:33:37 PM", + "status": "FINISHED", + "progressUpdateIntervalMs": 500 + }, + { + "text": "%spark\r\nprint(s\"\"\"\r\n%network {\r\n \"nodes\": [\r\n {\"id\": 1, \"label\": \"Author\"},\r\n {\"id\": 2, \"label\": \"Resource\"},\r\n {\"id\": 3, \"label\": \"Tag\"}\r\n ],\r\n \"edges\": [\r\n\t\t{\"source\": 1, \"target\": 2, \"id\" : 1, \"label\": \"CREATED\"},\r\n\t\t{\"source\": 2, \"target\": 3, \"id\" : 2, \"label\": \"TAGGED_AS\"}\r\n\t]\r\n}\r\n\"\"\")", + "user": "anonymous", + "dateUpdated": "Jan 16, 2017 9:12:54 AM", + "config": { + "colWidth": 12.0, + "enabled": true, + "results": { + "1": { + "graph": { + "mode": "network", + "height": 128.0, + "optionOpen": false, + "setting": { + "network": { + "properties": { + "Author": { + "selected": "label", + "keys": [ + "id", + "label" + ] + }, + "Resource": { + "selected": "label", + "keys": [ + "id", + "label" + ] + }, + "Tag": { + "selected": "label", + "keys": [ + "id", + "label" + ] + } + }, + "d3Graph": { + "forceLayout": { + "timeout": "5000", + "charge": -120.0, + "linkDistance": 80.0 + }, + "zoom": { + "minScale": "1" + } + } + } + }, + "commonSetting": {} + }, + "helium": {} + } + }, + "editorSetting": { + "language": "scala", + "editOnDblClick": false + }, + "editorMode": "ace/mode/scala" + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TEXT", + "data": "\n" + }, + { + "type": "NETWORK", + "data": "{\n \"nodes\": [\n {\"id\": 1, \"label\": \"Author\"},\n {\"id\": 2, \"label\": \"Resource\"},\n {\"id\": 3, \"label\": \"Tag\"}\n ],\n \"edges\": [\n\t\t{\"source\": 1, \"target\": 2, \"id\" : 1, \"label\": \"CREATED\"},\n\t\t{\"source\": 2, \"target\": 3, \"id\" : 2, \"label\": \"TAGGED_AS\"}\n\t]\n}\n" + } + ] + }, + "apps": [], + "jobName": "paragraph_1484501116117_1953042985", + "id": "20170115-182516_489605271", + "dateCreated": "Jan 15, 2017 6:25:16 PM", + "dateStarted": "Jan 15, 2017 7:23:57 PM", + "dateFinished": "Jan 15, 2017 7:23:58 PM", + "status": "FINISHED", + "progressUpdateIntervalMs": 500 + }, + { + "text": "%neo4j\n//Step 0: Import the data into Neo4j from a csv file\ncreate index on :Resource(name)", + "user": "anonymous", + "dateUpdated": "Jan 15, 2017 3:22:01 PM", + "config": { + "colWidth": 12.0, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "cypher", + "editOnDblClick": false + }, + "editorMode": "ace/mode/cypher", + "tableHide": true + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TABLE", + "data": "" + } + ] + }, + "apps": [], + "jobName": "paragraph_1484490033680_-60881287", + "id": "20170115-152033_542083475", + "dateCreated": "Jan 15, 2017 3:20:33 PM", + "dateStarted": "Jan 15, 2017 3:21:52 PM", + "dateFinished": "Jan 15, 2017 3:21:52 PM", + "status": "FINISHED", + "progressUpdateIntervalMs": 500 + }, + { + "text": "%neo4j\n//Step 0: mport the data into Neo4j from a csv file\ncreate index on :Resource(comments)", + "user": "anonymous", + "dateUpdated": "Jan 15, 2017 3:22:04 PM", + "config": { + "colWidth": 12.0, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "cypher", + "editOnDblClick": false + }, + "editorMode": "ace/mode/cypher", + "tableHide": true + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TABLE", + "data": "" + } + ] + }, + "apps": [], + "jobName": "paragraph_1484490093873_-1082112137", + "id": "20170115-152133_1231910179", + "dateCreated": "Jan 15, 2017 3:21:33 PM", + "dateStarted": "Jan 15, 2017 3:21:56 PM", + "dateFinished": "Jan 15, 2017 3:21:56 PM", + "status": "FINISHED", + "progressUpdateIntervalMs": 500 + }, + { + "text": "%neo4j\r\n//Step 1: Import the csv data into Neo4j from a csv file\r\nload csv with headers from \"https://docs.google.com/a/neotechnology.com/spreadsheets/d/1X6DpFZoS01V1crgRED4dRz2UkbiYR8FJMPf9xey9Lwc/export?format\u003dcsv\u0026id\u003d1X6DpFZoS01V1crgRED4dRz2UkbiYR8FJMPf9xey9Lwc\u0026gid\u003d0\" as csv\r\nmerge (r:Resource {name: csv.What, url: csv.Where, comments: csv.Comments})\r\nwith csv\r\nmerge (a:Author {name: csv.Who})\r\nwith csv\r\nmatch (r:Resource {name: csv.What}), (a:Author {name: csv.Who})\r\nmerge (a)-[:CREATED]-\u003e(r)\r\nwith csv,a,r\r\nmerge (a)-[:CREATED]-\u003e(r)\r\nwith csv.What as Resource, csv.Tags as row\r\nunwind row as text\r\nwith Resource, [w in split(text,\", \") | trim(w)] as words\r\nunwind range(0,size(words)-2) as idx\r\nMATCH (r:Resource {name: Resource})\r\nMERGE (t1:Tag {name:words[idx]})\r\nMERGE (t2:Tag {name:words[idx+1]})\r\nMERGE (r)-[:TAGGED_AS]-\u003e(t1)\r\nMERGE (r)-[:TAGGED_AS]-\u003e(t2);", + "user": "anonymous", + "dateUpdated": "Jan 15, 2017 6:34:03 PM", + "config": { + "colWidth": 12.0, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "cypher", + "editOnDblClick": false + }, + "editorMode": "ace/mode/cypher", + "tableHide": true + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TABLE", + "data": "" + } + ] + }, + "apps": [], + "jobName": "paragraph_1484489491100_483384642", + "id": "20170115-151131_929877784", + "dateCreated": "Jan 15, 2017 3:11:31 PM", + "dateStarted": "Jan 15, 2017 6:34:03 PM", + "dateFinished": "Jan 15, 2017 6:34:05 PM", + "status": "ABORT", + "progressUpdateIntervalMs": 500 + }, + { + "text": "%neo4j\n//Find some Authors, Resources and Tags\nMATCH p \u003d ((a:Author)--(r:Resource)--(t:Tag))\nreturn p\nlimit 25", + "user": "anonymous", + "dateUpdated": "Jan 16, 2017 9:17:13 AM", + "config": { + "colWidth": 12.0, + "enabled": true, + "results": { + "0": { + "graph": { + "mode": "network", + "height": 379.0, + "optionOpen": false + }, + "helium": {} + } + }, + "editorSetting": { + "language": "cypher", + "editOnDblClick": false + }, + "editorMode": "ace/mode/cypher" + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "NETWORK", + "data": "{\"nodes\":[{\"id\":0,\"data\":{\"comments\":\"A WebGL distributed graph visualization library\",\"name\":\"3dg-viz\",\"url\":\"https://github.com/kbastani/3dg-viz\"},\"label\":\"Resource\",\"color\":\"#9DE79F\"},{\"id\":192,\"data\":{\"name\":\"import\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":1,\"data\":{\"comments\":\"Easily import data into Neo4j from a relational database\",\"name\":\"RDBMS2Neo4j\",\"url\":\"https://github.com/johnymontana/RDBMS2Neo4j\"},\"label\":\"Resource\",\"color\":\"#9DE79F\"},{\"id\":3,\"data\":{\"comments\":\"The lazy way to run multi-statement Neo4j Cypher scripts from the web\",\"name\":\"LazyWebCypher\",\"url\":\"https://github.com/johnymontana/LazyWebCypher\"},\"label\":\"Resource\",\"color\":\"#9DE79F\"},{\"id\":262,\"data\":{\"name\":\"big data\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":263,\"data\":{\"name\":\"spark\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":200,\"data\":{\"name\":\"document\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":266,\"data\":{\"name\":\"library\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":281,\"data\":{\"name\":\"classification\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":224,\"data\":{\"name\":\"nlp\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":225,\"data\":{\"name\":\"text\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":100,\"data\":{\"comments\":\"Will Lyon\\u0027s blog\",\"name\":\"Will Lyon\\u0027s blog\",\"url\":\"http://www.lyonwj.com/\"},\"label\":\"Resource\",\"color\":\"#9DE79F\"},{\"id\":306,\"data\":{\"name\":\"usa\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":116,\"data\":{\"comments\":\"Mazerunner extends a Neo4j graph database to run scheduled big data graph compute algorithms at scale with HDFS and Apache Spark.\",\"name\":\"neo4j-mazerunner\",\"url\":\"https://github.com/neo4j-contrib/neo4j-mazerunner\"},\"label\":\"Resource\",\"color\":\"#9DE79F\"},{\"id\":52,\"data\":{\"comments\":\"Graphify is a Neo4j unmanaged extension used for document and text classification using graph-based hierarchical pattern recognition.\",\"name\":\"graphify\",\"url\":\"https://github.com/Graphify/graphify\"},\"label\":\"Resource\",\"color\":\"#9DE79F\"},{\"id\":181,\"data\":{\"name\":\"code\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":182,\"data\":{\"name\":\"visualization\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":183,\"data\":{\"name\":\"webgl\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":120,\"data\":{\"name\":\"Kenny Bastani\"},\"label\":\"Author\",\"color\":\"#17F40D\"},{\"id\":184,\"data\":{\"name\":\"rdbms\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":121,\"data\":{\"name\":\"Will Lyon\"},\"label\":\"Author\",\"color\":\"#17F40D\"},{\"id\":185,\"data\":{\"name\":\"tool\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":186,\"data\":{\"name\":\"integration\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":315,\"data\":{\"name\":\"graph algorithms\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":187,\"data\":{\"name\":\"cypher\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":252,\"data\":{\"name\":\"blog\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":188,\"data\":{\"name\":\"script\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":191,\"data\":{\"name\":\"component\"},\"label\":\"Tag\",\"color\":\"#1B289C\"}],\"edges\":[{\"source\":120,\"target\":0,\"type\":\"arrow\",\"count\":1,\"id\":0,\"data\":{},\"label\":\"CREATED\",\"color\":\"#D3D3D3\"},{\"source\":121,\"target\":1,\"type\":\"arrow\",\"count\":1,\"id\":1,\"data\":{},\"label\":\"CREATED\",\"color\":\"#D3D3D3\"},{\"source\":121,\"target\":3,\"type\":\"arrow\",\"count\":1,\"id\":3,\"data\":{},\"label\":\"CREATED\",\"color\":\"#D3D3D3\"},{\"source\":3,\"target\":181,\"type\":\"arrow\",\"count\":1,\"id\":131,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":3,\"target\":187,\"type\":\"arrow\",\"count\":1,\"id\":132,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":3,\"target\":188,\"type\":\"arrow\",\"count\":1,\"id\":133,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":100,\"target\":252,\"type\":\"arrow\",\"count\":1,\"id\":340,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":100,\"target\":306,\"type\":\"arrow\",\"count\":1,\"id\":471,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":121,\"target\":100,\"type\":\"arrow\",\"count\":1,\"id\":100,\"data\":{},\"label\":\"CREATED\",\"color\":\"#D3D3D3\"},{\"source\":116,\"target\":315,\"type\":\"arrow\",\"count\":1,\"id\":487,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":52,\"target\":281,\"type\":\"arrow\",\"count\":1,\"id\":425,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":116,\"target\":181,\"type\":\"arrow\",\"count\":1,\"id\":366,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":116,\"target\":262,\"type\":\"arrow\",\"count\":1,\"id\":367,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":116,\"target\":263,\"type\":\"arrow\",\"count\":1,\"id\":368,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":52,\"target\":181,\"type\":\"arrow\",\"count\":1,\"id\":241,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":52,\"target\":191,\"type\":\"arrow\",\"count\":1,\"id\":242,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":52,\"target\":224,\"type\":\"arrow\",\"count\":1,\"id\":243,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":120,\"target\":116,\"type\":\"arrow\",\"count\":1,\"id\":116,\"data\":{},\"label\":\"CREATED\",\"color\":\"#D3D3D3\"},{\"source\":120,\"target\":52,\"type\":\"arrow\",\"count\":1,\"id\":52,\"data\":{},\"label\":\"CREATED\",\"color\":\"#D3D3D3\"},{\"source\":52,\"target\":200,\"type\":\"arrow\",\"count\":1,\"id\":244,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":52,\"target\":225,\"type\":\"arrow\",\"count\":1,\"id\":245,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":0,\"target\":266,\"type\":\"arrow\",\"count\":1,\"id\":373,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":1,\"target\":192,\"type\":\"arrow\",\"count\":1,\"id\":374,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":0,\"target\":181,\"type\":\"arrow\",\"count\":1,\"id\":120,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":3,\"target\":185,\"type\":\"arrow\",\"count\":1,\"id\":376,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":0,\"target\":182,\"type\":\"arrow\",\"count\":1,\"id\":121,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":0,\"target\":183,\"type\":\"arrow\",\"count\":1,\"id\":122,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":1,\"target\":181,\"type\":\"arrow\",\"count\":1,\"id\":123,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":1,\"target\":184,\"type\":\"arrow\",\"count\":1,\"id\":124,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":1,\"target\":185,\"type\":\"arrow\",\"count\":1,\"id\":125,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":1,\"target\":186,\"type\":\"arrow\",\"count\":1,\"id\":126,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"}],\"labels\":{\"Resource\":\"#9DE79F\",\"Author\":\"#17F40D\",\"Tag\":\"#1B289C\"},\"types\":[\"CREATED\",\"TAGGED_AS\"]}" + } + ] + }, + "apps": [], + "jobName": "paragraph_1484554427445_-1764437803", + "id": "20170116-091347_2034270437", + "dateCreated": "Jan 16, 2017 9:13:47 AM", + "dateStarted": "Jan 16, 2017 9:13:51 AM", + "dateFinished": "Jan 16, 2017 9:13:54 AM", + "status": "FINISHED", + "progressUpdateIntervalMs": 500 + }, + { + "text": "%neo4j\n//Find some Authors, Resources and Tags connected to Rik or Max\nMATCH (t:Tag)--(r:Resource)--(a:Author)\nwhere a.name contains \"${Name To Find\u003dRik,Rik|Max}\"\nreturn t,r,a", + "user": "anonymous", + "dateUpdated": "Jan 16, 2017 9:16:47 AM", + "config": { + "colWidth": 12.0, + "enabled": true, + "results": { + "0": { + "graph": { + "mode": "network", + "height": 207.0, + "optionOpen": false, + "setting": { + "multiBarChart": {}, + "network": { + "properties": { + "Resource": { + "selected": "name", + "keys": [ + "comments", + "name", + "url", + "id", + "label" + ] + }, + "Tag": { + "selected": "name", + "keys": [ + "name", + "id", + "label" + ] + }, + "Author": { + "selected": "name", + "keys": [ + "name", + "id", + "label" + ] + } + }, + "d3Graph": { + "forceLayout": { + "timeout": 10000.0, + "charge": -120.0, + "linkDistance": 80.0 + }, + "zoom": { + "minScale": "1" + } + } + } + }, + "commonSetting": {}, + "keys": [ + { + "name": "label", + "index": 1.0, + "aggr": "sum" + } + ], + "groups": [], + "values": [ + { + "name": "label", + "index": 1.0, + "aggr": "sum" + } + ] + }, + "helium": {} + } + }, + "editorSetting": { + "language": "cypher", + "editOnDblClick": false + }, + "editorMode": "ace/mode/cypher" + }, + "settings": { + "params": { + "First Name To Find,Rik": "", + "Second Name To Find,Max": "", + "First Name To Find": "Rik", + "Second Name To Find": "Max", + "Name To Find": "Rik" + }, + "forms": { + "Name To Find": { + "name": "Name To Find", + "defaultValue": "Rik", + "options": [ + { + "value": "Rik" + }, + { + "value": "Max" + } + ], + "hidden": false + } + } + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "NETWORK", + "data": "{\"nodes\":[{\"id\":241,\"data\":{\"name\":\"book\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":243,\"data\":{\"name\":\"english\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":244,\"data\":{\"name\":\"packt\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":250,\"data\":{\"name\":\"podcast\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":74,\"data\":{\"comments\":\"Run blazingly fast queries on complex graph datasets with the power of the Neo4j graph database.\",\"name\":\"Learning Neo4j\",\"url\":\"http://learningneo4j.net\"},\"label\":\"Resource\",\"color\":\"#9DE79F\"},{\"id\":155,\"data\":{\"name\":\"Rik Van Bruggen\"},\"label\":\"Author\",\"color\":\"#17F40D\"},{\"id\":251,\"data\":{\"name\":\"fun\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":252,\"data\":{\"name\":\"blog\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":93,\"data\":{\"comments\":\"Podcast on all things Neo4j\",\"name\":\"Neo4j podcast\",\"url\":\"http://graphistania.com\"},\"label\":\"Resource\",\"color\":\"#9DE79F\"},{\"id\":94,\"data\":{\"comments\":\"Rik Van Bruggen\\u0027s blog\",\"name\":\"Rik Van Bruggen\\u0027s blog\",\"url\":\"http://blog.bruggen.com\"},\"label\":\"Resource\",\"color\":\"#9DE79F\"},{\"id\":302,\"data\":{\"name\":\"audio\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":303,\"data\":{\"name\":\"belgium\"},\"label\":\"Tag\",\"color\":\"#1B289C\"}],\"edges\":[],\"labels\":{\"Resource\":\"#9DE79F\",\"Author\":\"#17F40D\",\"Tag\":\"#1B289C\"},\"types\":[\"CREATED\",\"TAGGED_AS\"]}" + } + ] + }, + "apps": [], + "jobName": "paragraph_1484490205850_296812597", + "id": "20170115-152325_387433852", + "dateCreated": "Jan 15, 2017 3:23:25 PM", + "dateStarted": "Jan 15, 2017 8:05:18 PM", + "dateFinished": "Jan 15, 2017 8:05:18 PM", + "status": "FINISHED", + "progressUpdateIntervalMs": 500 + }, + { + "text": "%md\nWhen your Cypher query return data as a table the Network visualization is automatically excluded\n", + "user": "anonymous", + "dateUpdated": "Jan 15, 2017 6:32:14 PM", + "config": { + "colWidth": 12.0, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "markdown", + "editOnDblClick": true + }, + "editorMode": "ace/mode/markdown", + "editorHide": true, + "tableHide": false + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "HTML", + "data": "\u003cdiv class\u003d\"markdown-body\"\u003e\n\u003cp\u003eWhen your Cypher query return data as a table the Network visualization is automatically excluded\u003c/p\u003e\n\u003c/div\u003e" + } + ] + }, + "apps": [], + "jobName": "paragraph_1484501447412_1083770982", + "id": "20170115-183047_202915023", + "dateCreated": "Jan 15, 2017 6:30:47 PM", + "dateStarted": "Jan 15, 2017 6:32:14 PM", + "dateFinished": "Jan 15, 2017 6:32:15 PM", + "status": "FINISHED", + "progressUpdateIntervalMs": 500 + }, + { + "text": "%neo4j\r\n//find some resources and authors\r\nMATCH (r:Resource)--(a:Author)\r\nwhere a.name contains \"${First Name To Find\u003dRik}\" or a.name contains \"${Second Name To Find\u003dMax}\"\r\nreturn distinct a.name as Author, r.name as Resource, r.url as URL, r.comments as Description\r\norder by Author;", + "user": "anonymous", + "dateUpdated": "Jan 15, 2017 6:34:32 PM", + "config": { + "colWidth": 12.0, + "enabled": true, + "results": { + "0": { + "graph": { + "mode": "pieChart", + "height": 300.0, + "optionOpen": false, + "setting": { + "pieChart": {} + }, + "commonSetting": {}, + "keys": [ + { + "name": "Author", + "index": 2.0, + "aggr": "sum" + } + ], + "groups": [], + "values": [ + { + "name": "Author", + "index": 2.0, + "aggr": "count" + } + ] + }, + "helium": {} + } + }, + "editorSetting": { + "language": "cypher", + "editOnDblClick": false + }, + "editorMode": "ace/mode/cypher" + }, + "settings": { + "params": { + "First Name To Find": "Rik", + "Second Name To Find": "Max" + }, + "forms": { + "Second Name To Find": { + "name": "Second Name To Find", + "defaultValue": "Max", + "hidden": false + }, + "First Name To Find": { + "name": "First Name To Find", + "defaultValue": "Rik", + "hidden": false + } + } + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TABLE", + "data": "Description\tResource\tAuthor\tURL\n\"Demo visualization of Neo4j data\"\t\"neovigator\"\t\"Max De Marzi\"\t\"https://github.com/maxdemarzi/neovigator\"\n\"Neo4j POC to Integrate VisualSearch.js and Cypher\"\t\"neo-visual-search\"\t\"Max De Marzi\"\t\"https://github.com/maxdemarzi/neo_visual_search\"\n\"Max De Marzi\u0027s blog\"\t\"Max De Marzi\u0027s blog\"\t\"Max De Marzi\"\t\"http://maxdemarzi.com\"\n\"A thin Ruby wrapper to the Neo4j Rest API.\"\t\"neography\"\t\"Max De Marzi\"\t\"https://github.com/maxdemarzi/neography\"\n\"Rik Van Bruggen\u0027s blog\"\t\"Rik Van Bruggen\u0027s blog\"\t\"Rik Van Bruggen\"\t\"http://blog.bruggen.com\"\n\"Podcast on all things Neo4j\"\t\"Neo4j podcast\"\t\"Rik Van Bruggen\"\t\"http://graphistania.com\"\n\"Run blazingly fast queries on complex graph datasets with the power of the Neo4j graph database.\"\t\"Learning Neo4j\"\t\"Rik Van Bruggen\"\t\"http://learningneo4j.net\"\n" + } + ] + }, + "apps": [], + "jobName": "paragraph_1484500926122_1350835980", + "id": "20170115-182206_1701051593", + "dateCreated": "Jan 15, 2017 6:22:06 PM", + "dateStarted": "Jan 15, 2017 6:30:36 PM", + "dateFinished": "Jan 15, 2017 6:30:36 PM", + "status": "FINISHED", + "progressUpdateIntervalMs": 500 + }, + { + "text": "%neo4j\r\n//find some paths between books and blogs\r\nmatch (t1:Tag {name:\"book\"}), (t2:Tag {name:\"blog\"}),\r\np \u003d allshortestpaths ((t1)-[*]-(t2))\r\nreturn p\r\nlimit 10", + "user": "anonymous", + "dateUpdated": "Jan 16, 2017 9:04:12 AM", + "config": { + "colWidth": 12.0, + "enabled": true, + "results": { + "0": { + "graph": { + "mode": "network", + "height": 300.0, + "optionOpen": false + }, + "helium": {} + } + }, + "editorSetting": { + "language": "cypher", + "editOnDblClick": false + }, + "editorMode": "ace/mode/cypher" + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "NETWORK", + "data": "{\"nodes\":[{\"id\":241,\"data\":{\"name\":\"book\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":74,\"data\":{\"comments\":\"Run blazingly fast queries on complex graph datasets with the power of the Neo4j graph database.\",\"name\":\"Learning Neo4j\",\"url\":\"http://learningneo4j.net\"},\"label\":\"Resource\",\"color\":\"#9DE79F\"},{\"id\":122,\"data\":{\"name\":\"Michael Hunger\"},\"label\":\"Author\",\"color\":\"#17F40D\"},{\"id\":155,\"data\":{\"name\":\"Rik Van Bruggen\"},\"label\":\"Author\",\"color\":\"#17F40D\"},{\"id\":75,\"data\":{\"comments\":\"Eine Graphdatenbank für alle\",\"name\":\"Neo4j 2.0\",\"url\":\"http://neo4j.com/books/neo4j-2-0-eine-graphdatenbank-fur-alle/\"},\"label\":\"Resource\",\"color\":\"#9DE79F\"},{\"id\":252,\"data\":{\"name\":\"blog\"},\"label\":\"Tag\",\"color\":\"#1B289C\"},{\"id\":94,\"data\":{\"comments\":\"Rik Van Bruggen\\u0027s blog\",\"name\":\"Rik Van Bruggen\\u0027s blog\",\"url\":\"http://blog.bruggen.com\"},\"label\":\"Resource\",\"color\":\"#9DE79F\"},{\"id\":95,\"data\":{\"comments\":\"Michael Hunger\\u0027s blog\",\"name\":\"Michael Hunger\\u0027s blog\",\"url\":\"http://jexp.de/blog\"},\"label\":\"Resource\",\"color\":\"#9DE79F\"}],\"edges\":[{\"source\":74,\"target\":241,\"type\":\"arrow\",\"count\":1,\"id\":295,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":75,\"target\":241,\"type\":\"arrow\",\"count\":1,\"id\":297,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":155,\"target\":74,\"type\":\"arrow\",\"count\":1,\"id\":74,\"data\":{},\"label\":\"CREATED\",\"color\":\"#D3D3D3\"},{\"source\":122,\"target\":75,\"type\":\"arrow\",\"count\":1,\"id\":75,\"data\":{},\"label\":\"CREATED\",\"color\":\"#D3D3D3\"},{\"source\":155,\"target\":94,\"type\":\"arrow\",\"count\":1,\"id\":94,\"data\":{},\"label\":\"CREATED\",\"color\":\"#D3D3D3\"},{\"source\":94,\"target\":252,\"type\":\"arrow\",\"count\":1,\"id\":334,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"},{\"source\":122,\"target\":95,\"type\":\"arrow\",\"count\":1,\"id\":95,\"data\":{},\"label\":\"CREATED\",\"color\":\"#D3D3D3\"},{\"source\":95,\"target\":252,\"type\":\"arrow\",\"count\":1,\"id\":335,\"data\":{},\"label\":\"TAGGED_AS\",\"color\":\"#D3D3D3\"}],\"labels\":{\"Resource\":\"#9DE79F\",\"Author\":\"#17F40D\",\"Tag\":\"#1B289C\"},\"types\":[\"CREATED\",\"TAGGED_AS\"]}" + } + ] + }, + "apps": [], + "jobName": "paragraph_1484506516640_1639023821", + "id": "20170115-195516_709966475", + "dateCreated": "Jan 15, 2017 7:55:16 PM", + "dateStarted": "Jan 15, 2017 8:06:11 PM", + "dateFinished": "Jan 15, 2017 8:06:12 PM", + "status": "FINISHED", + "progressUpdateIntervalMs": 500 + }, + { + "user": "anonymous", + "config": {}, + "settings": { + "params": {}, + "forms": {} + }, + "apps": [], + "jobName": "paragraph_1484507139767_925173928", + "id": "20170115-200539_1236670114", + "dateCreated": "Jan 15, 2017 8:05:39 PM", + "status": "READY", + "progressUpdateIntervalMs": 500 + } + ], + "name": "Zeppelin Tutorial/Using Neo4j", + "id": "2C8QUSPXP", + "angularObjects": { + "2C69VZSHH:shared_process": [], + "2C7NPWJN9:shared_process": [], + "2C9CRSNEJ:shared_process": [], + "2C8FBTA2M:shared_process": [], + "2C7J47MSN:shared_process": [], + "2C772Q3UZ:shared_process": [], + "2C5NCX7B4:shared_process": [], + "2C98M48X5:shared_process": [], + "2C93N42FT:shared_process": [], + "2C8WAY6V3:shared_process": [], + "2C8D3NDXW:shared_process": [], + "2C7QW1QE4:shared_process": [], + "2C5S4JN33:shared_process": [], + "2C8GXP4YH:shared_process": [], + "2C5ZE5S93:shared_process": [], + "2C8YZ8XHF:shared_process": [], + "2C8CX1HH2:shared_process": [], + "2C5X2BVCC:shared_process": [], + "2C898P8HW:shared_process": [], + "2C7AC9CD7:shared_process": [] + }, + "config": {}, + "info": {} +} diff --git a/pom.xml b/pom.xml index fdca38177ad..a24ca99ff21 100644 --- a/pom.xml +++ b/pom.xml @@ -75,6 +75,7 @@ bigquery alluxio scio + neo4j zeppelin-web zeppelin-server zeppelin-distribution diff --git a/zeppelin-distribution/src/bin_license/LICENSE b/zeppelin-distribution/src/bin_license/LICENSE index d27f27d44ea..081f994a3cb 100644 --- a/zeppelin-distribution/src/bin_license/LICENSE +++ b/zeppelin-distribution/src/bin_license/LICENSE @@ -214,6 +214,7 @@ The following components are provided under Apache License. (Apache 2.0) Maven Wagon HTTP Shared 1.0 (org.apache.maven.wagon:wagon-http-shared:1.0 - https://mvnrepository.com/artifact/org.apache.maven.wagon/wagon-http-shared/1.0) (Apache 2.0) Commons HTTP Client 3.1 (commons-httpclient:commons-httpclient:3.1 - https://mvnrepository.com/artifact/commons-httpclient/commons-httpclient/3.1) (Apache 2.0) Scalatest 2.2.4 (org.scalatest:scalatest_2.10:2.2.4 - https://github.com/scalatest/scalatest) + (Apache 2.0) Neo4j Java Driver (https://github.com/neo4j/neo4j-java-driver) - https://github.com/neo4j/neo4j-java-driver/blob/1.1/LICENSE.txt (Apache 2.0) frontend-maven-plugin 1.3 (com.github.eirslett:frontend-maven-plugin:1.3 - https://github.com/eirslett/frontend-maven-plugin/blob/frontend-plugins-1.3/LICENSE (Apache 2.0) frontend-plugin-core 1.3 (com.github.eirslett:frontend-plugin-core) - https://github.com/eirslett/frontend-maven-plugin/blob/frontend-plugins-1.3/LICENSE diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterResult.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterResult.java index 5288f6f4ef9..6c7a1ca72aa 100644 --- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterResult.java +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterResult.java @@ -50,7 +50,8 @@ public static enum Type { TABLE, IMG, SVG, - NULL + NULL, + NETWORK } Code code; diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/GraphEntity.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/GraphEntity.java new file mode 100644 index 00000000000..73d1c6f1894 --- /dev/null +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/GraphEntity.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zeppelin.interpreter.graph; + +import java.util.Map; + +/** + * The base network entity + * + */ +public abstract class GraphEntity { + + private long id; + + /** + * The data of the entity + * + */ + private Map data; + + /** + * The primary type of the entity + */ + private String label; + + private String color; + + public GraphEntity() {} + + public GraphEntity(long id, Map data, String label, + String color) { + super(); + this.setId(id); + this.setData(data); + this.setLabel(label); + this.setColor(color); + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public Map getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + +} diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/GraphResult.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/GraphResult.java new file mode 100644 index 00000000000..29356dc6305 --- /dev/null +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/GraphResult.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zeppelin.interpreter.graph; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import org.apache.zeppelin.interpreter.InterpreterResult; + +import com.google.gson.Gson; + +/** + * The intepreter result template for Networks + * + */ +public class GraphResult extends InterpreterResult { + + /** + * The Graph structure parsed from the front-end + * + */ + public static class Graph { + private Collection nodes; + + private Collection edges; + + /** + * The node types in the whole graph, and the related colors + * + */ + private Map labels; + + /** + * The relationship types in the whole graph + * + */ + private Set types; + + public Graph() {} + + public Graph(Collection nodes, Collection edges, + Map labels, Set types) { + super(); + this.setNodes(nodes); + this.setEdges(edges); + this.setLabels(labels); + this.setTypes(types); + } + + public Collection getNodes() { + return nodes; + } + + public void setNodes(Collection nodes) { + this.nodes = nodes; + } + + public Collection getEdges() { + return edges; + } + + public void setEdges(Collection edges) { + this.edges = edges; + } + + public Map getLabels() { + return labels; + } + + public void setLabels(Map labels) { + this.labels = labels; + } + + public Set getTypes() { + return types; + } + + public void setTypes(Set types) { + this.types = types; + } + + } + + private static final Gson gson = new Gson(); + + public GraphResult(Code code, Graph graphObject) { + super(code, Type.NETWORK, gson.toJson(graphObject)); + } + +} diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/GraphUtils.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/GraphUtils.java new file mode 100644 index 00000000000..59c51619471 --- /dev/null +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/GraphUtils.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zeppelin.interpreter.graph; + +/** + * An utiliy class for networks + * + */ +public class GraphUtils { + private GraphUtils() {} + + private static final String[] LETTERS = "0123456789ABCDEF".split(""); + + public static String getRandomColor() { + char[] color = new char[7]; + color[0] = '#'; + for (int i = 1; i < color.length; i++) { + color[i] = LETTERS[(int) Math.floor(Math.random() * 16)].charAt(0); + } + return new String(color); + } + +} diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/Node.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/Node.java new file mode 100644 index 00000000000..1ad6d9c8970 --- /dev/null +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/Node.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zeppelin.interpreter.graph; + +import java.util.Map; +import java.util.Set; + +/** + * The Zeppelin Node Entity + * + */ +public class Node extends GraphEntity { + + /** + * The labels (types) attached to a node + */ + private Set labels; + + public Node() {} + + + public Node(long id, Map data, Set labels, + String color) { + super(id, data, labels.iterator().next(), color); + } + + public Set getLabels() { + return labels; + } + + public void setLabels(Set labels) { + this.labels = labels; + } + +} diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/Relationship.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/Relationship.java new file mode 100644 index 00000000000..a32bcc3fbc9 --- /dev/null +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/Relationship.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zeppelin.interpreter.graph; + +import java.util.Map; + +/** + * The Zeppelin Relationship entity + * + */ +public class Relationship extends GraphEntity { + + private long source; + + private long target; + + private Type type; + + /** + * The number of relations that exists between source and target + * + */ + private int count; + + /** + * The relationship shape type + * + */ + public enum Type{arrow, curvedArrow} + + public static final String COLOR_GREY = "#D3D3D3"; + + public Relationship() {} + + public Relationship(long id, Map data, long source, + long target, String label, Type type, int count) { + super(id, data, label, COLOR_GREY); + this.setSource(source); + this.setTarget(target); + this.setType(type); + this.setCount(count); + } + + public Relationship(long id, Map data, long source, + long target, String label, Type type) { + this(id, data, source, target, label, type, 0); + } + + public long getSource() { + return source; + } + + public void setSource(long startNodeId) { + this.source = startNodeId; + } + + public long getTarget() { + return target; + } + + public void setTarget(long endNodeId) { + this.target = endNodeId; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + +} diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.css b/zeppelin-web/src/app/notebook/paragraph/paragraph.css index 961a5f089ca..51118afd86c 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph.css +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.css @@ -595,3 +595,7 @@ table.table-striped { .markdown-body h4 { font-size: 16px; } + +.network-badge { + margin: 0.2em; +} \ No newline at end of file diff --git a/zeppelin-web/src/app/notebook/paragraph/result/result-chart-selector.html b/zeppelin-web/src/app/notebook/paragraph/result/result-chart-selector.html index 0d2afb7b530..a46e4d6b62d 100644 --- a/zeppelin-web/src/app/notebook/paragraph/result/result-chart-selector.html +++ b/zeppelin-web/src/app/notebook/paragraph/result/result-chart-selector.html @@ -13,13 +13,14 @@ -->
    -
    +
    @@ -27,7 +28,7 @@
    + +
    + +
    + +
    + +
    \ No newline at end of file diff --git a/zeppelin-web/src/app/tabledata/networkdata.js b/zeppelin-web/src/app/tabledata/networkdata.js new file mode 100644 index 00000000000..5059ed2e72d --- /dev/null +++ b/zeppelin-web/src/app/tabledata/networkdata.js @@ -0,0 +1,135 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import TableData from './tabledata'; +import {DatasetType} from './dataset'; + +/** + * Create network data object from paragraph graph type result + */ +export default class NetworkData extends TableData { + constructor(graph) { + super(); + this.graph = graph || {}; + if (this.graph.nodes) { + this.loadParagraphResult({msg: JSON.stringify(graph), type: DatasetType.NETWORK}); + } + }; + + loadParagraphResult(paragraphResult) { + if (!paragraphResult || paragraphResult.type !== DatasetType.NETWORK) { + console.log('Can not load paragraph result'); + return; + } + + this.graph = JSON.parse(paragraphResult.msg.trim() || '{}'); + + if (!this.graph.nodes) { + console.log('Graph result is empty'); + return; + } + + this.setNodesDefaults(); + this.setEdgesDefaults(); + + this.networkNodes = angular.equals({}, this.graph.labels || {}) ? + null : {count: this.graph.nodes.length, labels: this.graph.labels}; + this.networkRelationships = angular.equals([], this.graph.types || []) ? + null : {count: this.graph.edges.length, types: this.graph.types}; + + var columnNames = []; + var rows = []; + var comment = ''; + var entities = this.graph.nodes.concat(this.graph.edges); + var baseColumnNames = [{name: 'id', index: 0, aggr: 'sum'}, + {name: 'label', index: 1, aggr: 'sum'}]; + var internalFieldsToJump = ['count', 'type', 'size', + 'data', 'x', 'y', 'color', + 'labels']; + var baseCols = _.map(baseColumnNames, function(col) { return col.name; }); + var keys = _.map(entities, function(elem) { return Object.keys(elem.data || {}); }); + keys = _.flatten(keys); + keys = _.uniq(keys).filter(function(key) { + return baseCols.indexOf(key) === -1; + }); + var columnNames = baseColumnNames.concat(_.map(keys, function(elem, i) { + return {name: elem, index: i + baseColumnNames.length, aggr: 'sum'}; + })); + for (var i = 0; i < entities.length; i++) { + var entity = entities[i]; + var col = []; + var col2 = []; + entity.data = entity.data || {}; + for (var j = 0; j < columnNames.length; j++) { + var name = columnNames[j].name; + var value = name in entity && internalFieldsToJump.indexOf(name) === -1 ? + entity[name] : entity.data[name]; + var parsedValue = value === null || value === undefined ? '' : value; + col.push(parsedValue); + col2.push({key: name, value: parsedValue}); + } + rows.push(col); + } + + this.comment = comment; + this.columns = columnNames; + this.rows = rows; + }; + + setNodesDefaults() { + this.graph.nodes + .forEach(function(node) { + node.x = node.x || Math.random(); + node.y = node.y || Math.random(); + node.size = node.size || 10; + node.weight = node.weight || 1; + }); + }; + + setEdgesDefaults() { + let nodes = this.graph.nodes; + this.graph.edges + .forEach(function(edge) { + edge.type = edge.type || 'arrow'; + edge.color = edge.color || '#D3D3D3'; + edge.count = edge.count || 1; + if (typeof +edge.source === 'number') { + edge.source = nodes.filter((node) => edge.source === node.id)[0] || null; + } + if (typeof +edge.target === 'number') { + edge.target = nodes.filter((node) => edge.target === node.id)[0] || null; + } + }); + }; + + getNetworkProperties() { + var baseCols = ['id', 'label']; + var properties = {}; + this.graph.nodes.forEach(function(node) { + var hasLabel = 'label' in node && node.label !== ''; + if (!hasLabel) { + return; + } + var label = node.label; + var hasKey = hasLabel && label in properties; + var keys = _.uniq(Object.keys(node.data || {}) + .concat(hasKey ? properties[label].keys : baseCols)); + if (!hasKey) { + properties[label] = {selected: 'label'}; + } + properties[label].keys = keys; + }); + return properties; + }; +} \ No newline at end of file diff --git a/zeppelin-web/src/app/visualization/builtins/visualization-d3network.js b/zeppelin-web/src/app/visualization/builtins/visualization-d3network.js new file mode 100644 index 00000000000..82b5aef40f1 --- /dev/null +++ b/zeppelin-web/src/app/visualization/builtins/visualization-d3network.js @@ -0,0 +1,264 @@ +/* + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Visualization from '../visualization'; +import NetworkTransformation from '../../tabledata/network'; + +/** + * Visualize data in network format + */ +export default class NetworkVisualization extends Visualization { + constructor(targetEl, config) { + super(targetEl, config); + console.log('Init network viz'); + + if (!config.properties) { + config.properties = {}; + } + if (!config.d3Graph) { + config.d3Graph = { + forceLayout: { + timeout: 10000, + charge: -120, + linkDistance: 80, + }, + zoom: { + minScale: 1.3 + } + }; + } + this.targetEl.addClass('network'); + this.containerId = this.targetEl.prop('id'); + this.force = null; + this.svg = null; + this.$timeout = angular.injector(['ng']).get('$timeout'); + this.$interpolate = angular.injector(['ng']).get('$interpolate'); + this.transformation = new NetworkTransformation(config); + }; + + refresh() { + console.log('refresh'); + }; + + render(networkData) { + if (!('graph' in networkData)) { + console.log('graph not found'); + return; + } + console.log('Render Graph Visualization'); + + let transformationConfig = this.transformation.getSetting().scope.config; + console.log('cfg', transformationConfig); + if (transformationConfig && angular.equals({}, transformationConfig.properties)) { + transformationConfig.properties = networkData.getNetworkProperties(); + } + + this.targetEl.empty().append(''); + + let width = this.targetEl.width(); + let height = this.targetEl.height(); + let self = this; + let defaultOpacity = 0; + + let arcPath = (leftHand, d) => { + let start = leftHand ? d.source : d.target, + end = leftHand ? d.target : d.source, + dx = end.x - start.x, + dy = end.y - start.y, + dr = d.count === 1 && d.type === 'arrow' ? + 0 : Math.max(Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)), 200)/d.count, + sweep = leftHand ? 0 : 1; + return 'M' + start.x + ',' + start.y + 'A' + dr + ',' + dr + ' 0 0,' + sweep + ' ' + end.x + ',' + end.y; + }; + // Use elliptical arc path segments to doubly-encode directionality. + let tick = () => { + //Links + linkPath.attr('d', function(d) { + return arcPath(true, d); + }); + textPath.attr('d', function(d) { + return arcPath(d.source.x < d.target.x, d); + }); + //Nodes + circle.attr('transform', function(d) { + return 'translate(' + d.x + ',' + d.y + ')'; + }); + text.attr('transform', function(d) { + return 'translate(' + d.x + ',' + d.y + ')'; + }); + }; + + let setOpacity = (scale) => { + let opacity = scale >= +transformationConfig.d3Graph.zoom.minScale ? 1 : 0; + this.svg.selectAll('.nodeLabel') + .style('opacity', opacity); + this.svg.selectAll('textPath') + .style('opacity', opacity); + }; + + let zoom = d3.behavior.zoom() + .scaleExtent([1, 10]) + .on('zoom', () => { + console.log('zoom'); + setOpacity(d3.event.scale); + container.attr('transform', 'translate(' + d3.event.translate + ')scale(' + d3.event.scale + ')'); + }); + + this.svg = d3.select('#' + this.containerId + ' svg') + .attr('width', width) + .attr('height', height) + .call(zoom); + + this.force = d3.layout.force() + .charge(transformationConfig.d3Graph.forceLayout.charge) + .linkDistance(transformationConfig.d3Graph.forceLayout.linkDistance) + .on('tick', tick) + .nodes(networkData.graph.nodes) + .links(networkData.graph.edges) + .size([width, height]) + .on('start', () => { + console.log('force layout start'); + this.$timeout(() => { this.force.stop(); }, transformationConfig.d3Graph.forceLayout.timeout); + }) + .on('end', () => { + console.log('force layout stop'); + setOpacity(zoom.scale()); + }) + .start(); + + let renderFooterOnClick = (entity, type) => { + let footerId = this.containerId + '_footer'; + let obj = {id: entity.id, label: entity.defaultLabel || entity.label, type: type}; + let html = [this.$interpolate(['
  • {{type}}_id: {{id}}
  • ', + '
  • {{type}}_type: {{label}}
  • '].join(''))(obj)]; + html = html.concat(_.map(entity.data, (v, k) => { + return this.$interpolate('
  • {{field}}: {{value}}
  • ')({field: k, value: v}); + })); + angular.element('#' + footerId) + .find('.list-inline') + .empty() + .append(html.join('')); + }; + + let drag = d3.behavior.drag() + .origin((d) => d) + .on('dragstart', function(d) { + console.log('dragstart'); + d3.event.sourceEvent.stopPropagation(); + d3.select(this).classed('dragging', true); + self.force.stop(); + }) + .on('drag', function(d) { + console.log('drag'); + d.px += d3.event.dx; + d.py += d3.event.dy; + d.x += d3.event.dx; + d.y += d3.event.dy; + }) + .on('dragend', function(d) { + console.log('dragend'); + d.fixed = true; + d3.select(this).classed('dragging', false); + self.force.resume(); + }); + + let container = this.svg.append('g'); + container.append('svg:defs').selectAll('marker') + .data(['suit']) + .enter() + .append('svg:marker') + .attr('id', String) + .attr('viewBox', '0 -5 10 10') + .attr('refX', 16) + .attr('refY', 0) + .attr('markerWidth', 4) + .attr('markerHeight', 4) + .attr('orient', 'auto') + .append('svg:path') + .attr('d', 'M0,-5L10,0L0,5'); + //Links + let link = container.append('svg:g') + .on('click', () => { + renderFooterOnClick(d3.select(d3.event.target).datum(), 'edge'); + }) + .selectAll('g.link') + .data(self.force.links()) + .enter() + .append('g'); + let getPathId = (d) => this.containerId + '_' + d.source.index + '_' + d.target.index + '_' + d.count; + let showLabel = (d) => this._showNodeLabel(d); + let linkPath = link.append('svg:path') + .attr('class', 'link') + .attr('size', 10) + .attr('stroke', (d) => d.color) + .attr('marker-end', 'url(#suit)'); + let textPath = link.append('svg:path') + .attr('id', getPathId) + .attr('class', 'textpath'); + container.append('svg:g') + .selectAll('.pathLabel') + .data(self.force.links()) + .enter() + .append('svg:text') + .attr('class', 'pathLabel') + .append('svg:textPath') + .attr('startOffset', '50%') + .attr('text-anchor', 'middle') + .attr('xlink:href', (d) => '#' + getPathId(d)) + .text((d) => d.label) + .style('opacity', defaultOpacity); + //Nodes + let circle = container.append('svg:g') + .on('click', () => { + renderFooterOnClick(d3.select(d3.event.target).datum(), 'node'); + }) + .selectAll('circle') + .data(self.force.nodes()) + .enter().append('svg:circle') + .attr('r', (d) => d.size) + .attr('fill', (d) => d.color) + .call(drag); + let text = container.append('svg:g').selectAll('g') + .data(self.force.nodes()) + .enter().append('svg:g'); + text.append('svg:text') + .attr('x', (d) => d.size + 3) + .attr('size', 10) + .attr('y', '.31em') + .attr('class', (d) => 'nodeLabel shadow label-' + d.label) + .text(showLabel) + .style('opacity', defaultOpacity); + text.append('svg:text') + .attr('x',(d) => d.size + 3) + .attr('size', 10) + .attr('y', '.31em') + .attr('class', (d) => 'nodeLabel label-' + d.label) + .text(showLabel) + .style('opacity', defaultOpacity); + }; + + destroy() { + }; + + _showNodeLabel(d) { + let transformationConfig = this.transformation.getSetting().scope.config; + let selectedLabel = (transformationConfig.properties[d.label] || {selected: 'label'}).selected; + return d.data[selectedLabel] || d[selectedLabel]; + }; + + getTransformation() { + return this.transformation; + }; + +} \ No newline at end of file diff --git a/zeppelin-web/src/components/resizable/resizable.directive.js b/zeppelin-web/src/components/resizable/resizable.directive.js index afcfd1b7672..e1d9dd9b754 100644 --- a/zeppelin-web/src/components/resizable/resizable.directive.js +++ b/zeppelin-web/src/components/resizable/resizable.directive.js @@ -35,7 +35,9 @@ function resizable() { var colStep = window.innerWidth / 12; elem.off('resizestop'); var conf = angular.copy(resizableConfig); - if (resize.graphType === 'TABLE' || resize.graphType === 'TEXT') { + if (resize.graphType === 'TABLE' || + resize.graphType === 'TEXT' || + resize.graphType === 'NETWORK') { conf.grid = [colStep, 10]; conf.minHeight = 100; } else { diff --git a/zeppelin-web/test/spec/tabledata/datasetfactory.js b/zeppelin-web/test/spec/tabledata/datasetfactory.js new file mode 100644 index 00000000000..38b34681884 --- /dev/null +++ b/zeppelin-web/test/spec/tabledata/datasetfactory.js @@ -0,0 +1,48 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import NetworkData from '../../../src/app/tabledata/networkdata.js'; +import TableData from '../../../src/app/tabledata/tabledata.js'; +import {DatasetType} from '../../../src/app/tabledata/dataset.js'; +import DatasetFactory from '../../../src/app/tabledata/datasetfactory.js'; + + +describe('DatasetFactory build', function() { + var df; + + beforeAll(function() { + df = new DatasetFactory(); + }); + + it('should create a TableData instance', function() { + var td = df.createDataset(DatasetType.TABLE); + expect(td instanceof TableData).toBeTruthy(); + expect(td.columns.length).toBe(0); + expect(td.rows.length).toBe(0); + }); + + it('should create a NetworkData instance', function() { + var nd = df.createDataset(DatasetType.NETWORK); + expect(nd instanceof NetworkData).toBeTruthy(); + expect(nd.columns.length).toBe(0); + expect(nd.rows.length).toBe(0); + expect(nd.graph).toEqual({}); + }); + + it('should thrown an Error', function() { + expect(function() { df.createDataset('text'); }) + .toThrow(new Error('Dataset type not found')); + }); + +}); diff --git a/zeppelin-web/test/spec/tabledata/networkdata.js b/zeppelin-web/test/spec/tabledata/networkdata.js new file mode 100644 index 00000000000..a0007d28770 --- /dev/null +++ b/zeppelin-web/test/spec/tabledata/networkdata.js @@ -0,0 +1,46 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import NetworkData from '../../../src/app/tabledata/networkdata.js'; +import {DatasetType} from '../../../src/app/tabledata/dataset.js'; + +describe('NetworkData build', function() { + var nd; + + beforeEach(function() { + nd = new NetworkData(); + }); + + it('should initialize the default value', function() { + expect(nd.columns.length).toBe(0); + expect(nd.rows.length).toBe(0); + expect(nd.graph).toEqual({}); + }); + + it('should able to create NetowkData from paragraph result', function() { + var jsonExpected = {nodes: [{id: 1}, {id: 2}], edges: [{source: 2, target: 1, id: 1}]}; + nd.loadParagraphResult({ + type: DatasetType.NETWORK, + msg: JSON.stringify(jsonExpected) + }); + + expect(nd.columns.length).toBe(2); + expect(nd.rows.length).toBe(3); + expect(nd.graph.nodes[0].id).toBe(jsonExpected.nodes[0].id); + expect(nd.graph.nodes[1].id).toBe(jsonExpected.nodes[1].id); + expect(nd.graph.edges[0].id).toBe(jsonExpected.edges[0].id); + expect(nd.graph.edges[0].source.id).toBe(jsonExpected.nodes[1].id); + expect(nd.graph.edges[0].target.id).toBe(jsonExpected.nodes[0].id); + }); +}); diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java index 0708719c30d..baf0ad33e83 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java @@ -355,7 +355,7 @@ public String getTrustStorePassword() { public String getNotebookDir() { return getString(ConfVars.ZEPPELIN_NOTEBOOK_DIR); } - + public String getUser() { return getString(ConfVars.ZEPPELIN_NOTEBOOK_S3_USER); } @@ -569,7 +569,8 @@ public static enum ConfVars { + "org.apache.zeppelin.hbase.HbaseInterpreter," + "org.apache.zeppelin.bigquery.BigQueryInterpreter," + "org.apache.zeppelin.beam.BeamInterpreter," - + "org.apache.zeppelin.scio.ScioInterpreter"), + + "org.apache.zeppelin.scio.ScioInterpreter," + + "org.apache.zeppelin.neo4j.Neo4jCypherInterpreter"), ZEPPELIN_INTERPRETER_JSON("zeppelin.interpreter.setting", "interpreter-setting.json"), ZEPPELIN_INTERPRETER_DIR("zeppelin.interpreter.dir", "interpreter"), ZEPPELIN_INTERPRETER_LOCALREPO("zeppelin.interpreter.localRepo", "local-repo"), @@ -577,7 +578,7 @@ public static enum ConfVars { ZEPPELIN_INTERPRETER_MAX_POOL_SIZE("zeppelin.interpreter.max.poolsize", 10), ZEPPELIN_INTERPRETER_GROUP_ORDER("zeppelin.interpreter.group.order", "spark,md,angular,sh," + "livy,alluxio,file,psql,flink,python,ignite,lens,cassandra,geode,kylin,elasticsearch," - + "scalding,jdbc,hbase,bigquery,beam,pig,scio"), + + "scalding,jdbc,hbase,bigquery,beam,pig,scio,neo4j"), ZEPPELIN_INTERPRETER_OUTPUT_LIMIT("zeppelin.interpreter.output.limit", 1024 * 100), ZEPPELIN_ENCODING("zeppelin.encoding", "UTF-8"), ZEPPELIN_NOTEBOOK_DIR("zeppelin.notebook.dir", "notebook"),