Newer
Older
moodlog_web / habit.js
0xRoM on 1 Mar 7 KB minor ui bug fixes
// Dictionary to store Cal-HeatMap instances indexed by word
const calHeatMapInstances = {};

function initializeDailyCalendar(selector, options) {
	var cal2 = new CalHeatMap();
	var datethen = new Date();
		datethen.setDate(datethen.getDate() - (7 * 23));
	// These two following calls are identicals
	// cal2.paint({ itemSelector: '#habit-cal' });
	cal2.init({
		itemSelector: selector,
		//data: "http://localhost:8080/index.php?action=main_cal",
		data: mainurl,
		id: "graph",
		dataType: "json",
			//afterLoadData: parser,
		start: datethen,
		domain : "week",			// Group data by month
		subDomain : "day",			// Split each month by days
		cellSize: 15,
		cellPadding: 2,
		cellRadius: 3,
		domainGutter:2,
		subDomainTitleFormat: {
	        empty: "{date}",
	        filled: "{date}"
	    },
	    //itemSelector: "#cal-heatmap",
		range : 24,					// Just display 10 months
		//legend: [2,3,4,5,6,7,8,9], 	// Custom threshold for the scale
		tooltip: false,
		displayLegend: false,
		weekStartOnMonday: true,
		considerMissingDataAsZero: true,
		legendHorizontalPosition: "center",
		subDomainTextFormat: '', // %d = day no in box text
		...options, // Merge custom options
	});

	return cal2;
}

function initializeWeeklyCalendar(selector, options) {
	var cal2 = new CalHeatMap();
	var datethen = new Date();
		datethen.setMonth(datethen.getMonth() - 24);
	// These two following calls are identicals
	// cal2.paint({ itemSelector: '#habit-cal' });
	cal2.init({
		itemSelector: selector,
		//data: "http://localhost:8080/index.php?action=main_cal",
		data: mainurl,
		dataType: "json",
			//afterLoadData: parser,
		start: datethen,
		id : "graph",
		domain : "month",			// Group data by month
		subDomain : "x_week",			// Split each month by days
		cellSize: 15,
		cellPadding: 2,
		cellRadius: 3,
		domainGutter:2,
		subDomainTitleFormat: {
	        empty: "{date}",
	        filled: "{count} - {date}"
	    },
	    //itemSelector: "#cal-heatmap",
		range : 24,					// Just display 10 months
		legend: [1,2], 	// Custom threshold for the scale
		tooltip: false,
		displayLegend: false,
		weekStartOnMonday: true,
		considerMissingDataAsZero: true,
		legendHorizontalPosition: "center",
		legendColors: {
			min: "#6b6de5",
			max: "#46e260",
		},
		subDomainTextFormat: '',
		domainLabelFormat: "%m-%Y",
		...options, // Merge custom options
	});
}

function update_weekly_cal(word, multiplier) {
  // Construct the URL
  const url = `/index.php?action=habit_cal_weekly&habit=${word}`;

  // Fetch data from the URL
  fetch(url)
    .then(response => response.json())
    .then(data => {
      // Iterate through key-value pairs in the received JSON
      for (const [key, value] of Object.entries(data)) {
        // Get the corresponding div element by ID within the habit-cal container
        const containerElement = document.getElementById(`habit-cal-${word}`);
        const divElement = containerElement.querySelector(`[id="${key}"]`);

        // Check if the value is greater than or equal to the multiplier
        if (value >= multiplier) {
          // Set the class to "green" for the div element
          divElement.classList.add("green");
        } else {
          // Set the class to "neut" for the div element
          divElement.classList.add("neut");
          divElement.textContent = value;
        }
      }
    })
    .catch(error => console.error('Error fetching data:', error));
}

function updateHabit(word) {
    // Fetch data from the server
    fetch('/index.php?action=habit_update&habit=' + encodeURIComponent(word))
        .then(response => response.json())
        .then(data => {
            // Update HTML content based on fetched data
            updateHTML(word, data);
        })
        .catch(error => {
            console.error('Error fetching habit data:', error);
        });
}

