From 3e3acdf90d39a3bf44017680f8665f002012bacf Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Tue, 28 Apr 2015 18:22:55 +0200 Subject: [PATCH 01/21] Reporting charts: allow creating concrete number charts. --- .../report_controller/reports/editor.rb | 57 ++++++++++++++----- app/helpers/report_helper.rb | 12 ++++ app/views/report/_form_chart.html.haml | 22 +++++++ lib/charting/jqplot.rb | 14 ++--- lib/report_formatter/chart_common.rb | 46 ++++++++++++++- lib/report_formatter/jqplot.rb | 23 ++++++++ 6 files changed, 150 insertions(+), 24 deletions(-) diff --git a/app/controllers/report_controller/reports/editor.rb b/app/controllers/report_controller/reports/editor.rb index f8337264490..5f6b4492177 100644 --- a/app/controllers/report_controller/reports/editor.rb +++ b/app/controllers/report_controller/reports/editor.rb @@ -321,6 +321,8 @@ def reset_report_col_fields @edit[:new][:filter_string] = nil @edit[:new][:categories] = [] @edit[:new][:graph_type] = nil # Clear graph field + @edit[:new][:chart_mode] = nil + @edit[:new][:chart_column] = nil @edit[:new][:perf_trend_col] = nil @edit[:new][:perf_trend_db] = nil @edit[:new][:perf_trend_pct1] = nil @@ -661,21 +663,39 @@ def gfv_charts if params[:chosen_graph] == "" @edit[:new][:graph_type] = nil # Reset other setting to initial settings if choosing - @edit[:new][:graph_count] = @edit[:current][:graph_count] - @edit[:new][:graph_other] = @edit[:current][:graph_other] + @edit[:new][:graph_count] = @edit[:current][:graph_count] + @edit[:new][:graph_other] = @edit[:current][:graph_other] + @edit[:new][:chart_mode] = @edit[:current][:chart_mode] + @edit[:new][:chart_column] = @edit[:current][:chart_column] else - @edit[:new][:graph_other] = true if @edit[:new][:graph_type].nil? # Reset other setting if choosing first chart - @edit[:new][:graph_type] = params[:chosen_graph] # Save graph type - @edit[:new][:graph_count] ||= GRAPH_MAX_COUNT # Reset graph count, if not set + @edit[:new][:graph_other] = true if @edit[:new][:graph_type].nil? # Reset other setting if choosing first chart + @edit[:new][:graph_type] = params[:chosen_graph] # Save graph type + @edit[:new][:graph_count] ||= GRAPH_MAX_COUNT # Reset graph count, if not set + @edit[:new][:chart_mode] ||= 'counts' + @edit[:new][:chart_column] ||= '' end @refresh_div = "chart_div" @refresh_partial = "form_chart" end + + if params[:chart_mode] && params[:chart_mode] != @edit[:new][:chart_mode] + @edit[:new][:chart_mode] = params[:chart_mode] + @refresh_div = "chart_sample_div" + @refresh_partial = "form_chart_sample" + end + + if params[:chart_column] && params[:chart_column] != @edit[:new][:chart_column] + @edit[:new][:chart_column] = params[:chart_column] + @refresh_div = "chart_sample_div" + @refresh_partial = "form_chart_sample" + end + if params[:chosen_count] && params[:chosen_count] != @edit[:new][:graph_count] @edit[:new][:graph_count] = params[:chosen_count] @refresh_div = "chart_sample_div" @refresh_partial = "form_chart_sample" end + if params[:chosen_other] # If a chart is showing, set the other setting based on check box present chosen = (params[:chosen_other].to_s == "1") if @edit[:new][:graph_other] != chosen @@ -1108,10 +1128,13 @@ def set_record_vars(rpt) else rpt.dims = @edit[:new][:sortby2] == NOTHING_STRING ? 1 : 2 # Set dims to 1 or 2 based on presence of sortby2 end - rpt.graph = Hash.new - rpt.graph[:type] = @edit[:new][:graph_type] - rpt.graph[:count] = @edit[:new][:graph_count] - rpt.graph[:other] = @edit[:new][:graph_other] + rpt.graph = { + :type => @edit[:new][:graph_type], + :mode => @edit[:new][:chart_mode], + :column => @edit[:new][:chart_column], + :count => @edit[:new][:graph_count], + :other => @edit[:new][:graph_other], + } end # Set the conditions field (expression) @@ -1378,13 +1401,17 @@ def set_form_vars # @edit[:new][:graph] = @rpt.graph # Replaced above line to handle new graph settings Hash if @rpt.graph.is_a?(Hash) - @edit[:new][:graph_type] = @rpt.graph[:type] - @edit[:new][:graph_count] = @rpt.graph[:count] - @edit[:new][:graph_other] = @rpt.graph[:other] ? @rpt.graph[:other] : false + @edit[:new][:graph_type] = @rpt.graph[:type] + @edit[:new][:graph_count] = @rpt.graph[:count] + @edit[:new][:chart_mode] = @rpt.graph[:mode] + @edit[:new][:chart_column] = @rpt.graph[:column] + @edit[:new][:graph_other] = @rpt.graph[:other] ? @rpt.graph[:other] : false else - @edit[:new][:graph_type] = @rpt.graph - @edit[:new][:graph_count] = GRAPH_MAX_COUNT - @edit[:new][:graph_other] = true + @edit[:new][:graph_type] = @rpt.graph + @edit[:new][:graph_count] = GRAPH_MAX_COUNT + @edit[:new][:chart_mode] = 'counts' + @edit[:new][:chart_column] = '' + @edit[:new][:graph_other] = true end @edit[:new][:dims] = @rpt.dims diff --git a/app/helpers/report_helper.rb b/app/helpers/report_helper.rb index b2ebb7e2b07..77f0bace24c 100644 --- a/app/helpers/report_helper.rb +++ b/app/helpers/report_helper.rb @@ -25,4 +25,16 @@ def visibility_options(widget) _("By %{typ}: %{values}") % {:typ => typ.to_s.titleize, :values => values.join(',')} end end + + + def chart_fields_options + # @edit[:pivot_cols] => {"Vm-mem_cpu"=>[:avg, :total]} + options = [] + @edit[:pivot_cols].each do |field, agreg| + agreg.each do |fun| + options << ["#{field} (#{fun.to_s.titleize})", "#{field}:#{fun}"] + end + end + options + end end diff --git a/app/views/report/_form_chart.html.haml b/app/views/report/_form_chart.html.haml index 0c2e85e8f58..73bd375ddc8 100644 --- a/app/views/report/_form_chart.html.haml +++ b/app/views/report/_form_chart.html.haml @@ -15,6 +15,28 @@ "data-miq_sparkle_off" => true, "data-miq_observe" => {:url => url}.to_json) - unless @edit[:new][:graph_type].blank? + %tr + %td.key + = _('Chart mode') + %td + = select_tag('chart_mode', + options_for_select([['Counts', 'counts'], ['Values', 'values']], @edit[:new][:chart_mode]), + :multiple => false, + :class => "widthed", + "data-miq_sparkle_on" => true, + "data-miq_sparkle_off" => true, + "data-miq_observe" => {:url => url}.to_json) + %tr + %td.key + = _('Data column') + %td + = select_tag('chart_column', + options_for_select(chart_fields_options, @edit[:new][:chart_column]), + :multiple => false, + :class => "widthed", + "data-miq_sparkle_on" => true, + "data-miq_sparkle_off" => true, + "data-miq_observe" => {:url => url}.to_json) %tr %td.key = _('Top values to show') diff --git a/lib/charting/jqplot.rb b/lib/charting/jqplot.rb index b4066f0b35c..237153476d6 100644 --- a/lib/charting/jqplot.rb +++ b/lib/charting/jqplot.rb @@ -40,7 +40,7 @@ def basic_chart(chart_type) :options => { :seriesDefaults => { :renderer => 'jQuery.jqplot.BarRenderer', - :rendererOptions => {:barDirection => 'horizontal'}, + :rendererOptions => {:barDirection => 'horizontal', :barWidth => 5}, }, :series => [] }, @@ -52,7 +52,7 @@ def basic_chart(chart_type) :stackSeries => true, :seriesDefaults => { :renderer => 'jQuery.jqplot.BarRenderer', - :rendererOptions => {:barDirection => 'horizontal'}, + :rendererOptions => {:barDirection => 'horizontal', :barWidth => 5}, }, :series => [] }, @@ -63,7 +63,7 @@ def basic_chart(chart_type) :options => { :seriesDefaults => { :renderer => 'jQuery.jqplot.BarRenderer', - :rendererOptions => {:barDirection => 'vertical'}, + :rendererOptions => {:barDirection => 'vertical', :barWidth => 5}, }, :series => [] }, @@ -75,7 +75,7 @@ def basic_chart(chart_type) :stackSeries => true, :seriesDefaults => { :renderer => 'jQuery.jqplot.BarRenderer', - :rendererOptions => {:barDirection => 'vertical'}, + :rendererOptions => {:barDirection => 'vertical', :barWidth => 5}, }, :series => [] }, @@ -85,9 +85,9 @@ def basic_chart(chart_type) when 'Pie' Jqplot.default_legend( :options => { - :seriesDefaults => { - :renderer => 'jQuery.jqplot.PieRenderer', - :rendererOptions => {:showDataLabels => true} + :seriesdefaults => { + :renderer => 'jquery.jqplot.pierenderer', + :rendereroptions => {:showdatalabels => true} }, :series => [] }, diff --git a/lib/report_formatter/chart_common.rb b/lib/report_formatter/chart_common.rb index 8de27526d0b..499b0de89e5 100644 --- a/lib/report_formatter/chart_common.rb +++ b/lib/report_formatter/chart_common.rb @@ -58,7 +58,8 @@ def build_document_body when :performance then :build_performance_chart # performance chart (time based) when :util_ts then :build_util_ts_chart # utilization timestamp chart (grouped columns) when :planning then :build_planning_chart # trend based planning chart - else :build_reporting_chart # standard reporting chart + else # reporting charts + mri.graph[:mode] == 'values' ? :build_reporting_chart_numeric : :build_reporting_chart end method(fun).call(maxcols, divider) end @@ -347,11 +348,48 @@ def build_reporting_chart_dim2 series.push(:value => ocount, :tooltip => "#{key1} / Other: #{ocount}") end - add_series("Other", series) + add_series(_("Other"), series) end counts # FIXME end + def build_reporting_chart_dim2_numeric + # FIXME: styling + binding.pry + end + + def build_reporting_chart_other_numeric + categories = [] + + model, col = mri.graph[:column].split('-', 2) + col, aggreg = col.split(':', 2) + data_col_name = "#{col}__#{aggreg}" + + sorted_data = mri.table.data.sort_by { |row| row[data_col_name] } + + series = sorted_data.reverse.take(mri.graph[:count]). + each_with_object(series_class.new(@is_pie_type ? :pie : :flat)) do |row, a| + + a.push(:value => row[data_col_name], + :tooltip => row[mri.col_order[0]]) + categories.push([row[mri.col_order[0]], row[data_col_name]]) + end + + if mri.graph[:other] + ocount = sorted_data[0, sorted_data.length - mri.graph[:count]]. + inject(0) { |sum, row| sum += row[data_col_name] } + series.push(:value => ocount, :tooltip => _('Other')) + categories.push([_('Other'), ocount]) + end + + # Pie charts put categories in legend, else in axis labels + limit = @is_pie_type ? LEGEND_LENGTH : LABEL_LENGTH + categories.collect! { |c| slice_legend(c[0], limit) } + add_axis_category_text(categories) + + add_series(mri.headers[0], series) + end + def build_reporting_chart_other @is_pie_type = mri.graph[:type] =~ /^(Pie|Donut)/ save_key = nil @@ -406,6 +444,10 @@ def build_util_ts_chart(maxcols, divider) build_util_ts_chart_column if %w(Column ColumnThreed).index(mri.graph[:type]) end + def build_reporting_chart_numeric(maxcols, divider) + mri.dims == 2 ? build_reporting_chart_dim2_numeric : build_reporting_chart_other_numeric + end + def build_reporting_chart(maxcols, divider) mri.dims == 2 ? build_reporting_chart_dim2 : build_reporting_chart_other end diff --git a/lib/report_formatter/jqplot.rb b/lib/report_formatter/jqplot.rb index 39160bee96a..1d4019c67a5 100644 --- a/lib/report_formatter/jqplot.rb +++ b/lib/report_formatter/jqplot.rb @@ -87,6 +87,11 @@ def build_util_ts_chart_column x_axis_category_labels end + def build_reporting_chart_dim2_numeric + # FIXME: styling + super + end + def build_reporting_chart_dim2 counts = super # FIXME: counts are passed for now, should handle this in a better way default_legend @@ -120,6 +125,24 @@ def build_planning_chart(maxcols, divider) x_axis_category_labels end + def build_reporting_chart_other_numeric + mri.chart.update(Jqplot.basic_chart_fallback(mri.graph[:type])) + mri.chart[:options][:seriesDefaults][:rendererOptions].update( + :varyBarColor => true + ) if mri.graph[:type] =~ /(Bar|Column)/ + super + + # x_axis_category_labels if mri.graph[:type] =~ /(Bar|Column)/ + + # horizontal_legend(mri.chart) if mri.graph[:type] =~ /Bar/ + # default_legend(mri.chart) if mri.graph[:type] =~ /Column/ + end + + def build_reporting_chart_dim2_numeric + # FIXME + super + end + def build_reporting_chart_other mri.chart.update(Jqplot.basic_chart_fallback(mri.graph[:type])) super From f414e8cb651ebbeabea0c14a5d3bcebc306e94d9 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Thu, 16 Jul 2015 07:55:13 +0200 Subject: [PATCH 02/21] Report charts: implement charts with concrete numeric values. --- app/assets/javascripts/application.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index a2e5d7f37b4..2e86976a48e 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -38,6 +38,8 @@ //= require jqplot-plugins/jqplot.highlighter //= require jqplot-plugins/jqplot.cursor //= require jqplot-plugins/jqplot.enhancedLegendRenderer +//= require jqplot-plugins/jqplot.canvasAxisTickRenderer +//= require jqplot-plugins/jqplot.canvasTextRenderer //= require miq_jqplot //= require jquery/jquery-ui-1.9.2.custom.min //= require bootstrap From 42584d533d3c8603e6c9c70e542e206e82b1bba6 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Tue, 21 Jul 2015 11:50:43 +0200 Subject: [PATCH 03/21] Report charts: implement sum of "other" values for 2dim case. --- lib/report_formatter/chart_common.rb | 79 +++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 13 deletions(-) diff --git a/lib/report_formatter/chart_common.rb b/lib/report_formatter/chart_common.rb index 499b0de89e5..01a1d73f951 100644 --- a/lib/report_formatter/chart_common.rb +++ b/lib/report_formatter/chart_common.rb @@ -354,30 +354,83 @@ def build_reporting_chart_dim2 end def build_reporting_chart_dim2_numeric - # FIXME: styling - binding.pry + (sort1, sort2) = mri.sortby + (keep, show_other) = keep_and_show_other + + # Group values by sort1 + # 3rd dimension in the chart is defined by sort2 + groups = mri.table.data.group_by { |row| row[sort1] } + + group_sums = groups.each_with_object({}) do |(key, rows), h| + h[key] = rows.inject(0) { |sum, row| sum += row[data_column_name] } + end + sorted_sums = group_sums.sort_by { |key, sum| sum } + + selected_groups = sorted_sums.reverse.take(mri.graph[:count]) + + cathegory_texts = selected_groups.collect { |key, _| slice_legend(key, LABEL_LENGTH) } + cathegory_texts << _('Other') if show_other + + add_axis_category_text(cathegory_texts) + + groups_hash = selected_groups.each_with_object(Hash.new { |h, k| h[k] = {} }) do |(key, _), h| + groups[key].each { |row| h[key][row[sort2]] = row } + end + + if show_other + other_groups = sorted_sums[0, sorted_sums.length - mri.graph[:count]] + other = other_groups.each_with_object(Hash.new(0)) do |(key, _), o| + groups[key].each do |row| + o[row[sort2]] += row[data_column_name] + end + end + end + + # For each value in sort2 column we create a series. + sort2_values = mri.table.data.each_with_object({}) { |row, h| h[row[sort2]] = true } + sort2_values.each_key do |val2| + series = selected_groups.each_with_object(series_class.new) do |(key1, _), a| + + row = groups_hash.fetch_path(key1, val2) + value = row ? row[data_column_name] : 0 + a.push(:value => value, + :tooltip => "#{key1} / #{val2}: #{value}") + end + + series.push(:value => other[val2], + :tooltip => "Other / #{val2}: #{other[val2]}") if show_other + + label = slice_legend(val2) if val2.kind_of?(String) + label = label.to_s.gsub(/\\/, ' \ ') + label = _('no value') if label.blank? + add_series(label, series) + end + groups + end + + def data_column_name + @data_column_name ||= ( + model, col = mri.graph[:column].split('-', 2) + col, aggreg = col.split(':', 2) + "#{col}__#{aggreg}" + ) end def build_reporting_chart_other_numeric categories = [] - - model, col = mri.graph[:column].split('-', 2) - col, aggreg = col.split(':', 2) - data_col_name = "#{col}__#{aggreg}" - - sorted_data = mri.table.data.sort_by { |row| row[data_col_name] } + (sort1, _) = mri.sortby + sorted_data = mri.table.data.sort_by { |row| row[data_column_name] } series = sorted_data.reverse.take(mri.graph[:count]). each_with_object(series_class.new(@is_pie_type ? :pie : :flat)) do |row, a| - - a.push(:value => row[data_col_name], - :tooltip => row[mri.col_order[0]]) - categories.push([row[mri.col_order[0]], row[data_col_name]]) + a.push(:value => row[data_column_name], + :tooltip => row[sort1]) + categories.push([row[sort1], row[data_column_name]]) end if mri.graph[:other] ocount = sorted_data[0, sorted_data.length - mri.graph[:count]]. - inject(0) { |sum, row| sum += row[data_col_name] } + inject(0) { |sum, row| sum += row[data_column_name] } series.push(:value => ocount, :tooltip => _('Other')) categories.push([_('Other'), ocount]) end From 6180f83d977c882ff3a5e6be7b470659667aa885 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Tue, 21 Jul 2015 16:45:31 +0200 Subject: [PATCH 04/21] Report charts: cleanups --- lib/report_formatter/chart_common.rb | 24 ++++++++++++++---------- lib/report_formatter/jqplot.rb | 18 +++++++++++++++++- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/lib/report_formatter/chart_common.rb b/lib/report_formatter/chart_common.rb index 01a1d73f951..09a8571ffa7 100644 --- a/lib/report_formatter/chart_common.rb +++ b/lib/report_formatter/chart_common.rb @@ -366,7 +366,7 @@ def build_reporting_chart_dim2_numeric end sorted_sums = group_sums.sort_by { |key, sum| sum } - selected_groups = sorted_sums.reverse.take(mri.graph[:count]) + selected_groups = sorted_sums.reverse.take(keep) cathegory_texts = selected_groups.collect { |key, _| slice_legend(key, LABEL_LENGTH) } cathegory_texts << _('Other') if show_other @@ -378,7 +378,7 @@ def build_reporting_chart_dim2_numeric end if show_other - other_groups = sorted_sums[0, sorted_sums.length - mri.graph[:count]] + other_groups = sorted_sums[0, sorted_sums.length - keep] other = other_groups.each_with_object(Hash.new(0)) do |(key, _), o| groups[key].each do |row| o[row[sort2]] += row[data_column_name] @@ -419,32 +419,36 @@ def data_column_name def build_reporting_chart_other_numeric categories = [] (sort1, _) = mri.sortby + (keep, show_other) = keep_and_show_other sorted_data = mri.table.data.sort_by { |row| row[data_column_name] } - series = sorted_data.reverse.take(mri.graph[:count]). - each_with_object(series_class.new(@is_pie_type ? :pie : :flat)) do |row, a| + series = sorted_data.reverse.take(keep). + each_with_object(series_class.new(is_pie_type ? :pie : :flat)) do |row, a| a.push(:value => row[data_column_name], :tooltip => row[sort1]) categories.push([row[sort1], row[data_column_name]]) end - if mri.graph[:other] - ocount = sorted_data[0, sorted_data.length - mri.graph[:count]]. + if show_other + ocount = sorted_data[0, sorted_data.length - keep]. inject(0) { |sum, row| sum += row[data_column_name] } series.push(:value => ocount, :tooltip => _('Other')) categories.push([_('Other'), ocount]) end # Pie charts put categories in legend, else in axis labels - limit = @is_pie_type ? LEGEND_LENGTH : LABEL_LENGTH + limit = is_pie_type ? LEGEND_LENGTH : LABEL_LENGTH categories.collect! { |c| slice_legend(c[0], limit) } add_axis_category_text(categories) add_series(mri.headers[0], series) end + def is_pie_type + @is_pie_type ||= mri.graph[:type] =~ /^(Pie|Donut)/ + end + def build_reporting_chart_other - @is_pie_type = mri.graph[:type] =~ /^(Pie|Donut)/ save_key = nil counter = 0 categories = [] # Store categories and series counts in an array of arrays @@ -470,12 +474,12 @@ def build_reporting_chart_other end series = categories.each_with_object( - series_class.new(@is_pie_type ? :pie : :flat)) do |cat, a| + series_class.new(is_pie_type ? :pie : :flat)) do |cat, a| a.push(:value => cat.last, :tooltip => "#{cat.first}: #{cat.last}") end # Pie charts put categories in legend, else in axis labels - limit = @is_pie_type ? LEGEND_LENGTH : LABEL_LENGTH + limit = is_pie_type ? LEGEND_LENGTH : LABEL_LENGTH categories.collect! { |c| slice_legend(c[0], limit) } add_axis_category_text(categories) add_series(mri.headers[0], series) diff --git a/lib/report_formatter/jqplot.rb b/lib/report_formatter/jqplot.rb index 1d4019c67a5..356f8d051d6 100644 --- a/lib/report_formatter/jqplot.rb +++ b/lib/report_formatter/jqplot.rb @@ -136,6 +136,22 @@ def build_reporting_chart_other_numeric # horizontal_legend(mri.chart) if mri.graph[:type] =~ /Bar/ # default_legend(mri.chart) if mri.graph[:type] =~ /Column/ + + #mri.chart.store_path(:options, :highlighter, :show, true) + #mri.chart.store_path(:options, :highlighter, :tooltipAxes, 'y') + binding.pry + mri.chart[:options].update( + :highlighter => { + :show => true, + :useAxesFormatters => false, + :tooltipAxes => 'y', + :tooltipContentEditor => "foobar = function(str, seriesIndex, pointIndex, plot) { + return plot.series[seriesIndex].data[pointIndex][0] + ': ' + + plot.series[seriesIndex].data[pointIndex][1]; + }", + :tooltipLocation => 'n' + } + ) if is_pie_type end def build_reporting_chart_dim2_numeric @@ -157,7 +173,7 @@ def build_reporting_chart_other }", :tooltipLocation => 'n' } - ) if @is_pie_type + ) if is_pie_type end def finalize_document From a17100d57acf88c8d6159f3ad7db8b4108333770 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Wed, 22 Jul 2015 11:13:42 +0200 Subject: [PATCH 05/21] jqplot charting: fix a regression in pie sample chart. --- lib/charting/jqplot.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/charting/jqplot.rb b/lib/charting/jqplot.rb index 237153476d6..87b45e6da53 100644 --- a/lib/charting/jqplot.rb +++ b/lib/charting/jqplot.rb @@ -85,9 +85,9 @@ def basic_chart(chart_type) when 'Pie' Jqplot.default_legend( :options => { - :seriesdefaults => { - :renderer => 'jquery.jqplot.pierenderer', - :rendereroptions => {:showdatalabels => true} + :seriesDefaults => { + :renderer => 'jQuery.jqplot.PieRenderer', + :rendererOptions => {:showDataLabels => true} }, :series => [] }, From 388127aeddec2db997cfacac3cf216cfb8d57fd5 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Wed, 22 Jul 2015 11:14:43 +0200 Subject: [PATCH 06/21] Charting: handle empty values better. --- lib/report_formatter/chart_common.rb | 7 +++++-- lib/report_formatter/jqplot_series.rb | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/report_formatter/chart_common.rb b/lib/report_formatter/chart_common.rb index 09a8571ffa7..dc616290632 100644 --- a/lib/report_formatter/chart_common.rb +++ b/lib/report_formatter/chart_common.rb @@ -424,9 +424,12 @@ def build_reporting_chart_other_numeric series = sorted_data.reverse.take(keep). each_with_object(series_class.new(is_pie_type ? :pie : :flat)) do |row, a| + + tooltip = row[sort1] + tooltip = _('no value') if tooltip.blank? a.push(:value => row[data_column_name], - :tooltip => row[sort1]) - categories.push([row[sort1], row[data_column_name]]) + :tooltip => tooltip) + categories.push([tooltip, row[data_column_name]]) end if show_other diff --git a/lib/report_formatter/jqplot_series.rb b/lib/report_formatter/jqplot_series.rb index 840ff08f020..b5b395a89e2 100644 --- a/lib/report_formatter/jqplot_series.rb +++ b/lib/report_formatter/jqplot_series.rb @@ -37,7 +37,7 @@ def add_to_value(index, addition) private def shorten_label(label) - label[0, 14] + label.to_s[0, 14] end end end From 84db438b566a793b550b961505d877c9167a203b Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Wed, 22 Jul 2015 11:41:14 +0200 Subject: [PATCH 07/21] Report charts: cleanups --- lib/report_formatter/chart_common.rb | 2 +- lib/report_formatter/jqplot.rb | 8 +- .../report_formater/jqplot_formater_spec.rb | 95 +++++++++++++++++++ 3 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 spec/lib/report_formater/jqplot_formater_spec.rb diff --git a/lib/report_formatter/chart_common.rb b/lib/report_formatter/chart_common.rb index dc616290632..6afa84e18c1 100644 --- a/lib/report_formatter/chart_common.rb +++ b/lib/report_formatter/chart_common.rb @@ -378,7 +378,7 @@ def build_reporting_chart_dim2_numeric end if show_other - other_groups = sorted_sums[0, sorted_sums.length - keep] + other_groups = Array(sorted_sums[0, sorted_sums.length - keep]) other = other_groups.each_with_object(Hash.new(0)) do |(key, _), o| groups[key].each do |row| o[row[sort2]] += row[data_column_name] diff --git a/lib/report_formatter/jqplot.rb b/lib/report_formatter/jqplot.rb index 356f8d051d6..7d6e76c445f 100644 --- a/lib/report_formatter/jqplot.rb +++ b/lib/report_formatter/jqplot.rb @@ -134,12 +134,6 @@ def build_reporting_chart_other_numeric # x_axis_category_labels if mri.graph[:type] =~ /(Bar|Column)/ - # horizontal_legend(mri.chart) if mri.graph[:type] =~ /Bar/ - # default_legend(mri.chart) if mri.graph[:type] =~ /Column/ - - #mri.chart.store_path(:options, :highlighter, :show, true) - #mri.chart.store_path(:options, :highlighter, :tooltipAxes, 'y') - binding.pry mri.chart[:options].update( :highlighter => { :show => true, @@ -155,7 +149,7 @@ def build_reporting_chart_other_numeric end def build_reporting_chart_dim2_numeric - # FIXME + mri.chart.update(Jqplot.basic_chart_fallback(mri.graph[:type])) super end diff --git a/spec/lib/report_formater/jqplot_formater_spec.rb b/spec/lib/report_formater/jqplot_formater_spec.rb new file mode 100644 index 00000000000..14b4c4fb476 --- /dev/null +++ b/spec/lib/report_formater/jqplot_formater_spec.rb @@ -0,0 +1,95 @@ +require 'spec_helper' + +describe ReportFormatter::JqplotFormatter do + before (:each) do + MiqRegion.seed + + @guid = MiqUUID.new_guid + MiqServer.stub(:my_guid).and_return(@guid) + @zone = FactoryGirl.create(:zone) + @miq_server = FactoryGirl.create(:miq_server, :guid => @guid, :zone => @zone) + MiqServer.stub(:my_server).and_return(@miq_server) + + + @group = FactoryGirl.create(:miq_group) + @user = FactoryGirl.create(:user, :miq_groups => [@group]) + end + + context '#build_reporting_chart_other_numeric' do + it 'builds 2d numeric charts' do + FactoryGirl.create(:vm_vmware, :host => host = FactoryGirl.create(:host, :name => 'host'))#, :miq_server => @server) + + report = MiqReport.new( + :db => "Vm", + :sortby => ["host_name"], + :order => "Descending", + :cols => ["mem_cpu", "host_name"], + :include => {}, + :col_order => ["mem_cpu__total", "host_name"], + :headers => ["Parent Host", "Memory (Avg)", "Memory (Total)", "OS Product Type"], + :dims => 1, + :rpt_options => {:pivot => {:group_cols => ["host_name"]}}, + :graph => {:type => "Column", :mode => "values", :column => "Vm-mem_cpu:total", :count => 10, :other => false} + ) + + report.generate_table(:userid => 'test') + report.table = Struct.new(:data).new + report.table.data = [ + Ruport::Data::Record.new("mem_cpu__total" => 0.0, "host_name" => "host") + ] + + expect_any_instance_of(described_class).to receive(:build_reporting_chart_other_numeric).once.and_call_original + + ReportFormatter::ReportRenderer.render(Charting.format) do |e| + e.options.mri = report + e.options.show_title = true + e.options.graph_options = MiqReport.graph_options(600, 400) + e.options.theme = 'miq' + end + + expect(report.chart[:data][0][0]).to eq(0.0) + expect(report.chart[:options][:axes][:xaxis][:ticks][0]).to eq(host.name) + end + end + + context '#build_reporting_chart_dim2_numeric' do + it 'builds 3d numeric charts' do + report = MiqReport.new( + :db => "Vm", + :cols => ["host_name", "mem_cpu"], + :include => {"operating_system"=>{"columns"=>["product_type"]}}, + :col_order => ["host_name", "operating_system.product_type", "mem_cpu__avg", "mem_cpu__max", "mem_cpu__min", "mem_cpu__total"], + :headers => ["Parent Host", "OS Product Type", " Memory (Avg)", " Memory (Max)", " Memory (Min)", "Memory (Total)"], + :order => "Ascending", + :sortby => ["host_name", "operating_system.product_type"], + :graph => {:type=>"StackedBar", :mode=>"values", :column=>"Vm-mem_cpu:total", :count=>10, :other=>true}, + :dims => 2, + :rpt_options => {:pivot=>{:group_cols=>["host_name", "operating_system.product_type"]}, :pdf=>{:page_size=>"US-Letter"}, :queue_timeout=>nil}, + ) + + report.table = Struct.new(:data).new + report.table.data = [ + Ruport::Data::Record.new( + 'host_name' => 'foobar', + 'operating_system.product_type' => 'linux', + 'mem_cpu__avg' => 4437, + 'mem_cpu__max' => 6144, + 'mem_cpu__min' => 1024, + 'mem_cpu__total' => 13312 + ) + ] + + expect_any_instance_of(described_class).to receive(:build_reporting_chart_dim2_numeric).once.and_call_original + + ReportFormatter::ReportRenderer.render(Charting.format) do |e| + e.options.mri = report + e.options.show_title = true + e.options.graph_options = MiqReport.graph_options(600, 400) + e.options.theme = 'miq' + end + + expect(report.chart[:data][0][0]).to eq(13312) + expect(report.chart[:options][:series][0][:label]).to eq('linux') + end + end +end From 34554999e7b63d28f453bfc434c667a61ab41496 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Thu, 23 Jul 2015 19:48:16 +0200 Subject: [PATCH 08/21] Report charts: style cleanups. --- .../report_controller/reports/editor.rb | 2 +- app/helpers/report_helper.rb | 1 - app/views/report/_form_chart.html.haml | 4 +- lib/report_formatter/chart_common.rb | 42 +++++++------- lib/report_formatter/jqplot.rb | 4 +- .../report_formater/jqplot_formater_spec.rb | 55 +++++++++---------- 6 files changed, 52 insertions(+), 56 deletions(-) diff --git a/app/controllers/report_controller/reports/editor.rb b/app/controllers/report_controller/reports/editor.rb index 5f6b4492177..d99017573ff 100644 --- a/app/controllers/report_controller/reports/editor.rb +++ b/app/controllers/report_controller/reports/editor.rb @@ -1401,7 +1401,7 @@ def set_form_vars # @edit[:new][:graph] = @rpt.graph # Replaced above line to handle new graph settings Hash if @rpt.graph.is_a?(Hash) - @edit[:new][:graph_type] = @rpt.graph[:type] + @edit[:new][:graph_type] = @rpt.graph[:type] @edit[:new][:graph_count] = @rpt.graph[:count] @edit[:new][:chart_mode] = @rpt.graph[:mode] @edit[:new][:chart_column] = @rpt.graph[:column] diff --git a/app/helpers/report_helper.rb b/app/helpers/report_helper.rb index 77f0bace24c..eda00bebe1c 100644 --- a/app/helpers/report_helper.rb +++ b/app/helpers/report_helper.rb @@ -26,7 +26,6 @@ def visibility_options(widget) end end - def chart_fields_options # @edit[:pivot_cols] => {"Vm-mem_cpu"=>[:avg, :total]} options = [] diff --git a/app/views/report/_form_chart.html.haml b/app/views/report/_form_chart.html.haml index 73bd375ddc8..bcf725caa39 100644 --- a/app/views/report/_form_chart.html.haml +++ b/app/views/report/_form_chart.html.haml @@ -8,7 +8,7 @@ = _('Choose a chart type') %td = select_tag('chosen_graph', - options_for_select([""] + Charting.chart_names_for_select, @edit[:new][:graph_type]), + options_for_select([_("")] + Charting.chart_names_for_select, @edit[:new][:graph_type]), :multiple => false, :class => "widthed", "data-miq_sparkle_on" => true, @@ -20,7 +20,7 @@ = _('Chart mode') %td = select_tag('chart_mode', - options_for_select([['Counts', 'counts'], ['Values', 'values']], @edit[:new][:chart_mode]), + options_for_select([[_('Counts'), 'counts'], [_('Values'), 'values']], @edit[:new][:chart_mode]), :multiple => false, :class => "widthed", "data-miq_sparkle_on" => true, diff --git a/lib/report_formatter/chart_common.rb b/lib/report_formatter/chart_common.rb index 6afa84e18c1..cb0a5d6b33c 100644 --- a/lib/report_formatter/chart_common.rb +++ b/lib/report_formatter/chart_common.rb @@ -362,9 +362,9 @@ def build_reporting_chart_dim2_numeric groups = mri.table.data.group_by { |row| row[sort1] } group_sums = groups.each_with_object({}) do |(key, rows), h| - h[key] = rows.inject(0) { |sum, row| sum += row[data_column_name] } - end - sorted_sums = group_sums.sort_by { |key, sum| sum } + h[key] = rows.inject(0) { |sum, row| sum + row[data_column_name] } + end + sorted_sums = group_sums.sort_by { |_key, sum| sum } selected_groups = sorted_sums.reverse.take(keep) @@ -380,17 +380,16 @@ def build_reporting_chart_dim2_numeric if show_other other_groups = Array(sorted_sums[0, sorted_sums.length - keep]) other = other_groups.each_with_object(Hash.new(0)) do |(key, _), o| - groups[key].each do |row| - o[row[sort2]] += row[data_column_name] - end - end + groups[key].each do |row| + o[row[sort2]] += row[data_column_name] + end + end end # For each value in sort2 column we create a series. sort2_values = mri.table.data.each_with_object({}) { |row, h| h[row[sort2]] = true } sort2_values.each_key do |val2| series = selected_groups.each_with_object(series_class.new) do |(key1, _), a| - row = groups_hash.fetch_path(key1, val2) value = row ? row[data_column_name] : 0 a.push(:value => value, @@ -410,7 +409,7 @@ def build_reporting_chart_dim2_numeric def data_column_name @data_column_name ||= ( - model, col = mri.graph[:column].split('-', 2) + _model, col = mri.graph[:column].split('-', 2) col, aggreg = col.split(':', 2) "#{col}__#{aggreg}" ) @@ -418,13 +417,12 @@ def data_column_name def build_reporting_chart_other_numeric categories = [] - (sort1, _) = mri.sortby + (sort1,) = mri.sortby (keep, show_other) = keep_and_show_other sorted_data = mri.table.data.sort_by { |row| row[data_column_name] } - series = sorted_data.reverse.take(keep). - each_with_object(series_class.new(is_pie_type ? :pie : :flat)) do |row, a| - + series = sorted_data.reverse.take(keep) + .each_with_object(series_class.new(pie_type? ? :pie : :flat)) do |row, a| tooltip = row[sort1] tooltip = _('no value') if tooltip.blank? a.push(:value => row[data_column_name], @@ -433,22 +431,22 @@ def build_reporting_chart_other_numeric end if show_other - ocount = sorted_data[0, sorted_data.length - keep]. - inject(0) { |sum, row| sum += row[data_column_name] } + ocount = sorted_data[0, sorted_data.length - keep] + .inject(0) { |sum, row| sum + row[data_column_name] } series.push(:value => ocount, :tooltip => _('Other')) categories.push([_('Other'), ocount]) end # Pie charts put categories in legend, else in axis labels - limit = is_pie_type ? LEGEND_LENGTH : LABEL_LENGTH + limit = pie_type? ? LEGEND_LENGTH : LABEL_LENGTH categories.collect! { |c| slice_legend(c[0], limit) } add_axis_category_text(categories) add_series(mri.headers[0], series) end - def is_pie_type - @is_pie_type ||= mri.graph[:type] =~ /^(Pie|Donut)/ + def pie_type? + @pie_type ||= mri.graph[:type] =~ /^(Pie|Donut)/ end def build_reporting_chart_other @@ -477,12 +475,12 @@ def build_reporting_chart_other end series = categories.each_with_object( - series_class.new(is_pie_type ? :pie : :flat)) do |cat, a| + series_class.new(pie_type? ? :pie : :flat)) do |cat, a| a.push(:value => cat.last, :tooltip => "#{cat.first}: #{cat.last}") end # Pie charts put categories in legend, else in axis labels - limit = is_pie_type ? LEGEND_LENGTH : LABEL_LENGTH + limit = pie_type? ? LEGEND_LENGTH : LABEL_LENGTH categories.collect! { |c| slice_legend(c[0], limit) } add_axis_category_text(categories) add_series(mri.headers[0], series) @@ -504,11 +502,11 @@ def build_util_ts_chart(maxcols, divider) build_util_ts_chart_column if %w(Column ColumnThreed).index(mri.graph[:type]) end - def build_reporting_chart_numeric(maxcols, divider) + def build_reporting_chart_numeric(_maxcols, _divider) mri.dims == 2 ? build_reporting_chart_dim2_numeric : build_reporting_chart_other_numeric end - def build_reporting_chart(maxcols, divider) + def build_reporting_chart(_maxcols, _divider) mri.dims == 2 ? build_reporting_chart_dim2 : build_reporting_chart_other end end diff --git a/lib/report_formatter/jqplot.rb b/lib/report_formatter/jqplot.rb index 7d6e76c445f..8dc38506959 100644 --- a/lib/report_formatter/jqplot.rb +++ b/lib/report_formatter/jqplot.rb @@ -145,7 +145,7 @@ def build_reporting_chart_other_numeric }", :tooltipLocation => 'n' } - ) if is_pie_type + ) if pie_type? end def build_reporting_chart_dim2_numeric @@ -167,7 +167,7 @@ def build_reporting_chart_other }", :tooltipLocation => 'n' } - ) if is_pie_type + ) if pie_type? end def finalize_document diff --git a/spec/lib/report_formater/jqplot_formater_spec.rb b/spec/lib/report_formater/jqplot_formater_spec.rb index 14b4c4fb476..bd53bb61966 100644 --- a/spec/lib/report_formater/jqplot_formater_spec.rb +++ b/spec/lib/report_formater/jqplot_formater_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe ReportFormatter::JqplotFormatter do - before (:each) do + before(:each) do MiqRegion.seed @guid = MiqUUID.new_guid @@ -10,26 +10,25 @@ @miq_server = FactoryGirl.create(:miq_server, :guid => @guid, :zone => @zone) MiqServer.stub(:my_server).and_return(@miq_server) - @group = FactoryGirl.create(:miq_group) @user = FactoryGirl.create(:user, :miq_groups => [@group]) end context '#build_reporting_chart_other_numeric' do it 'builds 2d numeric charts' do - FactoryGirl.create(:vm_vmware, :host => host = FactoryGirl.create(:host, :name => 'host'))#, :miq_server => @server) + FactoryGirl.create(:vm_vmware, :host => host = FactoryGirl.create(:host, :name => 'host')) report = MiqReport.new( - :db => "Vm", - :sortby => ["host_name"], - :order => "Descending", - :cols => ["mem_cpu", "host_name"], - :include => {}, - :col_order => ["mem_cpu__total", "host_name"], - :headers => ["Parent Host", "Memory (Avg)", "Memory (Total)", "OS Product Type"], - :dims => 1, - :rpt_options => {:pivot => {:group_cols => ["host_name"]}}, - :graph => {:type => "Column", :mode => "values", :column => "Vm-mem_cpu:total", :count => 10, :other => false} + :db => "Vm", + :sortby => ["host_name"], + :order => "Descending", + :cols => %w(mem_cpu host_name), + :include => {}, + :col_order => %w(mem_cpu__total host_name), + :headers => ["Parent Host", "Memory (Avg)", "Memory (Total)", "OS Product Type"], + :dims => 1, + :rpt_options => {:pivot => {:group_cols => ["host_name"]}}, + :graph => {:type => "Column", :mode => "values", :column => "Vm-mem_cpu:total", :count => 10, :other => false} ) report.generate_table(:userid => 'test') @@ -55,16 +54,16 @@ context '#build_reporting_chart_dim2_numeric' do it 'builds 3d numeric charts' do report = MiqReport.new( - :db => "Vm", - :cols => ["host_name", "mem_cpu"], - :include => {"operating_system"=>{"columns"=>["product_type"]}}, - :col_order => ["host_name", "operating_system.product_type", "mem_cpu__avg", "mem_cpu__max", "mem_cpu__min", "mem_cpu__total"], - :headers => ["Parent Host", "OS Product Type", " Memory (Avg)", " Memory (Max)", " Memory (Min)", "Memory (Total)"], - :order => "Ascending", - :sortby => ["host_name", "operating_system.product_type"], - :graph => {:type=>"StackedBar", :mode=>"values", :column=>"Vm-mem_cpu:total", :count=>10, :other=>true}, - :dims => 2, - :rpt_options => {:pivot=>{:group_cols=>["host_name", "operating_system.product_type"]}, :pdf=>{:page_size=>"US-Letter"}, :queue_timeout=>nil}, + :db => "Vm", + :cols => %w(host_name mem_cpu), + :include => {"operating_system" => {"columns" => ["product_type"]}}, + :col_order => %w(host_name operating_system.product_type mem_cpu__avg mem_cpu__max mem_cpu__min mem_cpu__total), + :headers => ["Parent Host", "OS Product Type", " Memory (Avg)", " Memory (Max)", " Memory (Min)", "Memory (Total)"], + :order => "Ascending", + :sortby => %w(host_name operating_system.product_type), + :graph => {:type => "StackedBar", :mode => "values", :column => "Vm-mem_cpu:total", :count => 10, :other => true}, + :dims => 2, + :rpt_options => {:pivot => {:group_cols => %w(host_name operating_system.product_type)}}, ) report.table = Struct.new(:data).new @@ -72,10 +71,10 @@ Ruport::Data::Record.new( 'host_name' => 'foobar', 'operating_system.product_type' => 'linux', - 'mem_cpu__avg' => 4437, - 'mem_cpu__max' => 6144, - 'mem_cpu__min' => 1024, - 'mem_cpu__total' => 13312 + 'mem_cpu__avg' => 4_437, + 'mem_cpu__max' => 6_144, + 'mem_cpu__min' => 1_024, + 'mem_cpu__total' => 13_312 ) ] @@ -88,7 +87,7 @@ e.options.theme = 'miq' end - expect(report.chart[:data][0][0]).to eq(13312) + expect(report.chart[:data][0][0]).to eq(13_312) expect(report.chart[:options][:series][0][:label]).to eq('linux') end end From 6780a73907cfc18d812d3c13bd9742fb09920c7d Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Fri, 24 Jul 2015 11:38:29 +0200 Subject: [PATCH 09/21] Report charts: fixes after rebase. --- lib/report_formatter/chart_common.rb | 2 +- lib/report_formatter/jqplot.rb | 26 ++++++++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/lib/report_formatter/chart_common.rb b/lib/report_formatter/chart_common.rb index cb0a5d6b33c..60c1f8c8445 100644 --- a/lib/report_formatter/chart_common.rb +++ b/lib/report_formatter/chart_common.rb @@ -2,7 +2,7 @@ module ReportFormatter module ChartCommon def slice_legend(string, limit = LEGEND_LENGTH) string = string.to_s - string.length > limit ? string.slice(0, limit) + "..." : string + string = string.length > limit ? string.slice(0, limit) + "..." : string string.gsub(/\n/, ' ') end diff --git a/lib/report_formatter/jqplot.rb b/lib/report_formatter/jqplot.rb index 8dc38506959..499b86354b7 100644 --- a/lib/report_formatter/jqplot.rb +++ b/lib/report_formatter/jqplot.rb @@ -78,6 +78,21 @@ def x_axis_category_labels mri.chart.store_path(:options, :axes, :xaxis, :renderer, 'jQuery.jqplot.CategoryAxisRenderer') end + def vertical? + @vertical ||= mri.graph[:type] =~ /(Column)/ + end + + def axis_category_labels_ticks + return if Array(mri.chart[:axis_category_text]).empty? + + axis = vertical? ? :xaxis : :yaxis + mri.chart.store_path(:options, :axes, axis, :renderer, 'jQuery.jqplot.CategoryAxisRenderer') + mri.chart.store_path(:options, :axes, axis, :ticks, mri.chart[:axis_category_text][0].collect { |l| slice_legend(l) }) + mri.chart.store_path(:options, :axes, axis, :tickRenderer, 'jQuery.jqplot.CanvasAxisTickRenderer') + + mri.chart.store_path(:options, :axes, axis, :tickOptions, :angle, -45.0) if vertical? + end + # Utilization timestamp charts def build_util_ts_chart_column return unless super @@ -87,11 +102,6 @@ def build_util_ts_chart_column x_axis_category_labels end - def build_reporting_chart_dim2_numeric - # FIXME: styling - super - end - def build_reporting_chart_dim2 counts = super # FIXME: counts are passed for now, should handle this in a better way default_legend @@ -132,7 +142,7 @@ def build_reporting_chart_other_numeric ) if mri.graph[:type] =~ /(Bar|Column)/ super - # x_axis_category_labels if mri.graph[:type] =~ /(Bar|Column)/ + axis_category_labels_ticks if mri.graph[:type] =~ /(Bar|Column)/ mri.chart[:options].update( :highlighter => { @@ -151,6 +161,10 @@ def build_reporting_chart_other_numeric def build_reporting_chart_dim2_numeric mri.chart.update(Jqplot.basic_chart_fallback(mri.graph[:type])) super + horizontal_legend if mri.graph[:type] =~ /Bar/ + default_legend if mri.graph[:type] =~ /Column/ + + axis_category_labels_ticks if mri.graph[:type] =~ /(Bar|Column)/ end def build_reporting_chart_other From 9e48c4f2b10a79ac41fd1992d02622d45a1831b2 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Mon, 3 Aug 2015 15:21:34 +0200 Subject: [PATCH 10/21] Report charts: handle situation with other=>true... Handle situation when other==true and there are less than requested values for the chart. --- lib/report_formatter/chart_common.rb | 8 +-- .../report_formater/jqplot_formater_spec.rb | 58 ++++++++++--------- 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/lib/report_formatter/chart_common.rb b/lib/report_formatter/chart_common.rb index 60c1f8c8445..e3fbac08271 100644 --- a/lib/report_formatter/chart_common.rb +++ b/lib/report_formatter/chart_common.rb @@ -431,10 +431,10 @@ def build_reporting_chart_other_numeric end if show_other - ocount = sorted_data[0, sorted_data.length - keep] - .inject(0) { |sum, row| sum + row[data_column_name] } - series.push(:value => ocount, :tooltip => _('Other')) - categories.push([_('Other'), ocount]) + other_sum = Array(sorted_data[0, sorted_data.length - keep]). + inject(0) { |sum, row| sum += row[data_column_name] } + series.push(:value => other_sum, :tooltip => _('Other')) + categories.push([_('Other'), other_sum]) end # Pie charts put categories in legend, else in axis labels diff --git a/spec/lib/report_formater/jqplot_formater_spec.rb b/spec/lib/report_formater/jqplot_formater_spec.rb index bd53bb61966..09ea8926eac 100644 --- a/spec/lib/report_formater/jqplot_formater_spec.rb +++ b/spec/lib/report_formater/jqplot_formater_spec.rb @@ -15,39 +15,41 @@ end context '#build_reporting_chart_other_numeric' do - it 'builds 2d numeric charts' do - FactoryGirl.create(:vm_vmware, :host => host = FactoryGirl.create(:host, :name => 'host')) + [true, false].each do |other| + it "builds 2d numeric charts #{other ? 'with' : 'without'} 'other'" do + FactoryGirl.create(:vm_vmware, :host => host = FactoryGirl.create(:host, :name => 'host')) - report = MiqReport.new( - :db => "Vm", - :sortby => ["host_name"], - :order => "Descending", - :cols => %w(mem_cpu host_name), - :include => {}, - :col_order => %w(mem_cpu__total host_name), - :headers => ["Parent Host", "Memory (Avg)", "Memory (Total)", "OS Product Type"], - :dims => 1, - :rpt_options => {:pivot => {:group_cols => ["host_name"]}}, - :graph => {:type => "Column", :mode => "values", :column => "Vm-mem_cpu:total", :count => 10, :other => false} - ) + report = MiqReport.new( + :db => "Vm", + :sortby => ["host_name"], + :order => "Descending", + :cols => %w(mem_cpu host_name), + :include => {}, + :col_order => %w(mem_cpu__total host_name), + :headers => ["Parent Host", "Memory (Avg)", "Memory (Total)", "OS Product Type"], + :dims => 1, + :rpt_options => {:pivot => {:group_cols => ["host_name"]}}, + :graph => {:type => "Column", :mode => "values", :column => "Vm-mem_cpu:total", :count => 10, :other => other} + ) - report.generate_table(:userid => 'test') - report.table = Struct.new(:data).new - report.table.data = [ - Ruport::Data::Record.new("mem_cpu__total" => 0.0, "host_name" => "host") - ] + report.generate_table(:userid => 'test') + report.table = Struct.new(:data).new + report.table.data = [ + Ruport::Data::Record.new("mem_cpu__total" => 0.0, "host_name" => "host") + ] - expect_any_instance_of(described_class).to receive(:build_reporting_chart_other_numeric).once.and_call_original + expect_any_instance_of(described_class).to receive(:build_reporting_chart_other_numeric).once.and_call_original - ReportFormatter::ReportRenderer.render(Charting.format) do |e| - e.options.mri = report - e.options.show_title = true - e.options.graph_options = MiqReport.graph_options(600, 400) - e.options.theme = 'miq' - end + ReportFormatter::ReportRenderer.render(Charting.format) do |e| + e.options.mri = report + e.options.show_title = true + e.options.graph_options = MiqReport.graph_options(600, 400) + e.options.theme = 'miq' + end - expect(report.chart[:data][0][0]).to eq(0.0) - expect(report.chart[:options][:axes][:xaxis][:ticks][0]).to eq(host.name) + expect(report.chart[:data][0][0]).to eq(0.0) + expect(report.chart[:options][:axes][:xaxis][:ticks][0]).to eq(host.name) + end end end From e5a63c0336909c3e00ce27276d8093f697cc0bb6 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Tue, 28 Apr 2015 18:22:55 +0200 Subject: [PATCH 11/21] Reporting charts: allow creating concrete number charts. --- lib/charting/jqplot.rb | 6 ++--- lib/report_formatter/chart_common.rb | 39 ++++++++++++++++++++++++++-- lib/report_formatter/jqplot.rb | 5 ++++ 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/lib/charting/jqplot.rb b/lib/charting/jqplot.rb index 87b45e6da53..237153476d6 100644 --- a/lib/charting/jqplot.rb +++ b/lib/charting/jqplot.rb @@ -85,9 +85,9 @@ def basic_chart(chart_type) when 'Pie' Jqplot.default_legend( :options => { - :seriesDefaults => { - :renderer => 'jQuery.jqplot.PieRenderer', - :rendererOptions => {:showDataLabels => true} + :seriesdefaults => { + :renderer => 'jquery.jqplot.pierenderer', + :rendereroptions => {:showdatalabels => true} }, :series => [] }, diff --git a/lib/report_formatter/chart_common.rb b/lib/report_formatter/chart_common.rb index e3fbac08271..4784ff431da 100644 --- a/lib/report_formatter/chart_common.rb +++ b/lib/report_formatter/chart_common.rb @@ -354,6 +354,7 @@ def build_reporting_chart_dim2 end def build_reporting_chart_dim2_numeric +<<<<<<< HEAD (sort1, sort2) = mri.sortby (keep, show_other) = keep_and_show_other @@ -413,10 +414,15 @@ def data_column_name col, aggreg = col.split(':', 2) "#{col}__#{aggreg}" ) +======= + # FIXME: styling + binding.pry +>>>>>>> 7d2022d... Reporting charts: allow creating concrete number charts. end def build_reporting_chart_other_numeric categories = [] +<<<<<<< HEAD (sort1,) = mri.sortby (keep, show_other) = keep_and_show_other sorted_data = mri.table.data.sort_by { |row| row[data_column_name] } @@ -439,16 +445,45 @@ def build_reporting_chart_other_numeric # Pie charts put categories in legend, else in axis labels limit = pie_type? ? LEGEND_LENGTH : LABEL_LENGTH +======= + + model, col = mri.graph[:column].split('-', 2) + col, aggreg = col.split(':', 2) + data_col_name = "#{col}__#{aggreg}" + + sorted_data = mri.table.data.sort_by { |row| row[data_col_name] } + + series = sorted_data.reverse.take(mri.graph[:count]). + each_with_object(series_class.new(@is_pie_type ? :pie : :flat)) do |row, a| + + a.push(:value => row[data_col_name], + :tooltip => row[mri.col_order[0]]) + categories.push([row[mri.col_order[0]], row[data_col_name]]) + end + + if mri.graph[:other] + ocount = sorted_data[0, sorted_data.length - mri.graph[:count]]. + inject(0) { |sum, row| sum += row[data_col_name] } + series.push(:value => ocount, :tooltip => _('Other')) + categories.push([_('Other'), ocount]) + end + + # Pie charts put categories in legend, else in axis labels + limit = @is_pie_type ? LEGEND_LENGTH : LABEL_LENGTH +>>>>>>> 7d2022d... Reporting charts: allow creating concrete number charts. categories.collect! { |c| slice_legend(c[0], limit) } add_axis_category_text(categories) add_series(mri.headers[0], series) end +<<<<<<< HEAD def pie_type? @pie_type ||= mri.graph[:type] =~ /^(Pie|Donut)/ end +======= +>>>>>>> 7d2022d... Reporting charts: allow creating concrete number charts. def build_reporting_chart_other save_key = nil counter = 0 @@ -502,11 +537,11 @@ def build_util_ts_chart(maxcols, divider) build_util_ts_chart_column if %w(Column ColumnThreed).index(mri.graph[:type]) end - def build_reporting_chart_numeric(_maxcols, _divider) + def build_reporting_chart_numeric(maxcols, divider) mri.dims == 2 ? build_reporting_chart_dim2_numeric : build_reporting_chart_other_numeric end - def build_reporting_chart(_maxcols, _divider) + def build_reporting_chart(maxcols, divider) mri.dims == 2 ? build_reporting_chart_dim2 : build_reporting_chart_other end end diff --git a/lib/report_formatter/jqplot.rb b/lib/report_formatter/jqplot.rb index 499b86354b7..309ba060c26 100644 --- a/lib/report_formatter/jqplot.rb +++ b/lib/report_formatter/jqplot.rb @@ -102,6 +102,11 @@ def build_util_ts_chart_column x_axis_category_labels end + def build_reporting_chart_dim2_numeric + # FIXME: styling + super + end + def build_reporting_chart_dim2 counts = super # FIXME: counts are passed for now, should handle this in a better way default_legend From dd5796ac9f3b9edb63539e880d5b4cc26d1b7cf6 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Thu, 16 Jul 2015 07:55:13 +0200 Subject: [PATCH 12/21] Report charts: implement charts with concrete numeric values. From 0e7f9d97e25153f7ea8057df8d02dafcac1c31e5 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Tue, 21 Jul 2015 11:50:43 +0200 Subject: [PATCH 13/21] Report charts: implement sum of "other" values for 2dim case. --- lib/report_formatter/chart_common.rb | 35 ---------------------------- 1 file changed, 35 deletions(-) diff --git a/lib/report_formatter/chart_common.rb b/lib/report_formatter/chart_common.rb index 4784ff431da..141d662a7a2 100644 --- a/lib/report_formatter/chart_common.rb +++ b/lib/report_formatter/chart_common.rb @@ -354,7 +354,6 @@ def build_reporting_chart_dim2 end def build_reporting_chart_dim2_numeric -<<<<<<< HEAD (sort1, sort2) = mri.sortby (keep, show_other) = keep_and_show_other @@ -414,15 +413,10 @@ def data_column_name col, aggreg = col.split(':', 2) "#{col}__#{aggreg}" ) -======= - # FIXME: styling - binding.pry ->>>>>>> 7d2022d... Reporting charts: allow creating concrete number charts. end def build_reporting_chart_other_numeric categories = [] -<<<<<<< HEAD (sort1,) = mri.sortby (keep, show_other) = keep_and_show_other sorted_data = mri.table.data.sort_by { |row| row[data_column_name] } @@ -445,45 +439,16 @@ def build_reporting_chart_other_numeric # Pie charts put categories in legend, else in axis labels limit = pie_type? ? LEGEND_LENGTH : LABEL_LENGTH -======= - - model, col = mri.graph[:column].split('-', 2) - col, aggreg = col.split(':', 2) - data_col_name = "#{col}__#{aggreg}" - - sorted_data = mri.table.data.sort_by { |row| row[data_col_name] } - - series = sorted_data.reverse.take(mri.graph[:count]). - each_with_object(series_class.new(@is_pie_type ? :pie : :flat)) do |row, a| - - a.push(:value => row[data_col_name], - :tooltip => row[mri.col_order[0]]) - categories.push([row[mri.col_order[0]], row[data_col_name]]) - end - - if mri.graph[:other] - ocount = sorted_data[0, sorted_data.length - mri.graph[:count]]. - inject(0) { |sum, row| sum += row[data_col_name] } - series.push(:value => ocount, :tooltip => _('Other')) - categories.push([_('Other'), ocount]) - end - - # Pie charts put categories in legend, else in axis labels - limit = @is_pie_type ? LEGEND_LENGTH : LABEL_LENGTH ->>>>>>> 7d2022d... Reporting charts: allow creating concrete number charts. categories.collect! { |c| slice_legend(c[0], limit) } add_axis_category_text(categories) add_series(mri.headers[0], series) end -<<<<<<< HEAD def pie_type? @pie_type ||= mri.graph[:type] =~ /^(Pie|Donut)/ end -======= ->>>>>>> 7d2022d... Reporting charts: allow creating concrete number charts. def build_reporting_chart_other save_key = nil counter = 0 From 085345484e93d1502946e7863bdf83ec27b376a1 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Tue, 21 Jul 2015 16:45:31 +0200 Subject: [PATCH 14/21] Report charts: cleanups --- lib/report_formatter/chart_common.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/report_formatter/chart_common.rb b/lib/report_formatter/chart_common.rb index 141d662a7a2..4e17fab1540 100644 --- a/lib/report_formatter/chart_common.rb +++ b/lib/report_formatter/chart_common.rb @@ -417,12 +417,12 @@ def data_column_name def build_reporting_chart_other_numeric categories = [] - (sort1,) = mri.sortby + (sort1, _) = mri.sortby (keep, show_other) = keep_and_show_other sorted_data = mri.table.data.sort_by { |row| row[data_column_name] } series = sorted_data.reverse.take(keep) - .each_with_object(series_class.new(pie_type? ? :pie : :flat)) do |row, a| + .each_with_object(series_class.new(is_pie_type ? :pie : :flat)) do |row, a| tooltip = row[sort1] tooltip = _('no value') if tooltip.blank? a.push(:value => row[data_column_name], From a3e3cf5f5b8dd5a7ca26c7a745d0a366ffbcb76a Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Wed, 22 Jul 2015 11:13:42 +0200 Subject: [PATCH 15/21] jqplot charting: fix a regression in pie sample chart. --- lib/charting/jqplot.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/charting/jqplot.rb b/lib/charting/jqplot.rb index 237153476d6..87b45e6da53 100644 --- a/lib/charting/jqplot.rb +++ b/lib/charting/jqplot.rb @@ -85,9 +85,9 @@ def basic_chart(chart_type) when 'Pie' Jqplot.default_legend( :options => { - :seriesdefaults => { - :renderer => 'jquery.jqplot.pierenderer', - :rendereroptions => {:showdatalabels => true} + :seriesDefaults => { + :renderer => 'jQuery.jqplot.PieRenderer', + :rendererOptions => {:showDataLabels => true} }, :series => [] }, From 6c22479906ff66ee3a115a38851d219308892bbf Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Wed, 22 Jul 2015 11:14:43 +0200 Subject: [PATCH 16/21] Charting: handle empty values better. --- lib/report_formatter/chart_common.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/report_formatter/chart_common.rb b/lib/report_formatter/chart_common.rb index 4e17fab1540..b829e6a7180 100644 --- a/lib/report_formatter/chart_common.rb +++ b/lib/report_formatter/chart_common.rb @@ -421,8 +421,11 @@ def build_reporting_chart_other_numeric (keep, show_other) = keep_and_show_other sorted_data = mri.table.data.sort_by { |row| row[data_column_name] } + series = sorted_data.reverse.take(keep). + each_with_object(series_class.new(is_pie_type ? :pie : :flat)) do |row, a| + series = sorted_data.reverse.take(keep) - .each_with_object(series_class.new(is_pie_type ? :pie : :flat)) do |row, a| + .each_with_object(series_class.new(pie_type? ? :pie : :flat)) do |row, a| tooltip = row[sort1] tooltip = _('no value') if tooltip.blank? a.push(:value => row[data_column_name], From 6e5a0d9580f547b3d9c877f1216d52f1b2bb47b6 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Thu, 23 Jul 2015 19:48:16 +0200 Subject: [PATCH 17/21] Report charts: style cleanups. --- lib/report_formatter/chart_common.rb | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/report_formatter/chart_common.rb b/lib/report_formatter/chart_common.rb index b829e6a7180..bf8121753de 100644 --- a/lib/report_formatter/chart_common.rb +++ b/lib/report_formatter/chart_common.rb @@ -417,13 +417,10 @@ def data_column_name def build_reporting_chart_other_numeric categories = [] - (sort1, _) = mri.sortby + (sort1,) = mri.sortby (keep, show_other) = keep_and_show_other sorted_data = mri.table.data.sort_by { |row| row[data_column_name] } - series = sorted_data.reverse.take(keep). - each_with_object(series_class.new(is_pie_type ? :pie : :flat)) do |row, a| - series = sorted_data.reverse.take(keep) .each_with_object(series_class.new(pie_type? ? :pie : :flat)) do |row, a| tooltip = row[sort1] @@ -434,8 +431,8 @@ def build_reporting_chart_other_numeric end if show_other - other_sum = Array(sorted_data[0, sorted_data.length - keep]). - inject(0) { |sum, row| sum += row[data_column_name] } + other_sum = Array(sorted_data[0, sorted_data.length - keep]) + .inject(0) { |sum, row| sum + row[data_column_name] } series.push(:value => other_sum, :tooltip => _('Other')) categories.push([_('Other'), other_sum]) end @@ -505,11 +502,11 @@ def build_util_ts_chart(maxcols, divider) build_util_ts_chart_column if %w(Column ColumnThreed).index(mri.graph[:type]) end - def build_reporting_chart_numeric(maxcols, divider) + def build_reporting_chart_numeric(_maxcols, _divider) mri.dims == 2 ? build_reporting_chart_dim2_numeric : build_reporting_chart_other_numeric end - def build_reporting_chart(maxcols, divider) + def build_reporting_chart(_maxcols, _divider) mri.dims == 2 ? build_reporting_chart_dim2 : build_reporting_chart_other end end From 3d38dbe252f9d3a930e64cd02d4ab2adcae81d49 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Fri, 24 Jul 2015 11:38:29 +0200 Subject: [PATCH 18/21] Report charts: fixes after rebase. --- lib/report_formatter/jqplot.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/report_formatter/jqplot.rb b/lib/report_formatter/jqplot.rb index 309ba060c26..499b86354b7 100644 --- a/lib/report_formatter/jqplot.rb +++ b/lib/report_formatter/jqplot.rb @@ -102,11 +102,6 @@ def build_util_ts_chart_column x_axis_category_labels end - def build_reporting_chart_dim2_numeric - # FIXME: styling - super - end - def build_reporting_chart_dim2 counts = super # FIXME: counts are passed for now, should handle this in a better way default_legend From 25e9b2926b33cbe1082efdb78d4fef31889a20a4 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Tue, 4 Aug 2015 23:00:53 +0200 Subject: [PATCH 19/21] Report charts: add js options to eval. --- app/assets/javascripts/miq_jqplot.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/assets/javascripts/miq_jqplot.js b/app/assets/javascripts/miq_jqplot.js index ad8029e2b42..08c863fb1e5 100644 --- a/app/assets/javascripts/miq_jqplot.js +++ b/app/assets/javascripts/miq_jqplot.js @@ -17,6 +17,9 @@ function _jqplot_eval_option(data, option) { function jqplot_process_options(data) { $.each([ 'seriesDefaults.renderer', 'axes.xaxis.renderer', + 'axes.yaxis.tickRenderer', + 'axes.yaxis.renderer', + 'axes.xaxis.tickRenderer', 'legend.renderer', 'highlighter.tooltipContentEditor' ], function (index, key) { _jqplot_eval_option(data, key); From fd2d4ee5c227aa327e3f9e312491247b9108f5e1 Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Tue, 4 Aug 2015 23:02:26 +0200 Subject: [PATCH 20/21] WIP --- app/helpers/report_helper.rb | 13 +-- lib/report_formatter/chart_common.rb | 4 +- .../report_formater/jqplot_formater_spec.rb | 81 ++++++++++++++----- 3 files changed, 69 insertions(+), 29 deletions(-) diff --git a/app/helpers/report_helper.rb b/app/helpers/report_helper.rb index eda00bebe1c..a238ee26621 100644 --- a/app/helpers/report_helper.rb +++ b/app/helpers/report_helper.rb @@ -27,13 +27,14 @@ def visibility_options(widget) end def chart_fields_options - # @edit[:pivot_cols] => {"Vm-mem_cpu"=>[:avg, :total]} - options = [] - @edit[:pivot_cols].each do |field, agreg| - agreg.each do |fun| - options << ["#{field} (#{fun.to_s.titleize})", "#{field}:#{fun}"] + if @edit[:pivot_cols].empty? + @edit[:new][:fields] + else + @edit[:pivot_cols].each_with_object([]) do |(field, agreg), options| + agreg.each do |fun| + options << ["#{field} (#{fun.to_s.titleize})", "#{field}:#{fun}"] + end end end - options end end diff --git a/lib/report_formatter/chart_common.rb b/lib/report_formatter/chart_common.rb index bf8121753de..a7f8b4057e9 100644 --- a/lib/report_formatter/chart_common.rb +++ b/lib/report_formatter/chart_common.rb @@ -411,7 +411,7 @@ def data_column_name @data_column_name ||= ( _model, col = mri.graph[:column].split('-', 2) col, aggreg = col.split(':', 2) - "#{col}__#{aggreg}" + aggreg.blank? ? col : "#{col}__#{aggreg}" ) end @@ -419,7 +419,7 @@ def build_reporting_chart_other_numeric categories = [] (sort1,) = mri.sortby (keep, show_other) = keep_and_show_other - sorted_data = mri.table.data.sort_by { |row| row[data_column_name] } + sorted_data = mri.table.data.sort_by { |row| row[data_column_name] || 0 } series = sorted_data.reverse.take(keep) .each_with_object(series_class.new(pie_type? ? :pie : :flat)) do |row, a| diff --git a/spec/lib/report_formater/jqplot_formater_spec.rb b/spec/lib/report_formater/jqplot_formater_spec.rb index 09ea8926eac..ae7bc646928 100644 --- a/spec/lib/report_formater/jqplot_formater_spec.rb +++ b/spec/lib/report_formater/jqplot_formater_spec.rb @@ -15,28 +15,28 @@ end context '#build_reporting_chart_other_numeric' do - [true, false].each do |other| - it "builds 2d numeric charts #{other ? 'with' : 'without'} 'other'" do + context 'report w/o grouping' do + it "builds 2d numeric charts" do FactoryGirl.create(:vm_vmware, :host => host = FactoryGirl.create(:host, :name => 'host')) - report = MiqReport.new( - :db => "Vm", - :sortby => ["host_name"], - :order => "Descending", - :cols => %w(mem_cpu host_name), - :include => {}, - :col_order => %w(mem_cpu__total host_name), - :headers => ["Parent Host", "Memory (Avg)", "Memory (Total)", "OS Product Type"], - :dims => 1, - :rpt_options => {:pivot => {:group_cols => ["host_name"]}}, - :graph => {:type => "Column", :mode => "values", :column => "Vm-mem_cpu:total", :count => 10, :other => other} - ) + #report = MiqReport.new( + # :db => "Vm", + # :sortby => ["host_name"], + # :order => "Descending", + # :cols => %w(mem_cpu host_name), + # :include => {}, + # :col_order => %w(mem_cpu__total host_name), + # :headers => ["Parent Host", "Memory (Avg)", "Memory (Total)", "OS Product Type"], + # :dims => 1, + # :rpt_options => {:pivot => {:group_cols => ["host_name"]}}, + # :graph => {:type => "Column", :mode => "values", :column => "Vm-mem_cpu:total", :count => 10, :other => other} + #) - report.generate_table(:userid => 'test') - report.table = Struct.new(:data).new - report.table.data = [ - Ruport::Data::Record.new("mem_cpu__total" => 0.0, "host_name" => "host") - ] + #report.generate_table(:userid => 'test') + #report.table = Struct.new(:data).new + #report.table.data = [ + # Ruport::Data::Record.new("mem_cpu__total" => 0.0, "host_name" => "host") + #] expect_any_instance_of(described_class).to receive(:build_reporting_chart_other_numeric).once.and_call_original @@ -47,8 +47,47 @@ e.options.theme = 'miq' end - expect(report.chart[:data][0][0]).to eq(0.0) - expect(report.chart[:options][:axes][:xaxis][:ticks][0]).to eq(host.name) + #expect(report.chart[:data][0][0]).to eq(0.0) + #expect(report.chart[:options][:axes][:xaxis][:ticks][0]).to eq(host.name) + end + end + + context 'report with grouping' do + [true, false].each do |other| + it "builds 2d numeric charts #{other ? 'with' : 'without'} 'other'" do + FactoryGirl.create(:vm_vmware, :host => host = FactoryGirl.create(:host, :name => 'host')) + + report = MiqReport.new( + :db => "Vm", + :sortby => ["host_name"], + :order => "Descending", + :cols => %w(mem_cpu host_name), + :include => {}, + :col_order => %w(mem_cpu__total host_name), + :headers => ["Parent Host", "Memory (Avg)", "Memory (Total)", "OS Product Type"], + :dims => 1, + :rpt_options => {:pivot => {:group_cols => ["host_name"]}}, + :graph => {:type => "Column", :mode => "values", :column => "Vm-mem_cpu:total", :count => 10, :other => other} + ) + + report.generate_table(:userid => 'test') + report.table = Struct.new(:data).new + report.table.data = [ + Ruport::Data::Record.new("mem_cpu__total" => 0.0, "host_name" => "host") + ] + + expect_any_instance_of(described_class).to receive(:build_reporting_chart_other_numeric).once.and_call_original + + ReportFormatter::ReportRenderer.render(Charting.format) do |e| + e.options.mri = report + e.options.show_title = true + e.options.graph_options = MiqReport.graph_options(600, 400) + e.options.theme = 'miq' + end + + expect(report.chart[:data][0][0]).to eq(0.0) + expect(report.chart[:options][:axes][:xaxis][:ticks][0]).to eq(host.name) + end end end end From d211fa34f58557cec56e1dcc72032c3ae717b79f Mon Sep 17 00:00:00 2001 From: Martin Povolny Date: Fri, 7 Aug 2015 06:35:14 +0200 Subject: [PATCH 21/21] report editor fix --- app/controllers/report_controller/reports/editor.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/report_controller/reports/editor.rb b/app/controllers/report_controller/reports/editor.rb index d99017573ff..2a745ff2c4e 100644 --- a/app/controllers/report_controller/reports/editor.rb +++ b/app/controllers/report_controller/reports/editor.rb @@ -680,8 +680,8 @@ def gfv_charts if params[:chart_mode] && params[:chart_mode] != @edit[:new][:chart_mode] @edit[:new][:chart_mode] = params[:chart_mode] - @refresh_div = "chart_sample_div" - @refresh_partial = "form_chart_sample" + @refresh_div = "chart_div" + @refresh_partial = "form_chart" end if params[:chart_column] && params[:chart_column] != @edit[:new][:chart_column]