chartkick 2.3.5 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of chartkick might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d37a995b1d870a7e93be5d5eb338d163e1b42653304baab7bad889aff6f655fe
4
- data.tar.gz: 9c5495a74d4e6c03b199a263556d9dcee91ee4e0c87fb7694851971068a817e2
3
+ metadata.gz: ad30daf6a29dc9c07b5f6f7df88224d459bbcf285474178871beb146995856d8
4
+ data.tar.gz: 24404117c464a9b34d85d33a5961185b7ef519dfb70ad53cb921555a0fc2769c
5
5
  SHA512:
6
- metadata.gz: e2e350cf8f342a7d55bfbc0a6581c92e25b4a59442719ef12aa32400ba9610b137360a10535a96afa049025a739235f28b00ade4299ad1cad5d2f9525ea1517d
7
- data.tar.gz: 3de86761cb1f9e63d71589640827cc8391c668b398f9e49cdf4f4029351850181cc4e8197d8c6c341b6e7d79147ee01d96be6cf72b55ccca1f1395f4504d951e
6
+ metadata.gz: 888b38d483647415c0be6a1201e47110989274c592c1456bda39e2c5be558155c17d78218c55848b86c4249677763d65e48ac500aa1f9542b9a329dedc81a995
7
+ data.tar.gz: e4caaf76d598629d0aad188718a1b0cc4dbe8b5cbe0257d2b727d3736eaca6ba9e000f83c1ae75469ca5dba34aebe8e3f538b74c7968bddc97a2d938b188bd2e
@@ -1,3 +1,17 @@
1
+ ## 3.0.0
2
+
3
+ - Updated Chartkick.js to 3.0.0
4
+ - Added `code` option
5
+ - Added support for `nonce: true`
6
+
7
+ Breaking changes
8
+
9
+ - Removed support for Rails < 4.2
10
+ - Removed chartkick.js from asset precompile (no longer needed)
11
+ - Removed `xtype` option - numeric axes are automatically detected
12
+ - Removed `window.Chartkick = {...}` way to set config - use `Chartkick.configure` instead
13
+ - Removed support for the Google Charts jsapi loader - use loader.js instead
14
+
1
15
  ## 2.3.5
2
16
 
3
17
  - Updated Chartkick.js to 2.3.6
@@ -2,17 +2,15 @@
2
2
 
3
3
  First, thanks for wanting to contribute. You’re awesome! :heart:
4
4
 
5
- ## Questions
5
+ ## Help
6
6
 
