D3 Bar Chart

HTML

<script src="//d3js.org/d3.v3.min.js"></script>
<svg></svg>

CSS

svg text {
    font-family: "Helvetica";
    font-size: 24px;
}

CoffeeScript

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


svg = d3.select("svg")
  .attr("width", opts.W)
  .attr("height", opts.H)
 

chart = svg.append("g")
  .classed("chart", true)
  .attr("transform", "translate(#{opts.margin.left}, #{opts.margin.top})")
    

    
data = [
  {x: "A", y: 5},
  {x: "B", y: 10},
  {x: "C", y: 15}
]

A =
  x: (d) -> d.x
  y: (d) -> d.y
    
S = 
  x: d3.scale.ordinal().rangeRoundBands([0, opts.width], 0.1)
  y: d3.scale.linear().range([opts.height, 0])
  

S.x.domain(data.map A.x)
S.y.domain([0, 20])


cell = chart.selectAll(".cell")
  .data(data).enter()
  .append("g")
  #.attr("transform", (d) -> "translate(#{S.x(A.x(d))}, #{S.y(A.y(d))})")
    

    
rectAttrs = (S, A) ->
  x: (d) -> S.x(A.x d)
  y: (d) -> S.y(A.y d)
  width: S.x.rangeBand()
  height: (d) -> S.y(0) - S.y(A.y d)

textAttrs = (S, A) ->
  x: (d) -> S.x(A.x d) + S.x.rangeBand()/2
  y: (d) -> S.y(A.y d) - 10
  "text-anchor": "middle"

    
cell.append("rect")
  .attr(rectAttrs(S, A))
  .attr("fill", "steelblue")
    
cell.append("text")
  .attr(textAttrs(S, A))
  .text((d) -> A.y d)
 
###
cell  
  .append("rect")
  .attr("x", 0)
  .attr("y", 0)
  .attr("width", S.x.rangeBand())
  .attr("height", (d) -> S.y(0) - S.y(A.y d))
  .attr("fill", "steelblue")


cell
  .append("text")
  .attr("y", "-0.5em")
  .attr("x", (d) -> S.x.rangeBand()/2)
  .text((d) -> A.y d)
  .attr("text-anchor", "middle")
###