3

I'm trying to create a little application in PHP for a website. For this application i use neo4j community database.

I'm trying to create nice looking navigation with a graph. The problem is not the styling but to get the graph running.

Right now i get the output of neoclient (the php solution to communicate with neo4j database) and creating JSON (ON MY OWN! I need this step because, i want to add data of other scripts later... sry : ( ).

Now i want to use this data and create a graph of it. All i'm getting is that all nodes and links are given as error. Funny thing is that i can say graph = error in javascript and the points (NOT THE LINKS : () get printed.

I really searched through many things and tried with examples but I can't find the answer of what I'm doing wrong. Hope this question is not to stupid and didn't get asked to frequently. I admit I'm new to d3j. Can somebody say what is wrong?

complete json: http://meggeslp.noxxkn.de/graph.json

generated by:

<?php namespace engine\encoder;
class GraphJSONEncoder {

    public static function encodeNeo4JResponse($response) {
        $result = "{ ";
        //$result .= '"comment": "Automatic Generated JSON Response by HIDDEN ; )" , ';
        $result .= '"nodes": [ ';
        $i = 0;
        $num = count($response->getNodes());
        $ids = [];
        foreach ($response->getNodes() as $node) {
            $result .= "{ ";
            foreach($node->getProperties() as $name => $prop) {
                $result .= '"'.$name.'": "'.$prop.'", ';
            }
            $result .= '"label": "'.$node->getLabel().'",';
            $result .= '"id": '. $node->getId().' ';
            $result .= " }";
            if(++$i !== $num) {
                $result .= ", ";
            } 

            $id[$node->getId()] = $i-1;
        }

        $result.= '], "links": [ ';
        $i = 0;
        $num = count($response->getRelationships());
        foreach ($response->getRelationships() as $rel) {
            $result .= "{";

            $result .= '"source": '.$id[$rel->getStartNode()->getId()].',';
            $result .= '"target": '.$id[$rel->getEndNode()->getId()].',';
            $result .= '"type": "'.$rel->getType().'",';
            $result .= '"weight": 1';
            $result .= " }";

            if(++$i !== $num) {
                $result .= ", ";
            } 
        }

        $result.= "]}";

        return $result;
    }
}

The Function get used like this: (graphgenerator.php)

<?php namespace mygn;

require_once '../vendor/autoload.php'; 

use mygn\application\Application;
use engine\database\Query;
use engine\encoder\GraphJSONEncoder;

$app = Application::getInstance();
$app->init();
$app->run();
$result = $app->dbProxy()->query(new Query("neo4j", "MATCH n-[r]->g RETURN n,r,g;"));
?><?= GraphJSONEncoder::encodeNeo4JResponse($result) ?>

And finally (sry for the stuff above, if it wasn't needed) to the actual problem:

<?php namespace mygn;

require_once 'vendor/autoload.php'; 

use mygn\application\Application;
use engine\database\Query;

$app = Application::getInstance();
$app->init();
$app->run();

<!DOCTYPE html>
<html style="height:100%">
    <head >
    <title>MYGN</title>
    <meta charset="UTF-8">
    <link href="external/jquery-ui/jquery-ui.css" rel="stylesheet">

    <script src="external/jquery-ui/external/jquery/jquery.js"></script>
    <script src="external/jquery-ui/jquery-ui.js"></script>
    <script src="http://d3js.org/d3.v2.js?2.9.3"  charset="utf-8"></script>

</head>

<body style="height:100%">
    <div id="graph" style="height:100%"></div>
    <script>
        var width = 800, height = 800;
        // force layout setup
        var force = d3.layout.force()
                .charge(-200).linkDistance(30).size([width, height]);

        // setup svg div
        var svg = d3.select("#graph").append("svg")
                .attr("width", "100%").attr("height", "100%")
                .attr("pointer-events", "all");

        // load graph (nodes,links) json from /graph endpoint
        d3.json("calls/graphgenerator.php", function(error, graph) {
            console.log(error);
            graph = error;
            force
                .nodes(graph.nodes)
                .links(graph.links)
                .start();

            var link = svg.selectAll(".link")
                .data(graph.links)
                .enter().append("line")
                .attr("class", "link");

            var node = svg.selectAll(".node")
                .data(graph.nodes)
                .enter().append("circle")
                .attr("class", "node")
                .attr("r", 5)
                .call(force.drag);

            node.append("title")
                .text(function(d) { return d.name; });

            force.on("tick", function() {
                link.attr("x1", function(d) { return d.source.x; })
                    .attr("y1", function(d) { return d.source.y; })
                    .attr("x2", function(d) { return d.target.x; })
                    .attr("y2", function(d) { return d.target.y; });

                node.attr("cx", function(d) { return d.x; })
                    .attr("cy", function(d) { return d.y; });
          });
        });
    </script>

</body>

</html>

you see know in line 41 "graph = error" ... i really don't understand why all is just simply "error" and it is quite frustrating. If i do this step with "graph = error" all nodes get painted but the links not.

I tried to do something like mentioned here: http://neo4j.com/developer/guide-data-visualization/ I had to add the "weight:" property to print the graph. (mentioned in other stackoverflow questions). Also i want to add if you look at the encoder i already know that i have to use the ids of the arrays for the links and not the original ids ... but maybe i still do this wrong ? Can somebody help pls?

Hope this question is ok to ask.

Greets Noxxer

1 Answer 1

1

The problem with graph being undefined is, that you are using a very old version (from 2012) of d3.js. I tested your code with a newer version and it works just fine. So you should include it like so:

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>

And your Links are being generated, but not visible. You have to add a strokecolor to your links like so:

var link = svg.selectAll(".link")
    .data(graph.links)
    .enter()
  .append("line")
    .attr("class", "link")
    .attr("stroke", "black");

Or you set the stroke via CSS with this in your html head:

<style>
  .link { stroke: black; }
</style>
Sign up to request clarification or add additional context in comments.

1 Comment

thank you so much ... and i'm just sitting here like "._____________:" .. omg i'm so sry and thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.