apexcharts 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +248 -52
  3. data/lib/apexcharts.rb +2 -1
  4. data/lib/apexcharts/charts.rb +11 -18
  5. data/lib/apexcharts/charts/base.rb +19 -18
  6. data/lib/apexcharts/charts/bubble.rb +2 -8
  7. data/lib/apexcharts/charts/cartesian.rb +30 -29
  8. data/lib/apexcharts/charts/donut.rb +0 -1
  9. data/lib/apexcharts/charts/features/annotations.rb +16 -17
  10. data/lib/apexcharts/charts/features/mixable.rb +1 -2
  11. data/lib/apexcharts/charts/heatmap.rb +2 -4
  12. data/lib/apexcharts/charts/mixed.rb +42 -32
  13. data/lib/apexcharts/charts/pie.rb +0 -1
  14. data/lib/apexcharts/charts/polar.rb +2 -9
  15. data/lib/apexcharts/charts/radar.rb +2 -4
  16. data/lib/apexcharts/charts/radial_bar.rb +0 -1
  17. data/lib/apexcharts/charts/syncing.rb +39 -25
  18. data/lib/apexcharts/colors.rb +4 -6
  19. data/lib/apexcharts/config.rb +25 -0
  20. data/lib/apexcharts/config/default_options.rb +12 -0
  21. data/lib/apexcharts/helper.rb +151 -87
  22. data/lib/apexcharts/options/annotations.rb +5 -5
  23. data/lib/apexcharts/options/axis.rb +12 -12
  24. data/lib/apexcharts/options/chart.rb +21 -21
  25. data/lib/apexcharts/options/data_labels.rb +9 -7
  26. data/lib/apexcharts/options/div_attributes.rb +4 -5
  27. data/lib/apexcharts/options/fill.rb +7 -7
  28. data/lib/apexcharts/options/grid.rb +10 -10
  29. data/lib/apexcharts/options/legend.rb +22 -19
  30. data/lib/apexcharts/options/markers.rb +13 -13
  31. data/lib/apexcharts/options/no_data.rb +7 -7
  32. data/lib/apexcharts/options/plot_options.rb +7 -7
  33. data/lib/apexcharts/options/root.rb +30 -30
  34. data/lib/apexcharts/options/states.rb +4 -4
  35. data/lib/apexcharts/options/stroke.rb +7 -7
  36. data/lib/apexcharts/options/subtitle.rb +3 -1
  37. data/lib/apexcharts/options/theme.rb +3 -3
  38. data/lib/apexcharts/options/title.rb +8 -8
  39. data/lib/apexcharts/options/tooltip.rb +17 -17
  40. data/lib/apexcharts/options/x_axis.rb +5 -5
  41. data/lib/apexcharts/options/y_axis.rb +8 -8
  42. data/lib/apexcharts/options_builder.rb +49 -60
  43. data/lib/apexcharts/prefix_with_apex.rb +5 -0
  44. data/lib/apexcharts/prefixer.rb +19 -0
  45. data/lib/apexcharts/renderer.rb +64 -17
  46. data/lib/apexcharts/series.rb +5 -3
  47. data/lib/apexcharts/series/bubble.rb +33 -22
  48. data/lib/apexcharts/series/cartesian.rb +63 -49
  49. data/lib/apexcharts/series/polar.rb +31 -17
  50. data/lib/apexcharts/support/rails.rb +1 -1
  51. data/lib/apexcharts/support/sinatra.rb +9 -0
  52. data/lib/apexcharts/theme.rb +5 -6
  53. data/lib/apexcharts/utils.rb +1 -0
  54. data/lib/apexcharts/utils/copy.rb +9 -0
  55. data/lib/apexcharts/utils/date_time.rb +50 -44
  56. data/lib/apexcharts/utils/hash.rb +2 -3
  57. data/lib/apexcharts/version.rb +1 -1
  58. data/vendor/assets/javascripts/apexcharts.js +2 -2
  59. metadata +27 -7
