Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Friday, January 18, 2013

Fun with JIT, part1

Over the past year, I've been integrating JIT  (thejit.org) with my GWT application.  Javascript is not something for the faint of heart and personally I try to stay far away from it instead allowing  GWT to generate the Javascript for me based on my Java implementation code.  But to make use of, extend, and better control the canvas based layout tool JIT, I had to take on some Javascript.  So here's some things I did with it.  Any code snippets here should be considered pseudo-code and are for representation only.


Saving & Restoring Node Positions

The Force-Directed Graph has a built in layout algorithm that draws a graph as best as it can.  However, each time the graph is rendered, the layout algorithm produces a different layout.  We offer the user the ability to control the layout somewhat, specifying spacing between nodes and how many iterations the algorithm should use based on a complexity setting and some others:


Once the layout has been run, we then let the user drag the nodes and links around the screen to better position items to their liking.  To fully make this work, we need to save the node positions so that the next time we view the graph, we put all the nodes back into their original positions.  This also provides a big performance boost, in that we never run the layout algorithm a second time, but instead tell JIT where we want the nodes.

Save Positions:

// We store the node positions using our string object id, and the x,y values.
HashMap<String, ArrayList<Integer>> nodePositions;

// We iterate over the graph, getting the positions of each node.
mygraph.graph.eachNode(function(n) {
saveNodeData(n.id, Math.floor(n.getPos().x), Math.floor(n.getPos().y));
});

saveNodeData(String id, int x, int y)
{
    ArrayList<Integer> locations = new ArrayList<Integer>();
    locations.add(x);
    locations.add(y);
    nodePositions.put(id, locations);
}

Restore Positions:

// Lood our JSON data
nativeGraph.loadJSON(data);

// Put the nodes at the positions we want. No need to run the layout algorithm.

iterate over the saved node positions data and call this:
setNodePosition(JavaScriptObject nativeGraph, String id, int x, int y)
{
    node = nativeGraph.graph.getNode(id);
    if (node != null) {
        node.setPos(new $wnd.$jit.Complex(x,y), 'current');
        nativeGraph.plot();
    }
}


Resizing the Graph

JIT comes with some built-in functionality on many of their graphs that allows the user to scroll their mouse wheel which then causes the canvas to scale in and out, making the drawn objects grow or shrink.  I found this functionality to be somewhat difficult to control and also I wanted to control how large and how small I would allow the screen to scale to.  



I implemented two push buttons on my graph that allow the user to scale up or down as they are pressed.  One jumps 125% and the other jumps 80% which provides an even up/down scaling so that they user can always return to the default, 100%.

Scaling In:

Scaling in makes the objects larger.  Each time the user presses the "+" button, I ask JIT to:

nativeGraph.canvas.scale(1.25, 1.25);


Scaling Out:

Scaling out makes the objects smaller.  Each time the user presses the "-" button, I ask JIT to:

nativeGraph.canvas.scale(.8, .8);


Searching the Graph

Since my graph can get quite large with many of the objects off the edges of the viewable area, I implemented the ability to search for any node by name.  Once found, the node would be selected and the graph would be centered on the object, bringing the object into view for the user.  Here's how.


Find Node:

findNode(JavaScriptObject nativeGraph, String name)
{
    var p = new RegExp(name.replace("*", ".*"));
    
    nativeGraph.graph.eachNode(function(node) {
        if (p.test(node.name)) {
            // Found the node, we can get the x,y positions of this node.
    centerScreen(node.getPos().x, node.getPos().y);
}
}

centerScreen(String x, String y)
{
    // We are using a scroll panel with scroll bars as the parent of our JIT canvas
    // so we just adjust these scrollbars.
    graphContainer.setScrollLeft(((graphWidth / 2) -
(getOffsetWidth() / 2)) + x);
    graphContainer.setScrollTop(((graphHeight / 2) -
(getOffsetHeight() / 2) + y);
}

...More Fun with JIT, part2 coming soon.






Monday, June 27, 2011

Welcome to GWT

After spending many years doing GUI development (starting with XWindows, DECwindows, then on to Motif and Java Swing) I was recently given the opportunity to move away from the application space and into the web space. "Build the same application you did with Swing, but make it web based" were the marching orders.

Now, I have to say that UI development seems to have not changed in 25 years. Yes, we got color, a mouse, animation, nicer fonts, etc. but we still create and manage widgets, think object oriented always, and need to put together layouts that adapt to screen sizes. Without even cracking a manual (actually a Google search now!) one can sit in Eclipse and pretty much guess what the method might be for doing something to a widget or for setting up a callback.

...Back to building my Swing app for the web. I was to use a technology called ADF (Oracle's Application Development Framework) with the end product deployed using Weblogic. Being a new Oracle employee, I had no prior knowledge of this technology and found not a lot in the internet about "how to" do things with it, so I decided why not share my findings as I went. My ADF blog was born. In very little time, I was able to start a new complete UI from scratch, taking advantage of templates, css styles, and a lot of code sharing. The complexity came in when trying to model and display data that was stored in our backend database that was "not" a typical RDB conforming data store, but that is a different story for a different day. Let's just say that where many web apps (and non-web apps) fall down is in building a multi-user, concurrent, auto refreshing application where all users coexist in harmony and life is good.

So now I've moved on to a very exciting new startup and was given free rain to "pick" the UI technologies that will be used. Slick, fast, usable, state of the art were the marching orders. After evaluating and comparing Swing, GWT and Flash, GWT was the winner. This blog will follow my adventure into GWT for the first time.

I knew nothing of XWindows/DECwindows and built DECplan, aka Microsoft Project before there was a Microsoft. Then on to Motif based NETarchitect integrated with an ObjectStore backend and is still the "fastest" performing application I have ever worked on. Next came a Swing based networking Control Center and a Virtualization Manager. Last was the ADF based Virtualization Manager and now a GWT set of applications.

I guess starting from drawing lines with X and building menu bars by hand has helped lead me on the path of making UI design and implementation "natural". I'm just wondering what will lead us into a new paradigm and really change the way Gui's are done. Maybe next lifetime.