I'm a student, and currently I'm developing an application that visualizes a user's music library.
My data is all the artists, and the similarity between each of them.
What I'm doing now is to represent this information in a graph, where each artist is connected to another artist if they are similar.
My problem is that this way, most artists will be linked together, creating a big mess.
I've tried changing the size of the edges, but as each node is connected to many other nodes, the result is not very good.
I think the ideal solution would be mapping each artist to coordinates x and y. The similar artists would form a cluster. And if the artists weren't similar, they would be far apart.
I've tried everything, but I can't achieve the visualization I wanted… Does anyone have an idea on how I can use prefuse to visualize what I want?
Thanks in advance.
I have a few ideas.
As you said, visualize connections between artists as edges. For ease of discussion, I assume you have the strength of the connection between two artists available in form of a numerical value in a datafield of the edge. (For example Artists A and B are loosely coupled (strength 5) and Artists B and C are strongly couple (strengt 95) or similar. Strength can be 0 to 100.)
Color the edges according to the strength value? Nearly transparent/invisible is loosely coupled, full/dark colored is strongly coupled.
Hide edges (or even artists) which have strength<50.
You can even bind this "strength<50" to a slider/etc, so the user can configure this.
(Strength < 0 will show all edges, Strength < 100 will hide all; I guess you got the idea)
People probably just want to see the ~5-10 strongest connections?
Maybe a JRangeSlider (slider with both ends "slidable"), which allows to display only connections with strength 70 to 80.
Without edges, connections via coordinates, as your second idea.
The layout will be the problem, as you cannot place D very close to C and E, while C and E must have largest possible distance.
Clusters (Aggregates or AggregateItems in prefuse) are a good idea, too. Depending on the amount of artists :)
Positioning coupled artists near together and drawing a cloud around artists with certain strength may also work. Even imaginable to bind the value which determines if two artists are in the same cluster to a slider. One item can be in >1 cluster/aggregate.
Using ForceDirectedLayout and let the graph arrange itself? The "strength" value of the edges needs to represent the repellent/attracting force.
If there's too much data to visualize, the user must be able to filter. A basic rule in creating visualizations, isn't it? :)
hope there are some ideas that help, Björn
Get the big picture of prefuse at: http://prefuse.blogspot.com/
More (custom) prefuse examples at: http://goosebumps4all.net/34all/bb/forumdisplay.php?fid=18
First of all, thank you Björn for your insightful advices.
What you supposed is totally correct, the similarity is in form of a percentage. Now, analyzing your advices:
1) I didn't know edges allowed data fields… I thought it was just a mere linker between 2 nodes. I'll check this out.
2) This is a great idea. Based on this, I've managed to see an interesting graph. Now I only create an edge in the strongest connection of each artist.
3) I guess I'll not try to map coordinates individually, since it involves complex math calculations.
4) That's a good idea too, I'll try drawing the clusters tomorrow.
5) I couldn't find a good way to use the strength of the edge… Currently I'm using a customized ForceDirectedLayout, redefining the method getSpringCoefficient(EdgeItem). How do you suggest I use this method? Or is there another way around?
And I didn't want to apply filters to see only some artists… I want an abstraction of a full music library.
By the way, some artists in the library may not be connected to any of the other artists (since they have no similarity). In this case, I wanted to position them away from the main graph. How can I do this? I've tried to get the VisualItem and then use setX and setY, but with no success…
Thank you A LOT! :)
I got a couple more questions.
1. When I start the visualization, the graph takes some time to arrange itself to the final configuration. Is it possible to visualize this final configuration right from the beginning? How? And the nodes never stop moving… How can I stop them?
2. I have some artists aggregated by a tag. And my idea was having 2 levels of zoom. In the detailed one, individual artists were displayed. If the zoom was out, only the tags were displayed. Is there a way to do this?
Thanks in avance.
sure, all items are stored like rows in a table. A table for nodes, one for edges (by default). And you can add columns to these tables. For example a column with name 'strength' and datatype integer or double to the edges table. You can even create computed columns, like concatenated strings, multiplied values, etc.
If you have the strength available in a datafield (column of the edges table), try DataColorAction, DataSizeAction.
Your FDL sounds good, I'm not too familiar with it and would need to experiment myself.
> And I didn't want to apply filters to see only some artists… I want an abstraction of a full music library.
My idea was to let the user take influence on this abstraction :)
Some generals about FDL:
- you can let it run for a certain amount of time (well hmm, depends on PC performance, graph size, etc, so hard to determine in general) via ActionList duration
- there was at least one post in the past about your question "Is it possible to visualize this final configuration right from the beginning?". I can't remember a link, maybe searching this forum reveals it. An idea was to let FDL run while the nodes are invisible and after an amount of time, when FDL is assumed to have "stabilized", make the items visible.
- for both above points, there was a discussion about how to check if FDL has "finished" (items don't move more than x in time t - or something similar)
- if you have a unique identifier for your items/nodes persistent, then you could store and load a layout (GraphMLWriter/Reader and SpecifiedLayout)
Maybe manually create something with PaintListener, but also seems like a workaround to me.
I will try GraphMLWriter to save my graph. I guess this will sort it out. If not, I'll try to search in the forum.
> Your idea could be done by visualizing the aggregates while hiding the contained items (not the perfect solution, as aggregates are drawn around their containings).
Maybe instead of hiding, I could change the nodes color to transparent, and the aggregates would be fine :)
By the way… I need one more feature.
When I click a node, I'm changing it's size and color. But I want it to be flashing two colors, or continually changing it's size, to become more obvious that node is selected. Is it possible to accomplish that?
Take a look at the prefuse.action.animate package.
There are ColorAnimator and SizeAnimator. Should be exactly what you need.
I'm not sure if you can find them in one of the demos, but as the javadoc comments are well in prefuse, it shouldn't be too hard to get it running.
Sign up for the SourceForge newsletter:
You seem to have CSS turned off.
Please don't fill out this field.