help with a tag cloud widget

Hello, list. I'm trying to make a new widget, (after searching and
not finding one already, which could be called wxTagCloud, and which
should look like a traditional web-based tag cloud (like
http://isp.webopedia.com/FIG/tag_cloud.jpg). But I have two issues so
far. Two runnable code examples attached. The problems are:

1) scrolledpanel + FlowSizer = no scroll bars

I am using a FlowSizer (where the widgets wrap or "flow" down to the
next row), and have started with this one I found on this list:

http://groups.google.com/group/wxpython-users/browse_thread/thread/7822b4aae1629121?fwc=2&pli=1

(I also realize a new one is coming with wxPython 2.9, but I wanted to
get started now)

The problem is, there may be more tags than can fit in the space
provided (assuming that space can only be expanded so much), and so at
that point I would like to have scroll bars to allow the user to see
the remaining tags.

[Human usage note: I think it's best that a tag cloud is all seen at
once, so every tag has a chance to jog the user's memory to possibly
use it, but on the other hand sometimes it is also important to
constrain the size of the space allotted, so I think scroll bars to
reveal the remainder of the tag cloud is not going to bias the user
too much toward ignoring the lower tags.]

I am not even sure where to begin to make it such that scroll bars
will appear when the tag cloud can be compressed no further. They do
appear if I change the FlowSizer to a wxBoxSizer, so it is something
about the FlowSizer which is not compatible with the scrolledpanel. I
tried with a scrolledwindow, too, but was unable to get it to do more
than just initially put scroll bars--resizing caused them to
disappear.

So, any ideas how I can make scroll bars to kick in when needed?

Problem 2: The words are unevenly vertically aligned

This has nothing to do with the FlowSizer, as I have the same problem
using a BoxSizer. It's just that staticTexts of different font sizes
don't line up well (see 2nd attached example), at least the way I'm
doing it. This makes the cloud of words look messier than it ought
to. Again, compare the ideal image here
(http://isp.webopedia.com/FIG/tag_cloud.jpg), which shows each word
aligned to the bottom of each row. I imagine this is a simple fix,
but I don't know it and would rather not reinvent the wheel w/
something more complex than it need be.

I think if I can get past these two problems and then just bind events
to the words and make it into a class which accepts a list of tags, it
can be a nice tag cloud widget. Previously, I had been using just
checkboxes all neatly aligned in a flexGridSizer, but that looks kind
of rigid and uninspiring compared to a tag cloud. And any suggestions
for changes to the overall thinking are very welcome. [wxPython
2.8.10.1, winXP, Python 2.5]

Thanks,
Che

tag_cloud.py (8.57 KB)

uneven_text.py (2.34 KB)

I think if I can get past these two problems and then just bind events
to the words and make it into a class which accepts a list of tags, it
can be a nice tag cloud widget.

(I forgot to mention that the sample app uses randomization to size
the fonts, just to give it the typical look; the actual widget, of
course, should be passed information about font sizes based on how
often each tag has previously been used. Maybe it should be passed a
dictionary.)

I am not even sure where to begin to make it such that scroll bars
will appear when the tag cloud can be compressed no further. They do
appear if I change the FlowSizer to a wxBoxSizer, so it is something
about the FlowSizer which is not compatible with the scrolledpanel. I
tried with a scrolledwindow, too, but was unable to get it to do more
than just initially put scroll bars--resizing caused them to
disappear.

So, any ideas how I can make scroll bars to kick in when needed?

Take a look at the CalcMin method. That is what will eventually get called to decide how to set the virtual size of the scrolled panel. The first if statement is suspicious since it will always return the very first size that it calculated.

Problem 2: The words are unevenly vertically aligned

This has nothing to do with the FlowSizer, as I have the same problem
using a BoxSizer. It's just that staticTexts of different font sizes
don't line up well (see 2nd attached example), at least the way I'm
doing it. This makes the cloud of words look messier than it ought
to. Again, compare the ideal image here
(http://isp.webopedia.com/FIG/tag_cloud.jpg), which shows each word
aligned to the bottom of each row. I imagine this is a simple fix,
but I don't know it and would rather not reinvent the wheel w/
something more complex than it need be.

By default they are aligned on the top edge of the widgets. You can easily do a center alignment by passing flags to the sizer.Add method (assuming the FlowSizer supports that.) Probably better would be to do a baseline alignment, but sizers don't know how to do that since they just deal with generic widgets and don't deal directly with fonts. You could probably create a custom widget that can draw its text with the baseline at a certain offset from the top, but if you're going to go that far it may just be easier to make a the tag cloud widget draw all of the text on itself instead of using a separate widget for each tag.

···

On 7/1/10 8:54 PM, C M wrote:

--
Robin Dunn
Software Craftsman

If you do this you may also want the ability to have it be a listbox
with different color fonts or simply a freq or priority tag next to
the word to make it fit in with the typical GUI.