peity_vanilla_rails 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c48643fc2950ad8495f99384593c7fd1ee26732b64c9df86b62781b738a25ce
4
- data.tar.gz: c6ef11ccda4de91fd692c17902255a719b64cfb8038dbd0aefa02ffb13b107ab
3
+ metadata.gz: 53261d4741de90d14704c23e23624151184465c0e1a57edcd00b32b6751167e5
4
+ data.tar.gz: f7215991dffe2cc9756842981d36714b72c779cf7fabf9f3e522fda478b2a42d
5
5
  SHA512:
6
- metadata.gz: 77de0c81a7259fb311f37804511e85654e1bd91eca5dc3a487d2b49a8a5b433a2100eaa6af5ff5c012070188316e60f3af5e9079f8902377e901efd38777b7dd
7
- data.tar.gz: eab3b26b503ebf900d799a8cbdca94aee4acc85bc57fbba4144a9be393d03c889c0802d47931e9decfc44025d11161a3e5faab25db16c2a75933fef19276a6d6
6
+ metadata.gz: 38eb290c3931f3fcb6ddb0b0397e039793a15b1475915839b02575640b413cd48fecd97b0e327cfe8cf4992096af73c9e6c645fee297525bcf01e7792f0d00c6
7
+ data.tar.gz: ca345ad7e083cb26559c9605235718795e81a374ea819e6349f09f239475c254c028cc22ba3ebd7bdb94d7656edfa1c465427a87d46b4a4a73e5a3498f743a9b
data/README.md CHANGED
@@ -1,20 +1,41 @@
1
1
  # Peity Vanilla Rails
2
2
 
