peity_vanilla_rails 0.1.1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32f04e35a10743476825e404056471ab5ec13c54372653d516a43c684e632b82
4
- data.tar.gz: ae91de3bee20977261f2ac80a70fcac274aa27e109035f5fdfe825f9f5481a92
3
+ metadata.gz: de5631424fd3980ed3c9c8a7e02a4c7e10cc77650ebdea1f8d17cb99d526ca96
4
+ data.tar.gz: 85a1ae8f2d6e05fad50d5362c0ce3c55d8e0b8d04354d028cf247562a76194a6
5
5
  SHA512:
6
- metadata.gz: 5a5903519f2834b17ab6a9e1421636855cba3602206e50d2224b4e072b38d218145e5ea6d0fef7ffbd35552494b51f57517ec25f6e8701048cf35a226dc1f213
7
- data.tar.gz: 3a3cf7fc61864c1b88d3459568997b56de62732eaf476b13bea94741942b25e59abfe43b88818fa6261f84043b8b54d17f190308aef3b538fb2f91e317342eef
6
+ metadata.gz: a90b637c07453922d6ad43cff0def5c8daa35fcdd4c0e094acd053f6e85226fab91a5f606efc434fe9144ed676993a2ebe95582ad8420aca182cf6e987674054
7
+ data.tar.gz: 0b2a6938fd2ab60492f943965a8a45e128f31098d262ec5315a9e3252daa257b40be98728dee23402192ac5bd485069d839cfa080102126af39d711aa870c4ec
data/README.md CHANGED
@@ -1,6 +1,8 @@
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
+
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.
4
6
 
5
7
  <img src="./docs/sparklines.png" height="400px"/>
6
8
 
@@ -14,10 +16,23 @@ gem "peity_vanilla_rails"
14
16
 
15
17
  2. Add to `application.js`
16
18
 
19
+ ### For Assets Pipeline:
20
+
17
21
  ```javascript
18
- //= require peity_vanilla.js
22
+ //= require peity-vanilla-rails.js
23
+ ```
24
+
25
+ ### For Importmaps
26
+
27
+ In `application.js`
28
+
29
+ ```js
30
+ import "peity-vanilla-rails";
19
31
  ```
20
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
+
21
36
  3. Add charts in your code:
22
37
 
23
38
  ```erb
@@ -50,21 +65,19 @@ Check the [original](https://github.com/railsjazz/peity_vanilla) page.
50
65
  <img src="https://github.com/railsjazz/peity_vanilla/raw/main/docs/custom.png"/>
51
66
  <img src="https://github.com/railsjazz/peity_vanilla/raw/main/docs/animation.gif"/>
52
67
 
53
- ```html
54
- <span class="updating-chart">5,3,9,6,5,9,7,3,5,2,5,3,9,6,5,9,7,3,5,2</span>
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') %>
55
70
 
56
71
  <script>
57
- var updatingChart = peity(document.getElementById("updating-chart"), "line", { width: 64 });
72
+ var updatingChart = document.getElementById("updating-chart");
58
73
 
59
74
  setInterval(function() {
60
75
  var random = Math.round(Math.random() * 10)
61
- // debugger
62
76
  var values = updatingChart.innerText.split(",")
63
77
  values.shift()
64
78
  values.push(random)
65
79
 
66
80
  updatingChart.innerText = values.join(",")
67
- updatingChart.dispatchEvent(new Event('change'))
68
81
  }, 1000);
69
82
  </script>