7
- Use [Stack Overflow](https://stackoverflow.com/) with the tag `chartkick`.
7
+ We’re not able to provide support through GitHub Issues. If you’re looking for help with your code, try posting on [Stack Overflow](https://stackoverflow.com/).
8
8
 
9
- ## Feature Requests
9
+ All features should be documented. If you don’t see a feature in the docs, assume it doesn’t exist.
10
10
 
11
- Create an issue. Start the title with `[Idea]`.
11
+ ## Bugs
12
12
 
13
- ## Issues
14
-
15
- Think you’ve discovered an issue?
13
+ Think you’ve discovered a bug?
16
14
 
17
15
  1. Search existing issues to see if it’s been reported.
18
16
  2. Try the `master` branch to make sure it hasn’t been fixed.
@@ -27,6 +25,10 @@ If the above steps don’t help, create an issue. Include:
27
25
  - JavaScript rendered by Chartkick
28
26
  - Complete backtraces for exceptions
29
27
 
28
+ ## New Features
29
+
30
+ If you’d like to discuss a new feature, create an issue and start the title with `[Idea]`.
31
+
30
32
  ## Pull Requests
31
33
 
32
34
  Fork the project and create a pull request. A few tips:
data/README.md CHANGED
@@ -284,12 +284,22 @@ For multiple series, use the format
284
284
  ] %>
285
285
  ```
286
286
 
287
- Times can be a time, a timestamp, or a string (strings are parsed)
287
+ Times can be a time or a string (strings are parsed)
288
288
 
289
289
  ```erb
290
- <%= line_chart({20.day.ago => 5, 1368174456 => 4, "2013-05-07 00:00:00 UTC" => 7}) %>
290
+ <%= line_chart({20.day.ago => 5, "2013-05-07 00:00:00 UTC" => 7}) %>
291
291
  ```
292
292
 
293
+ ### Code
294
+
295
+ If you want to use the charting library directly, get the code with:
296
+
297
+ ```erb
298
+ <%= line_chart data, code: true %>
299
+ ```
300
+
301
+ The code will be logged to the JavaScript console.
302
+
293
303
  ### Download Charts
294
304
 
295
305
  *Chart.js only*
@@ -469,6 +479,10 @@ Chartkick.eachChart( function(chart) {
469
479
  })
470
480
  ```
471
481
 
482
+ ## Content Security Policy (CSP)
483
+
484
+ Check out [how to configure CSP](https://github.com/ankane/chartkick/blob/master/guides/Content-Security-Policy.md)
485
+
472
486
  ## No Ruby? No Problem
473
487
 
474
488
  Check out [chartkick.js](https://github.com/ankane/chartkick.js)
@@ -481,6 +495,16 @@ Check out [chartkick.js](https://github.com/ankane/chartkick.js)
481
495
 
482
496
  ## Upgrading
483
497
 
498
+ ### 3.0
499
+
500
+ Breaking changes
501
+
502
+ - Removed support for Rails < 4.2
503
+ - Removed chartkick.js from asset precompile (no longer needed)
504
+ - Removed `xtype` option - numeric axes are automatically detected
505
+ - Removed `window.Chartkick = {...}` way to set config - use `Chartkick.configure` instead
506
+ - Removed support for the Google Charts jsapi loader - use loader.js instead
507
+
484
508
  ### 2.0
485
509
 
486
510
  Breaking changes
@@ -1,8 +1,16 @@
1
- require "chartkick/version"
2
1
  require "chartkick/helper"
3
- require "chartkick/rails" if defined?(Rails)
2
+ require "chartkick/version"
3
+
4
+ # integrations
5
+ require "chartkick/engine" if defined?(Rails)
4
6
  require "chartkick/sinatra" if defined?(Sinatra)
5
7
 
8
+ if defined?(ActiveSupport)
9
+ ActiveSupport.on_load(:action_view) do
10
+ include Chartkick::Helper
11
+ end
12
+ end
13
+
6
14
  module Chartkick
7
15
  class << self
8
16
  attr_accessor :content_for
@@ -15,9 +23,21 @@ end
15
23
  # use Enumerable so it can be called on arrays
16
24
  module Enumerable
17
25
  def chart_json
18
- if is_a?(Hash) && (key = keys.first) && key.is_a?(Array) && key.size == 2
19
- group_by { |k, _v| k[0] }.map do |name, data|
20
- {name: name, data: data.map { |k, v| [k[1], v] }}
26
+ if is_a?(Hash)
27
+ if (key = keys.first) && key.is_a?(Array) && key.size == 2
28
+ group_by { |k, _v| k[0] }.map do |name, data|
29
+ {name: name, data: data.map { |k, v| [k[1], v] }}
30
+ end
31
+ else
32
+ to_a
33
+ end
34
+ elsif is_a?(Array)
35
+ map do |v|
36
+ if v.is_a?(Hash) && v[:data].is_a?(Hash)
37
+ v = v.dup
38
+ v[:data] = v[:data].to_a
39
+ end
40
+ v
21
41
  end
22
42
  else
23
43
  self
@@ -1,20 +1,5 @@
1
1
  module Chartkick
2
2
  class Engine < ::Rails::Engine
3
- initializer "precompile", group: :all do |app|
4
- if app.config.respond_to?(:assets)
5
- if defined?(Sprockets) && Gem::Version.new(Sprockets::VERSION) >= Gem::Version.new("4.0.0.beta1")
6
- app.config.assets.precompile << "chartkick.js"
7
- else
8
- # use a proc instead of a string
9
- app.config.assets.precompile << proc { |path| path == "chartkick.js" }
10
- end
11
- end
12
- end
13
-
14
- initializer "helper" do
15
- ActiveSupport.on_load(:action_view) do
16
- include Helper
17
- end
18
- end
3
+ # for assets
19
4
  end
20
5
  end
@@ -3,41 +3,41 @@ require "erb"
3
3
 
4
4
  module Chartkick
5
5
  module Helper
6
- def line_chart(data_source, options = {})
6
+ def line_chart(data_source, **options)
7
7
  chartkick_chart "LineChart", data_source, options
8
8
  end
9
9
 
10
- def pie_chart(data_source, options = {})
10
+ def pie_chart(data_source, **options)
11
11
  chartkick_chart "PieChart", data_source, options
12
12
  end
13
13
 
14
- def column_chart(data_source, options = {})
14
+ def column_chart(data_source, **options)
15
15
  chartkick_chart "ColumnChart", data_source, options
16
16
  end
17
17
 
18
- def bar_chart(data_source, options = {})
18
+ def bar_chart(data_source, **options)
19
19
  chartkick_chart "BarChart", data_source, options
20
20
  end
21
21
 
22
- def area_chart(data_source, options = {})
22
+ def area_chart(data_source, **options)
23
23
  chartkick_chart "AreaChart", data_source, options
24
24
  end
25
25
 
26
- def scatter_chart(data_source, options = {})
26
+ def scatter_chart(data_source, **options)
27
27
  chartkick_chart "ScatterChart", data_source, options
28
28
  end
29
29
 
30
- def geo_chart(data_source, options = {})
30
+ def geo_chart(data_source, **options)
31
31
  chartkick_chart "GeoChart", data_source, options
32
32
  end
33
33
 
34
- def timeline(data_source, options = {})
34
+ def timeline(data_source, **options)
35
35
  chartkick_chart "Timeline", data_source, options
36
36
  end
37
37
 
38
38
  private
39
39
 
40
- def chartkick_chart(klass, data_source, options)
40
+ def chartkick_chart(klass, data_source, **options)
41
41
  @chartkick_chart_id ||= 0
42
42
  options = chartkick_deep_merge(Chartkick.options, options)
43
43
  element_id = options.delete(:id) || "chart-#{@chartkick_chart_id += 1}"
@@ -46,13 +46,25 @@ module Chartkick
46
46
  defer = !!options.delete(:defer)
47
47
  # content_for: nil must override default
48
48
  content_for = options.key?(:content_for) ? options.delete(:content_for) : Chartkick.content_for
49
- nonce = options.key?(:nonce) ? " nonce=\"#{ERB::Util.html_escape(options.delete(:nonce))}\"" : nil
49
+
50
+ nonce = options.delete(:nonce)
51
+ if nonce == true
52
+ if respond_to?(:content_security_policy_nonce) && content_security_policy_nonce
53
+ # Rails 5.2
54
+ nonce = content_security_policy_nonce
55
+ elsif respond_to?(:content_security_policy_script_nonce)
56
+ # Secure Headers
57
+ nonce = content_security_policy_script_nonce
58
+ end
59
+ end
60
+ nonce_html = nonce ? " nonce=\"#{ERB::Util.html_escape(nonce)}\"" : nil
61
+
50
62
  html = (options.delete(:html) || %(<div id="%{id}" style="height: %{height}; width: %{width}; text-align: center; color: #999; line-height: %{height}; font-size: 14px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif;">Loading...</div>)) % {id: ERB::Util.html_escape(element_id), height: ERB::Util.html_escape(height), width: ERB::Util.html_escape(width)}
51
63
 
52
64
  createjs = "new Chartkick.#{klass}(#{element_id.to_json}, #{data_source.respond_to?(:chart_json) ? data_source.chart_json : data_source.to_json}, #{options.to_json});"
53
65
  if defer
54
66
  js = <<JS
55
- <script type="text/javascript"#{nonce}>
67
+ <script type="text/javascript"#{nonce_html}>
56
68
  (function() {
57
69
  var createChart = function() { #{createjs} };
58
70
  if (window.addEventListener) {
@@ -67,7 +79,7 @@ module Chartkick
67
79
  JS
68
80
  else
69
81
  js = <<JS
70
- <script type="text/javascript"#{nonce}>
82
+ <script type="text/javascript"#{nonce_html}>
71
83
  #{createjs}
72
84
  </script>
73
85
  JS
@@ -1,3 +1,3 @@
1
1
  module Chartkick
2
- VERSION = "2.3.5"
2
+ VERSION = "3.0.0"
3
3
  end
@@ -2,7 +2,7 @@
2
2
  * Chartkick.js
3
3
  * Create beautiful charts with one line of JavaScript
4
4
  * https://github.com/ankane/chartkick.js
5
- * v2.3.6
5
+ * v3.0.0
6
6
  * MIT License
7
7
  */
8
8
 
@@ -233,6 +233,10 @@
233
233
  return !isNaN(toDate(obj)) && toStr(obj).length >= 6;
234
234
  }
235
235
 
236
+ function isNumber(obj) {
237
+ return typeof obj === "number";
238
+ }
239
+
236
240
  function formatValue(pre, value, options) {
237
241
  pre = pre || "";
238
242
  if (options.prefix) {
@@ -371,7 +375,7 @@
371
375
  options.scales.yAxes[0].scaleLabel.labelString = title;
372
376
  };
373
377
 
374
- // http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
378
+ // https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
375
379
  var addOpacity = function(hex, opacity) {
376
380
  var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
377
381
  return result ? "rgba(" + parseInt(result[1], 16) + ", " + parseInt(result[2], 16) + ", " + parseInt(result[3], 16) + ", " + opacity + ")" : hex;
@@ -381,15 +385,19 @@
381
385
  var maxLabelSize = Math.ceil(chart.element.offsetWidth / 4.0 / data.labels.length);
382
386
  if (maxLabelSize > 25) {
383
387
  maxLabelSize = 25;
388
+ } else if (maxLabelSize < 10) {
389
+ maxLabelSize = 10;
390
+ }
391
+ if (!options.scales.xAxes[0].ticks.callback) {
392
+ options.scales.xAxes[0].ticks.callback = function (value) {
393
+ value = toStr(value);
394
+ if (value.length > maxLabelSize) {
395
+ return value.substring(0, maxLabelSize - 2) + "...";
396
+ } else {
397
+ return value;
398
+ }
399
+ };
384
400
  }
385
- options.scales.xAxes[0].ticks.callback = function (value) {
386
- value = toStr(value);
387
- if (value.length > maxLabelSize) {
388
- return value.substring(0, maxLabelSize - 2) + "...";
389
- } else {
390
- return value;
391
- }
392
- };
393
401
  };
394
402
 
395
403
  var setFormatOptions = function(chart, options, chartType) {
@@ -400,48 +408,63 @@
400
408
  decimal: chart.options.decimal
401
409
  };
402
410
 
403
- if (formatOptions.prefix || formatOptions.suffix || formatOptions.thousands || formatOptions.decimal) {
404
- if (chartType !== "pie") {
405
- var myAxes = options.scales.yAxes;
406
- if (chartType === "bar") {
407
- myAxes = options.scales.xAxes;
408
- }
411
+ if (chartType !== "pie") {
412
+ var myAxes = options.scales.yAxes;
413
+ if (chartType === "bar") {
414
+ myAxes = options.scales.xAxes;
415
+ }
409
416
 
410
- if (!myAxes[0].ticks.callback) {
411
- myAxes[0].ticks.callback = function (value) {
412
- return formatValue("", value, formatOptions);
413
- };
414
- }
417
+ if (!myAxes[0].ticks.callback) {
418
+ myAxes[0].ticks.callback = function (value) {
419
+ return formatValue("", value, formatOptions);
420
+ };
415
421
  }
422
+ }
416
423
 
417
- if (!options.tooltips.callbacks.label) {
418
- if (chartType !== "pie") {
419
- var valueLabel = chartType === "bar" ? "xLabel" : "yLabel";
420
- options.tooltips.callbacks.label = function (tooltipItem, data) {
421
- var label = data.datasets[tooltipItem.datasetIndex].label || '';
422
- if (label) {
423
- label += ': ';
424
- }
425
- return formatValue(label, tooltipItem[valueLabel], formatOptions);
426
- };
427
- } else {
428
- // need to use separate label for pie charts
429
- options.tooltips.callbacks.label = function (tooltipItem, data) {
430
- var dataLabel = data.labels[tooltipItem.index];
431
- var value = ': ';
432
-
433
- if (isArray(dataLabel)) {
434
- // show value on first line of multiline label
435
- // need to clone because we are changing the value
436
- dataLabel = dataLabel.slice();
437
- dataLabel[0] += value;
438
- } else {
439
- dataLabel += value;
440
- }
424
+ if (!options.tooltips.callbacks.label) {
425
+ if (chartType === "scatter") {
426
+ options.tooltips.callbacks.label = function (item, data) {
427
+ var label = data.datasets[item.datasetIndex].label || '';
428
+ if (label) {
429
+ label += ': ';
430
+ }
431
+ return label + '(' + item.xLabel + ', ' + item.yLabel + ')';
432
+ };
433
+ } else if (chartType === "bubble") {
434
+ options.tooltips.callbacks.label = function (item, data) {
435
+ var label = data.datasets[item.datasetIndex].label || '';
436
+ if (label) {
437
+ label += ': ';
438
+ }
439
+ var dataPoint = data.datasets[item.datasetIndex].data[item.index];
440
+ return label + '(' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.v + ')';
441
+ };
442
+ } else if (chartType === "pie") {
443
+ // need to use separate label for pie charts
444
+ options.tooltips.callbacks.label = function (tooltipItem, data) {
445
+ var dataLabel = data.labels[tooltipItem.index];
446
+ var value = ': ';
447
+
448
+ if (isArray(dataLabel)) {
449
+ // show value on first line of multiline label
450
+ // need to clone because we are changing the value
451
+ dataLabel = dataLabel.slice();
452
+ dataLabel[0] += value;
453
+ } else {
454
+ dataLabel += value;
455
+ }
441
456
 
442
- return formatValue(dataLabel, data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index], formatOptions);
443
- };
444
- }
457
+ return formatValue(dataLabel, data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index], formatOptions);
458
+ };
459
+ } else {
460
+ var valueLabel = chartType === "bar" ? "xLabel" : "yLabel";
461
+ options.tooltips.callbacks.label = function (tooltipItem, data) {
462
+ var label = data.datasets[tooltipItem.datasetIndex].label || '';
463
+ if (label) {
464
+ label += ': ';
465
+ }
466
+ return formatValue(label, tooltipItem[valueLabel], formatOptions);
467
+ };
445
468
  }
446
469
  }
447
470
  };
@@ -461,61 +484,92 @@
461
484
  var year = true;
462
485
  var hour = true;
463
486
  var minute = true;
464
- var detectType = (chartType === "line" || chartType === "area") && !chart.discrete;
465
487
 
466
488
  var series = chart.data;
467
489
 
468
- var sortedLabels = [];
469
-
470
- var i, j, s, d, key, rows = [];
471
- for (i = 0; i < series.length; i++) {
472
- s = series[i];
473
-
474
- for (j = 0; j < s.data.length; j++) {
475
- d = s.data[j];
476
- key = detectType ? d[0].getTime() : d[0];
477
- if (!rows[key]) {
478
- rows[key] = new Array(series.length);
479
- }
480
- rows[key][i] = toFloat(d[1]);
481
- if (sortedLabels.indexOf(key) === -1) {
482
- sortedLabels.push(key);
490
+ var max = 0;
491
+ if (chartType === "bubble") {
492
+ for (var i$1 = 0; i$1 < series.length; i$1++) {
493
+ var s$1 = series[i$1];
494
+ for (var j$1 = 0; j$1 < s$1.data.length; j$1++) {
495
+ if (s$1.data[j$1][2] > max) {
496
+ max = s$1.data[j$1][2];
497
+ }
483
498
  }
484
499
  }
485
500
  }
486
501
 
487
- if (detectType || chart.options.xtype === "number") {
488
- sortedLabels.sort(sortByNumber);
489
- }
502
+ var i, j, s, d, key, rows = [], rows2 = [];
490
503
 
491
- var rows2 = [];
492
- for (j = 0; j < series.length; j++) {
493
- rows2.push([]);
494
- }
504
+ if (chart.xtype === "number" || chartType === "bubble") {
505
+ for (var i$2 = 0; i$2 < series.length; i$2++) {
506
+ var s$2 = series[i$2];
507
+ var d$1 = [];
508
+ for (var j$2 = 0; j$2 < s$2.data.length; j$2++) {
509
+ var point = {
510
+ x: toFloat(s$2.data[j$2][0]),
511
+ y: toFloat(s$2.data[j$2][1])
512
+ };
513
+ if (chartType === "bubble") {
514
+ point.r = toFloat(s$2.data[j$2][2]) * 20 / max;
515
+ // custom attribute, for tooltip
516
+ point.v = s$2.data[j$2][2];
517
+ }
518
+ d$1.push(point);
519
+ }
520
+ rows2.push(d$1);
521
+ }
522
+ } else {
523
+ var sortedLabels = [];
495
524
 
496
- var value;
497
- var k;
498
- for (k = 0; k < sortedLabels.length; k++) {
499
- i = sortedLabels[k];
500
- if (detectType) {
501
- value = new Date(toFloat(i));
502
- // TODO make this efficient
503
- day = day && isDay(value);
504
- if (!dayOfWeek) {
505
- dayOfWeek = value.getDay();
525
+ for (i = 0; i < series.length; i++) {
526
+ s = series[i];
527
+
528
+ for (j = 0; j < s.data.length; j++) {
529
+ d = s.data[j];
530
+ key = chart.xtype == "datetime" ? d[0].getTime() : d[0];
531
+ if (!rows[key]) {
532
+ rows[key] = new Array(series.length);
533
+ }
534
+ rows[key][i] = toFloat(d[1]);
535
+ if (sortedLabels.indexOf(key) === -1) {
536
+ sortedLabels.push(key);
537
+ }
506
538
  }
507
- week = week && isWeek(value, dayOfWeek);
508
- month = month && isMonth(value);
509
- year = year && isYear(value);
510
- hour = hour && isHour(value);
511
- minute = minute && isMinute(value);
512
- } else {
513
- value = i;
514
539
  }
515
- labels.push(value);
540
+
541
+ if (chart.xtype === "datetime") {
542
+ sortedLabels.sort(sortByNumber);
543
+ }
544
+
516
545
  for (j = 0; j < series.length; j++) {
517
- // Chart.js doesn't like undefined
518
- rows2[j].push(rows[i][j] === undefined ? null : rows[i][j]);
546
+ rows2.push([]);
547
+ }
548
+
549
+ var value;
550
+ var k;
551
+ for (k = 0; k < sortedLabels.length; k++) {
552
+ i = sortedLabels[k];
553
+ if (chart.xtype === "datetime") {
554
+ value = new Date(toFloat(i));
555
+ // TODO make this efficient
556
+ day = day && isDay(value);
557
+ if (!dayOfWeek) {
558
+ dayOfWeek = value.getDay();
559
+ }
560
+ week = week && isWeek(value, dayOfWeek);
561
+ month = month && isMonth(value);
562
+ year = year && isYear(value);
563
+ hour = hour && isHour(value);
564
+ minute = minute && isMinute(value);
565
+ } else {
566
+ value = i;
567
+ }
568
+ labels.push(value);
569
+ for (j = 0; j < series.length; j++) {
570
+ // Chart.js doesn't like undefined
571
+ rows2[j].push(rows[i][j] === undefined ? null : rows[i][j]);
572
+ }
519
573
  }
520
574
  }
521
575
 
@@ -532,10 +586,14 @@
532
586
  borderColor: color,
533
587
  backgroundColor: backgroundColor,
534
588
  pointBackgroundColor: color,
535
- pointHoverBackgroundColor: color,
536
- borderWidth: 2
589
+ borderWidth: 2,
590
+ pointHoverBackgroundColor: color
537
591
  };
538
592
 
593
+ if (chartType === "scatter" || chartType === "bubble") {
594
+ dataset.showLine = false;
595
+ }
596
+
539
597
  if (s.stack) {
540
598
  dataset.stack = s.stack;
541
599
  }
@@ -556,16 +614,16 @@
556
614
  datasets.push(dataset);
557
615
  }
558
616
 
559
- if (detectType && labels.length > 0) {
617
+ if (chart.xtype === "datetime" && labels.length > 0) {
560
618
  var minTime = labels[0].getTime();
561
619
  var maxTime = labels[0].getTime();
562
620
  for (i = 1; i < labels.length; i++) {
563
- value = labels[i].getTime();
564
- if (value < minTime) {
565
- minTime = value;
621
+ var value$1 = labels[i].getTime();
622
+ if (value$1 < minTime) {
623
+ minTime = value$1;
566
624
  }
567
- if (value > maxTime) {
568
- maxTime = value;
625
+ if (value$1 > maxTime) {
626
+ maxTime = value$1;
569
627
  }
570
628
  }
571
629
 
@@ -626,10 +684,6 @@
626
684
  };
627
685
 
628
686
  defaultExport.prototype.renderLineChart = function renderLineChart (chart, chartType) {
629
- if (chart.options.xtype === "number") {
630
- return this.renderScatterChart(chart, chartType, true);
631
- }
632
-
633
687
  var chartOptions = {};
634
688
  // fix for https://github.com/chartjs/Chart.js/issues/2441
635
689
  if (!chart.options.max && allZeros(chart.data)) {
@@ -641,7 +695,7 @@
641
695
 
642
696
  var data = createDataTable(chart, options, chartType || "line");
643
697
 
644
- options.scales.xAxes[0].type = chart.discrete ? "category" : "time";
698
+ options.scales.xAxes[0].type = chart.xtype === "string" ? "category" : (chart.xtype == "number" ? "linear" : "time");
645
699
 
646
700
  this.drawChart(chart, "line", data, options);
647
701
  };
@@ -708,51 +762,13 @@
708
762
  this.renderColumnChart(chart, "bar");
709
763
  };
710
764
 
711
- defaultExport.prototype.renderScatterChart = function renderScatterChart (chart, chartType, lineChart) {
712
- chartType = chartType || "line";
765
+ defaultExport.prototype.renderScatterChart = function renderScatterChart (chart, chartType) {
766
+ chartType = chartType || "scatter";
713
767
 
714
768
  var options = jsOptions(chart, chart.options);
715
- if (!lineChart) {
716
- setFormatOptions(chart, options, chartType);
717
- }
718
-
719
- var colors = chart.options.colors || defaultColors;
720
-
721
- var datasets = [];
722
- var series = chart.data;
723
- for (var i = 0; i < series.length; i++) {
724
- var s = series[i];
725
- var d = [];
726
- for (var j = 0; j < s.data.length; j++) {
727
- var point = {
728
- x: toFloat(s.data[j][0]),
729
- y: toFloat(s.data[j][1])
730
- };
731
- if (chartType === "bubble") {
732
- point.r = toFloat(s.data[j][2]);
733
- }
734
- d.push(point);
735
- }
736
-
737
- var color = s.color || colors[i];
738
- var backgroundColor = chartType === "area" ? addOpacity(color, 0.5) : color;
739
-
740
- datasets.push({
741
- label: s.name,
742
- showLine: lineChart || false,
743
- data: d,
744
- borderColor: color,
745
- backgroundColor: backgroundColor,
746
- pointBackgroundColor: color,
747
- fill: chartType === "area"
748
- });
749
- }
750
-
751
- if (chartType === "area") {
752
- chartType = "line";
753
- }
769
+ setFormatOptions(chart, options, chartType);
754
770
 
755
- var data = {datasets: datasets};
771
+ var data = createDataTable(chart, options, chartType);
756
772
 
757
773
  options.scales.xAxes[0].type = "linear";
758
774
  options.scales.xAxes[0].position = "bottom";
@@ -773,13 +789,19 @@
773
789
  defaultExport.prototype.drawChart = function drawChart (chart, type, data, options) {
774
790
  this.destroy(chart);
775
791
 
776
- chart.element.innerHTML = "<canvas></canvas>";
777
- var ctx = chart.element.getElementsByTagName("CANVAS")[0];
778
- chart.chart = new this.library(ctx, {
792
+ var chartOptions = {
779
793
  type: type,
780
794
  data: data,
781
795
  options: options
782
- });
796
+ };
797
+
798
+ if (chart.options.code) {
799
+ window.console.log("new Chart(ctx, " + JSON.stringify(chartOptions) + ");");
800
+ }
801
+
802
+ chart.element.innerHTML = "<canvas></canvas>";
803
+ var ctx = chart.element.getElementsByTagName("CANVAS")[0];
804
+ chart.chart = new this.library(ctx, chartOptions);
783
805
  };
784
806
 
785
807
  var defaultOptions$1 = {
@@ -877,18 +899,16 @@
877
899
  decimal: chart.options.decimal
878
900
  };
879
901
 
880
- if (formatOptions.prefix || formatOptions.suffix || formatOptions.thousands || formatOptions.decimal) {
881
- if (chartType !== "pie" && !options.yAxis.labels.formatter) {
882
- options.yAxis.labels.formatter = function () {
883
- return formatValue("", this.value, formatOptions);
884
- };
885
- }
902
+ if (chartType !== "pie" && !options.yAxis.labels.formatter) {
903
+ options.yAxis.labels.formatter = function () {
904
+ return formatValue("", this.value, formatOptions);
905
+ };
906
+ }
886
907
 
887
- if (!options.tooltip.pointFormatter) {
888
- options.tooltip.pointFormatter = function () {
889
- return '<span style="color:' + this.color + '>\u25CF</span> ' + formatValue(this.series.name + ': <b>', this.y, formatOptions) + '</b><br/>';
890
- };
891
- }
908
+ if (!options.tooltip.pointFormatter) {
909
+ options.tooltip.pointFormatter = function () {
910
+ return '<span style="color:' + this.color + '>\u25CF</span> ' + formatValue(this.series.name + ': <b>', this.y, formatOptions) + '</b><br/>';
911
+ };
892
912
  }
893
913
  };
894
914
 
@@ -927,7 +947,7 @@
927
947
  }
928
948
 
929
949
  var options = jsOptions$1(chart, chart.options, chartOptions), data, i, j;
930
- options.xAxis.type = chart.discrete ? "category" : "datetime";
950
+ options.xAxis.type = chart.xtype === "string" ? "category" : (chart.xtype === "number" ? "linear" : "datetime");
931
951
  if (!options.chart.type) {
932
952
  options.chart.type = chartType;
933
953
  }
@@ -935,8 +955,9 @@
935
955
 
936
956
  var series = chart.data;
937
957
  for (i = 0; i < series.length; i++) {
958
+ series[i].name = series[i].name || "Value";
938
959
  data = series[i].data;
939
- if (!chart.discrete) {
960
+ if (chart.xtype === "datetime") {
940
961
  for (j = 0; j < data.length; j++) {
941
962
  data[j][0] = data[j][0].getTime();
942
963
  }
@@ -1005,7 +1026,7 @@
1005
1026
  }
1006
1027
  }
1007
1028
 
1008
- if (chart.options.xtype === "number") {
1029
+ if (chart.xtype === "number") {
1009
1030
  categories.sort(sortByNumber);
1010
1031
  }
1011
1032
 
@@ -1019,7 +1040,7 @@
1019
1040
  }
1020
1041
 
1021
1042
  d2 = {
1022
- name: series[i].name,
1043
+ name: series[i].name || "Value",
1023
1044
  data: d
1024
1045
  };
1025
1046
  if (series[i].stack) {
@@ -1051,6 +1072,11 @@
1051
1072
 
1052
1073
  options.chart.renderTo = chart.element.id;
1053
1074
  options.series = data;
1075
+
1076
+ if (chart.options.code) {
1077
+ window.console.log("new Highcharts.Chart(" + JSON.stringify(options) + ");");
1078
+ }
1079
+
1054
1080
  chart.chart = new this.library.Chart(options);
1055
1081
  };
1056
1082
 
@@ -1182,13 +1208,9 @@
1182
1208
  }
1183
1209
 
1184
1210
  var options = jsOptions$2(chart, chart.options, chartOptions);
1185
- var columnType = chart.discrete ? "string" : "datetime";
1186
- if (chart.options.xtype === "number") {
1187
- columnType = "number";
1188
- }
1189
- var data = this$1.createDataTable(chart.data, columnType);
1211
+ var data = this$1.createDataTable(chart.data, chart.xtype);
1190
1212
 
1191
- this$1.drawChart(chart, this$1.library.visualization.LineChart, data, options);
1213
+ this$1.drawChart(chart, "LineChart", data, options);
1192
1214
  });
1193
1215
  };
1194
1216
 
@@ -1222,7 +1244,7 @@
1222
1244
  data.addColumn("number", "Value");
1223
1245
  data.addRows(chart.data);
1224
1246
 
1225
- this$1.drawChart(chart, this$1.library.visualization.PieChart, data, options);
1247
+ this$1.drawChart(chart, "PieChart", data, options);
1226
1248
  });
1227
1249
  };
1228
1250
 
@@ -1231,9 +1253,9 @@
1231
1253
 
1232
1254
  this.waitForLoaded(chart, function () {
1233
1255
  var options = jsOptions$2(chart, chart.options);
1234
- var data = this$1.createDataTable(chart.data, "string", chart.options.xtype);
1256
+ var data = this$1.createDataTable(chart.data, chart.xtype);
1235
1257
 
1236
- this$1.drawChart(chart, this$1.library.visualization.ColumnChart, data, options);
1258
+ this$1.drawChart(chart, "ColumnChart", data, options);
1237
1259
  });
1238
1260
  };
1239
1261
 
@@ -1249,9 +1271,9 @@
1249
1271
  }
1250
1272
  };
1251
1273
  var options = jsOptionsFunc(defaultOptions$2, hideLegend$2, setTitle$2, setBarMin$1, setBarMax$1, setStacked$2, setXtitle$2, setYtitle$2)(chart, chart.options, chartOptions);
1252
- var data = this$1.createDataTable(chart.data, "string", chart.options.xtype);
1274
+ var data = this$1.createDataTable(chart.data, chart.xtype);
1253
1275
 
1254
- this$1.drawChart(chart, this$1.library.visualization.BarChart, data, options);
1276
+ this$1.drawChart(chart, "BarChart", data, options);
1255
1277
  });
1256
1278
  };
1257
1279
 
@@ -1266,13 +1288,9 @@
1266
1288
  };
1267
1289
 
1268
1290
  var options = jsOptions$2(chart, chart.options, chartOptions);
1269
- var columnType = chart.discrete ? "string" : "datetime";
1270
- if (chart.options.xtype === "number") {
1271
- columnType = "number";
1272
- }
1273
- var data = this$1.createDataTable(chart.data, columnType);
1291
+ var data = this$1.createDataTable(chart.data, chart.xtype);
1274
1292
 
1275
- this$1.drawChart(chart, this$1.library.visualization.AreaChart, data, options);
1293
+ this$1.drawChart(chart, "AreaChart", data, options);
1276
1294
  });
1277
1295
  };
