note on speed prob.
TODO note on topic_docs
experimental: topic_docs moved into a Worker

which requires some refactoring. the dt object methods get moved off into a
separate file. For this first pass, I have left duplicate copies of the
doc-topics matrix, one in the model (main thread) and one for the
worker, so I wouldn't have to make every single dt access call out to
the worker. But m.topic_docs() now takes a callback that receives
the result of the calculation. This is used in topic_view_docs() to
render the table of top docs for the topic asynchronously.

The worker in js/model_worker.js responds to messages sent by the model
object in the main thread. So far it only knows "topic_docs," but
eventually it should hold all the model data and handle all the lengthy
computations. The model stores a d3.map of callbacks on its interface to
the worker (this is needed so parallel requests don't cross).

It's not possible to use the d3 array utility routines in the worker,
because there is no "document" object in the worker's thread and d3
requires one. So I've copied those routines into utils, which can be
in the worker's thread.

The topic_view should give a visual indication that a calculation is in
progress. index.js has a view_calculating function but it doesn't do
anything yet.
calculating messaging for topic_docs
progress in refactoring: view.topic

Putting the model in another thread makes it necessary to work out more
carefully what data the views actually need. This leads pretty naturally
to an MVC-style architecture, so I'm going to go ahead and separate out
the view code completely. There is now a view object which accepts
messages from index.js to draw views. So far the only messages it knows
about are the parts of the topic view (view.topic, view.topic.words,
etc.).

Also moved doc_topics off into the worker, with the requisite
modifications to the doc_view (but not yet factoring that out
completely).

Also: topic_words now returns a list of objects rather than just a list
of words that have to be passed back to the model, in preparation for
further refactoring.

In this intermediate stage, there are two copies of the document topic
matrix: one is held in the Worker thread, and one is still held in the
main thread.

Finally, this gave me an opportunity to reconsider the render_updown
architecture and buttons, which produce more visual interference than
they're worth. They are partly but not entirely removed in this commit:

- topic_view: words and docs use the settings held in the VIS object
- doc_view: just show all the doc_topics.
view_loading etc. -> view.loading etc.
view.doc encapsulated

This uses the threaded doc_topics call as well, though in practice this
is pretty fast for 100ish topics.
fix missing grid view words

errant parenthesis meant all words were getting size 0.
yearly tallying into the worker thread

continuing the refactor, this moves the work of tallying up yearly
totals by topic and overall into the Worker. (One fun wrinkle is that
this means I can't use d3.map anymore, and have fallen back to tricks
with regular arrays.)

meanwhile, model_view_list is now view.model.list and makes use of the
threaded calls. So does the yearly plot in the view.topic.

Some more calculating notices are strewn around too, but that's getting
intrusive.
factor out about.view
factor out model_view_plot

also, model.topic_words(undefined, n) means return an array with top words
for each topic
factor out words view
bug fix in callback id
make lint happy
refactoring of view.model.yearly

and the controller now makes use of the threaded model calls to supply
data for this.
view.topic() invoked with threaded calls
remove duplicate dt object in model

all doc-topics work is now done in the worker thread

slight modification to loading process and flags: m.set_dt now takes a
callback to be executed when the dt is ready. This now has the task of
refreshing the view when the data is in.

also m.dt() checks are replaced with m.has_dt().
less obstrusive messaging

"Loading" and "Calculating" show in the navbar rather than as wells that
shuffle the page layout.
refactoring of word view

now in view.word method.
delete yearly_stacked_series()

this is now view.model.yearly.stacked_series in view.model.yearly.js