@@ -0,0 +1,5 @@
1
+ require_relative 'config'
2
+
3
+ ApexCharts.helper_prefix = 'apex_'
4
+
5
+ require_relative '../apexcharts'
@@ -0,0 +1,19 @@
1
+ module ApexCharts
2
+ module Prefixer
3
+ def self.extended(helper)
4
+ @@helper = helper
5
+ end
6
+
7
+ def with_prefix(&block)
8
+ @@prefixed = Module.new(&block)
9
+
10
+ unless [nil, ''].include? ApexCharts.helper_prefix
11
+ (@@prefixed.instance_methods - @@helper.instance_methods).each do |method|
12
+ @@prefixed.send(:alias_method, "#{ApexCharts.helper_prefix}#{method}", method)
13
+ @@prefixed.send(:remove_method, method)
14
+ end
15
+ end
16
+ @@helper.send(:include, @@prefixed)
17
+ end
18
+ end
19
+ end
@@ -1,21 +1,68 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json' unless defined? JSON
4
-
5
- class ApexCharts::Renderer
6
- def self.render_default(options)
7
- attributes = options.delete(:div) { {} }
8
- variable = attributes.delete(:var) { "chart#{attributes[:id]&.[](/\d+/)}" }
9
- element_id = attributes.delete(:id)
10
- css_class = attributes.delete(:class)
11
- height = "#{options[:chart][:height].to_i}px"
12
- style = "height: #{height}; #{attributes.delete(:style)}"
13
- html =<<~HTML
14
- <div id="#{element_id}" class="#{css_class}" style="#{style}"></div>
15
- <script type="text/javascript">
16
- var #{variable} = new ApexCharts(document.querySelector("##{element_id}"), #{options.to_json});
17
- #{variable}.render();
18
- </script>
19
- HTML
3
+ require 'json'
4
+
5
+ module ApexCharts
6
+ class Renderer
7
+ class << self
8
+ def render_default(options)
9
+ renderer = new options
10
+
11
+ html = if renderer.id_number == '1' && !ApexCharts.config.default_options.empty?
12
+ renderer.window_apex
13
+ else
14
+ ''
15
+ end
16
+ html + <<~HTML
17
+ <div id="#{renderer.element_id}" class="#{renderer.css_class}" style="#{renderer.style}"></div>
18
+ <script type="text/javascript">
19
+ var #{renderer.variable} = new ApexCharts(document.querySelector("##{renderer.element_id}"), #{renderer.options.to_json});
20
+ #{renderer.variable}.render();
21
+ </script>
22
+ HTML
23
+ end
24
+ end
25
+
26
+ attr_reader :options
27
+
28
+ def initialize(options)
29
+ @options = options
30
+ end
31
+
32
+ def attributes
33
+ @attributes ||= options.delete(:div) { {} }
34
+ end
35
+
36
+ def element_id
37
+ @element_id ||= attributes.delete(:id)
38
+ end
39
+
40
+ def id_number
41
+ @id_number ||= element_id&.[](/\d+/)
42
+ end
43
+
44
+ def variable
45
+ @variable ||= attributes.delete(:var) { "chart#{id_number}" }
46
+ end
47
+
48
+ def css_class
49
+ attributes.delete(:class)
50
+ end
51
+
52
+ def height
53
+ "#{options[:chart][:height].to_i}px"
54
+ end
55
+
56
+ def style
57
+ "height: #{height}; #{attributes.delete(:style)}"
58
+ end
59
+
60
+ def window_apex
61
+ <<~HTML
62
+ <script type="text/javascript">
63
+ window.Apex = #{ApexCharts.config.default_options.to_json}
64
+ </script>
65
+ HTML
66
+ end
20
67
  end
21
68
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'series/cartesian'
4
- require_relative 'series/bubble'
5
- require_relative 'series/polar'
3
+ module ApexCharts
4
+ %w(cartesian bubble polar).each do |type|
5
+ autoload :"#{type.capitalize}Series", "apexcharts/series/#{type}.rb"
6
+ end
7
+ end
@@ -1,37 +1,48 @@
1
+ require_relative '../utils/copy'
2
+
1
3
  module ApexCharts
2
4
  class BubbleSeries
5
+ include Utils::Copy
6
+
3
7
  attr_reader :sanitized
4
8
 
5
9
  def initialize(data)
6
10
  data = deep_copy(data)
