apexcharts 0.1.5 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +456 -38
- data/lib/apex_charts/charts.rb +16 -0
- data/lib/{apexcharts/charts/area.rb → apex_charts/charts/area_chart.rb} +1 -1
- data/lib/{apexcharts/charts/bar.rb → apex_charts/charts/bar_chart.rb} +1 -1
- data/lib/apex_charts/charts/base_chart.rb +37 -0
- data/lib/apex_charts/charts/bubble_chart.rb +13 -0
- data/lib/{apexcharts/charts/candlestick.rb → apex_charts/charts/candlestick_chart.rb} +1 -1
- data/lib/apex_charts/charts/cartesian_chart.rb +82 -0
- data/lib/{apexcharts/charts/column.rb → apex_charts/charts/column_chart.rb} +3 -1
- data/lib/{apexcharts/charts/donut.rb → apex_charts/charts/donut_chart.rb} +1 -2
- data/lib/{apexcharts → apex_charts}/charts/features/annotations.rb +22 -21
- data/lib/{apexcharts → apex_charts}/charts/features/mixable.rb +2 -3
- data/lib/{apexcharts/charts/heatmap.rb → apex_charts/charts/heatmap_chart.rb} +3 -5
- data/lib/{apexcharts/charts/line.rb → apex_charts/charts/line_chart.rb} +1 -1
- data/lib/apex_charts/charts/mixed_charts.rb +101 -0
- data/lib/{apexcharts/charts/pie.rb → apex_charts/charts/pie_chart.rb} +1 -2
- data/lib/apex_charts/charts/polar_chart.rb +9 -0
- data/lib/{apexcharts/charts/radar.rb → apex_charts/charts/radar_chart.rb} +3 -5
- data/lib/{apexcharts/charts/radial_bar.rb → apex_charts/charts/radial_bar_chart.rb} +1 -2
- data/lib/apex_charts/charts/range_bar_chart.rb +9 -0
- data/lib/{apexcharts/charts/scatter.rb → apex_charts/charts/scatter_chart.rb} +1 -1
- data/lib/apex_charts/charts/syncing_charts.rb +84 -0
- data/lib/apex_charts/colors.rb +27 -0
- data/lib/apex_charts/config/default_options.rb +16 -0
- data/lib/apex_charts/configuration.rb +25 -0
- data/lib/apex_charts/helper.rb +190 -0
- data/lib/apex_charts/options/annotations_options.rb +15 -0
- data/lib/apex_charts/options/chart_options.rb +32 -0
- data/lib/apex_charts/options/data_labels_options.rb +18 -0
- data/lib/apex_charts/options/div_attributes.rb +11 -0
- data/lib/apex_charts/options/fill_options.rb +14 -0
- data/lib/apex_charts/options/grid_options.rb +17 -0
- data/lib/apex_charts/options/legend_options.rb +32 -0
- data/lib/apex_charts/options/markers_options.rb +24 -0
- data/lib/apex_charts/options/no_data_options.rb +14 -0
- data/lib/apex_charts/options/plot_options.rb +16 -0
- data/lib/apex_charts/options/root_options.rb +47 -0
- data/lib/apex_charts/options/states_options.rb +11 -0
- data/lib/apex_charts/options/stroke_options.rb +14 -0
- data/lib/apex_charts/options/theme_options.rb +11 -0
- data/lib/apex_charts/options/title_subtitle_options.rb +15 -0
- data/lib/apex_charts/options/tooltip_options.rb +25 -0
- data/lib/apex_charts/options/x_axis_options.rb +26 -0
- data/lib/apex_charts/options/y_axis_options.rb +28 -0
- data/lib/{apexcharts → apex_charts}/options_builder.rb +95 -90
- data/lib/apex_charts/prefix_with_apex.rb +7 -0
- data/lib/apex_charts/prefixer.rb +21 -0
- data/lib/apex_charts/renderer.rb +113 -0
- data/lib/apex_charts/series.rb +7 -0
- data/lib/apex_charts/series/bubble_series.rb +50 -0
- data/lib/apex_charts/series/cartesian_series.rb +81 -0
- data/lib/apex_charts/series/polar_series.rb +48 -0
- data/lib/{apexcharts → apex_charts}/support/rails.rb +1 -1
- data/lib/apex_charts/support/sinatra.rb +9 -0
- data/lib/apex_charts/theme.rb +60 -0
- data/lib/{apexcharts → apex_charts}/utils.rb +1 -0
- data/lib/apex_charts/utils/copy.rb +11 -0
- data/lib/apex_charts/utils/date_time.rb +70 -0
- data/lib/{apexcharts → apex_charts}/utils/hash.rb +4 -3
- data/lib/{apexcharts → apex_charts}/version.rb +2 -1
- data/lib/apexcharts.rb +3 -2
- data/vendor/assets/javascripts/apexcharts.js +11 -3
- metadata +85 -65
- data/lib/apexcharts/charts.rb +0 -19
- data/lib/apexcharts/charts/base.rb +0 -34
- data/lib/apexcharts/charts/bubble.rb +0 -19
- data/lib/apexcharts/charts/cartesian.rb +0 -81
- data/lib/apexcharts/charts/mixed.rb +0 -85
- data/lib/apexcharts/charts/polar.rb +0 -14
- data/lib/apexcharts/charts/syncing.rb +0 -70
- data/lib/apexcharts/helper.rb +0 -109
- data/lib/apexcharts/options/annotations.rb +0 -10
- data/lib/apexcharts/options/axis.rb +0 -17
- data/lib/apexcharts/options/chart.rb +0 -26
- data/lib/apexcharts/options/data_labels.rb +0 -12
- data/lib/apexcharts/options/div_attributes.rb +0 -10
- data/lib/apexcharts/options/fill.rb +0 -12
- data/lib/apexcharts/options/grid.rb +0 -15
- data/lib/apexcharts/options/legend.rb +0 -24
- data/lib/apexcharts/options/markers.rb +0 -18
- data/lib/apexcharts/options/no_data.rb +0 -12
- data/lib/apexcharts/options/plot_options.rb +0 -12
- data/lib/apexcharts/options/root.rb +0 -42
- data/lib/apexcharts/options/states.rb +0 -9
- data/lib/apexcharts/options/stroke.rb +0 -12
- data/lib/apexcharts/options/subtitle.rb +0 -7
- data/lib/apexcharts/options/theme.rb +0 -8
- data/lib/apexcharts/options/title.rb +0 -13
- data/lib/apexcharts/options/tooltip.rb +0 -22
- data/lib/apexcharts/options/x_axis.rb +0 -12
- data/lib/apexcharts/options/y_axis.rb +0 -15
- data/lib/apexcharts/renderer.rb +0 -21
- data/lib/apexcharts/series.rb +0 -5
- data/lib/apexcharts/series/bubble.rb +0 -37
- data/lib/apexcharts/series/cartesian.rb +0 -65
- data/lib/apexcharts/series/polar.rb +0 -32
- data/lib/apexcharts/utils/date_time.rb +0 -59
@@ -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,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
|
@@ -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
|
@@ -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
|