[Userscript] Wanikani Heatmap

What is Wanikani Heatmap

This script adds a so called heatmap to your dashboard, which displays how many reviews and lessons you did on each day. The reviews heatmap additionally features a forecast for upcoming reviews. Along with the heat maps you also get a number of interesting stats, such as how many days you have studied, your daily average, and your streak.

The look and feel of the heatmaps is very customizable. See the settings section for more detail.

A lot of this info can be hovered over to display some additional or more detailed info. The time spent on reviews, for example, can also show you how much time you have spent in the last year, month, week, or day. If you hover over a day it will tell you the exact number of items you did on that date. It will also tell you if you burned any items on that day.

You may notice that some days in the above screenshots have white borders around them. These are the dates where you leveled up. If you hover on these days it will also tell you what level you reached that day.

If you click on a date, you will also be provided with specific information on what you did that day. This will tell you the levels of the items, the SRS, types, and how well your reviews went. The items you learned or did reviews for are also displayed, and if you hover over them you can see detailed information about that item.

The script will not show any review data from before August 2017 since Wanikani did not log reviews before that. All lessons will be shown, however, as long as you have not reset them. If you have reset before then the script can recover lost lesson data by looking at your review history and guessing when the lesson was done, but only for resets after August 2017.


Settings

There are plenty of settings available for this script

General


  • Position: This determines where the heatmap should be inserted into the page. Try out the different positions and see which you like best

  • Start Date: This allows you to set a manual start date. The script will ignore any data before this date. This is useful for users who went away for years then came back and want a fresh start

  • First Day Of The Week: Determines which day of the week should be on top. Each row of a year represents a different weekday. Default is Monday because Monday is obviously the correct choice upside_down_face

  • New Day Starts At: This setting allows you to determine when a new day starts. If you set it to 4, then the new day will start at 4 AM on the following date. This is useful if you stay up late and want your reviews to count towards the day before.

  • Session Time Limit: This determines how long you can go between review or lesson answers that it should still count to the same session. This has bearing on your total number of sessions as well as your time spent.

  • Theme: Mainly used to change the background between light and dark, but there is also a Breeze Dark theme which changes the color of the items in the pop-up.


  • Reverse Year Order: If you want the most recent year on the bottom instead of the top, this setting is for you.

  • Segment Year: Put spaces between the months to clearly show when one ends and another starts.

  • No Gap: Removes the gap between dates.

  • Day Of Week Labels: Whether you want the day of week labels displayed?!

  • Month Labels: Month labels offers three different settings. Only on top, which… Only displays the month labels on the topmost year. All, which… Displays them on all years. And none… Which displays them twice each year.


  • Current Day Indicator: Puts a border with a color of your choosing around the current day. Fancy.

  • Level-up Indicator: Puts a border with a color of your choosing around the dates of your level ups! Incredible!

Reviews & Lessons


  • Auto Range: Let the script determine what the bounds of your intervals should be using quantiles.

  • Use Gradients: Let days take on any color between your chosen colors depending on the actual number of items you did that specific day.


