# http://bl.ocks.org/jensgrubert/7789216 # http://www.datavizcatalogue.com/methods/box_plot.html#.U0S8Ra1dUyE # http://mbostock.github.io/protovis/ex/box-and-whisker.html # http://bl.ocks.org/mbostock/4061502 # http://johan.github.io/d3/ex/box.html # http://johan.github.io/d3/ex/box.html # http://bl.ocks.org/mbostock/4061502 class RailsDataExplorer class Chart class BoxPlotGroup < Chart # TODO: imitate this: # http://www.stata.com/support/faqs/graphics/gph/graphdocs/horizontal-box-plot-of-variable-by-values-of-categorical-variable/ def initialize(_data_set, options = {}) @data_set = _data_set @options = {}.merge(options) end def compute_chart_attrs x_candidates = @data_set.data_series.find_all { |ds| (ds.chart_roles[Chart::BoxPlotGroup] & [:x, :any]).any? } y_candidates = @data_set.data_series.find_all { |ds| (ds.chart_roles[Chart::BoxPlotGroup] & [:y, :any]).any? } x_ds = x_candidates.first y_ds = (y_candidates - [x_ds]).first return false if x_ds.nil? || y_ds.nil? min = x_ds.min_val # get global min max = x_ds.max_val # get global max values_hash = y_ds.uniq_vals.inject({}) { |m,y_val| m[y_val] = [] m } y_ds.values.each_with_index { |y_val, idx| next if (y_val.nil? || Float::NAN == y_val) values_hash[y_val] << x_ds.values[idx] } y_sorted_keys = y_ds.uniq_vals.sort( &y_ds.label_sorter( nil, lambda { |a,b| a <=> b } ) ) sorted_values = y_sorted_keys.map { |y_val| values_hash[y_val] } { values: sorted_values, category_labels: y_sorted_keys, min: min, max: max, base_width: 120, base_height: 800, axis_tick_format: x_ds.axis_tick_format, num_box_plots: y_ds.uniq_vals_count, axis_scale: DataSeries.new('_', [min, max]).axis_scale(:d3) } end def render return '' unless render? ca = compute_chart_attrs return '' unless ca svg_trs = ca[:category_labels].map { |cat_label| %(