
C2: Clojure(Script) data visualization - DanielRibeiro
http://keminglabs.com/c2/
======
lynaghk
github: <https://github.com/lynaghk/c2>

video intro:
[http://www.youtube.com/watch?feature=player_detailpage&v...](http://www.youtube.com/watch?feature=player_detailpage&v=T83P3PVSy_8#t=510s)

------
nilliams
Agreed, weird to say this to a lisper as you guys are all about the elegance
etc, but you should really take a leaf out of some JS library authors' books.

<http://oesmith.github.com/morris.js>
<http://humblesoftware.com/flotr2#!basic> <http://wijmo.com/widgets/>

You seem to have mixed some nice 'magic' (i.e. enough magic to draw a somewhat
beautiful map of the United States, and your very interesting theming feature)
with some very odd low-level stuff, e.g.

':path.state {:d (geo->svg (get states state-name) :projection proj'

What is that about? Why should I have to know about those things?

Also I think you should seriously consider factoring your styles out of your
ClojureScript, that's what CSS is for. i.e. this stuff:

[:div {:style (style {:height bar-height ... :background-color "gray"})}
[:span {:style "color: white;"} label]]))])

... should no more be written in ClojureScript than it should be written in
JavaScript. That's CSS's domain.

You will reap the rewards (first simple win being able to tweak and experiment
with styles in Chrome's dev tools) if you start using CSS classes to define
your styles.

Apart from that it's very interesting work and you clearly have an eye for
beauty, look forward to seeing more.

~~~
milroc
Just a little info on this, this is not a charting library, it's probably
closer to a graphics or visualization library.

It pulls a lot of it's ideas from d3.js, allowing CSS to dictate a lot of your
style choices, but also allowing the data to change the style (a typical
example is a chart where you have different categories of data, coloring those
categories depending on the data).

This is low level for a reason, most charting libraries take a specific stance
on how to visualize something. d3 and c2 let that be dictated entirely by the
developer. It may take more effort to get a bar chart working in either of
these libraries but generally the control you have allows you to fit it into
your design rather than your design molding around the charting library you
use.

~~~
nilliams
Okay, interesting. I perhaps don't understand enough about the syntax to
appreciate why those lower-level constructs would be beneficial w.r.t the geo
stuff.

On the styling sure, data should often dictate the style in visualisations -
the most noddy example people tend to give in JS as the exception to the rule
of never 'programatically' (JS) setting styles is the _progress bar_ where the
width has to be data-based (as CSS-classes only make sense for discrete
increments or 'states'). Of course the same applies for colouring/shading and
sizing based on say population data or whatever is being modeled in a
visualisation, I get that.

But, in the example on the first page the bars of the histogram are all
explicitly coloured gray w/ white text programatically and the bar heights are
manually set to '20' (presumably px). What would make more sense is for them
to have a default class of say 'hist-bar-default', which is set in CSS to {
height: 20px; background: gray; color: white }. If anything it would just make
the example simpler as it actually muddles up the code where the widths are
being dynamically set. _shrug_

Edit: btw, you will see that d3.js does this, it applies classes where
appropriate rather than setting styles explicitly:
<http://mbostock.github.com/d3/ex/cartogram.html>

~~~
milroc
This is more of a choice of how the creator wanted to display the usefulness
of C2. That can just as easily be done with C2.

[:div {:class "hist-bar-default"}] would likely be the way to do it.

Also d3.js examples are riddled with bars.attr("style", "height: " + 30px)
just because sometimes it's easier to think about it while developing there.
It's not maintainable and very problematic in large designs but I would
recommend not judging a library based off of design choices like that with
examples of d3 or c2.

I'm glad you're passionate about visualization though, you should definitely
start using these libraries, and after a while (d3.js has been said to "melt
your brain initially) you'll realize the benefits of working at a lower level
with the data.

------
rgbrgb
OK, so I've looked at a few of the code samples and my biggest recommendation
is that you include some higher level functions which can be customized.
Compare the very simple histogram on the front page and the code used to make
it with the code to make a histogram in R. Graphics is something R does right.
The equivalent code in R:

>> vals = read.csv('somedata.csv')

>> hist(vals)

~~~
lynaghk
C2 isn't a charting library; it's a collection of composable primitives for
building statistical graphics. There are some built in helpers---scales, axis
templates, and the tick-selection algorithm---that would make it pretty easy
to build exactly the histogram graphic you want.

If you want to pick from a menu of fixed data graphics, though, HighCharts,
R's ggplot, or Tableau are much better choices than C2.

~~~
bedatadriven
Take another look at ggplot2; it's exactly the "collection of composable
primitives for building statistical graphs" that you mention; but it also
gives you some higher level functions that give you a starting point that you
can then customize.

~~~
lynaghk
I've talked with Hadley about this at length = )

There's a benefit to working in Hadley's / Wilkinson's grammar, but the
tradeoff is that it obscures the underlying DOM representation (or R's
graphics subsystem, as the case may be).

ggplot is for analysts, and c2 is for web devs and hackers.

------
vutekst
At the risk of being slightly off-topic, does anyone know a name for the color
scheme used in the code samples? It's quite pretty.

~~~
lynaghk
It's Twilight:

<http://keminglabs.com/css/twilight.css>

------
nkh
Hey Kevin, what led you deprecate cljs-d3 in favor of C2? In your Clojure conj
talk, you mentioned a JS implementation change caused your code to break. Was
that the main motivation, or where there other reasons?

~~~
lynaghk
We needed it working on the JVM.

Also, it wasn't clear how to wrap D3's functions in a consistent way w.r.t.
data handling. For instance, D3 has a histogram calculator that will bin your
data--should that return a Clojure map/vector (so you can use those densities
in ClojureScript) or should it return the plain JavaScript construct (so you
can pass directly to other D3 functions).

It wasn't something that I thought much about at first, but the DOM-
representation as hiccup vectors instead of chained syntax is a huge win
because it makes mapping data to hierarchies much easier than in D3.

------
latortuga
Your demo video is very awesome - short, easy to follow, clear instructions!
The library looks pretty cool!

~~~
bOR_
Wish there were a bit more instructions on how to get it running using lein2 /
project.clj. Maybe that happens this weekend :-). I am a bit at a loss how to
start the webserver used by c2 (and if its even included) from within
emacs/slime/swank.

~~~
lynaghk
There's no webserver built into C2. The visual REPL is a separate (toy)
project.

To use within Clojure, just add c2 to your deps as usual and then

    
    
        (ns your-ns
          (:use [c2.core :only [unify!]]))
    

Use from within ClojureScript is pretty much the same. Checkout

<https://github.com/lynaghk/cassowary-cljs-demo>

for a rough demo.

------
jdonaldson
Great stuff Kevin!

------
kultus
Great stuff

