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.
 
 
 

348 lines
8.3 KiB

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