1278
1296
 
@@ -1293,7 +1311,7 @@
1293
1311
  data.addColumn("number", chart.options.label || "Value");
1294
1312
  data.addRows(chart.data);
1295
1313
 
1296
- this$1.drawChart(chart, this$1.library.visualization.GeoChart, data, options);
1314
+ this$1.drawChart(chart, "GeoChart", data, options);
1297
1315
  });
1298
1316
  };
1299
1317
 
@@ -1306,6 +1324,7 @@
1306
1324
 
1307
1325
  var series = chart.data, rows2 = [], i, j, data, d;
1308
1326
  for (i = 0; i < series.length; i++) {
1327
+ series[i].name = series[i].name || "Value";
1309
1328
  d = series[i].data;
1310
1329
  for (j = 0; j < d.length; j++) {
1311
1330
  var row = new Array(series.length + 1);
@@ -1322,7 +1341,7 @@
1322
1341
  }
1323
1342
  data.addRows(rows2);
1324
1343
 
1325
- this$1.drawChart(chart, this$1.library.visualization.ScatterChart, data, options);
1344
+ this$1.drawChart(chart, "ScatterChart", data, options);
1326
1345
  });
1327
1346
  };
1328
1347
 
@@ -1347,7 +1366,7 @@
1347
1366
 
