diff --git a/app/assets/javascripts/stats.js.coffee b/app/assets/javascripts/stats.js.coffee
new file mode 100644
index 000000000..7fcdfb00a
--- /dev/null
+++ b/app/assets/javascripts/stats.js.coffee
@@ -0,0 +1,11 @@
+# Helper for generate C3.js graphs
+#----------------------------------------------------------------------
+
+buildGraph = (el) ->
+ url = $(el).data 'graph'
+ conf = bindto: el, data: {x: 'x', url: url, mimeType: 'json'}, axis: { x: {type: 'timeseries',tick: { format: '%Y-%m-%d' } }}
+ graph = c3.generate conf
+
+App.Stats =
+ initialize: ->
+ buildGraph(g) for g in $("[data-graph]")
diff --git a/app/controllers/api/stats_controller.rb b/app/controllers/api/stats_controller.rb
index 26fb373fb..d44262b45 100644
--- a/app/controllers/api/stats_controller.rb
+++ b/app/controllers/api/stats_controller.rb
@@ -1,10 +1,22 @@
class Api::StatsController < Api::ApiController
def show
- event_type = params[:event]
- unless event_type.present?
+ unless params[:events].present? || params[:visits].present?
return render json: {}, status: :bad_request
end
- render json: Ahoy::Event.where(name: event_type).group_by_day(:time).count
+ ds = Ahoy::DataSource.new
+
+ if params[:events].present?
+ event_types = params[:events].split ','
+ event_types.each do |event|
+ ds.add event.titleize, Ahoy::Event.where(name: event).group_by_day(:time).count
+ end
+ end
+
+ if params[:visits].present?
+ ds.add "Visits", Visit.group_by_day(:started_at).count
+ end
+
+ render json: ds.build
end
end
diff --git a/app/helpers/stats_helper.rb b/app/helpers/stats_helper.rb
new file mode 100644
index 000000000..e517767e3
--- /dev/null
+++ b/app/helpers/stats_helper.rb
@@ -0,0 +1,16 @@
+module StatsHelper
+ def events_chart_tag(events, opt={})
+ events = events.join(',') if events.is_a? Array
+ opt[:data] ||= {}
+ opt[:data][:graph] = api_stats_path(events: events)
+ content_tag :div, "", opt
+ end
+
+ def visits_chart_tag(opt={})
+ events = events.join(',') if events.is_a? Array
+ opt[:data] ||= {}
+ opt[:data][:graph] = api_stats_path(visits: true)
+ content_tag :div, "", opt
+ end
+
+end
diff --git a/app/views/stats/show.html.erb b/app/views/stats/show.html.erb
index 0671b15ad..033d2714d 100644
--- a/app/views/stats/show.html.erb
+++ b/app/views/stats/show.html.erb
@@ -1,9 +1,13 @@
Stats
Visits
-<%= line_chart Visit.group_by_day(:started_at).count %>
+<%= visits_chart_tag id: "visits" %>
+
+Combined
+<%= events_chart_tag @event_types, id: 'combined' %>
+
<% @event_types.each do |event_type| %>
<%= event_type.titleize %>
- <%= line_chart api_stats_path(event: event_type) %>
+ <%= events_chart_tag event_type %>
<% end %>
diff --git a/spec/controllers/api/stats_controller_spec.rb b/spec/controllers/api/stats_controller_spec.rb
index e2f4cd02b..9fd3ebd47 100644
--- a/spec/controllers/api/stats_controller_spec.rb
+++ b/spec/controllers/api/stats_controller_spec.rb
@@ -8,36 +8,89 @@ describe Api::StatsController do
describe 'GET index' do
let(:user) { create :user }
- context 'event not present' do
+ context 'events or visits not present' do
it 'should respond with bad_request' do
sign_in user
get :show
+ expect(response).to_not be_ok
expect(response.status).to eq 400
end
end
- context 'event present' do
- it 'should return event counts' do
- time_1 = DateTime.yesterday.to_datetime
- time_2 = DateTime.now
+ context 'events present' do
+ before :each do
+ time_1 = DateTime.parse("2015-01-01")
+ time_2 = DateTime.parse("2015-01-02")
+ time_3 = DateTime.parse("2015-01-03")
- event_1 = create :ahoy_event, name: 'foo', time: time_1
- event_2 = create :ahoy_event, name: 'foo', time: time_1
- event_3 = create :ahoy_event, name: 'foo', time: time_2
- event_4 = create :ahoy_event, name: 'bar'
+ create :ahoy_event, name: 'foo', time: time_1
+ create :ahoy_event, name: 'foo', time: time_1
+ create :ahoy_event, name: 'foo', time: time_2
+ create :ahoy_event, name: 'bar', time: time_1
+ create :ahoy_event, name: 'bar', time: time_3
+ create :ahoy_event, name: 'bar', time: time_3
+ end
+ it 'should return single events formated for working with c3.js' do
sign_in user
- get :show, event: 'foo'
+ get :show, events: 'foo'
expect(response).to be_ok
data = JSON.parse(response.body)
- dates = data.keys
+ expect(data).to eq "x"=>["2015-01-01", "2015-01-02"], "Foo"=>[2, 1]
+ end
- expect(DateTime.parse dates.first).to eq time_1.utc.beginning_of_day
- expect(DateTime.parse dates.last).to eq time_2.utc.beginning_of_day
- expect(data[dates.first]).to eq 2
- expect(data[dates.last]).to eq 1
+ it 'should return combined comma separated events formated for working with c3.js' do
+ sign_in user
+ get :show, events: 'foo,bar'
+
+ expect(response).to be_ok
+
+ data = JSON.parse(response.body)
+ expect(data).to eq "x"=>["2015-01-01", "2015-01-02", "2015-01-03"], "Foo"=>[2, 1, 0], "Bar"=>[1, 0, 2]
+ end
+ end
+
+ context 'visits present' do
+ it 'should return visits formated for working with c3.js' do
+ time_1 = DateTime.parse("2015-01-01")
+ time_2 = DateTime.parse("2015-01-02")
+
+ create :visit, started_at: time_1
+ create :visit, started_at: time_1
+ create :visit, started_at: time_2
+
+ sign_in user
+ get :show, visits: true
+
+ expect(response).to be_ok
+
+ data = JSON.parse(response.body)
+ expect(data).to eq "x"=>["2015-01-01", "2015-01-02"], "Visits"=>[2, 1]
+ end
+ end
+
+ context 'visits and events present' do
+ it 'should return combined events and visits formated for working with c3.js' do
+ time_1 = DateTime.parse("2015-01-01")
+ time_2 = DateTime.parse("2015-01-02")
+
+ create :ahoy_event, name: 'foo', time: time_1
+ create :ahoy_event, name: 'foo', time: time_2
+ create :ahoy_event, name: 'foo', time: time_2
+
+ create :visit, started_at: time_1
+ create :visit, started_at: time_1
+ create :visit, started_at: time_2
+
+ sign_in user
+ get :show, events: 'foo', visits: true
+
+ expect(response).to be_ok
+
+ data = JSON.parse(response.body)
+ expect(data).to eq "x"=>["2015-01-01", "2015-01-02"], "Foo"=>[1, 2], "Visits"=>[2, 1]
end
end
end
diff --git a/spec/factories.rb b/spec/factories.rb
index 18b65b7f3..cf653a7cf 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -36,4 +36,9 @@ FactoryGirl.define do
time DateTime.now
sequence(:name) {|n| "Event #{n} type"}
end
+
+ factory :visit do
+ id { SecureRandom.uuid }
+ started_at DateTime.now
+ end
end