JSFiddle - React, Tailwind, and code Playground

by ramnathv

HTML

<svg></svg>

CoffeeScript

d3.viz = {} if !d3.viz
d3.viz.histogram = (S, A) ->
  viz = this
  opts = {
    bins: 10       
  }
  statistic = d3.layout.histogram()
    .bins(opts.bins)
    .value(A.x)
  attrs =
    x: (d) -> S.x d.x
    y: (d) -> S.y d.y
    width: null
    height: (d) -> S.y.range()[0] - S.y d.y
  exports = (selection) ->
    selection.each (data) ->
      S.x.domain d3.extent(data, A.x)
      data = statistic(data)
      S.y.domain [0, d3.max(data, (d) -> d.y)]
      attrs.width = S.x.range()[1]/data.length*0.99
      chart = d3.select(this).append("g")
        .attr("class", "hist bars")
        .selectAll("rect")
        .data(data).enter()
        .append("rect")
        .attr attrs
  d3.rebind(exports, chart, 'attr')
  d3.rebind(exports, statistic, 'bins')
  exports
        

O =
  margin: {top: 20, bottom: 20, left: 20, right: 20}
  width: 400
  height: 200
  
O.W = O.width + O.margin.left + O.margin.right
O.H = O.height + O.margin.top + O.margin.bottom

svg = d3.select("svg").attr({width: O.W, height: O.H})
chart = svg.append("g").attr("id", "chart")
  .attr("transform", "translate(#{O.margin.left}, #{O.margin.top})")

A =
  x: (d) -> d

S =
  x: d3.scale.linear().range([0, O.width])
  y: d3.scale.linear().range([O.height, 0])
    

values = d3.range(1000).map(d3.random.logNormal(Math.log(30), .4))
S.x.domain d3.extent(values, A.x)

hist = d3.viz.histogram(S, A)
  .bins(S.x.ticks(20))
  .attr("fill", "steelblue")
chart.datum(values).call(hist)