diff --git a/app/helpers/chart_helper.rb b/app/helpers/chart_helper.rb new file mode 100644 index 0000000..9f610e1 --- /dev/null +++ b/app/helpers/chart_helper.rb @@ -0,0 +1,15 @@ +module ChartHelper + def baas_chart(id, chart_options) + html = <<-HTML + + HTML + html.html_safe + end +end diff --git a/lib/chart.rb b/lib/chart.rb new file mode 100644 index 0000000..29c58c0 --- /dev/null +++ b/lib/chart.rb @@ -0,0 +1,57 @@ +class Chart < Hash + class Pie + attr_accessor :chart_opts + + def initialize(series, opts) + @chart_opts = { + chart: { + plotBackgroundColor: nil, + plotBorderWidth: nil, + plotShadow: false, + type: 'pie' + }, + title: { text: opts[:title] }, + tooltip: { pointFormat: '{series.name}: {point.percentage:.1f}%' }, + plotOptions: { + pie: { + allowPointSelect: true, + cursor: 'pointer', + dataLabels: { enabled: false }, + showInLegend: true + } + }, + series: [ + { + name: opts[:name], + colorByPoint: true, + data: series + } + ] + } + end + end + + class ColumnTwoAxis + attr_accessor :chart_opts + + def initialize(series, opts) + @chart_opts = { + chart: { type: 'column' }, + title: { text: opts[:title] }, + xAxis: { + categories: opts[:categories], + crosshair: true + }, + yAxis: opts[:yaxis], + tooltip: { shared: true }, + plotOptions: { + column: { + pointPadding: 0.2, + borderWidth: 0 + } + }, + series: series + } + end + end +end diff --git a/lib/chart_generator.rb b/lib/chart_generator.rb new file mode 100644 index 0000000..54dcdf2 --- /dev/null +++ b/lib/chart_generator.rb @@ -0,0 +1,78 @@ +module ChartGenerator + extend self + + def job_statuses(clients, days_ago) + result = { + 'Running' => { y: 0, color: '#D9EDF7' }, + 'Completed' => { y: 0, color: '#DFF0D8' }, + 'Canceled' => { y: 0, color: '#999999' }, + 'Failed' => { y: 0, color: '#FFDEDE' }, + 'Waiting' => { y: 0, color: '#FCF8E3' }, + } + + Job.where(ClientId: clients). + where('StartTime > :time OR SchedTime > :time', time: days_ago.days.ago). + group(:JobStatus).count.each do |k,v| + if k == 'R' + result['Running'][:y] += v + elsif k == 'T' + result['Completed'][:y] += v + elsif ['f', 'E'].include? k + result['Failed'][:y] += v + elsif k == 'A' + result['Canceled'][:y] += v + elsif ["C","F", "M", "S", "c", "d", "j", "m", "p", "s", "t"].include? k + result['Waiting'][:y] += v + end + end + + series = result.map { |k,v| { name: "#{v[:y]} #{k}", y: v[:y], color: v[:color] } } + + Chart::Pie.new( + series, + title: 'Job Status', + name: 'Status' + ).chart_opts.to_json + end + + def job_stats(clients, days_ago) + days = days_ago.downto(0).map {|x| I18n.l(x.days.ago.to_date, format: :short) } + year_days = days_ago.downto(0).map {|x| x.days.ago.yday } + + yaxis = [ + { + title: { text: 'Bytes Size' }, + labels: { format: '{value} MB' }, + opposite: true + }, + { + title: { text: 'Files Count' }, + labels: { format: '{value} Files' } + } + ] + + files_data = year_days.map { |x| [x, 0] }.to_h + bytes_data = year_days.map { |x| [x, 0] }.to_h + + Job.where(ClientId: clients, JobStatus: 'T'). + where(EndTime: days_ago.days.ago.end_of_day..Time.now.end_of_day).each do |job| + files_data.merge!(Hash[job.end_time.yday, job.job_files.to_i]) do |_, old_v, new_v| + old_v + new_v + end + + bytes_data.merge!(Hash[job.end_time.yday, (job.job_bytes.to_f / 1048576).round(1)]) do |_, old_v, new_v| + old_v + new_v + end + end + + files = { name: 'Files Count', data: files_data.values, yAxis: 1, tooltip: { valueSuffix: '' } } + bytes = { name: 'Bytes Size', data: bytes_data.values, yAxis: 0, tooltip: { valueSuffix: 'MB'} } + + Chart::ColumnTwoAxis.new( + [files, bytes], + title: 'Job Stats', + categories: days, + yaxis: yaxis + ).chart_opts.to_json + end +end