app/assets/javascripts/plasticine/column.coffee in plasticine-1.1.1 vs app/assets/javascripts/plasticine/column.coffee in plasticine-1.2.0

- old
+ new

@@ -1,43 +1,38 @@ class @PlasticineColumn constructor: (@holder) -> @holder = $('.plasticine-column') - @setLocale() + PlasticineHelpers.setLocale() @drawTooltip() - width = @holderWidth() - height = @holder.height() - - @xScale = d3.scale.ordinal() + @xScale = d3.scaleBand() @setXScaleRange() - @yScale = d3.scale.linear().range([height,0]) + @yScale = d3.scaleLinear().range([@holder.height(),0]) @setXAxis() @setYAxis() - @svg = d3.select("##{@holder.attr('id')}").append('svg').style('width', width).style('height', height).append('g') + @svg = d3.select("##{@holder.attr('id')}").append('svg').style('width', @holderWidth()).style('height', @holder.height()).append('g') + d3.json(@holder.data('url')).then (data) => @build(data) - d3.json @holder.data('url'), (data) => @build(data) - build: (data) -> columnIds = data.columns[0].y_values.map (d,i) -> "col#{i+1}" + colGroup = d3.scaleBand().range(columnIds).domain(columnIds) - @colGroup = d3.scale.ordinal().range(columnIds).domain(columnIds) - @xAxisFormat = data.axis_x_format @yAxisFormat = data.axis_y_format @yAxisTickCount = data.axis_y_tick_count @quarterStartMonth = Number(data.quarter_start_month) data.columns.forEach (d) => y0 = 0 - d.yValues = @colGroup.domain().map (name,i) => { name: name, y0: y0, y1: y0 += @formatValue(d.y_values[i], @yAxisFormat) } + d.yValues = colGroup.domain().map (name,i) => { name: name, y0: y0, y1: y0 += PlasticineHelpers.parseValue(d.y_values[i], @yAxisFormat) } d.total = d.yValues[d.yValues.length - 1].y1 - d.x = @formatValue(d.x_value, @xAxisFormat) + d.x = PlasticineHelpers.parseValue(d.x_value, @xAxisFormat) @xScale.domain data.columns.map( (d) -> d.x ) @yScale.domain [0, d3.max(data.columns, (d) => d.total * @holder.data('y-spacing-ratio'))] @drawYAxis() @@ -66,73 +61,44 @@ group.selectAll("g").filter((d) -> d).classed("minor", true) @refreshYAxis() - formatValue: (value, format) -> - switch format - when 'date' then new Date(value) - else value + hideTooltip: () -> @holder.find('.tooltip').hide() holderWidth: () -> @holder.width() - refreshXAxis: () -> - @setXAxis() - @svg.select('.x.axis').call @xAxis - - - refreshYAxis: () -> - @setYAxis() - @svg.select('.y.axis').call @yAxis - - - setXAxis: () -> - @xAxis = d3.svg.axis().scale(@xScale).orient('bottom') - @xAxis.tickSize -@holder.height() - - switch @xAxisFormat - when 'date' then @xAxis.tickFormat(d3.time.format('%b')) - when 'quarter' then @xAxis.tickFormat (d) => @toQuarter(d) - when 'year' then @xAxis.tickFormat (d) => @toYear(d) - when 'money' then @xAxis.tickFormat (d) => @toPrice(d) - - - setYAxis: () -> - @yAxis = d3.svg.axis().scale(@yScale).orient("left"); - @yAxis.tickSize -@holderWidth() - @yAxis.ticks @yAxisTickCount - - switch @yAxisFormat - when 'date' then @yAxis.tickFormat(d3.time.format('%b')) - when 'money' then @yAxis.tickFormat (d) => @toPrice(d) - - hideTooltip: () -> @holder.find('.tooltip').hide() - refreshColumns: () -> self = this $('g.column').remove() - @columns.enter().append('g') - .attr('class', 'column') + @columns.enter().append("g").attr('class', 'column') .attr('data-x-val', (d) -> d.x_value) - .attr('transform', (d) => 'translate(' + @xScale(d.x) + ',0)') .attr('x', (d) => @xScale(d.x)) + .attr('transform', (d) => 'translate(' + @xScale(d.x) + ',0)') .on("mouseover", (d) -> self.showTooltip(@, d)) .on("mouseout", (d) -> self.hideTooltip(@)) - @columns.exit().remove() - @columns.selectAll('rect') - .data((d) -> d.yValues) - .enter() - .append('rect') - .attr('width', @xScale.rangeBand()) - .attr('y', (d) => @yScale d.y1) - .attr('height', (d) => @yScale(d.y0) - @yScale(d.y1)) - .attr('class', (d) => @colGroup d.name) + .selectAll("rect").data((d) => d.yValues).enter() + .append("rect") + .attr('class', (d,i) => "col#{i+1}") + .attr("width", @xScale.bandwidth()) + .attr("y", (d) => @yScale d.y1) + .attr("height", (d) => @yScale(d.y0) - @yScale(d.y1)) + refreshXAxis: () -> + @setXAxis() + @svg.select('.x.axis').call @xAxis + + + refreshYAxis: () -> + @setYAxis() + @svg.select('.y.axis').call @yAxis + + resizeX: () -> d3.select(@svg.node().parentNode).style('width', @holderWidth() + 'px') @setXScaleRange() @@ -140,39 +106,40 @@ @refreshYAxis() @hideTooltip() @refreshColumns() - setLocale: () -> - french = d3.locale( - "decimal": ",", - "thousands": " ", - "grouping": [3], - "currency": ["$", ""], - "dateTime": "%a %b %e %X %Y", - "date": "%d-%m-%Y", - "time": "%H:%M:%S", - "periods": ["AM", "PM"], - "days": ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"], - "shortDays": ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"], - "months": ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"], - "shortMonths": ["Jan", "Fev", "Mar", "Avr", "Mai", "Jun", "Jul", "Aou", "Sep", "Oct", "Nov", "Dec"] - ) + setXAxis: () -> + @xAxis = d3.axisBottom(@xScale) + @xAxis.tickSize -@holder.height() - d3.time.format = french.timeFormat - d3.format = french.numberFormat + switch @xAxisFormat + when 'date' then @xAxis.tickFormat(d3.timeFormat('%b')) + when 'quarter' then @xAxis.tickFormat (d) => PlasticineHelpers.toQuarter(d, @quarterStartMonth) + when 'year' then @xAxis.tickFormat (d) => PlasticineHelpers.toYear(d, @quarterStartMonth) + when 'money' then @xAxis.tickFormat (d) => PlasticineHelpers.toPrice(d) setXScaleRange: () -> columnsMargin = @holder.data('columns-margin') columnsLeftPadding = @holder.data('columns-left-padding') columnsRightPadding = @holder.data('columns-right-padding') width = @holderWidth() + + @xScale = @xScale.rangeRound([columnsLeftPadding, width - columnsRightPadding]).padding(columnsMargin); - @xScale = @xScale.rangeRoundBands([columnsLeftPadding, width - columnsRightPadding], columnsMargin, 0) + setYAxis: () -> + @yAxis = d3.axisLeft(@yScale) + @yAxis.tickSize -@holderWidth() + @yAxis.ticks @yAxisTickCount + switch @yAxisFormat + when 'date' then @yAxis.tickFormat(d3.timeFormat('%b')) + when 'money' then @yAxis.tickFormat (d) => PlasticineHelpers.toPrice(d) + + showTooltip: (bar, data) -> barNode = $($(bar).find('rect:last-child')[0]) barX = $(bar).attr('x') barY = barNode.attr('y') @@ -188,56 +155,5 @@ d3.select(".tooltip") .style("left", tooltipX + "px") .style("top", (yPosition - tooltip.outerHeight()) + "px") - - toPrice: (amount) -> - if amount is 0 - price = "0" - else - price = String(amount)[0..-3] - price = "0" if price is "" - - price = switch price.length - when 4 then [price.slice(0, 1), ' ', price.slice(1)].join('') - when 5 then [price.slice(0, 2), ' ', price.slice(2)].join('') - when 6 then [price.slice(0, 3), ' ', price.slice(3)].join('') - when 7 then [price.slice(0, 4), ' ', price.slice(4)].join('') - else price - - # Show decimals - #price += ',' + String(amount).slice(-2) - - price += '$' - - - toQuarter: (strDate) -> - date = new Date(strDate + 'T12:00:00') - - month = date.getMonth() + 1 - monthEquiv = (month + (13 - @quarterStartMonth)) % 12 - - value = switch - when monthEquiv <= 3 then 'Q1' - when monthEquiv <= 6 then 'Q2' - when monthEquiv <= 9 then 'Q3' - else 'Q4' - - year = Number(date.getFullYear()) - - if (value is "Q1" and @quarterStartMonth >= 10) or ((value is "Q1" or value is "Q2") and @quarterStartMonth >= 7 and @quarterStartMonth < 10) - year += 1 - - value += " #{year}" - value - - - toYear: (strDate) -> - date = new Date(strDate + 'T12:00:00') - - year = Number(date.getFullYear()) - - if @quarterStartMonth >= 7 and (date.getMonth() + 1) >= 7 - year += 1 - - year