7
- @sanitized = case data
8
- when Array
9
- if array_of_threes?(data)
10
- [{data: data}]
11
- else
12
- data
13
- end
14
-
15
- when Hash
16
- if data_value = data[:data]
17
- if array_of_threes?(data_value)
18
- [data]
19
- end
20
- end
21
-
22
- end
23
-
24
- @sanitized = {series: @sanitized}
11
+ sanitized =
12
+ case data
13
+ when Array
14
+ if array_of_threes?(data)
15
+ [{data: data}]
16
+ else
17
+ data
18
+ end
19
+
20
+ when Hash
21
+ if data_value = data[:data]
22
+ [data] if array_of_threes?(data_value)
23
+ end
24
+
25
+ end
26
+
27
+ @sanitized = {series: sanitized}
25
28
  end
26
29
 
27
- def deep_copy(data)
28
- Marshal.load(Marshal.dump(data))
30
+ def sample
31
+ return if empty?
32
+
33
+ sanitized[:series][0][:data][0]
34
+ end
35
+
36
+ private
37
+
38
+ def empty?
39
+ sanitized[:series].empty? || sanitized[:series][0][:data].empty?
29
40
  end
30
41
 
31
42
  def array_of_threes?(data)
32
43
  return false if data.empty?
33
- data.all?{|d| d.length == 3 }
44
+
45
+ data.all? {|d| d.length == 3 }
34
46
  end
35
47
  end
36
48
  end
37
-
@@ -1,65 +1,79 @@
1
+ require_relative '../utils/copy'
2
+
1
3
  module ApexCharts
2
4
  class CartesianSeries
5
+ include Utils::Copy
6
+
3
7
  attr_reader :sanitized
4
8
 
5
9
  def initialize(data)
6
- data = deep_copy(data)
7
- @sanitized = case data
8
- when Array
9
- case first_data = data[0]
10
- when Array
11
- [
12
- {
13
- data: array_of_array_to_array_of_xy(data)
14
- }
15
- ]
16
-
17
- when Hash
18
- if first_data[:data]
19
- data.each{|h| h[:data] = array_of_array_to_array_of_xy(h[:data]) }
20
- data
21
- end
22
-
23
- end
24
-
25
- when Hash
26
- if data_value = data[:data]
27
- if array_of_pairs?(data_value)
28
- data[:data] = array_of_array_to_array_of_xy(data_value)
29
- [data]
30
- end
31
-
32
- else
33
- if data[:x] && data[:y]
34
- [{data: [data]}]
35
-
36
- else
37
- [
38
- {
39
- data: data.map do |k,v|
40
- {x: k, y: v}
41
- end
42
- }
43
- ]
44
-
45
- end
46
- end
47
- end
48
-
49
- @sanitized = {series: @sanitized}
10
+ @sanitized = {series: build_series(deep_copy(data))}
11
+ end
12
+
13
+ def sample
14
+ return if empty?
15
+
16
+ sanitized[:series][0][:data][0][:x]
17
+ end
18
+
19
+ private
20
+
21
+ def empty?
22
+ sanitized[:series].empty? || sanitized[:series][0][:data].empty?
23
+ end
24
+
25
+ def build_series(data)
26
+ return data if data.empty?
27
+
28
+ case data
29
+ when Array
30
+ build_series_from_array(data)
31
+ when Hash
32
+ build_series_from_hash(data)
33
+ end
50
34
  end
51
35
 
52
- def deep_copy(data)
53
- Marshal.load(Marshal.dump(data))
36
+ def build_series_from_array(data)
37
+ case first_data = data[0]
38
+ when Array
39
+ [{data: array_of_array_to_array_of_xy(data)}]
40
+
41
+ when Hash
42
+ if first_data[:data]
43
+ data.each {|h| h[:data] = array_of_array_to_array_of_xy(h[:data]) }
44
+ data
45
+ end
46
+ end
47
+ end
48
+
49
+ def build_series_from_hash(data)
50
+ if data_value = data[:data]
51
+ if array_of_pairs?(data_value)
52
+ data[:data] = array_of_array_to_array_of_xy(data_value)
53
+ [data]
54
+ end
55
+
56
+ elsif data[:x] && data[:y]
57
+ [{data: [data]}]
58
+
59
+ else
60
+ [
61
+ {
62
+ data: data.map do |key, value|
63
+ {x: key, y: value}
64
+ end
65
+ }
66
+ ]
67
+
68
+ end
54
69
  end
