I have heard that I can use the API to get SVG radical images. How can I use the API using JavaScript (at the time of writing, ideally v2) to get all non-Unicode radical images (with the Radicals Update of December 2018 if that makes a difference.)
Are you familiar using the APIv2? The SVGs are in the /subjects
endpoint, under the JSON path data.character_images.
curl --request GET \
--url 'https://api.wanikani.com/v2/subjects?types=radical' \
--header 'accept: application/json' \
--header 'authorization: Bearer YOUR-KEY-HERE' \
--header 'wanikani-revision: 20170710'
Since there’s less than 1000 radicals, you should only need to make the one request.
Then, to get all the svg images (assuming you’re familiar with JsonPath notation):
$.data[*].data.character_images[?(@.content_type == 'image/svg+xml')].url
There are two copies of each SVG: one with CSS styling, and one without.
I personally prefer the ones without, so you can change the color and thickness.
If you want to style it yourself, here are the initial attributes:
svg.radical {
fill:none;
stroke:#000;
stroke-linecap:square;
stroke-miterlimit:2;
stroke-width:68px;
}
The JsonPath to only retrieve the ones without styling:
$.data[*].data.character_images[?(@.content_type == 'image/svg+xml' && @.metadata.inline_styles == false)].url
Alternately: $.data[*].data.character_images[?(@.content_type == 'image/svg+xml' && !@.metadata.inline_styles)].url
, but that can resolve ambiguously if some svg doesn’t have the inline_styles metadata for whatever reason.
Thanks for the quick responses! Actually, I’m not familiar with the APIv2, although your wkstats.com:10001 with it is great! How can I get this with JavaScript?
What language are you planning on using to do things with the svgs? If it’s something like JavaScript or python I can whip up a simple script to grab the links.
Can you create it in JavaScript? Thank you!
Here you go. I’ve tested this in Chrome 67 (the version I have at work), so it should work in most browsers released in the past year.
function getRadicalSVGS(v2Key){
var headers = new Headers({
"Authorization": `Bearer ${v2Key}`,
"Accept": "application/json",
"Wanikani-Revision": "20170710"
});
return fetch("https://api.wanikani.com/v2/subjects?types=radical", {headers: headers})
.then(response => {
if(!response.ok) throw new Error(response.status);
return response.json();
})
.then(data => {
var radicalSVGs = {};
data.data.forEach(function(radical){
var primaryMeaning = radical.data.meanings.find(function(meaning){ // Find the Primary meaning
return meaning.primary;
}).meaning.toLowerCase(); // Set the primary meaning
var svgUrl = radical.data.character_images.find(function(image){ // Find the first SVG that does not have styling. Omit the '!' to get the ones with styling.
return image.content_type == "image/svg+xml" && !image.metadata.inline_styles;
});
if(svgUrl){ // Not all radicals have an SVG
radicalSVGs[primaryMeaning] = svgUrl.url;
};
});
return radicalSVGs
});;
}
getRadicalSVGS("YOUR_V2_KEY_HERE").then(radicalSVGs => {
// Do whatever you want with the mapping here, for example:
for (var key in radicalSVGs){
if(radicalSVGs.hasOwnProperty(key))
console.log(key + ": " + radicalSVGs[key]);
}
});
This gladiator radical isn’t showing up correctly - can someone explain this?
@rfindley, how does it look right on WK Stats v2?
You need to add the CSS styling to it to get it to render properly.
svg.radical {
fill:none;
stroke:#000;
stroke-linecap:square;
stroke-miterlimit:2;
stroke-width:68px;
}
will give you this:
You can also just use the pre-styled ones if you like, just remove the !
from the script I posted.
Great! Can I filter out the radicals with a Unicode codepoint (e.g. ground = 一, so don’t include that one)?
You can check to see if the radical’s characters
property is null
before doing any work on it.
An updated script:
function getRadicalSVGS(v2Key){
var headers = new Headers({
"Authorization": `Bearer ${v2Key}`,
"Accept": "application/json",
"Wanikani-Revision": "20170710"
});
return fetch("https://api.wanikani.com/v2/subjects?types=radical", {headers: headers})
.then(response => {
if(!response.ok) throw new Error(response.status);
return response.json();
})
.then(data => {
var radicalSVGs = {};
data.data.forEach(function(radical){
if(radical.data.characters !== null)
return;
var primaryMeaning = radical.data.meanings.find(function(meaning){ // Find the Primary meaning
return meaning.primary;
}).meaning.toLowerCase(); // Set the primary meaning
var svgUrl = radical.data.character_images.find(function(image){ // Find the first SVG that does not have styling. Omit the '!' to get the ones with styling.
return image.content_type == "image/svg+xml" && !image.metadata.inline_styles;
});
if(svgUrl){ // Not all radicals have an SVG
radicalSVGs[primaryMeaning] = svgUrl.url;
};
});
return radicalSVGs
});;
}
getRadicalSVGS("YOUR_KEY_HERE").then(radicalSVGs => {
// Do whatever you want with the mapping here, for example:
for (var key in radicalSVGs){
if(radicalSVGs.hasOwnProperty(key))
console.log(key + ": " + radicalSVGs[key]);
}
});
There are much fewer of them.