Skip to content

Commit

Permalink
Upgrade T.js, clean up rankings page
Browse files Browse the repository at this point in the history
  • Loading branch information
gcao committed Nov 5, 2013
1 parent d34c0ed commit 25b4a5d
Show file tree
Hide file tree
Showing 4 changed files with 457 additions and 486 deletions.
8 changes: 4 additions & 4 deletions source/index.html.haml
@@ -1,10 +1,10 @@
%h2 Welcome to TennisForFans.com!

%p
This site contains ATP's top 50 players' <a href='rankings.html'>current ranking</a>
and their <a href='rank-history.html'>rank history</a> starting from 2003.
It also includes <a href='tournaments.html'>a map</a> that shows all professional-level tournaments occurred in 2013.
Top players' <a href='win-loss.html?players=novak_djokovic,roger_federer,rafael_nadal,andy_murray'>overall win-loss chart</a> and <a href='win-loss.html?players=novak_djokovic%2Croger_federer%2Crafael_nadal%2Candy_murray&grandSlam=true'>grand-slam win-loss chart</a> are also neatly presented.
This site contains ATP's top 50 players' <a href='#/rankings'>current ranking</a>
and their <a href='#/rank-history/novak_djokovic,roger_federer,rafael_nadal,andy_murray'>rank history</a> starting from 2003.
It also includes <a href='#/tournaments'>a map</a> that shows all professional-level tournaments occurred in 2013.
Top players' <a href='#/win-loss/novak_djokovic,roger_federer,rafael_nadal,andy_murray'>overall win-loss chart</a> and <a href='#/win-loss/novak_djokovic,roger_federer,rafael_nadal,andy_murray?grandSlam'>grand-slam win-loss chart</a> are also neatly presented.

%br
%h2 Credit
Expand Down
12 changes: 1 addition & 11 deletions source/javascripts/rank-history.js.coffee
Expand Up @@ -19,17 +19,9 @@ T.def 'rank-history', ->
players = $("[name=player]:checked").map(-> @value)
if players.length is 0
alert "No player is selected."
else if players.length is 1
window.location.hash = "#/ranking-history?players=" + players[0]
else
s = players[0]
i = 1
window.location.hash = "#/ranking-history/#{players.join(',')}?fromYear=#{$("[name=fromYear]").val()}&toYear=#{$("[name=toYear]").val()}"

while i < players.length
s += "," + players[i]
i++

window.location.hash = "#/ranking-history?players=" + s + "&fromYear=" + $("[name=fromYear]").val() + "&toYear=" + $("[name=toYear]").val()
'Update graph'
]
]
Expand Down Expand Up @@ -121,8 +113,6 @@ window.changeFromYear = ->
$("[name=toYear]").val (if toYear then toYear else getYear())

router.get '/rank-history/:players', (req) ->
console.log 'rank-history'

T('rank-history').render inside: '.main'

