D3Kit Bar Chart with React

by ramnathv

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/mithril/0.2.3/mithril.min.js"></script>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//cdn.rawgit.com/twitter/d3kit/master/dist/d3kit.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.3.6/paper/bootstrap.min.css">
<div class="container" id="main">
  <div class="row">
    <div class="col-xs-12 col-md-6">
      <div id="app"></div>
    </div>
  </div>
</div>

CSS

#main{margin-top: 20px;}
.y-axis-layer path,
.y-axis-layer line{
  fill: none;
}
.y-axis-layer line{
  stroke: lightgray;
}
.y-axis-layer text{
  font-size: 11px;
}

Babel + JSX

/** @jsx m */
const defaults = {
  margin: {left: 20, right: 20, bottom: 20, top: 20},
  initialWidth: "auto",
  initialHeight: 300
}

const chartConstructor = (skeleton) => {
  // setup 
  const S = {x: d3.scale.ordinal(), y: d3.scale.linear()}
  const A = {x: d => d[0], y: d => d[1]}
  
  const L = skeleton.getLayerOrganizer()
  L.create(['y-axis', 'bars', 'points'])
  const visualize = () => {
    // get data, width and height
    const data = skeleton.data()
    const W = skeleton.getInnerWidth()
    const H = skeleton.getInnerHeight()
    
    // update scales
    S.x.rangeRoundBands([0, W], 0.1).domain(data.map(A.x))
    S.y.range([H, 0]).domain([0, d3.max(data, A.y)])
   
    // render bars
    const bars = L.get('bars').selectAll('.bar').data(data)
    bars.enter().append('rect').classed('bar', true)
    bars.attr({
      x: d => S.x(A.x(d)),
      y: d => S.y(A.y(d)),
      width: S.x.rangeBand(),
      height: d => H - S.y(A.y(d)),
      fill: "steelblue"
    })
    
    // render points
    const points = L.get('points').selectAll('.point').data(data)
    points.enter().append('circle').classed('point', true)
    points.attr({
      cx: d => S.x(A.x(d)) + S.x.rangeBand()/2,
      cy: H,
      r: 3,
      fill: "darkblue"
    })
    points.transition().attr({
      cy: d => S.y(A.y(d)),
    })
    
    // render y-axis
    const yAxis = d3.svg.axis()
      .scale(S.y)
      .orient('left')
      .tickSize(-W)
      .tickValues([0, 0.2, 0.4, 0.6, 0.8, 1])
    L.get('y-axis').call(yAxis)
    
  }
  skeleton
    .resizeToFitContainer("width")
    .autoResize('width')
    .on("data", visualize)
    .on("resize", visualize)
}

const data = d3.range(15).map((d, i) => [i, Math.random()])


const Chart = d3Kit.factory.createChart(
  defaults, [], chartConstructor
)

//new Chart("#app").data(data)

const drawChart = (el, isInit, ctx) => {
  if (!isInit) ctx.chart = new Chart(el)
  ctx.chart.data(data)
}

const App = {
  view(ctrl, props){
    return <div...