I am a new to the prefuse visualization toolkit and have a couple of general questions. For my purpose, I would like to perform an initial visualization using prefuse (graphview / graphml). Once rendered, upon a user click of a node, I would like to completely reload a new xml file for a new visualization. I want to do this in order to allow me to "pre-package" graphs for display.
For example. If I search for Ted. I would like to have an xml file relating to Ted load and render a display. Now in the display I see that Ted has nodes associated called Bill and Joe. When I click Joe, I would like to clear the display and load an xml file associated with Joe. And so on.
I have looked into loading one very large xml file containing all node and node relationship info and allowing prefuse to handle this using the hops from one level to another. However, eventually I am sure that system performance issues will arise due to the size of data.
Thanks in advance for any help,
John
Of course as you said, one option is loading all nodes and then set the nodes you don't need to be invisible. Prefuse scales fairly well, but of course it has its limits. The second option is to just create a brand new panel and replace the old panel. I've used the option 2 and it works quite well.
I'm far from an expert on Prefuse's performance issues, but I think it is definitely more resource intensive to have a huge xml file loaded at once than to do the processing to only re-load the necessary nodes.
I don't know what kind of graph you are using, but I would place a 'refreshGraph' that removes the graph from the Visualization object, cancels Activity, cancels Layout, refreshes the ActionList and re-starts over. It would probably turn out something like this:
public void refresh(clickedNode){
visualization.removeGroup(GRAPH);
visualization.removeGroup(AGGR);
activity.cancel();
actionList.cancel();
visualization.reset();
// process the XML and reload your graph here
}
Related
Obviously it takes a lot of memory to store an array of a history of changes... that's how I had my application working but it just seems like there's a smarter way to go about doing this.
ArrayList<Photo> photoHistory = new ArrayList<>();
photoHistory.add(originalPhoto);
photoHistory.add(change1);
photoHistory.add(change2);
// bad implementation - lots of memory
Maybe store only an original and a current view model and keep a log of the methods/filters used? Then when a user hits 'undo' it would take the total number of changes made and run through all of them again minus one? This also seems incredibly inefficient.
I guess I'm just looking for advice on how to implement a general 'undo' function of a software application.
Here is a tip from how GIMP implements it:
GIMP's implementation of Undo is rather sophisticated. Many operations require very little Undo memory (e.g., changing visibility of a layer), so you can perform long sequences of them before they drop out of the Undo History. Some operations, such as changing layer visibility, are compressed, so that doing them several times in a row produces only a single point in the Undo History. However, there are other operations that may consume a lot of undo memory. Most filters are implemented by plug-ins, so the GIMP core has no efficient way of knowing what changed. As such, there is no way to implement Undo except by memorizing the entire contents of the affected layer before and after the operation. You might only be able to perform a few such operations before they drop out of the Undo History.
Source
So to do it as optimally as possible, you have to do different things depending on what action is being undone. Showing or hiding a layer can be represented in a neglible amount of space, but filtering the whole image might necessitate storing another copy of the whole image. However, if you only filter part of the image (or draw in a small section of the image) perhaps you only need to store that piece of the image.
I have a Java Swing application that contains a bunch of frames which in turn predominantly contains tables that display large amounts of data. Since it is always a hassle and its time consuming to arrange all windows and tables on startup, I would like to implement 'workspace'-functionality so that the user can save a setup of preference and on startup choose to automatically load the stored workspace to have all windows and tables appear as previously saved. Specifically, the settings that I wish to store in a workspace are:
Active windows (JFrame) and their sizes and positions on screen
Table settings, incl selected columns, column order, column width, sorting, filtering
Does anyone know of a smart and easy way to accomplish this without the obvious, and what seems like a very complex and cumbersome, solution of iterating over all open windows and saving each piece of information with the Preferences api? Thanks
In this case, the obvious solution, java.util.prefs.Preferences, is probably the correct one. RCPrefs from this game is a simple example that demonstrates saving a variety of data types, including enum. The exact implementation is highly dependent on the application. While tedious, it needn't be especially complex. For expedience, the example uses static methods; frame and table preferences are probably worth a class each.
I am having a problem with my SWT Tree. It contains many leaves what makes expanding an item very time consuming. Sometimes I even need to expand all items. Is there a way to expand it asynchronously? I have tried to use asyncExec() on the display putting expandAll() inside the run() method, but it didn't help. And it doesn't solve the first problem where I want to expand only one item. Any ideas?
Additional node: The slow expansion of an item happenes only the first time I expand it. All later expansions of the same item (after collapsing it) are fast.
I solved performance issues with large trees by change the content provider to an ILazyTreeContentProvider. This won't help if you have to expand the full tree at once.
An alternative: Have a closer look at your content and label providers. Maybe their operations are too expensive and you can speed up things if you cache or pre-calculate some information for the tree. If, for example, you have a normal (non-lazy) content provider that loads the items from a database (one-by-one), expanding the tree will take forever...
Are you loading the model items in the UI thread? You should ideally load your model items in a non-UI thread and then update the tree with the items in the UI thread.
Is there a way to speed up the population of a page with GWT's UI elements which are generated from data loaded from the datastore? Can I avoid making the unnecessary RPC call when the page is loaded?
More details about the problem I am experiencing: There is a page on which I generate a table with names and buttons for a list of entities loaded from the datastore. There is an EntryPoint for the page and in its onModuleLoad() I do something like this:
final FlexTable table = new FlexTable();
rpcAsyncService.getAllCandidates(new AsyncCallback<List<Candidate>>() {
public void onSuccess(List<Candidate> candidates) {
int row = 0;
for (Candidate person : candidates) {
table.setText(row, 0, person.getName());
table.setWidget(row, 1, new ToggleButton("Yes"));
table.setWidget(row, 2, new ToggleButton("No"));
row++;
}
}
...
});
This works, but takes more than 30 seconds to load the page with buttons for 300 candidates. This is unacceptable.
The app is running on Google App Engine and using the app engine's datastore.
You could do a lot of things, I will just list them in order that will give you the best impact.
FlexTable is not meant for 300 rows. Since your table is so simple, you should consider generating the HTML by hand, and then using simple HTML widget. Also, 300 rows is a lot of information - consider using pagination. The DynaTable sample app shows you how to do this.
It looks like you are using one GWT module per page. That is the wrong approach to GWT. Loading a GWT module has some non-trivial cost. To understand what I mean, compare browser refresh on gmail v/s the refresh link that gmail provides. That is the same cost you pay when every page in your website has a distinct GWT module.
If the list of candidates is needed across views, you can send it along with the HTML as a JSON object, and then use the Dictionary class in GWT to read it. This saves you the RPC call that you are making. This approach is only recommended if the data is going to be useful across multiple views/screens (like logged in users info)
Check how long your RPC method call is taking. You can enable stats in GWT to figure out where your application is taking time.
You can also run Speed Tracer to identify where the bottleneck is. This is last only because it is obvious FlexTable is performing a lot of DOM manipulations. In general, if you don't know where to start, Speed Tracer is a great tool.
The significant thing here is how you're retrieving the list of candidates, which you haven't shown. 30 seconds is extremely high, and it's unlikely that it's due to the datastore alone.
Have you tried using appstats to profile your app?
Like sri suggested - pagination is easiest and (I think) best solution (along with switching to Grid or just <table>). But in case you wanted for some reason to show/render many rows at once, the GWT Incubator project has a nice wiki page about it - along with some benchmarks showing how FlexTable sucks at large row count. Check out their other tables too ;)
Your problem is that everytime you add something to the FlexTable it has to re-render the whole page and repaint. Try creating a new FlexTable, populating it, when it is fully populated, get rid of the old one and put the new one there.
I am using JUNG for a project and when I am displaying relatively large graphs eg 1500 nodes, my pc would not be able to handle it (graphs are rendered but If I want to navigate the graph the system become very slow). Any Suggestions.
So, there are two things that JUNG visualization doesn't always scale very well right now:
iterative force-directed layouts
interaction: figuring out which node or edge (if any) is being referenced for hover and click events.
It sounds like it's the latter that you're running into right now.
Depending on your requirements, you have a couple of options:
(a) turn off mouse events, or at least hover events
(b) hack the visualization system so that lookups of event targets aren't O(m+n).
Simple solutions for (b) basically just partition the viewing area into smallish chunks and only sends events to elements that are in the same chunk as the pointer. (Obviously, the smaller you make the chunks, the more memory is required.)
We've had plans to do (b) (and a design sketched out) for some time but have been working on other things. Anyone that wants to help with a more permanent solution, please contact me.
How much memory are you starting your VM with? Assuming your working on windows, looking at the Task Manager, does the VM hit the maximum amount of allocated memory and start using swap?
The problem probably lies with the calculation of your vertices' positions. The only layout that I've found fairly easy to calculate was the Tree Layout and obviously that's not suitable for all data sets.
The solution probably is to write your own custom layout with a lot less calculations than say an FRLayout.