1348
1367
  chart.element.style.lineHeight = "normal";
1349
1368
 
1350
- this$1.drawChart(chart, this$1.library.visualization.Timeline, data, options);
1369
+ this$1.drawChart(chart, "Timeline", data, options);
1351
1370
  });
1352
1371
  };
1353
1372
 
@@ -1360,7 +1379,11 @@
1360
1379
  defaultExport$2.prototype.drawChart = function drawChart (chart, type, data, options) {
1361
1380
  this.destroy(chart);
1362
1381
 
1363
- chart.chart = new type(chart.element);
1382
+ if (chart.options.code) {
1383
+ window.console.log("var data = new google.visualization.DataTable(" + data.toJSON() + ");\nvar chart = new google.visualization." + type + "(element);\nchart.draw(data, " + JSON.stringify(options) + ");");
1384
+ }
1385
+
1386
+ chart.chart = new this.library.visualization[type](chart.element);
1364
1387
  resize(function () {
1365
1388
  chart.chart.draw(data, options);
1366
1389
  });
@@ -1394,11 +1417,7 @@
1394
1417
  loadOptions.mapsApiKey = config.mapsApiKey;
1395
1418
  }
1396
1419
 
1397
- if (this.library.setOnLoadCallback) {
1398
- this.library.load("visualization", "1", loadOptions);
1399
- } else {
1400
- this.library.charts.load("current", loadOptions);
1401
- }
1420
+ this.library.charts.load("current", loadOptions);
1402
1421
  }
