mirror of
https://github.com/tomgi/git_stats.git
synced 2024-12-22 13:32:17 +01:00
chart generation splitted to classes
This commit is contained in:
parent
cf27a2967b
commit
a69446bed3
25 changed files with 348 additions and 93 deletions
|
@ -18,7 +18,7 @@ module GitStats
|
|||
end
|
||||
|
||||
def files_by_extension_count
|
||||
@files_by_extension ||= Hash[files_by_extension.map { |ext, files| [ext, files.count] }]
|
||||
@files_by_extension_count ||= Hash[files_by_extension.map { |ext, files| [ext, files.count] }]
|
||||
end
|
||||
|
||||
def lines_by_extension
|
||||
|
|
|
@ -36,6 +36,30 @@ module GitStats
|
|||
commits.map(&:date).minmax
|
||||
end
|
||||
|
||||
def files_count_each_day
|
||||
@files_count_each_day ||= commits_period_range.map { |day|
|
||||
files_count_at day
|
||||
}
|
||||
end
|
||||
|
||||
def files_count_at(day)
|
||||
last_commit_at(day).try(:files_count) || 0
|
||||
end
|
||||
|
||||
def lines_count_each_day
|
||||
@lines_count_each_day ||= commits_period_range.map { |day|
|
||||
lines_count_at day
|
||||
}
|
||||
end
|
||||
|
||||
def lines_count_at(day)
|
||||
last_commit_at(day).try(:lines_count) || 0
|
||||
end
|
||||
|
||||
def last_commit_at(day)
|
||||
commits.reverse.find { |c| c.date < day }
|
||||
end
|
||||
|
||||
def last_commit
|
||||
commits.last
|
||||
end
|
||||
|
@ -105,6 +129,11 @@ module GitStats
|
|||
command_observers.each { |o| o.call(command, result) }
|
||||
end
|
||||
|
||||
def commits_period_range
|
||||
period = commits_period.map(&:midnight)
|
||||
period.first.upto (period.last + 1.day)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
21
lib/git_stats/stats_view/charts/activity_charts.rb
Normal file
21
lib/git_stats/stats_view/charts/activity_charts.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
module GitStats
|
||||
module StatsView
|
||||
module Charts
|
||||
class ActivityCharts
|
||||
def initialize(activity)
|
||||
@activity = activity
|
||||
end
|
||||
|
||||
def activity_by_hour
|
||||
Chart.new do |f|
|
||||
f.type "column"
|
||||
f.title "Commits"
|
||||
f.x_categories (0..23)
|
||||
f.y_text 'Commits'
|
||||
f.series(name: "commits", data: @activity.by_hour.to_key_indexed_array)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
25
lib/git_stats/stats_view/charts/authors_charts.rb
Normal file
25
lib/git_stats/stats_view/charts/authors_charts.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
module GitStats
|
||||
module StatsView
|
||||
module Charts
|
||||
class AuthorsCharts
|
||||
def initialize(authors)
|
||||
@authors = authors
|
||||
end
|
||||
|
||||
def by_authors_wday
|
||||
Chart.new do |c|
|
||||
c.type "column"
|
||||
c.title 'by_wday_authors'
|
||||
c.x_categories Date::ABBR_DAYNAMES
|
||||
c.y_text 'y_text'
|
||||
c.default_legend
|
||||
|
||||
@authors.each do |author|
|
||||
c.series(name: author.email, data: author.activity.by_wday.to_key_indexed_array)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
46
lib/git_stats/stats_view/charts/chart.rb
Normal file
46
lib/git_stats/stats_view/charts/chart.rb
Normal file
|
@ -0,0 +1,46 @@
|
|||
module GitStats
|
||||
module StatsView
|
||||
module Charts
|
||||
class Chart
|
||||
|
||||
def method_missing(name, *args, &block)
|
||||
@chart.send(name, *args, &block)
|
||||
end
|
||||
|
||||
def initialize
|
||||
@chart = LazyHighCharts::HighChart.new('graph')
|
||||
yield self if block_given?
|
||||
end
|
||||
|
||||
def type(type)
|
||||
@chart.chart(type: type)
|
||||
end
|
||||
|
||||
def x_categories(categories)
|
||||
@chart.xAxis(categories: categories)
|
||||
end
|
||||
|
||||
def y_text(text)
|
||||
@chart.yAxis(min: 0, title: {text: text})
|
||||
end
|
||||
|
||||
def title(title)
|
||||
@chart.title(text: title)
|
||||
end
|
||||
|
||||
def default_legend
|
||||
legend(
|
||||
layout: 'vertical',
|
||||
backgroundColor: '#FFFFFF',
|
||||
align: 'left',
|
||||
verticalAlign: 'top',
|
||||
x: 100,
|
||||
y: 70,
|
||||
floating: true,
|
||||
shadow: true
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
30
lib/git_stats/stats_view/charts/charts.rb
Normal file
30
lib/git_stats/stats_view/charts/charts.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
module GitStats
|
||||
module StatsView
|
||||
module Charts
|
||||
class All
|
||||
delegate :files_by_extension, :lines_by_extension, :files_by_date, :lines_by_date, to: :repo_charts
|
||||
delegate :by_authors_wday, to: :authors_charts
|
||||
delegate :activity_by_hour, to: :activity_charts
|
||||
|
||||
attr_reader :repo
|
||||
|
||||
def initialize(repo)
|
||||
@repo = repo
|
||||
end
|
||||
|
||||
def repo_charts
|
||||
@repo_charts ||= Charts::RepoCharts.new(repo)
|
||||
end
|
||||
|
||||
def authors_charts
|
||||
@authors_charts ||= Charts::AuthorsCharts.new(repo.authors)
|
||||
end
|
||||
|
||||
def activity_charts
|
||||
@activity_charts ||= Charts::ActivityCharts.new(repo.activity)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
62
lib/git_stats/stats_view/charts/repo_charts.rb
Normal file
62
lib/git_stats/stats_view/charts/repo_charts.rb
Normal file
|
@ -0,0 +1,62 @@
|
|||
module GitStats
|
||||
module StatsView
|
||||
module Charts
|
||||
class RepoCharts
|
||||
def initialize(repo)
|
||||
@repo = repo
|
||||
end
|
||||
|
||||
def files_by_extension
|
||||
Chart.new do |f|
|
||||
f.type "column"
|
||||
f.title "files by extension"
|
||||
f.x_categories @repo.files_by_extension_count.keys
|
||||
f.y_text 'Commits'
|
||||
f.series(name: "commits", data: @repo.files_by_extension_count.values)
|
||||
end
|
||||
end
|
||||
|
||||
def lines_by_extension
|
||||
Chart.new do |f|
|
||||
f.type "column"
|
||||
f.title "lines by extension"
|
||||
f.x_categories @repo.lines_by_extension.keys
|
||||
f.y_text 'Commits'
|
||||
f.series(name: "commits", data: @repo.lines_by_extension.values)
|
||||
end
|
||||
end
|
||||
|
||||
def files_by_date
|
||||
Chart.new do |f|
|
||||
f.title "Files"
|
||||
f.type "datetime"
|
||||
f.y_text 'Commits'
|
||||
f.series(
|
||||
type: "area",
|
||||
name: "commits",
|
||||
pointInterval: 1.day * 1000,
|
||||
pointStart: @repo.commits.first.date.to_i * 1000,
|
||||
data: @repo.files_count_each_day
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def lines_by_date
|
||||
Chart.new do |f|
|
||||
f.title "Files"
|
||||
f.type "datetime"
|
||||
f.y_text 'Commits'
|
||||
f.series(
|
||||
type: "area",
|
||||
name: "commits",
|
||||
pointInterval: 1.day * 1000,
|
||||
pointStart: @repo.commits.first.date.to_i * 1000,
|
||||
data: @repo.lines_count_each_day
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,100 +3,16 @@ module GitStats
|
|||
class ViewData
|
||||
include ActionView::Helpers::TagHelper
|
||||
include LazyHighCharts::LayoutHelper
|
||||
|
||||
attr_reader :repo
|
||||
|
||||
def initialize(repo)
|
||||
@repo = repo
|
||||
end
|
||||
|
||||
def by_wday
|
||||
@by_wday ||= LazyHighCharts::HighChart.new('graph') do |f|
|
||||
f.chart(type: "column")
|
||||
f.title(text: "Commits")
|
||||
f.xAxis(categories: Date::ABBR_DAYNAMES)
|
||||
f.yAxis(min: 0, title: {text: 'Commits'})
|
||||
f.legend(
|
||||
layout: 'vertical',
|
||||
backgroundColor: '#FFFFFF',
|
||||
align: 'left',
|
||||
verticalAlign: 'top',
|
||||
x: 100,
|
||||
y: 70,
|
||||
floating: true,
|
||||
shadow: true
|
||||
)
|
||||
repo.authors.each do |email, author|
|
||||
f.series(name: email, data: author.activity.by_wday.to_key_indexed_array)
|
||||
end
|
||||
end
|
||||
def charts
|
||||
@charts ||= Charts::All.new(repo)
|
||||
end
|
||||
|
||||
def by_hour
|
||||
@by_hour ||= LazyHighCharts::HighChart.new('graph') do |f|
|
||||
f.chart(type: "column")
|
||||
f.title(text: "Commits")
|
||||
f.xAxis(categories: (0..23))
|
||||
f.yAxis(min: 0, title: {text: 'Commits'})
|
||||
f.series(name: "commits", data: repo.activity.by_hour.to_key_indexed_array)
|
||||
end
|
||||
end
|
||||
|
||||
def files_by_extension
|
||||
@files_by_extension ||= LazyHighCharts::HighChart.new('graph') do |f|
|
||||
f.chart(type: "column")
|
||||
f.title(text: "files by extension")
|
||||
f.xAxis(categories: repo.commits.last.files_by_extension.keys)
|
||||
f.yAxis(min: 0, title: {text: 'Commits'})
|
||||
f.series(name: "commits", data: repo.commits.last.files_by_extension.values.map(&:count))
|
||||
end
|
||||
end
|
||||
|
||||
def lines_by_extension
|
||||
@lines_by_extension ||= LazyHighCharts::HighChart.new('graph') do |f|
|
||||
f.chart(type: "column")
|
||||
f.title(text: "files by extension")
|
||||
f.xAxis(categories: repo.commits.last.lines_by_extension.keys)
|
||||
f.yAxis(min: 0, title: {text: 'Commits'})
|
||||
f.series(name: "commits", data: repo.commits.last.lines_by_extension.values)
|
||||
end
|
||||
end
|
||||
|
||||
def files_by_date
|
||||
@files_by_date ||= LazyHighCharts::HighChart.new('graph') do |f|
|
||||
f.title(text: "Files")
|
||||
f.xAxis(type: "datetime")
|
||||
f.yAxis(min: 0, title: {text: 'Commits'})
|
||||
rcommits = repo.commits.reverse
|
||||
f.series(
|
||||
type: "area",
|
||||
name: "commits",
|
||||
pointInterval: 1.day * 1000,
|
||||
pointStart: repo.commits.first.date.to_i * 1000,
|
||||
data: repo.commits.first.date.midnight.upto((repo.commits.last.date + 1.day).midnight).map { |day|
|
||||
rcommits.find { |c| c.date < day }.files_count rescue 0
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def lines_by_date
|
||||
@lines_by_date ||= LazyHighCharts::HighChart.new('graph') do |f|
|
||||
f.title(text: "Files")
|
||||
f.xAxis(type: "datetime")
|
||||
f.yAxis(min: 0, title: {text: 'Commits'})
|
||||
rcommits = repo.commits.reverse
|
||||
f.series(
|
||||
type: "area",
|
||||
name: "commits",
|
||||
pointInterval: 1.day * 1000,
|
||||
pointStart: repo.commits.first.date.to_i * 1000,
|
||||
data: repo.commits.first.date.midnight.upto((repo.commits.last.date + 1.day).midnight).map { |day|
|
||||
rcommits.find { |c| c.date < day }.lines_count rescue 0
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -30,6 +30,14 @@ describe GitStats::GitData::Repo do
|
|||
repo.files_count.should == 6
|
||||
end
|
||||
|
||||
it 'should count files by date' do
|
||||
repo.files_count_each_day.should == [0, 3, 3, 5, 5, 5, 6, 6, 6]
|
||||
end
|
||||
|
||||
it 'should count lines by date' do
|
||||
repo.lines_count_each_day.should == [0, 11, 11, 1014, 1014, 1014, 1114, 1114, 1114]
|
||||
end
|
||||
|
||||
it 'should count all lines in repo' do
|
||||
repo.lines_count.should == 1114
|
||||
end
|
||||
|
|
21
spec/stats_view/charts/activity_charts_spec.rb
Normal file
21
spec/stats_view/charts/activity_charts_spec.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe GitStats::StatsView::Charts::ActivityCharts do
|
||||
let(:charts) { GitStats::StatsView::Charts::All.new(repo) }
|
||||
|
||||
context 'activity_by_hour chart' do
|
||||
let(:activity) { double(by_hour: double(to_key_indexed_array: 'result')) }
|
||||
let(:repo) { double(activity: activity) }
|
||||
let(:chart) { charts.activity_charts.activity_by_hour }
|
||||
|
||||
it 'should be a column chart' do
|
||||
chart.should be_a GitStats::StatsView::Charts::Chart
|
||||
chart.options[:chart][:type].should == "column"
|
||||
end
|
||||
|
||||
it 'should have 1 data series with activity by_hour' do
|
||||
chart.should have(1).data
|
||||
chart.data.first[:data].should == activity.by_hour.to_key_indexed_array
|
||||
end
|
||||
end
|
||||
end
|
28
spec/stats_view/charts/authors_charts_spec.rb
Normal file
28
spec/stats_view/charts/authors_charts_spec.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe GitStats::StatsView::Charts::AuthorsCharts do
|
||||
let(:charts) { GitStats::StatsView::Charts::All.new(repo) }
|
||||
|
||||
context 'by_authors_wday chart' do
|
||||
let(:authors) { [
|
||||
double(email: "email1", activity: double(by_wday: double(to_key_indexed_array: "result1"))),
|
||||
double(email: "email2", activity: double(by_wday: double(to_key_indexed_array: "result2")))
|
||||
] }
|
||||
let(:repo) { double(authors: authors) }
|
||||
let(:chart) { charts.authors_charts.by_authors_wday }
|
||||
|
||||
it 'should be a column chart' do
|
||||
chart.should be_a GitStats::StatsView::Charts::Chart
|
||||
chart.options[:chart][:type].should == "column"
|
||||
end
|
||||
|
||||
it 'should have 2 data series with authors activity by_wday' do
|
||||
chart.should have(2).data
|
||||
chart.data[0][:data].should == "result1"
|
||||
chart.data[0][:name].should == "email1"
|
||||
|
||||
chart.data[1][:data].should == "result2"
|
||||
chart.data[1][:name].should == "email2"
|
||||
end
|
||||
end
|
||||
end
|
69
spec/stats_view/charts/repo_charts_spec.rb
Normal file
69
spec/stats_view/charts/repo_charts_spec.rb
Normal file
|
@ -0,0 +1,69 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe GitStats::StatsView::Charts::RepoCharts do
|
||||
let(:charts) { GitStats::StatsView::Charts::All.new(repo) }
|
||||
|
||||
context 'files_by_extension chart' do
|
||||
let(:repo) { double(files_by_extension_count: {'.rb' => 5, '.txt' => 3}) }
|
||||
let(:chart) { charts.repo_charts.files_by_extension }
|
||||
|
||||
it 'should be a column chart' do
|
||||
chart.should be_a GitStats::StatsView::Charts::Chart
|
||||
chart.options[:chart][:type].should == "column"
|
||||
end
|
||||
|
||||
it 'should have 1 data series with files_by_extension_count' do
|
||||
chart.should have(1).data
|
||||
chart.options[:xAxis][:categories].should == %w(.rb .txt)
|
||||
chart.data[0][:data].should == [5, 3]
|
||||
end
|
||||
end
|
||||
|
||||
context 'lines_by_extension chart' do
|
||||
let(:repo) { double(lines_by_extension: {'.rb' => 50, '.txt' => 30}) }
|
||||
let(:chart) { charts.repo_charts.lines_by_extension }
|
||||
|
||||
it 'should be a column chart' do
|
||||
chart.should be_a GitStats::StatsView::Charts::Chart
|
||||
chart.options[:chart][:type].should == "column"
|
||||
end
|
||||
|
||||
it 'should have 1 data series with lines_by_extension' do
|
||||
chart.should have(1).data
|
||||
chart.options[:xAxis][:categories].should == %w(.rb .txt)
|
||||
chart.data[0][:data].should == [50, 30]
|
||||
end
|
||||
end
|
||||
|
||||
context 'files_by_date chart' do
|
||||
let(:repo) { double(commits: [double(date: 5)], files_count_each_day: [10, 15, 12, 20]) }
|
||||
let(:chart) { charts.repo_charts.files_by_date }
|
||||
|
||||
it 'should be a datetime chart' do
|
||||
chart.should be_a GitStats::StatsView::Charts::Chart
|
||||
chart.options[:chart][:type].should == "datetime"
|
||||
end
|
||||
|
||||
it 'should have 1 data series with files_by_date' do
|
||||
chart.should have(1).data
|
||||
chart.data[0][:data].should == [10, 15, 12, 20]
|
||||
chart.data[0][:pointStart].should == 5000
|
||||
end
|
||||
end
|
||||
|
||||
context 'lines_by_date chart' do
|
||||
let(:repo) { double(commits: [double(date: 6)], lines_count_each_day: [100, 150, 120, 200]) }
|
||||
let(:chart) { charts.repo_charts.lines_by_date }
|
||||
|
||||
it 'should be a datetime chart' do
|
||||
chart.should be_a GitStats::StatsView::Charts::Chart
|
||||
chart.options[:chart][:type].should == "datetime"
|
||||
end
|
||||
|
||||
it 'should have 1 data series with lines_by_date' do
|
||||
chart.should have(1).data
|
||||
chart.data[0][:data].should == [100, 150, 120, 200]
|
||||
chart.data[0][:pointStart].should == 6000
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1 +1 @@
|
|||
= high_chart("by_hour", by_hour)
|
||||
= high_chart("activity_by_hour", charts.activity_by_hour)
|
|
@ -1 +1 @@
|
|||
= high_chart("by_wday", by_wday)
|
||||
= high_chart("by_authors_wday", charts.by_authors_wday)
|
|
@ -1,2 +1,2 @@
|
|||
= high_chart("files_by_date", files_by_date)
|
||||
= high_chart("files_by_extension", files_by_extension)
|
||||
= high_chart("files_by_date", charts.files_by_date)
|
||||
= high_chart("files_by_extension", charts.files_by_extension)
|
|
@ -1,2 +1,2 @@
|
|||
= high_chart("lines_by_date", lines_by_date)
|
||||
= high_chart("lines_by_extension", lines_by_extension)
|
||||
= high_chart("lines_by_date", charts.lines_by_date)
|
||||
= high_chart("lines_by_extension", charts.lines_by_extension)
|
Loading…
Reference in a new issue