rails_charts 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +487 -0
  4. data/Rakefile +3 -0
  5. data/lib/rails_charts/area_chart.rb +31 -0
  6. data/lib/rails_charts/bar_chart.rb +25 -0
  7. data/lib/rails_charts/base_chart.rb +123 -0
  8. data/lib/rails_charts/calendar_chart.rb +36 -0
  9. data/lib/rails_charts/candlestick_chart.rb +25 -0
  10. data/lib/rails_charts/custom_chart.rb +14 -0
  11. data/lib/rails_charts/donut_chart.rb +36 -0
  12. data/lib/rails_charts/engine.rb +33 -0
  13. data/lib/rails_charts/funnel_chart.rb +30 -0
  14. data/lib/rails_charts/gauge_chart.rb +30 -0
  15. data/lib/rails_charts/helpers.rb +83 -0
  16. data/lib/rails_charts/javascript.rb +17 -0
  17. data/lib/rails_charts/line_chart.rb +78 -0
  18. data/lib/rails_charts/parallel_chart.rb +30 -0
  19. data/lib/rails_charts/pie_chart.rb +55 -0
  20. data/lib/rails_charts/radar_chart.rb +38 -0
  21. data/lib/rails_charts/ruby_ext.rb +28 -0
  22. data/lib/rails_charts/sankey_chart.rb +31 -0
  23. data/lib/rails_charts/scatter_chart.rb +34 -0
  24. data/lib/rails_charts/stacked_bar_chart.rb +13 -0
  25. data/lib/rails_charts/version.rb +3 -0
  26. data/lib/rails_charts.rb +43 -0
  27. data/vendor/assets/rails_charts/echarts.min.js +45 -0
  28. data/vendor/assets/rails_charts/extension/bmap.js +413 -0
  29. data/vendor/assets/rails_charts/extension/bmap.js.map +1 -0
  30. data/vendor/assets/rails_charts/extension/bmap.min.js +22 -0
  31. data/vendor/assets/rails_charts/extension/dataTool.js +436 -0
  32. data/vendor/assets/rails_charts/extension/dataTool.js.map +1 -0
  33. data/vendor/assets/rails_charts/extension/dataTool.min.js +22 -0
  34. data/vendor/assets/rails_charts/i18n/langCS-obj.js +172 -0
  35. data/vendor/assets/rails_charts/i18n/langCS.js +168 -0
  36. data/vendor/assets/rails_charts/i18n/langDE-obj.js +172 -0
  37. data/vendor/assets/rails_charts/i18n/langDE.js +168 -0
  38. data/vendor/assets/rails_charts/i18n/langEN-obj.js +173 -0
  39. data/vendor/assets/rails_charts/i18n/langEN.js +169 -0
  40. data/vendor/assets/rails_charts/i18n/langES-obj.js +111 -0
  41. data/vendor/assets/rails_charts/i18n/langES.js +107 -0
  42. data/vendor/assets/rails_charts/i18n/langFI-obj.js +111 -0
  43. data/vendor/assets/rails_charts/i18n/langFI.js +107 -0
  44. data/vendor/assets/rails_charts/i18n/langFR-obj.js +173 -0
  45. data/vendor/assets/rails_charts/i18n/langFR.js +169 -0
  46. data/vendor/assets/rails_charts/i18n/langIT-obj.js +173 -0
  47. data/vendor/assets/rails_charts/i18n/langIT.js +169 -0
  48. data/vendor/assets/rails_charts/i18n/langJA-obj.js +173 -0
  49. data/vendor/assets/rails_charts/i18n/langJA.js +169 -0
  50. data/vendor/assets/rails_charts/i18n/langKO-obj.js +173 -0
  51. data/vendor/assets/rails_charts/i18n/langKO.js +169 -0
  52. data/vendor/assets/rails_charts/i18n/langPL-obj.js +173 -0
  53. data/vendor/assets/rails_charts/i18n/langPL.js +169 -0
  54. data/vendor/assets/rails_charts/i18n/langPT-br-obj.js +174 -0
  55. data/vendor/assets/rails_charts/i18n/langPT-br.js +170 -0
  56. data/vendor/assets/rails_charts/i18n/langRO-obj.js +173 -0
  57. data/vendor/assets/rails_charts/i18n/langRO.js +169 -0
  58. data/vendor/assets/rails_charts/i18n/langRU-obj.js +174 -0
  59. data/vendor/assets/rails_charts/i18n/langRU.js +170 -0
  60. data/vendor/assets/rails_charts/i18n/langSI-obj.js +172 -0
  61. data/vendor/assets/rails_charts/i18n/langSI.js +168 -0
  62. data/vendor/assets/rails_charts/i18n/langTH-obj.js +111 -0
  63. data/vendor/assets/rails_charts/i18n/langTH.js +107 -0
  64. data/vendor/assets/rails_charts/i18n/langZH-obj.js +168 -0
  65. data/vendor/assets/rails_charts/i18n/langZH.js +164 -0
  66. data/vendor/assets/rails_charts/theme/azul.js +163 -0
  67. data/vendor/assets/rails_charts/theme/bee-inspired.js +178 -0
  68. data/vendor/assets/rails_charts/theme/blue.js +178 -0
  69. data/vendor/assets/rails_charts/theme/caravan.js +178 -0
  70. data/vendor/assets/rails_charts/theme/carp.js +163 -0
  71. data/vendor/assets/rails_charts/theme/cool.js +180 -0
  72. data/vendor/assets/rails_charts/theme/dark-blue.js +164 -0
  73. data/vendor/assets/rails_charts/theme/dark-bold.js +164 -0
  74. data/vendor/assets/rails_charts/theme/dark-digerati.js +164 -0
  75. data/vendor/assets/rails_charts/theme/dark-fresh-cut.js +164 -0
  76. data/vendor/assets/rails_charts/theme/dark-mushroom.js +164 -0
  77. data/vendor/assets/rails_charts/theme/dark.js +224 -0
  78. data/vendor/assets/rails_charts/theme/eduardo.js +178 -0
  79. data/vendor/assets/rails_charts/theme/forest.js +163 -0
  80. data/vendor/assets/rails_charts/theme/fresh-cut.js +163 -0
  81. data/vendor/assets/rails_charts/theme/fruit.js +178 -0
  82. data/vendor/assets/rails_charts/theme/gray.js +220 -0
  83. data/vendor/assets/rails_charts/theme/green.js +222 -0
  84. data/vendor/assets/rails_charts/theme/helianthus.js +263 -0
  85. data/vendor/assets/rails_charts/theme/infographic.js +236 -0
  86. data/vendor/assets/rails_charts/theme/inspired.js +163 -0
  87. data/vendor/assets/rails_charts/theme/jazz.js +163 -0
  88. data/vendor/assets/rails_charts/theme/london.js +163 -0
  89. data/vendor/assets/rails_charts/theme/macarons.js +240 -0
  90. data/vendor/assets/rails_charts/theme/macarons2.js +249 -0
  91. data/vendor/assets/rails_charts/theme/mint.js +155 -0
  92. data/vendor/assets/rails_charts/theme/red-velvet.js +163 -0
  93. data/vendor/assets/rails_charts/theme/red.js +225 -0
  94. data/vendor/assets/rails_charts/theme/roma.js +119 -0
  95. data/vendor/assets/rails_charts/theme/royal.js +163 -0
  96. data/vendor/assets/rails_charts/theme/sakura.js +140 -0
  97. data/vendor/assets/rails_charts/theme/shine.js +177 -0
  98. data/vendor/assets/rails_charts/theme/tech-blue.js +180 -0
  99. data/vendor/assets/rails_charts/theme/vintage.js +63 -0
  100. metadata +268 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d37477aa0733f7871c04744cd0ac01c4364210bbb115baa68926cc28900c9f7d
