Created
January 30, 2013 03:26
-
-
Save jraines/4670344 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# An attempt to do object oriented d3 graphing | |
# | |
# This graphs a swimmer's progress through a challenge set. | |
# | |
# x is the swim (1 of 5, 2 of 5, etc) | |
# y is their time in seconds | |
# | |
# radius of orange circles is the swimmers heart rate after 1 swim | |
# | |
# radius of red background circles is swimmer's heart rate after that swim | |
# | |
# data is in form: {hr: 155, seconds: 115} | |
# 'this' is the window; this makes the class available to js defined in other files | |
class @Graph | |
constructor: (config, json) -> | |
[@w, @h, @padding] = [config.width, config.height, config.padding] | |
@data = JSON.parse json | |
@data2 = JSON.parse json | |
#domain is number of seconds between 1:45 and 2:20 | |
@y = d3.scale.linear().domain([105, 140]).range([@w - @padding, @padding]) | |
#domain is index of swim | |
@x = d3.scale.linear().domain([-1, 5]).range([@padding, @h - @padding]) | |
@yAxis = | |
d3.svg.axis() | |
.scale(@y) | |
.orient('left') | |
.tickFormat getTime | |
render: => | |
@create_canvas() | |
@draw_axis() | |
@draw_best_time_line() | |
@create_circles() | |
@render_circles() | |
create_canvas: => | |
@svg = | |
d3.select(config.element) | |
.append('svg') | |
.attr('width', @w) | |
.attr('height', @h) | |
#update the position of the info box to follow the mouse | |
.on('mousemove', mouseMoveFunction) | |
draw_axis: => | |
@svg.append('g') | |
.attr('transform', "translate(#{@padding},0)") | |
.attr('class', 'yAxis') | |
.call @yAxis | |
#Draw a line across the graph showing the swimmer's best time in this event. | |
#Hard coding it in this case at 1:52 | |
draw_best_time_line: => | |
@svg.append('svg:line') | |
.attr('x1', 40) | |
.attr('x2', 500) | |
.attr('y1', @h - 112) | |
.attr('y2', @h - 112) | |
#weirdly, this comes out gray | |
.style('stroke', 'black') | |
create_circles: => | |
@circles = | |
@svg.selectAll('.circle') | |
.data(@data) | |
.enter() | |
.append('circle') | |
@circles2 = | |
@svg.selectAll('.circle2') | |
.data(@data2) | |
.enter() | |
.append('circle') | |
render_circles: => | |
@circles.attr('cx', (d, i) => @x(i)) | |
.attr('cy', (d) => @y(parseInt(d.seconds))) | |
.attr('r', 0) | |
.attr('time', (d) -> getTime d.seconds) | |
.attr('hr', (d) -> d.hr) | |
.attr('fill', 'red') | |
.attr('class', 'point') | |
#d3 convention - outdent 2 spaces when changing the graph | |
.transition() | |
.duration(4000) | |
.attr('r', (d) -> (parseInt(d.hr) / 12) + 2) | |
@circles2.attr('cx', (d, i) => @x(i)) | |
.attr('cy', (d) => @y(parseInt(d.seconds))) | |
.attr('r', 0) | |
.attr('time', (d) -> getTime d.seconds) | |
.attr('hr', (d) -> d.hr) | |
.attr('fill', 'orange') | |
.attr('class', 'circle2') | |
.transition() | |
.attr('r', parseInt(@data[0].hr) / 12) | |
#show and hide the info box tooltip | |
@circles2.on('mouseover', mouseOverFunction) | |
@circles2.on('mouseout', mouseOutFunction) | |
#event listeners for moving/displaying/hiding info tooltip | |
mouseOverFunction = -> | |
d3.select('.infobox').style('display', 'block') | |
d3.select('.infobox p').text d3.select(this).attr('hr') | |
mouseOutFunction = -> | |
d3.select('.infobox').style('display', 'none') | |
d3.select(this).attr('fill', 'orange') | |
mouseMoveFunction = -> | |
infobox = d3.select(".infobox") | |
infobox.style("left", d3.event.pageX + "px" ) | |
infobox.style("top", d3.event.pageY + "px") | |
# format the time for displaying on the axis and info box | |
getTime = (seconds) -> | |
seconds = parseInt seconds | |
mins = Math.floor seconds/60 | |
seconds = seconds % 60 | |
seconds = seconds.toString() | |
seconds = ('0' + seconds) if seconds.length is 1 | |
"#{mins}:#{seconds}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment