timebars.coffee 2.34 KB
Newer Older
Kjetil Thuen's avatar
Kjetil Thuen committed
1
2
d3 = require 'd3-browserify'
lodash = require 'lodash'
3

4
5
completeData = {}

6
7
8
9
chartWidth = -> 900
chartHeight = -> 500
numBars = -> 100
speed = -> 100
Kjetil Thuen's avatar
Kjetil Thuen committed
10
margin = -> 10
11
12

barThickness = ->
Kjetil Thuen's avatar
Kjetil Thuen committed
13
  chartHeight() / numBars()
14

Kjetil Thuen's avatar
Kjetil Thuen committed
15
x = d3.scale.linear()
16
17
  .domain [ 0, 100]
  .range [ 0, chartWidth() / 2 ]
Kjetil Thuen's avatar
Kjetil Thuen committed
18
19

y = d3.scale.linear()
20
21
22
23
24
25
26
27
28
29
30
  .domain [ 0, numBars()]
  .rangeRound [ 0, chartHeight() ]

addBar = (newBar) ->
  barGroup = newBar.append "g"
    .attr "class", "valuepoint"
    .attr "transform", (d, i) ->
      "translate(0, " + (y(i) + .5) + ")"

  barGroup.append "rect"
    .attr "class", "right"
Kjetil Thuen's avatar
Kjetil Thuen committed
31
    .attr "x", chartWidth() / 2 - margin()
32
33
34
35
36
    .attr "width", (d) -> x d.rvalue
    .attr "height", barThickness()

  barGroup.append "rect"
    .attr "class", "left"
Kjetil Thuen's avatar
Kjetil Thuen committed
37
    .attr "x", (d) -> (chartWidth() / 2) - x d.lvalue + margin()
38
39
40
    .attr "width", (d) -> x d.lvalue
    .attr "height", barThickness()

41
42
43
44
45
46
valuesFromFrame = (containerId, frameNum) ->
  frameIndexes = lodash.keys(completeData[containerId])
  completeData[containerId]['' + frameIndexes[frameNum] + '']

updateChart = (containerId, frameNum) ->
  data = valuesFromFrame containerId, frameNum
47
48
  chart = d3.select containerId + " svg.chart"
  valuepoints = chart.selectAll "g.valuepoint"
49
    .data data, (d) -> d.birthyear
50
51
52
53
54
55
56

  valuepoints.transition()
    .ease "linear"
    .duration speed()
    .attr "transform", (d, i) ->
      "translate(0, " + (y(i) + .5) + ")"

57
  addBar valuepoints.enter()
58
59

  valuepoints.exit()
60
    .transition()
61
62
    .duration speed() / 2
    .attr "height", 0
63
    .remove()
64
  undefined
65

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
nextFrame = (containerId, frameNum) ->
  num = frameNum or 0
  num++
  if num > lodash.keys(completeData[containerId]).length
    num = 0
  updateChart containerId, num
  num

#Constructor.
#
#The data parameter should be an object with named years. Each year member
#should be an array with at least two members (male and female, further members
#are ignored), each element in these arrays should contain an object that has
#the value property.
#
#The conteinerId is just a string identfying a div within wich the graph should
#be built
83
setupChart = (containerId, data) ->
84
  completeData[containerId] = data
85
  chart = d3.select containerId
86
    .insert "svg"
87
88
89
90
      .attr "class", "chart"
      .attr "width", chartWidth()
      .attr "height", chartHeight()

91
92
93
exports.setupChart = setupChart
exports.speed = speed
exports.nextFrame = nextFrame