* [Heatmap] Adjusting grid calculation for consistent grid layout Date math is hard! This addresses a problem in how the heatmap lays calculates days to layout the grid. The calculations were being thrown off in some scenarios by a combination of factors including timezone offsets, time of day, and daylight savings time. This patch should correct all this by forcing each day to be midnight UTC when laying out the grid. Co-authored-by: Michael Bester <michael@kimili.com> Co-authored-by: t47io <t47@alumni.stanford.edu> Co-authored-by: Saqib Ansari <nextchamp.saqib@gmail.com>
564 lines
16 KiB
JavaScript
564 lines
16 KiB
JavaScript
(function () {
|
|
'use strict';
|
|
|
|
var HEATMAP_COLORS_BLUE = ['#ebedf0', '#c0ddf9', '#73b3f3', '#3886e1', '#17459e'];
|
|
var HEATMAP_COLORS_YELLOW = ['#ebedf0', '#fdf436', '#ffc700', '#ff9100', '#06001c'];
|
|
|
|
// Universal constants
|
|
var ANGLE_RATIO = Math.PI / 180;
|
|
|
|
/**
|
|
* Shuffles array in place. ES6 version
|
|
* @param {Array} array An array containing the items.
|
|
*/
|
|
function shuffle(array) {
|
|
// Awesomeness: https://bost.ocks.org/mike/shuffle/
|
|
// https://stackoverflow.com/a/2450976/6495043
|
|
// https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array?noredirect=1&lq=1
|
|
|
|
for (var i = array.length - 1; i > 0; i--) {
|
|
var j = Math.floor(Math.random() * (i + 1));
|
|
var _ref = [array[j], array[i]];
|
|
array[i] = _ref[0];
|
|
array[j] = _ref[1];
|
|
}
|
|
|
|
return array;
|
|
}
|
|
|
|
// https://stackoverflow.com/a/29325222
|
|
function getRandomBias(min, max, bias, influence) {
|
|
var range = max - min;
|
|
var biasValue = range * bias + min;
|
|
var rnd = Math.random() * range + min,
|
|
// random in range
|
|
mix = Math.random() * influence; // random mixer
|
|
return rnd * (1 - mix) + biasValue * mix; // mix full range and bias
|
|
}
|
|
|
|
// Playing around with dates
|
|
var NO_OF_MILLIS = 1000;
|
|
var SEC_IN_DAY = 86400;
|
|
var MONTH_NAMES_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
|
|
function clone(date) {
|
|
return new Date(date.getTime());
|
|
}
|
|
|
|
function timestampSec(date) {
|
|
return date.getTime() / NO_OF_MILLIS;
|
|
}
|
|
|
|
function timestampToMidnight(timestamp) {
|
|
var roundAhead = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
|
|
var midnightTs = Math.floor(timestamp - timestamp % SEC_IN_DAY);
|
|
if (roundAhead) {
|
|
return midnightTs + SEC_IN_DAY;
|
|
}
|
|
return midnightTs;
|
|
}
|
|
|
|
// mutates
|
|
function addDays(date, numberOfDays) {
|
|
date.setDate(date.getDate() + numberOfDays);
|
|
}
|
|
|
|
// Composite Chart
|
|
// ================================================================================
|
|
var reportCountList = [152, 222, 199, 287, 534, 709, 1179, 1256, 1632, 1856, 1850];
|
|
|
|
var lineCompositeData = {
|
|
labels: ["2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017"],
|
|
|
|
yMarkers: [{
|
|
label: "Average 100 reports/month",
|
|
value: 1200,
|
|
options: { labelPos: "left" }
|
|
}],
|
|
|
|
datasets: [{
|
|
name: "Events",
|
|
values: reportCountList
|
|
}]
|
|
};
|
|
|
|
var fireball_5_25 = [[4, 0, 3, 1, 1, 2, 1, 1, 1, 0, 1, 1], [2, 3, 3, 2, 1, 3, 0, 1, 2, 7, 10, 4], [5, 6, 2, 4, 0, 1, 4, 3, 0, 2, 0, 1], [0, 2, 6, 2, 1, 1, 2, 3, 6, 3, 7, 8], [6, 8, 7, 7, 4, 5, 6, 5, 22, 12, 10, 11], [7, 10, 11, 7, 3, 2, 7, 7, 11, 15, 22, 20], [13, 16, 21, 18, 19, 17, 12, 17, 31, 28, 25, 29], [24, 14, 21, 14, 11, 15, 19, 21, 41, 22, 32, 18], [31, 20, 30, 22, 14, 17, 21, 35, 27, 50, 117, 24], [32, 24, 21, 27, 11, 27, 43, 37, 44, 40, 48, 32], [31, 38, 36, 26, 23, 23, 25, 29, 26, 47, 61, 50]];
|
|
var fireball_2_5 = [[22, 6, 6, 9, 7, 8, 6, 14, 19, 10, 8, 20], [11, 13, 12, 8, 9, 11, 9, 13, 10, 22, 40, 24], [20, 13, 13, 19, 13, 10, 14, 13, 20, 18, 5, 9], [7, 13, 16, 19, 12, 11, 21, 27, 27, 24, 33, 33], [38, 25, 28, 22, 31, 21, 35, 42, 37, 32, 46, 53], [50, 33, 36, 34, 35, 28, 27, 52, 58, 59, 75, 69], [54, 67, 67, 45, 66, 51, 38, 64, 90, 113, 116, 87], [84, 52, 56, 51, 55, 46, 50, 87, 114, 83, 152, 93], [73, 58, 59, 63, 56, 51, 83, 140, 103, 115, 265, 89], [106, 95, 94, 71, 77, 75, 99, 136, 129, 154, 168, 156], [81, 102, 95, 72, 58, 91, 89, 122, 124, 135, 183, 171]];
|
|
var fireballOver25 = [
|
|
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0], [1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2], [3, 2, 1, 3, 2, 0, 2, 2, 2, 3, 0, 1], [2, 3, 5, 2, 1, 3, 0, 2, 3, 5, 1, 4], [7, 4, 6, 1, 9, 2, 2, 2, 20, 9, 4, 9], [5, 6, 1, 2, 5, 4, 5, 5, 16, 9, 14, 9], [5, 4, 7, 5, 1, 5, 3, 3, 5, 7, 22, 2], [5, 13, 11, 6, 1, 7, 9, 8, 14, 17, 16, 3], [8, 9, 8, 6, 4, 8, 5, 6, 14, 11, 21, 12]];
|
|
|
|
var barCompositeData = {
|
|
labels: MONTH_NAMES_SHORT,
|
|
datasets: [{
|
|
name: "Over 25 reports",
|
|
values: fireballOver25[9]
|
|
}, {
|
|
name: "5 to 25 reports",
|
|
values: fireball_5_25[9]
|
|
}, {
|
|
name: "2 to 5 reports",
|
|
values: fireball_2_5[9]
|
|
}]
|
|
};
|
|
|
|
// Demo Chart multitype Chart
|
|
// ================================================================================
|
|
var typeData = {
|
|
labels: ["12am-3am", "3am-6am", "6am-9am", "9am-12pm", "12pm-3pm", "3pm-6pm", "6pm-9pm", "9pm-12am"],
|
|
|
|
yMarkers: [{
|
|
label: "Marker",
|
|
value: 43,
|
|
options: { labelPos: "left" }
|
|
// type: 'dashed'
|
|
}],
|
|
|
|
yRegions: [{
|
|
label: "Region",
|
|
start: -10,
|
|
end: 50,
|
|
options: { labelPos: "right" }
|
|
}],
|
|
|
|
datasets: [{
|
|
name: "Some Data",
|
|
values: [18, 40, 30, 35, 8, 52, 17, -4],
|
|
axisPosition: "right",
|
|
chartType: "bar"
|
|
}, {
|
|
name: "Another Set",
|
|
values: [30, 50, -10, 15, 18, 32, 27, 14],
|
|
axisPosition: "right",
|
|
chartType: "bar"
|
|
}, {
|
|
name: "Yet Another",
|
|
values: [15, 20, -3, -15, 58, 12, -17, 37],
|
|
chartType: "line"
|
|
}]
|
|
};
|
|
|
|
var trendsData = {
|
|
labels: [1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016],
|
|
datasets: [{
|
|
values: [132.9, 150.0, 149.4, 148.0, 94.4, 97.6, 54.1, 49.2, 22.5, 18.4, 39.3, 131.0, 220.1, 218.9, 198.9, 162.4, 91.0, 60.5, 20.6, 14.8, 33.9, 123.0, 211.1, 191.8, 203.3, 133.0, 76.1, 44.9, 25.1, 11.6, 28.9, 88.3, 136.3, 173.9, 170.4, 163.6, 99.3, 65.3, 45.8, 24.7, 12.6, 4.2, 4.8, 24.9, 80.8, 84.5, 94.0, 113.3, 69.8, 39.8]
|
|
}]
|
|
};
|
|
|
|
var moonData = {
|
|
names: ["Ganymede", "Callisto", "Io", "Europa"],
|
|
masses: [14819000, 10759000, 8931900, 4800000],
|
|
distances: [1070.412, 1882.709, 421.7, 671.034],
|
|
diameters: [5262.4, 4820.6, 3637.4, 3121.6]
|
|
};
|
|
|
|
var demoConfig = {
|
|
lineComposite: {
|
|
elementID: "#chart-composite-1",
|
|
options: {
|
|
title: "Fireball/Bolide Events - Yearly (reported)",
|
|
data: lineCompositeData,
|
|
type: "line",
|
|
height: 190,
|
|
colors: ["green"],
|
|
isNavigable: 1,
|
|
valuesOverPoints: 1,
|
|
|
|
lineOptions: {
|
|
dotSize: 8
|
|
}
|
|
}
|
|
},
|
|
|
|
barComposite: {
|
|
elementID: "#chart-composite-2",
|
|
options: {
|
|
data: barCompositeData,
|
|
type: "bar",
|
|
height: 210,
|
|
colors: ["violet", "light-blue", "#46a9f9"],
|
|
valuesOverPoints: 1,
|
|
axisOptions: {
|
|
xAxisMode: "tick",
|
|
shortenYAxisNumbers: true
|
|
},
|
|
barOptions: {
|
|
stacked: 1
|
|
}
|
|
}
|
|
},
|
|
|
|
demoMain: {
|
|
elementID: "",
|
|
options: {
|
|
title: "My Awesome Chart",
|
|
data: "typeData",
|
|
type: "axis-mixed",
|
|
height: 300,
|
|
colors: ["purple", "magenta", "light-blue"],
|
|
maxSlices: 10,
|
|
|
|
tooltipOptions: {
|
|
formatTooltipX: function formatTooltipX(d) {
|
|
return (d + '').toUpperCase();
|
|
},
|
|
formatTooltipY: function formatTooltipY(d) {
|
|
return d + ' pts';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// import { lineComposite, barComposite } from './demoConfig';
|
|
// ================================================================================
|
|
|
|
var Chart = frappe.Chart; // eslint-disable-line no-undef
|
|
|
|
var lc = demoConfig.lineComposite;
|
|
var lineCompositeChart = new Chart(lc.elementID, lc.options);
|
|
|
|
var bc = demoConfig.barComposite;
|
|
var barCompositeChart = new Chart(bc.elementID, bc.options);
|
|
|
|
lineCompositeChart.parent.addEventListener('data-select', function (e) {
|
|
var i = e.index;
|
|
barCompositeChart.updateDatasets([fireballOver25[i], fireball_5_25[i], fireball_2_5[i]]);
|
|
});
|
|
|
|
// ================================================================================
|
|
|
|
var customColors = ['purple', 'magenta', 'light-blue'];
|
|
var typeChartArgs = {
|
|
title: "My Awesome Chart",
|
|
data: typeData,
|
|
type: 'axis-mixed',
|
|
height: 300,
|
|
colors: customColors,
|
|
|
|
// maxLegendPoints: 6,
|
|
maxSlices: 10,
|
|
|
|
tooltipOptions: {
|
|
formatTooltipX: function formatTooltipX(d) {
|
|
return (d + '').toUpperCase();
|
|
},
|
|
formatTooltipY: function formatTooltipY(d) {
|
|
return d + ' pts';
|
|
}
|
|
}
|
|
};
|
|
|
|
var aggrChart = new Chart("#chart-aggr", typeChartArgs);
|
|
|
|
Array.prototype.slice.call(document.querySelectorAll('.aggr-type-buttons button')).map(function (el) {
|
|
el.addEventListener('click', function (e) {
|
|
var btn = e.target;
|
|
var type = btn.getAttribute('data-type');
|
|
typeChartArgs.type = type;
|
|
if (type !== 'axis-mixed') {
|
|
typeChartArgs.colors = undefined;
|
|
} else {
|
|
typeChartArgs.colors = customColors;
|
|
}
|
|
|
|
if (type !== 'percentage') {
|
|
typeChartArgs.height = 300;
|
|
} else {
|
|
typeChartArgs.height = undefined;
|
|
}
|
|
|
|
var newChart = new Chart("#chart-aggr", typeChartArgs);
|
|
if (newChart) {
|
|
aggrChart = newChart;
|
|
}
|
|
Array.prototype.slice.call(btn.parentNode.querySelectorAll('button')).map(function (el) {
|
|
el.classList.remove('active');
|
|
});
|
|
btn.classList.add('active');
|
|
});
|
|
});
|
|
|
|
document.querySelector('.export-aggr').addEventListener('click', function () {
|
|
aggrChart.export();
|
|
});
|
|
|
|
// Update values chart
|
|
// ================================================================================
|
|
var updateDataAllLabels = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon"];
|
|
|
|
var getRandom = function getRandom() {
|
|
return Math.floor(getRandomBias(-40, 60, 0.8, 1));
|
|
};
|
|
var updateDataAllValues = Array.from({ length: 30 }, getRandom);
|
|
|
|
// We're gonna be shuffling this
|
|
var updateDataAllIndices = updateDataAllLabels.map(function (d, i) {
|
|
return i;
|
|
});
|
|
|
|
var getUpdateData = function getUpdateData(source_array) {
|
|
var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10;
|
|
|
|
var indices = updateDataAllIndices.slice(0, length);
|
|
return indices.map(function (index) {
|
|
return source_array[index];
|
|
});
|
|
};
|
|
|
|
var updateData = {
|
|
labels: getUpdateData(updateDataAllLabels),
|
|
datasets: [{
|
|
"values": getUpdateData(updateDataAllValues)
|
|
}],
|
|
yMarkers: [{
|
|
label: "Altitude",
|
|
value: 25,
|
|
type: 'dashed'
|
|
}],
|
|
yRegions: [{
|
|
label: "Range",
|
|
start: 10,
|
|
end: 45
|
|
}]
|
|
};
|
|
|
|
var updateChart = new Chart("#chart-update", {
|
|
data: updateData,
|
|
type: 'line',
|
|
height: 300,
|
|
colors: ['#ff6c03'],
|
|
lineOptions: {
|
|
// hideLine: 1,
|
|
regionFill: 1
|
|
}
|
|
});
|
|
|
|
var chartUpdateButtons = document.querySelector('.chart-update-buttons');
|
|
|
|
chartUpdateButtons.querySelector('[data-update="random"]').addEventListener("click", function () {
|
|
shuffle(updateDataAllIndices);
|
|
var value = getRandom();
|
|
var start = getRandom();
|
|
var end = getRandom();
|
|
var data = {
|
|
labels: updateDataAllLabels.slice(0, 10),
|
|
datasets: [{ values: getUpdateData(updateDataAllValues) }],
|
|
yMarkers: [{
|
|
label: "Altitude",
|
|
value: value,
|
|
type: 'dashed'
|
|
}],
|
|
yRegions: [{
|
|
label: "Range",
|
|
start: start,
|
|
end: end
|
|
}]
|
|
};
|
|
updateChart.update(data);
|
|
});
|
|
|
|
chartUpdateButtons.querySelector('[data-update="add"]').addEventListener("click", function () {
|
|
var index = updateChart.state.datasetLength; // last index to add
|
|
if (index >= updateDataAllIndices.length) return;
|
|
updateChart.addDataPoint(updateDataAllLabels[index], [updateDataAllValues[index]]);
|
|
});
|
|
|
|
chartUpdateButtons.querySelector('[data-update="remove"]').addEventListener("click", function () {
|
|
updateChart.removeDataPoint();
|
|
});
|
|
|
|
document.querySelector('.export-update').addEventListener('click', function () {
|
|
updateChart.export();
|
|
});
|
|
|
|
// Trends Chart
|
|
// ================================================================================
|
|
|
|
var plotChartArgs = {
|
|
title: "Mean Total Sunspot Count - Yearly",
|
|
data: trendsData,
|
|
type: 'line',
|
|
height: 300,
|
|
colors: ['#238e38'],
|
|
lineOptions: {
|
|
hideDots: 1,
|
|
heatline: 1
|
|
},
|
|
axisOptions: {
|
|
xAxisMode: 'tick',
|
|
yAxisMode: 'span',
|
|
xIsSeries: 1
|
|
}
|
|
};
|
|
|
|
var trendsChart = new Chart("#chart-trends", plotChartArgs);
|
|
|
|
Array.prototype.slice.call(document.querySelectorAll('.chart-plot-buttons button')).map(function (el) {
|
|
el.addEventListener('click', function (e) {
|
|
var btn = e.target;
|
|
var type = btn.getAttribute('data-type');
|
|
var config = {};
|
|
config[type] = 1;
|
|
|
|
if (['regionFill', 'heatline'].includes(type)) {
|
|
config.hideDots = 1;
|
|
}
|
|
|
|
// plotChartArgs.init = false;
|
|
plotChartArgs.lineOptions = config;
|
|
|
|
new Chart("#chart-trends", plotChartArgs);
|
|
|
|
Array.prototype.slice.call(btn.parentNode.querySelectorAll('button')).map(function (el) {
|
|
el.classList.remove('active');
|
|
});
|
|
btn.classList.add('active');
|
|
});
|
|
});
|
|
|
|
document.querySelector('.export-trends').addEventListener('click', function () {
|
|
trendsChart.export();
|
|
});
|
|
|
|
// Event chart
|
|
// ================================================================================
|
|
|
|
|
|
var eventsData = {
|
|
labels: ["Ganymede", "Callisto", "Io", "Europa"],
|
|
datasets: [{
|
|
"values": moonData.distances,
|
|
"formatted": moonData.distances.map(function (d) {
|
|
return d * 1000 + " km";
|
|
})
|
|
}]
|
|
};
|
|
|
|
var eventsChart = new Chart("#chart-events", {
|
|
title: "Jupiter's Moons: Semi-major Axis (1000 km)",
|
|
data: eventsData,
|
|
type: 'bar',
|
|
height: 330,
|
|
colors: ['grey'],
|
|
isNavigable: 1
|
|
});
|
|
|
|
var dataDiv = document.querySelector('.chart-events-data');
|
|
|
|
eventsChart.parent.addEventListener('data-select', function (e) {
|
|
var name = moonData.names[e.index];
|
|
dataDiv.querySelector('.moon-name').innerHTML = name;
|
|
dataDiv.querySelector('.semi-major-axis').innerHTML = moonData.distances[e.index] * 1000;
|
|
dataDiv.querySelector('.mass').innerHTML = moonData.masses[e.index];
|
|
dataDiv.querySelector('.diameter').innerHTML = moonData.diameters[e.index];
|
|
dataDiv.querySelector('img').src = "./assets/img/" + name.toLowerCase() + ".jpg";
|
|
});
|
|
|
|
// Heatmap
|
|
// ================================================================================
|
|
|
|
var today = new Date();
|
|
var start = clone(today);
|
|
addDays(start, 4);
|
|
var end = clone(start);
|
|
start.setFullYear(start.getFullYear() - 2);
|
|
end.setFullYear(end.getFullYear() - 1);
|
|
|
|
var dataPoints = {};
|
|
|
|
var startTs = timestampSec(start);
|
|
var endTs = timestampSec(end);
|
|
|
|
startTs = timestampToMidnight(startTs);
|
|
endTs = timestampToMidnight(endTs, true);
|
|
|
|
while (startTs < endTs) {
|
|
dataPoints[parseInt(startTs)] = Math.floor(getRandomBias(0, 5, 0.2, 1));
|
|
startTs += SEC_IN_DAY;
|
|
}
|
|
|
|
var heatmapData = {
|
|
dataPoints: dataPoints,
|
|
start: start,
|
|
end: end
|
|
};
|
|
|
|
var heatmapArgs = {
|
|
title: "Monthly Distribution",
|
|
data: heatmapData,
|
|
type: 'heatmap',
|
|
discreteDomains: 1,
|
|
countLabel: 'Level',
|
|
colors: HEATMAP_COLORS_BLUE,
|
|
legendScale: [0, 1, 2, 4, 5]
|
|
};
|
|
var heatmapChart = new Chart("#chart-heatmap", heatmapArgs);
|
|
|
|
Array.prototype.slice.call(document.querySelectorAll('.heatmap-mode-buttons button')).map(function (el) {
|
|
el.addEventListener('click', function (e) {
|
|
var btn = e.target;
|
|
var mode = btn.getAttribute('data-mode');
|
|
var discreteDomains = 0;
|
|
|
|
if (mode === 'discrete') {
|
|
discreteDomains = 1;
|
|
}
|
|
|
|
var colors = [];
|
|
var colors_mode = document.querySelector('.heatmap-color-buttons .active').getAttribute('data-color');
|
|
if (colors_mode === 'halloween') {
|
|
colors = HEATMAP_COLORS_YELLOW;
|
|
} else if (colors_mode === 'blue') {
|
|
colors = HEATMAP_COLORS_BLUE;
|
|
}
|
|
|
|
heatmapArgs.discreteDomains = discreteDomains;
|
|
heatmapArgs.colors = colors;
|
|
new Chart("#chart-heatmap", heatmapArgs);
|
|
|
|
Array.prototype.slice.call(btn.parentNode.querySelectorAll('button')).map(function (el) {
|
|
el.classList.remove('active');
|
|
});
|
|
btn.classList.add('active');
|
|
});
|
|
});
|
|
|
|
Array.prototype.slice.call(document.querySelectorAll('.heatmap-color-buttons button')).map(function (el) {
|
|
el.addEventListener('click', function (e) {
|
|
var btn = e.target;
|
|
var colors_mode = btn.getAttribute('data-color');
|
|
var colors = [];
|
|
|
|
if (colors_mode === 'halloween') {
|
|
colors = HEATMAP_COLORS_YELLOW;
|
|
} else if (colors_mode === 'blue') {
|
|
colors = HEATMAP_COLORS_BLUE;
|
|
}
|
|
|
|
var discreteDomains = 1;
|
|
|
|
var view_mode = document.querySelector('.heatmap-mode-buttons .active').getAttribute('data-mode');
|
|
if (view_mode === 'continuous') {
|
|
discreteDomains = 0;
|
|
}
|
|
|
|
heatmapArgs.discreteDomains = discreteDomains;
|
|
heatmapArgs.colors = colors;
|
|
new Chart("#chart-heatmap", heatmapArgs);
|
|
|
|
Array.prototype.slice.call(btn.parentNode.querySelectorAll('button')).map(function (el) {
|
|
el.classList.remove('active');
|
|
});
|
|
btn.classList.add('active');
|
|
});
|
|
});
|
|
|
|
document.querySelector('.export-heatmap').addEventListener('click', function () {
|
|
heatmapChart.export();
|
|
});
|
|
|
|
}());
|
|
//# sourceMappingURL=index.min.js.map
|