Let me explain the intervals. To the left you have your interval bounds. These determine at what number of items the color on the right should start to be used. In the screenshot above, you can see that days between 1 and 64 items should have the color \definecolor{c}{rgb}{0.68, 0.895, 1}\color{c}\text{#ADE4FF}. And then to the right there is a trash can for removing intervals.

  • Add Interval: This button adds an interval to your intervals! Amazing! Don’t forget to choose an interval bound and color.

  • Generate Colors: This button generates new colors for your intervals through interpolation between your first and last non-zero interval.


  • Reload Review Data: In case anything goes wrong you can choose to clear the review cache and fetch all your reviews anew.

  • Include Zeros In Streak: If you don’t want your lesson streak to be broken by not having any lessons to do, then tick this boxxy box. This setting makes days without any lessons available count towards your streak.

  • Recover Reset Lessons: If you have ever reset then your lessons heatmap will be missing some data. This is due to WK deleting lesson data for all items that you reset. Ticking this box allows the Heatmap to guess when you did those lessons based on your review history, and thus restore reset lessons to your heatmap.


For more heatmap screenshots, have a look at this thread


Available at

the local ice cream stand

145 Likes
The New And Improved List Of API and Third Party Apps
7 kinds of WaniKani users (to be continued)
Review heatmap script?
End of free level. Considering subscription~
What do you want now? (Request extensions here)
New People Questions! ~~~<3 [Lost?! Confused?! We're here to help!]
Wanikani screenshots :camera_flash:
How long do you spend on WaniKani each day?
No Burns Yet
ロウェナの学習ログ・(Rowena's Study Log)
Website for graph of total kanji learned over time?
Did you ever do too many lessons at once?
Reviews after level 60
Level 38 and ready to give up
Graduating from Wanikani, feeling grateful (Level 60)
The 0/0 Streak Challenge
Let's climb Tokyo Skytree - level 60 in spring 2022
Level 21 before 2021!
Level 21 before 2021!
Easy Reviews: A Beginner's Guide
New People Questions! ~~~<3 [Lost?! Confused?! We're here to help!]
Hello and Goodbye (Level 60 Post)
Subscribed today
My Journey of 368 days (+ The Ultimate Guide for WK :open_book: )
Creating a Consistent 日本語 Routine (WK and Beyond)
Feature request: Last review date in progression area
Overall Statistics
How to build an efficient WaniKani schedule (level up as comfortable as possible): the guide
Heatmap Stories! (WaniKani Activity Chart)
Wanikani screenshots :camera_flash:
Streak counter for WaniKani?
Fixed limit of lessos per-day?
Level 21 before 2021!
How to use the Heatmap Script
100+ review a day with less than 50 apprentice
Level 21 before 2021!
View Lessons Completed Per Day
Race to Your Goal! December 2020 JLPT
Level 21 before 2021!
Joining the level 60 club after 350 days
Level 60 in 362 straight days of reviews
BOOM! Level 60 in a little under a year (361 days)
Kumirei's Userscripts
Weird pop up on WK all of a sudden
Race to Your Goal! December 2020 JLPT
Is there a plugin to see total time spent on reviews? :)
A month in a row
Why are items not burning yet?
Race to Your Goal! December 2020 JLPT
A new year! How's it looking?
So I restarted. Again
Doing reviews on phone vs. computer
Random thoughts after 1 year on WaniKani
Random thoughts after 1 year on WaniKani
Daily Review Count
Making Progress on the Dashboard, Take 2
One month of WaniKani
What level to get 200+ reviews each day?
Yay! Level 60!
Yay! Level 60!
[Android] Leap for WaniKani Demo (Native, Offline, No Web)
How Many Lessons Per Day
Some reasons I love Wanikani
Wanikani Open Framework [developer thread]
Longest Review Session
Truandissimo‘s Study Log
Longest Review Session
(Feature Request) Heatmap on dashboard
Stuck at 87%
One review at a time club
Race to Your Goal! December 2020 JLPT
The 0/0 Streak Challenge
Ah! Everything looks different!
Wanikani screenshots :camera_flash:
Finally made it out of Level 11
An overdue level 60 post
What to expect when changing levels?
Level 60! Double Cake Day!
Is there a peak hellish level after which it gets easier again?
My Journey of 368 days (+ The Ultimate Guide for WK :open_book: )
Level 60 in more than 350 days :D
Is there a way to get Anki like timeline for statistics in wanikani
I finally broke my record!
Level 60 in less than a year (350 days)
My Journey of 368 days (+ The Ultimate Guide for WK :open_book: )
うちはは を なめるな!- My Level 60 Post
Wanikani Open Framework [developer thread]
Could we have an option for removing the 42 lesson/review limit?
Level 60 in more than 350 days :D
How much time do you dedicate to Japanese daily?
Heatmap script- Need help
Random Thoughts After 2 Years on WaniKani
Let's climb Tokyo Skytree - level 60 in spring 2022
My progress on a timeline
New to forums, not entirely new to Wanikani
Is it weird how excited and nervous I am to have become a lifer?
The climb to the :cake:, a diary. Let's go to level 60! (59 now) :fire:
I am on level 10, and getting burnt out
Userscripts Help
Diary of a mad level 50'er
Diary of a mad level 50'er
Level 20 and unburned
Am I too slow at Wanikani?
How to find stats
My Journey of 352 days

Nice script. You should add a note that WKOF is a prerequisite (and what it is/link) and is not bundled in the heatmap script, and if possible add a notification to the heatmap script that the WKOF is missing (dialog or whatever).

It will be easier for first-time users.

7 Likes

Maybe follow WK colors (from apprentice, guru, master…)

10 Likes

I have been tricked (ಥ_ʖಥ)

12 Likes

I thought I did
You didn’t get an alert?

// Make sure WKOF is installed
		if (!wkof) {
				var response = confirm('WaniKani Heatmap requires WaniKani Open Framework.\n Click "OK" to be forwarded to installation instructions.');
				if (response) window.location.href = 'https://community.wanikani.com/t/instructions-installing-wanikani-open-framework/28549';
				return;
		}

I did try that, but it got rather messy. I think having a spectrum is more intuitive. Thanks for the suggestion though. I don’t really like the current colors.

8 Likes

Nope, no window.

I am not exactly sure how Tampermonkey works in Firefox, but the script itself is executed in the strict mode. In strict mode, they did some changes with the strict mode and undeclared variables… not really sure what (I am not a JS developer), the code itself is run in the eval() (or apply() or something).

Anyway, when I debug the code, once I reach the if (!wkof), the ReferenceError is thrown, unless I enable the WKOF in the Tapermonkey dashboard.

I guess the reason is same as why this (fix quotes, not sure why are they changed in the post):
(function() {“use strict”; eval(“if (!wk) { console.log(1);} else {console.log(2);}”); }())

throw ReferenceError: wk is not defined when I run it in the console.

Huh. I didn’t know about that. @rfindley do you know if there’s a good reason why Firefox would throw a ReferenceError? Should we maybe use a try-catch instead of if (!wkof)?

It’s wkof, not wk. Does it work with wkof?

Thanks so much for this! It’s really interesting to see.

4 Likes

Could change it to:

if (!window.wkof) ...

Or don’t turn on strict in your script (though I don’t know whether there’s a setting to make it default to strict, in which case some people may still have problems.).

2 Likes

I don’t have 'use strict' in the script, so I would assume it’s something on their end. I’ll use just put var wkof = window.wkof in my scripts from now on

1 Like

Awesome!! Looks very nice, thank you!
I love my review heatmap in Anki. I was not sooo excited about getting it for WaniKani since I could imagine what it would look like anyway (who doesn’t painfully remember when you had those few weeks where you didn’t review) but now that I see it, I love it :slight_smile:

In case you are interested in extending this further, here’s a screenshot of the info that the Anki plugin shows below the heatmap. This is also super motivating, I look at it even more than at the actual heatmap:

8 Likes

Sounds like good info for an update at some point ukKr5

7 Likes

I couldn’t wait :smiley:

Added no styling, just quickly threw something together. In case you want to reuse it. It is called in the same way as create_heatmap:

    function create_streakinfo(data) {
        var streakinfoSection = document.createElement('section');
        $(streakinfoSection).attr("class", "streakinfo");

        var daysWithReviews = 0;
        var daysWithoutReviews = 0;
        var longestStreak = 0;
        var totalReviews = 0;

        //get date without time (00:00) in order to match date in data
        let firstDate = new Date(new Date(data.first_date).getFullYear(), new Date(data.first_date).getMonth(), new Date(data.first_date).getDate());
        let lastDate = new Date(new Date(data.last_date).getFullYear(), new Date(data.last_date).getMonth(), new Date(data.last_date).getDate());

        var currentDate = firstDate;
        var currentStreak = 0;
        var previousDayHadReviews = false;

        while (currentDate <= lastDate) {
            var dateInSeconds = currentDate.getTime() / 1000;
            var count = data.counts[dateInSeconds];
            if (count) {
                if (previousDayHadReviews) {
                    currentStreak++;
                }
                totalReviews += count;
                daysWithReviews++;
                previousDayHadReviews = true;
            } else {
                if (currentStreak > longestStreak) {
                    longestStreak = currentStreak;
                }
                currentStreak = 0;
                daysWithoutReviews++;
                previousDayHadReviews = false;
            }
            currentDate.setDate(currentDate.getDate() + 1);
        }
        if (currentStreak > longestStreak) longestStreak = currentStreak;
        let averageReviews = Math.round(totalReviews / (daysWithReviews + daysWithoutReviews));
        let percentageWithReviews = Math.round(daysWithReviews / ((daysWithReviews + daysWithoutReviews) / 100));

        streakinfoSection.append("Average daily reviews: " + averageReviews + " Studied on " + percentageWithReviews + "% of days (" + daysWithReviews + " out of " + (daysWithReviews + daysWithoutReviews) + ") Longest streak: " + longestStreak + " Current streak: " + currentStreak );
        $('.progression').after(streakinfoSection);
    }

(I also didn’t double check super duper carefully so the calculation might be a bit off; it “felt right” and I decided I was done :wink: )

6 Likes

It looks super cool! Small idea, it might be fun to see when you had WaniKani on vacation mode. Is it possible to add that?

4 Likes

I pretty much never use strict mode, and I’d still expect it to throw an error if it doesn’t have “window.” in front and the variable hasn’t been declared or assigned yet. That’s just normal JavaScript. Maybe greasemonkey/tampermonkey handles that differently somehow?

1 Like

I like it! And the colors seem fine to me.

Minor thing: it time travels.
49%20PM

3 Likes

Seems like you wouldn’t want that to throw an error if the state of being undefined was one of the conditions you were trying to test. How would you get a false? or true for if-not, ykwim

2 Likes

Nice script Kumi! For colors, maybe yellow to dark red? It’s is a heat map after all.

This is really one of those things that @viet and @oldbonsai should implement as a proper feature though…

3 Likes

Hey, you made it! Thanks Kumi! You’re awesome.

1 Like

:ok_hand:

I definitely started on July 4th, is there no data prior to August 4th?

3 Likes