apexcharts 0.1.5 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +456 -38
  3. data/lib/apex_charts/charts.rb +16 -0
  4. data/lib/{apexcharts/charts/area.rb → apex_charts/charts/area_chart.rb} +1 -1
  5. data/lib/{apexcharts/charts/bar.rb → apex_charts/charts/bar_chart.rb} +1 -1
  6. data/lib/apex_charts/charts/base_chart.rb +37 -0
  7. data/lib/apex_charts/charts/bubble_chart.rb +13 -0
  8. data/lib/{apexcharts/charts/candlestick.rb → apex_charts/charts/candlestick_chart.rb} +1 -1
  9. data/lib/apex_charts/charts/cartesian_chart.rb +82 -0
  10. data/lib/{apexcharts/charts/column.rb → apex_charts/charts/column_chart.rb} +3 -1
  11. data/lib/{apexcharts/charts/donut.rb → apex_charts/charts/donut_chart.rb} +1 -2
  12. data/lib/{apexcharts → apex_charts}/charts/features/annotations.rb +22 -21
  13. data/lib/{apexcharts → apex_charts}/charts/features/mixable.rb +2 -3
  14. data/lib/{apexcharts/charts/heatmap.rb → apex_charts/charts/heatmap_chart.rb} +3 -5
  15. data/lib/{apexcharts/charts/line.rb → apex_charts/charts/line_chart.rb} +1 -1
  16. data/lib/apex_charts/charts/mixed_charts.rb +101 -0
  17. data/lib/{apexcharts/charts/pie.rb → apex_charts/charts/pie_chart.rb} +1 -2
  18. data/lib/apex_charts/charts/polar_chart.rb +9 -0
  19. data/lib/{apexcharts/charts/radar.rb → apex_charts/charts/radar_chart.rb} +3 -5
  20. data/lib/{apexcharts/charts/radial_bar.rb → apex_charts/charts/radial_bar_chart.rb} +1 -2
  21. data/lib/apex_charts/charts/range_bar_chart.rb +9 -0
  22. data/lib/{apexcharts/charts/scatter.rb → apex_charts/charts/scatter_chart.rb} +1 -1
  23. data/lib/apex_charts/charts/syncing_charts.rb +84 -0
  24. data/lib/apex_charts/colors.rb +27 -0
  25. data/lib/apex_charts/config/default_options.rb +16 -0
  26. data/lib/apex_charts/configuration.rb +25 -0
  27. data/lib/apex_charts/helper.rb +190 -0
  28. data/lib/apex_charts/options/annotations_options.rb +15 -0
  29. data/lib/apex_charts/options/chart_options.rb +32 -0
  30. data/lib/apex_charts/options/data_labels_options.rb +18 -0
  31. data/lib/apex_charts/options/div_attributes.rb +11 -0
  32. data/lib/apex_charts/options/fill_options.rb +14 -0
  33. data/lib/apex_charts/options/grid_options.rb +17 -0
  34. data/lib/apex_charts/options/legend_options.rb +32 -0
  35. data/lib/apex_charts/options/markers_options.rb +24 -0
  36. data/lib/apex_charts/options/no_data_options.rb +14 -0
  37. data/lib/apex_charts/options/plot_options.rb +16 -0
  38. data/lib/apex_charts/options/root_options.rb +47 -0
  39. data/lib/apex_charts/options/states_options.rb +11 -0
  40. data/lib/apex_charts/options/stroke_options.rb +14 -0
  41. data/lib/apex_charts/options/theme_options.rb +11 -0
  42. data/lib/apex_charts/options/title_subtitle_options.rb +15 -0
  43. data/lib/apex_charts/options/tooltip_options.rb +25 -0
  44. data/lib/apex_charts/options/x_axis_options.rb +26 -0
  45. data/lib/apex_charts/options/y_axis_options.rb +28 -0
  46. data/lib/{apexcharts → apex_charts}/options_builder.rb +95 -90
  47. data/lib/apex_charts/prefix_with_apex.rb +7 -0
  48. data/lib/apex_charts/prefixer.rb +21 -0
  49. data/lib/apex_charts/renderer.rb +113 -0
  50. data/lib/apex_charts/series.rb +7 -0
  51. data/lib/apex_charts/series/bubble_series.rb +50 -0
  52. data/lib/apex_charts/series/cartesian_series.rb +81 -0
  53. data/lib/apex_charts/series/polar_series.rb +48 -0
  54. data/lib/{apexcharts → apex_charts}/support/rails.rb +1 -1
  55. data/lib/apex_charts/support/sinatra.rb +9 -0
  56. data/lib/apex_charts/theme.rb +60 -0
  57. data/lib/{apexcharts → apex_charts}/utils.rb +1 -0
  58. data/lib/apex_charts/utils/copy.rb +11 -0
  59. data/lib/apex_charts/utils/date_time.rb +70 -0
  60. data/lib/{apexcharts → apex_charts}/utils/hash.rb +4 -3
  61. data/lib/{apexcharts → apex_charts}/version.rb +2 -1
  62. data/lib/apexcharts.rb +3 -2
  63. data/vendor/assets/javascripts/apexcharts.js +11 -3
  64. metadata +85 -65
  65. data/lib/apexcharts/charts.rb +0 -19
  66. data/lib/apexcharts/charts/base.rb +0 -34
  67. data/lib/apexcharts/charts/bubble.rb +0 -19
  68. data/lib/apexcharts/charts/cartesian.rb +0 -81
  69. data/lib/apexcharts/charts/mixed.rb +0 -85
  70. data/lib/apexcharts/charts/polar.rb +0 -14
  71. data/lib/apexcharts/charts/syncing.rb +0 -70
  72. data/lib/apexcharts/helper.rb +0 -109
  73. data/lib/apexcharts/options/annotations.rb +0 -10
  74. data/lib/apexcharts/options/axis.rb +0 -17
  75. data/lib/apexcharts/options/chart.rb +0 -26
  76. data/lib/apexcharts/options/data_labels.rb +0 -12
  77. data/lib/apexcharts/options/div_attributes.rb +0 -10
  78. data/lib/apexcharts/options/fill.rb +0 -12
  79. data/lib/apexcharts/options/grid.rb +0 -15
  80. data/lib/apexcharts/options/legend.rb +0 -24
  81. data/lib/apexcharts/options/markers.rb +0 -18
  82. data/lib/apexcharts/options/no_data.rb +0 -12
  83. data/lib/apexcharts/options/plot_options.rb +0 -12
  84. data/lib/apexcharts/options/root.rb +0 -42
  85. data/lib/apexcharts/options/states.rb +0 -9
  86. data/lib/apexcharts/options/stroke.rb +0 -12
  87. data/lib/apexcharts/options/subtitle.rb +0 -7
  88. data/lib/apexcharts/options/theme.rb +0 -8
  89. data/lib/apexcharts/options/title.rb +0 -13
  90. data/lib/apexcharts/options/tooltip.rb +0 -22
  91. data/lib/apexcharts/options/x_axis.rb +0 -12
  92. data/lib/apexcharts/options/y_axis.rb +0 -15
  93. data/lib/apexcharts/renderer.rb +0 -21
  94. data/lib/apexcharts/series.rb +0 -5
  95. data/lib/apexcharts/series/bubble.rb +0 -37
  96. data/lib/apexcharts/series/cartesian.rb +0 -65
  97. data/lib/apexcharts/series/polar.rb +0 -32
  98. data/lib/apexcharts/utils/date_time.rb +0 -59
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'configuration'
4
+
5
+ ApexCharts.helper_prefix = 'apex_'
6
+
7
+ require_relative '../apexcharts'
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ApexCharts
4
+ module Prefixer
5
+ def self.extended(helper)
6
+ @@helper = helper
7
+ end
8
+
9
+ def with_prefix(&block)
10
+ @@prefixed = Module.new(&block)
11
+
12
+ unless [nil, ''].include? ApexCharts.helper_prefix
13
+ (@@prefixed.instance_methods - @@helper.instance_methods).each do |method|
14
+ @@prefixed.send(:alias_method, "#{ApexCharts.helper_prefix}#{method}", method)
15
+ @@prefixed.send(:remove_method, method)
16
+ end
17
+ end
18
+ @@helper.send(:include, @@prefixed)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require_relative 'version'
5
+
6
+ module ApexCharts
7
+ class Renderer
8
+ class << self
9
+ def render(options)
10
+ new(options).render
11
+ end
12
+ end
13
+
14
+ attr_reader :options
15
+
16
+ def initialize(options)
17
+ @options = options
18
+ end
19
+
20
+ def render
21
+ html = ''
22
+ html = window_apex if id_number == '1' && !ApexCharts.config.default_options.empty?
23
+
24
+ chart_rendering = <<~JS
25
+ var #{variable} = new ApexCharts(document.querySelector("##{element_id}"), #{substitute_function_object(options.to_json)});
26
+ #{variable}.render();
27
+ JS
28
+
29
+ html += <<~HTML
30
+ <div id="#{element_id}" class="#{css_class}" style="#{style}"></div>
31
+ #{script(defer(chart_rendering))}
32
+ HTML
33
+ end
34
+
35
+ def defer(js)
36
+ if defer?
37
+ <<~DEFERRED
38
+ (function() {
39
+ var createChart = function() {
40
+ #{indent(js)}
41
+ };
42
+ if (window.addEventListener) {
43
+ window.addEventListener("load", createChart, true);
44
+ } else if (window.attachEvent) {
45
+ window.attachEvent("onload", createChart);
46
+ } else {
47
+ createChart();
48
+ }
49
+ })();
50
+ DEFERRED
51
+ else
52
+ js
53
+ end
54
+ end
55
+
56
+ def substitute_function_object(json)
57
+ json.gsub(%r[{"function":{"args":"(?<args>.*?)","body":"(?<body>.*?)"}}]) do
58
+ body = "\"#{$~&.[](:body)}\"".undump
59
+ "function(#{$~&.[](:args)}){#{body}}"
60
+ end
61
+ end
62
+
63
+ def defer?
64
+ @defer ||= options.delete(:defer)
65
+ end
66
+
67
+ def attributes
68
+ @attributes ||= options.delete(:div) { {} }
69
+ end
70
+
71
+ def element_id
72
+ @element_id ||= attributes.delete(:id)
73
+ end
74
+
75
+ def id_number
76
+ @id_number ||= element_id&.[](/\d+/)
77
+ end
78
+
79
+ def variable
80
+ @variable ||= attributes.delete(:var) { "chart#{id_number}" }
81
+ end
82
+
83
+ def css_class
84
+ attributes.delete(:class)
85
+ end
86
+
87
+ def height
88
+ "#{options[:chart][:height].to_i}px"
89
+ end
90
+
91
+ def style
92
+ "height: #{height}; #{attributes.delete(:style)}"
93
+ end
94
+
95
+ def window_apex
96
+ script("window.Apex = #{ApexCharts.config.default_options.to_json}")
97
+ end
98
+
99
+ def script(js)
100
+ <<~SCRIPT
101
+ <script type="text/javascript" apexcharts-rb="#{RELEASE}">
102
+ #{js}
103
+ </script>
104
+ SCRIPT
105
+ end
106
+
107
+ def indent(content, times=2)
108
+ content.lines.map.with_index do |line, index|
109
+ (index == 0 ? '' : ' ' * times) + line
110
+ end.join
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ApexCharts::Series
4
+ %w[cartesian bubble polar].each do |type|
5
+ autoload :"#{type.capitalize}Series", "apex_charts/series/#{type}_series.rb"
6
+ end
7
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../utils/copy'
4
+
5
+ module ApexCharts::Series
6
+ class BubbleSeries
7
+ include ApexCharts::Utils::Copy
8
+
9
+ attr_reader :sanitized
10
+
11
+ def initialize(data)
12
+ data = deep_copy(data)
13
+ sanitized =
14
+ case data
15
+ when Array
16
+ if array_of_threes?(data)
17
+ [{data: data}]
18
+ else
19
+ data
20
+ end
21
+
22
+ when Hash
23
+ if data_value = data[:data]
24
+ [data] if array_of_threes?(data_value)
25
+ end
26
+
27
+ end
28
+
29
+ @sanitized = {series: sanitized}
30
+ end
31
+
32
+ def sample
33
+ return if empty?
34
+
35
+ sanitized[:series][0][:data][0]
36
+ end
37
+
38
+ private
39
+
40
+ def empty?
41
+ sanitized[:series].empty? || sanitized[:series][0][:data].empty?
42
+ end
43
+
44
+ def array_of_threes?(data)
45
+ return false if data.empty?
46
+
47
+ data.all? {|d| d.length == 3 }
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../utils/copy'
4
+
5
+ module ApexCharts::Series
6
+ class CartesianSeries
7
+ include ApexCharts::Utils::Copy
8
+
9
+ attr_reader :sanitized
10
+
11
+ def initialize(data)
12
+ @sanitized = {series: build_series(deep_copy(data))}
13
+ end
14
+
15
+ def sample
16
+ return if empty?
17
+
18
+ sanitized[:series][0][:data][0][:x]
19
+ end
20
+
21
+ private
22
+
23
+ def empty?
24
+ sanitized[:series].empty? || sanitized[:series][0][:data].empty?
25
+ end
26
+
27
+ def build_series(data)
28
+ return data if data.empty?
29
+
30
+ case data
31
+ when Array
32
+ build_series_from_array(data)
33
+ when Hash
34
+ build_series_from_hash(data)
35
+ end
36
+ end
37
+
38
+ def build_series_from_array(data)
39
+ case first_data = data[0]
40
+ when Array
41
+ [{data: array_of_array_to_array_of_xy(data)}]
42
+
43
+ when Hash
44
+ if first_data[:data]
45
+ data.each {|h| h[:data] = array_of_array_to_array_of_xy(h[:data]) }
46
+ data
47
+ end
48
+ end
49
+ end
50
+
51
+ def build_series_from_hash(data)
52
+ if data_value = data[:data]
53
+ if array_of_pairs?(data_value)
54
+ data[:data] = array_of_array_to_array_of_xy(data_value)
55
+ [data]
56
+ end
57
+
58
+ elsif data[:x] && data[:y]
59
+ [{data: [data]}]
60
+
61
+ else
62
+ [
63
+ {
64
+ data: data.map do |key, value|
65
+ {x: key, y: value}
66
+ end
67
+ }
68
+ ]
69
+
70
+ end
71
+ end
72
+
73
+ def array_of_pairs?(data)
74
+ !data.empty? && data.all? {|d| d.length == 2 }
75
+ end
76
+
77
+ def array_of_array_to_array_of_xy(data)
78
+ data.map {|d| {x: d.first, y: d.last} }
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../utils/copy'
4
+
5
+ module ApexCharts::Series
6
+ class PolarSeries
7
+ include ApexCharts::Utils::Copy
8
+
9
+ attr_reader :sanitized
10
+
11
+ def initialize(data)
12
+ build_labels_and_series(deep_copy(data))
13
+
14
+ @sanitized = {
15
+ labels: @labels.empty? ? nil : @labels,
16
+ series: @series
17
+ }.compact
18
+ end
19
+
20
+ def sample
21
+ return if empty?
22
+
23
+ sanitized[:series][0]
24
+ end
25
+
26
+ private
27
+
28
+ def empty?
29
+ sanitized[:series].nil? || sanitized[:series][0].nil?
30
+ end
31
+
32
+ def build_labels_and_series(data)
33
+ @labels = []
34
+ case data
35
+ when Array
36
+ case data.first
37
+ when Numeric
38
+ @series = data
39
+ when Hash
40
+ @labels = data.map {|m| m[:name] }.compact
41
+ @series = data.map {|m| m[:data] }
42
+ end
43
+ when Hash
44
+ @series = data[:data] if data[:data].is_a? Array
45
+ end
46
+ end
47
+ end
48
+ end
@@ -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
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'colors'
4
+
5
+ module ApexCharts
6
+ class Theme
7
+ PALETTES = %w[palette1 palette2 palette3 palette4 palette5
8
+ palette6 palette7 palette8 palette9 palette10].freeze
9
+
10
+ @custom_palettes = {}
11
+
12
+ module ClassMethods
13
+ def create(palette_name, colors)
14
+ palettes[palette_name] = Colors.new colors
15
+ end
16
+
17
+ def destroy(palette_name)
18
+ palettes.delete palette_name
19
+ end
20
+
21
+ def get_colors(palette_name)
22
+ custom_palettes[palette_name]&.values
23
+ end
24
+
25
+ def palette_names
26
+ custom_palettes.keys
27
+ end
28
+
29
+ def all_palettes
30
+ PALETTES + palette_names
31
+ end
32
+
33
+ def custom_palettes
34
+ palettes
35
+ end
36
+
37
+ def palettes
38
+ @custom_palettes
39
+ end
40
+ end
41
+
42
+ class Local
43
+ module LocalClassMethods
44
+ include ClassMethods
45
+
46
+ def custom_palettes
47
+ Theme.palettes.merge(super)
48
+ end
49
+
50
+ def palettes
51
+ Thread.current[:_ApexCharts_Palettes_] ||= {}
52
+ end
53
+ end
54
+
55
+ extend LocalClassMethods
56
+ end
57
+
58
+ extend ClassMethods
59
+ end
60
+ end
@@ -2,3 +2,4 @@
2
2
 
