govuk_publishing_components 46.4.0 → 47.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/govuk_publishing_components/_all_components.scss +0 -1
  3. data/app/assets/stylesheets/govuk_publishing_components/components/_heading.scss +6 -14
  4. data/app/assets/stylesheets/govuk_publishing_components/components/_organisation-logo.scss +4 -0
  5. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_highlight-answer.scss +4 -4
  6. data/app/models/govuk_publishing_components/component_doc.rb +1 -1
  7. data/app/views/govuk_publishing_components/components/_heading.html.erb +24 -9
  8. data/app/views/govuk_publishing_components/components/_skip_link.html.erb +6 -1
  9. data/app/views/govuk_publishing_components/components/_step_by_step_nav_header.html.erb +4 -7
  10. data/app/views/govuk_publishing_components/components/_step_by_step_nav_related.html.erb +6 -5
  11. data/app/views/govuk_publishing_components/components/docs/heading.yml +34 -10
  12. data/app/views/govuk_publishing_components/components/docs/inverse_header.yml +1 -1
  13. data/app/views/govuk_publishing_components/components/docs/organisation_logo.yml +9 -0
  14. data/app/views/govuk_publishing_components/components/docs/skip_link.yml +1 -0
  15. data/app/views/govuk_publishing_components/components/docs/step_by_step_nav_header.yml +1 -0
  16. data/app/views/govuk_publishing_components/components/docs/step_by_step_nav_related.yml +1 -0
  17. data/config/locales/ar.yml +0 -8
  18. data/config/locales/az.yml +0 -8
  19. data/config/locales/be.yml +0 -8
  20. data/config/locales/bg.yml +0 -8
  21. data/config/locales/bn.yml +0 -8
  22. data/config/locales/cs.yml +0 -8
  23. data/config/locales/cy.yml +0 -8
  24. data/config/locales/da.yml +0 -8
  25. data/config/locales/de.yml +0 -8
  26. data/config/locales/dr.yml +0 -8
  27. data/config/locales/el.yml +0 -8
  28. data/config/locales/en.yml +0 -8
  29. data/config/locales/es-419.yml +0 -8
  30. data/config/locales/es.yml +0 -8
  31. data/config/locales/et.yml +0 -8
  32. data/config/locales/fa.yml +0 -8
  33. data/config/locales/fi.yml +0 -8
  34. data/config/locales/fr.yml +0 -8
  35. data/config/locales/gd.yml +0 -8
  36. data/config/locales/gu.yml +0 -8
  37. data/config/locales/he.yml +0 -8
  38. data/config/locales/hi.yml +0 -8
  39. data/config/locales/hr.yml +0 -8
  40. data/config/locales/hu.yml +0 -8
  41. data/config/locales/hy.yml +0 -8
  42. data/config/locales/id.yml +0 -8
  43. data/config/locales/is.yml +0 -8
  44. data/config/locales/it.yml +0 -8
  45. data/config/locales/ja.yml +0 -8
  46. data/config/locales/ka.yml +0 -8
  47. data/config/locales/kk.yml +0 -8
  48. data/config/locales/ko.yml +0 -8
  49. data/config/locales/lt.yml +0 -8
  50. data/config/locales/lv.yml +0 -8
  51. data/config/locales/ms.yml +0 -8
  52. data/config/locales/mt.yml +0 -8
  53. data/config/locales/nl.yml +0 -8
  54. data/config/locales/no.yml +0 -8
  55. data/config/locales/pa-pk.yml +0 -8
  56. data/config/locales/pa.yml +0 -8
  57. data/config/locales/pl.yml +0 -8
  58. data/config/locales/ps.yml +0 -8
  59. data/config/locales/pt.yml +0 -8
  60. data/config/locales/ro.yml +0 -8
  61. data/config/locales/ru.yml +0 -8
  62. data/config/locales/si.yml +0 -8
  63. data/config/locales/sk.yml +0 -8
  64. data/config/locales/sl.yml +0 -8
  65. data/config/locales/so.yml +0 -8
  66. data/config/locales/sq.yml +0 -8
  67. data/config/locales/sr.yml +0 -8
  68. data/config/locales/sv.yml +0 -8
  69. data/config/locales/sw.yml +0 -8
  70. data/config/locales/ta.yml +0 -8
  71. data/config/locales/th.yml +0 -8
  72. data/config/locales/tk.yml +0 -8
  73. data/config/locales/tr.yml +0 -8
  74. data/config/locales/uk.yml +0 -8
  75. data/config/locales/ur.yml +0 -8
  76. data/config/locales/uz.yml +0 -8
  77. data/config/locales/vi.yml +0 -8
  78. data/config/locales/zh-hk.yml +0 -8
  79. data/config/locales/zh-tw.yml +0 -8
  80. data/config/locales/zh.yml +0 -8
  81. data/lib/govuk_publishing_components/presenters/heading_helper.rb +3 -3
  82. data/lib/govuk_publishing_components/presenters/organisation_logo_helper.rb +3 -1
  83. data/lib/govuk_publishing_components/version.rb +1 -1
  84. data/lib/govuk_publishing_components.rb +0 -1
  85. metadata +3 -36
  86. data/app/assets/javascripts/govuk_publishing_components/components/chart.js +0 -1
  87. data/app/assets/stylesheets/govuk_publishing_components/components/_chart.scss +0 -57
  88. data/app/assets/stylesheets/govuk_publishing_components/components/_chat-entry.scss +0 -39
  89. data/app/views/govuk_publishing_components/components/_chart.html.erb +0 -146
  90. data/app/views/govuk_publishing_components/components/_chat_entry.html.erb +0 -55
  91. data/app/views/govuk_publishing_components/components/docs/chart.yml +0 -576
  92. data/app/views/govuk_publishing_components/components/docs/chat_entry.yml +0 -45
  93. data/lib/govuk_publishing_components/presenters/chart_helper.rb +0 -112
  94. data/node_modules/chartkick/LICENSE.txt +0 -22
  95. data/node_modules/chartkick/README.md +0 -593
  96. data/node_modules/chartkick/chart.js/chart.esm.js +0 -5
  97. data/node_modules/chartkick/chart.js/package.json +0 -6
  98. data/node_modules/chartkick/dist/chartkick.esm.js +0 -2562
  99. data/node_modules/chartkick/dist/chartkick.js +0 -2570
  100. data/node_modules/chartkick/dist/chartkick.min.js +0 -2
  101. data/node_modules/chartkick/highcharts/highcharts.esm.js +0 -4
  102. data/node_modules/chartkick/highcharts/package.json +0 -6
  103. data/node_modules/chartkick/package.json +0 -50
