Mithril with D3
HTML
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="//d3js.org/d3.v3.min.js"></script>
<link rel="stylesheet" href="//keen.github.io/dashboards/assets/css/keen-dashboards.css">
<div class="container-fluid" id='main'>
<div class="row">
<div class="col-xs-12 col-md-6" id='app'>
Hello World
</div>
<div class="col-xs-12 col-md-6" id='readme'>
<div class="well">
This is an attempt to recreate a <a href="http://nicolashery.com/integrating-d3js-visualizations-in-a-react-app/"><code>React</code> example</a> using Mithril. My objective is to show how one can write really concise code using <code>Mithril</code>.
</div>
</div>
</div>
</div>
CSS
#main{
margin-top: 20px;
}
#app .chart-notes{
background: none;
border-top: none;
}
CoffeeScript
Pagination =
view: (ctrl, args) ->
m "ul.pagination", {
style: {margin: "0 auto"; width: "50%"}
},
args.data.map (d, i) ->
m 'li', {
onclick: (e) -> args.active(i)
class: if i is args.active() then 'active'
},
m 'a[href="#"]', d
generate_point = ->
x: Math.random()
y: Math.random()
r: Math.abs(Math.random())
TitlePanel =
view: (ctrl, args) ->
m 'div',
'Mithril with D3 '
m 'a.btn.btn-danger.btn-sm', {
onclick: (e) -> args.data.push(generate_point())
}, "Add Point"
m 'span.pull-right',
"Avg Size: ", m("b", "#{args.avg_size}")
Circles =
view: (ctrl, args) ->
S =
x: d3.scale.linear()
y: d3.scale.linear()
r: d3.scale.linear()
A =
x: (d) -> d.x
y: (d) -> d.y
r: (d) -> d.r
S.x.range([0, 300]).domain(args.xDomain)
S.y.range([200, 0]).domain(args.yDomain)
S.r.range([3, 8])
m 'svg', {width: 440, height: 240},
m 'g.circle', {
transform: "translate(20, 20)"
},
args.data[args.active()].map (d, i) ->
m 'circle', {
cx: S.x A.x(d)
cy: S.y A.y(d)
r: S.r A.r(d)
fill: 'steelblue'
stroke: 'white',
config: (el) ->
d3.select(el).on "mouseover", ->
console.log(d)
}
kPanel =
view: (ctrl, args) ->
m '.chart-wrapper',
m '.chart-title', args.title
m '.chart-stage', args.stage
m '.chart-notes', args.footer
make_data = (N) ->
d3.range(N).map (d, i) ->
x: Math.random()
y: Math.random(),
r: Math.abs(Math.random())
data = d3.range(5).map (d) ->
make_data(20)
compute_avg_size = (dat) ->
av = d3.sum(dat, (d) -> d.r)/dat.length
App =
controller: ->
active: m.prop(0)
data: data
avg_size: ->
d = data[@active()]
av = compute_avg_size(d)
d3.format('.2f')(av)
...