Mithril with D3Kit
by ramnathv
HTML
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//rawgit.com/kristw/75b61f9beeab9b530612/raw/389e984e4041117a9185cf6edad9f6b85a38097a/d3kit.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<div class="container-fluid" id='main'>
<div class="row">
<div class="col-xs-12 col-md-6">
<div id="chart"></div>
<div class="well">
This is an example of hooking up Mithril with a D3 chart that automatically handles resize events. If you open the developer console, you will notice that resizing the chart will not initiate a redraw by mithril, as it is being handled directly by the chart code.
</div>
</div>
</div>
</div>
CSS
.x-axis-layer line, .y-axis-layer line,
.x-axis-layer path, .y-axis-layer path {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
#main{
margin-top: 30px;
}
}
JavaScript
// Define bubble chart
var BubbleChart = d3Kit.factory.createChart(
// First argument is the default options for this chart
{
margin: {top: 60, right: 60, bottom: 60, left: 60},
initialWidth: 800,
initialHeight: 400
},
// The second argument is an Array that contains
// names of custom events from this chart.
// In this example chart,
// it will dispatch event "bubbleClick" when users click on a bubble.
['bubbleClick'],
// The third argument is an internal constructor.
// This is where you would implement a bubble chart
// inside the passed skeleton.
function(skeleton){
var layers = skeleton.getLayerOrganizer();
var dispatch = skeleton.getDispatcher();
var color = d3.scale.category10();
layers.create(['content', 'x-axis', 'y-axis']);
var x = d3.scale.linear()
.range([0, skeleton.getInnerWidth()]);
var y = d3.scale.linear()
.range([0, skeleton.getInnerHeight()]);
var xAxis = d3.svg.axis()
.scale(x)
.orient('bottom');
var yAxis = d3.svg.axis()
.scale(y)
.orient('left');
var visualize = d3Kit.helper.debounce(function(){
if(!skeleton.hasData()){
d3Kit.helper.removeAllChildren(layers.get('content'));
return;
}
var data = skeleton.data();
x.domain(d3.extent(data, function(d){return d.x;}))
.range([0, skeleton.getInnerWidth()]);
y.domain(d3.extent(data, function(d){return d.y;}))
.range([skeleton.getInnerHeight(), 0]);
layers.get('x-axis')
.attr('transform', 'translate(0,' + skeleton.getInnerHeight() + ')')
.call(xAxis);
layers.get('y-axis')
.call(yAxis);
var selection = layers.get('content').selectAll('circle')
.data(data);
selection.exit().remove();
selection.enter().append('circle')
.attr('cx', function(d){return x(d.x);})
.attr('cy', function(d){return y(d.y);})
.on('click', dispatch.bubbleClick);
...