Created
March 12, 2014 21:11
-
-
Save cmpolis/9516434 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
| $(document).on 'page:load', () -> | |
| return unless $('#ca-vis').length | |
| # | |
| margin = { top: 0, right: 60, left: 50, bottom: 100 } | |
| width = $('.container').width() - margin.right - margin.left | |
| height = 540 - margin.top - margin.bottom | |
| colors = ['#8dd3c7', '#E1C368', '#bebada', '#fb8072', '#80b1d3', '#fdb462', | |
| '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5', '#ffed6f'] | |
| months = ['Oct', 'Nov', 'Dec', 'Jan', 'Feb', 'Mar', | |
| 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'] | |
| # | |
| svg = d3.select('#ca-vis') | |
| .append('svg') | |
| .attr('width', width + margin.left + margin.right) | |
| .attr('height', height + margin.top + margin.bottom) | |
| .append('g') | |
| .attr('transform', "translate(#{margin.left},#{margin.top})") | |
| # | |
| d3.csv '/fresno_tpcp.csv', (error, raw) -> | |
| waterYears = [] | |
| # | |
| for ndx in [0...raw.length] by 12 | |
| waterYear = { | |
| year: parseInt(raw[ndx]['YYYYMM'].substring(0, 4)) | |
| months: raw.slice(ndx, ndx+12).map (d) -> parseInt(d['TPCP']) | |
| } | |
| y0 = 0 | |
| waterYear.bars = waterYear.months.map (d, ndx) -> | |
| y0prev = y0 | |
| { | |
| y0: y0prev, | |
| y: (y0 += d), | |
| color: colors[ndx], | |
| year: waterYear.year | |
| mon: ndx | |
| } | |
| # Calculate totals and averages | |
| y0 = 0 | |
| waterYear.total = d3.sum(waterYear.months) | |
| avgMonths = [0...12].map (d, ndx) -> | |
| y0prev = y0 | |
| val = d3.mean(waterYears, (d) -> d.months[ndx]) | |
| { val: val, y0: y0prev, y: (y0 += val), color: colors[ndx], mon: ndx } | |
| # Moving averages | |
| if waterYears.length > 2 | |
| waterYear.ma_3 = (waterYear.total + | |
| waterYears[waterYears.length-1].total + | |
| waterYears[waterYears.length-2].total)/3 | |
| if waterYears.length > 4 | |
| waterYear.ma_5 = (waterYear.total + | |
| waterYears[waterYears.length-1].total + | |
| waterYears[waterYears.length-2].total + | |
| waterYears[waterYears.length-3].total + | |
| waterYears[waterYears.length-4].total)/5 | |
| waterYears.push waterYear | |
| # | |
| maxTotal = d3.max(waterYears, (d) -> d.total) | |
| meanTotal = d3.mean(waterYears, (d) -> d.total) | |
| # | |
| y = d3.scale.linear().range( [height, 0] ) | |
| .domain( [0, maxTotal] ) | |
| x = d3.scale.linear().range( [0, width] ) | |
| .domain( [1931, 2014] ) | |
| barWidth = (width / (2015 - 1932)) - 1 | |
| # | |
| xAxis = d3.svg.axis().scale(x) | |
| .orient('bottom') | |
| .tickValues([1941, 1951, 1961, 1971, 1981, 1991, 2001, 2011]) | |
| .tickFormat((d) -> d-1) | |
| yAxis = d3.svg.axis().scale(y) | |
| .ticks(10) | |
| .tickFormat((d) -> (d/100)) | |
| .orient('left') | |
| # | |
| ma_3 = d3.svg.line().x((d) -> x(d.year)) | |
| .y((d) -> y(d.ma_3)) | |
| ma_5 = d3.svg.line().x((d) -> x(d.year)) | |
| .y((d) -> y(d.ma_5)) | |
| # | |
| svg.append('g') | |
| .attr('class', 'x axis') | |
| .attr('transform', "translate(0, #{height})") | |
| .call(xAxis) | |
| svg.append('g') | |
| .attr('class', 'y axis') | |
| .call(yAxis) | |
| # Year groups, month bars | |
| year = svg.selectAll('g.yearBars').data(waterYears) | |
| .enter().append('g') | |
| .attr('class', (d) -> "yearBars #{d.year}") | |
| .attr('opacity', 0.6) | |
| .attr('transform', (d) -> "translate(#{x(d.year) + barWidth/2},0)") | |
| .on('mouseover', (d) -> | |
| d3.select(@).attr('opacity', 1) | |
| d3.select('.typical') | |
| .attr("d", "M 0 #{y(d.bars[4].y)} H #{width + barWidth + 10}") | |
| d3.select('.year-label').text("#{d.year}:") | |
| d3.select('.total-value').text("#{d3.round((d.total/100), 2)}") | |
| d3.selectAll('text.month-value').data(d.months) | |
| .text((d) -> d3.round((d/100), 2)) | |
| ).on('mouseout', (d) -> | |
| d3.select(@).attr('opacity', 0.6) | |
| ) | |
| year.selectAll('rect').data((d) -> d.bars) | |
| .enter().append('rect') | |
| .attr('opacity', (d) -> | |
| return 0.5 if d.year == 2013 and d.mon > 4 | |
| 1 ) | |
| .attr('width', barWidth) | |
| .attr('y', (d) -> y(d.y)) | |
| .attr('height', (d) -> y(d.y0) - y(d.y)) | |
| .attr('fill', (d) -> d.color) | |
| # Average months | |
| meanGroup = svg.append('g') | |
| .attr('class', 'mean-group') | |
| .attr('opacity', 0.6) | |
| .on('mouseover', (d) -> | |
| d3.select(@).attr('opacity', 1) | |
| d3.select('.typical') | |
| .attr("d", "M 0 #{y(721)} H #{width + barWidth + 10}") | |
| d3.select('.year-label').text("Mean:") | |
| d3.select('.total-value').text("#{d3.round((meanTotal/100), 2)}") | |
| d3.selectAll('text.month-value').data(avgMonths) | |
| .text((d) -> d3.round((d.val/100), 2)) | |
| ).on('mouseout', (d) -> | |
| d3.select(@).attr('opacity', 0.6) | |
| ) | |
| .selectAll('rect.avg-month').data(avgMonths) | |
| .enter().append('rect') | |
| .attr('class', (d) -> "avg-month #{d}") | |
| .attr('width', barWidth) | |
| .attr('x', (d) -> width + 10) | |
| .attr('y', (d) -> y(d.y)) | |
| .attr('height', (d) -> y(d.y0) - y(d.y)) | |
| .attr('fill', (d) -> d.color) | |
| # Moving averages, mean line | |
| svg.append("path").attr("class", "mean") | |
| .attr("d", "M 0 #{y(meanTotal)} H #{width + barWidth + 10}") | |
| svg.append("path").attr("class", "current") | |
| .attr("d", "M 0 #{y(283)} H #{width + barWidth + 10}") | |
| svg.append("path").attr("class", "typical") | |
| .attr("d", "M 0 #{y(721)} H #{width + barWidth + 10}") | |
| svg.append("path").datum(waterYears.slice(5, waterYears.length)) | |
| .attr("class", "ma ma-five") | |
| .attr("d", ma_5) | |
| .attr("transform", "translate(#{barWidth},0)") | |
| .on('mouseover', (d) -> | |
| d3.select(@).attr('opacity', 1) | |
| ).on('mouseout', (d) -> | |
| d3.select(@).attr('opacity', 0.8) | |
| ) | |
| svg.append("path").datum(waterYears.slice(3, waterYears.length)) | |
| .attr("class", "ma ma-three") | |
| .attr("d", ma_3) | |
| .attr("transform", "translate(#{barWidth},0)") | |
| .on('mouseover', (d) -> | |
| d3.select(@).attr('opacity', 1) | |
| ).on('mouseout', (d) -> | |
| d3.select(@).attr('opacity', 0.9) | |
| ) | |
| # Axis, mean labels | |
| svg.append("text") | |
| .attr('class', 'x-label') | |
| .attr('text-anchor', 'middle') | |
| .attr('transform', "translate(#{width/2}, #{height + 40})") | |
| .text('Water Year (Oct. 1 of given year to Sept. 31 of next year)') | |
| svg.append("text") | |
| .attr('class', 'y-label') | |
| .attr('text-anchor', 'middle') | |
| .attr('transform', "translate(-30, #{height/2}) rotate(270)") | |
| .text('Precipitation in Inches') | |
| svg.append("text") | |
| .attr('class', 'mean-label') | |
| .attr('text-anchor', 'middle') | |
| .attr('transform', "translate(#{width + 20}, 150) rotate(270)") | |
| .text('Mean values (1931 to 2013)') | |
| # Month/color labels | |
| svg.selectAll('rect.month-rect').data(months) | |
| .enter().append('rect') | |
| .attr('class', (d) -> "month-rect #{d}") | |
| .attr('opacity', 0.6) | |
| .attr('width', width/12) | |
| .attr('x', (d, ndx) -> ndx * width / 12) | |
| .attr('y', (d) -> height + 60) | |
| .attr('height', 20) | |
| .attr('fill', (d, ndx) -> colors[ndx]) | |
| svg.selectAll('text.month-label').data(months) | |
| .enter().append('text') | |
| .attr('class', (d) -> "month-label #{d}") | |
| .attr('text-anchor', 'middle') | |
| .attr('x', (d, ndx) -> (ndx+.5) * width / 12) | |
| .attr('y', (d) -> height + 74) | |
| .text((d) -> d) | |
| if width > 440 | |
| svg.selectAll('text.month-value').data(avgMonths) | |
| .enter().append('text') | |
| .attr('class', (d) -> "month-value #{d}") | |
| .attr('text-anchor', 'middle') | |
| .attr('x', (d, ndx) -> (ndx+.5) * width / 12) | |
| .attr('y', (d) -> height + 94) | |
| .text((d) -> d3.round((d.val/100), 2)) | |
| svg.append('text') | |
| .attr('class', 'total-label') | |
| .attr('text-anchor', 'middle') | |
| .attr('x', (d) -> width + 28) | |
| .attr('y', (d) -> height + 74) | |
| .text('Total') | |
| svg.append('text') | |
| .attr('class', 'year-label') | |
| .attr('text-anchor', 'middle') | |
| .attr('x', (d) -> -30) | |
| .attr('y', (d) -> height + 94) | |
| .text('Mean:') | |
| svg.append('text') | |
| .attr('class', 'total-value') | |
| .attr('text-anchor', 'middle') | |
| .attr('x', (d) -> width + 28) | |
| .attr('y', (d) -> height + 94) | |
| .text((d) -> d3.round((meanTotal/100), 2)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment