Newer
Older
moodlog_web / habit.js
0xRoM on 4 Jan 2024 7 KB now with added habit tracker
  1. // Dictionary to store Cal-HeatMap instances indexed by word
  2. const calHeatMapInstances = {};
  3.  
  4. function initializeDailyCalendar(selector, options) {
  5. var cal2 = new CalHeatMap();
  6. var datethen = new Date();
  7. datethen.setDate(datethen.getDate() - (7 * 23));
  8. // These two following calls are identicals
  9. // cal2.paint({ itemSelector: '#habit-cal' });
  10. cal2.init({
  11. itemSelector: selector,
  12. //data: "http://localhost:8080/index.php?action=main_cal",
  13. data: mainurl,
  14. id: "graph",
  15. dataType: "json",
  16. //afterLoadData: parser,
  17. start: datethen,
  18. domain : "week", // Group data by month
  19. subDomain : "day", // Split each month by days
  20. cellSize: 15,
  21. cellPadding: 2,
  22. cellRadius: 3,
  23. domainGutter:2,
  24. subDomainTitleFormat: {
  25. empty: "{date}",
  26. filled: "{date}"
  27. },
  28. //itemSelector: "#cal-heatmap",
  29. range : 24, // Just display 10 months
  30. //legend: [2,3,4,5,6,7,8,9], // Custom threshold for the scale
  31. tooltip: false,
  32. displayLegend: false,
  33. weekStartOnMonday: true,
  34. considerMissingDataAsZero: true,
  35. legendHorizontalPosition: "center",
  36. subDomainTextFormat: '', // %d = day no in box text
  37. ...options, // Merge custom options
  38. });
  39.  
  40. return cal2;
  41. }
  42.  
  43. function initializeWeeklyCalendar(selector, options) {
  44. var cal2 = new CalHeatMap();
  45. var datethen = new Date();
  46. datethen.setMonth(datethen.getMonth() - 23);
  47. // These two following calls are identicals
  48. // cal2.paint({ itemSelector: '#habit-cal' });
  49. cal2.init({
  50. itemSelector: selector,
  51. //data: "http://localhost:8080/index.php?action=main_cal",
  52. data: mainurl,
  53. dataType: "json",
  54. //afterLoadData: parser,
  55. start: datethen,
  56. id : "graph",
  57. domain : "month", // Group data by month
  58. subDomain : "x_week", // Split each month by days
  59. cellSize: 15,
  60. cellPadding: 2,
  61. cellRadius: 3,
  62. domainGutter:2,
  63. subDomainTitleFormat: {
  64. empty: "{date}",
  65. filled: "{count} - {date}"
  66. },
  67. //itemSelector: "#cal-heatmap",
  68. range : 24, // Just display 10 months
  69. legend: [1,2], // Custom threshold for the scale
  70. tooltip: false,
  71. displayLegend: false,
  72. weekStartOnMonday: true,
  73. considerMissingDataAsZero: true,
  74. legendHorizontalPosition: "center",
  75. legendColors: {
  76. min: "#6b6de5",
  77. max: "#46e260",
  78. },
  79. subDomainTextFormat: '',
  80. domainLabelFormat: "%m-%Y",
  81. ...options, // Merge custom options
  82. });
  83. }
  84.  
  85. function update_weekly_cal(word, multiplier) {
  86. // Construct the URL
  87. const url = `/index.php?action=habit_cal_weekly&habit=${word}`;
  88.  
  89. // Fetch data from the URL
  90. fetch(url)
  91. .then(response => response.json())
  92. .then(data => {
  93. // Iterate through key-value pairs in the received JSON
  94. for (const [key, value] of Object.entries(data)) {
  95. // Get the corresponding div element by ID within the habit-cal container
  96. const containerElement = document.getElementById(`habit-cal-${word}`);
  97. const divElement = containerElement.querySelector(`[id="${key}"]`);
  98.  
  99. // Check if the value is greater than or equal to the multiplier
  100. if (value >= multiplier) {
  101. // Set the class to "green" for the div element
  102. divElement.classList.add("green");
  103. } else {
  104. // Set the class to "neut" for the div element
  105. divElement.classList.add("neut");
  106. divElement.textContent = value;
  107. }
  108. }
  109. })
  110. .catch(error => console.error('Error fetching data:', error));
  111. }
  112.  
  113. function updateHabit(word) {
  114. // Fetch data from the server
  115. fetch('/index.php?action=habit_update&habit=' + encodeURIComponent(word))
  116. .then(response => response.json())
  117. .then(data => {
  118. // Update HTML content based on fetched data
  119. updateHTML(word, data);
  120. })
  121. .catch(error => {
  122. console.error('Error fetching habit data:', error);
  123. });
  124. }
  125.  
  126. function updateHTML(word, data) {
  127. // Update HTML content based on fetched data
  128. var habitContainer = document.getElementById(word);
  129.  
  130. if (habitContainer) {
  131. // Update button class and text
  132. const logButton = habitContainer.querySelector('.habit-log-button');
  133. if (logButton) {
  134. logButton.className = 'habit-log-button ' + data.buttonClass;
  135. logButton.innerText = data.buttonText;
  136. }
  137.  
  138. // Update align class
  139. const habitTitle = habitContainer.querySelector('.habit-title');
  140. if (habitTitle) {
  141. habitTitle.className = data.align + ' habit-title';
  142. }
  143.  
  144. // Update other content as needed
  145. const scoreValue1 = habitContainer.querySelector('.habit-score .result1');
  146. if (scoreValue1) {
  147. scoreValue1.innerText = data.result1;
  148. }
  149.  
  150. const scoreValue2 = habitContainer.querySelector('.habit-score .result2');
  151. if (scoreValue2) {
  152. scoreValue2.innerText = data.result2;
  153. }
  154.  
  155. const scoreValue3 = habitContainer.querySelector('.habit-score .result3');
  156. if (scoreValue3) {
  157. scoreValue3.innerText = data.result3;
  158. }
  159.  
  160. if(data.freq == "d"){
  161. // Destroy existing Cal-HeatMap instance
  162. destroyCalHeatMap(word);
  163.  
  164. // Reinitialize Cal-HeatMap with updated data
  165. calHeatMapInstances[word] = initializeDailyCalendar('#habit-cal-'+word, {
  166. data: "/index.php?action=habit_cal_daily&habit="+word,
  167. id: word,
  168. legendColors: {
  169. min: data.calCol,
  170. max: data.calCol,
  171. },
  172. });
  173.  
  174. }
  175. if(data.freq == "w"){
  176. // Get the current date
  177. const currentDate = new Date();
  178.  
  179. // Calculate year, month, and week number for today
  180. const year = currentDate.getFullYear();
  181. const month = currentDate.getMonth() + 1; // Months are zero-indexed
  182. const weekNo = getWeekNumber(currentDate);
  183.  
  184. // Build the "year-month-weekno" string
  185. const yearMonthWeekNoString = `${year}-${padNumber(month)}-${padNumber(weekNo)}`;
  186.  
  187. // Construct the ID of the parent div
  188. const parentDivId = "habit-cal-" + word; // Replace "your_word_here" with the actual word
  189.  
  190. // Get the parent div element
  191. const parentDiv = document.getElementById(parentDivId);
  192.  
  193. // Check if the parent div exists
  194. if (parentDiv) {
  195. //console.log('Parent div found:', parentDiv);
  196. // Find the "year-month-weekno" element within the parent div
  197. const element = parentDiv.querySelector(`[id='${yearMonthWeekNoString}']`);
  198.  
  199. // Check if the element exists
  200. if (element && parentDiv.contains(element)) {
  201. //console.log('Element found:', element);
  202. // Remove the classes "neut" and "green"
  203. element.classList.remove("neut", "green");
  204.  
  205. // Set the text content to the value of data.buttonText
  206. element.textContent = data.buttonText;
  207. if( data.weekSoFar > 0 ){
  208. if (data.weekSoFar < data.weekGoal) {
  209. element.classList.add("neut");
  210. element.textContent = data.weekSoFar;
  211. }
  212. if (data.weekSoFar >= data.weekGoal) {
  213. element.classList.add("green");
  214. }
  215. }
  216. }
  217. }
  218. }
  219. // Add code to update other elements as needed
  220. } else {
  221. console.error('Habit container not found for word:', word);
  222. }
  223. }
  224.  
  225. function destroyCalHeatMap(word) {
  226. // Destroy existing Cal-HeatMap instance
  227. const calInstance = calHeatMapInstances[word];
  228. if (calInstance) {
  229. calInstance.destroy();
  230. console.log('Cal-HeatMap destroyed successfully for word:', word);
  231. }
  232. }
  233.  
  234. // Function to pad a number with leading zeros (if needed)
  235. function padNumber(number) {
  236. return number.toString().padStart(2, "0");
  237. }
  238.  
  239. // Function to get the ISO week number of a date
  240. function getWeekNumber(date) {
  241. const d = new Date(date);
  242. d.setHours(0, 0, 0, 0);
  243. d.setDate(d.getDate() + 4 - (d.getDay() || 7));
  244. const yearStart = new Date(d.getFullYear(), 0, 1);
  245. const weekNo = Math.ceil(((d - yearStart) / 86400000 + 1) / 7);
  246. return weekNo;
  247. }
Buy Me A Coffee