[Directed Graph Editor] How to exchange data with server-side

30 views
Skip to first unread message

Joao Bosco Jares

unread,
Jul 27, 2015, 8:24:17 AM7/27/15
to d3-js
Hi all,

Let me see, if anyone could give an idea to support a requirement of my demo app. 
I'm customizing the Directed Graph Editor from: http://bl.ocks.org/rkirsling/5001347

At this moment I'm loading the graph with a json data who comes from the server side (working pretty well). 

So, the next step is send the graph to server side as a json format to save his changed state, once the user can edit and save the graphic on any moment.

My question is: How can I send a snapshot of the shown graph to the server side?






Thanks in advance.
--
Joao
Untitled.png

Drew Winget

unread,
Jul 27, 2015, 2:01:02 PM7/27/15
to d3...@googlegroups.com
Hi Joao,

You'll need to send a POST request to your server. The server will also need to be able to handle the contents of this POST request. 

d3's .json() method is a convenience specifically for "GET"-ing json. If you want to use d3 to manage your data loading (rather than some other requests library), you must use the d3.xhr method. This will allow you to explicitly structure a an XMLHTTPRequest object to send data back to the server. In general the technique of utilising XHR to incrementally update a web UI is called AJAX

A great deal has changed and evolved since the emergence of AJAX since 2005, particularly around the topic of application structure and persistence strategies. You'll soon discover that there are quite a few problems surrounding the approach you've taken of loading everything at once and trying to send the entire graph back every time a single change is made. When/if you encounter them, feel free to post here and we can work through them.
--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

João Bosco Jares

unread,
Jul 27, 2015, 2:19:15 PM7/27/15
to d3...@googlegroups.com
Hi Drew,


Thanks for quick reply. You're right and I'm aware of the possibility of overhead latency problems. I'm not planning interact with the server-side after each change. In reality my conceptual proof is not related to performance, just with the API usage at this first moment. However, thank you so much, I'll take care :)
So, could you show me one simple example about your mentioned approach, please? If not, could you tell me what object holds the graph?



Best Regards.

--
João Bosco Jares

--
You received this message because you are subscribed to a topic in the Google Groups "d3-js" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/d3-js/Pqa_rP3zdbQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to d3-js+un...@googlegroups.com.

João Bosco Jares

unread,
Jul 27, 2015, 2:36:32 PM7/27/15
to d3...@googlegroups.com
Hi All,

I know that I can send an AJAX POST, but my main doubt is what is the object that holds the values of the shown graph?
Let's take the code below, for instance. As we can see the json data is formated in hardcoded way (see: JSON.stringify({year: "2012", customer: "type1"})). It's not what I'm looking for. I need to discovery the object that holds the shown graph, then parse it to json, and just after that make the d3.xhr call, passing the parsed graph as json to server-side.

d3.xhr(url)
    .header("Content-Type", "application/json")
    .post(
        JSON.stringify({year: "2012", customer: "type1"}),
        function(err, rawData){
            var data = JSON.parse(rawData);
            console.log("got response", data);
        }
    );

Ps.: Anybody could tell me who's the object that holds the graph?



Cheers.

--
João Bosco Jares

Drew Winget

unread,
Jul 27, 2015, 2:39:54 PM7/27/15
to d3...@googlegroups.com
Hi João
​,

Inside whatever event handler will trigger the message back to the server, use the xhr methods to POST there. You'll need to serialise the data you want to send (this will depend on how you would like to parse it on the backend).​ In line 21 of your example you generate a "resultJson". You will need another module of some kind to receive post requests. I guess you're using Java Servlets. I don't really know much about those, but it seems you already include the necessary modules. 

The Ajax would look something like:
d3.json("/path/to/your/backend/request/handler")
    .header("yourHeaderName", "yourHeaderValue") // This will depend on what your server needs
    .post(yourDataInJSON, function(error, data) { // The data you create depends on your preference, more on that below
      // Do things with the return
    });

Drew Winget

unread,
Jul 27, 2015, 2:40:36 PM7/27/15
to d3...@googlegroups.com
Sorry, I didn't see your other response. One moment.

João Bosco Jares

unread,
Jul 27, 2015, 2:43:59 PM7/27/15
to d3...@googlegroups.com
ehehhehehe :)
No problem Drew. You're welcome.
Thanks million.

--
João Bosco Jares

Drew Winget

unread,
Jul 27, 2015, 2:57:02 PM7/27/15
to d3...@googlegroups.com
Right now the data is stored as two separate arrays, the nodes and links arrays. If you look at the event handlers, you'll see that all they do is create a new object from the event parameters and push it onto the array. Then the handler re-renders the graph. Because of d3's enter, exit, and update selections, d3 only touches the parts of the DOM that need updating. Note that the event handlers do not touch the DOM in any way. Data always flows FROM and event TO the handler and BACK INTO THE TOP OF THE RENDER FUNCTION.

In practice, this means that you can always get the data by looking at the nodes and links arrays. Therefore, you probably want to send the data back in the same form you sent it in: as an object with two keys "nodes" and "links". Try console.logging the nodes and links arrays in the respective event handler. Start with the mousedown handler (which adds a new node at the mouse position). In the mousedown handler (line 462 in your file), add a:
console.log(node);
console.log(nodes);
Do the same thing in the other event handlers that change data (with links). Dragging will change the x,y properties, creating a new link will append a link, etc. So, to structure the postData, whenever you want, just put the nodes and links in an object like you did what you first started the page.
postData = { nodes: nodes, links: links };
JSON.stringify(postData);

João Bosco Jares

unread,
Jul 27, 2015, 3:10:15 PM7/27/15
to d3...@googlegroups.com
Drew, excellent. fits very well. Thank you so much.
Cheers :)

--
João Bosco Jares

Joao Bosco Jares

unread,
Jul 28, 2015, 9:46:57 AM7/28/15
to d3-js, jbj...@gmail.com
Hi All,

Goes my solution below:
First of all, I decided to use jquery (for convenience), then I created a javascript function (named as test temporarily), and of course on button to trigger this function. So let's see step by step, and the code on pastebin as the link below.
a) I load a group of data sets to be presented to the user. At this moment, the first data set is hard coded.
b) The user can make changes on the graph, and then click on the button that will trigger the jquery ajax POST action.
c) I created a Java Servlet (on server-side) to handle with GET and POST methods. So, the trick is do the properly customization on the json that comes from UI, once that json contains some irrelevant data to this current scenario, like x/y coordinates, and if you let these properties filled, the nodes and links will be shown separately (What not sounds well). So, to solve this problem I removed the unnecessary properties, sending just the basic properties to D3 make your work, using his default properties.


Thanks so much!
Reply all
Reply to author
Forward
0 new messages