chartkick 4.0.0 → 4.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/README.md +19 -19
- data/lib/chartkick/helper.rb +9 -3
- data/lib/chartkick/version.rb +1 -1
- data/vendor/assets/javascripts/Chart.bundle.js +24607 -2
- data/vendor/assets/javascripts/chartkick.js +235 -226
- metadata +3 -5
- data/vendor/assets/javascripts/chart.js +0 -12486
- data/vendor/assets/javascripts/chartjs-adapter-date-fns.bundle.js +0 -6313
|
@@ -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
|
-
* v4.0.
|
|
5
|
+
* v4.0.5
|
|
6
6
|
* MIT License
|
|
7
7
|
*/
|
|
8
8
|
|
|
@@ -92,7 +92,8 @@
|
|
|
92
92
|
// try our best to get the str into iso8601
|
|
93
93
|
// TODO be smarter about this
|
|
94
94
|
var str = n.replace(/ /, "T").replace(" ", "").replace("UTC", "Z");
|
|
95
|
-
|
|
95
|
+
// Date.parse returns milliseconds if valid and NaN if invalid
|
|
96
|
+
n = new Date(Date.parse(str) || n);
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
99
|
}
|
|
@@ -559,6 +560,11 @@
|
|
|
559
560
|
} else {
|
|
560
561
|
var valueLabel = chartType === "bar" ? "x" : "y";
|
|
561
562
|
options.plugins.tooltip.callbacks.label = function (context) {
|
|
563
|
+
// don't show null values for stacked charts
|
|
564
|
+
if (context.parsed[valueLabel] === null) {
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
|
|
562
568
|
var label = context.dataset.label || '';
|
|
563
569
|
if (label) {
|
|
564
570
|
label += ': ';
|
|
@@ -680,7 +686,7 @@
|
|
|
680
686
|
s = series[i];
|
|
681
687
|
|
|
682
688
|
// use colors for each bar for single series format
|
|
683
|
-
if (chart.options.colors && chart.singleSeriesFormat && (chartType === "bar" || chartType === "column") && !s.color) {
|
|
689
|
+
if (chart.options.colors && chart.singleSeriesFormat && (chartType === "bar" || chartType === "column") && !s.color && isArray(chart.options.colors) && !isArray(chart.options.colors[0])) {
|
|
684
690
|
color = colors;
|
|
685
691
|
backgroundColor = [];
|
|
686
692
|
for (var j$3 = 0; j$3 < colors.length; j$3++) {
|
|
@@ -810,11 +816,15 @@
|
|
|
810
816
|
}
|
|
811
817
|
|
|
812
818
|
if (step && timeDiff > 0) {
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
819
|
+
// width not available for hidden elements
|
|
820
|
+
var width = chart.element.offsetWidth;
|
|
821
|
+
if (width > 0) {
|
|
822
|
+
var unitStepSize = Math.ceil(timeDiff / step / (width / 100.0));
|
|
823
|
+
if (week && step === 1) {
|
|
824
|
+
unitStepSize = Math.ceil(unitStepSize / 7.0) * 7;
|
|
825
|
+
}
|
|
826
|
+
options.scales.x.time.stepSize = unitStepSize;
|
|
816
827
|
}
|
|
817
|
-
options.scales.x.time.stepSize = unitStepSize;
|
|
818
828
|
}
|
|
819
829
|
}
|
|
820
830
|
|
|
@@ -855,8 +865,8 @@
|
|
|
855
865
|
var data = createDataTable(chart, options, chartType || "line");
|
|
856
866
|
|
|
857
867
|
if (chart.xtype === "number") {
|
|
858
|
-
options.scales.x.type = "linear";
|
|
859
|
-
options.scales.x.position = "bottom";
|
|
868
|
+
options.scales.x.type = options.scales.x.type || "linear";
|
|
869
|
+
options.scales.x.position = options.scales.x.position ||"bottom";
|
|
860
870
|
} else {
|
|
861
871
|
options.scales.x.type = chart.xtype === "string" ? "category" : "time";
|
|
862
872
|
}
|
|
@@ -946,8 +956,8 @@
|
|
|
946
956
|
|
|
947
957
|
var data = createDataTable(chart, options, chartType);
|
|
948
958
|
|
|
949
|
-
options.scales.x.type = "linear";
|
|
950
|
-
options.scales.x.position = "bottom";
|
|
959
|
+
options.scales.x.type = options.scales.x.type || "linear";
|
|
960
|
+
options.scales.x.position = options.scales.x.position || "bottom";
|
|
951
961
|
|
|
952
962
|
// prevent grouping hover and tooltips
|
|
953
963
|
if (!("mode" in options.interaction)) {
|
|
@@ -1097,7 +1107,7 @@
|
|
|
1097
1107
|
};
|
|
1098
1108
|
}
|
|
1099
1109
|
|
|
1100
|
-
if (!options.tooltip.pointFormatter) {
|
|
1110
|
+
if (!options.tooltip.pointFormatter && !options.tooltip.pointFormat) {
|
|
1101
1111
|
options.tooltip.pointFormatter = function () {
|
|
1102
1112
|
return '<span style="color:' + this.color + '">\u25CF</span> ' + formatValue(this.series.name + ': <b>', this.y, formatOptions) + '</b><br/>';
|
|
1103
1113
|
};
|
|
@@ -1139,7 +1149,11 @@
|
|
|
1139
1149
|
}
|
|
1140
1150
|
|
|
1141
1151
|
var options = jsOptions$1(chart, chart.options, chartOptions), data, i, j;
|
|
1142
|
-
|
|
1152
|
+
if (chart.xtype === "number") {
|
|
1153
|
+
options.xAxis.type = options.xAxis.type || "linear";
|
|
1154
|
+
} else {
|
|
1155
|
+
options.xAxis.type = chart.xtype === "string" ? "category" : "datetime";
|
|
1156
|
+
}
|
|
1143
1157
|
if (!options.chart.type) {
|
|
1144
1158
|
options.chart.type = chartType;
|
|
1145
1159
|
}
|
|
@@ -1686,6 +1700,211 @@
|
|
|
1686
1700
|
return data;
|
|
1687
1701
|
};
|
|
1688
1702
|
|
|
1703
|
+
function formatSeriesData(data, keyType) {
|
|
1704
|
+
var r = [], j, keyFunc;
|
|
1705
|
+
|
|
1706
|
+
if (keyType === "number") {
|
|
1707
|
+
keyFunc = toFloat;
|
|
1708
|
+
} else if (keyType === "datetime") {
|
|
1709
|
+
keyFunc = toDate;
|
|
1710
|
+
} else {
|
|
1711
|
+
keyFunc = toStr;
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1714
|
+
if (keyType === "bubble") {
|
|
1715
|
+
for (j = 0; j < data.length; j++) {
|
|
1716
|
+
r.push([toFloat(data[j][0]), toFloat(data[j][1]), toFloat(data[j][2])]);
|
|
1717
|
+
}
|
|
1718
|
+
} else {
|
|
1719
|
+
for (j = 0; j < data.length; j++) {
|
|
1720
|
+
r.push([keyFunc(data[j][0]), toFloat(data[j][1])]);
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
if (keyType === "datetime") {
|
|
1725
|
+
r.sort(sortByTime);
|
|
1726
|
+
} else if (keyType === "number") {
|
|
1727
|
+
r.sort(sortByNumberSeries);
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
return r;
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
function detectXType(series, noDatetime, options) {
|
|
1734
|
+
if (dataEmpty(series)) {
|
|
1735
|
+
if ((options.xmin || options.xmax) && (!options.xmin || isDate(options.xmin)) && (!options.xmax || isDate(options.xmax))) {
|
|
1736
|
+
return "datetime";
|
|
1737
|
+
} else {
|
|
1738
|
+
return "number";
|
|
1739
|
+
}
|
|
1740
|
+
} else if (detectXTypeWithFunction(series, isNumber)) {
|
|
1741
|
+
return "number";
|
|
1742
|
+
} else if (!noDatetime && detectXTypeWithFunction(series, isDate)) {
|
|
1743
|
+
return "datetime";
|
|
1744
|
+
} else {
|
|
1745
|
+
return "string";
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
function detectXTypeWithFunction(series, func) {
|
|
1750
|
+
var i, j, data;
|
|
1751
|
+
for (i = 0; i < series.length; i++) {
|
|
1752
|
+
data = toArr(series[i].data);
|
|
1753
|
+
for (j = 0; j < data.length; j++) {
|
|
1754
|
+
if (!func(data[j][0])) {
|
|
1755
|
+
return false;
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
return true;
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
// creates a shallow copy of each element of the array
|
|
1763
|
+
// elements are expected to be objects
|
|
1764
|
+
function copySeries(series) {
|
|
1765
|
+
var newSeries = [], i, j;
|
|
1766
|
+
for (i = 0; i < series.length; i++) {
|
|
1767
|
+
var copy = {};
|
|
1768
|
+
for (j in series[i]) {
|
|
1769
|
+
if (series[i].hasOwnProperty(j)) {
|
|
1770
|
+
copy[j] = series[i][j];
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
newSeries.push(copy);
|
|
1774
|
+
}
|
|
1775
|
+
return newSeries;
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
function processSeries(chart, keyType, noDatetime) {
|
|
1779
|
+
var i;
|
|
1780
|
+
|
|
1781
|
+
var opts = chart.options;
|
|
1782
|
+
var series = chart.rawData;
|
|
1783
|
+
|
|
1784
|
+
// see if one series or multiple
|
|
1785
|
+
chart.singleSeriesFormat = (!isArray(series) || typeof series[0] !== "object" || isArray(series[0]));
|
|
1786
|
+
if (chart.singleSeriesFormat) {
|
|
1787
|
+
series = [{name: opts.label, data: series}];
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
// convert to array
|
|
1791
|
+
// must come before dataEmpty check
|
|
1792
|
+
series = copySeries(series);
|
|
1793
|
+
for (i = 0; i < series.length; i++) {
|
|
1794
|
+
series[i].data = toArr(series[i].data);
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
chart.xtype = keyType ? keyType : (opts.discrete ? "string" : detectXType(series, noDatetime, opts));
|
|
1798
|
+
|
|
1799
|
+
// right format
|
|
1800
|
+
for (i = 0; i < series.length; i++) {
|
|
1801
|
+
series[i].data = formatSeriesData(series[i].data, chart.xtype);
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
return series;
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
function processSimple(chart) {
|
|
1808
|
+
var perfectData = toArr(chart.rawData), i;
|
|
1809
|
+
for (i = 0; i < perfectData.length; i++) {
|
|
1810
|
+
perfectData[i] = [toStr(perfectData[i][0]), toFloat(perfectData[i][1])];
|
|
1811
|
+
}
|
|
1812
|
+
return perfectData;
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
function dataEmpty(data, chartType) {
|
|
1816
|
+
if (chartType === "PieChart" || chartType === "GeoChart" || chartType === "Timeline") {
|
|
1817
|
+
return data.length === 0;
|
|
1818
|
+
} else {
|
|
1819
|
+
for (var i = 0; i < data.length; i++) {
|
|
1820
|
+
if (data[i].data.length > 0) {
|
|
1821
|
+
return false;
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
return true;
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
function addDownloadButton(chart) {
|
|
1829
|
+
var element = chart.element;
|
|
1830
|
+
var link = document.createElement("a");
|
|
1831
|
+
|
|
1832
|
+
var download = chart.options.download;
|
|
1833
|
+
if (download === true) {
|
|
1834
|
+
download = {};
|
|
1835
|
+
} else if (typeof download === "string") {
|
|
1836
|
+
download = {filename: download};
|
|
1837
|
+
}
|
|
1838
|
+
link.download = download.filename || "chart.png"; // https://caniuse.com/download
|
|
1839
|
+
|
|
1840
|
+
link.style.position = "absolute";
|
|
1841
|
+
link.style.top = "20px";
|
|
1842
|
+
link.style.right = "20px";
|
|
1843
|
+
link.style.zIndex = 1000;
|
|
1844
|
+
link.style.lineHeight = "20px";
|
|
1845
|
+
link.target = "_blank"; // for safari
|
|
1846
|
+
var image = document.createElement("img");
|
|
1847
|
+
image.alt = "Download";
|
|
1848
|
+
image.style.border = "none";
|
|
1849
|
+
// icon from font-awesome
|
|
1850
|
+
// http://fa2png.io/
|
|
1851
|
+
image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAABCFBMVEUAAADMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMywEsqxAAAAV3RSTlMAAQIDBggJCgsMDQ4PERQaHB0eISIjJCouLzE0OTo/QUJHSUpLTU5PUllhYmltcHh5foWLjI+SlaCio6atr7S1t7m6vsHHyM7R2tze5Obo7fHz9ff5+/1hlxK2AAAA30lEQVQYGUXBhVYCQQBA0TdYWAt2d3d3YWAHyur7/z9xgD16Lw0DW+XKx+1GgX+FRzM3HWQWrHl5N/oapW5RPe0PkBu+UYeICvozTWZVK23Ao04B79oJrOsJDOoxkZoQPWgX29pHpCZEk7rEvQYiNSFq1UMqvlCjJkRBS1R8hb00Vb/TajtBL7nTHE1X1vyMQF732dQhyF2o6SAwrzP06iUQzvwsArlnzcOdrgBhJyHa1QOgO9U1GsKuvjUTjavliZYQ8nNPapG6sap/3nrIdJ6bOWzmX/fy0XVpfzZP3S8OJT3g9EEiJwAAAABJRU5ErkJggg==";
|
|
1852
|
+
link.appendChild(image);
|
|
1853
|
+
element.style.position = "relative";
|
|
1854
|
+
|
|
1855
|
+
chart.__downloadAttached = true;
|
|
1856
|
+
|
|
1857
|
+
// mouseenter
|
|
1858
|
+
chart.__enterEvent = addEvent(element, "mouseover", function(e) {
|
|
1859
|
+
var related = e.relatedTarget;
|
|
1860
|
+
// check download option again to ensure it wasn't changed
|
|
1861
|
+
if ((!related || (related !== this && !childOf(this, related))) && chart.options.download) {
|
|
1862
|
+
link.href = chart.toImage(download);
|
|
1863
|
+
element.appendChild(link);
|
|
1864
|
+
}
|
|
1865
|
+
});
|
|
1866
|
+
|
|
1867
|
+
// mouseleave
|
|
1868
|
+
chart.__leaveEvent = addEvent(element, "mouseout", function(e) {
|
|
1869
|
+
var related = e.relatedTarget;
|
|
1870
|
+
if (!related || (related !== this && !childOf(this, related))) {
|
|
1871
|
+
if (link.parentNode) {
|
|
1872
|
+
link.parentNode.removeChild(link);
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
});
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
// https://stackoverflow.com/questions/10149963/adding-event-listener-cross-browser
|
|
1879
|
+
function addEvent(elem, event, fn) {
|
|
1880
|
+
if (elem.addEventListener) {
|
|
1881
|
+
elem.addEventListener(event, fn, false);
|
|
1882
|
+
return fn;
|
|
1883
|
+
} else {
|
|
1884
|
+
var fn2 = function() {
|
|
1885
|
+
// set the this pointer same as addEventListener when fn is called
|
|
1886
|
+
return(fn.call(elem, window.event));
|
|
1887
|
+
};
|
|
1888
|
+
elem.attachEvent("on" + event, fn2);
|
|
1889
|
+
return fn2;
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
function removeEvent(elem, event, fn) {
|
|
1894
|
+
if (elem.removeEventListener) {
|
|
1895
|
+
elem.removeEventListener(event, fn, false);
|
|
1896
|
+
} else {
|
|
1897
|
+
elem.detachEvent("on" + event, fn);
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1901
|
+
// https://gist.github.com/shawnbot/4166283
|
|
1902
|
+
function childOf(p, c) {
|
|
1903
|
+
if (p === c) { return false; }
|
|
1904
|
+
while (c && c !== p) { c = c.parentNode; }
|
|
1905
|
+
return c === p;
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1689
1908
|
var pendingRequests = [], runningRequests = 0, maxRequests = 4;
|
|
1690
1909
|
|
|
1691
1910
|
function pushRequest(url, success, error) {
|
|
@@ -1804,86 +2023,6 @@
|
|
|
1804
2023
|
}
|
|
1805
2024
|
}
|
|
1806
2025
|
|
|
1807
|
-
function addDownloadButton(chart) {
|
|
1808
|
-
var element = chart.element;
|
|
1809
|
-
var link = document.createElement("a");
|
|
1810
|
-
|
|
1811
|
-
var download = chart.options.download;
|
|
1812
|
-
if (download === true) {
|
|
1813
|
-
download = {};
|
|
1814
|
-
} else if (typeof download === "string") {
|
|
1815
|
-
download = {filename: download};
|
|
1816
|
-
}
|
|
1817
|
-
link.download = download.filename || "chart.png"; // https://caniuse.com/download
|
|
1818
|
-
|
|
1819
|
-
link.style.position = "absolute";
|
|
1820
|
-
link.style.top = "20px";
|
|
1821
|
-
link.style.right = "20px";
|
|
1822
|
-
link.style.zIndex = 1000;
|
|
1823
|
-
link.style.lineHeight = "20px";
|
|
1824
|
-
link.target = "_blank"; // for safari
|
|
1825
|
-
var image = document.createElement("img");
|
|
1826
|
-
image.alt = "Download";
|
|
1827
|
-
image.style.border = "none";
|
|
1828
|
-
// icon from font-awesome
|
|
1829
|
-
// http://fa2png.io/
|
|
1830
|
-
image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAABCFBMVEUAAADMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMywEsqxAAAAV3RSTlMAAQIDBggJCgsMDQ4PERQaHB0eISIjJCouLzE0OTo/QUJHSUpLTU5PUllhYmltcHh5foWLjI+SlaCio6atr7S1t7m6vsHHyM7R2tze5Obo7fHz9ff5+/1hlxK2AAAA30lEQVQYGUXBhVYCQQBA0TdYWAt2d3d3YWAHyur7/z9xgD16Lw0DW+XKx+1GgX+FRzM3HWQWrHl5N/oapW5RPe0PkBu+UYeICvozTWZVK23Ao04B79oJrOsJDOoxkZoQPWgX29pHpCZEk7rEvQYiNSFq1UMqvlCjJkRBS1R8hb00Vb/TajtBL7nTHE1X1vyMQF732dQhyF2o6SAwrzP06iUQzvwsArlnzcOdrgBhJyHa1QOgO9U1GsKuvjUTjavliZYQ8nNPapG6sap/3nrIdJ6bOWzmX/fy0XVpfzZP3S8OJT3g9EEiJwAAAABJRU5ErkJggg==";
|
|
1831
|
-
link.appendChild(image);
|
|
1832
|
-
element.style.position = "relative";
|
|
1833
|
-
|
|
1834
|
-
chart.__downloadAttached = true;
|
|
1835
|
-
|
|
1836
|
-
// mouseenter
|
|
1837
|
-
chart.__enterEvent = addEvent(element, "mouseover", function(e) {
|
|
1838
|
-
var related = e.relatedTarget;
|
|
1839
|
-
// check download option again to ensure it wasn't changed
|
|
1840
|
-
if ((!related || (related !== this && !childOf(this, related))) && chart.options.download) {
|
|
1841
|
-
link.href = chart.toImage(download);
|
|
1842
|
-
element.appendChild(link);
|
|
1843
|
-
}
|
|
1844
|
-
});
|
|
1845
|
-
|
|
1846
|
-
// mouseleave
|
|
1847
|
-
chart.__leaveEvent = addEvent(element, "mouseout", function(e) {
|
|
1848
|
-
var related = e.relatedTarget;
|
|
1849
|
-
if (!related || (related !== this && !childOf(this, related))) {
|
|
1850
|
-
if (link.parentNode) {
|
|
1851
|
-
link.parentNode.removeChild(link);
|
|
1852
|
-
}
|
|
1853
|
-
}
|
|
1854
|
-
});
|
|
1855
|
-
}
|
|
1856
|
-
|
|
1857
|
-
// https://stackoverflow.com/questions/10149963/adding-event-listener-cross-browser
|
|
1858
|
-
function addEvent(elem, event, fn) {
|
|
1859
|
-
if (elem.addEventListener) {
|
|
1860
|
-
elem.addEventListener(event, fn, false);
|
|
1861
|
-
return fn;
|
|
1862
|
-
} else {
|
|
1863
|
-
var fn2 = function() {
|
|
1864
|
-
// set the this pointer same as addEventListener when fn is called
|
|
1865
|
-
return(fn.call(elem, window.event));
|
|
1866
|
-
};
|
|
1867
|
-
elem.attachEvent("on" + event, fn2);
|
|
1868
|
-
return fn2;
|
|
1869
|
-
}
|
|
1870
|
-
}
|
|
1871
|
-
|
|
1872
|
-
function removeEvent(elem, event, fn) {
|
|
1873
|
-
if (elem.removeEventListener) {
|
|
1874
|
-
elem.removeEventListener(event, fn, false);
|
|
1875
|
-
} else {
|
|
1876
|
-
elem.detachEvent("on" + event, fn);
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
|
-
|
|
1880
|
-
// https://gist.github.com/shawnbot/4166283
|
|
1881
|
-
function childOf(p, c) {
|
|
1882
|
-
if (p === c) { return false; }
|
|
1883
|
-
while (c && c !== p) { c = c.parentNode; }
|
|
1884
|
-
return c === p;
|
|
1885
|
-
}
|
|
1886
|
-
|
|
1887
2026
|
function getAdapterType(library) {
|
|
1888
2027
|
if (library) {
|
|
1889
2028
|
if (library.product === "Highcharts") {
|
|
@@ -1920,19 +2059,6 @@
|
|
|
1920
2059
|
}
|
|
1921
2060
|
}
|
|
1922
2061
|
|
|
1923
|
-
function dataEmpty(data, chartType) {
|
|
1924
|
-
if (chartType === "PieChart" || chartType === "GeoChart" || chartType === "Timeline") {
|
|
1925
|
-
return data.length === 0;
|
|
1926
|
-
} else {
|
|
1927
|
-
for (var i = 0; i < data.length; i++) {
|
|
1928
|
-
if (data[i].data.length > 0) {
|
|
1929
|
-
return false;
|
|
1930
|
-
}
|
|
1931
|
-
}
|
|
1932
|
-
return true;
|
|
1933
|
-
}
|
|
1934
|
-
}
|
|
1935
|
-
|
|
1936
2062
|
function renderChart(chartType, chart) {
|
|
1937
2063
|
if (dataEmpty(chart.data, chartType)) {
|
|
1938
2064
|
var message = chart.options.empty || (chart.options.messages && chart.options.messages.empty) || "No data";
|
|
@@ -1970,121 +2096,6 @@
|
|
|
1970
2096
|
}
|
|
1971
2097
|
}
|
|
1972
2098
|
|
|
1973
|
-
// process data
|
|
1974
|
-
|
|
1975
|
-
var toFormattedKey = function (key, keyType) {
|
|
1976
|
-
if (keyType === "number") {
|
|
1977
|
-
key = toFloat(key);
|
|
1978
|
-
} else if (keyType === "datetime") {
|
|
1979
|
-
key = toDate(key);
|
|
1980
|
-
} else {
|
|
1981
|
-
key = toStr(key);
|
|
1982
|
-
}
|
|
1983
|
-
return key;
|
|
1984
|
-
};
|
|
1985
|
-
|
|
1986
|
-
var formatSeriesData = function (data, keyType) {
|
|
1987
|
-
var r = [], key, j;
|
|
1988
|
-
for (j = 0; j < data.length; j++) {
|
|
1989
|
-
if (keyType === "bubble") {
|
|
1990
|
-
r.push([toFloat(data[j][0]), toFloat(data[j][1]), toFloat(data[j][2])]);
|
|
1991
|
-
} else {
|
|
1992
|
-
key = toFormattedKey(data[j][0], keyType);
|
|
1993
|
-
r.push([key, toFloat(data[j][1])]);
|
|
1994
|
-
}
|
|
1995
|
-
}
|
|
1996
|
-
if (keyType === "datetime") {
|
|
1997
|
-
r.sort(sortByTime);
|
|
1998
|
-
} else if (keyType === "number") {
|
|
1999
|
-
r.sort(sortByNumberSeries);
|
|
2000
|
-
}
|
|
2001
|
-
return r;
|
|
2002
|
-
};
|
|
2003
|
-
|
|
2004
|
-
function detectXType(series, noDatetime, options) {
|
|
2005
|
-
if (dataEmpty(series)) {
|
|
2006
|
-
if ((options.xmin || options.xmax) && (!options.xmin || isDate(options.xmin)) && (!options.xmax || isDate(options.xmax))) {
|
|
2007
|
-
return "datetime";
|
|
2008
|
-
} else {
|
|
2009
|
-
return "number";
|
|
2010
|
-
}
|
|
2011
|
-
} else if (detectXTypeWithFunction(series, isNumber)) {
|
|
2012
|
-
return "number";
|
|
2013
|
-
} else if (!noDatetime && detectXTypeWithFunction(series, isDate)) {
|
|
2014
|
-
return "datetime";
|
|
2015
|
-
} else {
|
|
2016
|
-
return "string";
|
|
2017
|
-
}
|
|
2018
|
-
}
|
|
2019
|
-
|
|
2020
|
-
function detectXTypeWithFunction(series, func) {
|
|
2021
|
-
var i, j, data;
|
|
2022
|
-
for (i = 0; i < series.length; i++) {
|
|
2023
|
-
data = toArr(series[i].data);
|
|
2024
|
-
for (j = 0; j < data.length; j++) {
|
|
2025
|
-
if (!func(data[j][0])) {
|
|
2026
|
-
return false;
|
|
2027
|
-
}
|
|
2028
|
-
}
|
|
2029
|
-
}
|
|
2030
|
-
return true;
|
|
2031
|
-
}
|
|
2032
|
-
|
|
2033
|
-
// creates a shallow copy of each element of the array
|
|
2034
|
-
// elements are expected to be objects
|
|
2035
|
-
function copySeries(series) {
|
|
2036
|
-
var newSeries = [], i, j;
|
|
2037
|
-
for (i = 0; i < series.length; i++) {
|
|
2038
|
-
var copy = {};
|
|
2039
|
-
for (j in series[i]) {
|
|
2040
|
-
if (series[i].hasOwnProperty(j)) {
|
|
2041
|
-
copy[j] = series[i][j];
|
|
2042
|
-
}
|
|
2043
|
-
}
|
|
2044
|
-
newSeries.push(copy);
|
|
2045
|
-
}
|
|
2046
|
-
return newSeries;
|
|
2047
|
-
}
|
|
2048
|
-
|
|
2049
|
-
function processSeries(chart, keyType, noDatetime) {
|
|
2050
|
-
var i;
|
|
2051
|
-
|
|
2052
|
-
var opts = chart.options;
|
|
2053
|
-
var series = chart.rawData;
|
|
2054
|
-
|
|
2055
|
-
// see if one series or multiple
|
|
2056
|
-
if (!isArray(series) || typeof series[0] !== "object" || isArray(series[0])) {
|
|
2057
|
-
series = [{name: opts.label, data: series}];
|
|
2058
|
-
chart.singleSeriesFormat = true;
|
|
2059
|
-
} else {
|
|
2060
|
-
chart.singleSeriesFormat = false;
|
|
2061
|
-
}
|
|
2062
|
-
|
|
2063
|
-
// convert to array
|
|
2064
|
-
// must come before dataEmpty check
|
|
2065
|
-
series = copySeries(series);
|
|
2066
|
-
for (i = 0; i < series.length; i++) {
|
|
2067
|
-
series[i].data = toArr(series[i].data);
|
|
2068
|
-
}
|
|
2069
|
-
|
|
2070
|
-
chart.xtype = keyType ? keyType : (opts.discrete ? "string" : detectXType(series, noDatetime, opts));
|
|
2071
|
-
|
|
2072
|
-
// right format
|
|
2073
|
-
for (i = 0; i < series.length; i++) {
|
|
2074
|
-
series[i].data = formatSeriesData(series[i].data, chart.xtype);
|
|
2075
|
-
}
|
|
2076
|
-
|
|
2077
|
-
return series;
|
|
2078
|
-
}
|
|
2079
|
-
|
|
2080
|
-
function processSimple(chart) {
|
|
2081
|
-
var perfectData = toArr(chart.rawData), i;
|
|
2082
|
-
for (i = 0; i < perfectData.length; i++) {
|
|
2083
|
-
perfectData[i] = [toStr(perfectData[i][0]), toFloat(perfectData[i][1])];
|
|
2084
|
-
}
|
|
2085
|
-
return perfectData;
|
|
2086
|
-
}
|
|
2087
|
-
|
|
2088
2099
|
// define classes
|
|
2089
2100
|
|
|
2090
2101
|
var Chart = function Chart(element, dataSource, options) {
|
|
@@ -2192,8 +2203,8 @@
|
|
|
2192
2203
|
if (this.adapter === "chartjs") {
|
|
2193
2204
|
if (download && download.background && download.background !== "transparent") {
|
|
2194
2205
|
// https://stackoverflow.com/questions/30464750/chartjs-line-chart-set-background-color
|
|
2195
|
-
var canvas = this.chart.
|
|
2196
|
-
var ctx = this.chart.
|
|
2206
|
+
var canvas = this.chart.canvas;
|
|
2207
|
+
var ctx = this.chart.ctx;
|
|
2197
2208
|
var tmpCanvas = document.createElement("canvas");
|
|
2198
2209
|
var tmpCtx = tmpCanvas.getContext("2d");
|
|
2199
2210
|
tmpCanvas.width = ctx.canvas.width;
|
|
@@ -2206,9 +2217,7 @@
|
|
|
2206
2217
|
return this.chart.toBase64Image();
|
|
2207
2218
|
}
|
|
2208
2219
|
} else {
|
|
2209
|
-
|
|
2210
|
-
// throw new Error("Feature only available for Chart.js");
|
|
2211
|
-
return null;
|
|
2220
|
+
throw new Error("Feature only available for Chart.js");
|
|
2212
2221
|
}
|
|
2213
2222
|
};
|
|
2214
2223
|
|