Remove unneeded variables

`transform` was actually unused. `scale` is simply unneeded because, in
our implementation, it’ll always compute to 1.
updateTokens shouldn't depend on size
Fix re-rendering on resize

Before, when render() got called with no words, drawCloud happened to
handle that by leaving the old words in place, which worked but was a
bug. Now that drawCloud’s changed, when actually have to get the
argument right.
Remove sorting in tokensToArray

The word cloud layout sorts them anyway, as it positions the highest
rated words first + closest to the center.
Switch to force directed
Rewrite + a workable force-directed layout

First of all, this is a major clean up of the existing codebase. I
converted it to ES6 (transpiled with tracer by gulp), which provided an
increasingly-needed division of the client-side code into modules,
along with a generally cleaner syntax. I also removed some unneeded
libraries, cleaned up the template, etc.

In terms of new functionality, the force directed layout now works
decently. This took quite a lot of playing.

Nothing that I tried for creating edges (and setting their distances)
before starting the layout simulation worked. The final layout that we
want is more or less a spiral (bigger words in the center, with smaller
words radiating out), which means that two low-frequency words could be
right next to each other (along the outer edge of the spiral) or
completely across the layout from each other, and I wasn’t sure how to
create edges to make this happen.

So, the approach I ended up using simply leaves the graph disconnected
but then gives each word/node a repulsive force proportional to its
frequency (and to the window’s area, so the visualization gets more
breathing room as the window expands, which lowers the odds of word
overlap and is more aesthetically pleasing).

Making this work also required setting the initial conditions of the
layout in such a way that the frequent words would be in the center.
Further, I wanted the initial position of a word to be 1) deterministic
and 2) independent of its index in the token list, so that the layout
would stay largely intact when a token was removed. To accomplish this
I ended up using polar coordinates. I set the theta for each word as
(2π*(frequency % 360)/360). The (frequency % 360)/360 part is
semi-arbitrary, but it nicely satisfies the two conditions listed
above. Then, I set the r of each node/word to be (node’s frequency/max
frequency)*(length of the line segment drawn at angle ø from the center
to the nearest window edge).

Finally, to keep the nodes from spreading out into space too far, I
added another force like the built in gravity option (though mine is
sensitive to the window’s aspect ratio) and imposed a hard bounding so
no node can go off the edge of the screen. This is coupled with code
that reduces the number of words shown as the window’s area shrinks,
again so that all the words can fit without collision. (The word count
is reduced almost exponentially as the window shrinks, rather than
linearly, because the remaining words at a given size are, by
definition, disproportionately large.

The above algorithm works as well as any I’ve able to make so far, but
its layout is still both less compact than the non-force directed
algorithm’s and, unlike the original layout, is prone to word overlap
at far greater rates than I’d like. When I tried to implement a
collision detection algorithm to prevent the overlaps (after adapting
that algorithm to work with word-shaped items, not points or circles),
it didn’t work, because the collision detection algorithm ended up
moving the biggest words way too far from the center (as there was
nothing holding them there; they were there only by virtue of their
initial positions).

After a bit of googling, I stumbled upon a Microsoft paper
(http://research.microsoft.com/en-us/um/people/weiweicu/images/wordpv.pd
f) that points to a solution: draw edges between nodes (with a Delaunay
triangulation) _after_ doing a rough initial layout, so that then those
edges can hold the nodes in place during the collision detection
process. Brilliant! Naturally, though, I found this paper only after
doing all the above work. I will implement it, but not until next week
when I have more time.
Modeless erasing ui, first draft
Restore word clickability
Whoops, remove debugger
Rename _render methods to make them "public"

These should be exposed, as this class is for layout, after all.
Misc/Stylistic Cleanup
Add collision detection

Includes updating visualSize to return good estimates…of course, these
will only work with Open Sans in English :/
Make the cloud denser

Collision detection lets us do this.
Fix gulpfile

Must reset the builder or the `watch` use of this command won’t work.
Make percentComplete affect how many words are shown

This has the effect of making the cloud less jumpy, as only the top
words—which are also the words less likely to move or disappear—are
shown at first.
Add a compacting force

This replaces d3’s standard links-attract force. It’s better because it
stops exerting a force once the words start overlapping, which d3’s
implementation isn’t smart enough to do. Unfortunately, if making this
new force really strong makes the graph highly non-planar (i.e. far
from its initial layout), so I’ve turned it down for now. But, in the
future, when we have a force that keeps the graph planar, we’ll be able
to crank it back up to awesome effect.
Include links in the DOM

These can be interesting to see.
Preserve existing word's positions between token updates

To make adding new tokens less jumpy.
Increase font sizes

Helps readability + accurate representation of the data. And now we
have the space to do it.
Remove animations

These were more distracting than they were worth, as they had words
flying across each other all the time.