From 2830e96f7f35bb09fb977694a4536f4cfc94704e Mon Sep 17 00:00:00 2001 From: "Andrew S. Brown" Date: Fri, 10 Oct 2014 23:38:47 -0700 Subject: [PATCH] support mutliple series organized as a hash of series --- lib/chartnado/renderer.rb | 45 +++++++++++++++++++-------------------- spec/renderer_spec.rb | 12 +++++++++++ 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/lib/chartnado/renderer.rb b/lib/chartnado/renderer.rb index 8c94258..78e988a 100644 --- a/lib/chartnado/renderer.rb +++ b/lib/chartnado/renderer.rb @@ -11,7 +11,7 @@ def initialize(context, data_block, &render_block) delegate :controller, to: :context - def render(*args, **options) + def render(*args, ** options) json_options = {} chartkick_options = options.dup @@ -40,7 +40,7 @@ def render(*args, **options) } if options[:wrapper_proc] - context.instance_exec(*args, renderer, **options, &options[:wrapper_proc]) + context.instance_exec(*args, renderer, ** options, &options[:wrapper_proc]) else renderer.call end @@ -49,32 +49,33 @@ def render(*args, **options) def chart_json(series, show_total: false, reverse_sort: false, percentage: false) series = Chartnado::Series::Wrap[series] series *= 100.0 if percentage - if series.hash? - if (key = series.keys.first) and key.is_a?(Array) and key.size == 2 + if series.has_separate_named_series? + series = series.to_a + if series.first.second.respond_to?(:map) totals = Hash.new(0.0) - new_series = series.group_by{|k, v| k[0] }.sort_by { |k| k.to_s } + new_series = series.sort_by { |item| item.first.to_s } new_series = new_series.reverse if reverse_sort new_series = new_series.map do |name, data| { name: name, data: data.map do |k, v| - totals[k[1]] += v if show_total - [k[1], v] + totals[k] += v if show_total + [k, v] end } end if show_total [{name: 'Total', - data: totals.map {|k,v| [k, 0] }, - tooltip: totals.map {|k,v| [k, v] } + data: totals.map { |k, v| [k, 0] }, + tooltip: totals.map { |k, v| [k, v] } }] + new_series else new_series end else - new_series = series.sort_by { |key| key.to_s } + new_series = series.sort_by { |item| item.first.to_s } new_series = new_series.reverse if reverse_sort if show_total @@ -83,32 +84,32 @@ def chart_json(series, show_total: false, reverse_sort: false, percentage: false new_series end end - elsif series.array? && series.first.is_a?(Array) - if series.first.second.respond_to?(:map) + elsif series.hash? + if (key = series.keys.first) and key.is_a?(Array) and key.size == 2 totals = Hash.new(0.0) - new_series = series.sort_by { |item| item.first.to_s } + new_series = series.group_by { |k, v| k[0] }.sort_by { |k| k.to_s } new_series = new_series.reverse if reverse_sort new_series = new_series.map do |name, data| { name: name, data: data.map do |k, v| - totals[k] += v if show_total - [k, v] + totals[k[1]] += v if show_total + [k[1], v] end } end if show_total [{name: 'Total', - data: totals.map {|k,v| [k, 0] }, - tooltip: totals.map {|k,v| [k, v] } + data: totals.map { |k, v| [k, 0] }, + tooltip: totals.map { |k, v| [k, v] } }] + new_series else new_series end else - new_series = series.sort_by { |item| item.first.to_s } + new_series = series.sort_by { |key| key.to_s } new_series = new_series.reverse if reverse_sort if show_total @@ -117,12 +118,10 @@ def chart_json(series, show_total: false, reverse_sort: false, percentage: false new_series end end + elsif series.respond_to?(:map) + series else - if series.respond_to?(:map) - series - else - [['Total', series]] - end + [['Total', series]] end end end diff --git a/spec/renderer_spec.rb b/spec/renderer_spec.rb index a90c652..849b12c 100644 --- a/spec/renderer_spec.rb +++ b/spec/renderer_spec.rb @@ -46,6 +46,18 @@ def chart_json(*series, **options) {name: :b, data: [[1, 20]]}] end end + describe "for multiple series organized as a hash" do + it "can generate chartkick compatible series" do + expect(chart_json({:a => {1 => 10}, :b => {1 => 20}})). + to eq [{name: :a, data: [[1, 10]]}, {name: :b, data: [[1,20]]}] + end + it "can add totals" do + expect(chart_json({:a => {1 => 10}, :b => {1 => 20}}, show_total: true)). + to eq [{name: 'Total', data: [[1, 0]], tooltip: [[1, 30.0]]}, + {name: :a, data: [[1, 10]]}, + {name: :b, data: [[1, 20]]}] + end + end describe "for data that is just a scalar" do it "shows the scalar as the total" do expect(chart_json(10)).