1403
1422
  };
1404
1423
 
@@ -1418,10 +1437,11 @@
1418
1437
  };
1419
1438
 
1420
1439
  // cant use object as key
1421
- defaultExport$2.prototype.createDataTable = function createDataTable (series, columnType, xtype) {
1440
+ defaultExport$2.prototype.createDataTable = function createDataTable (series, columnType) {
1422
1441
  var i, j, s, d, key, rows = [], sortedLabels = [];
1423
1442
  for (i = 0; i < series.length; i++) {
1424
1443
  s = series[i];
1444
+ series[i].name = series[i].name || "Value";
1425
1445
 
1426
1446
  for (j = 0; j < s.data.length; j++) {
1427
1447
  d = s.data[j];
@@ -1453,14 +1473,12 @@
1453
1473
  rows2.sort(sortByTime);
1454
1474
  } else if (columnType === "number") {
1455
1475
  rows2.sort(sortByNumberSeries);
1456
- }
1457
-
1458
- if (xtype === "number") {
1459
- rows2.sort(sortByNumberSeries);
1460
1476
 
1461
1477
  for (i = 0; i < rows2.length; i++) {
1462
1478
  rows2[i][0] = toStr(rows2[i][0]);
1463
1479
  }
1480
+
1481
+ columnType = "string";
1464
1482
  }
1465
1483
 
1466
1484
  // create datatable
@@ -1532,7 +1550,7 @@
1532
1550
  }
1533
1551
  }
1534
1552
 
1535
- var config = (typeof window !== "undefined" && window.Chartkick) || {};
1553
+ var config = {};
1536
1554
  var adapters = [];
1537
1555
 
1538
1556
  // helpers
@@ -1576,7 +1594,7 @@
1576
1594
  function addDownloadButton(chart) {
1577
1595
  var element = chart.element;
1578
1596
  var link = document.createElement("a");
1579
- link.download = chart.options.download === true ? "chart.png" : chart.options.download; // http://caniuse.com/download
1597
+ link.download = chart.options.download === true ? "chart.png" : chart.options.download; // https://caniuse.com/download
1580
1598
  link.style.position = "absolute";
1581
1599
  link.style.top = "20px";
1582
1600
  link.style.right = "20px";
@@ -1615,7 +1633,7 @@
1615
1633
  });
