apexcharts 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +132 -0
  4. data/lib/apexcharts/charts/area.rb +7 -0
  5. data/lib/apexcharts/charts/bar.rb +11 -0
  6. data/lib/apexcharts/charts/capabilities/annotations.rb +75 -0
  7. data/lib/apexcharts/charts/cartesian.rb +60 -0
  8. data/lib/apexcharts/charts/column.rb +7 -0
  9. data/lib/apexcharts/charts/line.rb +7 -0
  10. data/lib/apexcharts/charts/mixed.rb +72 -0
  11. data/lib/apexcharts/charts/scatter.rb +7 -0
  12. data/lib/apexcharts/charts/syncing.rb +61 -0
  13. data/lib/apexcharts/charts.rb +8 -0
  14. data/lib/apexcharts/helper.rb +66 -0
  15. data/lib/apexcharts/options/annotations.rb +10 -0
  16. data/lib/apexcharts/options/axis.rb +17 -0
  17. data/lib/apexcharts/options/chart.rb +24 -0
  18. data/lib/apexcharts/options/data_labels.rb +12 -0
  19. data/lib/apexcharts/options/div_attributes.rb +10 -0
  20. data/lib/apexcharts/options/fill.rb +12 -0
  21. data/lib/apexcharts/options/grid.rb +15 -0
  22. data/lib/apexcharts/options/legend.rb +24 -0
  23. data/lib/apexcharts/options/markers.rb +18 -0
  24. data/lib/apexcharts/options/no_data.rb +12 -0
  25. data/lib/apexcharts/options/plot_options.rb +11 -0
  26. data/lib/apexcharts/options/root.rb +41 -0
  27. data/lib/apexcharts/options/states.rb +9 -0
  28. data/lib/apexcharts/options/stroke.rb +12 -0
  29. data/lib/apexcharts/options/subtitle.rb +7 -0
  30. data/lib/apexcharts/options/theme.rb +8 -0
  31. data/lib/apexcharts/options/title.rb +13 -0
  32. data/lib/apexcharts/options/tooltip.rb +22 -0
  33. data/lib/apexcharts/options/x_axis.rb +12 -0
  34. data/lib/apexcharts/options/y_axis.rb +15 -0
  35. data/lib/apexcharts/options_builder.rb +320 -0
  36. data/lib/apexcharts/series/cartesian.rb +24 -0
  37. data/lib/apexcharts/series.rb +1 -0
  38. data/lib/apexcharts/support/rails.rb +9 -0
  39. data/lib/apexcharts/utils/date_time.rb +60 -0
  40. data/lib/apexcharts/utils/hash.rb +31 -0
  41. data/lib/apexcharts/utils.rb +2 -0
  42. data/lib/apexcharts/version.rb +3 -0
  43. data/lib/apexcharts.rb +2 -0
  44. data/vendor/assets/javascripts/apexcharts.js +6 -0
  45. metadata +157 -0