55
70
 
56
71
  def array_of_pairs?(data)
57
- !data.empty? && data.all?{|d| d.length == 2 }
72
+ !data.empty? && data.all? {|d| d.length == 2 }
58
73
  end
59
74
 
60
75
  def array_of_array_to_array_of_xy(data)
61
- data.map{|d| {x: d.first, y: d.last} }
76
+ data.map {|d| {x: d.first, y: d.last} }
62
77
  end
63
78
  end
64
79
  end
65
-
@@ -1,22 +1,13 @@
1
+ require_relative '../utils/copy'
2
+
1
3
  module ApexCharts
2
4
  class PolarSeries
5
+ include Utils::Copy
6
+
3
7
  attr_reader :sanitized
4
8
 
5
9
  def initialize(data)
6
- @labels = []
7
- data = deep_copy(data)
8
- if data.is_a? Array
9
- if data.first.is_a? Numeric
10
- @series = data
11
- elsif data.first.is_a? Hash
12
- @labels = data.map{|m| m[:name] }.compact
13
- @series = data.map{|m| m[:data] }
14
- end
15
- elsif data.is_a? Hash
16
- if data[:data].is_a? Array
17
- @series = data[:data]
18
- end
19
- end
10
+ build_labels_and_series(deep_copy(data))
20
11
 
21
12
  @sanitized = {
22
13
  labels: @labels.empty? ? nil : @labels,
@@ -24,9 +15,32 @@ module ApexCharts
24
15
  }.compact
25
16
  end
26
17
 
27
- def deep_copy(data)
28
- Marshal.load(Marshal.dump(data))
18
+ def sample
19
+ return if empty?
20
+
21
+ sanitized[:series][0]
22
+ end
23
+
24
+ private
25
+
26
+ def empty?
27
+ sanitized[:series].nil? || sanitized[:series][0].nil?
28
+ end
29
+
30
+ def build_labels_and_series(data)
31
+ @labels = []
32
+ case data
33
+ when Array
34
+ case data.first
35
+ when Numeric
36
+ @series = data
37
+ when Hash
38
+ @labels = data.map {|m| m[:name] }.compact
39
+ @series = data.map {|m| m[:data] }
40
+ end
41
+ when Hash
42
+ @series = data[:data] if data[:data].is_a? Array
43
+ end
29
44
  end
30
45
  end
31
46
  end
32
-
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ApexCharts
4
4
  class Engine < ::Rails::Engine
5
- initializer "helper" do |app|
5
+ initializer 'helper' do
6
6
  ActiveSupport.on_load(:action_view) do
7
7
  include Helper
8
8
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sinatra
4
+ module ApexCharts
5
+ include ::ApexCharts::Helper
6
+ end
7
+
8
+ helpers ApexCharts
9
+ end
@@ -4,17 +4,17 @@ require_relative 'colors'
4
4
 
5
5
  module ApexCharts
6
6
  class Theme
7
- PALETTES = ["palette1", "palette2", "palette3", "palette4", "palette5",
8
- "palette6", "palette7", "palette8", "palette9", "palette10"]
7
+ PALETTES = %w(palette1 palette2 palette3 palette4 palette5
8
+ palette6 palette7 palette8 palette9 palette10).freeze
9
9
 
10
10
  @custom_palettes = {}
11
11
 
12
12
  module ClassMethods
13
- def create palette_name, colors
13
+ def create(palette_name, colors)
14
14
  palettes[palette_name] = Colors.new colors
15
15
  end
16
16
 
17
- def destroy palette_name
17
+ def destroy(palette_name)
18
18
  palettes.delete palette_name
19
19
  end
20
20
 
@@ -44,7 +44,7 @@ module ApexCharts
44
44
  include ClassMethods
45
45
 
46
46
  def custom_palettes
47
- ApexCharts::Theme.palettes.merge(super)
47
+ Theme.palettes.merge(super)
48
48
  end
49
49
 
50
50
  def palettes
@@ -58,4 +58,3 @@ module ApexCharts
58
58
  extend ClassMethods
59
59
  end
60
60
  end
61
-
@@ -2,3 +2,4 @@
2
2
 
3
3
  require_relative 'utils/date_time'
4
4
  require_relative 'utils/hash'
5
+ require_relative 'utils/copy'