diff --git a/app/assets/javascripts/toggle_chart.js b/app/assets/javascripts/toggle_chart.js new file mode 100644 index 000000000..b415619c7 --- /dev/null +++ b/app/assets/javascripts/toggle_chart.js @@ -0,0 +1,20 @@ +var TPS = TPS || {}; + +TPS.toggleChart = function(event, chartClass) { + var nextSelectorItem = $(event.target), + nextChart = $(chartClass), + nextChartId = nextChart.children().first().attr('id'), + currentSelectorItem = nextSelectorItem.parent().find(".segmented-control-item-active"), + currentChart = nextSelectorItem.parent().parent().find(".chart:not(.hidden)"); + + // Change the current selector and the next selector states + currentSelectorItem.toggleClass("segmented-control-item-active"); + nextSelectorItem.toggleClass("segmented-control-item-active"); + + // Hide the currently shown chart and show the new one + currentChart.toggleClass("hidden"); + nextChart.toggleClass("hidden"); + + // Reflow needed, see https://github.com/highcharts/highcharts/issues/1979 + Chartkick.charts[nextChartId].getChartObject().reflow(); +} diff --git a/app/assets/stylesheets/stats.scss b/app/assets/stylesheets/stats.scss index e5579254a..f7a33df32 100644 --- a/app/assets/stylesheets/stats.scss +++ b/app/assets/stylesheets/stats.scss @@ -1,6 +1,8 @@ @import "card"; $dark-grey: #333333; +$blue: rgba(61, 149, 236, 1); +$blue-hover: rgba(61, 149, 236, 0.8); $default-space: 15px; @@ -42,9 +44,53 @@ $stat-card-half-horizontal-spacing: 4 * $default-space; .stat-card-title { color: $dark-grey; - margin-top: -2px; font-size: 26px; font-weight: 500; + width: 200px; +} + +$segmented-control-margin-top: $default-space; +.segmented-control { + border-radius: 36px; + height: 36px; + line-height: 36px; + font-size: 0; + padding: 0; + display: inline-block; + margin-top: $segmented-control-margin-top; +} + +$segmented-control-item-horizontal-padding: $default-space; +$segmented-control-item-border-radius: 2 * $default-space; +.segmented-control-item { + color: $blue; + display: inline-block; + font-size: 15px; + border: 2px solid $blue; + margin-right: -2px; + padding-left: $segmented-control-item-horizontal-padding; + padding-right: $segmented-control-item-horizontal-padding; + color: $blue; + + &:first-of-type { + border-radius: $segmented-control-item-border-radius 0px 0px $segmented-control-item-border-radius; + } + + &:last-of-type { + border-radius: 0px $segmented-control-item-border-radius $segmented-control-item-border-radius 0px; + margin-right: 0; + } + + &:hover { + background-color: $blue-hover; + color: white; + cursor: pointer; + } +} + +.segmented-control-item-active { + background-color: $blue; + color: white; } .chart-container { diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 56ca12b6e..b099b2a17 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -6,6 +6,9 @@ class StatsController < ApplicationController @procedures_30_days_flow = thirty_days_flow_hash(procedures) @dossiers_30_days_flow = thirty_days_flow_hash(dossiers) + + @procedures_cumulative = cumulative_hash(procedures) + @dossiers_cumulative = cumulative_hash(dossiers) end private @@ -28,4 +31,15 @@ class StatsController < ApplicationController end h end + + def cumulative_hash(association) + sum = 0 + association + .group("DATE_TRUNC('month', created_at)") + .count + .to_a + .sort{ |x, y| x[0] <=> y[0] } + .map { |x, y| { x => (sum += y)} } + .reduce({}, :merge) + end end diff --git a/app/views/stats/index.html.haml b/app/views/stats/index.html.haml index 5fe3fca0d..88d5b4d1b 100644 --- a/app/views/stats/index.html.haml +++ b/app/views/stats/index.html.haml @@ -7,16 +7,36 @@ .stat-cards .stat-card.stat-card-half.pull-left - %span.stat-card-title.pull-left Procédures + %ul.segmented-control.pull-right + %li.segmented-control-item.segmented-control-item-active{ :onclick => "TPS.toggleChart(event, '.cumulative-procedures-chart');" } + Cumul + %li.segmented-control-item{ :onclick => "TPS.toggleChart(event, '.flux-procedures-chart');" } + Flux (30 jours) + %span.stat-card-title.pull-left Démarches dématérialisées + .clearfix + .chart-container - .chart.flux-procedures-chart + .chart.cumulative-procedures-chart + = area_chart @procedures_cumulative, + :colors => ["rgba(61, 149, 236, 1)"] + .chart.flux-procedures-chart.hidden = line_chart @procedures_30_days_flow, :colors => ["rgba(61, 149, 236, 1)"] .stat-card.stat-card-half.pull-left - %span.stat-card-title.pull-left Dossiers + %ul.segmented-control.pull-right + %li.segmented-control-item.segmented-control-item-active{ :onclick => "TPS.toggleChart(event, '.cumulative-dossiers-chart');" } + Cumul + %li.segmented-control-item{ :onclick => "TPS.toggleChart(event, '.flux-dossiers-chart');" } + Flux (30 jours) + %span.stat-card-title.pull-left Dossiers déposés + .clearfix + .chart-container - .chart.flux-dossiers-chart + .chart.cumulative-dossiers-chart + = area_chart @dossiers_cumulative, + :colors => ["rgba(61, 149, 236, 1)"] + .chart.flux-dossiers-chart.hidden = line_chart @dossiers_30_days_flow, :colors => ["rgba(61, 149, 236, 1)"] diff --git a/spec/controllers/stats_controller_spec.rb b/spec/controllers/stats_controller_spec.rb index f555a402f..bcaaeb409 100644 --- a/spec/controllers/stats_controller_spec.rb +++ b/spec/controllers/stats_controller_spec.rb @@ -23,4 +23,21 @@ describe StatsController, type: :controller do it { expect(subject).to eq(@expected_hash) } end + + describe '#cumulative_hash' do + before do + FactoryGirl.create(:procedure, :created_at => 45.days.ago) + FactoryGirl.create(:procedure, :created_at => 15.days.ago) + FactoryGirl.create(:procedure, :created_at => 15.days.ago) + end + + let (:association) { Procedure.all } + + subject { StatsController.new.send(:cumulative_hash, association) } + + it { expect(subject).to eq({ + 45.days.ago.beginning_of_month => 1, + 15.days.ago.beginning_of_month => 3 + }) } + end end