3
3
  require_relative 'utils/date_time'
4
4
  require_relative 'utils/hash'
5
+ require_relative 'utils/copy'
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ApexCharts
4
+ module Utils
5
+ module Copy
6
+ def deep_copy(data)
7
+ Marshal.load(Marshal.dump(data))
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+
5
+ module ApexCharts
6
+ module Utils
7
+ module DateTime
8
+ module_function
9
+
10
+ def convert(input)
11
+ case input
12
+ when Time
13
+ (input.to_f * 1000).round
14
+ when ::DateTime, Date
15
+ (input.to_time.to_f * 1000).round
16
+ else
17
+ if (dt = ::DateTime.iso8601(input)).iso8601 == input
18
+ (dt.to_time.to_f * 1000).round
19
+ elsif (d = Date.iso8601(input)).iso8601 == input
20
+ (d.to_time.to_f * 1000).round
21
+ end
22
+ end
23
+ rescue StandardError
24
+ input
25
+ end
26
+
27
+ def convert_range(input)
28
+ input_first, input_last = input.first, input.last
29
+ case input_first
30
+ when Time
31
+ to_milliseconds_range(input_first, input_last)
32
+ when ::DateTime, Date
33
+ to_milliseconds_range(input_first.to_time, input_last.to_time)
34
+ else
35
+ if (datetime = ::DateTime.iso8601(input_first)).iso8601 == input_first
36
+ to_milliseconds_range(datetime.to_time, ::DateTime.iso8601(input_last).to_time)
37
+ elsif (date = Date.iso8601(input.first)).iso8601 == input_first
38
+ to_milliseconds_range(date.to_time, ::Date.iso8601(input_last).to_time)
39
+ end
40
+ end
41
+ rescue StandardError
42
+ input
43
+ end
44
+
45
+ def to_milliseconds(input)
46
+ (input.to_f * 1000).round
47
+ end
48
+
49
+ def to_milliseconds_range(first, last)
50
+ to_milliseconds(first)..to_milliseconds(last)
51
+ end
52
+
53
+ def type(input)
54
+ case input
55
+ when Time, ::DateTime, Date
56
+ 'datetime'
57
+ else
58
+ if [
59
+ ::DateTime.iso8601(input).iso8601,
60
+ Date.iso8601(input).iso8601
61
+ ].include? input
62
+ 'datetime'
63
+ end
64
+ end
65
+ rescue StandardError
66
+ nil
67
+ end
68
+ end
69
+ end
70
+ end