loadData "rankings", (rankings) ->
Expand Down
249 changes: 122 additions & 127 deletions source/javascripts/rankings.js.coffee
Expand Up @@ -2,11 +2,11 @@ T.def 'rankings', ->
[
[ 'h2'
'ATP rankings chart for top 50 players'
[ 'span.generated-note'
'(generated at'
[ 'span.generated-at' ]
')'
]
#[ 'span.generated-note'
# '(generated at'
# [ 'span.generated-at' ]
# ')'
#]
]
[ 'form#rankings-form'
action: "#/rankings"
Expand All @@ -15,7 +15,7 @@ T.def 'rankings', ->
type: "checkbox"
name: "ytd"
value: "true"
click: -> toggle($(this).attr('checked'))
click: -> toggle($(this).is(':checked'))
]
[ 'label'
for: "ytd"
Expand All @@ -26,42 +26,38 @@ T.def 'rankings', ->
[ "#rankings-chart", style: 'height: 1000px' ]
]

router.get '/rankings', ->
console.log 'rankings'

T('rankings').render inside: '.main'

# http://d3-generator.com/

i2rank = (i) ->
if i < 10
" _" + i
else
" " + i

firstTime = true
valueLabelWidth = 50 #space reserved for value labels (right)
barHeight = 20 #height of one bar
barLabelWidth = 107 #space reserved for bar labels
barLabelPadding = 5 #padding between bar and bar labels (left)
gridLabelHeight = 18 #space reserved for gridline labels
gridChartOffset = 3 #space between start of grid and first bar
maxBarWidth = 920 #width of the bar with the max value
dataLength = 51
xMax = 13999 #Avoid draw 14000 vertical grid
duration = -> (if firstTime then 0 else 3000)
exitDuration = -> (if firstTime then 0 else 1200)

label = (d, i) -> d.last + i2rank(d.rank)
barLabel = (d, i) -> d.points

# scales
yScale = d3.scale.ordinal().domain(d3.range(0, dataLength)).rangeBands([0, dataLength * barHeight])
y = (d, i) -> yScale i
yText = (d, i) -> yScale(i) + yScale.rangeBand() / 2
x = d3.scale.linear().domain([0, xMax]).range([0, maxBarWidth])
xBarLabel = (d) -> x d.points

# http://d3-generator.com/

firstTime = true
valueLabelWidth = 50 #space reserved for value labels (right)
barHeight = 20 #height of one bar
barLabelWidth = 107 #space reserved for bar labels
barLabelPadding = 5 #padding between bar and bar labels (left)
gridLabelHeight = 18 #space reserved for gridline labels
gridChartOffset = 3 #space between start of grid and first bar
maxBarWidth = 920 #width of the bar with the max value
dataLength = 51
xMax = 13999 #Avoid draw 14000 vertical grid
duration = -> (if firstTime then 0 else 3000)
exitDuration = -> (if firstTime then 0 else 1200)

i2rank = (i) -> if i < 10 then " _" + i else " " + i

label = (d, i) -> d.last + i2rank(d.rank)
barLabel = (d, i) -> d.points

# scales
yScale = d3.scale.ordinal().domain(d3.range(0, dataLength)).rangeBands([0, dataLength * barHeight])
y = (d, i) -> yScale i
yText = (d, i) -> yScale(i) + yScale.rangeBand() / 2
x = d3.scale.linear().domain([0, xMax]).range([0, maxBarWidth])
xBarLabel = (d) -> x d.points

toggle = (ytd) ->
resource = if ytd then "rankings_ytd" else "rankings"
loadData resource, (rankings) -> showChart rankings

initChart = ->
# svg container element
chart = d3.select("#rankings-chart")
.append("svg")
Expand Down Expand Up @@ -103,97 +99,96 @@ router.get '/rankings', ->

# bar labels
labelsContainer = chart.append("g")
.attr('id', 'labelsContainer')
.attr("transform", "translate(" + (barLabelWidth - barLabelPadding) + "," + (gridLabelHeight + gridChartOffset) + ")")

barsContainer = chart.append("g")
.attr('id', 'barsContainer')
.attr("transform", "translate(" + barLabelWidth + "," + (gridLabelHeight + gridChartOffset) + ")")

showChart = (rankings) ->
#updateGenerationTime rankings.generated_at
data = rankings.data

labels = d3.select("#labelsContainer").selectAll("text").data(data, (d) -> d.first + d.last)

# Update transitions
labels.transition()
.duration(duration)
.ease("exp-out")
.attr("y", yText)
.text(label)
labels.enter()
.append("text")
.attr("y", yScale(dataLength - 1))
.attr("stroke", "none")
.attr("fill", "black")
.attr("dy", ".35em") # vertical-align: middle
.attr("text-anchor", "end")
.text(label)
.transition()
.duration(duration)
.ease("exp-out")
.attr("y", yText)
labels.exit()
.remove()

barsContainer = d3.select("#barsContainer")

bars = barsContainer.selectAll("rect").data(data, (d) -> d.first + d.last)

# Update transitions
bars.transition()
.duration(duration)
.ease("exp-out")
.attr("width", (d) -> x d
.points).attr("y", y)
bars.enter()
.append("rect")
.attr("y", yScale(dataLength - 1))
.attr("height", yScale.rangeBand())
.attr("width", (d) -> x d.points)
.attr("stroke", "white")
.attr("fill", "steelblue")
.transition()
.duration(duration)
.ease("exp-out")
.attr("y", y)
bars.exit()
.remove()

barLabels = barsContainer.selectAll("text").data(data, (d) -> d.first + d.last)

# Update transitions
barLabels.transition()
.duration(duration)
.ease("exp-out")
.attr("x", xBarLabel)
.attr("y", yText)
.text(barLabel)
barLabels.enter()
.append("text")
.attr("x", xBarLabel)
.attr("y", yScale(dataLength - 1))
.attr("dx", 3)# padding-left
.attr("dy", ".35em")# vertical-align: middle
.attr("text-anchor", "start")# text-align: right
.attr("fill", "black")
.attr("stroke", "none")
.text(barLabel)
.transition()
.duration(duration)
.ease("exp-out")
.attr("y", yText)
barLabels.exit()
.remove()

firstTime = false

router.get '/rankings', ->
T('rankings').render inside: '.main'

window.toggle = (ytd) ->
if ytd
loadData "rankings_ytd", (rankings) ->
showChart rankings

else
loadData "rankings", (rankings) ->
showChart rankings

showChart = (rankings) ->
updateGenerationTime rankings.generated_at
data = rankings.data

labels = labelsContainer.selectAll("text").data(data, (d) -> d.first + d.last)

# Update transitions
labels.transition()
.duration(duration)
.ease("exp-out")
.attr("y", yText)
.text(label)
labels.enter()
.append("text")
.attr("y", yScale(dataLength - 1))
.attr("stroke", "none")
.attr("fill", "black")
.attr("dy", ".35em") # vertical-align: middle
.attr("text-anchor", "end")
.text(label)
.transition()
.duration(duration)
.ease("exp-out")
.attr("y", yText)
labels.exit()
.remove()

bars = barsContainer.selectAll("rect").data(data, (d) -> d.first + d.last)

# Update transitions
bars.transition()
.duration(duration)
.ease("exp-out")
.attr("width", (d) -> x d
.points).attr("y", y)
bars.enter()
.append("rect")
.attr("y", yScale(dataLength - 1))
.attr("height", yScale.rangeBand())
.attr("width", (d) -> x d.points)
.attr("stroke", "white")
.attr("fill", "steelblue")
.transition()
.duration(duration)
.ease("exp-out")
.attr("y", y)
bars.exit()
.remove()

barLabels = barsContainer.selectAll("text").data(data, (d) -> d.first + d.last)

# Update transitions
barLabels.transition()
.duration(duration)
.ease("exp-out")
.attr("x", xBarLabel)
.attr("y", yText)
.text(barLabel)
barLabels.enter()
.append("text")
.attr("x", xBarLabel)
.attr("y", yScale(dataLength - 1))
.attr("dx", 3)# padding-left
.attr("dy", ".35em")# vertical-align: middle
.attr("text-anchor", "start")# text-align: right
.attr("fill", "black")
.attr("stroke", "none")
.text(barLabel)
.transition()
.duration(duration)
.ease("exp-out")
.attr("y", yText)
barLabels.exit()
.remove()

firstTime = false
initChart()

loadData "rankings", (rankings) -> showChart rankings

0 comments on commit 25b4a5d

Please sign in to comment.