4
+ data.tar.gz: 10377955bf42d126819dc8422b96a1519ccb66a2ee96678d5268af60e2c00d77
5
+ SHA512:
6
+ metadata.gz: 9e1745b0e47ed759fcbae21a00a888b4b884011a1b6807904b43273cb2b5749920370112a5548244bf9c0d17af28c400d43af0fb75f21657db8a41a430d1a445
7
+ data.tar.gz: 163f8f54a5f6edd7659f3d560c14713df15c4c3bcd123a66420f6fe10aecd3ef8af003db8ab9ab8582253f7408c9703cc1f073b0fa700e38e028a3de5d4547a6
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2022
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,487 @@
1
+ # Rails Charts
2
+
3
+ ![Charts](docs/all.jpg)
4
+
5
+ One more gem to build nice charts for your Ruby on Rails application.
6
+
7
+ With it you can build various types of charts Apache eCharts library (v. 5.3.2). This gem simplifies interface and adding few helpers to start adding charts in your app with just a few lines of code.
8
+
9
+ What you can build with it:
10
+
11
+ - line chart
12
+ - area chart
13
+ - bar chart
14
+ - donut chart
15
+ - pie chart
16
+ - radar chart
17
+ - calendar chart
18
+ - candlestick chart
19
+ - funnel chart
20
+ - gauge chart
21
+ - parallel chart
22
+ - sankey chart
23
+ - scatter chart
24
+ - stacked bar chart
25
+ - custom chart
26
+
27
+ In most cases with one line of code you can have a nice chart. The idea of this gem was inspired by [Charkick](https://github.com/ankane/chartkick) gem which is great and allows you to build charts very quickly. It works the best with cooperation of [groupdate](https://github.com/ankane/groupdate) gem. Unfortunatelly it's missing many needed types of charts or other customization options.
28
+
29
+ This implementation have more options and similar "interface" how to build charts (thanks to more Apache eCharts).
30
+
31
+ 1) add gem in Gemfile,
32
+ ```ruby
33
+ gem "rails_charts"
34
+ ```
35
+ 2) add JS, for example in `application.js`
36
+
37
+ ```js
38
+ //= require rails_charts/echarts.min.js
39
+ //= require rails_charts/theme/vintage.js
40
+ ```
41
+
42
+ Note you can specify different themes.
43
+
44
+ 3) add your first chart
45
+ ```ruby
46
+ <%= line_chart User.group(:age).count %>
47
+ ```
48
+ 4) customize charts if needed. See available options or [official documentation](https://echarts.apache.org/examples/en/index.html).
49
+
50
+ ## Installation
51
+
52
+ Add this line to your application's Gemfile:
53
+
54
+ ```ruby
55
+ gem "rails_charts"
56
+ ```
57
+
58
+ And then execute:
59
+ ```bash
60
+ $ bundle
61
+ ```
62
+
63
+ ### Sprockets
64
+
65
+ 1) add eCharts in main JS bundle, e.g. `app/assets/javascripts/application.js`
66
+
67
+ ```javascript
68
+ //= require rails_charts/echarts.min.js
69
+ //= require rails_charts/theme/dark.js
70
+ ```
71
+
72
+ 2) start using :)
73
+
74
+ ### Importmaps
75
+
76
+ 1) change `config/importmap.rb`
77
+
78
+ ```ruby
79
+ pin "rails_charts/echarts.min.js", to: "rails_charts/echarts.min.js", preload: true
80
+ pin "rails_charts/theme/dark.js", to: "rails_charts/theme/dark.js", preload: true
81
+ ```
82
+
83
+ 2) change manifest `app/assets/config/manifest.js`
84
+
85
+ ```javascript
86
+ //= link rails_charts/echarts.min.js
87
+ //= link rails_charts/theme/dark.js
88
+ ```
89
+
90
+ 3) add eCharts in main JS
91
+
92
+ ```javascript
93
+ import "rails_charts/echarts.min.js"
94
+ ```
95
+
96
+ 4) start using :)
97
+
98
+ ## Options
99
+
100
+ ```ruby
101
+ <%= link_chart data, {
102
+ width: '250px',
103
+ height: '250px',
104
+ theme: 'dark',
105
+ class: 'chart-container-class',
106
+ style: 'padding: 10px'
107
+ } %>
108
+ ```
109
+
110
+ Available options:
111
+
112
+ ```
113
+ width: specify width of the chart
114
+ height: specify height of the chart
115
+ theme: specify theme of the chart (available themes examples https://echarts.apache.org/en/download-theme.html)
116
+ class: specify container's CSS class
117
+ id: specify container's ID
118
+ style: add inline style
119
+ debug: for gem development useful if you want to pause somewhere in the code
120
+ vertical: applicable for some types of charts
121
+ code: to see output code what is generated to see the chart, useful for debugging
122
+ options: {...}, nested hash, specify additional eCharts options
123
+ ```
124
+
125
+ Apache eCharts options - https://echarts.apache.org/en/option.html#title.
126
+
127
+ If you need to format tooltip (or other javascript function as an option) you can pass a JS function, but you need to wrap it like:
128
+
129
+ ```ruby
130
+ options: {
131
+ tooltip: {
132
+ valueFormatter: RailsCharts::Javascript.new("(value) => '$' + Math.round(value)")
133
+ }
134
+ }
135
+ ```
136
+
137
+ ## Charts
138
+
139
+ All examples available in https://github.com/railsjazz/rails_charts/tree/main/test/dummy/app/views/home. You can see more examples if you clone this repo and start a dummy app.
140
+
141
+ Every chart has a built in default configuration for tooltips, or other options (sample https://github.com/railsjazz/rails_charts/blob/main/lib/rails_charts/line_chart.rb#L64-L75). This is just to simplify usage of this gem. In the future the plan is to have it configured in initializer.
142
+
143
+ ### Area Chart
144
+
145
+ ![Area Chart](docs/area_chart.png)
146
+
147
+ ```ruby
148
+ <%= area_chart User.distinct.pluck(:role).map{|e| {name: e, data: User.where(role: e).group_by_day(:created_at).count} } %>
149
+ ```
150
+
151
+ ### Line Chart
152
+
153
+ ![Line Chart](docs/line_chart.png)
154
+
155
+ ```ruby
156
+ <%= line_chart User.group(:age).count, class: 'box',
157
+ options: {
158
+ title: {
159
+ text: "People count by age",
160
+ left: 'center'
161
+ },
162
+ }
163
+ %>
164
+ ```
165
+
166
+ ### Bar Chart
167
+
168
+ ![Bar Chart](docs/bar_chart.png)
169
+
170
+ ```ruby
171
+ <%= bar_chart User.group(:role).average(:age),
172
+ class: 'box',
173
+ theme: 'sakura',
174
+ options: {
175
+ series: {
176
+ barWidth: '50%'
177
+ },
178
+ tooltip: {
179
+ valueFormatter: RailsCharts::Javascript.new("(value) => '$' + Math.round(value)")
180
+ }
181
+ }
182
+ %>
183
+ ```
184
+
185
+ ### Calendar Chart
186
+
187
+ ![Calendar Chart](docs/calendar_chart.png)
188
+
189
+ ```ruby
190
+ <%= calendar_chart Commit.for_calendar_chart,
191
+ class: 'box',
192
+ options: {
193
+ visualMap: {
194
+ show: true,
195
+ min: 0,
196
+ max: 40,
197
+ orient: 'horizontal'
198
+ },
199
+ calendar: [{
200
+ range: '2021',
201
+ },]
202
+ }
203
+ %>
204
+
205
+ ```
206
+
207
+ ### Candlestick Chart
208
+
209
+ ![Candlestick Chart](docs/candlestick_chart.png)
210
+
211
+ ```ruby
212
+ <%= candlestick_chart({
213
+ '2017-10-24' => [20, 34, 10, 38],
214
+ '2017-10-25' => [40, 35, 30, 50],
215
+ '2017-10-26' => [31, 38, 33, 44],
216
+ '2017-10-27' => [38, 15, 5, 42]
217
+ },
218
+ class: 'box',
219
+ theme: 'roma',
220
+ options: {
221
+ xAxis: {
222
+ axisTick: {
223
+ alignWithLabel: true
224
+ }
225
+ }
226
+ })
227
+ %>
228
+ ```
229
+
230
+ ### Funnel Chart
231
+
232
+ ![Funnel Chart](docs/funnel_chart.png)
233
+
234
+ ```ruby
235
+ <%= funnel_chart User.get_funnel_sample_data,
236
+ class: 'box',
237
+ height: '400px',
238
+ options: {
239
+ title: {
240
+ text: 'Demo',
241
+ left: 'center'
242
+ }
243
+ }
244
+ %>
245
+ ```
246
+
247
+ ### Gauge Chart
248
+
249
+ ![Gauge Chart](docs/gauge_chart.png)
250
+
251
+ ```ruby
252
+ <%= gauge_chart User.get_gauge_sample_data,
253
+ class: 'box',
254
+ height: '400px',
255
+ options: {
256
+ title: {
257
+ text: 'Demo',
258
+ left: 'center'
259
+ }
260
+ }
261
+ %>
262
+ ```
263
+
264
+ ### Parallel Chart
265
+
266
+ ![Parallel Chart](docs/parallel_chart.png)
267
+
268
+ ```ruby
269
+ <div class="box">
270
+ <%= parallel_chart [
271
+ [1, 2, 1, "Ruby"],
272
+ [2, 3, 2, "JavaScript"],
273
+ [3, 1, 3, "C#"]
274
+ ], {
275
+ options: {
276
+ parallelAxis: [
277
+ { dim: 0, name: '2019', inverse: true, minInterval: 1, min: 1, nameTextStyle: { fontSize: 16 }, axisLabel: { fontSize: 16 } },
278
+ { dim: 1, name: '2020', inverse: true, minInterval: 1, min: 1, nameTextStyle: { fontSize: 16 }, axisLabel: { fontSize: 16 } },
279
+ { dim: 2, name: '2021', inverse: true, minInterval: 1, min: 1, nameTextStyle: { fontSize: 16 }, axisLabel: { fontSize: 16 } },
280
+ { dim: 3, type: "category", name: 'Language', data: ["Ruby", "JavaScript", "C#"], inverse: true, nameTextStyle: { fontSize: 16 }, axisLabel: { fontSize: 14 } },
281
+ ]
282
+ }
283
+ }
284
+ %>
285
+ </div>
286
+ ```
287
+
288
+ ### Donut Chart
289
+
290
+ ![Donut Chart](docs/donut_chart.png)
291
+
292
+ ```ruby
293
+ <%= donut_chart User.group(:role).count,
294
+ class: 'box',
295
+ options: {
296
+ legend: {
297
+ bottom: '0'
298
+ },
299
+ emphasis: {
300
+ itemStyle: {
301
+ shadowBlur: 10,
302
+ shadowOffsetX: 0,
303
+ shadowColor: 'rgba(0, 0, 0, 0.5)'
304
+ }
305
+ }
306
+ }
307
+ %>
308
+ ```
309
+
310
+ ### Pie Chart
311
+
312
+ ![Pie Chart](docs/pie_chart.png)
313
+
314
+ ```ruby
315
+ <%= pie_chart User.group(:role).count,
316
+ class: 'box',
317
+ options: {
318
+ legend: { orient: 'vertical', left: 'left' }
319
+ }
320
+ %>
321
+ ```
322
+
323
+ ### Radar Chart
324
+
325
+ ![Radar Chart](docs/radar_chart.png)
326
+
327
+ ```ruby
328
+ <%= radar_chart User.get_data_for_radar_chart,
329
+ class: 'box',
330
+ options: {
331
+ legend: {
332
+ data: ['Average Salaries', 'Maximum Salary'],
333
+ orient: 'vertical',
334
+ left: '20%'
335
+ }
336
+ }
337
+ %>
338
+ ```
339
+
340
+ ### Sankey Chart
341
+
342
+ ![Sankey Chart](docs/sankey_chart.png)
343
+
344
+ ```ruby
345
+ <%= sankey_chart({
346
+ data: [
347
+ {name: 'Ruby'}, {name: 'HTML'}, {name: 'JS'}, {name: 'Good'}, {name: 'Bad'}, {name: 'CSS'}, {name: 'PHP'}, {name: 'Frontend'}, {name: 'Backend'}
348
+ ],
349
+ links: [
350
+ {
351
+ source: 'Ruby',
352
+ target: 'Good',
353
+ value: 1
354
+ },
355
+ {
356
+ source: 'HTML',
357
+ target: 'Good',
358
+ value: 1
359
+ },
360
+ {
361
+ source: 'JS',
362
+ target: 'Good',
363
+ value: 1
364
+ },
365
+ {
366
+ source: 'CSS',
367
+ target: 'Good',
368
+ value: 1
369
+ },
370
+ {
371
+ source: 'PHP',
372
+ target: 'Bad',
373
+ value: 1
374
+ },
375
+ {
376
+ source: 'Good',
377
+ target: 'Backend',
378
+ value: 1
379
+ },
380
+ {
381
+ source: 'Good',
382
+ target: 'Frontend',
383
+ value: 3
384
+ },
385
+ {
386
+ source: 'Bad',
387
+ target: 'Backend',
388
+ value: 1
389
+ },
390
+ ]
391
+ }, {
392
+ options: {
393
+
394
+ }
395
+ })
396
+ %>
397
+ ```
398
+
399
+ ### Scatter Chart
400
+
401
+ ![Scatter Chart](docs/scatter_chart.png)
402
+
403
+ ```ruby
404
+ <%= scatter_chart [
405
+ { name: 'John', data: User.random_scatter_chart(500, 200) },
406
+ { name: 'Bob', data: User.random_scatter_chart(500, 1000) },
407
+ ],
408
+ {
409
+ class: 'box',
410
+ options: {
411
+ xAxis: {
412
+ name: 'Distance'
413
+ },
414
+ yAxis: {
415
+ name: 'Sales'
416
+ },
417
+ legend: {
418
+ data: [
419
+ {name: 'John'},
420
+ {name: 'Bob'},
421
+ ]
422
+ },
423
+ },
424
+ }
425
+ %>
426
+ ```
427
+
428
+ ### Stacked bar Chart
429
+
430
+ ![Stacked bar Chart](docs/stacked_bar_chart.png)
431
+
432
+ ```ruby
433
+ <%= stacked_bar_chart [
434
+ { name: 'high priority', data: Account.high_priority.group_by_month(:created_at, format: "%b %Y").count },
435
+ { name: 'low priority', data: Account.low_priority.group_by_month(:created_at, format: "%b %Y").count }
436
+ ],
437
+ {
438
+ options: {
439
+ title: {
440
+ text: "Popular vs Unpopular"
441
+ },
442
+ },
443
+ class: 'box',
444
+ vertical: true
445
+ }
446
+ %>
447
+ ```
448
+
449
+ ### Custom Chart
450
+
451
+ ![Custom Chart](docs/custom_chart.png)
452
+
453
+ ```ruby
454
+ <%= custom_chart {...raw JS options ...} %>
455
+ ```
456
+
457
+ ## Contributing
458
+
459
+ You are welcome to contributes. Some open tasks:
460
+
461
+ - importmaps support?
462
+ - webpacker support
463
+ - add more specs
464
+ - add more examples to the dummy app
465
+ - customization, options overides, default values?
466
+ - every "5sec" refresh
467
+ - remote data
468
+ - how to access chart from JS
469
+ - better documentation how to specify theme, locale, etc
470
+ - more examples with data structure
471
+ - add github actions
472
+ - add info about initializer and it's configuration
473
+ - specify info about default configs per chart
474
+ - add support for CSP similar to https://github.com/ankane/chartkick/blob/master/lib/chartkick/helper.rb#L55
475
+ - example of how to build multiple-chart charts
476
+
477
+ ### Development and testing
478
+
479
+ `test/dummy/bin/rails s` - to start dummy app.
480
+
481
+ `rspec` - to run specs.
482
+
483
+ ## License
484
+
485
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
486
+
487
+ Gem is using https://echarts.apache.org/ to build charts.
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require "bundler/setup"
2
+
3
+ require "bundler/gem_tasks"
@@ -0,0 +1,31 @@
1
+ module RailsCharts
2
+ class AreaChart < LineChart
3
+
4
+ def defaults
5
+ {
6
+ tooltip: {
7
+ trigger: 'axis'
8
+ },
9
+ xAxis: {
10
+ boundaryGap: false
11
+ },
12
+ series: {
13
+ areaStyle: {},
14
+ stack: 'Total'
15
+ },
16
+ toolbox: {
17
+ feature: {
18
+ saveAsImage: {}
19
+ },
20
+ }
21
+ }
22
+ end
23
+
24
+ def x_axis
25
+ {
26
+ type: 'category'
27
+ }
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ module RailsCharts
2
+ class BarChart < LineChart
3
+
4
+ def type
5
+ 'bar'
6
+ end
7
+
8
+ def defaults
9
+ {
10
+ tooltip: {
11
+ trigger: 'axis',
12
+ axisPointer: {
13
+ type: 'shadow'
14
+ }
15
+ },
16
+ toolbox: {
17
+ feature: {
18
+ saveAsImage: {}
19
+ },
20
+ }
21
+ }
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,123 @@
1
+ module RailsCharts
2
+ class BaseChart
3
+ using RubyExt
4
+
5
+ attr_reader :data, :options, :container_id, :defaults
6
+ attr_reader :width, :height, :style, :klass, :theme, :locale
7
+ attr_reader :other_options, :debug
8
+ attr_reader :vertical
9
+
10
+ def initialize(data, options = {})
11
+ @data = data
12
+ @options = options
13
+ @other_options = options.delete(:options).presence || {}
14
+ @defaults = RailsCharts.defaults[self.class].presence || {}
15
+
16
+ @container_id = options.delete(:id).presence || "rails_charts_#{Digest::SHA1.hexdigest([Time.now, rand].join)}"
17
+
18
+ @width = options.delete(:width).presence || RailsCharts.options[:width]
19
+ @height = options.delete(:height).presence || RailsCharts.options[:height]
20
+ @theme = options.delete(:theme).presence || RailsCharts.options[:theme]
21
+ @locale = options.delete(:locale).presence || RailsCharts.options[:locale]
22
+ @klass = options.delete(:class).presence || RailsCharts.options[:class]
23
+ @style = options.delete(:style).presence || RailsCharts.options[:style]
24
+
25
+ @debug = options.delete(:debug)
26
+
27
+ @vertical = options.delete(:vertical).presence
28
+ end
29
+
30
+ def js_code
31
+ style_css = []
32
+ style_css << "width: #{width}" if width
33
+ style_css << "height: #{height}" if height
34
+ style_css << style
35
+
36
+ %Q{
37
+ <div id="#{container_id}" class="#{klass}" style="#{style_css.compact.join('; ')}">
38
+ <script>
39
+ if (!window.RailsCharts) {
40
+ window.RailsCharts = {}
41
+ window.RailsCharts.charts = {}
42
+ }
43
+
44
+ function init#{container_id}(e) {
45
+ if (document.documentElement.hasAttribute("data-turbolinks-preview")) return;
46
+ if (document.documentElement.hasAttribute("data-turbo-preview")) return;
47
+
48
+ <!-- #{self.class} -->
49
+ var chartDom = document.getElementById('#{container_id}');
50
+
51
+ if (!chartDom) { return }
52
+
53
+ var lib = ("echarts" in window) ? window.echarts : echarts;
54
+ var chart = lib.init(chartDom, #{theme.to_json}, { "locale": #{locale.to_json} });
55
+ var option = #{option};
56
+ option && chart.setOption(option);
57
+
58
+ window.RailsCharts.charts["#{container_id}"] = chart;
59
+ }
60
+
61
+ function destroy#{container_id}(e) {
62
+ var chart = window.RailsCharts.charts["#{container_id}"];
63
+ if (chart) {
64
+ chart.dispose()
65
+ }
66
+ delete window.RailsCharts.charts["#{container_id}"];
67
+ }
68
+
69
+ window.addEventListener('load', init#{container_id});
70
+ window.addEventListener('turbo:load', init#{container_id});
71
+ window.addEventListener('turbolinks:load', init#{container_id});
72
+
73
+ document.addEventListener("turbolinks:before-render", destroy#{container_id});
74
+ document.addEventListener("turbo:before-render", destroy#{container_id});
75
+ </script>
76
+ </div>
77
+ }
78
+ end
79
+
80
+ def option
81
+ str = build_options.to_json
82
+ Thread.current[:rails_charts_js_code].each do |k, v|
83
+ str.gsub!("\"#{k}\"", v)
84
+ end if Thread.current[:rails_charts_js_code]
85
+ str
86
+ end
87
+
88
+ def build_options
89
+ hash = {}
90
+
91
+ hash[:series] = Array.wrap(generate_series_options)
92
+
93
+ hash = hash.complex_merge(axises)
94
+ hash = hash.complex_merge(defaults)
95
+ hash = hash.complex_merge(other_options)
96
+
97
+ hash
98
+ end
99
+
100
+ def axises
101
+ if self.vertical
102
+ {
103
+ xAxis: y_axis,
104
+ yAxis: x_axis,
105
+ }
106
+ else
107
+ {
108
+ xAxis: x_axis,
109
+ yAxis: y_axis,
110
+ }
111
+ end
112
+ end
113
+
114
+ def x_axis
115
+ []
116
+ end
117
+
118
+ def y_axis
119
+ []
120
+ end
121
+
122
+ end
123
+ end