@@ -1,2570 +0,0 @@
1
- /*!
2
- * Chartkick.js v5.0.1
3
- * Create beautiful charts with one line of JavaScript
4
- * https://github.com/ankane/chartkick.js
5
- * MIT License
6
- */
7
-
8
- (function (global, factory) {
9
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
10
- typeof define === 'function' && define.amd ? define(factory) :
11
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Chartkick = factory());
12
- })(this, (function () { 'use strict';
13
-
14
- function isArray(variable) {
15
- return Object.prototype.toString.call(variable) === "[object Array]";
16
- }
17
-
18
- function isFunction(variable) {
19
- return variable instanceof Function;
20
- }
21
-
22
- function isPlainObject(variable) {
23
- // protect against prototype pollution, defense 2
24
- return Object.prototype.toString.call(variable) === "[object Object]" && !isFunction(variable) && variable instanceof Object;
25
- }
26
-
27
- // https://github.com/madrobby/zepto/blob/master/src/zepto.js
28
- function extend(target, source) {
29
- for (var key in source) {
30
- // protect against prototype pollution, defense 1
31
- if (key === "__proto__") { continue; }
32
-
33
- if (isPlainObject(source[key]) || isArray(source[key])) {
34
- if (isPlainObject(source[key]) && !isPlainObject(target[key])) {
35
- target[key] = {};
36
- }
37
- if (isArray(source[key]) && !isArray(target[key])) {
38
- target[key] = [];
39
- }
40
- extend(target[key], source[key]);
41
- } else if (source[key] !== undefined) {
42
- target[key] = source[key];
43
- }
44
- }
45
- }
46
-
47
- function merge(obj1, obj2) {
48
- var target = {};
49
- extend(target, obj1);
50
- extend(target, obj2);
51
- return target;
52
- }
53
-
54
- var DATE_PATTERN = /^(\d\d\d\d)(?:-)?(\d\d)(?:-)?(\d\d)$/i;
55
-
56
- function negativeValues(series) {
57
- for (var i = 0; i < series.length; i++) {
58
- var data = series[i].data;
59
- for (var j = 0; j < data.length; j++) {
60
- if (data[j][1] < 0) {
61
- return true;
62
- }
63
- }
64
- }
65
- return false;
66
- }
67
-
68
- function toStr(obj) {
69
- return "" + obj;
70
- }
71
-
72
- function toFloat(obj) {
73
- return parseFloat(obj);
74
- }
75
-
76
- function toDate(obj) {
77
- if (obj instanceof Date) {
78
- return obj;
79
- } else if (typeof obj === "number") {
80
- return new Date(obj * 1000); // ms
81
- } else {
82
- var s = toStr(obj);
83
- var matches = s.match(DATE_PATTERN);
84
- if (matches) {
85
- var year = parseInt(matches[1], 10);
86
- var month = parseInt(matches[2], 10) - 1;
87
- var day = parseInt(matches[3], 10);
88
- return new Date(year, month, day);
89
- } else {
90
- // try our best to get the str into iso8601
91
- // TODO be smarter about this
92
- var str = s.replace(/ /, "T").replace(" ", "").replace("UTC", "Z");
93
- // Date.parse returns milliseconds if valid and NaN if invalid
94
- return new Date(Date.parse(str) || s);
95
- }
96
- }
97
- }
98
-
99
- function toArr(obj) {
100
- if (isArray(obj)) {
101
- return obj;
102
- } else {
103
- var arr = [];
104
- for (var i in obj) {
105
- if (Object.prototype.hasOwnProperty.call(obj, i)) {
106
- arr.push([i, obj[i]]);
107
- }
108
- }
109
- return arr;
110
- }
111
- }
112
-
113
- function jsOptionsFunc(defaultOptions, hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle) {
114
- return function (chart, opts, chartOptions) {
115
- var series = chart.data;
116
- var options = merge({}, defaultOptions);
117
- options = merge(options, chartOptions || {});
118
-
119
- if (chart.singleSeriesFormat || "legend" in opts) {
120
- hideLegend(options, opts.legend, chart.singleSeriesFormat);
121
- }
122
-
123
- if (opts.title) {
124
- setTitle(options, opts.title);
125
- }
126
-
127
- // min
128
- if ("min" in opts) {
129
- setMin(options, opts.min);
130
- } else if (!negativeValues(series)) {
131
- setMin(options, 0);
132
- }
133
-
134
- // max
135
- if (opts.max) {
136
- setMax(options, opts.max);
137
- }
138
-
139
- if ("stacked" in opts) {
140
- setStacked(options, opts.stacked);
141
- }
142
-
143
- if (opts.colors) {
144
- options.colors = opts.colors;
145
- }
146
-
147
- if (opts.xtitle) {
148
- setXtitle(options, opts.xtitle);
149
- }
150
-
151
- if (opts.ytitle) {
152
- setYtitle(options, opts.ytitle);
153
- }
154
-
155
- // merge library last
156
- options = merge(options, opts.library || {});
157
-
158
- return options;
159
- };
160
- }
161
-
162
- function sortByTime(a, b) {
163
- return a[0].getTime() - b[0].getTime();
164
- }
165
-
166
- function sortByNumberSeries(a, b) {
167
- return a[0] - b[0];
168
- }
169
-
170
- // needed since sort() without arguments does string comparison
171
- function sortByNumber(a, b) {
172
- return a - b;
173
- }
174
-
175
- function every(values, fn) {
176
- for (var i = 0; i < values.length; i++) {
177
- if (!fn(values[i])) {
178
- return false;
179
- }
180
- }
181
- return true;
182
- }
183
-
184
- function isDay(timeUnit) {
185
- return timeUnit === "day" || timeUnit === "week" || timeUnit === "month" || timeUnit === "year";
186
- }
187
-
188
- function calculateTimeUnit(values, maxDay) {
189
- if ( maxDay === void 0 ) maxDay = false;
190
-
191
- if (values.length === 0) {
192
- return null;
193
- }
194
-
195
- var minute = every(values, function (d) { return d.getMilliseconds() === 0 && d.getSeconds() === 0; });
196
- if (!minute) {
197
- return null;
198
- }
199
-
200
- var hour = every(values, function (d) { return d.getMinutes() === 0; });
201
- if (!hour) {
202
- return "minute";
203
- }
204
-
205
- var day = every(values, function (d) { return d.getHours() === 0; });
206
- if (!day) {
207
- return "hour";
208
- }
209
-
210
- if (maxDay) {
211
- return "day";
212
- }
213
-
214
- var month = every(values, function (d) { return d.getDate() === 1; });
215
- if (!month) {
216
- var dayOfWeek = values[0].getDay();
217
- var week = every(values, function (d) { return d.getDay() === dayOfWeek; });
218
- return (week ? "week" : "day");
219
- }
220
-
221
- var year = every(values, function (d) { return d.getMonth() === 0; });
222
- if (!year) {
223
- return "month";
224
- }
225
-
226
- return "year";
227
- }
228
-
229
- function isDate(obj) {
230
- return !isNaN(toDate(obj)) && toStr(obj).length >= 6;
231
- }
232
-
233
- function isNumber(obj) {
234
- return typeof obj === "number";
235
- }
236
-
237
- var byteSuffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB"];
238
-
239
- function formatValue(pre, value, options, axis) {
240
- pre = pre || "";
241
- if (options.prefix) {
242
- if (value < 0) {
243
- value = value * -1;
244
- pre += "-";
245
- }
246
- pre += options.prefix;
247
- }
248
-
249
- var suffix = options.suffix || "";
250
- var precision = options.precision;
251
- var round = options.round;
252
-
253
- if (options.byteScale) {
254
- var positive = value >= 0;
255
- if (!positive) {
256
- value *= -1;
257
- }
258
-
259
- var baseValue = axis ? options.byteScale : value;
260
-
261
- var suffixIdx;
262
- if (baseValue >= 1152921504606846976) {
263
- value /= 1152921504606846976;
264
- suffixIdx = 6;
265
- } else if (baseValue >= 1125899906842624) {
266
- value /= 1125899906842624;
267
- suffixIdx = 5;
268
- } else if (baseValue >= 1099511627776) {
269
- value /= 1099511627776;
270
- suffixIdx = 4;
271
- } else if (baseValue >= 1073741824) {
272
- value /= 1073741824;
273
- suffixIdx = 3;
274
- } else if (baseValue >= 1048576) {
275
- value /= 1048576;
276
- suffixIdx = 2;
277
- } else if (baseValue >= 1024) {
278
- value /= 1024;
279
- suffixIdx = 1;
280
- } else {
281
- suffixIdx = 0;
282
- }
283
-
284
- // TODO handle manual precision case
285
- if (precision === undefined && round === undefined) {
286
- if (value >= 1023.5) {
287
- if (suffixIdx < byteSuffixes.length - 1) {
288
- value = 1.0;
289
- suffixIdx += 1;
290
- }
291
- }
292
- precision = value >= 1000 ? 4 : 3;
293
- }
294
- suffix = " " + byteSuffixes[suffixIdx];
295
-
296
- // flip value back
297
- if (!positive) {
298
- value *= -1;
299
- }
300
- }
301
-
302
- if (precision !== undefined && round !== undefined) {
303
- throw Error("Use either round or precision, not both");
304
- }
305
-
306
- if (!axis) {
307
- if (precision !== undefined) {
308
- value = value.toPrecision(precision);
309
- if (!options.zeros) {
310
- value = parseFloat(value);
311
- }
312
- }
313
-
314
- if (round !== undefined) {
315
- if (round < 0) {
316
- var num = Math.pow(10, -1 * round);
317
- value = parseInt((1.0 * value / num).toFixed(0)) * num;
318
- } else {
319
- value = value.toFixed(round);
320
- if (!options.zeros) {
321
- value = parseFloat(value);
322
- }
323
- }
324
- }
325
- }
326
-
327
- if (options.thousands || options.decimal) {
328
- value = toStr(value);
329
- var parts = value.split(".");
330
- value = parts[0];
331
- if (options.thousands) {
332
- value = value.replace(/\B(?=(\d{3})+(?!\d))/g, options.thousands);
333
- }
334
- if (parts.length > 1) {
335
- value += (options.decimal || ".") + parts[1];
336
- }
337
- }
338
-
339
- return pre + value + suffix;
340
- }
341
-
342
- function seriesOption(chart, series, option) {
343
- if (option in series) {
344
- return series[option];
345
- } else if (option in chart.options) {
346
- return chart.options[option];
347
- }
348
- return null;
349
- }
350
-
351
- var baseOptions = {
352
- maintainAspectRatio: false,
353
- animation: false,
354
- plugins: {
355
- legend: {},
356
- tooltip: {
357
- displayColors: false,
358
- callbacks: {}
359
- },
360
- title: {
361
- font: {
362
- size: 20
363
- },
364
- color: "#333"
365
- }
366
- },
367
- interaction: {}
368
- };
369
-
370
- var defaultOptions$2 = {
371
- scales: {
372
- y: {
373
- ticks: {
374
- maxTicksLimit: 4
375
- },
376
- title: {
377
- font: {
378
- size: 16
379
- },
380
- color: "#333"
381
- },
382
- grid: {}
383
- },
384
- x: {
385
- grid: {
386
- drawOnChartArea: false
387
- },
388
- title: {
389
- font: {
390
- size: 16
391
- },
392
- color: "#333"
393
- },
394
- time: {},
395
- ticks: {}
396
- }
397
- }
398
- };
399
-
400
- // http://there4.io/2012/05/02/google-chart-color-list/
401
- var defaultColors = [
402
- "#3366CC", "#DC3912", "#FF9900", "#109618", "#990099", "#3B3EAC", "#0099C6",
403
- "#DD4477", "#66AA00", "#B82E2E", "#316395", "#994499", "#22AA99", "#AAAA11",
404
- "#6633CC", "#E67300", "#8B0707", "#329262", "#5574A6", "#651067"
405
- ];
406
-
407
- function hideLegend$2(options, legend, hideLegend) {
408
- if (legend !== undefined) {
409
- options.plugins.legend.display = !!legend;
410
- if (legend && legend !== true) {
411
- options.plugins.legend.position = legend;
412
- }
413
- } else if (hideLegend) {
414
- options.plugins.legend.display = false;
415
- }
416
- }
417
-
418
- function setTitle$2(options, title) {
419
- options.plugins.title.display = true;
420
- options.plugins.title.text = title;
421
- }
422
-
423
- function setMin$2(options, min) {
424
- if (min !== null) {
425
- options.scales.y.min = toFloat(min);
426
- }
427
- }
428
-
429
- function setMax$2(options, max) {
430
- options.scales.y.max = toFloat(max);
431
- }
432
-
433
- function setBarMin$1(options, min) {
434
- if (min !== null) {
435
- options.scales.x.min = toFloat(min);
436
- }
437
- }
438
-
439
- function setBarMax$1(options, max) {
440
- options.scales.x.max = toFloat(max);
441
- }
442
-
443
- function setStacked$2(options, stacked) {
444
- options.scales.x.stacked = !!stacked;
445
- options.scales.y.stacked = !!stacked;
446
- }
447
-
448
- function setXtitle$2(options, title) {
449
- options.scales.x.title.display = true;
450
- options.scales.x.title.text = title;
451
- }
452
-
453
- function setYtitle$2(options, title) {
454
- options.scales.y.title.display = true;
455
- options.scales.y.title.text = title;
456
- }
457
-
458
- // https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
459
- function addOpacity(hex, opacity) {
460
- var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
461
- return result ? "rgba(" + parseInt(result[1], 16) + ", " + parseInt(result[2], 16) + ", " + parseInt(result[3], 16) + ", " + opacity + ")" : hex;
462
- }
463
-
464
- function notnull(x) {
465
- return x !== null && x !== undefined;
466
- }
467
-
468
- function setLabelSize(chart, data, options) {
469
- var maxLabelSize = Math.ceil(chart.element.offsetWidth / 4.0 / data.labels.length);
470
- if (maxLabelSize > 25) {
471
- maxLabelSize = 25;
472
- } else if (maxLabelSize < 10) {
473
- maxLabelSize = 10;
474
- }
475
- if (!options.scales.x.ticks.callback) {
476
- options.scales.x.ticks.callback = function (value) {
477
- value = toStr(this.getLabelForValue(value));
478
- if (value.length > maxLabelSize) {
479
- return value.substring(0, maxLabelSize - 2) + "...";
480
- } else {
481
- return value;
482
- }
483
- };
484
- }
485
- }
486
-
487
- function calculateScale(series) {
488
- var scale = 1;
489
- var max = maxAbsY(series);
490
- while (max >= 1024) {
491
- scale *= 1024;
492
- max /= 1024;
493
- }
494
- return scale;
495
- }
496
-
497
- function setFormatOptions$1(chart, options, chartType) {
498
- // options to apply to x and r values for scatter and bubble
499
- var numericOptions = {
500
- thousands: chart.options.thousands,
501
- decimal: chart.options.decimal
502
- };
503
-
504
- // options to apply to y value
505
- var formatOptions = merge({
506
- prefix: chart.options.prefix,
507
- suffix: chart.options.suffix,
508
- precision: chart.options.precision,
509
- round: chart.options.round,
510
- zeros: chart.options.zeros
511
- }, numericOptions);
512
-
513
- if (chart.options.bytes) {
514
- var series = chart.data;
515
- if (chartType === "pie") {
516
- series = [{data: series}];
517
- }
518
-
519
- // set step size
520
- formatOptions.byteScale = calculateScale(series);
521
- }
522
-
523
- if (chartType !== "pie") {
524
- var axis = options.scales.y;
525
- if (chartType === "bar") {
526
- axis = options.scales.x;
527
- }
528
-
529
- if (formatOptions.byteScale) {
530
- if (!axis.ticks.stepSize) {
531
- axis.ticks.stepSize = formatOptions.byteScale / 2;
532
- }
533
- if (!axis.ticks.maxTicksLimit) {
534
- axis.ticks.maxTicksLimit = 4;
535
- }
536
- }
537
-
538
- if (!axis.ticks.callback) {
539
- axis.ticks.callback = function (value) {
540
- return formatValue("", value, formatOptions, true);
541
- };
542
- }
543
-
544
- if ((chartType === "scatter" || chartType === "bubble") && !options.scales.x.ticks.callback) {
545
- options.scales.x.ticks.callback = function (value) {
546
- return formatValue("", value, numericOptions, true);
547
- };
548
- }
549
- }
550
-
551
- if (!options.plugins.tooltip.callbacks.label) {
552
- if (chartType === "scatter") {
553
- options.plugins.tooltip.callbacks.label = function (context) {
554
- var label = context.dataset.label || '';
555
- if (label) {
556
- label += ': ';
557
- }
558
-
559
- var dataPoint = context.parsed;
560
- return label + '(' + formatValue('', dataPoint.x, numericOptions) + ', ' + formatValue('', dataPoint.y, formatOptions) + ')';
561
- };
562
- } else if (chartType === "bubble") {
563
- options.plugins.tooltip.callbacks.label = function (context) {
564
- var label = context.dataset.label || '';
565
- if (label) {
566
- label += ': ';
567
- }
568
- var dataPoint = context.raw;
569
- return label + '(' + formatValue('', dataPoint.x, numericOptions) + ', ' + formatValue('', dataPoint.y, formatOptions) + ', ' + formatValue('', dataPoint.v, numericOptions) + ')';
570
- };
571
- } else if (chartType === "pie") {
572
- // need to use separate label for pie charts
573
- options.plugins.tooltip.callbacks.label = function (context) {
574
- return formatValue('', context.parsed, formatOptions);
575
- };
576
- } else {
577
- var valueLabel = chartType === "bar" ? "x" : "y";
578
- options.plugins.tooltip.callbacks.label = function (context) {
579
- // don't show null values for stacked charts
580
- if (context.parsed[valueLabel] === null) {
581
- return;
582
- }
583
-
584
- var label = context.dataset.label || '';
585
- if (label) {
586
- label += ': ';
587
- }
588
- return formatValue(label, context.parsed[valueLabel], formatOptions);
589
- };
590
- }
591
- }
592
-
593
- // avoid formatting x-axis labels
594
- // by default, Chart.js applies locale
595
- if ((chartType === "line" || chartType === "area") && chart.xtype === "number") {
596
- if (!options.scales.x.ticks.callback) {
597
- options.scales.x.ticks.callback = function (value) {
598
- return toStr(value);
599
- };
600
- }
601
-
602
- if (!options.plugins.tooltip.callbacks.title) {
603
- options.plugins.tooltip.callbacks.title = function (context) {
604
- return toStr(context[0].parsed.x);
605
- };
606
- }
607
- }
608
- }
609
-
610
- function maxAbsY(series) {
611
- var max = 0;
612
- for (var i = 0; i < series.length; i++) {
613
- var data = series[i].data;
614
- for (var j = 0; j < data.length; j++) {
615
- var v = Math.abs(data[j][1]);
616
- if (v > max) {
617
- max = v;
618
- }
619
- }
620
- }
621
- return max;
622
- }
623
-
624
- function maxR(series) {
625
- // start at zero since radius must be positive
626
- var max = 0;
627
- for (var i = 0; i < series.length; i++) {
628
- var data = series[i].data;
629
- for (var j = 0; j < data.length; j++) {
630
- var v = data[j][2];
631
- if (v > max) {
632
- max = v;
633
- }
634
- }
635
- }
636
- return max;
637
- }
638
-
639
- var jsOptions$2 = jsOptionsFunc(merge(baseOptions, defaultOptions$2), hideLegend$2, setTitle$2, setMin$2, setMax$2, setStacked$2, setXtitle$2, setYtitle$2);
640
-
641
- function prepareDefaultData(chart) {
642
- var series = chart.data;
643
- var rows = {};
644
- var keys = [];
645
- var labels = [];
646
- var values = [];
647
-
648
- for (var i = 0; i < series.length; i++) {
649
- var data = series[i].data;
650
-
651
- for (var j = 0; j < data.length; j++) {
652
- var d = data[j];
653
- var key = chart.xtype === "datetime" ? d[0].getTime() : d[0];
654
- if (!rows[key]) {
655
- rows[key] = new Array(series.length);
656
- keys.push(key);
657
- }
658
- rows[key][i] = d[1];
659
- }
660
- }
661
-
662
- if (chart.xtype === "datetime" || chart.xtype === "number") {
663
- keys.sort(sortByNumber);
664
- }
665
-
666
- for (var i$1 = 0; i$1 < series.length; i$1++) {
667
- values.push([]);
668
- }
669
-
670
- for (var i$2 = 0; i$2 < keys.length; i$2++) {
671
- var key$1 = keys[i$2];
672
-
673
- var label = chart.xtype === "datetime" ? new Date(key$1) : key$1;
674
- labels.push(label);
675
-
676
- var row = rows[key$1];
677
- for (var j$1 = 0; j$1 < series.length; j$1++) {
678
- var v = row[j$1];
679
- // Chart.js doesn't like undefined
680
- values[j$1].push(v === undefined ? null : v);
681
- }
682
- }
683
-
684
- return {
685
- labels: labels,
686
- values: values
687
- };
688
- }
689
-
690
- function prepareBubbleData(chart) {
691
- var series = chart.data;
692
- var values = [];
693
- var max = maxR(series);
694
-
695
- for (var i = 0; i < series.length; i++) {
696
- var data = series[i].data;
697
- var points = [];
698
- for (var j = 0; j < data.length; j++) {
699
- var v = data[j];
700
- points.push({
701
- x: v[0],
702
- y: v[1],
703
- r: v[2] * 20 / max,
704
- // custom attribute, for tooltip
705
- v: v[2]
706
- });
707
- }
708
- values.push(points);
709
- }
710
-
711
- return {
712
- labels: [],
713
- values: values
714
- };
715
- }
716
-
717
- // scatter or numeric line/area
718
- function prepareNumberData(chart) {
719
- var series = chart.data;
720
- var values = [];
721
-
722
- for (var i = 0; i < series.length; i++) {
723
- var data = series[i].data;
724
-
725
- data.sort(sortByNumberSeries);
726
-
727
- var points = [];
728
- for (var j = 0; j < data.length; j++) {
729
- var v = data[j];
730
- points.push({
731
- x: v[0],
732
- y: v[1]
733
- });
734
- }
735
- values.push(points);
736
- }
737
-
738
- return {
739
- labels: [],
740
- values: values
741
- };
742
- }
743
-
744
- function prepareData(chart, chartType) {
745
- if (chartType === "bubble") {
746
- return prepareBubbleData(chart);
747
- } else if (chart.xtype === "number" && chartType !== "bar" && chartType !== "column") {
748
- return prepareNumberData(chart);
749
- } else {
750
- return prepareDefaultData(chart);
751
- }
752
- }
753
-
754
- function createDataTable(chart, options, chartType) {
755
- var ref = prepareData(chart, chartType);
756
- var labels = ref.labels;
757
- var values = ref.values;
758
-
759
- var series = chart.data;
760
- var datasets = [];
761
- var colors = chart.options.colors || defaultColors;
762
- for (var i = 0; i < series.length; i++) {
763
- var s = series[i];
764
-
765
- // use colors for each bar for single series format
766
- var color = (void 0);
767
- var backgroundColor = (void 0);
768
- if (chart.options.colors && chart.singleSeriesFormat && (chartType === "bar" || chartType === "column") && !s.color && isArray(chart.options.colors) && !isArray(chart.options.colors[0])) {
769
- color = colors;
770
- backgroundColor = [];
771
- for (var j = 0; j < colors.length; j++) {
772
- backgroundColor[j] = addOpacity(color[j], 0.5);
773
- }
774
- } else {
775
- color = s.color || colors[i];
776
- backgroundColor = chartType !== "line" ? addOpacity(color, 0.5) : color;
777
- }
778
-
779
- var dataset = {
780
- label: s.name || "",
781
- data: values[i],
782
- fill: chartType === "area",
783
- borderColor: color,
784
- backgroundColor: backgroundColor,
785
- borderWidth: 2
786
- };
787
-
788
- var pointChart = chartType === "line" || chartType === "area" || chartType === "scatter" || chartType === "bubble";
789
- if (pointChart) {
790
- dataset.pointBackgroundColor = color;
791
- dataset.pointHoverBackgroundColor = color;
792
- dataset.pointHitRadius = 50;
793
- }
794
-
795
- if (chartType === "bubble") {
796
- dataset.pointBackgroundColor = backgroundColor;
797
- dataset.pointHoverBackgroundColor = backgroundColor;
798
- dataset.pointHoverBorderWidth = 2;
799
- }
800
-
801
- if (s.stack) {
802
- dataset.stack = s.stack;
803
- }
804
-
805
- var curve = seriesOption(chart, s, "curve");
806
- if (curve === false) {
807
- dataset.tension = 0;
808
- } else if (pointChart) {
809
- dataset.tension = 0.4;
810
- }
811
-
812
- var points = seriesOption(chart, s, "points");
813
- if (points === false) {
814
- dataset.pointRadius = 0;
815
- dataset.pointHoverRadius = 0;
816
- }
817
-
818
- dataset = merge(dataset, chart.options.dataset || {});
819
- dataset = merge(dataset, s.library || {});
820
- dataset = merge(dataset, s.dataset || {});
821
-
822
- datasets.push(dataset);
823
- }
824
-
825
- var xmin = chart.options.xmin;
826
- var xmax = chart.options.xmax;
827
-
828
- if (chart.xtype === "datetime") {
829
- if (notnull(xmin)) {
830
- options.scales.x.min = toDate(xmin).getTime();
831
- }
832
- if (notnull(xmax)) {
833
- options.scales.x.max = toDate(xmax).getTime();
834
- }
835
- } else if (chart.xtype === "number") {
836
- if (notnull(xmin)) {
837
- options.scales.x.min = xmin;
838
- }
839
- if (notnull(xmax)) {
840
- options.scales.x.max = xmax;
841
- }
842
- }
843
-
844
- if (chart.xtype === "datetime") {
845
- var timeUnit = calculateTimeUnit(labels);
846
-
847
- // for empty datetime chart
848
- if (labels.length === 0) {
849
- if (notnull(xmin)) {
850
- labels.push(toDate(xmin));
851
- }
852
- if (notnull(xmax)) {
853
- labels.push(toDate(xmax));
854
- }
855
- }
856
-
857
- if (labels.length > 0) {
858
- var minTime = (notnull(xmin) ? toDate(xmin) : labels[0]).getTime();
859
- var maxTime = (notnull(xmax) ? toDate(xmax) : labels[0]).getTime();
860
-
861
- for (var i$1 = 1; i$1 < labels.length; i$1++) {
862
- var value = labels[i$1].getTime();
863
- if (value < minTime) {
864
- minTime = value;
865
- }
866
- if (value > maxTime) {
867
- maxTime = value;
868
- }
869
- }
870
-
871
- var timeDiff = (maxTime - minTime) / (86400 * 1000.0);
872
-
873
- if (!options.scales.x.time.unit) {
874
- var step;
875
- if (timeUnit === "year" || timeDiff > 365 * 10) {
876
- options.scales.x.time.unit = "year";
877
- step = 365;
878
- } else if (timeUnit === "month" || timeDiff > 30 * 10) {
879
- options.scales.x.time.unit = "month";
880
- step = 30;
881
- } else if (timeUnit === "week" || timeUnit === "day" || timeDiff > 10) {
882
- options.scales.x.time.unit = "day";
883
- step = 1;
884
- } else if (timeUnit === "hour" || timeDiff > 0.5) {
885
- options.scales.x.time.displayFormats = {hour: "MMM d, h a"};
886
- options.scales.x.time.unit = "hour";
887
- step = 1 / 24.0;
888
- } else if (timeUnit === "minute") {
889
- options.scales.x.time.displayFormats = {minute: "h:mm a"};
890
- options.scales.x.time.unit = "minute";
891
- step = 1 / 24.0 / 60.0;
892
- }
893
-
894
- if (step && timeDiff > 0) {
895
- // width not available for hidden elements
896
- var width = chart.element.offsetWidth;
897
- if (width > 0) {
898
- var unitStepSize = Math.ceil(timeDiff / step / (width / 100.0));
899
- if (timeUnit === "week" && step === 1) {
900
- unitStepSize = Math.ceil(unitStepSize / 7.0) * 7;
901
- }
902
- options.scales.x.ticks.stepSize = unitStepSize;
903
- }
904
- }
905
- }
906
-
907
- if (!options.scales.x.time.tooltipFormat) {
908
- if (timeUnit === "year") {
909
- options.scales.x.time.tooltipFormat = "yyyy";
910
- } else if (timeUnit === "month") {
911
- options.scales.x.time.tooltipFormat = "MMM yyyy";
912
- } else if (timeUnit === "week" || timeUnit === "day") {
913
- options.scales.x.time.tooltipFormat = "PP";
914
- } else if (timeUnit === "hour") {
915
- options.scales.x.time.tooltipFormat = "MMM d, h a";
916
- } else if (timeUnit === "minute") {
917
- options.scales.x.time.tooltipFormat = "h:mm a";
918
- }
919
- }
920
- }
921
- }
922
-
923
- return {
924
- labels: labels,
925
- datasets: datasets
926
- };
927
- }
928
-
929
- var defaultExport$2 = function defaultExport(library) {
930
- this.name = "chartjs";
931
- this.library = library;
932
- };
933
-
934
- defaultExport$2.prototype.renderLineChart = function renderLineChart (chart, chartType) {
935
- if (!chartType) {
936
- chartType = "line";
937
- }
938
-
939
- var chartOptions = {};
940
-
941
- var options = jsOptions$2(chart, merge(chartOptions, chart.options));
942
- setFormatOptions$1(chart, options, chartType);
943
-
944
- var data = createDataTable(chart, options, chartType);
945
-
946
- if (chart.xtype === "number") {
947
- options.scales.x.type = options.scales.x.type || "linear";
948
- options.scales.x.position = options.scales.x.position || "bottom";
949
- } else {
950
- options.scales.x.type = chart.xtype === "string" ? "category" : "time";
951
- }
952
-
953
- this.drawChart(chart, "line", data, options);
954
- };
955
-
956
- defaultExport$2.prototype.renderPieChart = function renderPieChart (chart) {
957
- var options = merge({}, baseOptions);
958
- if (chart.options.donut) {
959
- options.cutout = "50%";
960
- }
961
-
962
- if ("legend" in chart.options) {
963
- hideLegend$2(options, chart.options.legend);
964
- }
965
-
966
- if (chart.options.title) {
967
- setTitle$2(options, chart.options.title);
968
- }
969
-
970
- options = merge(options, chart.options.library || {});
971
- setFormatOptions$1(chart, options, "pie");
972
-
973
- var labels = [];
974
- var values = [];
975
- for (var i = 0; i < chart.data.length; i++) {
976
- var point = chart.data[i];
977
- labels.push(point[0]);
978
- values.push(point[1]);
979
- }
980
-
981
- var dataset = {
982
- data: values,
983
- backgroundColor: chart.options.colors || defaultColors
984
- };
985
- dataset = merge(dataset, chart.options.dataset || {});
986
-
987
- var data = {
988
- labels: labels,
989
- datasets: [dataset]
990
- };
991
-
992
- this.drawChart(chart, "pie", data, options);
993
- };
994
-
995
- defaultExport$2.prototype.renderColumnChart = function renderColumnChart (chart, chartType) {
996
- var options;
997
- if (chartType === "bar") {
998
- var barOptions = merge(baseOptions, defaultOptions$2);
999
- barOptions.indexAxis = "y";
1000
-
1001
- // ensure gridlines have proper orientation
1002
- barOptions.scales.x.grid.drawOnChartArea = true;
1003
- barOptions.scales.y.grid.drawOnChartArea = false;
1004
- delete barOptions.scales.y.ticks.maxTicksLimit;
1005
-
1006
- options = jsOptionsFunc(barOptions, hideLegend$2, setTitle$2, setBarMin$1, setBarMax$1, setStacked$2, setXtitle$2, setYtitle$2)(chart, chart.options);
1007
- } else {
1008
- options = jsOptions$2(chart, chart.options);
1009
- }
1010
- setFormatOptions$1(chart, options, chartType);
1011
- var data = createDataTable(chart, options, "column");
1012
- if (chartType !== "bar") {
1013
- setLabelSize(chart, data, options);
1014
- }
1015
- if (!("mode" in options.interaction)) {
1016
- options.interaction.mode = "index";
1017
- }
1018
- this.drawChart(chart, "bar", data, options);
1019
- };
1020
-
1021
- defaultExport$2.prototype.renderAreaChart = function renderAreaChart (chart) {
1022
- this.renderLineChart(chart, "area");
1023
- };
1024
-
1025
- defaultExport$2.prototype.renderBarChart = function renderBarChart (chart) {
1026
- this.renderColumnChart(chart, "bar");
1027
- };
1028
-
1029
- defaultExport$2.prototype.renderScatterChart = function renderScatterChart (chart, chartType) {
1030
- chartType = chartType || "scatter";
1031
-
1032
- var options = jsOptions$2(chart, chart.options);
1033
- setFormatOptions$1(chart, options, chartType);
1034
-
1035
- if (!("showLine" in options)) {
1036
- options.showLine = false;
1037
- }
1038
-
1039
- var data = createDataTable(chart, options, chartType);
1040
-
1041
- options.scales.x.type = options.scales.x.type || "linear";
1042
- options.scales.x.position = options.scales.x.position || "bottom";
1043
-
1044
- // prevent grouping hover and tooltips
1045
- if (!("mode" in options.interaction)) {
1046
- options.interaction.mode = "nearest";
1047
- }
1048
-
1049
- this.drawChart(chart, chartType, data, options);
1050
- };
1051
-
1052
- defaultExport$2.prototype.renderBubbleChart = function renderBubbleChart (chart) {
1053
- this.renderScatterChart(chart, "bubble");
1054
- };
1055
-
1056
- defaultExport$2.prototype.destroy = function destroy (chart) {
1057
- if (chart.chart) {
1058
- chart.chart.destroy();
1059
- }
1060
- };
1061
-
1062
- defaultExport$2.prototype.drawChart = function drawChart (chart, type, data, options) {
1063
- this.destroy(chart);
1064
- if (chart.destroyed) { return; }
1065
-
1066
- var chartOptions = {
1067
- type: type,
1068
- data: data,
1069
- options: options
1070
- };
1071
-
1072
- if (chart.options.code) {
1073
- window.console.log("new Chart(ctx, " + JSON.stringify(chartOptions) + ");");
1074
- }
1075
-
1076
- chart.element.innerHTML = "<canvas></canvas>";
1077
- var ctx = chart.element.getElementsByTagName("CANVAS")[0];
1078
- chart.chart = new this.library(ctx, chartOptions);
1079
- };
1080
-
1081
- var defaultOptions$1 = {
1082
- chart: {},
1083
- xAxis: {
1084
- title: {
1085
- text: null
1086
- },
1087
- labels: {
1088
- style: {
1089
- fontSize: "12px"
1090
- }
1091
- }
1092
- },
1093
- yAxis: {
1094
- title: {
1095
- text: null
1096
- },
1097
- labels: {
1098
- style: {
1099
- fontSize: "12px"
1100
- }
1101
- }
1102
- },
1103
- title: {
1104
- text: null
1105
- },
1106
- credits: {
1107
- enabled: false
1108
- },
1109
- legend: {
1110
- borderWidth: 0
1111
- },
1112
- tooltip: {
1113
- style: {
1114
- fontSize: "12px"
1115
- }
1116
- },
1117
- plotOptions: {
1118
- areaspline: {},
1119
- area: {},
1120
- series: {
1121
- marker: {}
1122
- }
1123
- },
1124
- time: {
1125
- useUTC: false
1126
- }
1127
- };
1128
-
1129
- function hideLegend$1(options, legend, hideLegend) {
1130
- if (legend !== undefined) {
1131
- options.legend.enabled = !!legend;
1132
- if (legend && legend !== true) {
1133
- if (legend === "top" || legend === "bottom") {
1134
- options.legend.verticalAlign = legend;
1135
- } else {
1136
- options.legend.layout = "vertical";
1137
- options.legend.verticalAlign = "middle";
1138
- options.legend.align = legend;
1139
- }
1140
- }
1141
- } else if (hideLegend) {
1142
- options.legend.enabled = false;
1143
- }
1144
- }
1145
-
1146
- function setTitle$1(options, title) {
1147
- options.title.text = title;
1148
- }
1149
-
1150
- function setMin$1(options, min) {
1151
- options.yAxis.min = min;
1152
- }
1153
-
1154
- function setMax$1(options, max) {
1155
- options.yAxis.max = max;
1156
- }
1157
-
1158
- function setStacked$1(options, stacked) {
1159
- var stackedValue = stacked ? (stacked === true ? "normal" : stacked) : null;
1160
- options.plotOptions.series.stacking = stackedValue;
1161
- options.plotOptions.area.stacking = stackedValue;
1162
- options.plotOptions.areaspline.stacking = stackedValue;
1163
- }
1164
-
1165
- function setXtitle$1(options, title) {
1166
- options.xAxis.title.text = title;
1167
- }
1168
-
1169
- function setYtitle$1(options, title) {
1170
- options.yAxis.title.text = title;
1171
- }
1172
-
1173
- var jsOptions$1 = jsOptionsFunc(defaultOptions$1, hideLegend$1, setTitle$1, setMin$1, setMax$1, setStacked$1, setXtitle$1, setYtitle$1);
1174
-
1175
- function setFormatOptions(chart, options, chartType) {
1176
- var formatOptions = {
1177
- prefix: chart.options.prefix,
1178
- suffix: chart.options.suffix,
1179
- thousands: chart.options.thousands,
1180
- decimal: chart.options.decimal,
1181
- precision: chart.options.precision,
1182
- round: chart.options.round,
1183
- zeros: chart.options.zeros
1184
- };
1185
-
1186
- // skip when axis is an array (like with min/max)
1187
- if (chartType !== "pie" && !isArray(options.yAxis) && !options.yAxis.labels.formatter) {
1188
- options.yAxis.labels.formatter = function () {
1189
- return formatValue("", this.value, formatOptions);
1190
- };
1191
- }
1192
-
1193
- if (!options.tooltip.pointFormatter && !options.tooltip.pointFormat) {
1194
- options.tooltip.pointFormatter = function () {
1195
- return '<span style="color:' + this.color + '">\u25CF</span> ' + formatValue(this.series.name + ': <b>', this.y, formatOptions) + '</b><br/>';
1196
- };
1197
- }
1198
- }
1199
-
1200
- var defaultExport$1 = function defaultExport(library) {
1201
- this.name = "highcharts";
1202
- this.library = library;
1203
- };
1204
-
1205
- defaultExport$1.prototype.renderLineChart = function renderLineChart (chart, chartType) {
1206
- chartType = chartType || "spline";
1207
- var chartOptions = {};
1208
- if (chartType === "areaspline") {
1209
- chartOptions = {
1210
- plotOptions: {
1211
- areaspline: {
1212
- stacking: "normal"
1213
- },
1214
- area: {
1215
- stacking: "normal"
1216
- },
1217
- series: {
1218
- marker: {
1219
- enabled: false
1220
- }
1221
- }
1222
- }
1223
- };
1224
- }
1225
-
1226
- if (chart.options.curve === false) {
1227
- if (chartType === "areaspline") {
1228
- chartType = "area";
1229
- } else if (chartType === "spline") {
1230
- chartType = "line";
1231
- }
1232
- }
1233
-
1234
- var options = jsOptions$1(chart, chart.options, chartOptions);
1235
- if (chart.xtype === "number") {
1236
- options.xAxis.type = options.xAxis.type || "linear";
1237
- } else {
1238
- options.xAxis.type = chart.xtype === "string" ? "category" : "datetime";
1239
- }
1240
- if (!options.chart.type) {
1241
- options.chart.type = chartType;
1242
- }
1243
- setFormatOptions(chart, options, chartType);
1244
-
1245
- var series = chart.data;
1246
- for (var i = 0; i < series.length; i++) {
1247
- series[i].name = series[i].name || "Value";
1248
- var data = series[i].data;
1249
- if (chart.xtype === "datetime") {
1250
- for (var j = 0; j < data.length; j++) {
1251
- data[j][0] = data[j][0].getTime();
1252
- }
1253
- } else if (chart.xtype === "number") {
1254
- data.sort(sortByNumberSeries);
1255
- }
1256
- series[i].marker = {symbol: "circle"};
1257
- if (chart.options.points === false) {
1258
- series[i].marker.enabled = false;
1259
- }
1260
- }
1261
-
1262
- this.drawChart(chart, series, options);
1263
- };
1264
-
1265
- defaultExport$1.prototype.renderScatterChart = function renderScatterChart (chart) {
1266
- var options = jsOptions$1(chart, chart.options, {});
1267
- options.chart.type = "scatter";
1268
- this.drawChart(chart, chart.data, options);
1269
- };
1270
-
1271
- defaultExport$1.prototype.renderPieChart = function renderPieChart (chart) {
1272
- var chartOptions = merge(defaultOptions$1, {});
1273
-
1274
- if (chart.options.colors) {
1275
- chartOptions.colors = chart.options.colors;
1276
- }
1277
- if (chart.options.donut) {
1278
- chartOptions.plotOptions = {pie: {innerSize: "50%"}};
1279
- }
1280
-
1281
- if ("legend" in chart.options) {
1282
- hideLegend$1(chartOptions, chart.options.legend);
1283
- }
1284
-
1285
- if (chart.options.title) {
1286
- setTitle$1(chartOptions, chart.options.title);
1287
- }
1288
-
1289
- var options = merge(chartOptions, chart.options.library || {});
1290
- setFormatOptions(chart, options, "pie");
1291
- var series = [{
1292
- type: "pie",
1293
- name: chart.options.label || "Value",
1294
- data: chart.data
1295
- }];
1296
-
1297
- this.drawChart(chart, series, options);
1298
- };
1299
-
1300
- defaultExport$1.prototype.renderColumnChart = function renderColumnChart (chart, chartType) {
1301
- chartType = chartType || "column";
1302
- var series = chart.data;
1303
- var options = jsOptions$1(chart, chart.options);
1304
- var rows = [];
1305
- var categories = [];
1306
- options.chart.type = chartType;
1307
- setFormatOptions(chart, options, chartType);
1308
-
1309
- for (var i = 0; i < series.length; i++) {
1310
- var s = series[i];
1311
-
1312
- for (var j = 0; j < s.data.length; j++) {
1313
- var d = s.data[j];
1314
- if (!rows[d[0]]) {
1315
- rows[d[0]] = new Array(series.length);
1316
- categories.push(d[0]);
1317
- }
1318
- rows[d[0]][i] = d[1];
1319
- }
1320
- }
1321
-
1322
- if (chart.xtype === "number") {
1323
- categories.sort(sortByNumber);
1324
- }
1325
-
1326
- options.xAxis.categories = categories;
1327
-
1328
- var newSeries = [];
1329
- for (var i$1 = 0; i$1 < series.length; i$1++) {
1330
- var d$1 = [];
1331
- for (var j$1 = 0; j$1 < categories.length; j$1++) {
1332
- d$1.push(rows[categories[j$1]][i$1] || 0);
1333
- }
1334
-
1335
- var d2 = {
1336
- name: series[i$1].name || "Value",
1337
- data: d$1
1338
- };
1339
- if (series[i$1].stack) {
1340
- d2.stack = series[i$1].stack;
1341
- }
1342
-
1343
- newSeries.push(d2);
1344
- }
1345
-
1346
- this.drawChart(chart, newSeries, options);
1347
- };
1348
-
1349
- defaultExport$1.prototype.renderBarChart = function renderBarChart (chart) {
1350
- this.renderColumnChart(chart, "bar");
1351
- };
1352
-
1353
- defaultExport$1.prototype.renderAreaChart = function renderAreaChart (chart) {
1354
- this.renderLineChart(chart, "areaspline");
1355
- };
1356
-
1357
- defaultExport$1.prototype.destroy = function destroy (chart) {
1358
- if (chart.chart) {
1359
- chart.chart.destroy();
1360
- }
1361
- };
1362
-
1363
- defaultExport$1.prototype.drawChart = function drawChart (chart, data, options) {
1364
- this.destroy(chart);
1365
- if (chart.destroyed) { return; }
1366
-
1367
- options.chart.renderTo = chart.element.id;
1368
- options.series = data;
1369
-
1370
- if (chart.options.code) {
1371
- window.console.log("new Highcharts.Chart(" + JSON.stringify(options) + ");");
1372
- }
1373
-
1374
- chart.chart = new this.library.Chart(options);
1375
- };
1376
-
1377
- var loaded = {};
1378
- var callbacks = [];
1379
-
1380
- // Set chart options
1381
- var defaultOptions = {
1382
- chartArea: {},
1383
- fontName: "'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif",
1384
- pointSize: 6,
1385
- legend: {
1386
- textStyle: {
1387
- fontSize: 12,
1388
- color: "#444"
1389
- },
1390
- alignment: "center",
1391
- position: "right"
1392
- },
1393
- curveType: "function",
1394
- hAxis: {
1395
- textStyle: {
1396
- color: "#666",
1397
- fontSize: 12
1398
- },
1399
- titleTextStyle: {},
1400
- gridlines: {
1401
- color: "transparent"
1402
- },
1403
- baselineColor: "#ccc",
1404
- viewWindow: {}
1405
- },
1406
- vAxis: {
1407
- textStyle: {
1408
- color: "#666",
1409
- fontSize: 12
1410
- },
1411
- titleTextStyle: {},
1412
- baselineColor: "#ccc",
1413
- viewWindow: {}
1414
- },
1415
- tooltip: {
1416
- textStyle: {
1417
- color: "#666",
1418
- fontSize: 12
1419
- }
1420
- }
1421
- };
1422
-
1423
- function hideLegend(options, legend, hideLegend) {
1424
- if (legend !== undefined) {
1425
- var position;
1426
- if (!legend) {
1427
- position = "none";
1428
- } else if (legend === true) {
1429
- position = "right";
1430
- } else {
1431
- position = legend;
1432
- }
1433
- options.legend.position = position;
1434
- } else if (hideLegend) {
1435
- options.legend.position = "none";
1436
- }
1437
- }
1438
-
1439
- function setTitle(options, title) {
1440
- options.title = title;
1441
- options.titleTextStyle = {color: "#333", fontSize: "20px"};
1442
- }
1443
-
1444
- function setMin(options, min) {
1445
- options.vAxis.viewWindow.min = min;
1446
- }
1447
-
1448
- function setMax(options, max) {
1449
- options.vAxis.viewWindow.max = max;
1450
- }
1451
-
1452
- function setBarMin(options, min) {
1453
- options.hAxis.viewWindow.min = min;
1454
- }
1455
-
1456
- function setBarMax(options, max) {
1457
- options.hAxis.viewWindow.max = max;
1458
- }
1459
-
1460
- function setStacked(options, stacked) {
1461
- options.isStacked = stacked || false;
1462
- }
1463
-
1464
- function setXtitle(options, title) {
1465
- options.hAxis.title = title;
1466
- options.hAxis.titleTextStyle.italic = false;
1467
- }
1468
-
1469
- function setYtitle(options, title) {
1470
- options.vAxis.title = title;
1471
- options.vAxis.titleTextStyle.italic = false;
1472
- }
1473
-
1474
- var jsOptions = jsOptionsFunc(defaultOptions, hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle);
1475
-
1476
- function resize(callback) {
1477
- if (window.attachEvent) {
1478
- window.attachEvent("onresize", callback);
1479
- } else if (window.addEventListener) {
1480
- window.addEventListener("resize", callback, true);
1481
- }
1482
- callback();
1483
- }
1484
-
1485
- var defaultExport = function defaultExport(library) {
1486
- this.name = "google";
1487
- this.library = library;
1488
- };
1489
-
1490
- defaultExport.prototype.renderLineChart = function renderLineChart (chart) {
1491
- var this$1$1 = this;
1492
-
1493
- this.waitForLoaded(chart, function () {
1494
- var chartOptions = {};
1495
-
1496
- if (chart.options.curve === false) {
1497
- chartOptions.curveType = "none";
1498
- }
1499
-
1500
- if (chart.options.points === false) {
1501
- chartOptions.pointSize = 0;
1502
- }
1503
-
1504
- var options = jsOptions(chart, chart.options, chartOptions);
1505
- var data = this$1$1.createDataTable(chart.data, chart.xtype);
1506
-
1507
- this$1$1.drawChart(chart, "LineChart", data, options);
1508
- });
1509
- };
1510
-
1511
- defaultExport.prototype.renderPieChart = function renderPieChart (chart) {
1512
- var this$1$1 = this;
1513
-
1514
- this.waitForLoaded(chart, function () {
1515
- var chartOptions = {
1516
- chartArea: {
1517
- top: "10%",
1518
- height: "80%"
1519
- },
1520
- legend: {}
1521
- };
1522
- if (chart.options.colors) {
1523
- chartOptions.colors = chart.options.colors;
1524
- }
1525
- if (chart.options.donut) {
1526
- chartOptions.pieHole = 0.5;
1527
- }
1528
- if ("legend" in chart.options) {
1529
- hideLegend(chartOptions, chart.options.legend);
1530
- }
1531
- if (chart.options.title) {
1532
- setTitle(chartOptions, chart.options.title);
1533
- }
1534
- var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
1535
-
1536
- var data = new this$1$1.library.visualization.DataTable();
1537
- data.addColumn("string", "");
1538
- data.addColumn("number", "Value");
1539
- data.addRows(chart.data);
1540
-
1541
- this$1$1.drawChart(chart, "PieChart", data, options);
1542
- });
1543
- };
1544
-
1545
- defaultExport.prototype.renderColumnChart = function renderColumnChart (chart) {
1546
- var this$1$1 = this;
1547
-
1548
- this.waitForLoaded(chart, function () {
1549
- var options = jsOptions(chart, chart.options);
1550
- var data = this$1$1.createDataTable(chart.data, chart.xtype);
1551
-
1552
- this$1$1.drawChart(chart, "ColumnChart", data, options);
1553
- });
1554
- };
1555
-
1556
- defaultExport.prototype.renderBarChart = function renderBarChart (chart) {
1557
- var this$1$1 = this;
1558
-
1559
- this.waitForLoaded(chart, function () {
1560
- var chartOptions = {
1561
- hAxis: {
1562
- gridlines: {
1563
- color: "#ccc"
1564
- }
1565
- }
1566
- };
1567
- var options = jsOptionsFunc(defaultOptions, hideLegend, setTitle, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart, chart.options, chartOptions);
1568
- var data = this$1$1.createDataTable(chart.data, chart.xtype);
1569
-
1570
- this$1$1.drawChart(chart, "BarChart", data, options);
1571
- });
1572
- };
1573
-
1574
- defaultExport.prototype.renderAreaChart = function renderAreaChart (chart) {
1575
- var this$1$1 = this;
1576
-
1577
- this.waitForLoaded(chart, function () {
1578
- var chartOptions = {
1579
- isStacked: true,
1580
- pointSize: 0,
1581
- areaOpacity: 0.5
1582
- };
1583
-
1584
- var options = jsOptions(chart, chart.options, chartOptions);
1585
- var data = this$1$1.createDataTable(chart.data, chart.xtype);
1586
-
1587
- this$1$1.drawChart(chart, "AreaChart", data, options);
1588
- });
1589
- };
1590
-
1591
- defaultExport.prototype.renderGeoChart = function renderGeoChart (chart) {
1592
- var this$1$1 = this;
1593
-
1594
- this.waitForLoaded(chart, "geochart", function () {
1595
- var chartOptions = {
1596
- legend: "none",
1597
- colorAxis: {
1598
- colors: chart.options.colors || ["#f6c7b6", "#ce502d"]
1599
- }
1600
- };
1601
- var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
1602
-
1603
- var data = new this$1$1.library.visualization.DataTable();
1604
- data.addColumn("string", "");
1605
- data.addColumn("number", chart.options.label || "Value");
1606
- data.addRows(chart.data);
1607
-
1608
- this$1$1.drawChart(chart, "GeoChart", data, options);
1609
- });
1610
- };
1611
-
1612
- defaultExport.prototype.renderScatterChart = function renderScatterChart (chart) {
1613
- var this$1$1 = this;
1614
-
1615
- this.waitForLoaded(chart, function () {
1616
- var chartOptions = {};
1617
- var options = jsOptions(chart, chart.options, chartOptions);
1618
-
1619
- var series = chart.data;
1620
- var rows2 = [];
1621
- for (var i = 0; i < series.length; i++) {
1622
- series[i].name = series[i].name || "Value";
1623
- var d = series[i].data;
1624
- for (var j = 0; j < d.length; j++) {
1625
- var row = new Array(series.length + 1);
1626
- row[0] = d[j][0];
1627
- row[i + 1] = d[j][1];
1628
- rows2.push(row);
1629
- }
1630
- }
1631
-
1632
- var data = new this$1$1.library.visualization.DataTable();
1633
- data.addColumn("number", "");
1634
- for (var i$1 = 0; i$1 < series.length; i$1++) {
1635
- data.addColumn("number", series[i$1].name);
1636
- }
1637
- data.addRows(rows2);
1638
-
1639
- this$1$1.drawChart(chart, "ScatterChart", data, options);
1640
- });
1641
- };
1642
-
1643
- defaultExport.prototype.renderTimeline = function renderTimeline (chart) {
1644
- var this$1$1 = this;
1645
-
1646
- this.waitForLoaded(chart, "timeline", function () {
1647
- var chartOptions = {
1648
- legend: "none"
1649
- };
1650
-
1651
- if (chart.options.colors) {
1652
- chartOptions.colors = chart.options.colors;
1653
- }
1654
- var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
1655
-
1656
- var data = new this$1$1.library.visualization.DataTable();
1657
- data.addColumn({type: "string", id: "Name"});
1658
- data.addColumn({type: "date", id: "Start"});
1659
- data.addColumn({type: "date", id: "End"});
1660
- data.addRows(chart.data);
1661
-
1662
- chart.element.style.lineHeight = "normal";
1663
-
1664
- this$1$1.drawChart(chart, "Timeline", data, options);
1665
- });
1666
- };
1667
-
1668
- // TODO remove resize events
1669
- defaultExport.prototype.destroy = function destroy (chart) {
1670
- if (chart.chart) {
1671
- chart.chart.clearChart();
1672
- }
1673
- };
1674
-
1675
- defaultExport.prototype.drawChart = function drawChart (chart, type, data, options) {
1676
- this.destroy(chart);
1677
- if (chart.destroyed) { return; }
1678
-
1679
- if (chart.options.code) {
1680
- window.console.log("var data = new google.visualization.DataTable(" + data.toJSON() + ");\nvar chart = new google.visualization." + type + "(element);\nchart.draw(data, " + JSON.stringify(options) + ");");
1681
- }
1682
-
1683
- chart.chart = new this.library.visualization[type](chart.element);
1684
- resize(function () {
1685
- chart.chart.draw(data, options);
1686
- });
1687
- };
1688
-
1689
- defaultExport.prototype.waitForLoaded = function waitForLoaded (chart, pack, callback) {
1690
- var this$1$1 = this;
1691
-
1692
- if (!callback) {
1693
- callback = pack;
1694
- pack = "corechart";
1695
- }
1696
-
1697
- callbacks.push({pack: pack, callback: callback});
1698
-
1699
- if (loaded[pack]) {
1700
- this.runCallbacks();
1701
- } else {
1702
- loaded[pack] = true;
1703
-
1704
- // https://groups.google.com/forum/#!topic/google-visualization-api/fMKJcyA2yyI
1705
- var loadOptions = {
1706
- packages: [pack],
1707
- callback: function () { this$1$1.runCallbacks(); }
1708
- };
1709
- var config = chart.__config();
1710
- if (config.language) {
1711
- loadOptions.language = config.language;
1712
- }
1713
- if (pack === "geochart" && config.mapsApiKey) {
1714
- loadOptions.mapsApiKey = config.mapsApiKey;
1715
- }
1716
-
1717
- this.library.charts.load("current", loadOptions);
1718
- }
1719
- };
1720
-
1721
- defaultExport.prototype.runCallbacks = function runCallbacks () {
1722
- for (var i = 0; i < callbacks.length; i++) {
1723
- var cb = callbacks[i];
1724
- var call = this.library.visualization && ((cb.pack === "corechart" && this.library.visualization.LineChart) || (cb.pack === "timeline" && this.library.visualization.Timeline) || (cb.pack === "geochart" && this.library.visualization.GeoChart));
1725
- if (call) {
1726
- cb.callback();
1727
- callbacks.splice(i, 1);
1728
- i--;
1729
- }
1730
- }
1731
- };
1732
-
1733
- // cant use object as key
1734
- defaultExport.prototype.createDataTable = function createDataTable (series, columnType) {
1735
- var rows = [];
1736
- var sortedLabels = [];
1737
- for (var i = 0; i < series.length; i++) {
1738
- var s = series[i];
1739
- series[i].name = series[i].name || "Value";
1740
-
1741
- for (var j = 0; j < s.data.length; j++) {
1742
- var d = s.data[j];
1743
- var key = columnType === "datetime" ? d[0].getTime() : d[0];
1744
- if (!rows[key]) {
1745
- rows[key] = new Array(series.length);
1746
- sortedLabels.push(key);
1747
- }
1748
- rows[key][i] = d[1];
1749
- }
1750
- }
1751
-
1752
- var rows2 = [];
1753
- var values = [];
1754
- for (var j$1 = 0; j$1 < sortedLabels.length; j$1++) {
1755
- var i$1 = sortedLabels[j$1];
1756
- var value = (void 0);
1757
- if (columnType === "datetime") {
1758
- value = new Date(i$1);
1759
- values.push(value);
1760
- } else {
1761
- value = i$1;
1762
- }
1763
- rows2.push([value].concat(rows[i$1]));
1764
- }
1765
-
1766
- var day = true;
1767
- if (columnType === "datetime") {
1768
- rows2.sort(sortByTime);
1769
-
1770
- var timeUnit = calculateTimeUnit(values, true);
1771
- day = isDay(timeUnit);
1772
- } else if (columnType === "number") {
1773
- rows2.sort(sortByNumberSeries);
1774
-
1775
- for (var i$2 = 0; i$2 < rows2.length; i$2++) {
1776
- rows2[i$2][0] = toStr(rows2[i$2][0]);
1777
- }
1778
-
1779
- columnType = "string";
1780
- }
1781
-
1782
- // create datatable
1783
- var data = new this.library.visualization.DataTable();
1784
- columnType = columnType === "datetime" && day ? "date" : columnType;
1785
- data.addColumn(columnType, "");
1786
- for (var i$3 = 0; i$3 < series.length; i$3++) {
1787
- data.addColumn("number", series[i$3].name);
1788
- }
1789
- data.addRows(rows2);
1790
-
1791
- return data;
1792
- };
1793
-
1794
- var adapters = [];
1795
-
1796
- function getAdapterType(library) {
1797
- if (library) {
1798
- if (library.product === "Highcharts") {
1799
- return defaultExport$1;
1800
- } else if (library.charts) {
1801
- return defaultExport;
1802
- } else if (isFunction(library)) {
1803
- return defaultExport$2;
1804
- }
1805
- }
1806
- throw new Error("Unknown adapter");
1807
- }
1808
-
1809
- function addAdapter(library) {
1810
- var adapterType = getAdapterType(library);
1811
-
1812
- for (var i = 0; i < adapters.length; i++) {
1813
- if (adapters[i].library === library) {
1814
- return;
1815
- }
1816
- }
1817
-
1818
- adapters.push(new adapterType(library));
1819
- }
1820
-
1821
- function loadAdapters() {
1822
- if ("Chart" in window) {
1823
- addAdapter(window.Chart);
1824
- }
1825
-
1826
- if ("Highcharts" in window) {
1827
- addAdapter(window.Highcharts);
1828
- }
1829
-
1830
- if (window.google && window.google.charts) {
1831
- addAdapter(window.google);
1832
- }
1833
- }
1834
-
1835
- // TODO remove chartType if cross-browser way
1836
- // to get the name of the chart class
1837
- function callAdapter(chartType, chart) {
1838
- var fnName = "render" + chartType;
1839
- var adapterName = chart.options.adapter;
1840
-
1841
- loadAdapters();
1842
-
1843
- for (var i = 0; i < adapters.length; i++) {
1844
- var adapter = adapters[i];
1845
- if ((!adapterName || adapterName === adapter.name) && isFunction(adapter[fnName])) {
1846
- chart.adapter = adapter.name;
1847
- chart.__adapterObject = adapter;
1848
- return adapter[fnName](chart);
1849
- }
1850
- }
1851
-
1852
- if (adapters.length > 0) {
1853
- throw new Error("No charting library found for " + chartType);
1854
- } else {
1855
- throw new Error("No charting libraries found - be sure to include one before your charts");
1856
- }
1857
- }
1858
-
1859
- var Chartkick = {
1860
- charts: {},
1861
- configure: function (options) {
1862
- for (var key in options) {
1863
- if (Object.prototype.hasOwnProperty.call(options, key)) {
1864
- Chartkick.config[key] = options[key];
1865
- }
1866
- }
1867
- },
1868
- setDefaultOptions: function (opts) {
1869
- Chartkick.options = opts;
1870
- },
1871
- eachChart: function (callback) {
1872
- for (var chartId in Chartkick.charts) {
1873
- if (Object.prototype.hasOwnProperty.call(Chartkick.charts, chartId)) {
1874
- callback(Chartkick.charts[chartId]);
1875
- }
1876
- }
1877
- },
1878
- destroyAll: function () {
1879
- for (var chartId in Chartkick.charts) {
1880
- if (Object.prototype.hasOwnProperty.call(Chartkick.charts, chartId)) {
1881
- Chartkick.charts[chartId].destroy();
1882
- delete Chartkick.charts[chartId];
1883
- }
1884
- }
1885
- },
1886
- config: {},
1887
- options: {},
1888
- adapters: adapters,
1889
- addAdapter: addAdapter,
1890
- use: function (adapter) {
1891
- addAdapter(adapter);
1892
- return Chartkick;
1893
- }
1894
- };
1895
-
1896
- function formatSeriesBubble(data) {
1897
- var r = [];
1898
- for (var i = 0; i < data.length; i++) {
1899
- r.push([toFloat(data[i][0]), toFloat(data[i][1]), toFloat(data[i][2])]);
1900
- }
1901
- return r;
1902
- }
1903
-
1904
- // casts data to proper type
1905
- // sorting is left to adapters
1906
- function formatSeriesData(data, keyType) {
1907
- if (keyType === "bubble") {
1908
- return formatSeriesBubble(data);
1909
- }
1910
-
1911
- var keyFunc;
1912
- if (keyType === "number") {
1913
- keyFunc = toFloat;
1914
- } else if (keyType === "datetime") {
1915
- keyFunc = toDate;
1916
- } else {
1917
- keyFunc = toStr;
1918
- }
1919
-
1920
- var r = [];
1921
- for (var i = 0; i < data.length; i++) {
1922
- r.push([keyFunc(data[i][0]), toFloat(data[i][1])]);
1923
- }
1924
- return r;
1925
- }
1926
-
1927
- function detectXType(series, noDatetime, options) {
1928
- if (dataEmpty(series)) {
1929
- if ((options.xmin || options.xmax) && (!options.xmin || isDate(options.xmin)) && (!options.xmax || isDate(options.xmax))) {
1930
- return "datetime";
1931
- } else {
1932
- return "number";
1933
- }
1934
- } else if (detectXTypeWithFunction(series, isNumber)) {
1935
- return "number";
1936
- } else if (!noDatetime && detectXTypeWithFunction(series, isDate)) {
1937
- return "datetime";
1938
- } else {
1939
- return "string";
1940
- }
1941
- }
1942
-
1943
- function detectXTypeWithFunction(series, func) {
1944
- for (var i = 0; i < series.length; i++) {
1945
- var data = toArr(series[i].data);
1946
- for (var j = 0; j < data.length; j++) {
1947
- if (!func(data[j][0])) {
1948
- return false;
1949
- }
1950
- }
1951
- }
1952
- return true;
1953
- }
1954
-
1955
- // creates a shallow copy of each element of the array
1956
- // elements are expected to be objects
1957
- function copySeries(series) {
1958
- var newSeries = [];
1959
- for (var i = 0; i < series.length; i++) {
1960
- var copy = {};
1961
- for (var j in series[i]) {
1962
- if (Object.prototype.hasOwnProperty.call(series[i], j)) {
1963
- copy[j] = series[i][j];
1964
- }
1965
- }
1966
- newSeries.push(copy);
1967
- }
1968
- return newSeries;
1969
- }
1970
-
1971
- function processSeries(chart, keyType, noDatetime) {
1972
- var opts = chart.options;
1973
- var series = chart.rawData;
1974
-
1975
- // see if one series or multiple
1976
- chart.singleSeriesFormat = !isArray(series) || !isPlainObject(series[0]);
1977
- if (chart.singleSeriesFormat) {
1978
- series = [{name: opts.label, data: series}];
1979
- }
1980
-
1981
- // convert to array
1982
- // must come before dataEmpty check
1983
- series = copySeries(series);
1984
- for (var i = 0; i < series.length; i++) {
1985
- series[i].data = toArr(series[i].data);
1986
- }
1987
-
1988
- chart.xtype = keyType || (opts.discrete ? "string" : detectXType(series, noDatetime, opts));
1989
-
1990
- // right format
1991
- for (var i$1 = 0; i$1 < series.length; i$1++) {
1992
- series[i$1].data = formatSeriesData(series[i$1].data, chart.xtype);
1993
- }
1994
-
1995
- return series;
1996
- }
1997
-
1998
- function processSimple(chart) {
1999
- var perfectData = toArr(chart.rawData);
2000
- for (var i = 0; i < perfectData.length; i++) {
2001
- perfectData[i] = [toStr(perfectData[i][0]), toFloat(perfectData[i][1])];
2002
- }
2003
- return perfectData;
2004
- }
2005
-
2006
- function dataEmpty(data, chartType) {
2007
- if (chartType === "PieChart" || chartType === "GeoChart" || chartType === "Timeline") {
2008
- return data.length === 0;
2009
- } else {
2010
- for (var i = 0; i < data.length; i++) {
2011
- if (data[i].data.length > 0) {
2012
- return false;
2013
- }
2014
- }
2015
- return true;
2016
- }
2017
- }
2018
-
2019
- function addDownloadButton(chart) {
2020
- var download = chart.options.download;
2021
- if (download === true) {
2022
- download = {};
2023
- } else if (typeof download === "string") {
2024
- download = {filename: download};
2025
- }
2026
-
2027
- var link = document.createElement("a");
2028
- link.download = download.filename || "chart.png";
2029
- link.style.position = "absolute";
2030
- link.style.top = "20px";
2031
- link.style.right = "20px";
2032
- link.style.zIndex = 1000;
2033
- link.style.lineHeight = "20px";
2034
- link.target = "_blank"; // for safari
2035
-
2036
- var image = document.createElement("img");
2037
- // icon from Font Awesome, modified to set fill color
2038
- var svg = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path fill=\"#CCCCCC\" d=\"M344 240h-56L287.1 152c0-13.25-10.75-24-24-24h-16C234.7 128 223.1 138.8 223.1 152L224 240h-56c-9.531 0-18.16 5.656-22 14.38C142.2 263.1 143.9 273.3 150.4 280.3l88.75 96C243.7 381.2 250.1 384 256.8 384c7.781-.3125 13.25-2.875 17.75-7.844l87.25-96c6.406-7.031 8.031-17.19 4.188-25.88S353.5 240 344 240zM256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 464c-114.7 0-208-93.31-208-208S141.3 48 256 48s208 93.31 208 208S370.7 464 256 464z\"/></svg>";
2039
- image.src = "data:image/svg+xml;utf8," + (encodeURIComponent(svg));
2040
- image.alt = "Download";
2041
- image.style.width = "20px";
2042
- image.style.height = "20px";
2043
- image.style.border = "none";
2044
- link.appendChild(image);
2045
-
2046
- var element = chart.element;
2047
- element.style.position = "relative";
2048
-
2049
- chart.__downloadAttached = true;
2050
-
2051
- // mouseenter
2052
- chart.__enterEvent = element.addEventListener("mouseover", function (e) {
2053
- var related = e.relatedTarget;
2054
- // check download option again to ensure it wasn't changed
2055
- if ((!related || (related !== this && !this.contains(related))) && chart.options.download) {
2056
- link.href = chart.toImage(download);
2057
- element.appendChild(link);
2058
- }
2059
- });
2060
-
2061
- // mouseleave
2062
- chart.__leaveEvent = element.addEventListener("mouseout", function (e) {
2063
- var related = e.relatedTarget;
2064
- if (!related || (related !== this && !this.contains(related))) {
2065
- if (link.parentNode) {
2066
- link.parentNode.removeChild(link);
2067
- }
2068
- }
2069
- });
2070
- }
2071
-
2072
- var pendingRequests = [];
2073
- var runningRequests = 0;
2074
- var maxRequests = 4;
2075
-
2076
- function pushRequest(url, success, error) {
2077
- pendingRequests.push([url, success, error]);
2078
- runNext();
2079
- }
2080
-
2081
- function runNext() {
2082
- if (runningRequests < maxRequests) {
2083
- var request = pendingRequests.shift();
2084
- if (request) {
2085
- runningRequests++;
2086
- getJSON(request[0], request[1], request[2]);
2087
- runNext();
2088
- }
2089
- }
2090
- }
2091
-
2092
- function requestComplete() {
2093
- runningRequests--;
2094
- runNext();
2095
- }
2096
-
2097
- function getJSON(url, success, error) {
2098
- var xhr = new XMLHttpRequest();
2099
- xhr.open("GET", url, true);
2100
- xhr.setRequestHeader("Content-Type", "application/json");
2101
- xhr.onload = function () {
2102
- requestComplete();
2103
- if (xhr.status === 200) {
2104
- success(JSON.parse(xhr.responseText));
2105
- } else {
2106
- error(xhr.statusText);
2107
- }
2108
- };
2109
- xhr.send();
2110
- }
2111
-
2112
- // helpers
2113
-
2114
- function setText(element, text) {
2115
- element.textContent = text;
2116
- }
2117
-
2118
- // TODO remove prefix for all messages
2119
- function chartError(element, message, noPrefix) {
2120
- if (!noPrefix) {
2121
- message = "Error Loading Chart: " + message;
2122
- }
2123
- setText(element, message);
2124
- element.style.color = "#ff0000";
2125
- }
2126
-
2127
- function errorCatcher(chart) {
2128
- try {
2129
- chart.__render();
2130
- } catch (err) {
2131
- chartError(chart.element, err.message);
2132
- throw err;
2133
- }
2134
- }
2135
-
2136
- function fetchDataSource(chart, dataSource, showLoading) {
2137
- // only show loading message for urls and callbacks
2138
- if (showLoading && chart.options.loading && (typeof dataSource === "string" || typeof dataSource === "function")) {
2139
- setText(chart.element, chart.options.loading);
2140
- }
2141
-
2142
- if (typeof dataSource === "string") {
2143
- pushRequest(dataSource, function (data) {
2144
- chart.rawData = data;
2145
- errorCatcher(chart);
2146
- }, function (message) {
2147
- chartError(chart.element, message);
2148
- });
2149
- } else if (typeof dataSource === "function") {
2150
- try {
2151
- dataSource(function (data) {
2152
- chart.rawData = data;
2153
- errorCatcher(chart);
2154
- }, function (message) {
2155
- chartError(chart.element, message, true);
2156
- });
2157
- } catch (err) {
2158
- chartError(chart.element, err, true);
2159
- }
2160
- } else {
2161
- chart.rawData = dataSource;
2162
- errorCatcher(chart);
2163
- }
2164
- }
2165
-
2166
- function renderChart(chartType, chart) {
2167
- if (dataEmpty(chart.data, chartType)) {
2168
- var message = chart.options.empty || (chart.options.messages && chart.options.messages.empty) || "No data";
2169
- setText(chart.element, message);
2170
- } else {
2171
- callAdapter(chartType, chart);
2172
- // TODO add downloadSupported method to adapter
2173
- if (chart.options.download && !chart.__downloadAttached && chart.adapter === "chartjs") {
2174
- addDownloadButton(chart);
2175
- }
2176
- }
2177
- }
2178
-
2179
- function getElement(element) {
2180
- if (typeof element === "string") {
2181
- var elementId = element;
2182
- element = document.getElementById(element);
2183
- if (!element) {
2184
- throw new Error("No element with id " + elementId);
2185
- }
2186
- }
2187
- return element;
2188
- }
2189
-
2190
- // define classes
2191
-
2192
- var Chart = function Chart(element, dataSource, options) {
2193
- this.element = getElement(element);
2194
- this.options = merge(Chartkick.options, options || {});
2195
- this.dataSource = dataSource;
2196
-
2197
- // TODO handle charts without an id for eachChart and destroyAll
2198
- if (this.element.id) {
2199
- Chartkick.charts[this.element.id] = this;
2200
- }
2201
-
2202
- fetchDataSource(this, dataSource, true);
2203
-
2204
- if (this.options.refresh) {
2205
- this.startRefresh();
2206
- }
2207
- };
2208
-
2209
- Chart.prototype.getElement = function getElement () {
2210
- return this.element;
2211
- };
2212
-
2213
- Chart.prototype.getDataSource = function getDataSource () {
2214
- return this.dataSource;
2215
- };
2216
-
2217
- Chart.prototype.getData = function getData () {
2218
- return this.data;
2219
- };
2220
-
2221
- Chart.prototype.getOptions = function getOptions () {
2222
- return this.options;
2223
- };
2224
-
2225
- Chart.prototype.getChartObject = function getChartObject () {
2226
- return this.chart;
2227
- };
2228
-
2229
- Chart.prototype.getAdapter = function getAdapter () {
2230
- return this.adapter;
2231
- };
2232
-
2233
- Chart.prototype.updateData = function updateData (dataSource, options) {
2234
- this.dataSource = dataSource;
2235
- if (options) {
2236
- this.__updateOptions(options);
2237
- }
2238
- fetchDataSource(this, dataSource, true);
2239
- };
2240
-
2241
- Chart.prototype.setOptions = function setOptions (options) {
2242
- this.__updateOptions(options);
2243
- this.redraw();
2244
- };
2245
-
2246
- Chart.prototype.redraw = function redraw () {
2247
- fetchDataSource(this, this.rawData);
2248
- };
2249
-
2250
- Chart.prototype.refreshData = function refreshData () {
2251
- if (typeof this.dataSource === "string") {
2252
- // prevent browser from caching
2253
- var sep = this.dataSource.indexOf("?") === -1 ? "?" : "&";
2254
- var url = this.dataSource + sep + "_=" + (new Date()).getTime();
2255
- fetchDataSource(this, url);
2256
- } else if (typeof this.dataSource === "function") {
2257
- fetchDataSource(this, this.dataSource);
2258
- }
2259
- };
2260
-
2261
- Chart.prototype.startRefresh = function startRefresh () {
2262
- var this$1$1 = this;
2263
-
2264
- var refresh = this.options.refresh;
2265
-
2266
- if (refresh && typeof this.dataSource !== "string" && typeof this.dataSource !== "function") {
2267
- throw new Error("Data source must be a URL or callback for refresh");
2268
- }
2269
-
2270
- if (!this.intervalId) {
2271
- if (refresh) {
2272
- this.intervalId = setInterval(function () {
2273
- this$1$1.refreshData();
2274
- }, refresh * 1000);
2275
- } else {
2276
- throw new Error("No refresh interval");
2277
- }
2278
- }
2279
- };
2280
-
2281
- Chart.prototype.stopRefresh = function stopRefresh () {
2282
- if (this.intervalId) {
2283
- clearInterval(this.intervalId);
2284
- this.intervalId = null;
2285
- }
2286
- };
2287
-
2288
- Chart.prototype.toImage = function toImage (download) {
2289
- // TODO move logic to adapter
2290
- if (this.adapter === "chartjs") {
2291
- if (download && download.background && download.background !== "transparent") {
2292
- // https://stackoverflow.com/questions/30464750/chartjs-line-chart-set-background-color
2293
- var canvas = this.chart.canvas;
2294
- var ctx = this.chart.ctx;
2295
- var tmpCanvas = document.createElement("canvas");
2296
- var tmpCtx = tmpCanvas.getContext("2d");
2297
- tmpCanvas.width = ctx.canvas.width;
2298
- tmpCanvas.height = ctx.canvas.height;
2299
- tmpCtx.fillStyle = download.background;
2300
- tmpCtx.fillRect(0, 0, tmpCanvas.width, tmpCanvas.height);
2301
- tmpCtx.drawImage(canvas, 0, 0);
2302
- return tmpCanvas.toDataURL("image/png");
2303
- } else {
2304
- return this.chart.toBase64Image();
2305
- }
2306
- } else {
2307
- throw new Error("Feature only available for Chart.js");
2308
- }
2309
- };
2310
-
2311
- Chart.prototype.destroy = function destroy () {
2312
- this.destroyed = true;
2313
- this.stopRefresh();
2314
-
2315
- if (this.__adapterObject) {
2316
- this.__adapterObject.destroy(this);
2317
- }
2318
-
2319
- if (this.__enterEvent) {
2320
- this.element.removeEventListener("mouseover", this.__enterEvent);
2321
- }
2322
-
2323
- if (this.__leaveEvent) {
2324
- this.element.removeEventListener("mouseout", this.__leaveEvent);
2325
- }
2326
- };
2327
-
2328
- Chart.prototype.__updateOptions = function __updateOptions (options) {
2329
- var updateRefresh = options.refresh && options.refresh !== this.options.refresh;
2330
- this.options = merge(Chartkick.options, options);
2331
- if (updateRefresh) {
2332
- this.stopRefresh();
2333
- this.startRefresh();
2334
- }
2335
- };
2336
-
2337
- Chart.prototype.__render = function __render () {
2338
- this.data = this.__processData();
2339
- renderChart(this.__chartName(), this);
2340
- };
2341
-
2342
- Chart.prototype.__config = function __config () {
2343
- return Chartkick.config;
2344
- };
2345
-
2346
- var LineChart = /*@__PURE__*/(function (Chart) {
2347
- function LineChart () {
2348
- Chart.apply(this, arguments);
2349
- }
2350
-
2351
- if ( Chart ) LineChart.__proto__ = Chart;
2352
- LineChart.prototype = Object.create( Chart && Chart.prototype );
2353
- LineChart.prototype.constructor = LineChart;
2354
-
2355
- LineChart.prototype.__processData = function __processData () {
2356
- return processSeries(this);
2357
- };
2358
-
2359
- LineChart.prototype.__chartName = function __chartName () {
2360
- return "LineChart";
2361
- };
2362
-
2363
- return LineChart;
2364
- }(Chart));
2365
-
2366
- var PieChart = /*@__PURE__*/(function (Chart) {
2367
- function PieChart () {
2368
- Chart.apply(this, arguments);
2369
- }
2370
-
2371
- if ( Chart ) PieChart.__proto__ = Chart;
2372
- PieChart.prototype = Object.create( Chart && Chart.prototype );
2373
- PieChart.prototype.constructor = PieChart;
2374
-
2375
- PieChart.prototype.__processData = function __processData () {
2376
- return processSimple(this);
2377
- };
2378
-
2379
- PieChart.prototype.__chartName = function __chartName () {
2380
- return "PieChart";
2381
- };
2382
-
2383
- return PieChart;
2384
- }(Chart));
2385
-
2386
- var ColumnChart = /*@__PURE__*/(function (Chart) {
2387
- function ColumnChart () {
2388
- Chart.apply(this, arguments);
2389
- }
2390
-
2391
- if ( Chart ) ColumnChart.__proto__ = Chart;
2392
- ColumnChart.prototype = Object.create( Chart && Chart.prototype );
2393
- ColumnChart.prototype.constructor = ColumnChart;
2394
-
2395
- ColumnChart.prototype.__processData = function __processData () {
2396
- return processSeries(this, null, true);
2397
- };
2398
-
2399
- ColumnChart.prototype.__chartName = function __chartName () {
2400
- return "ColumnChart";
2401
- };
2402
-
2403
- return ColumnChart;
2404
- }(Chart));
2405
-
2406
- var BarChart = /*@__PURE__*/(function (Chart) {
2407
- function BarChart () {
2408
- Chart.apply(this, arguments);
2409
- }
2410
-
2411
- if ( Chart ) BarChart.__proto__ = Chart;
2412
- BarChart.prototype = Object.create( Chart && Chart.prototype );
2413
- BarChart.prototype.constructor = BarChart;
2414
-
2415
- BarChart.prototype.__processData = function __processData () {
2416
- return processSeries(this, null, true);
2417
- };
2418
-
2419
- BarChart.prototype.__chartName = function __chartName () {
2420
- return "BarChart";
2421
- };
2422
-
2423
- return BarChart;
2424
- }(Chart));
2425
-
2426
- var AreaChart = /*@__PURE__*/(function (Chart) {
2427
- function AreaChart () {
2428
- Chart.apply(this, arguments);
2429
- }
2430
-
2431
- if ( Chart ) AreaChart.__proto__ = Chart;
2432
- AreaChart.prototype = Object.create( Chart && Chart.prototype );
2433
- AreaChart.prototype.constructor = AreaChart;
2434
-
2435
- AreaChart.prototype.__processData = function __processData () {
2436
- return processSeries(this);
2437
- };
2438
-
2439
- AreaChart.prototype.__chartName = function __chartName () {
2440
- return "AreaChart";
2441
- };
2442
-
2443
- return AreaChart;
2444
- }(Chart));
2445
-
2446
- var GeoChart = /*@__PURE__*/(function (Chart) {
2447
- function GeoChart () {
2448
- Chart.apply(this, arguments);
2449
- }
2450
-
2451
- if ( Chart ) GeoChart.__proto__ = Chart;
2452
- GeoChart.prototype = Object.create( Chart && Chart.prototype );
2453
- GeoChart.prototype.constructor = GeoChart;
2454
-
2455
- GeoChart.prototype.__processData = function __processData () {
2456
- return processSimple(this);
2457
- };
2458
-
2459
- GeoChart.prototype.__chartName = function __chartName () {
2460
- return "GeoChart";
2461
- };
2462
-
2463
- return GeoChart;
2464
- }(Chart));
2465
-
2466
- var ScatterChart = /*@__PURE__*/(function (Chart) {
2467
- function ScatterChart () {
2468
- Chart.apply(this, arguments);
2469
- }
2470
-
2471
- if ( Chart ) ScatterChart.__proto__ = Chart;
2472
- ScatterChart.prototype = Object.create( Chart && Chart.prototype );
2473
- ScatterChart.prototype.constructor = ScatterChart;
2474
-
2475
- ScatterChart.prototype.__processData = function __processData () {
2476
- return processSeries(this, "number");
2477
- };
2478
-
2479
- ScatterChart.prototype.__chartName = function __chartName () {
2480
- return "ScatterChart";
2481
- };
2482
-
2483
- return ScatterChart;
2484
- }(Chart));
2485
-
2486
- var BubbleChart = /*@__PURE__*/(function (Chart) {
2487
- function BubbleChart () {
2488
- Chart.apply(this, arguments);
2489
- }
2490
-
2491
- if ( Chart ) BubbleChart.__proto__ = Chart;
2492
- BubbleChart.prototype = Object.create( Chart && Chart.prototype );
2493
- BubbleChart.prototype.constructor = BubbleChart;
2494
-
2495
- BubbleChart.prototype.__processData = function __processData () {
2496
- return processSeries(this, "bubble");
2497
- };
2498
-
2499
- BubbleChart.prototype.__chartName = function __chartName () {
2500
- return "BubbleChart";
2501
- };
2502
-
2503
- return BubbleChart;
2504
- }(Chart));
2505
-
2506
- var Timeline = /*@__PURE__*/(function (Chart) {
2507
- function Timeline () {
2508
- Chart.apply(this, arguments);
2509
- }
2510
-
2511
- if ( Chart ) Timeline.__proto__ = Chart;
2512
- Timeline.prototype = Object.create( Chart && Chart.prototype );
2513
- Timeline.prototype.constructor = Timeline;
2514
-
2515
- Timeline.prototype.__processData = function __processData () {
2516
- var data = this.rawData;
2517
- for (var i = 0; i < data.length; i++) {
2518
- data[i][1] = toDate(data[i][1]);
2519
- data[i][2] = toDate(data[i][2]);
2520
- }
2521
- return data;
2522
- };
2523
-
2524
- Timeline.prototype.__chartName = function __chartName () {
2525
- return "Timeline";
2526
- };
2527
-
2528
- return Timeline;
2529
- }(Chart));
2530
-
2531
- Chartkick.LineChart = LineChart;
2532
- Chartkick.PieChart = PieChart;
2533
- Chartkick.ColumnChart = ColumnChart;
2534
- Chartkick.BarChart = BarChart;
2535
- Chartkick.AreaChart = AreaChart;
2536
- Chartkick.GeoChart = GeoChart;
2537
- Chartkick.ScatterChart = ScatterChart;
2538
- Chartkick.BubbleChart = BubbleChart;
2539
- Chartkick.Timeline = Timeline;
2540
-
2541
- // not ideal, but allows for simpler integration
2542
- if (typeof window !== "undefined" && !window.Chartkick) {
2543
- window.Chartkick = Chartkick;
2544
-
2545
- // clean up previous charts before Turbolinks loads new page
2546
- document.addEventListener("turbolinks:before-render", function () {
2547
- if (Chartkick.config.autoDestroy !== false) {
2548
- Chartkick.destroyAll();
2549
- }
2550
- });
2551
-
2552
- // clean up previous charts before Turbo loads new page
2553
- document.addEventListener("turbo:before-render", function () {
2554
- if (Chartkick.config.autoDestroy !== false) {
2555
- Chartkick.destroyAll();
2556
- }
2557
- });
2558
-
2559
- // use setTimeout so charting library can come later in same JS file
2560
- setTimeout(function () {
2561
- window.dispatchEvent(new Event("chartkick:load"));
2562
- }, 0);
2563
- }
2564
-
2565
- // backwards compatibility for esm require
2566
- Chartkick.default = Chartkick;
2567
-
2568
- return Chartkick;
2569
-
2570
- }));