@@ -0,0 +1,24 @@
1
+ module Apexcharts
2
+ class LegendOptions < ::SmartKv
3
+ optional *%i[
4
+ container_margin containerMargin
5
+ floating
6
+ font_family fontFamily
7
+ font_size fontSize
8
+ formatter
9
+ horizontal_align horizontalAlign
10
+ item_margin itemMargin
11
+ labels
12
+ markers
13
+ offset_x offsetX
14
+ offset_y offsetY
15
+ on_item_click onItemClick
16
+ on_item_hover onItemHover
17
+ position
18
+ show
19
+ show_for_single_series showForSingleSeries
20
+ text_anchor textAnchor
21
+ vertical_align verticalAlign
22
+ ]
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ module Apexcharts
2
+ class MarkersOptions < ::SmartKv
3
+ optional *%i[
4
+ colors
5
+ discrete
6
+ fill_opacity fillOpacity
7
+ hover
8
+ offset_x offsetX
9
+ offset_y offsetY
10
+ radius
11
+ shape
12
+ size
13
+ stroke_color strokeColor
14
+ stroke_opacity strokeOpacity
15
+ stroke_width strokeWidth
16
+ ]
17
+ end
18
+ end
@@ -0,0 +1,12 @@
1
+ module Apexcharts
2
+ class NoDataOptions < ::SmartKv
3
+ optional *%i[
4
+ align
5
+ offset_x offsetX
6
+ offset_y offsetY
7
+ style
8
+ text
9
+ vertical_align verticalAlign
10
+ ]
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ module Apexcharts
2
+ class PlotOptions < ::SmartKv
3
+ optional *%i[
4
+ bar
5
+ candlestick
6
+ heatmap
7
+ pie
8
+ radial_bar radialBar
9
+ ]
10
+ end
11
+ end
@@ -0,0 +1,41 @@
1
+ require_relative 'div_attributes'
2
+ require_relative 'chart'
3
+ require_relative 'stroke'
4
+ require_relative 'states'
5
+
6
+ module Apexcharts
7
+ class RootOptions < ::SmartKv
8
+ optional *%i[
9
+ annotations
10
+ chart
11
+ chart_id
12
+ colors
13
+ data_labels dataLabels
14
+ fill
15
+ grid
16
+ group
17
+ labels
18
+ legend
19
+ markers
20
+ no_data noData
21
+ plot_options plotOptions
22
+ responsive
23
+ series
24
+ states
25
+ stroke
26
+ subtitle
27
+ theme
28
+ title
29
+ tooltip
30
+ var
31
+ xaxis
32
+ xtitle
33
+ yaxis
34
+ ytitle
35
+ ],
36
+ *DivAttributes.optional_keys,
37
+ *ChartOptions.optional_keys,
38
+ *StrokeOptions.optional_keys,
39
+ *StatesOptions.optional_keys
40
+ end
41
+ end
@@ -0,0 +1,9 @@
1
+ module Apexcharts
2
+ class StatesOptions < ::SmartKv
3
+ optional *%i[
4
+ active
5
+ hover
6
+ normal
7
+ ]
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ module Apexcharts
2
+ class StrokeOptions < ::SmartKv
3
+ optional *%i[
4
+ colors
5
+ curve
6
+ dash_array dashArray
7
+ line_cap lineCap
8
+ show
9
+ width
10
+ ]
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'title'
2
+
3
+ module Apexcharts
4
+ class SubtitleOptions < TitleOptions
5
+ optional *%i[ ]
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ module Apexcharts
2
+ class ThemeOptions < ::SmartKv
3
+ optional *%i[
4
+ monochrome
5
+ palette
6
+ ]
7
+ end
8
+ end
@@ -0,0 +1,13 @@
1
+ module Apexcharts
2
+ class TitleOptions < ::SmartKv
3
+ optional *%i[
4
+ align
5
+ floating
6
+ margin
7
+ offset_x offsetX
8
+ offset_y offsetY
9
+ style
10
+ text
11
+ ]
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ module Apexcharts
2
+ class TooltipOptions < ::SmartKv
3
+ optional *%i[
4
+ custom
5
+ enabled
6
+ fill_series_color fillSeriesColor
7
+ fixed
8
+ follow_cursor followCursor
9
+ intersect
10
+ inverse_order inverseOrder
11
+ items
12
+ marker
13
+ on_dataset_hover onDatasetHover
14
+ shared
15
+ style
16
+ theme
17
+ x
18
+ y
19
+ z
20
+ ]
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ require_relative 'axis'
2
+
3
+ module Apexcharts
4
+ class XAxisOptions < AxisOptions
5
+ optional *%i[
6
+ categories
7
+ position
8
+ range
9
+ tick_placement tickPlacement
10
+ ]
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'axis'
2
+
3
+ module Apexcharts
4
+ class YAxisOptions < AxisOptions
5
+ optional *%i[
6
+ decimals_in_float decimalsInFloat
7
+ force_nice_scale forceNiceScale
8
+ logarithmic
9
+ opposite
10
+ series_name seriesName
11
+ show
12
+ show_always showAlways
13
+ ]
14
+ end
15
+ end
@@ -0,0 +1,320 @@
1
+ require 'smart_kv'
2
+ require_relative 'options/root'
3
+ require_relative 'options/annotations'
4
+ require_relative 'options/data_labels'
5
+ require_relative 'options/fill'
6
+ require_relative 'options/grid'
7
+ require_relative 'options/legend'
8
+ require_relative 'options/markers'
9
+ require_relative 'options/no_data'
10
+ require_relative 'options/plot_options'
11
+ require_relative 'options/states'
12
+ require_relative 'options/subtitle'
13
+ require_relative 'options/theme'
14
+ require_relative 'options/tooltip'
15
+ require_relative 'options/x_axis'
16
+ require_relative 'options/y_axis'
17
+
18
+ module Apexcharts
19
+ class OptionsBuilder
20
+ THEME_PALETTES = ["palette1", "palette2", "palette3", "palette4", "palette5",
21
+ "palette6", "palette7", "palette8", "palette9", "palette10"]
22
+
23
+ attr_reader :built
24
+
25
+ def initialize(x_sample, options)
26
+ @options = options
27
+ @xtype = Utils::DateTime.xtype(x_sample)
28
+ @built = {}
29
+ build_options
30
+ @built.compact!
31
+ end
32
+
33
+ def build_options
34
+ RootOptions.check @options
35
+
36
+ build_chart
37
+ build_div
38
+ build_annotations
39
+ build_data_labels
40
+ build_fill
41
+ build_grid
42
+ build_labels
43
+ build_legend
44
+ build_markers
45
+ build_no_data
46
+ build_plot_options
47
+ build_responsive
48
+ build_states
49
+ build_stroke
50
+ build_subtitle
51
+ build_theme
52
+ build_title
53
+ build_tooltip
54
+ build_xaxis
55
+ build_yaxis
56
+ end
57
+
58
+ def build_div
59
+ @built[:div] = {
60
+ id: @options.delete(:id),
61
+ var: @options.delete(:var),
62
+ class: @options.delete(:class),
63
+ style: @options.delete(:style)
64
+ }.compact
65
+ end
66
+
67
+ def build_annotations
68
+ annotations = @options.delete :annotations
69
+ @built[:annotations] = if annotations.is_a? Hash
70
+ AnnotationsOptions.check annotations.compact
71
+ end
72
+ end
73
+
74
+ def build_chart
75
+ @built[:chart] = {
76
+ id: @options[:chart_id] || @options[:id],
77
+ group: @options.delete(:group),
78
+ height: @options.delete(:height) { 400 },
79
+ width: @options.delete(:width),
80
+ stacked: @options.delete(:stacked),
81
+ animations: enabled(@options.delete(:animations)),
82
+ sparkline: enabled(@options.delete(:sparkline)),
83
+ background: @options.delete(:background),
84
+ fore_color: @options.delete(:fore_color) do
85
+ @options.delete(:foreColor)
86
+ end
87
+ }.compact
88
+
89
+ chart = @options.delete :chart
90
+ if chart.is_a? Hash
91
+ @built[:chart].merge! ChartOptions.check(chart.compact)
92
+ end
93
+ end
94
+
95
+ def build_data_labels
96
+ data_labels = @options.delete :data_labels do
97
+ @options.delete :dataLabels
98
+ end
99
+ return if data_labels.nil?
100
+ @built[:data_labels] = if [true, false].include? data_labels
101
+ {enabled: data_labels}
102
+ elsif options.is_a? Hash
103
+ DataLabelsOptions.check options.compact
104
+ end
105
+ end
106
+
107
+ def build_fill
108
+ fill = @options.delete :fill
109
+ @built[:fill] = if fill.is_a? String
110
+ {type: fill}
111
+ elsif fill.is_a? Hash
112
+ FillOptions.check fill.compact
113
+ end
114
+ end
115
+
116
+ def build_grid
117
+ grid = @options.delete :grid
118
+ @built[:grid] = if [true, false].include? grid
119
+ {show: grid}
120
+ elsif grid.is_a? Hash
121
+ GridOptions.check grid.compact
122
+ end
123
+ end
124
+
125
+ def build_labels
126
+ labels = @options.delete :labels
127
+ @built[:labels] = if labels.nil?
128
+ elsif labels.is_a? Array
129
+ labels
130
+ else
131
+ [labels]
132
+ end
133
+ end
134
+
135
+ def build_legend
136
+ labels = @options.delete :labels
137
+ @built[:legend] = if [true, false].include? labels
138
+ {show: labels}
139
+ elsif labels.is_a? Hash
140
+ LegendOptions.check labels.compact
141
+ end
142
+ end
143
+
144
+ def build_markers
145
+ markers = @options.delete :markers
146
+ @built[:markers] = if markers.is_a? String
147
+ {shape: markers}
148
+ elsif markers.is_a? Hash
149
+ MarkersOptions.check markers.compact
150
+ end
151
+ end
152
+
153
+ def build_no_data
154
+ no_data = @options.delete :no_data
155
+ @built[:no_data] = if no_data.is_a? String
156
+ {text: no_data}
157
+ elsif no_data.is_a? Hash
158
+ NoDataOptions.check no_data.compact
159
+ end
160
+ end
161
+
162
+ def build_plot_options
163
+ plot_options = @options.delete :plot_options do
164
+ @options.delete :plotOptions
165
+ end
166
+ @built[:plot_options] = if plot_options.is_a? Hash
167
+ PlotOptions.check plot_options.compact
168
+ end
169
+ end
170
+
171
+ def build_responsive
172
+ responsive = @options.delete :responsive
173
+ @built[:responsive] = if responsive.nil?
174
+ elsif responsive.is_a? Array
175
+ responsive
176
+ else
177
+ [responsive]
178
+ end
179
+ end
180
+
181
+ def build_states
182
+ def filter_type_hash(state)
183
+ if state.is_a? String
184
+ {filter: {type: state}}
185
+ elsif state.is_a? Hash
186
+ state.compact
187
+ end
188
+ end
189
+
190
+ @built[:states] = {
191
+ normal: filter_type_hash(@options.delete :normal),
192
+ hover: filter_type_hash(@options.delete :hover),
193
+ active: filter_type_hash(@options.delete :active)
194
+ }.compact
195
+
196
+ states = @options.delete :states
197
+ if states.is_a? Hash
198
+ @built[:states].merge! StatesOptions.check(states.compact)
199
+ end
200
+
201
+ @built[:states] = nil if @built[:states].empty?
202
+ end
203
+
204
+ def build_stroke
205
+ curve = @options.delete :curve
206
+ @built[:stroke] = {curve: curve}.compact
207
+
208
+ stroke = @options.delete :stroke
209
+ if [true, false].include? stroke
210
+ @built[:stroke].merge!({show: stroke})
211
+ elsif stroke.is_a? Hash
212
+ @built[:stroke].merge! StrokeOptions.check(stroke.compact)
213
+ end
214
+
215
+ @built[:stroke] = nil if @built[:stroke].empty?
216
+ end
217
+
218
+ def build_subtitle
219
+ subtitle = @options.delete(:subtitle)
220
+ @built[:subtitle] = if subtitle.is_a? String
221
+ {text: subtitle}
222
+ elsif subtitle.is_a? Hash
223
+ SubtitleOptions.check subtitle.compact
224
+ end
225
+ end
226
+
227
+ def build_theme
228
+ theme = @options.delete(:theme)
229
+ @built[:theme] = if theme.is_a?(String)
230
+ case theme
231
+ when 'random'
232
+ {palette: THEME_PALETTES.sample}
233
+ when 'monochrome'
234
+ {monochrome: {enabled: true}}
235
+ else
236
+ {palette: theme}
237
+ end
238
+ elsif theme.is_a?(Hash)
239
+ ThemeOptions.check theme.compact
240
+ end
241
+ end
242
+
243
+ def build_title
244
+ title = @options.delete(:title)
245
+ @built[:title] = if title.is_a? String
246
+ {text: title}
247
+ elsif title.is_a? Hash
248
+ TitleOptions.check title.compact
249
+ end
250
+ end
251
+
252
+ def build_tooltip
253
+ tooltip = @options.delete :tooltip
254
+ @built[:tooltip] = if [true, false].include? tooltip
255
+ {enabled: tooltip}
256
+ elsif tooltip.is_a? Hash
257
+ TooltipOptions.check tooltip.compact
258
+ end
259
+ end
260
+
261
+ def build_xaxis
262
+ xaxis = @options.delete :xaxis
263
+ @built[:xaxis] = {
264
+ type: @options.delete(:xtype){ @xtype },
265
+ title: {
266
+ text: @options.delete(:xtitle)
267
+ }.compact
268
+ }.compact
269
+
270
+ if xaxis.is_a? String
271
+ @built[:xaxis][:title] = {text: xaxis}
272
+ elsif xaxis.is_a? Hash
273
+ XAxisOptions.check xaxis
274
+ @built[:xaxis].merge! xaxis
275
+ end
276
+ end
277
+
278
+ def build_yaxis
279
+ yaxis = @options.delete :yaxis
280
+ @built[:yaxis] = [{
281
+ type: @options.delete(:ytype),
282
+ title: {
283
+ text: @options.delete(:ytitle)
284
+ }.compact
285
+ }.compact]
286
+
287
+ if yaxis.is_a? String
288
+ @built[:yaxis][0][:title] = {text: yaxis}
289
+ elsif yaxis.is_a? Hash
290
+ YAxisOptions.check yaxis
291
+ @built[:yaxis][0].merge! yaxis
292
+ end
293
+ end
294
+
295
+ def xtype(x)
296
+ if DateTime.iso8601(x).iso8601 == x
297
+ 'datetime'
298
+ elsif Date.iso8601(x).iso8601 = x
299
+ 'datetime'
300
+ end
301
+ rescue
302
+ 'number'
303
+ end
304
+
305
+ def enabled(options)
306
+ boolean_to_hash(options) do |options|
307
+ {enabled: options}
308
+ end
309
+ end
310
+
311
+ def boolean_to_hash(options)
312
+ return if options.nil?
313
+ if [true, false].include? options
314
+ yield(options)
315
+ elsif options.is_a?(Hash)
316
+ options.compact
317
+ end
318
+ end
319
+ end
320
+ end
@@ -0,0 +1,24 @@
1
+ module Apexcharts
2
+ class CartesianSeries
3
+ attr_accessor :sanitized
4
+
5
+ def initialize(data)
6
+ if data.is_a?(Array)
7
+ if (data.to_h rescue nil)
8
+ @sanitized = [data.to_h]
9
+ else
10
+ @sanitized = data.map(&:to_h)
11
+ end
12
+ else
13
+ @sanitized = [data]
14
+ end
15
+
16
+ unless sanitized[0][:data]
17
+ @sanitized = sanitized.map{|a| {data: a} }
18
+ end
19
+
20
+ @sanitized = sanitized.each {|a| a[:data] = a[:data].map{|k,v| {x: k, y: v} } }
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1 @@
1
+ require_relative 'series/cartesian'
@@ -0,0 +1,9 @@
1
+ module Apexcharts
2
+ class Engine < ::Rails::Engine
3
+ initializer "helper" do |app|
4
+ ActiveSupport.on_load(:action_view) do
5
+ include Helper
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,60 @@
1
+ require 'date'
2
+
3
+ module Apexcharts::Utils
4
+ class DateTime
5
+ def self.convert input
6
+ case input
7
+ when Time
8
+ (input.to_f * 1000).round
9
+ when ::DateTime, Date
10
+ (input.to_time.to_f * 1000).round
11
+ else
12
+ if (dt = ::DateTime.iso8601(input)).iso8601 == input
13
+ (dt.to_time.to_f * 1000).round
14
+ else (d = Date.iso8601(input)).iso8601 == input
15
+ (d.to_time.to_f * 1000).round
16
+ end
17
+ end
18
+ rescue
19
+ input
20
+ end
21
+
22
+ def self.convert_range input
23
+ case input.first
24
+ when Time
25
+ ((input.first.to_f * 1000).round..(input.last.to_f * 1000).round)
26
+ when ::DateTime, Date
27
+ ((input.first.to_time.to_f * 1000).round..(input.last.to_time.to_f * 1000).round)
28
+ else
29
+ if (dt = ::DateTime.iso8601(input.first)).iso8601 == input.first
30
+ ((dt.to_time.to_f * 1000).round..(::DateTime.iso8601(input.last).to_time.to_f * 1000).round)
31
+ else (d = Date.iso8601(input.first)).iso8601 == input.first
32
+ ((d.to_time.to_f * 1000).round..(Date.iso8601(input.last).to_time.to_f * 1000).round)
33
+ end
34
+ end
35
+ rescue
36
+ input
37
+ end
38
+
39
+ def self.xtype input
40
+ case input
41
+ when Time
42
+ 'datetime'
43
+ when DateTime, Date
44
+ 'datetime'
45
+ when Date
46
+ 'date'
47
+ else
48
+ if DateTime.iso8601(input).iso8601 == input
49
+ 'datetime'
50
+ elsif Date.iso8601(input).iso8601 == input
51
+ 'datetime'
52
+ else
53
+ 'number'
54
+ end
55
+ end
56
+ rescue
57
+ 'number'
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,31 @@
1
+ module Apexcharts
2
+ module Utils
3
+ module Hash
4
+ def deep_merge(first_hash, second_hash)
5
+ first_hash.merge(second_hash) do |key, this_val, other_val|
6
+ if this_val.is_a?(::Hash) && other_val.is_a?(::Hash)
7
+ deep_merge(this_val.dup, other_val)
8
+ else
9
+ other_val
10
+ end
11
+ end
12
+ end
13
+ module_function :deep_merge
14
+
15
+ def camelize(key)
16
+ key.to_s.gsub(/_(.)/) {|m| m[1].upcase }.to_sym
17
+ end
18
+ module_function :camelize
19
+
20
+ def camelize_keys(value)
21
+ if value.is_a? ::Hash
22
+ ::Hash[value.map {|k, v| [camelize(k), camelize_keys(v)] }]
23
+ else
24
+ value
25
+ end
26
+ end
27
+ module_function :camelize_keys
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,2 @@
1
+ require_relative 'utils/date_time'
2
+ require_relative 'utils/hash'
@@ -0,0 +1,3 @@
1
+ module Apexcharts
2
+ VERSION = '0.1.1'
3
+ end
data/lib/apexcharts.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'apexcharts/support/rails' if defined?(Rails)
2
+ require 'apexcharts/helper'