[Userscript] Wanikani Item Lattice Script

Wanikani Item Lattice Script

This script brings back the previously removed item lattices, which display your SRS progress for radicals and kanji as a lattice:

The lattices are displayed at the bottom of your profile page:

Installation

This script can be installed via greasyfork.

Wanikani Open Framework is required.

Issues

I made this script a while ago and it has been sitting around for the past 2 weeks in purgatory because I can’t for the life of me get the image radicals to display. In the end I figured I’m better off publishing it with 30 or so missing file pictures than ripping my hair out trying to fix it for several weeks:

Also, your lattice will display on any user profile, which is obviously not meant to happen but I haven’t got around to fixing it since it’s a minor issue.

Finally, I never actually knew about this feature until after it was removed so I had to recreate the lattices using what few screenshots I could find. It seems like a pretty straightforward thing, but if I’ve missed any key features, please let me know.

5 Likes

Cool script!

Some things I noticed in the code:

  • What is this line supposed to do:

    filtered_items.sort((a,b) => a.data.slug - b.data.slug);
    

    The slugs are strings and attempting to subtract them will probably result in a bunch of NaN (I think – you never know with Javascript).

  • In the line

    let item_level = item_obj.assignments.srs_stage;
    

    you try to access the srs_stage property of assignments without first checking if assignments even exists (which it doesn’t if you have not unlocked the item yet). You could use optional chaining:

    let item_level = item_obj.assignments?.srs_stage ?? 0;
    
  • As for the problem with the image-based radicals: I have no idea if this can be fixed. I just noticed that the method I’m using in ConfusionGuesser has also stopped working. I think it is some CORS problem, but I’m not certain.

    EDIT: The reason why I’m thinking it is probably a CORS problem is that

    await (await fetch(items.find(i => i.id === 1).data.character_images[0].url)).text()
    

    works without a problem, but when I try to fetch it for item 8761 (which is the image-based “Stick” radical), I get a CORS error:

    await (await fetch(items.find(i => i.id === 8761).data.character_images[0].url)).text()
    
4 Likes

Thanks!

So originally I was going to convert the strings to unicode, however after checking the documentation for sort(), it turns out you can just compare the strings as is, as it converts strings automatically. I’m using the sort method here to arrange the items within each level in unicode order as @rfindley recommended a while back (however thinking about it, sorting by the character rather than the English may be closer to what WK did).

OH THAT’S WHAT THAT’S CALLED!

I spent ages trying to find what that was called since I didn’t know what it did but google kept thinking I meant ternary operators. I’ll be sure to add that later.

Oh well that’s slightly relieving knowing it may not entirely be my inability to implement svgs. I’ll look into it later maybe. I noticed the images still worked on the stats site though so I’m not entirely sure what I’ll be able to do.

2 Likes

fyi… strings in Javascript are already unicoded.
And the “proper” way to sort them:

filtered_items.sort((a,b) => a.data.slug.localeCompare(b.data.slug));
4 Likes

Just out of curiosity, is there any difference between this method and just using the greater than operator? I know localecompare is supposedly the correct way, but I never looked into the difference

1 Like

Different languages sort things differently.

Examples:
In German, “a” and “ä” get sorted together.
In Spanish, “n” and “ñ” get sorted together.

['Hängt', 'Haut', 'Hüllen', 'Hubert'].sort();
// ['Haut', 'Hubert', 'Hängt', 'Hüllen']

['Hängt', 'Haut', 'Hüllen', 'Hubert'].sort((a, b) => a.localeCompare(b));
// ['Hängt', 'Haut', 'Hubert', 'Hüllen']
4 Likes

Oh that’s useful to know! Although is there a way to sort by the alphabetical order of a given locale in that case? Since (and Kumirei can confirm) I believe Swedish puts those accented vowels at the end of the alphabet (X, Y, Z, Å, Ä, Ö).

This may have to be something I look into later since now I’m also curious about Japanese kana order… :thinking:

I think localeCompare() pulls your language settings from the Browser, which defaults to the OS settings.

If you need to specify the locale, you can use Intl.Collator, which is probably used internally by localeCompare():

['z', 'ä', 'Z', 'a'].sort(new Intl.Collator('en-US').compare);
['z', 'ä', 'Z', 'a'].sort(new Intl.Collator('en-GB').compare);
['z', 'ä', 'Z', 'a'].sort(new Intl.Collator('de').compare);
['z', 'ä', 'Z', 'a'].sort(new Intl.Collator('sv').compare);

[Edit: Some interesting Intl.Collator options [here] ].

4 Likes

Cool script!

Just one lil nugget left 0:

2 Likes