1616
1634
  }
1617
1635
 
1618
- // http://stackoverflow.com/questions/10149963/adding-event-listener-cross-browser
1636
+ // https://stackoverflow.com/questions/10149963/adding-event-listener-cross-browser
1619
1637
  function addEvent(elem, event, fn) {
1620
1638
  if (elem.addEventListener) {
1621
1639
  elem.addEventListener(event, fn, false);
@@ -1649,7 +1667,7 @@
1649
1667
  if (library) {
1650
1668
  if (library.product === "Highcharts") {
1651
1669
  return defaultExport$1;
1652
- } else if (library.setOnLoadCallback || library.charts) {
1670
+ } else if (library.charts) {
1653
1671
  return defaultExport$2;
1654
1672
  } else if (isFunction(library)) {
1655
1673
  return defaultExport;
@@ -1676,7 +1694,7 @@
1676
1694
  addAdapter(window.Highcharts);
1677
1695
  }
1678
1696
 
1679
- if (window.google && (window.google.setOnLoadCallback || window.google.charts)) {
1697
+ if (window.google && window.google.charts) {
1680
1698
  addAdapter(window.google);
1681
1699
  }
1682
1700
  }
@@ -1761,17 +1779,27 @@
1761
1779
  return r;
1762
1780
  };
1763
1781
 
1764
- function detectDiscrete(series) {
1782
+ function detectXType(series, noDatetime) {
1783
+ if (detectXTypeWithFunction(series, isNumber)) {
1784
+ return "number";
1785
+ } else if (!noDatetime && detectXTypeWithFunction(series, isDate)) {
1786
+ return "datetime";
1787
+ } else {
1788
+ return "string";
1789
+ }
1790
+ }
1791
+
1792
+ function detectXTypeWithFunction(series, func) {
1765
1793
  var i, j, data;
1766
1794
  for (i = 0; i < series.length; i++) {
1767
1795
  data = toArr(series[i].data);
1768
1796
  for (j = 0; j < data.length; j++) {
1769
- if (!isDate(data[j][0])) {
1770
- return true;
1797
+ if (!func(data[j][0])) {
1798
+ return false;
1771
1799
  }
1772
1800
  }
1773
1801
  }
1774
- return false;
1802
+ return true;
1775
1803
  }
1776
1804
 
1777
1805
  // creates a shallow copy of each element of the array
@@ -1790,7 +1818,7 @@
1790
1818
  return newSeries;
1791
1819
  }
1792
1820
 
1793
- function processSeries(chart, keyType) {
1821
+ function processSeries(chart, keyType, noDatetime) {
1794
1822
  var i;
1795
1823
 
1796
1824
  var opts = chart.options;
@@ -1798,27 +1826,18 @@
1798
1826
 
1799
1827
  // see if one series or multiple
1800
1828
  if (!isArray(series) || typeof series[0] !== "object" || isArray(series[0])) {
1801
- series = [{name: opts.label || "Value", data: series}];
1829
+ series = [{name: opts.label, data: series}];
1802
1830
  chart.hideLegend = true;
1803
1831
  } else {
1804
1832
  chart.hideLegend = false;
1805
1833
  }
1806
- if ((opts.discrete === null || opts.discrete === undefined) && keyType !== "bubble" && keyType !== "number") {
1807
- chart.discrete = detectDiscrete(series);
1808
- } else {
1809
- chart.discrete = opts.discrete;
1810
- }
1811
- if (chart.discrete) {
1812
- keyType = "string";
1813
- }
1814
- if (chart.options.xtype) {
1815
- keyType = chart.options.xtype;
1816
- }
1834
+
1835
+ chart.xtype = keyType ? keyType : (opts.discrete ? "string" : detectXType(series, noDatetime));
1817
1836
 
1818
1837
  // right format
1819
1838
  series = copySeries(series);
1820
1839
  for (i = 0; i < series.length; i++) {
1821
- series[i].data = formatSeriesData(toArr(series[i].data), keyType);
1840
+ series[i].data = formatSeriesData(toArr(series[i].data), chart.xtype);
1822
1841
  }
1823
1842
 
1824
1843
  return series;
@@ -1979,7 +1998,7 @@
1979
1998
  LineChart.prototype.constructor = LineChart;
1980
1999
 
1981
2000
  LineChart.prototype.__processData = function __processData () {
1982
- return processSeries(this, "datetime");
2001
+ return processSeries(this);
1983
2002
  };
1984
2003
 
1985
2004
  LineChart.prototype.__chartName = function __chartName () {
@@ -2019,7 +2038,7 @@
2019
2038
  ColumnChart.prototype.constructor = ColumnChart;
2020
2039
 
2021
2040
  ColumnChart.prototype.__processData = function __processData () {
2022
- return processSeries(this, "string");
2041
+ return processSeries(this, null, true);
2023
2042
  };
2024
2043
 
2025
2044
  ColumnChart.prototype.__chartName = function __chartName () {
@@ -2039,7 +2058,7 @@
2039
2058
  BarChart.prototype.constructor = BarChart;
2040
2059
 
2041
2060
  BarChart.prototype.__processData = function __processData () {
2042
- return processSeries(this, "string");
2061
+ return processSeries(this, null, true);
2043
2062
  };
2044
2063
 
2045
2064
  BarChart.prototype.__chartName = function __chartName () {
@@ -2059,7 +2078,7 @@
2059
2078
  AreaChart.prototype.constructor = AreaChart;
2060
2079
 
2061
2080
  AreaChart.prototype.__processData = function __processData () {
2062
- return processSeries(this, "datetime");
2081
+ return processSeries(this);
2063
2082
  };
2064
2083
 
2065
2084
  AreaChart.prototype.__chartName = function __chartName () {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chartkick
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.5
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-15 00:00:00.000000000 Z
11
+ date: 2018-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,30 +53,20 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  description:
56
- email:
57
- - andrew@chartkick.com
56
+ email: andrew@chartkick.com
58
57
  executables: []
59
58
  extensions: []
60
59
  extra_rdoc_files: []
61
60
  files:
62
- - ".github/ISSUE_TEMPLATE.md"
63
- - ".github/stale.yml"
64
- - ".gitignore"
65
61
  - CHANGELOG.md
66
62
  - CONTRIBUTING.md
67
- - Gemfile
68
63
  - LICENSE.txt
69
64
  - README.md
70
- - Rakefile
71
- - chartkick.gemspec
72
65
  - lib/chartkick.rb
73
66
  - lib/chartkick/engine.rb
74
67
  - lib/chartkick/helper.rb
75
- - lib/chartkick/rails.rb
76
68
  - lib/chartkick/sinatra.rb
77
69
  - lib/chartkick/version.rb
78
- - test/chartkick_test.rb
79
- - test/test_helper.rb
80
70
  - vendor/assets/javascripts/Chart.bundle.js
81
71
  - vendor/assets/javascripts/chartkick.js
82
72
  homepage: https://www.chartkick.com
@@ -91,7 +81,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
91
81
  requirements:
92
82
  - - ">="
93
83
  - !ruby/object:Gem::Version
94
- version: '0'
84
+ version: '2.2'
95
85
  required_rubygems_version: !ruby/object:Gem::Requirement
96
86
  requirements:
97
87
  - - ">="
@@ -99,10 +89,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
89
  version: '0'
100
90
  requirements: []
101
91
  rubyforge_project:
102
- rubygems_version: 2.7.6
92
+ rubygems_version: 2.7.7
103
93
  signing_key:
104
94
  specification_version: 4
105
95
  summary: Create beautiful JavaScript charts with one line of Ruby
106
- test_files:
107
- - test/chartkick_test.rb
108
- - test/test_helper.rb
96
+ test_files: []
@@ -1,7 +0,0 @@
1
- Hi,
2
-
3
- Before creating an issue, please check out the Contributing Guide:
4
-
5
- https://github.com/ankane/chartkick/blob/master/CONTRIBUTING.md
6
-
7
- Thanks!
@@ -1,16 +0,0 @@
1
- # Number of days of inactivity before an issue becomes stale
2
- daysUntilStale: 7
3
- # Number of days of inactivity before a stale issue is closed
4
- daysUntilClose: 7
5
- # Issues with these labels will never be considered stale
6
- exemptLabels:
7
- - enhancement
8
- # Label to use when marking an issue as stale
9
- staleLabel: stale
10
- # Comment to post when marking an issue as stale. Set to `false` to disable
11
- markComment: >
12
- This issue has been automatically marked as stale because it has not had
13
- recent activity. It will be closed if no further activity occurs. Thank you
14
- for your contributions.
15
- # Comment to post when closing a stale issue. Set to `false` to disable
16
- closeComment: true
data/.gitignore DELETED
@@ -1,17 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- # Specify your gem's dependencies in chartkick.gemspec
4
- gemspec
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- task default: :test
5
- Rake::TestTask.new do |t|
6
- t.libs << "test"
7
- t.pattern = "test/**/*_test.rb"
8
- end
@@ -1,23 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "chartkick/version"
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "chartkick"
8
- spec.version = Chartkick::VERSION
9
- spec.authors = ["Andrew Kane"]
10
- spec.email = ["andrew@chartkick.com"]
11
- spec.summary = "Create beautiful JavaScript charts with one line of Ruby"
12
- spec.homepage = "https://www.chartkick.com"
13
- spec.license = "MIT"
14
-
15
- spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
16
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
- spec.require_paths = ["lib"]
19
-
20
- spec.add_development_dependency "bundler"
21
- spec.add_development_dependency "rake"
22
- spec.add_development_dependency "minitest"
23
- end
@@ -1,5 +0,0 @@
1
- if Rails.version >= "3.1"
2
- require "chartkick/engine"
3
- else
4
- ActionView::Base.send :include, Chartkick::Helper
5
- end
@@ -1,43 +0,0 @@
1
- require "test_helper"
2
-
3
- class TestChartkick < Minitest::Test
4
- include Chartkick::Helper
5
-
6
- # TODO actual tests
7
-
8
- def setup
9
- @data = [[34, 42], [56, 49]]
10
- end
11
-
12
- def test_line_chart
13
- assert line_chart(@data)
14
- end
15
-
16
- def test_pie_chart
17
- assert pie_chart(@data)
18
- end
19
-
20
- def test_column_chart
21
- assert column_chart(@data)
22
- end
23
-
24
- def test_options_not_mutated
25
- options = {id: "boom"}
26
- line_chart @data, options
27
- assert_equal "boom", options[:id]
28
- end
29
-
30
- def test_chartkick_deep_merge_different_inner_key
31
- global_option = {library: {backgroundColor: "#eee"}}
32
- local_option = {library: {title: "test"}}
33
- correct_merge = {library: {backgroundColor: "#eee", title: "test"}}
34
- assert_equal chartkick_deep_merge(global_option, local_option), correct_merge
35
- end
36
-
37
- def test_chartkick_deep_merge_same_inner_key
38
- global_option = {library: {backgroundColor: "#eee"}}
39
- local_option = {library: {backgroundColor: "#fff"}}
40
- correct_merge = {library: {backgroundColor: "#fff"}}
41
- assert_equal chartkick_deep_merge(global_option, local_option), correct_merge
42
- end
43
- end
@@ -1,4 +0,0 @@
1
- require "bundler/setup"
2
- Bundler.require(:default)
3
- require "minitest/autorun"
4
- require "minitest/pride"