You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

374 lines
9.1 KiB

  1. import { shuffle, getRandomBias } from '../../../src/js/utils/helpers';
  2. import { HEATMAP_COLORS_YELLOW, HEATMAP_COLORS_BLUE } from '../../../src/js/utils/constants';
  3. import { fireballOver25, fireball_2_5, fireball_5_25, lineCompositeData,
  4. barCompositeData, typeData, trendsData, moonData, heatmapData } from './data';
  5. // ================================================================================
  6. let c1 = document.querySelector("#chart-composite-1");
  7. let c2 = document.querySelector("#chart-composite-2");
  8. let Chart = frappe.Chart; // eslint-disable-line no-undef
  9. let lineCompositeChart = new Chart (c1, {
  10. title: "Fireball/Bolide Events - Yearly (reported)",
  11. data: lineCompositeData,
  12. type: 'line',
  13. height: 190,
  14. colors: ['green'],
  15. isNavigable: 1,
  16. valuesOverPoints: 1,
  17. lineOptions: {
  18. dotSize: 8
  19. },
  20. // yAxisMode: 'tick'
  21. // regionFill: 1
  22. });
  23. let barCompositeChart = new Chart (c2, {
  24. data: barCompositeData,
  25. type: 'bar',
  26. height: 210,
  27. colors: ['violet', 'light-blue', '#46a9f9'],
  28. valuesOverPoints: 1,
  29. axisOptions: {
  30. xAxisMode: 'tick'
  31. },
  32. barOptions: {
  33. stacked: 1
  34. },
  35. });
  36. lineCompositeChart.parent.addEventListener('data-select', (e) => {
  37. let i = e.index;
  38. barCompositeChart.updateDatasets([
  39. fireballOver25[i], fireball_5_25[i], fireball_2_5[i]
  40. ]);
  41. });
  42. // ================================================================================
  43. let customColors = ['purple', 'magenta', 'light-blue'];
  44. let typeChartArgs = {
  45. title: "My Awesome Chart",
  46. data: typeData,
  47. type: 'axis-mixed',
  48. height: 300,
  49. colors: customColors,
  50. // maxLegendPoints: 6,
  51. maxSlices: 10,
  52. tooltipOptions: {
  53. formatTooltipX: d => (d + '').toUpperCase(),
  54. formatTooltipY: d => d + ' pts',
  55. }
  56. };
  57. let aggrChart = new Chart("#chart-aggr", typeChartArgs);
  58. Array.prototype.slice.call(
  59. document.querySelectorAll('.aggr-type-buttons button')
  60. ).map(el => {
  61. el.addEventListener('click', (e) => {
  62. let btn = e.target;
  63. let type = btn.getAttribute('data-type');
  64. typeChartArgs.type = type;
  65. if(type !== 'axis-mixed') {
  66. typeChartArgs.colors = undefined;
  67. } else {
  68. typeChartArgs.colors = customColors;
  69. }
  70. if(type !== 'percentage') {
  71. typeChartArgs.height = 300;
  72. } else {
  73. typeChartArgs.height = undefined;
  74. }
  75. let newChart = new Chart("#chart-aggr", typeChartArgs);
  76. if(newChart){
  77. aggrChart = newChart;
  78. }
  79. Array.prototype.slice.call(
  80. btn.parentNode.querySelectorAll('button')).map(el => {
  81. el.classList.remove('active');
  82. });
  83. btn.classList.add('active');
  84. });
  85. });
  86. document.querySelector('.export-aggr').addEventListener('click', () => {
  87. aggrChart.export();
  88. });
  89. // Update values chart
  90. // ================================================================================
  91. let updateDataAllLabels = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue",
  92. "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri",
  93. "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon"];
  94. let getRandom = () => Math.floor(getRandomBias(-40, 60, 0.8, 1));
  95. let updateDataAllValues = Array.from({length: 30}, getRandom);
  96. // We're gonna be shuffling this
  97. let updateDataAllIndices = updateDataAllLabels.map((d,i) => i);
  98. let getUpdateData = (source_array, length=10) => {
  99. let indices = updateDataAllIndices.slice(0, length);
  100. return indices.map((index) => source_array[index]);
  101. };
  102. let updateData = {
  103. labels: getUpdateData(updateDataAllLabels),
  104. datasets: [{
  105. "values": getUpdateData(updateDataAllValues)
  106. }],
  107. yMarkers: [
  108. {
  109. label: "Altitude",
  110. value: 25,
  111. type: 'dashed'
  112. }
  113. ],
  114. yRegions: [
  115. {
  116. label: "Range",
  117. start: 10,
  118. end: 45
  119. },
  120. ],
  121. };
  122. let updateChart = new Chart("#chart-update", {
  123. data: updateData,
  124. type: 'line',
  125. height: 300,
  126. colors: ['#ff6c03'],
  127. lineOptions: {
  128. // hideLine: 1,
  129. regionFill: 1
  130. },
  131. });
  132. let chartUpdateButtons = document.querySelector('.chart-update-buttons');
  133. chartUpdateButtons.querySelector('[data-update="random"]').addEventListener("click", () => {
  134. shuffle(updateDataAllIndices);
  135. let value = getRandom();
  136. let start = getRandom();
  137. let end = getRandom();
  138. let data = {
  139. labels: updateDataAllLabels.slice(0, 10),
  140. datasets: [{values: getUpdateData(updateDataAllValues)}],
  141. yMarkers: [
  142. {
  143. label: "Altitude",
  144. value: value,
  145. type: 'dashed'
  146. }
  147. ],
  148. yRegions: [
  149. {
  150. label: "Range",
  151. start: start,
  152. end: end
  153. },
  154. ],
  155. };
  156. updateChart.update(data);
  157. });
  158. chartUpdateButtons.querySelector('[data-update="add"]').addEventListener("click", () => {
  159. let index = updateChart.state.datasetLength; // last index to add
  160. if(index >= updateDataAllIndices.length) return;
  161. updateChart.addDataPoint(
  162. updateDataAllLabels[index], [updateDataAllValues[index]]
  163. );
  164. });
  165. chartUpdateButtons.querySelector('[data-update="remove"]').addEventListener("click", () => {
  166. updateChart.removeDataPoint();
  167. });
  168. document.querySelector('.export-update').addEventListener('click', () => {
  169. updateChart.export();
  170. });
  171. // Trends Chart
  172. // ================================================================================
  173. let plotChartArgs = {
  174. title: "Mean Total Sunspot Count - Yearly",
  175. data: trendsData,
  176. type: 'line',
  177. height: 300,
  178. colors: ['#238e38'],
  179. lineOptions: {
  180. hideDots: 1,
  181. heatline: 1,
  182. },
  183. axisOptions: {
  184. xAxisMode: 'tick',
  185. yAxisMode: 'span',
  186. xIsSeries: 1
  187. }
  188. };
  189. let trendsChart = new Chart("#chart-trends", plotChartArgs);
  190. Array.prototype.slice.call(
  191. document.querySelectorAll('.chart-plot-buttons button')
  192. ).map(el => {
  193. el.addEventListener('click', (e) => {
  194. let btn = e.target;
  195. let type = btn.getAttribute('data-type');
  196. let config = {};
  197. config[type] = 1;
  198. if(['regionFill', 'heatline'].includes(type)) {
  199. config.hideDots = 1;
  200. }
  201. // plotChartArgs.init = false;
  202. plotChartArgs.lineOptions = config;
  203. new Chart("#chart-trends", plotChartArgs);
  204. Array.prototype.slice.call(
  205. btn.parentNode.querySelectorAll('button')).map(el => {
  206. el.classList.remove('active');
  207. });
  208. btn.classList.add('active');
  209. });
  210. });
  211. document.querySelector('.export-trends').addEventListener('click', () => {
  212. trendsChart.export();
  213. });
  214. // Event chart
  215. // ================================================================================
  216. let eventsData = {
  217. labels: ["Ganymede", "Callisto", "Io", "Europa"],
  218. datasets: [
  219. {
  220. "values": moonData.distances,
  221. "formatted": moonData.distances.map(d => d*1000 + " km")
  222. }
  223. ]
  224. };
  225. let eventsChart = new Chart("#chart-events", {
  226. title: "Jupiter's Moons: Semi-major Axis (1000 km)",
  227. data: eventsData,
  228. type: 'bar',
  229. height: 330,
  230. colors: ['grey'],
  231. isNavigable: 1,
  232. });
  233. let dataDiv = document.querySelector('.chart-events-data');
  234. eventsChart.parent.addEventListener('data-select', (e) => {
  235. let name = moonData.names[e.index];
  236. dataDiv.querySelector('.moon-name').innerHTML = name;
  237. dataDiv.querySelector('.semi-major-axis').innerHTML = moonData.distances[e.index] * 1000;
  238. dataDiv.querySelector('.mass').innerHTML = moonData.masses[e.index];
  239. dataDiv.querySelector('.diameter').innerHTML = moonData.diameters[e.index];
  240. dataDiv.querySelector('img').src = "./assets/img/" + name.toLowerCase() + ".jpg";
  241. });
  242. // Heatmap
  243. // ================================================================================
  244. let heatmapArgs = {
  245. title: "Monthly Distribution",
  246. data: heatmapData,
  247. type: 'heatmap',
  248. discreteDomains: 1,
  249. countLabel: 'Level',
  250. colors: HEATMAP_COLORS_BLUE,
  251. legendScale: [0, 1, 2, 4, 5]
  252. };
  253. let heatmapChart = new Chart("#chart-heatmap", heatmapArgs);
  254. Array.prototype.slice.call(
  255. document.querySelectorAll('.heatmap-mode-buttons button')
  256. ).map(el => {
  257. el.addEventListener('click', (e) => {
  258. let btn = e.target;
  259. let mode = btn.getAttribute('data-mode');
  260. let discreteDomains = 0;
  261. if(mode === 'discrete') {
  262. discreteDomains = 1;
  263. }
  264. let colors = [];
  265. let colors_mode = document
  266. .querySelector('.heatmap-color-buttons .active')
  267. .getAttribute('data-color');
  268. if(colors_mode === 'halloween') {
  269. colors = HEATMAP_COLORS_YELLOW;
  270. } else if (colors_mode === 'blue') {
  271. colors = HEATMAP_COLORS_BLUE;
  272. }
  273. heatmapArgs.discreteDomains = discreteDomains;
  274. heatmapArgs.colors = colors;
  275. new Chart("#chart-heatmap", heatmapArgs);
  276. Array.prototype.slice.call(
  277. btn.parentNode.querySelectorAll('button')).map(el => {
  278. el.classList.remove('active');
  279. });
  280. btn.classList.add('active');
  281. });
  282. });
  283. Array.prototype.slice.call(
  284. document.querySelectorAll('.heatmap-color-buttons button')
  285. ).map(el => {
  286. el.addEventListener('click', (e) => {
  287. let btn = e.target;
  288. let colors_mode = btn.getAttribute('data-color');
  289. let colors = [];
  290. if(colors_mode === 'halloween') {
  291. colors = HEATMAP_COLORS_YELLOW;
  292. } else if (colors_mode === 'blue') {
  293. colors = HEATMAP_COLORS_BLUE;
  294. }
  295. let discreteDomains = 1;
  296. let view_mode = document
  297. .querySelector('.heatmap-mode-buttons .active')
  298. .getAttribute('data-mode');
  299. if(view_mode === 'continuous') {
  300. discreteDomains = 0;
  301. }
  302. heatmapArgs.discreteDomains = discreteDomains;
  303. heatmapArgs.colors = colors;
  304. new Chart("#chart-heatmap", heatmapArgs);
  305. Array.prototype.slice.call(
  306. btn.parentNode.querySelectorAll('button')).map(el => {
  307. el.classList.remove('active');
  308. });
  309. btn.classList.add('active');
  310. });
  311. });
  312. document.querySelector('.export-heatmap').addEventListener('click', () => {
  313. heatmapChart.export();
  314. });