70
83
  ```
@@ -119,7 +132,6 @@ You can pass in `options` any of the attributes.
119
132
 
120
133
  ## TODO
121
134
 
122
- - stimulus, turbo, etc.
123
135
  - remote datasource and autoupdate
124
136
 
125
137
  ## Contributing
@@ -129,3 +141,7 @@ You are welcome to contribute.
129
141
  ## License
130
142
 
131
143
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
144
+
145
+
146
+ [<img src="https://github.com/igorkasyanchuk/rails_time_travel/blob/main/docs/more_gems.png?raw=true"
147
+ />](https://www.railsjazz.com/?utm_source=github&utm_medium=bottom&utm_campaign=peity_vanilla_rails)
@@ -0,0 +1,519 @@
1
+ /*!
2
+ Peity Vanila Rails 0.2.1
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
+ function domReady() {
428
+ return new Promise((resolve) => {
429
+ if (document.readyState == "loading") {
430
+ document.addEventListener("DOMContentLoaded", resolve);
431
+ } else {
432
+ resolve();
433
+ }
434
+ });
435
+ }
436
+
437
+ const getPeityType = (node) => node.getAttribute("peity");
438
+
439
+ const elementFromNode = (node) => {
440
+ if (node.nodeType == Node.ELEMENT_NODE) {
441
+ return node;
442
+ }
443
+ };
444
+
445
+ const processNodeAdded = (node) => {
446
+ if (node.matches("[peity]")) {
447
+ peity(node, getPeityType(node));
448
+ }
449
+ };
450
+
451
+ const processNodeRemoved = (node) => {
452
+ if (node._peity) {
453
+ node._peity.destroy();
454
+ }
455
+ };
456
+
457
+ const processAttributeChanged = (mutation) => {
458
+ const node = mutation.target;
459
+ switch (mutation.attributeName) {
460
+ case "peity":
461
+ const type = getPeityType(node);
462
+ if (type) {
463
+ peity(node, type);
464
+ } else {
465
+ node._peity.unmount();
466
+ }
467
+ break;
468
+ case "data-peity":
469
+ if (node._peity) {
470
+ peity(node, node._peity.type);
471
+ }
472
+ break;
473
+ }
474
+ };
475
+
476
+ const callback = (mutationList, observer) => {
477
+ mutationList.forEach(function (mutation) {
478
+ switch (mutation.type) {
479
+ case "childList":
480
+ for (const node of Array.from(mutation.addedNodes)) {
481
+ const element = elementFromNode(node);
482
+ if (element) {
483
+ processNodeAdded(element);
484
+ }
485
+ }
486
+ for (const node of Array.from(mutation.removedNodes)) {
487
+ const element = elementFromNode(node);
488
+ if (element) {
489
+ processNodeRemoved(element);
490
+ }
491
+ }
492
+ break;
493
+ case "attributes":
494
+ processAttributeChanged(mutation);
495
+ break;
496
+ }
497
+ });
498
+ };
499
+
500
+ const observerOptions = {
501
+ childList: true,
502
+ attributes: true,
503
+ subtree: true,
504
+ };
505
+
506
+ const start = async () => {
507
+ await domReady();
508
+
509
+ const observer = new MutationObserver(callback);
510
+ observer.observe(document.documentElement, observerOptions);
511
+
512
+ for (const node of Array.from(document.documentElement.querySelectorAll("[peity]"))) {
513
+ processNodeAdded(node);
514
+ }
515
+ };
516
+
517
+ start();
518
+
519
+ export { peity as default };
@@ -0,0 +1,11 @@
1
+ /*!
2
+ Peity Vanila Rails 0.2.1
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 a=2*t.options.radius;const r=t.prepare(t.options.width||a,t.options.height||a),l=r.clientWidth,h=r.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],a=s/o;let l;if(0!=a){if(1==a)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,a>.5?1:0,1,f(t,d),"L");u?i=i.concat(f(t,u),"A",u,u,0,a>.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)),r.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),a=o.clientWidth,r=o.clientHeight,l=n-s,h=t.options.padding,p=t.fill(),c=t=>t*a/i.length,d=t=>r-(l?(t-s)/l*r:1);for(var u=0;u<i.length;u++){let a,r=c(u+h),m=c(u+1-h)-r,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)):a=1,a=v-y,0==a&&(a=1,n>0&&l&&y--),o.append(e("rect",{"data-value":f,fill:p.call(t,f,u,i),x:r,y:y,width:m,height:a}))}})),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),a=t.options.strokeWidth,r=o.clientWidth,l=o.clientHeight-a,h=n-s,p=t=>{let e=l;return h&&(e-=(t-s)/h*l),e+a/2};let c=p(Math.max(s,0)),d=[0,c];for(var u=0;u<i.length;u++)d.push(u*(r/(i.length-1)),p(i[u]));d.push(r,c),t.options.fill&&o.append(e("polygon",{fill:t.options.fill,points:d.join(" ")})),a&&o.append(e("polyline",{fill:"none",points:d.slice(2,d.length-2).join(" "),stroke:t.options.stroke,"stroke-width":a,"stroke-linecap":"square"}))}));const a=function(t,e,i){const s=new n(t,e,i);return s.mount(),s};a.defaults=n.defaults,a.graphers=n.graphers;const r=t=>t.getAttribute("peity"),l=t=>{if(t.nodeType==Node.ELEMENT_NODE)return t},h=t=>{t.matches("[peity]")&&a(t,r(t))},p=t=>{t._peity&&t._peity.destroy()},c=(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=r(e);t?a(e,t):e._peity.unmount();break;case"data-peity":e._peity&&a(e,e._peity.type)}})(t)}}))},d={childList:!0,attributes:!0,subtree:!0};return(async()=>{await new Promise((t=>{"loading"==document.readyState?document.addEventListener("DOMContentLoaded",t):t()}));new MutationObserver(c).observe(document.documentElement,d);for(const t of Array.from(document.documentElement.querySelectorAll("[peity]")))h(t)})(),a}();