3
- Sparklines are small but intense charts. This gem is a wrapper around [peity_vanilla](https://github.com/railsjazz/peity_vanilla) library. You can generate simple but informative charts with vanilla JS.
3
+ [![RailsJazz](https://github.com/igorkasyanchuk/rails_time_travel/blob/main/docs/my_other.svg?raw=true)](https://www.railsjazz.com)
4
4
 
5
- ![Sparklines Rails](docs/sparklines.png)
5
+ Sparklines are small but intense charts. This gem is a wrapper around [peity-vanilla](https://github.com/railsjazz/peity_vanilla) library. You can generate simple but informative charts with vanilla JS.
6
+
7
+ <img src="./docs/sparklines.png" height="400px"/>
6
8
 
7
9
  ## Usage
8
10
 
9
- 1. Add to `application.js`
11
+ 1. add gem to the `Gemfile`
12
+
13
+ ```ruby
14
+ gem "peity_vanilla_rails"
15
+ ```
16
+
17
+ 2. Add to `application.js`
18
+
19
+ ### For Assets Pipeline:
10
20
 
11
21
  ```javascript
12
- //= require peity_vanilla.js
22
+ //= require peity-vanilla-rails.js
13
23
  ```
14
24
 
15
- 2. Add charts in your code:
25
+ ### For Importmaps
16
26
 
17
- ```ruby
27
+ In `application.js`
28
+
29
+ ```js
30
+ import "peity-vanilla-rails";
31
+ ```
32
+
33
+ #### Note: After `peity-vanilla-rails.js` is imported, it will listen to changes of `peity` and `data-peity` attributes of every DOM element
34
+ Pure `peity-vanilla` library is also acessible via `peity-vanilla.js` for Assets Pipeline, and `import peity from "peity-vanilla"` for Importmaps
35
+
36
+ 3. Add charts in your code:
37
+
38
+ ```erb
18
39
  <h3>Line</h3>
19
40
  <%= peity_line_chart([115,123,234,-113,-43,-223,127,332,152,233]) %>
20
41
  <%= peity_line_chart(100.times.map{rand(100) * [1,-1].sample}, options: { width: 240, fill: 'lightgreen', stroke: 'blue' }) %>
@@ -36,16 +57,29 @@ Sparklines are small but intense charts. This gem is a wrapper around [peity_van
36
57
  <%= peity_donut_chart [236,300] %>
37
58
  ```
38
59
 
39
- ## Installation
40
- Add this line to your application's Gemfile:
60
+ ## More Examples
41
61
 
42
- ```ruby
43
- gem "peity_vanilla_rails"
44
- ```
62
+ Check the [original](https://github.com/railsjazz/peity_vanilla) page.
63
+
64
+ <img src="https://github.com/railsjazz/peity_vanilla/raw/main/docs/color.png"/>
65
+ <img src="https://github.com/railsjazz/peity_vanilla/raw/main/docs/custom.png"/>
66
+ <img src="https://github.com/railsjazz/peity_vanilla/raw/main/docs/animation.gif"/>
67
+
68
+ ```erb
69
+ <%= peity_line_chart([5,3,9,6,5,9,7,3,5,2,5,3,9,6,5,9,7,3,5,2], id: 'updating-chart') %>
45
70
 
46
- And then execute:
47
- ```bash
48
- $ bundle
71
+ <script>
72
+ var updatingChart = document.getElementById("updating-chart");
73
+
74
+ setInterval(function() {
75
+ var random = Math.round(Math.random() * 10)
76
+ var values = updatingChart.innerText.split(",")
77
+ values.shift()
78
+ values.push(random)
79
+
80
+ updatingChart.innerText = values.join(",")
81
+ }, 1000);
82
+ </script>
49
83
  ```
50
84
 
51
85
  ## Default Options
@@ -96,8 +130,14 @@ You can pass in `options` any of the attributes.
96
130
  </script>
97
131
  ```
98
132
 
133
+ ## TODO
134
+
135
+ - remote datasource and autoupdate
136
+
99
137
  ## Contributing
100
- Contribution directions go here.
138
+
139
+ You are welcome to contribute.
101
140
 
102
141
  ## License
142
+
103
143
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,503 @@
1
+ /*!
2
+ Peity Vanila Rails 0.2.0
3
+ Copyright © 2022 RailsJazz
4
+ https://railsjazz.com
5
+ */
6
+
7
+ /*!
8
+ Peity Vanila JS 0.0.8
9
+ Copyright © 2022 RailsJazz
10
+ https://railsjazz.com
11
+ */
12
+
13
+ const isFunction = (o) =>
14
+ o !== null && typeof o === "function" && !!o.apply;
15
+
16
+ const svgElement = (tag, attrs) => {
17
+ const element = document.createElementNS("http://www.w3.org/2000/svg", tag);
18
+ for (var attr in attrs) {
19
+ element.setAttribute(attr, attrs[attr]);
20
+ }
21
+ return element;
22
+ };
23
+
24
+ const svgSupported =
25
+ "createElementNS" in document && svgElement("svg", {}).createSVGRect();
26
+
27
+ class Peity {
28
+ static defaults = {};
29
+ static graphers = {};
30
+
31
+ constructor(element, type, options = {}) {
32
+ this.element = element;
33
+ this.type = type;
34
+ this.options = Object.assign(
35
+ {},
36
+ Peity.defaults[this.type],
37
+ JSON.parse(element.dataset["peity"] || "{}"),
38
+ options
39
+ );
40
+
41
+ if(this.element._peity) {
42
+ this.element._peity.destroy();
43
+ }
44
+ this.element._peity = this;
45
+ }
46
+
47
+ draw() {
48
+ const options = this.options;
49
+ Peity.graphers[this.type](this);
50
+ if (isFunction(options.after)) options.after.call(this, options);
51
+ }
52
+
53
+ fill() {
54
+ var fill = this.options.fill;
55
+
56
+ return isFunction(fill)
57
+ ? fill
58
+ : function (_, i) {
59
+ return fill[i % fill.length];
60
+ };
61
+ }
62
+
63
+ prepare(width, height) {
64
+ if (!this.svg) {
65
+ this.element.style.display = "none";
66
+ this.element.after(
67
+ (this.svg = svgElement("svg", {
68
+ class: "peity",
69
+ }))
70
+ );
71
+ }
72
+
73
+ this.svg.innerHTML = "";
74
+ this.svg.setAttribute("width", width);
75
+ this.svg.setAttribute("height", height);
76
+
77
+ return this.svg;
78
+ }
79
+
80
+ get values() {
81
+ return this.element.innerText
82
+ .split(this.options.delimiter)
83
+ .map((value) => parseFloat(value));
84
+ }
85
+
86
+ mount() {
87
+ if (!svgSupported) return;
88
+
89
+ this.element.addEventListener("DOMSubtreeModified", this.draw.bind(this));
90
+ this.draw();
91
+
92
+ this.mounted = true;
93
+ }
94
+
95
+ unmount() {
96
+ this.element.removeEventListener("DOMSubtreeModified", this.draw);
97
+ this.svg.remove();
98
+ this.mounted = false;
99
+ }
100
+
101
+ destroy() {
102
+ this.unmount();
103
+
104
+ delete this.element._peity;
105
+ }
106
+
107
+ static register(type, defaults, grapher) {
108
+ Peity.defaults[type] = defaults;
109
+ Peity.graphers[type] = grapher;
110
+ }
111
+ }
112
+
113
+ const renderer$2 = (peity) => {
114
+ if (!peity.options.delimiter) {
115
+ const delimiter = peity.element.innerText.match(/[^0-9\.]/);
116
+ peity.options.delimiter = delimiter ? delimiter[0] : ",";
117
+ }
118
+
119
+ let values = peity.values.map((n) => (n > 0 ? n : 0));
120
+
121
+ if (peity.options.delimiter == "/") {
122
+ let v1 = values[0];
123
+ let v2 = values[1];
124
+ values = [v1, Math.max(0, v2 - v1)];
125
+ }
126
+
127
+ let i = 0;
128
+ let length = values.length;
129
+ let sum = 0;
130
+
131
+ for (; i < length; i++) {
132
+ sum += values[i];
133
+ }
134
+
135
+ if (!sum) {
136
+ length = 2;
137
+ sum = 1;
138
+ values = [0, 1];
139
+ }
140
+
141
+ let diameter = peity.options.radius * 2;
142
+
143
+ const svg = peity.prepare(
144
+ peity.options.width || diameter,
145
+ peity.options.height || diameter
146
+ );
147
+
148
+ const width = svg.clientWidth;
149
+ const height = svg.clientHeight;
150
+ const cx = width / 2;
151
+ const cy = height / 2;
152
+
153
+ const radius = Math.min(cx, cy);
154
+ let innerRadius = peity.options.innerRadius;
155
+
156
+ if (peity.type == "donut" && !innerRadius) {
157
+ innerRadius = radius * 0.5;
158
+ }
159
+
160
+ const fill = peity.fill();
161
+
162
+ const scale = (value, radius) => {
163
+ const radians = (value / sum) * Math.PI * 2 - Math.PI / 2;
164
+
165
+ return [radius * Math.cos(radians) + cx, radius * Math.sin(radians) + cy];
166
+ };
167
+
168
+ let cumulative = 0;
169
+
170
+ for (i = 0; i < length; i++) {
171
+ const value = values[i];
172
+ const portion = value / sum;
173
+ let node;
174
+
175
+ if (portion == 0) continue;
176
+
177
+ if (portion == 1) {
178
+ if (innerRadius) {
179
+ const x2 = cx - 0.01;
180
+ const y1 = cy - radius;
181
+ const y2 = cy - innerRadius;
182
+
183
+ node = svgElement("path", {
184
+ d: [
185
+ "M",
186
+ cx,
187
+ y1,
188
+ "A",
189
+ radius,
190
+ radius,
191
+ 0,
192
+ 1,
193
+ 1,
194
+ x2,
195
+ y1,
196
+ "L",
197
+ x2,
198
+ y2,
199
+ "A",
200
+ innerRadius,
201
+ innerRadius,
202
+ 0,
203
+ 1,
204
+ 0,
205
+ cx,
206
+ y2,
207
+ ].join(" "),
208
+ "data-value": value,
209
+ });
210
+ } else {
211
+ node = svgElement("circle", {
212
+ cx: cx,
213
+ cy: cy,
214
+ "data-value": value,
215
+ r: radius,
216
+ });
217
+ }
218
+ } else {
219
+ const cumulativePlusValue = cumulative + value;
220
+
221
+ let d = ["M"].concat(
222
+ scale(cumulative, radius),
223
+ "A",
224
+ radius,
225
+ radius,
226
+ 0,
227
+ portion > 0.5 ? 1 : 0,
228
+ 1,
229
+ scale(cumulativePlusValue, radius),
230
+ "L"
231
+ );
232
+
233
+ if (innerRadius) {
234
+ d = d.concat(
235
+ scale(cumulativePlusValue, innerRadius),
236
+ "A",
237
+ innerRadius,
238
+ innerRadius,
239
+ 0,
240
+ portion > 0.5 ? 1 : 0,
241
+ 0,
242
+ scale(cumulative, innerRadius)
243
+ );
244
+ } else {
245
+ d.push(cx, cy);
246
+ }
247
+
248
+ cumulative += value;
249
+
250
+ node = svgElement("path", {
251
+ d: d.join(" "),
252
+ "data-value": value,
253
+ });
254
+ }
255
+
256
+ node.setAttribute("fill", fill.call(peity, value, i, values));
257
+
258
+ svg.append(node);
259
+ }
260
+ };
261
+
262
+ const defaults$2 = {
263
+ fill: ["#ff9900", "#fff4dd", "#ffc66e"],
264
+ radius: 8,
265
+ };
266
+
267
+ const renderer$1 = (peity) => {
268
+ const values = peity.values;
269
+ const max = Math.max.apply(
270
+ Math,
271
+ peity.options.max == undefined ? values : values.concat(peity.options.max)
272
+ );
273
+ const min = Math.min.apply(
274
+ Math,
275
+ peity.options.min == undefined ? values : values.concat(peity.options.min)
276
+ );
277
+
278
+ const svg = peity.prepare(peity.options.width, peity.options.height);
279
+ const width = svg.clientWidth;
280
+ const height = svg.clientHeight;
281
+ const diff = max - min;
282
+ const padding = peity.options.padding;
283
+ const fill = peity.fill();
284
+
285
+ const xScale = (input) => {
286
+ return (input * width) / values.length;
287
+ };
288
+
289
+ const yScale = (input) => {
290
+ return height - (diff ? ((input - min) / diff) * height : 1);
291
+ };
292
+
293
+ for (var i = 0; i < values.length; i++) {
294
+ let x = xScale(i + padding);
295
+ let w = xScale(i + 1 - padding) - x;
296
+ let value = values[i];
297
+ let valueY = yScale(value);
298
+ let y1 = valueY;
299
+ let y2 = valueY;
300
+ let h;
301
+
302
+ if (!diff) {
303
+ h = 1;
304
+ } else if (value < 0) {
305
+ y1 = yScale(Math.min(max, 0));
306
+ } else {
307
+ y2 = yScale(Math.max(min, 0));
308
+ }
309
+
310
+ h = y2 - y1;
311
+
312
+ if (h == 0) {
313
+ h = 1;
314
+ if (max > 0 && diff) y1--;
315
+ }
316
+
317
+ svg.append(
318
+ svgElement("rect", {
319
+ "data-value": value,
320
+ fill: fill.call(peity, value, i, values),
321
+ x: x,
322
+ y: y1,
323
+ width: w,
324
+ height: h,
325
+ })
326
+ );
327
+ }
328
+ };
329
+
330
+ const defaults$1 = {
331
+ delimiter: ",",
332
+ fill: ["#4D89F9"],
333
+ height: 16,
334
+ min: 0,
335
+ padding: 0.1,
336
+ width: 32,
337
+ };
338
+
339
+ const renderer = (peity) => {
340
+ const values = peity.values;
341
+ if (values.length == 1) values.push(values[0]);
342
+ const max = Math.max.apply(
343
+ Math,
344
+ peity.options.max == undefined ? values : values.concat(peity.options.max)
345
+ );
346
+ const min = Math.min.apply(
347
+ Math,
348
+ peity.options.min == undefined ? values : values.concat(peity.options.min)
349
+ );
350
+
351
+ const svg = peity.prepare(peity.options.width, peity.options.height);
352
+ const strokeWidth = peity.options.strokeWidth;
353
+ const width = svg.clientWidth;
354
+ const height = svg.clientHeight - strokeWidth;
355
+ const diff = max - min;
356
+
357
+ const xScale = (input) => {
358
+ return input * (width / (values.length - 1));
359
+ };
360
+
361
+ const yScale = (input) => {
362
+ let y = height;
363
+
364
+ if (diff) {
365
+ y -= ((input - min) / diff) * height;
366
+ }
367
+
368
+ return y + strokeWidth / 2;
369
+ };
370
+
371
+ let zero = yScale(Math.max(min, 0));
372
+ let coords = [0, zero];
373
+
374
+ for (var i = 0; i < values.length; i++) {
375
+ coords.push(xScale(i), yScale(values[i]));
376
+ }
377
+
378
+ coords.push(width, zero);
379
+
380
+ if (peity.options.fill) {
381
+ svg.append(
382
+ svgElement("polygon", {
383
+ fill: peity.options.fill,
384
+ points: coords.join(" "),
385
+ })
386
+ );
387
+ }
388
+
389
+ if (strokeWidth) {
390
+ svg.append(
391
+ svgElement("polyline", {
392
+ fill: "none",
393
+ points: coords.slice(2, coords.length - 2).join(" "),
394
+ stroke: peity.options.stroke,
395
+ "stroke-width": strokeWidth,
396
+ "stroke-linecap": "square",
397
+ })
398
+ );
399
+ }
400
+ };
401
+
402
+ const defaults = {
403
+ delimiter: ",",
404
+ fill: "#c6d9fd",
405
+ height: 16,
406
+ min: 0,
407
+ stroke: "#4d89f9",
408
+ strokeWidth: 1,
409
+ width: 32,
410
+ };
411
+
412
+ Peity.register("pie", defaults$2, renderer$2);
413
+ Peity.register("donut", defaults$2, renderer$2);
414
+ Peity.register("bar", defaults$1, renderer$1);
415
+ Peity.register("line", defaults, renderer);
416
+
417
+ const peity = function (element, type, options) {
418
+ const peity = new Peity(element, type, options);
419
+ peity.mount();
420
+
421
+ return peity;
422
+ };
423
+
424
+ peity.defaults = Peity.defaults;
425
+ peity.graphers = Peity.graphers;
426
+
427
+ const getPeityType = (node) => node.getAttribute('peity');
428
+
429
+ const elementFromNode = (node) => {
430
+ if (node.nodeType == Node.ELEMENT_NODE) {
431
+ return node;
432
+ }
433
+ };
434
+
435
+ const processNodeAdded = (node) => {
436
+ if (node.matches("[peity]")) {
437
+ peity(node, getPeityType(node));
438
+ }
439
+ };
440
+
441
+ const processNodeRemoved = (node) => {
442
+ if (node._peity) {
443
+ node._peity.destroy();
444
+ }
445
+ };
446
+
447
+ const processAttributeChanged = (mutation) => {
448
+ const node = mutation.target;
449
+ switch (mutation.attributeName) {
450
+ case "peity":
451
+ const type = getPeityType(node);
452
+ if (type) {
453
+ peity(node, type);
454
+ } else {
455
+ node._peity.unmount();
456
+ }
457
+ break;
458
+ case "data-peity":
459
+ if(node._peity) {
460
+ peity(node, node._peity.type);
461
+ }
462
+ break;
463
+ }
464
+ };
465
+
466
+ const callback = (mutationList, observer) => {
467
+ mutationList.forEach(function (mutation) {
468
+ switch (mutation.type) {
469
+ case "childList":
470
+ for (const node of Array.from(mutation.addedNodes)) {
471
+ const element = elementFromNode(node);
472
+ if (element) {
473
+ processNodeAdded(element);
474
+ }
475
+ }
476
+ for (const node of Array.from(mutation.removedNodes)) {
477
+ const element = elementFromNode(node);
478
+ if (element) {
479
+ processNodeRemoved(element);
480
+ }
481
+ }
482
+ break;
483
+ case "attributes":
484
+ processAttributeChanged(mutation);
485
+ break;
486
+ }
487
+ });
488
+ };
489
+
490
+ const observerOptions = {
491
+ childList: true,
492
+ attributes: true,
493
+ subtree: true,
494
+ };
495
+
496
+ const observer = new MutationObserver(callback);
497
+ observer.observe(document.documentElement, observerOptions);
498
+
499
+ for (const node of Array.from(document.documentElement.querySelectorAll('[peity]'))) {
500
+ processNodeAdded(node);
501
+ }
502
+
503
+ export { peity as default };
@@ -0,0 +1,11 @@
1
+ /*!
2
+ Peity Vanila Rails 0.2.0
3
+ Copyright © 2022 RailsJazz
4
+ https://railsjazz.com
5
+ */
6
+ var peity=function(){"use strict";
7
+ /*!
8
+ Peity Vanila JS 0.0.8
9
+ Copyright © 2022 RailsJazz
10
+ https://railsjazz.com
11
+ */const t=t=>null!==t&&"function"==typeof t&&!!t.apply,e=(t,e)=>{const i=document.createElementNS("http://www.w3.org/2000/svg",t);for(var n in e)i.setAttribute(n,e[n]);return i},i="createElementNS"in document&&e("svg",{}).createSVGRect();class n{static defaults={};static graphers={};constructor(t,e,i={}){this.element=t,this.type=e,this.options=Object.assign({},n.defaults[this.type],JSON.parse(t.dataset.peity||"{}"),i),this.element._peity&&this.element._peity.destroy(),this.element._peity=this}draw(){const e=this.options;n.graphers[this.type](this),t(e.after)&&e.after.call(this,e)}fill(){var e=this.options.fill;return t(e)?e:function(t,i){return e[i%e.length]}}prepare(t,i){return this.svg||(this.element.style.display="none",this.element.after(this.svg=e("svg",{class:"peity"}))),this.svg.innerHTML="",this.svg.setAttribute("width",t),this.svg.setAttribute("height",i),this.svg}get values(){return this.element.innerText.split(this.options.delimiter).map((t=>parseFloat(t)))}mount(){i&&(this.element.addEventListener("DOMSubtreeModified",this.draw.bind(this)),this.draw(),this.mounted=!0)}unmount(){this.element.removeEventListener("DOMSubtreeModified",this.draw),this.svg.remove(),this.mounted=!1}destroy(){this.unmount(),delete this.element._peity}static register(t,e,i){n.defaults[t]=e,n.graphers[t]=i}}const s=t=>{if(!t.options.delimiter){const e=t.element.innerText.match(/[^0-9\.]/);t.options.delimiter=e?e[0]:","}let i=t.values.map((t=>t>0?t:0));if("/"==t.options.delimiter){let t=i[0],e=i[1];i=[t,Math.max(0,e-t)]}let n=0,s=i.length,o=0;for(;n<s;n++)o+=i[n];o||(s=2,o=1,i=[0,1]);let r=2*t.options.radius;const a=t.prepare(t.options.width||r,t.options.height||r),l=a.clientWidth,h=a.clientHeight,p=l/2,c=h/2,d=Math.min(p,c);let u=t.options.innerRadius;"donut"!=t.type||u||(u=.5*d);const m=t.fill(),f=(t,e)=>{const i=t/o*Math.PI*2-Math.PI/2;return[e*Math.cos(i)+p,e*Math.sin(i)+c]};let g=0;for(n=0;n<s;n++){const s=i[n],r=s/o;let l;if(0!=r){if(1==r)if(u){const t=p-.01,i=c-d,n=c-u;l=e("path",{d:["M",p,i,"A",d,d,0,1,1,t,i,"L",t,n,"A",u,u,0,1,0,p,n].join(" "),"data-value":s})}else l=e("circle",{cx:p,cy:c,"data-value":s,r:d});else{const t=g+s;let i=["M"].concat(f(g,d),"A",d,d,0,r>.5?1:0,1,f(t,d),"L");u?i=i.concat(f(t,u),"A",u,u,0,r>.5?1:0,0,f(g,u)):i.push(p,c),g+=s,l=e("path",{d:i.join(" "),"data-value":s})}l.setAttribute("fill",m.call(t,s,n,i)),a.append(l)}}},o={fill:["#ff9900","#fff4dd","#ffc66e"],radius:8};n.register("pie",o,s),n.register("donut",o,s),n.register("bar",{delimiter:",",fill:["#4D89F9"],height:16,min:0,padding:.1,width:32},(t=>{const i=t.values,n=Math.max.apply(Math,null==t.options.max?i:i.concat(t.options.max)),s=Math.min.apply(Math,null==t.options.min?i:i.concat(t.options.min)),o=t.prepare(t.options.width,t.options.height),r=o.clientWidth,a=o.clientHeight,l=n-s,h=t.options.padding,p=t.fill(),c=t=>t*r/i.length,d=t=>a-(l?(t-s)/l*a:1);for(var u=0;u<i.length;u++){let r,a=c(u+h),m=c(u+1-h)-a,f=i[u],g=d(f),y=g,v=g;l?f<0?y=d(Math.min(n,0)):v=d(Math.max(s,0)):r=1,r=v-y,0==r&&(r=1,n>0&&l&&y--),o.append(e("rect",{"data-value":f,fill:p.call(t,f,u,i),x:a,y:y,width:m,height:r}))}})),n.register("line",{delimiter:",",fill:"#c6d9fd",height:16,min:0,stroke:"#4d89f9",strokeWidth:1,width:32},(t=>{const i=t.values;1==i.length&&i.push(i[0]);const n=Math.max.apply(Math,null==t.options.max?i:i.concat(t.options.max)),s=Math.min.apply(Math,null==t.options.min?i:i.concat(t.options.min)),o=t.prepare(t.options.width,t.options.height),r=t.options.strokeWidth,a=o.clientWidth,l=o.clientHeight-r,h=n-s,p=t=>{let e=l;return h&&(e-=(t-s)/h*l),e+r/2};let c=p(Math.max(s,0)),d=[0,c];for(var u=0;u<i.length;u++)d.push(u*(a/(i.length-1)),p(i[u]));d.push(a,c),t.options.fill&&o.append(e("polygon",{fill:t.options.fill,points:d.join(" ")})),r&&o.append(e("polyline",{fill:"none",points:d.slice(2,d.length-2).join(" "),stroke:t.options.stroke,"stroke-width":r,"stroke-linecap":"square"}))}));const r=function(t,e,i){const s=new n(t,e,i);return s.mount(),s};r.defaults=n.defaults,r.graphers=n.graphers;const a=t=>t.getAttribute("peity"),l=t=>{if(t.nodeType==Node.ELEMENT_NODE)return t},h=t=>{t.matches("[peity]")&&r(t,a(t))},p=t=>{t._peity&&t._peity.destroy()};new MutationObserver(((t,e)=>{t.forEach((function(t){switch(t.type){case"childList":for(const e of Array.from(t.addedNodes)){const t=l(e);t&&h(t)}for(const e of Array.from(t.removedNodes)){const t=l(e);t&&p(t)}break;case"attributes":(t=>{const e=t.target;switch(t.attributeName){case"peity":const t=a(e);t?r(e,t):e._peity.unmount();break;case"data-peity":e._peity&&r(e,e._peity.type)}})(t)}}))})).observe(document.documentElement,{childList:!0,attributes:!0,subtree:!0});for(const t of Array.from(document.documentElement.querySelectorAll("[peity]")))h(t);return r}();
@@ -0,0 +1,421 @@
1
+ /*!
2
+ Peity Vanila JS 0.0.8
3
+ Copyright © 2022 RailsJazz
4
+ https://railsjazz.com
5
+ */
6
+
7
+ const isFunction = (o) =>
8
+ o !== null && typeof o === "function" && !!o.apply;
9
+
10
+ const svgElement = (tag, attrs) => {
11
+ const element = document.createElementNS("http://www.w3.org/2000/svg", tag);
12
+ for (var attr in attrs) {
13
+ element.setAttribute(attr, attrs[attr]);
14
+ }
15
+ return element;
16
+ };
17
+
18
+ const svgSupported =
19
+ "createElementNS" in document && svgElement("svg", {}).createSVGRect();
20
+
21
+ class Peity {
22
+ static defaults = {};
23
+ static graphers = {};
24
+
25
+ constructor(element, type, options = {}) {
26
+ this.element = element;
27
+ this.type = type;
28
+ this.options = Object.assign(
29
+ {},
30
+ Peity.defaults[this.type],
31
+ JSON.parse(element.dataset["peity"] || "{}"),
32
+ options
33
+ );
34
+
35
+ if(this.element._peity) {
36
+ this.element._peity.destroy();
37
+ }
38
+ this.element._peity = this;
39
+ }
40
+
41
+ draw() {
42
+ const options = this.options;
43
+ Peity.graphers[this.type](this);
44
+ if (isFunction(options.after)) options.after.call(this, options);
45
+ }
46
+
47
+ fill() {
48
+ var fill = this.options.fill;
49
+
50
+ return isFunction(fill)
51
+ ? fill
52
+ : function (_, i) {
53
+ return fill[i % fill.length];
54
+ };
55
+ }
56
+
57
+ prepare(width, height) {
58
+ if (!this.svg) {
59
+ this.element.style.display = "none";
60
+ this.element.after(
61
+ (this.svg = svgElement("svg", {
62
+ class: "peity",
63
+ }))
64
+ );
65
+ }
66
+
67
+ this.svg.innerHTML = "";
68
+ this.svg.setAttribute("width", width);
69
+ this.svg.setAttribute("height", height);
70
+
71
+ return this.svg;
72
+ }
73
+
74
+ get values() {
75
+ return this.element.innerText
76
+ .split(this.options.delimiter)
77
+ .map((value) => parseFloat(value));
78
+ }
79
+
80
+ mount() {
81
+ if (!svgSupported) return;
82
+
83
+ this.element.addEventListener("DOMSubtreeModified", this.draw.bind(this));
84
+ this.draw();
85
+
86
+ this.mounted = true;
87
+ }
88
+
89
+ unmount() {
90
+ this.element.removeEventListener("DOMSubtreeModified", this.draw);
91
+ this.svg.remove();
92
+ this.mounted = false;
93
+ }
94
+
95
+ destroy() {
96
+ this.unmount();
97
+
98
+ delete this.element._peity;
99
+ }
100
+
101
+ static register(type, defaults, grapher) {
102
+ Peity.defaults[type] = defaults;
103
+ Peity.graphers[type] = grapher;
104
+ }
105
+ }
106
+
107
+ const renderer$2 = (peity) => {
108
+ if (!peity.options.delimiter) {
109
+ const delimiter = peity.element.innerText.match(/[^0-9\.]/);
110
+ peity.options.delimiter = delimiter ? delimiter[0] : ",";
111
+ }
112
+
113
+ let values = peity.values.map((n) => (n > 0 ? n : 0));
114
+
115
+ if (peity.options.delimiter == "/") {
116
+ let v1 = values[0];
117
+ let v2 = values[1];
118
+ values = [v1, Math.max(0, v2 - v1)];
119
+ }
120
+
121
+ let i = 0;
122
+ let length = values.length;
123
+ let sum = 0;
124
+
125
+ for (; i < length; i++) {
126
+ sum += values[i];
127
+ }
128
+
129
+ if (!sum) {
130
+ length = 2;
131
+ sum = 1;
132
+ values = [0, 1];
133
+ }
134
+
135
+ let diameter = peity.options.radius * 2;
136
+
137
+ const svg = peity.prepare(
138
+ peity.options.width || diameter,
139
+ peity.options.height || diameter
140
+ );
141
+
142
+ const width = svg.clientWidth;
143
+ const height = svg.clientHeight;
144
+ const cx = width / 2;
145
+ const cy = height / 2;
146
+
147
+ const radius = Math.min(cx, cy);
148
+ let innerRadius = peity.options.innerRadius;
149
+
150
+ if (peity.type == "donut" && !innerRadius) {
151
+ innerRadius = radius * 0.5;
152
+ }
153
+
154
+ const fill = peity.fill();
155
+
156
+ const scale = (value, radius) => {
157
+ const radians = (value / sum) * Math.PI * 2 - Math.PI / 2;
158
+
159
+ return [radius * Math.cos(radians) + cx, radius * Math.sin(radians) + cy];
160
+ };
161
+
162
+ let cumulative = 0;
163
+
164
+ for (i = 0; i < length; i++) {
165
+ const value = values[i];
166
+ const portion = value / sum;
167
+ let node;
168
+
169
+ if (portion == 0) continue;
170
+
171
+ if (portion == 1) {
172
+ if (innerRadius) {
173
+ const x2 = cx - 0.01;
174
+ const y1 = cy - radius;
175
+ const y2 = cy - innerRadius;
176
+
177
+ node = svgElement("path", {
178
+ d: [
179
+ "M",
180
+ cx,
181
+ y1,
182
+ "A",
183
+ radius,
184
+ radius,
185
+ 0,
186
+ 1,
187
+ 1,
188
+ x2,
189
+ y1,
190
+ "L",
191
+ x2,
192
+ y2,
193
+ "A",
194
+ innerRadius,
195
+ innerRadius,
196
+ 0,
197
+ 1,
198
+ 0,
199
+ cx,
200
+ y2,
201
+ ].join(" "),
202
+ "data-value": value,
203
+ });
204
+ } else {
205
+ node = svgElement("circle", {
206
+ cx: cx,
207
+ cy: cy,
208
+ "data-value": value,
209
+ r: radius,
210
+ });
211
+ }
212
+ } else {
213
+ const cumulativePlusValue = cumulative + value;
214
+
215
+ let d = ["M"].concat(
216
+ scale(cumulative, radius),
217
+ "A",
218
+ radius,
219
+ radius,
220
+ 0,
221
+ portion > 0.5 ? 1 : 0,
222
+ 1,
223
+ scale(cumulativePlusValue, radius),
224
+ "L"
225
+ );
226
+
227
+ if (innerRadius) {
228
+ d = d.concat(
229
+ scale(cumulativePlusValue, innerRadius),
230
+ "A",
231
+ innerRadius,
232
+ innerRadius,
233
+ 0,
234
+ portion > 0.5 ? 1 : 0,
235
+ 0,
236
+ scale(cumulative, innerRadius)
237
+ );
238
+ } else {
239
+ d.push(cx, cy);
240
+ }
241
+
242
+ cumulative += value;
243
+
244
+ node = svgElement("path", {
245
+ d: d.join(" "),
246
+ "data-value": value,
247
+ });
248
+ }
249
+
250
+ node.setAttribute("fill", fill.call(peity, value, i, values));
251
+
252
+ svg.append(node);
253
+ }
254
+ };
255
+
256
+ const defaults$2 = {
257
+ fill: ["#ff9900", "#fff4dd", "#ffc66e"],
258
+ radius: 8,
259
+ };
260
+
261
+ const renderer$1 = (peity) => {
262
+ const values = peity.values;
263
+ const max = Math.max.apply(
264
+ Math,
265
+ peity.options.max == undefined ? values : values.concat(peity.options.max)
266
+ );
267
+ const min = Math.min.apply(
268
+ Math,
269
+ peity.options.min == undefined ? values : values.concat(peity.options.min)
270
+ );
271
+
272
+ const svg = peity.prepare(peity.options.width, peity.options.height);
273
+ const width = svg.clientWidth;
274
+ const height = svg.clientHeight;
275
+ const diff = max - min;
276
+ const padding = peity.options.padding;
277
+ const fill = peity.fill();
278
+
279
+ const xScale = (input) => {
280
+ return (input * width) / values.length;
281
+ };
282
+
283
+ const yScale = (input) => {
284
+ return height - (diff ? ((input - min) / diff) * height : 1);
285
+ };
286
+
287
+ for (var i = 0; i < values.length; i++) {
288
+ let x = xScale(i + padding);
289
+ let w = xScale(i + 1 - padding) - x;
290
+ let value = values[i];
291
+ let valueY = yScale(value);
292
+ let y1 = valueY;
293
+ let y2 = valueY;
294
+ let h;
295
+
296
+ if (!diff) {
297
+ h = 1;
298
+ } else if (value < 0) {
299
+ y1 = yScale(Math.min(max, 0));
300
+ } else {
301
+ y2 = yScale(Math.max(min, 0));
302
+ }
303
+
304
+ h = y2 - y1;
305
+
306
+ if (h == 0) {
307
+ h = 1;
308
+ if (max > 0 && diff) y1--;
309
+ }
310
+
311
+ svg.append(
312
+ svgElement("rect", {
313
+ "data-value": value,
314
+ fill: fill.call(peity, value, i, values),
315
+ x: x,
316
+ y: y1,
317
+ width: w,
318
+ height: h,
319
+ })
320
+ );
321
+ }
322
+ };
323
+
324
+ const defaults$1 = {
325
+ delimiter: ",",
326
+ fill: ["#4D89F9"],
327
+ height: 16,
328
+ min: 0,
329
+ padding: 0.1,
330
+ width: 32,
331
+ };
332
+
333
+ const renderer = (peity) => {
334
+ const values = peity.values;
335
+ if (values.length == 1) values.push(values[0]);
336
+ const max = Math.max.apply(
337
+ Math,
338
+ peity.options.max == undefined ? values : values.concat(peity.options.max)
339
+ );
340
+ const min = Math.min.apply(
341
+ Math,
342
+ peity.options.min == undefined ? values : values.concat(peity.options.min)
343
+ );
344
+
345
+ const svg = peity.prepare(peity.options.width, peity.options.height);
346
+ const strokeWidth = peity.options.strokeWidth;
347
+ const width = svg.clientWidth;
348
+ const height = svg.clientHeight - strokeWidth;
349
+ const diff = max - min;
350
+
351
+ const xScale = (input) => {
352
+ return input * (width / (values.length - 1));
353
+ };
354
+
355
+ const yScale = (input) => {
356
+ let y = height;
357
+
358
+ if (diff) {
359
+ y -= ((input - min) / diff) * height;
360
+ }
361
+
362
+ return y + strokeWidth / 2;
363
+ };
364
+
365
+ let zero = yScale(Math.max(min, 0));
366
+ let coords = [0, zero];
367
+
368
+ for (var i = 0; i < values.length; i++) {
369
+ coords.push(xScale(i), yScale(values[i]));
370
+ }
371
+
372
+ coords.push(width, zero);
373
+
374
+ if (peity.options.fill) {
375
+ svg.append(
376
+ svgElement("polygon", {
377
+ fill: peity.options.fill,
378
+ points: coords.join(" "),
379
+ })
380
+ );
381
+ }
382
+
383
+ if (strokeWidth) {
384
+ svg.append(
385
+ svgElement("polyline", {
386
+ fill: "none",
387
+ points: coords.slice(2, coords.length - 2).join(" "),
388
+ stroke: peity.options.stroke,
389
+ "stroke-width": strokeWidth,
390
+ "stroke-linecap": "square",
391
+ })
392
+ );
393
+ }
394
+ };
395
+
396
+ const defaults = {
397
+ delimiter: ",",
398
+ fill: "#c6d9fd",
399
+ height: 16,
400
+ min: 0,
401
+ stroke: "#4d89f9",
402
+ strokeWidth: 1,
403
+ width: 32,
404
+ };
405
+
406
+ Peity.register("pie", defaults$2, renderer$2);
407
+ Peity.register("donut", defaults$2, renderer$2);
408
+ Peity.register("bar", defaults$1, renderer$1);
409
+ Peity.register("line", defaults, renderer);
410
+
411
+ const peity = function (element, type, options) {
412
+ const peity = new Peity(element, type, options);
413
+ peity.mount();
414
+
415
+ return peity;
416
+ };
417
+
418
+ peity.defaults = Peity.defaults;
419
+ peity.graphers = Peity.graphers;
420
+
421
+ export { peity as default };
@@ -0,0 +1,6 @@
1
+ var peity=function(){"use strict";
2
+ /*!
3
+ Peity Vanila JS 0.0.8
4
+ Copyright © 2022 RailsJazz
5
+ https://railsjazz.com
6
+ */const t=t=>null!==t&&"function"==typeof t&&!!t.apply,e=(t,e)=>{const i=document.createElementNS("http://www.w3.org/2000/svg",t);for(var n in e)i.setAttribute(n,e[n]);return i},i="createElementNS"in document&&e("svg",{}).createSVGRect();class n{static defaults={};static graphers={};constructor(t,e,i={}){this.element=t,this.type=e,this.options=Object.assign({},n.defaults[this.type],JSON.parse(t.dataset.peity||"{}"),i),this.element._peity&&this.element._peity.destroy(),this.element._peity=this}draw(){const e=this.options;n.graphers[this.type](this),t(e.after)&&e.after.call(this,e)}fill(){var e=this.options.fill;return t(e)?e:function(t,i){return e[i%e.length]}}prepare(t,i){return this.svg||(this.element.style.display="none",this.element.after(this.svg=e("svg",{class:"peity"}))),this.svg.innerHTML="",this.svg.setAttribute("width",t),this.svg.setAttribute("height",i),this.svg}get values(){return this.element.innerText.split(this.options.delimiter).map((t=>parseFloat(t)))}mount(){i&&(this.element.addEventListener("DOMSubtreeModified",this.draw.bind(this)),this.draw(),this.mounted=!0)}unmount(){this.element.removeEventListener("DOMSubtreeModified",this.draw),this.svg.remove(),this.mounted=!1}destroy(){this.unmount(),delete this.element._peity}static register(t,e,i){n.defaults[t]=e,n.graphers[t]=i}}const s=t=>{if(!t.options.delimiter){const e=t.element.innerText.match(/[^0-9\.]/);t.options.delimiter=e?e[0]:","}let i=t.values.map((t=>t>0?t:0));if("/"==t.options.delimiter){let t=i[0],e=i[1];i=[t,Math.max(0,e-t)]}let n=0,s=i.length,o=0;for(;n<s;n++)o+=i[n];o||(s=2,o=1,i=[0,1]);let l=2*t.options.radius;const a=t.prepare(t.options.width||l,t.options.height||l),r=a.clientWidth,h=a.clientHeight,p=r/2,d=h/2,c=Math.min(p,d);let u=t.options.innerRadius;"donut"!=t.type||u||(u=.5*c);const m=t.fill(),f=(t,e)=>{const i=t/o*Math.PI*2-Math.PI/2;return[e*Math.cos(i)+p,e*Math.sin(i)+d]};let g=0;for(n=0;n<s;n++){const s=i[n],l=s/o;let r;if(0!=l){if(1==l)if(u){const t=p-.01,i=d-c,n=d-u;r=e("path",{d:["M",p,i,"A",c,c,0,1,1,t,i,"L",t,n,"A",u,u,0,1,0,p,n].join(" "),"data-value":s})}else r=e("circle",{cx:p,cy:d,"data-value":s,r:c});else{const t=g+s;let i=["M"].concat(f(g,c),"A",c,c,0,l>.5?1:0,1,f(t,c),"L");u?i=i.concat(f(t,u),"A",u,u,0,l>.5?1:0,0,f(g,u)):i.push(p,d),g+=s,r=e("path",{d:i.join(" "),"data-value":s})}r.setAttribute("fill",m.call(t,s,n,i)),a.append(r)}}},o={fill:["#ff9900","#fff4dd","#ffc66e"],radius:8};n.register("pie",o,s),n.register("donut",o,s),n.register("bar",{delimiter:",",fill:["#4D89F9"],height:16,min:0,padding:.1,width:32},(t=>{const i=t.values,n=Math.max.apply(Math,null==t.options.max?i:i.concat(t.options.max)),s=Math.min.apply(Math,null==t.options.min?i:i.concat(t.options.min)),o=t.prepare(t.options.width,t.options.height),l=o.clientWidth,a=o.clientHeight,r=n-s,h=t.options.padding,p=t.fill(),d=t=>t*l/i.length,c=t=>a-(r?(t-s)/r*a:1);for(var u=0;u<i.length;u++){let l,a=d(u+h),m=d(u+1-h)-a,f=i[u],g=c(f),v=g,y=g;r?f<0?v=c(Math.min(n,0)):y=c(Math.max(s,0)):l=1,l=y-v,0==l&&(l=1,n>0&&r&&v--),o.append(e("rect",{"data-value":f,fill:p.call(t,f,u,i),x:a,y:v,width:m,height:l}))}})),n.register("line",{delimiter:",",fill:"#c6d9fd",height:16,min:0,stroke:"#4d89f9",strokeWidth:1,width:32},(t=>{const i=t.values;1==i.length&&i.push(i[0]);const n=Math.max.apply(Math,null==t.options.max?i:i.concat(t.options.max)),s=Math.min.apply(Math,null==t.options.min?i:i.concat(t.options.min)),o=t.prepare(t.options.width,t.options.height),l=t.options.strokeWidth,a=o.clientWidth,r=o.clientHeight-l,h=n-s,p=t=>{let e=r;return h&&(e-=(t-s)/h*r),e+l/2};let d=p(Math.max(s,0)),c=[0,d];for(var u=0;u<i.length;u++)c.push(u*(a/(i.length-1)),p(i[u]));c.push(a,d),t.options.fill&&o.append(e("polygon",{fill:t.options.fill,points:c.join(" ")})),l&&o.append(e("polyline",{fill:"none",points:c.slice(2,c.length-2).join(" "),stroke:t.options.stroke,"stroke-width":l,"stroke-linecap":"square"}))}));const l=function(t,e,i){const s=new n(t,e,i);return s.mount(),s};return l.defaults=n.defaults,l.graphers=n.graphers,l}();
@@ -0,0 +1,2 @@
1
+ pin 'peity-vanilla', to: 'peity-vanilla.esm.js'
2
+ pin 'peity-vanilla-rails', to: 'peity-vanilla-rails.esm.js'
@@ -1,15 +1,10 @@
1
1
  module PeityVanillaRails
2
2
  class Railtie < ::Rails::Engine
3
+ PRECOMPILE_ASSETS = %w( peity-vanilla-rails.esm.js peity-vanilla.esm.js )
3
4
  initializer "peity_vanilla_rails.importmap", before: "importmap" do |app|
4
- if defined?(Importmap)
5
- app.config.importmap.cache_sweepers << root.join("app/assets/javascripts")
6
- end
7
- end
8
-
9
- PRECOMPILE_ASSETS = Dir[root.join("app/assets/javascripts/**/*")]
10
- initializer 'peity_vanilla_rails.assets' do |app|
11
- if app.config.respond_to?(:assets)
5
+ if Rails.application.respond_to?(:importmap)
12
6
  app.config.assets.precompile += PRECOMPILE_ASSETS
7
+ app.config.importmap.paths << root.join("config/importmap.rb")
13
8
  end
14
9
  end
15
10
 
@@ -1,36 +1,28 @@
1
1
  module PeityVanillaRails
2
2
  module Helpers
3
-
4
- def peity_line_chart(data, options: {})
5
- peity_chart(data, "line", ",", options: options)
3
+
4
+ def peity_line_chart(data, id: nil, options: {})
5
+ peity_chart(data, "line", ",", id: id, options: options)
6
6
  end
7
7
 
8
- def peity_bar_chart(data, options: {})
9
- peity_chart(data, "bar", ",", options: options)
8
+ def peity_bar_chart(data, id: nil, options: {})
9
+ peity_chart(data, "bar", ",", id: id, options: options)
10
10
  end
11
11
 
12
- def peity_pie_chart(data, options: {})
13
- peity_chart(data, "pie", "/", options: options)
12
+ def peity_pie_chart(data, id: nil, options: {})
13
+ peity_chart(data, "pie", "/", id: id, options: options)
14
14
  end
15
15
 
16
- def peity_donut_chart(data, options: {})
17
- peity_chart(data, "donut", "/", options: options)
16
+ def peity_donut_chart(data, id: nil, options: {})
17
+ peity_chart(data, "donut", "/", id: id, options: options)
18
18
  end
19
19
 
20
- def peity_chart(value, type, delimiter, options: {})
20
+ def peity_chart(value, type, delimiter, id: nil, options: {})
21
21
  value = value.is_a?(Array) ? value.join(delimiter) : value
22
- id = "peity_charts_#{Digest::SHA1.hexdigest([Time.now, rand].join)}"
23
- [
24
- tag.span(class: 'peity_charts', id: id, "data-peity" => options.to_json) do
25
- value
26
- end,
27
- tag.script do
28
- %Q{
29
- peity(document.getElementById("#{id}"), "#{type}");
30
- }.html_safe
31
- end
32
- ].join.html_safe
33
- end
22
+ tag.span(id: id, class: 'peity_charts', peity: type, style: 'display: none;', data: { peity: options.to_json }) do
23
+ value
24
+ end
25
+ end
34
26
 
35
27
  end
36
28
  end
@@ -1,3 +1,3 @@
1
1
  module PeityVanillaRails
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: peity_vanilla_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Kasyanchuk
8
+ - Liubomyr Manastyretskyi
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2022-04-30 00:00:00.000000000 Z
12
+ date: 2022-05-02 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rails
@@ -69,6 +70,7 @@ dependencies:
69
70
  description: Sparklines are small but intense charts.
70
71
  email:
71
72
  - igorkasyanchuk@gmail.com
73
+ - manastyretskyi@gmail.com
72
74
  executables: []
73
75
  extensions: []
74
76
  extra_rdoc_files: []
@@ -76,8 +78,11 @@ files:
76
78
  - MIT-LICENSE
77
79
  - README.md
78
80
  - Rakefile
79
- - app/assets/javascripts/peity_vanilla.js
80
- - app/assets/javascripts/peity_vanilla.js.map
81
+ - app/assets/javascripts/peity-vanilla-rails.esm.js
82
+ - app/assets/javascripts/peity-vanilla-rails.min.js
83
+ - app/assets/javascripts/peity-vanilla.esm.js
84
+ - app/assets/javascripts/peity-vanilla.min.js
85
+ - config/importmap.rb
81
86
  - lib/peity_vanilla_rails.rb
82
87
  - lib/peity_vanilla_rails/engine.rb
83
88
  - lib/peity_vanilla_rails/helpers.rb
@@ -104,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
109
  - !ruby/object:Gem::Version
105
110
  version: '0'
106
111
  requirements: []
107
- rubygems_version: 3.2.3
112
+ rubygems_version: 3.3.7
108
113
  signing_key:
109
114
  specification_version: 4
110
115
  summary: Sparklines are small but intense charts.
@@ -1,2 +0,0 @@
1
- !function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var i,n=e();for(i in n)("object"==typeof exports?exports:t)[i]=n[i]}}(self,()=>(()=>{"use strict";function a(t,e,i){var n;if(s)return n=(t=t).dataset._peity,n=new r(t,e,Object.assign({},a.defaults[e],JSON.parse(t.dataset.peity||"{}"),i)),t.addEventListener("change",function(){n.draw()}),(t.dataset._peity=n).draw(),t}function r(t,e,i){this.$el=t,this.type=e,this.opts=i}var t=r.prototype,M=t.svgElement=function(t,e){var i,n=document.createElementNS("http://www.w3.org/2000/svg",t);for(i in e)n.setAttribute(i,e[i]);return n},s="createElementNS"in document&&M("svg",{}).createSVGRect();return t.draw=function(){var t=this.opts;a.graphers[this.type].call(this,t),t.after&&t.after.call(this,t)},t.isFunction=function(t){return null!==t&&"function"==typeof t&&!!t.apply},t.fill=function(){var i=this.opts.fill;return t.isFunction(i)?i:function(t,e){return i[e%i.length]}},t.prepare=function(t,e){return this.$svg||(this.$el.style.display="none",this.$el.after(this.$svg=M("svg",{class:"peity"}))),this.$svg.innerHTML="",this.$svg.setAttribute("width",t),this.$svg.setAttribute("height",e),this.$svg},t.values=function(){return this.$el.innerText.split(this.opts.delimiter).map(function(t){return parseFloat(t)})},a.defaults={},a.graphers={},a.register=function(t,e,i){this.defaults[t]=e,this.graphers[t]=i},a.register("pie",{fill:["#ff9900","#fff4dd","#ffc66e"],radius:8},function(t){t.delimiter||(l=this.$el.innerText.match(/[^0-9\.]/),t.delimiter=l?l[0]:",");for(var e=this.values().map(function(t){return 0<t?t:0}),i=("/"==t.delimiter&&(l=e[0],r=e[1],e=[l,Math.max(0,r-l)]),0),n=e.length,a=0;i<n;i++)a+=e[i];a||(n=2,e=[0,a=1]);for(var r=2*t.radius,s=this.prepare(t.width||r,t.height||r),l=s.clientWidth,r=s.clientHeight,h=l/2,o=r/2,u=Math.min(h,o),c=t.innerRadius,p=("donut"!=this.type||c||(c=.5*u),Math.PI),f=this.fill(),d=this.scale=function(t,e){t=t/a*p*2-p/2;return[e*Math.cos(t)+h,e*Math.sin(t)+o]},g=0,i=0;i<n;i++){var m,v,y=e[i],x=y/a;0!=x&&((x=1==x?c?M("path",{d:["M",h,v=o-u,"A",u,u,0,1,1,m=h-.01,v,"L",m,v=o-c,"A",c,c,0,1,0,h,v].join(" "),"data-value":y}):M("circle",{cx:h,cy:o,"data-value":y,r:u}):(m=g+y,v=["M"].concat(d(g,u),"A",u,u,0,.5<x?1:0,1,d(m,u),"L"),c?v=v.concat(d(m,c),"A",c,c,0,.5<x?1:0,0,d(g,c)):v.push(h,o),g+=y,M("path",{d:v.join(" "),"data-value":y}))).setAttribute("fill",f.call(this,y,i,e)),s.append(x))}}),a.register("donut",Object.assign(!0,{},a.defaults.pie),function(t){a.graphers.pie.call(this,t)}),a.register("bar",{delimiter:",",fill:["#4D89F9"],height:16,min:0,padding:.1,width:32},function(t){for(var e=this.values(),i=Math.max.apply(Math,null==t.max?e:e.concat(t.max)),n=Math.min.apply(Math,null==t.min?e:e.concat(t.min)),a=this.prepare(t.width,t.height),r=a.clientWidth,s=a.clientHeight,l=i-n,h=t.padding,o=this.fill(),u=this.x=function(t){return t*r/e.length},c=this.y=function(t){return s-(l?(t-n)/l*s:1)},p=0;p<e.length;p++){var f,d=u(p+h),g=u(p+1-h)-d,m=e[p],v=c(m),y=v;l?m<0?y=c(Math.min(i,0)):v=c(Math.max(n,0)):f=1,0==(f=v-y)&&(f=1,0<i&&l&&y--),a.append(M("rect",{"data-value":m,fill:o.call(this,m,p,e),x:d,y:y,width:g,height:f}))}}),a.register("line",{delimiter:",",fill:"#c6d9fd",height:16,min:0,stroke:"#4d89f9",strokeWidth:1,width:32},function(t){for(var e=this.values(),i=(1==e.length&&e.push(e[0]),Math.max.apply(Math,null==t.max?e:e.concat(t.max))),n=Math.min.apply(Math,null==t.min?e:e.concat(t.min)),a=this.prepare(t.width,t.height),r=t.strokeWidth,s=a.clientWidth,l=a.clientHeight-r,h=i-n,o=this.x=function(t){return t*(s/(e.length-1))},u=this.y=function(t){var e=l;return h&&(e-=(t-n)/h*l),e+r/2},i=u(Math.max(n,0)),c=[0,i],p=0;p<e.length;p++)c.push(o(p),u(e[p]));c.push(s,i),t.fill&&a.append(M("polygon",{fill:t.fill,points:c.join(" ")})),r&&a.append(M("polyline",{fill:"none",points:c.slice(2,c.length-2).join(" "),stroke:t.stroke,"stroke-width":r,"stroke-linecap":"square"}))}),window.peity=a,{}})());
2
- //# sourceMappingURL=peity_vanilla.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["webpack://piety_vanilla/webpack/universalModuleDefinition","webpack://piety_vanilla/./src/index.js"],"names":["root","factory","exports","module","define","amd","i","a","self","peity","element","type","options","chart","svgSupported","$this","dataset","Peity","Object","assign","defaults","JSON","parse","addEventListener","draw","$el","opts","this","PeityPrototype","prototype","svgElement","tag","attrs","attr","document","createElementNS","setAttribute","createSVGRect","graphers","call","after","isFunction","o","apply","fill","_","length","prepare","width","height","$svg","style","display","innerHTML","values","innerText","split","delimiter","map","value","parseFloat","register","grapher","radius","match","n","v1","v2","Math","max","sum","diameter","clientWidth","clientHeight","cx","cy","min","innerRadius","pi","PI","scale","radians","cos","sin","cumulative","cumulativePlusValue","d","portion","$node","y1","x2","y2","join","r","concat","push","append","pie","padding","undefined","diff","xScale","x","input","yScale","y","h","w","valueY","stroke","strokeWidth","zero","coords","points","slice","window"],"mappings":"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","file":"peity_vanilla.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse {\n\t\tvar a = factory();\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(self, () => {\nreturn ","\"use strict\";\r\n\r\nvar peity = function(element, type, options) {\r\n if (svgSupported) {\r\n var $this = element\r\n var chart = $this.dataset['_peity']\r\n\r\n chart = new Peity(\r\n $this,\r\n type,\r\n Object.assign({},\r\n peity.defaults[type],\r\n JSON.parse($this.dataset['peity'] || '{}'),\r\n options)\r\n )\r\n\r\n $this.addEventListener(\"change\", function() { chart.draw() })\r\n $this.dataset['_peity'] = chart\r\n\r\n chart.draw()\r\n return $this;\r\n }\r\n};\r\n\r\nvar Peity = function($el, type, opts) {\r\n this.$el = $el\r\n this.type = type\r\n this.opts = opts\r\n}\r\n\r\nvar PeityPrototype = Peity.prototype\r\n\r\nvar svgElement = PeityPrototype.svgElement = function(tag, attrs) {\r\n var element = document.createElementNS('http://www.w3.org/2000/svg', tag)\r\n for(var attr in attrs) {\r\n element.setAttribute(attr, attrs[attr])\r\n }\r\n return element;\r\n}\r\n\r\n// https://gist.github.com/madrobby/3201472\r\nvar svgSupported = 'createElementNS' in document && svgElement('svg', {}).createSVGRect()\r\n\r\nPeityPrototype.draw = function() {\r\n var opts = this.opts\r\n peity.graphers[this.type].call(this, opts)\r\n if (opts.after) opts.after.call(this, opts)\r\n}\r\n\r\nPeityPrototype.isFunction = function(o) { return null !== o && \"function\" === typeof o && !!o.apply; }\r\n\r\nPeityPrototype.fill = function() {\r\n var fill = this.opts.fill\r\n\r\n return PeityPrototype.isFunction(fill)\r\n ? fill\r\n : function(_, i) { return fill[i % fill.length] }\r\n}\r\n\r\nPeityPrototype.prepare = function(width, height) {\r\n if (!this.$svg) {\r\n this.$el.style.display = 'none'\r\n this.$el.after(\r\n this.$svg = svgElement('svg', {\r\n \"class\": \"peity\"\r\n })\r\n )\r\n }\r\n\r\n this.$svg.innerHTML = \"\";\r\n this.$svg.setAttribute(\"width\", width)\r\n this.$svg.setAttribute(\"height\", height)\r\n\r\n return this.$svg;\r\n}\r\n\r\nPeityPrototype.values = function() {\r\n return this.$el.innerText.split(this.opts.delimiter).map(function(value) {\r\n return parseFloat(value)\r\n })\r\n}\r\n\r\npeity.defaults = {}\r\npeity.graphers = {}\r\n\r\npeity.register = function(type, defaults, grapher) {\r\n this.defaults[type] = defaults\r\n this.graphers[type] = grapher\r\n}\r\n\r\npeity.register(\r\n 'pie',\r\n {\r\n fill: ['#ff9900', '#fff4dd', '#ffc66e'],\r\n radius: 8\r\n },\r\n function(opts) {\r\n if (!opts.delimiter) {\r\n var delimiter = this.$el.innerText.match(/[^0-9\\.]/)\r\n opts.delimiter = delimiter ? delimiter[0] : \",\"\r\n }\r\n\r\n var values = this.values().map(function(n) {\r\n return n > 0 ? n : 0\r\n });\r\n\r\n if (opts.delimiter == \"/\") {\r\n var v1 = values[0]\r\n var v2 = values[1]\r\n values = [v1, Math.max(0, v2 - v1)]\r\n }\r\n\r\n var i = 0\r\n var length = values.length\r\n var sum = 0\r\n\r\n for (; i < length; i++) {\r\n sum += values[i]\r\n }\r\n\r\n if (!sum) {\r\n length = 2\r\n sum = 1\r\n values = [0, 1]\r\n }\r\n\r\n var diameter = opts.radius * 2\r\n\r\n var $svg = this.prepare(\r\n opts.width || diameter,\r\n opts.height || diameter\r\n )\r\n\r\n var width = $svg.clientWidth\r\n , height = $svg.clientHeight\r\n , cx = width / 2\r\n , cy = height / 2\r\n\r\n var radius = Math.min(cx, cy)\r\n , innerRadius = opts.innerRadius\r\n\r\n if (this.type == 'donut' && !innerRadius) {\r\n innerRadius = radius * 0.5\r\n }\r\n\r\n var pi = Math.PI\r\n var fill = this.fill()\r\n\r\n var scale = this.scale = function(value, radius) {\r\n var radians = value / sum * pi * 2 - pi / 2\r\n\r\n return [\r\n radius * Math.cos(radians) + cx,\r\n radius * Math.sin(radians) + cy\r\n ]\r\n }\r\n\r\n var cumulative = 0\r\n\r\n for (i = 0; i < length; i++) {\r\n var value = values[i]\r\n , portion = value / sum\r\n , $node\r\n\r\n if (portion == 0) continue\r\n\r\n if (portion == 1) {\r\n if (innerRadius) {\r\n var x2 = cx - 0.01\r\n , y1 = cy - radius\r\n , y2 = cy - innerRadius\r\n\r\n $node = svgElement('path', {\r\n d: [\r\n 'M', cx, y1,\r\n 'A', radius, radius, 0, 1, 1, x2, y1,\r\n 'L', x2, y2,\r\n 'A', innerRadius, innerRadius, 0, 1, 0, cx, y2\r\n ].join(' '),\r\n 'data-value': value,\r\n })\r\n } else {\r\n $node = svgElement('circle', {\r\n cx: cx,\r\n cy: cy,\r\n 'data-value': value,\r\n r: radius\r\n })\r\n }\r\n } else {\r\n var cumulativePlusValue = cumulative + value\r\n\r\n var d = ['M'].concat(\r\n scale(cumulative, radius),\r\n 'A', radius, radius, 0, portion > 0.5 ? 1 : 0, 1,\r\n scale(cumulativePlusValue, radius),\r\n 'L'\r\n )\r\n\r\n if (innerRadius) {\r\n d = d.concat(\r\n scale(cumulativePlusValue, innerRadius),\r\n 'A', innerRadius, innerRadius, 0, portion > 0.5 ? 1 : 0, 0,\r\n scale(cumulative, innerRadius)\r\n )\r\n } else {\r\n d.push(cx, cy)\r\n }\r\n\r\n cumulative += value\r\n\r\n $node = svgElement('path', {\r\n d: d.join(\" \"),\r\n 'data-value': value,\r\n })\r\n }\r\n\r\n $node.setAttribute('fill', fill.call(this, value, i, values))\r\n\r\n $svg.append($node)\r\n }\r\n }\r\n)\r\n\r\npeity.register(\r\n 'donut',\r\n Object.assign(true, {}, peity.defaults.pie),\r\n function(opts) {\r\n peity.graphers.pie.call(this, opts)\r\n }\r\n)\r\n\r\npeity.register(\r\n 'bar',\r\n {\r\n delimiter: \",\",\r\n fill: [\"#4D89F9\"],\r\n height: 16,\r\n min: 0,\r\n padding: 0.1,\r\n width: 32\r\n },\r\n function(opts) {\r\n var values = this.values()\r\n , max = Math.max.apply(Math, opts.max == undefined ? values : values.concat(opts.max))\r\n , min = Math.min.apply(Math, opts.min == undefined ? values : values.concat(opts.min))\r\n\r\n var $svg = this.prepare(opts.width, opts.height)\r\n , width = $svg.clientWidth\r\n , height = $svg.clientHeight\r\n , diff = max - min\r\n , padding = opts.padding\r\n , fill = this.fill()\r\n\r\n var xScale = this.x = function(input) {\r\n return input * width / values.length\r\n }\r\n\r\n var yScale = this.y = function(input) {\r\n return height - (\r\n diff\r\n ? ((input - min) / diff) * height\r\n : 1\r\n )\r\n }\r\n\r\n for (var i = 0; i < values.length; i++) {\r\n var x = xScale(i + padding)\r\n , w = xScale(i + 1 - padding) - x\r\n , value = values[i]\r\n , valueY = yScale(value)\r\n , y1 = valueY\r\n , y2 = valueY\r\n , h\r\n\r\n if (!diff) {\r\n h = 1\r\n } else if (value < 0) {\r\n y1 = yScale(Math.min(max, 0))\r\n } else {\r\n y2 = yScale(Math.max(min, 0))\r\n }\r\n\r\n h = y2 - y1\r\n\r\n if (h == 0) {\r\n h = 1\r\n if (max > 0 && diff) y1--\r\n }\r\n\r\n $svg.append(\r\n svgElement('rect', {\r\n 'data-value': value,\r\n fill: fill.call(this, value, i, values),\r\n x: x,\r\n y: y1,\r\n width: w,\r\n height: h\r\n })\r\n )\r\n }\r\n }\r\n);\r\n\r\npeity.register(\r\n \"line\",\r\n {\r\n delimiter: \",\",\r\n fill: \"#c6d9fd\",\r\n height: 16,\r\n min: 0,\r\n stroke: \"#4d89f9\",\r\n strokeWidth: 1,\r\n width: 32\r\n },\r\n function(opts) {\r\n var values = this.values()\r\n if (values.length == 1) values.push(values[0])\r\n var max = Math.max.apply(Math, opts.max == undefined ? values : values.concat(opts.max))\r\n , min = Math.min.apply(Math, opts.min == undefined ? values : values.concat(opts.min))\r\n\r\n var $svg = this.prepare(opts.width, opts.height)\r\n , strokeWidth = opts.strokeWidth\r\n , width = $svg.clientWidth\r\n , height = $svg.clientHeight - strokeWidth\r\n , diff = max - min\r\n\r\n var xScale = this.x = function(input) {\r\n return input * (width / (values.length - 1))\r\n }\r\n\r\n var yScale = this.y = function(input) {\r\n var y = height\r\n\r\n if (diff) {\r\n y -= ((input - min) / diff) * height\r\n }\r\n\r\n return y + strokeWidth / 2\r\n }\r\n\r\n var zero = yScale(Math.max(min, 0))\r\n , coords = [0, zero]\r\n\r\n for (var i = 0; i < values.length; i++) {\r\n coords.push(\r\n xScale(i),\r\n yScale(values[i])\r\n )\r\n }\r\n\r\n coords.push(width, zero)\r\n\r\n if (opts.fill) {\r\n $svg.append(\r\n svgElement('polygon', {\r\n fill: opts.fill,\r\n points: coords.join(' ')\r\n })\r\n )\r\n }\r\n\r\n if (strokeWidth) {\r\n $svg.append(\r\n svgElement('polyline', {\r\n fill: 'none',\r\n points: coords.slice(2, coords.length - 2).join(' '),\r\n stroke: opts.stroke,\r\n 'stroke-width': strokeWidth,\r\n 'stroke-linecap': 'square'\r\n })\r\n )\r\n }\r\n }\r\n);\r\n\r\n// rework?\r\nwindow.peity = peity;"],"sourceRoot":""}