function updateHTML(word, data) {
    // Update HTML content based on fetched data
    var habitContainer = document.getElementById(word);

    if (habitContainer) {
        // Update button class and text
        const logButton = habitContainer.querySelector('.habit-log-button');
        if (logButton) {
            logButton.className = 'habit-log-button ' + data.buttonClass;
            logButton.innerText = data.buttonText;
        }

        // Update align class
        const habitTitle = habitContainer.querySelector('.habit-title');
        if (habitTitle) {
            habitTitle.className = data.align + ' habit-title';
        }

       // Update other content as needed
        const scoreValue1 = habitContainer.querySelector('.habit-score .result1');
        if (scoreValue1) {
            scoreValue1.innerText = data.result1;
        }

        const scoreValue2 = habitContainer.querySelector('.habit-score .result2');
        if (scoreValue2) {
            scoreValue2.innerText = data.result2;
        }

        const scoreValue3 = habitContainer.querySelector('.habit-score .result3');
        if (scoreValue3) {
            scoreValue3.innerText = data.result3;
        }

        if(data.freq == "d"){
        	// Destroy existing Cal-HeatMap instance
	        destroyCalHeatMap(word);

	        // Reinitialize Cal-HeatMap with updated data
	        calHeatMapInstances[word] = initializeDailyCalendar('#habit-cal-'+word, {
				data: "/index.php?action=habit_cal_daily&habit="+word,
				id: word,
				legendColors: {
					min: data.calCol,
					max: data.calCol,
				},
			});

        }
        if(data.freq == "w"){
			// Get the current date
			const currentDate = new Date();

			// Calculate year, month, and week number for today
			const year = currentDate.getFullYear();
			const month = currentDate.getMonth() + 1; // Months are zero-indexed
			const weekNo = getWeekNumber(currentDate);

			// Build the "year-month-weekno" string
			const yearMonthWeekNoString = `${year}-${padNumber(month)}-${padNumber(weekNo)}`;

			// Construct the ID of the parent div
			const parentDivId = "habit-cal-" + word; // Replace "your_word_here" with the actual word

			// Get the parent div element
			const parentDiv = document.getElementById(parentDivId);

			// Check if the parent div exists
			if (parentDiv) {
				//console.log('Parent div found:', parentDiv);
			  	// Find the "year-month-weekno" element within the parent div
				const element = parentDiv.querySelector(`[id='${yearMonthWeekNoString}']`);

				// Check if the element exists
				if (element && parentDiv.contains(element)) {
					//console.log('Element found:', element);
				  	// Remove the classes "neut" and "green"
				  	element.classList.remove("neut", "green");

				  	// Set the text content to the value of data.buttonText
				  	element.textContent = data.buttonText;
				  	if( data.weekSoFar > 0 ){
					  	if (data.weekSoFar < data.weekGoal) {
					    	element.classList.add("neut");
					    	element.textContent = data.weekSoFar;
					  	}
					  	if (data.weekSoFar >= data.weekGoal) {
					    	element.classList.add("green");
					  	}
					}
				}
			}
		}
        // Add code to update other elements as needed
    } else {
        console.error('Habit container not found for word:', word);
    }
}

function destroyCalHeatMap(word) {
    // Destroy existing Cal-HeatMap instance
    const calInstance = calHeatMapInstances[word];
    if (calInstance) {
        calInstance.destroy();
        console.log('Cal-HeatMap destroyed successfully for word:', word);
    }
}

// Function to pad a number with leading zeros (if needed)
function padNumber(number) {
  return number.toString().padStart(2, "0");
}

// Function to get the ISO week number of a date
function getWeekNumber(date) {
  const d = new Date(date);
  d.setHours(0, 0, 0, 0);
  d.setDate(d.getDate() + 4 - (d.getDay() || 7));
  const yearStart = new Date(d.getFullYear(), 0, 1);
  const weekNo = Math.ceil(((d - yearStart) / 86400000 + 1) / 7);
  return weekNo;
}