rails_charts 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +487 -0
- data/Rakefile +3 -0
- data/lib/rails_charts/area_chart.rb +31 -0
- data/lib/rails_charts/bar_chart.rb +25 -0
- data/lib/rails_charts/base_chart.rb +123 -0
- data/lib/rails_charts/calendar_chart.rb +36 -0
- data/lib/rails_charts/candlestick_chart.rb +25 -0
- data/lib/rails_charts/custom_chart.rb +14 -0
- data/lib/rails_charts/donut_chart.rb +36 -0
- data/lib/rails_charts/engine.rb +33 -0
- data/lib/rails_charts/funnel_chart.rb +30 -0
- data/lib/rails_charts/gauge_chart.rb +30 -0
- data/lib/rails_charts/helpers.rb +83 -0
- data/lib/rails_charts/javascript.rb +17 -0
- data/lib/rails_charts/line_chart.rb +78 -0
- data/lib/rails_charts/parallel_chart.rb +30 -0
- data/lib/rails_charts/pie_chart.rb +55 -0
- data/lib/rails_charts/radar_chart.rb +38 -0
- data/lib/rails_charts/ruby_ext.rb +28 -0
- data/lib/rails_charts/sankey_chart.rb +31 -0
- data/lib/rails_charts/scatter_chart.rb +34 -0
- data/lib/rails_charts/stacked_bar_chart.rb +13 -0
- data/lib/rails_charts/version.rb +3 -0
- data/lib/rails_charts.rb +43 -0
- data/vendor/assets/rails_charts/echarts.min.js +45 -0
- data/vendor/assets/rails_charts/extension/bmap.js +413 -0
- data/vendor/assets/rails_charts/extension/bmap.js.map +1 -0
- data/vendor/assets/rails_charts/extension/bmap.min.js +22 -0
- data/vendor/assets/rails_charts/extension/dataTool.js +436 -0
- data/vendor/assets/rails_charts/extension/dataTool.js.map +1 -0
- data/vendor/assets/rails_charts/extension/dataTool.min.js +22 -0
- data/vendor/assets/rails_charts/i18n/langCS-obj.js +172 -0
- data/vendor/assets/rails_charts/i18n/langCS.js +168 -0
- data/vendor/assets/rails_charts/i18n/langDE-obj.js +172 -0
- data/vendor/assets/rails_charts/i18n/langDE.js +168 -0
- data/vendor/assets/rails_charts/i18n/langEN-obj.js +173 -0
- data/vendor/assets/rails_charts/i18n/langEN.js +169 -0
- data/vendor/assets/rails_charts/i18n/langES-obj.js +111 -0
- data/vendor/assets/rails_charts/i18n/langES.js +107 -0
- data/vendor/assets/rails_charts/i18n/langFI-obj.js +111 -0
- data/vendor/assets/rails_charts/i18n/langFI.js +107 -0
- data/vendor/assets/rails_charts/i18n/langFR-obj.js +173 -0
- data/vendor/assets/rails_charts/i18n/langFR.js +169 -0
- data/vendor/assets/rails_charts/i18n/langIT-obj.js +173 -0
- data/vendor/assets/rails_charts/i18n/langIT.js +169 -0
- data/vendor/assets/rails_charts/i18n/langJA-obj.js +173 -0
- data/vendor/assets/rails_charts/i18n/langJA.js +169 -0
- data/vendor/assets/rails_charts/i18n/langKO-obj.js +173 -0
- data/vendor/assets/rails_charts/i18n/langKO.js +169 -0
- data/vendor/assets/rails_charts/i18n/langPL-obj.js +173 -0
- data/vendor/assets/rails_charts/i18n/langPL.js +169 -0
- data/vendor/assets/rails_charts/i18n/langPT-br-obj.js +174 -0
- data/vendor/assets/rails_charts/i18n/langPT-br.js +170 -0
- data/vendor/assets/rails_charts/i18n/langRO-obj.js +173 -0
- data/vendor/assets/rails_charts/i18n/langRO.js +169 -0
- data/vendor/assets/rails_charts/i18n/langRU-obj.js +174 -0
- data/vendor/assets/rails_charts/i18n/langRU.js +170 -0
- data/vendor/assets/rails_charts/i18n/langSI-obj.js +172 -0
- data/vendor/assets/rails_charts/i18n/langSI.js +168 -0
- data/vendor/assets/rails_charts/i18n/langTH-obj.js +111 -0
- data/vendor/assets/rails_charts/i18n/langTH.js +107 -0
- data/vendor/assets/rails_charts/i18n/langZH-obj.js +168 -0
- data/vendor/assets/rails_charts/i18n/langZH.js +164 -0
- data/vendor/assets/rails_charts/theme/azul.js +163 -0
- data/vendor/assets/rails_charts/theme/bee-inspired.js +178 -0
- data/vendor/assets/rails_charts/theme/blue.js +178 -0
- data/vendor/assets/rails_charts/theme/caravan.js +178 -0
- data/vendor/assets/rails_charts/theme/carp.js +163 -0
- data/vendor/assets/rails_charts/theme/cool.js +180 -0
- data/vendor/assets/rails_charts/theme/dark-blue.js +164 -0
- data/vendor/assets/rails_charts/theme/dark-bold.js +164 -0
- data/vendor/assets/rails_charts/theme/dark-digerati.js +164 -0
- data/vendor/assets/rails_charts/theme/dark-fresh-cut.js +164 -0
- data/vendor/assets/rails_charts/theme/dark-mushroom.js +164 -0
- data/vendor/assets/rails_charts/theme/dark.js +224 -0
- data/vendor/assets/rails_charts/theme/eduardo.js +178 -0
- data/vendor/assets/rails_charts/theme/forest.js +163 -0
- data/vendor/assets/rails_charts/theme/fresh-cut.js +163 -0
- data/vendor/assets/rails_charts/theme/fruit.js +178 -0
- data/vendor/assets/rails_charts/theme/gray.js +220 -0
- data/vendor/assets/rails_charts/theme/green.js +222 -0
- data/vendor/assets/rails_charts/theme/helianthus.js +263 -0
- data/vendor/assets/rails_charts/theme/infographic.js +236 -0
- data/vendor/assets/rails_charts/theme/inspired.js +163 -0
- data/vendor/assets/rails_charts/theme/jazz.js +163 -0
- data/vendor/assets/rails_charts/theme/london.js +163 -0
- data/vendor/assets/rails_charts/theme/macarons.js +240 -0
- data/vendor/assets/rails_charts/theme/macarons2.js +249 -0
- data/vendor/assets/rails_charts/theme/mint.js +155 -0
- data/vendor/assets/rails_charts/theme/red-velvet.js +163 -0
- data/vendor/assets/rails_charts/theme/red.js +225 -0
- data/vendor/assets/rails_charts/theme/roma.js +119 -0
- data/vendor/assets/rails_charts/theme/royal.js +163 -0
- data/vendor/assets/rails_charts/theme/sakura.js +140 -0
- data/vendor/assets/rails_charts/theme/shine.js +177 -0
- data/vendor/assets/rails_charts/theme/tech-blue.js +180 -0
- data/vendor/assets/rails_charts/theme/vintage.js +63 -0
- 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,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
|