pwnt.be

Introducing Pwnt.TagSphere

As you may know, I’ve already done quite a few experiments with visualizing tags. Sadly, up until now, I was mostly unsatisfied. Today, however, I am presenting Pwnt.TagSphere, a three-dimensional tag cloud I hope you’ll all enjoy. Head here for an example.

Update: The code has changed a bit since I wrote this, mostly to mimic the behavior of WP-Cumulus. Everything’s backward compatible, so all the documentation below still applies. I’ve also set up a little demo.

Chihuly Glass Seaforms
Chihuly Glass Seaforms by Jill Clardy
Some rights reserved

As the name suggests, Pwnt.TagSphere puts your tags on a spherical body. The sphere automatically rotates, but you can also drag it around in a very natural way. Like with any other tag cloud, the more important a tag is, the more prominently it is visualized. Clicking on a tag takes you to the URL associated with it. The whole thing was written in JavaScript, with MooTools and using a bit of CSS for visual styling.

Of course, you’ll want to use Pwnt.TagSphere on your own web site. Good news: you can; all I ask is that you give credit. I’ll now try and explain how to integrate this gizmo.

Basic Installation

  1. Get the scripts. You need both MooTools (Core) and tag_sphere.js.

  2. Include the scripts in your HTML code, e.g.

    <script type="text/javascript"
        src="/js/tag_sphere.js"></script>
  3. Add the following bit of JavaScript code to your page:

    window.addEvent("load", function() {
        var tags = [
            [ "One", 12, "/tag/1" ],
            [ "Two", 345, "/tag/2" ]
        ];
        var sphere = new Pwnt.TagSphere(tags);
        sphere.getElement().inject(document.body);
        sphere.start();
    });

    This creates a Pwnt.TagSphere with two tags: “One,” which was used 12 times and links to the URL /tag/1, and “Two,” with 345 uses and the URL /tag/2. Of course, you can add as many tags as you like, and you’ll probably want to fetch them from some data source; I’ll leave that to you.

    As you can see, sphere exposes a getElement() method, which actually returns the panel containing the whole thing—a HTML <div>. It’s up to you to add it to the document and subsequently call the start() function to activate it.

  4. If you navigate to the page, you should already see some action, but it won’t be pretty. That’s because we haven’t added any CSS code yet. So, let’s do so now. At the very least, you need to set the tag sphere’s dimensions:

    .tag-sphere {
        width: 400px;
        height: 300px;
    }

    If, for whatever reason, you want to include multiple tag spheres, you can easily assign an ID to the panel returned by getElement() and adjust your CSS accordingly.

  5. That’s it. You’ve got yourself a spiffy tag sphere.

Further Configuration

You may find the default tag sphere ugly and boring. Fortunately, you can do a hell of a lot of tweaking via both JavaScript and CSS. I’ll first cover the CSS part, since it’ll probably be less complicated.

Stylesheet Options

As you may have noticed above, the <div> returned by getElement() has the tag-sphere class by default. The individual tags are actually standard <a> elements with absolute positioning. This provides an easy way to apply some styles to the tag sphere. I’ll suggest a few …

  • To set the maximum font size used in the sphere to 18 points, use

    .tag-sphere {
        font-size: 18pt;
    }
  • If you want to remove underlining from the tag links, just add

    .tag-sphere a {
        text-decoration: none;
    }
  • To emphasize the tag the cursor is currently hovering, use

    .tag-sphere a:hover {
        opacity: 1 !important;
        z-index: 101 !important;
    }

    This makes the link opaque and brings it to the front. The latter works because the links silently get a z-index between 0 and 100 while rotating. Any value over 100 will thus place it in front.

  • While any of the links is hovered, the whole panel temporarily receives the focused class. This allows you to “dim” all the non-hovered links to silver, while making the hovered one black:

    .tag-sphere.focused a {
        color: silver;
    }
    
    .tag-sphere a:hover {
        color: black;
    }

    You could also use the opacity property for this, but keep in mind that you would lose the depth effect.

  • If you want to change the cursor for the whole panel, use

    .tag-sphere, .tag-sphere.dragging a:hover {
        cursor: move;
    }

    While the user is manually rotating the sphere, the panel receives the dragging class. This explains the part after the comma: if, while dragging, the cursor hits a tag, it won’t change. While not dragging, on the other hand, it’ll behave like any other link.

