diff --git a/habitrpg_user_data_display.html b/habitrpg_user_data_display.html index eb86042..ebc4c4f 100644 --- a/habitrpg_user_data_display.html +++ b/habitrpg_user_data_display.html @@ -187,6 +187,7 @@ // false through all future re-fetches var tellMe = 'tell me'; +var weekdayArray = [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ]; // TODO: replace this with momentjs code ////////////////////////////////////////////////////////////////////// //// Allow Show/Hide Toggling to work /////////////////////////// @@ -688,7 +689,7 @@ 'HEADING Tasks', 'taskOverview', 'taskStatistics', 'untaggedTasks', // 'HEADING Habits', - 'habitTrends', 'habitHistory', + 'habitTrends', 'habitHistoryList', 'habitHistoryTable', 'HEADING', // 'HEADING Dailies', 'dailiesHistory', 'dailiesIncomplete', @@ -732,7 +733,7 @@ // elements are in the order that the sections would appear on the page // if they were all visible at once): var keys = ['taskOverview', 'taskStatistics', 'untaggedTasks', - 'habitTrends', 'habitHistory', 'dailiesHistory', 'todosDated', + 'habitTrends', 'habitHistoryList', 'habitHistoryTable', 'dailiesHistory', 'todosDated', 'todosCompleted', 'dropsToday', 'questProgress', 'questsCompleted', 'damageDailies','dailiesIncomplete',//keep in that order 'statsAndStreaks', 'guildsList', @@ -938,7 +939,6 @@ if (userId == '3e595299-3d8a-4a10-bfe0-88f555e4aa0c' || // AliceHarris userId == 'e7b5d1e2-3b6e-4192-b867-8bafdb03eeec' // Ryan ) { - // displayName = 'Slayer of Dailies... Eater of Toast'; displayName = 'A valiant Github warrior'; } $('#headerExtras').html('
' + @@ -1091,7 +1091,8 @@ taskStatistics(); untaggedTasksSection(); habitTrends(); - habitHistory(); + habitHistoryList(); + habitHistoryTable(); damageFromDailies(); dailiesIncomplete(); dailiesHistory(); @@ -1820,7 +1821,7 @@ } function habitTrends() { - var html = '

The chart below provides a visual representation of the trends in your Habits as reflected by the data recorded in Habitica. Here you can get an idea of which Habits you are reinforcing, and which are being neglected. The data provided to this chart is the same as displayed in the Habit History section, limited to the last 500 entries. The Habit History section only records when a change occurs in a Habit, while the trend chart includes the values for all Habits every day, regardless if they changed.

'; + var html = '

The chart below provides a visual representation of the trends in your Habits as reflected by the data recorded in Habitica. Here you can get an idea of which Habits you are reinforcing, and which are being neglected. The data provided to this chart is the same as displayed in the Habit History List section, limited to the last 500 entries. The Habit History List section only records when a change occurs in a Habit, while the trend chart includes the values for all Habits every day, regardless if they changed.

'; html += '

This chart is interactive, and exposes multiple controls:

'; html += ''; var habitNames = habits.reduce(function(names, item) { @@ -1969,23 +1970,69 @@ } } - function habitHistory() { - var id = 'habitHistorySection'; - var title = 'Habit History'; - var orderId = 'habitHistory'; + function habitHistoryList() { + var html = '

This shows your Habits, the dates you clicked on them, and the total number of plus and minus clicks on each of those dates.

'; + html += '

Habits with no history are highlighted in bold, in case you would like to consider them for greater focus.