Class Options

By adding a second parameter to the constructor, you can configure a couple of options. For instance, if you wanted to change the tag opacity range—don’t worry, we’ll get to that in a moment—, you’d write:

var sphere = new Pwnt.TagSphere(tags, {
    minAlpha: 0.5,
    maxAlpha: 0.75
});

Now, here’s a list of available options and their default values:

minAlpha: 0.05
maxAlpha: 1.00

The minimum and maximum opacity of a tag. The least important tag gets minimal opacity, the most important one maximal.

zoom: 0.9

The relative size of the furthest tag—i.e., the one at the back of the orb. The smaller this number, the deeper the sphere will appear to be. This factor also applies to opacity.

scale: "linear"

If the tags’ usage counts aren’t uniformly distributed, the sphere might look prettier if you set the scaling method to "quadratic" or "exponential", depending on your preference.

paddingX: 1/5
paddingY: 1/20

The horizontal and vertical distance from the edge of the panel to the outline of the sphere, expressed as a fraction of the width and height, respectively. As the tag names will overflow this outline, these distances will need to be sufficiently large.

rotationInterval: 100

The number of milliseconds between two frames—i.e., the inverse of the frame rate.

rotationAngleX: Math.PI/500
rotationAngleY: -Math.PI/200
rotationAngleZ: 0

The rotation angle around the X, Y and Z axis, expressed in radians per frame. Hence, set rotationInterval accordingly.

dragAngle: Math.PI

The rotation angle when manually rotating the sphere, expressed in radians divided by width or height, depending on the direction. For example, if the user dragged the mouse vertically over a distance that was half the height of the panel, the sphere would be rotated 0.5 * dragAngle radians around the X axis.

That’s it. If you’ve got any suggestions, I’d love to hear them.

Comments on This Post

  • Says John Brand, roughly 1 year and 8 months ago:

    I love that you made it MooTools. Now what would be really kewl is to do this.

    Take the sphere’s surface and sub-divide that evenly with the degrees of seperation, e.g. if there are 36 tags then each tag would be seperated by an even amount of space. The random method of spacing the elements don’t work well, as some large tags could overlap one another.

    Basically an even distribution of tags accross the surface on initialization would help immensely.

  • Says Tim, roughly 1 year and 8 months ago:

    Thanks for the compliment!

    I’ve thought about even spacing, but I’m not sure how well that would work, given the different font sizes and fake perspective. If the tags were actually rendered on top of a spheric surface, this approach would absolutely rock.

    Unfortunately, I’m not nearly good enough at 3D to accomplish this, but I /am/ sure that it can be done using a canvas. Can’t wait until someone actually makes it and I get to take credit for the idea.

Post a Comment

This contraption supports Gravatar, as well as Markdown with SmartyPants. If none of that made sense to you, feel free to ignore it and start typing.

  • :)
  • :D
  • ;)
  • :-O
  • :P
  • :@
  • :$
  • :S
  • :(
  • :'(
  • :|
  • :-#
  • 8-|
  • ^o)
  • :-*
  • +o(
  • :^)
  • *-)
  • 8-)
  • |-)
Disorientation
Continuity
Tangentiality
Retributions
Koop eens een Nokia Lumia 800
Samuel Debruyn
Bizar Hairdressing & Beyond
Hanne, Hanne, Ruxi, Wim, Tim, Sarina, Lies, Lynn, erwin, Ano, Frederick, Jacqueline, Wazaaa, Tim, Rebecca, Charlie
Lplayer for the Rest of Us
fieryy-AA, jesus2099, Tim, jesus2099, Tim, jesus2099, Tim, PixelPirate
Automating OpenVPN Connection on Windows XP
blanky, sky, Tim, Geb, 12vpn, Tim, neecom
Simple Linear Regression with JFreeChart
Nicolas Machado, Sascha, Tim, Sascha, Tim, Sascha
Colophonics