'; + html += ''; + var id = 'habitHistoryListSection'; + var title = 'Habit History List'; + var orderId = 'habitHistoryList'; + TOC[orderId] = {'target': id, 'title': title}; + MAIN[orderId] = {'id': id, 'title': title, 'longContent': true, + 'html': html}; - // ### Habit History Chart ### + function collateHistoryForOneHabit(obj) { + // ASSUMPTION: The history array is in chronological order (cross fingers). + var historyList = []; + $.each(obj.history, function(index, histObj){ + if (typeof histObj.scoredUp !== 'undefined' && typeof histObj.scoredDown !== 'undefined') { + var valueRounded = Math.round(histObj.value * 100) / 100; + var string = moment(histObj.date).format('YYYY-MM-DD') + ' : '; + if (obj.up) { + string += ' up: ' + histObj.scoredUp; + if (obj.down) string += '; '; + } + if (obj.down) { + string += ' down: ' + histObj.scoredDown; + } + string += ' (value: ' + valueRounded + ')'; + historyList.push('
  • ' + string + '
  • '); + } + }); + + var habitText = obj.text; + var noHistoryClass = ''; + if (historyList.length == 0) { + noHistoryClass = 'noHistory'; + habitText += ' (no history)'; + } + else { + historyList.reverse(); // put most recent at top + habitText += ''; + } + return '
  • ' + habitText + '
  • '; + } + } + + function habitHistoryTable() { + var id = 'habitHistoryTableSection'; + var title = 'Habit History Table'; + var orderId = 'habitHistoryTable'; // Create some needed constants. var todayDateObj = new Date(Date.now()); var todayLocalDateString = getLocalDateStringForUser_FromUtcMillsStamp(todayDateObj.getTime()); var oldDateString = '2000-01-01'; - var weekdayArray = [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ]; - // Create a data structure for the chart. + // Create a data structure for the table. // The desired structure is: // habitsWithHistory[habitIndex]['name'] = 'Some Habit Name'; - // habitsWithHistory[habitIndex]['entries'][historyEntryDate]['upCount'] + // habitsWithHistory[habitIndex]['entries'][historyEntryDate]['upCount'] // habitsWithHistory[habitIndex]['entries'][historyEntryDate]['downCount'] // habitsWithHistory[habitIndex]['entries'][historyEntryDate]['netCount'] @@ -2019,7 +2066,7 @@ allHistoryEntriesForThisHabit['mostRecentDate'] = entryDate; } allHistoryEntriesForThisHabit[entryDate] = entry; - } + } }); if(allHistoryEntriesForThisHabit['mostRecentDate'] > oldDateString) { var mostRecentLocalDateObj = new Date(allHistoryEntriesForThisHabit['mostRecentDate']); @@ -2032,7 +2079,7 @@ return allHistoryEntriesForThisHabit; } - // Create the html for the chart. + // Create the html for the table. var maxDaysToShow = 31; var headerRow = 'Days
    Since
    ActiveHabit'; for (var dateIdx=0; dateIdx20/g, ">'"); // remove century headerRow = headerRow.replace(/-/g, "-
    "); // line break after - - var tableBody = ''; for (var habitIdx=0,ic=habitsWithHistory.length; habitIdx 0) { - formattedNetCount = netCount; + formattedNetCount = netCount; classNames = 'safe'; } if(netCount < 0) { - formattedNetCount = netCount; + formattedNetCount = netCount; classNames = 'danger'; } if(weekdayString === 'Mo'){ @@ -2089,92 +2135,42 @@ tableBody += '' ; } - var chartOutput = - '
    show explanation
    ' + - '
    ' + - '

    The table below shows historical data for your Habits. One month\'s worth of data is shown. (31 days.) Each cell shows the \'Net\' number of times that you clicked plus or minus for that habit, on the specified date. Positive numbers are in blue, negative numbers are in red, and zero is in yellow.'+ - '

    For example:' + - '

      ' + - '
    • 3 \'plus\' clicks and No \'minus\' clicks = Net 3. (blue)
    • ' + - '
    • 4 \'plus\' clicks and 2 \'minus\' clicks = Net 2. (blue)
    • ' + - '
    • 1 \'minus\' click and No \'plus\' clicks = Net (-1). (red)
    • ' + - '
    • No clicks = Net 0. (Zero is shown as a dot, in yellow.)
    • ' + - '
    • 1 \'minus\' click and 1 \'plus\' click = Net 0. (Zero is shown as a dot, in yellow.)
    • ' + + var tableOutput = + '
      show explanation
      ' + + '
      ' + + '

      The table below shows historical data for your Habits. One month\'s worth of data is shown (31 days). Each cell shows the "Net" number of times that you clicked plus or minus for that habit, on the specified date. Positive numbers are in blue, negative numbers are in red, and zero is in yellow.'+ + '

      For example:' + + '

        ' + + '
      • 3 "plus" clicks and no "minus" clicks = Net 3 (blue).
      • ' + + '
      • 4 "plus" clicks and 2 "minus" clicks = Net 2 (blue).
      • ' + + '
      • 1 "minus" click and no "plus" clicks = Net -1 (red).
      • ' + + '
      • No clicks = Net 0 (zero is shown as a dot, in yellow).
      • ' + + '
      • 1 "minus" click and 1 "plus" click = Net 0 (zero is shown as a dot, in yellow).
      • ' + '
      ' + - ' The \'Days Since Active\' field shows the number of days since any plus/minus button was clicked for that habit. (Or a hyphen if the habit has never been active.)
      ' + - 'Vertical black bars indicate the start of each week. (Week start is Monday.)' + - '

      ' + - 'If you scoll down past the chart area, you can view the \'Habit Details\' section.
      The Habit Details section contains additional information that is not in the chart.
      Including: The absolute number of Plus and Minus button clicks, and older history beyond 31 days.' + + ' The "Days Since Active" field shows the number of days since any plus/minus button was clicked for that habit (or a hyphen if the habit has never been active).
      ' + + 'Vertical black bars indicate the start of each week (week start is Monday).' + '

      ' + - '
      hide explanation
      ' + - '
      ' + - '' + headerRow + + '
      hide explanation
      ' + + '' + + '
      ' + headerRow + '' + tableBody + '' + '
      '; - // ### Habit History Details ### - - var detailOutput = - '











      '+ - '











      '+ - '

      Habit Details

      ' + - '

      This shows your Habits, the dates you clicked on them, and the total number of plus and minus clicks on each of those dates.

      '; - detailOutput += '

      Habits with no history are highlighted in bold, in case you would like to consider them for greater focus.

      '; - detailOutput += '
        '; - $.each(habits, function(index, obj){ - detailOutput += collateHistoryForOneHabit(obj); - }); - detailOutput += '
      '; - - function collateHistoryForOneHabit(obj) { - // ASSUMPTION: The history array is in chronological order (cross fingers). - var historyList = []; - $.each(obj.history, function(index, histObj){ - if (typeof histObj.scoredUp !== 'undefined' && typeof histObj.scoredDown !== 'undefined') { - var valueRounded = Math.round(histObj.value * 100) / 100; - var string = moment(histObj.date).format('YYYY-MM-DD') + ' : '; - if (obj.up) { - string += ' up: ' + histObj.scoredUp; - if (obj.down) string += '; '; - } - if (obj.down) { - string += ' down: ' + histObj.scoredDown; - } - string += ' (value: ' + valueRounded + ')'; - historyList.push('
    • ' + string + '
    • '); - } - }); - - var habitText = obj.text; - var noHistoryClass = ''; - if (historyList.length == 0) { - noHistoryClass = 'noHistory'; - habitText += ' (no history)'; - } - else { - historyList.reverse(); // put most recent at top - habitText += '
        ' + - historyList.join('') + '
      '; - } - return '
    • ' + habitText + '
    • '; - } - - var html = chartOutput + detailOutput; + var html = tableOutput; TOC[orderId] = {'target': id, 'title': title}; MAIN[orderId] = {'id': id, 'title': title, 'longContent': true, 'html': html}; - } - - function getLocalDateStringForUser_FromUtcMillsStamp(dateStampUtcMills) { - // Format the date to the user's time zone. - var dateUTC = new Date(dateStampUtcMills); - var userZoneOffsetMins = user.preferences.timezoneOffset; - var userZoneOffsetMills = userZoneOffsetMins * 60 * 1000; - var localDateMills = dateUTC - userZoneOffsetMills; - var localDate = new Date(localDateMills); - var isoLocalDateString = formatIsoDateString(localDate); - return isoLocalDateString; + function getLocalDateStringForUser_FromUtcMillsStamp(dateStampUtcMills) { + // Format the date to the user's time zone. + var dateUTC = new Date(dateStampUtcMills); + var userZoneOffsetMins = user.preferences.timezoneOffset; + var userZoneOffsetMills = userZoneOffsetMins * 60 * 1000; + var localDateMills = dateUTC - userZoneOffsetMills; + var localDate = new Date(localDateMills); + var isoLocalDateString = formatIsoDateString(localDate); + return isoLocalDateString; + } } @@ -2462,23 +2458,30 @@ var title = 'Dailies History'; var orderId = 'dailiesHistory'; - var todayDateObj = new Date(Date.now()); - var todayLocalDateString = getLocalDateStringForUser_FromUtcMillsStamp(todayDateObj.getTime()); - var weekdayArray = [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ]; - - // Preprocess the Dailies to work out if each day was a success or fail or neither. + // preprocess the Dailies to find all the dates on which data + // exists, and to work out if each day was a success or fail + // or neither (e.g., Grey Daily) based on whether the day's value + // is higher or lower than the previous day's: + var allDates = {}; var allWeekdays = {}; - for (var dailyIdx=0,c=dailies.length; dailyIdx 0) || (previousValue !== null && value > previousValue) ) { success = '✓'; // user did the Daily @@ -2501,53 +2504,53 @@ success = 'x'; // user did not do the Daily status = 'danger'; } - daily['historyItems'][formattedDate] = []; - daily['historyItems'][formattedDate]['value'] = success; - daily['historyItems'][formattedDate]['status'] = status; + obj['historyItems'][formattedDate] = []; + obj['historyItems'][formattedDate]['value'] = success; + // + '
      ' + (Math.round(value * 10) / 10); // TST + obj['historyItems'][formattedDate]['status'] = status; + allDates[formattedDate] = true; previousValue = value; } } } - var maxDaysToShow = 31; - var headerRow = 'Task'; - for (var dateIdx=0; dateIdx' + - currentLocalDateString + '

      ' + - weekdayString + ' '; + var allDatesInOrder = Object.keys(allDates).sort().reverse(); + var datesWithGaps = {}; + var previousDate = null; + var headerRow = 'task'; + for (var i=0,ic=allDatesInOrder.length; i 24*60*60*1000) { + // there's a gap between the dates of more than one day + datesWithGaps[allDatesInOrder[i]] = true; + missingDate = 'missingDate'; + } + } + headerRow += '' + + allDatesInOrder[i] + '

      ' + + allWeekdays[allDatesInOrder[i]] + ' '; + previousDate = date; } headerRow += ''; headerRow = headerRow.replace(/>20/g, ">'"); // remove century headerRow = headerRow.replace(/-/g, "-
      "); // line break after - - - var tableBody = ''; - for (var dailyIdx=0, c=dailies.length; dailyIdx'; - for (var dateIdx=0; dateIdx'; + for (var j=0,jc=allDatesInOrder.length; j' + value + ''; + tableBody += '' + + value + ''; } tableBody += '' ; } @@ -2555,21 +2558,21 @@ var html = '
      show explanation
      ' + '
      ' + -'

      The table below shows historical data for your Dailies. One month\'s worth of data is shown. (31 days.) In the table are symbols indicating your actions on each day:

      • V You ticked off the Daily, even if it was a ' + +'

        The table below shows historical data for your Dailies. If you are a subscriber, you will see data for every day going back to the date on which you subscribed. If you are not a subscriber, you will see data for every day for the past week, but before that your data points start to be merged together (this is to save on expensive database storage space). In the table are symbols indicating your actions on each day:

        • V You ticked off the Daily, even if it was a ' + wiki('Dailies#Grey_Dailies', 'Grey Daily') + ', or you left the Daily incomplete but cast ' + wiki('Healer#Skills', 'Searing Brightness') + ' or ' + wiki('Warrior#Skills', 'Brutal Smash') + -' on it.
        • x You did not tick off the Daily but you should have (it was due that day), or you used the ' + wiki('Orb_of_Rebirth', 'Orb of Rebirth') + ' or ' + wiki('Settings#Reset_Account', 'Reset') + ' to set all your tasks back to yellow.
        • · You took no damage from the Daily, for one of several possible reasons. (You ticked the Daily the next morning in the ' + +' on it.
        • x You did not tick off the Daily but you should have (it was due that day), or you used the ' + wiki('Orb_of_Rebirth', 'Orb of Rebirth') + ' or ' + wiki('Settings#Reset_Account', 'Reset') + ' to set all your tasks back to yellow.
        • - You did not tick off the Daily on the day it was due but you took no damage from it for several possible reasons (you ticked the Daily the next morning in the ' + wiki('Dailies#Record_Yesterday.27s_Activities', 'Record Yesterday\'s Activity screen') + '; the Daily was not due that day; you ticked off all of the ' + wiki('Checklist#Dailies', 'checklist') + ' items under that Daily, although not the Daily itself; you evaded the Daily with ' + wiki('Rogue#Skills', 'Stealth') + '; you were ' + wiki('Tavern', 'resting in the inn') + -'; you had not logged in to Habitica that day; the Daily did not yet exist on that day). This symbol will also appear frequently for old data for non-subscribers because it is not possible to correctly determine the actions you took after your data has been merged.

        Vertical black bars indicate the start of each week. (Week start is Monday.)

        ' + -'
        hide explanation
        ' + +'; you had not logged in to Habitica that day; the Daily did not yet exist on that day). This symbol will also appear frequently for old data for non-subscribers because it is not possible to correctly determine the actions you took after your data has been merged.

      Vertical grey bars in the table indicate gaps in the historical record (e.g., periods of a day or more in which you were resting in the inn).

      ' + +'
      hide explanation
      ' + '
      ' + '' + headerRow + '' + @@ -2577,6 +2580,8 @@ TOC[orderId] = {'target': id, 'title': title}; MAIN[orderId] = {'id': id, 'title': title, 'longContent': true, 'html': html}; + +// LIST FORMAT FOR REASONS (INCOMPLETE):
    • - you did not tick off the Daily but you took no damage from it for a reason such as:
      • the Daily was not due that day
      • you evaded the Daily with Stealth
      • you were resting in the inn
      • you had not logged in to Habitica that day
      • the Daily did not yet exist on that day
    • #dailiesHistorySection > ul ul { margin-left: 2em; } } @@ -5364,40 +5369,40 @@ } -#habitHistorySection .historyValue { +#habitHistoryListSection .historyValue { font-size: .8em; } -#habitHistorySection li li { +#habitHistoryListSection li li { padding: 1px 0; } -#habitHistorySection .noHistory { +#habitHistoryListSection .noHistory { font-weight: bold; } -#habitHistorySection .noHistory span { +#habitHistoryListSection .noHistory span { font-size: .8em; font-style: italic; font-weight: normal; } -#habitHistorySection table { +#habitHistoryTableSection table { margin-top: 1.5em; border-bottom: 1px solid #ccc; border-left: 1px solid #ccc; } -#habitHistorySection table th { +#habitHistoryTableSection table th { background-color: rgb(242, 242, 230); /* XXX_SOON replace with proper scrolling */ } -#habitHistorySection table th, -#habitHistorySection table td { +#habitHistoryTableSection table th, +#habitHistoryTableSection table td { text-align: center; border-top: 1px solid #ccc; border-right: 1px solid #ccc; } -#habitHistorySection table th:nth-child(2) { +#habitHistoryTableSection table th:nth-child(2) { border-right: 0.3em solid #999; } -#habitHistorySection table td:nth-child(2) { +#habitHistoryTableSection table td:nth-child(2) { text-align: left; border-right: 0.3em solid #999; display: inline-block; @@ -5405,10 +5410,10 @@ overflow: hidden; width: 14.5em; } -#habitHistorySection table th.weekstart { +#habitHistoryTableSection table th.weekstart { border-right: 0.15em solid #000; } -#habitHistorySection table td.weekstart { +#habitHistoryTableSection table td.weekstart { border-right: 0.15em solid #000; } @@ -5457,13 +5462,11 @@ display: inline-block; white-space: nowrap; overflow: hidden; - width: 14.5em; + width: 12em; } -#dailiesHistorySection table th.weekstart { - border-right: 0.15em solid #000; -} -#dailiesHistorySection table td.weekstart { - border-right: 0.15em solid #000; +#dailiesHistorySection table th.missingDate, +#dailiesHistorySection table td.missingDate { + border-left: 0.3em solid #999; } @@ -5790,8 +5793,8 @@
      -

      Habitica Official User Data Display Tool - (v9.17)

      +

      Habitica User Data Display Tool + (v9.18)


      @@ -5822,11 +5825,28 @@

      Habitica Official User Data Display Tool

      Version History

      +
      9.18 2022-12-29
      +
        +
      • Features: + +
      • +
      • Code: +
          +
        • Renamed function formatDateFromUTC to formatIsoDateString (from PR 62 by BlakeTNC).
        • +
        • Renamed function habitHistory to habitHistoryList.
        • +
        +
      • +
      +
      9.17 2022-11-26
      • Bug fix:
          -
        • In the Dailies History section, BladeTNC / Tenali fixed the days of the week day so that they match the dates.
        • +
        • In the Dailies History section, BladeTNC / Tenali fixed the days of the week day so that they match the dates.
      @@ -7068,7 +7088,8 @@

      What's On This Page?

    • Task Statistics: How many Habits, Dailies, To Do's, and Rewards you have in total, and how many are assigned to each Stat. If you have task-based auto-allocation turned on, this section will also show your Training Points.
    • Tasks Untagged: If you have any Habits, Dailies, To Do's, or Rewards that have not been tagged they will be listed. This will be useful to you only if you prefer to tag all your tasks and are looking for any you have missed. This section is shown only if you have untagged tasks.
    • Habit Trends: An interactive chart that provides a visual representation of the trends in your Habits. It gives you an idea of which Habits you are reinforcing, and which are being neglected.
    • -
    • Habit History: This shows some of the dates and times you recently clicked on your Habits. But note the disclaimer you'll see at the top of the list! Most of your clicks can not be shown.
    • +
    • Habit History List (previously Habit History): This shows some of the dates and times you recently clicked on your Habits. But note the disclaimer you'll see at the top of the list! Most of your clicks can not be shown.
    • +
    • Habit History Table (created by BlakeTNC): This shows summarised information from the Habit History List section, in a tablular format.
    • Dailies History: A spreadsheet-like view showing the days on which you did and did not tick off your Dailies.
    • Dailies Incomplete: A list of Dailies scheduled for today that you have not yet completed, and the estimated damage you will take from each one. It also has a separate list of Grey Dailies that have not been completed (you don't need to do those today, but you might want to for extra rewards).
    • To Do's with Dates: A list of all To Do's that have been given due dates, sorted by date. If there are any To Do's due today or overdue, a red tile will appear in the dashboard to tell you how many there are. This section is shown only if you have dated To Do's.
    • @@ -7094,7 +7115,8 @@

      Starting with a Section Open

    • Task Statistics
    • Tasks Untagged
    • Habit Trends
    • -
    • Habit History
    • +
    • Habit History List (previously Habit History)
    • +
    • Habit History Table
    • Dailies History
    • Dailies Incomplete
    • To Do's with Dates
    • @@ -7131,7 +7153,7 @@

      Possible Future Features

    • For Task Overview and the Dailies sections, show the dates that tasks were last completed to assist with keeping track of monthly and bi-weekly tasks.
    • Modify the "Random To Do" function to also display a random Daily from those that have not been completed.
    • Create a "Random Task" button that displays a randomly-selected To Do and Daily near the top of the page. Allow the button to be clicked to show different tasks without the whole page having to be refetched. Remove the random task currently shown at the bottom of the Task Overview section.
    • -
    • For Habit History and Untagged Tasks, apply the "longContent" class if there are more than x number of items.
    • +
    • For Habit History List and Untagged Tasks, apply the "longContent" class if there are more than x number of items.