color in chart.js

I've been thinking about adding charts to my site for a bit, mostly for the fun of messing around with them, and my reading (modern) classics project page gave me the perfect excuse, since I knew I wanted to make a status pie chart.

I decided to use Chart.js, an open-source JavaScript charting library under the MIT license. This ended up being more of a project than I initially anticipated. Honestly, I was a little spoiled after setting up Prism.JS, the JS library I use for syntactical highlighting in code, which claims to be "dead simple" and absolutely lives up to that claim. Setting it up involved absolutely no fucking around in the JS and only a handful of extremely obvious changes to the accompanying CSS.

To be absolutely fair, Chart.js would have been much the same if I'd been content to use their code as intended. However, I was not going to be using their default colors, and I also wasn't particularly interested in setting the color variables in every page on which I was using charts. What I wanted was a way to use my theme colors in place of their theme colors.

It ended up being a pretty simple fix, once I found what I wanted to be fixing.

My solution involves self-hosting the script, which was a thing I had always intended to do and thus not something for which I tried to find a work-around. If you meant to do something else, then I don't know if this solution will be of much use to you—I presume you could make a full extension if you were more comfortable with JS than I am, but I'm going to leave things here.

setting new defaults

So, the Chart.js code (which I retrieved from here) has been processed from a human-readable CommonJS code into, like, vanilla JS code-soup. The first thing I did once I copied the code into my own JS file in VSCode was do a regex find/replace to put a line break after each close curly bracket ({) and each semicolon (;), which broke things up into small enough chunks for my syntax highlighter to start functioning and my eyes to stop glazing over.

Then I went to find the color variables, which took for-fucking-ever. You're looking for an array called $o, which will have a set of RGB codes, beginning with "rgb(54, 162, 235)". These are the default colors: if you just want to replace them with your own theme colors, you just need to put your colors into this array. Your colors do need to be in RGB format (the subsequent Yo array relies on this format), but you do not need to use the same number of colors (I went from their seven to my eight with no trouble whatsoever).

Just for absolute clarity, this is what the relevant section looks like in the original code:

const $o=["rgb(54, 162, 235)","rgb(255, 99, 132)","rgb(255, 159, 64)","rgb(255, 205, 86)","rgb(75, 192, 192)","rgb(153, 102, 255)","rgb(201, 203, 207)"], Yo=$o.map((t=>t.replace("rgb(","rgba(").replace(")",", 0.5)")));

and this is what it looked like once I was done with it:

const $o=["rgb(118, 80, 135)","rgb(63, 124, 172)","rgb(101, 129, 109)","rgb(139, 134, 45)","rgb(228, 162, 29)","rgb(221, 125, 44)","rgb(213, 87, 59)","rgb(175, 84, 71)"], Yo=$o.map((t=>t.replace("rgb(","rgba(").replace(")",", 0.5)")));

If you just want to switch out one color for another, then you're done. However, I had to make things (even more) complicated...

using CSS variables

My next problem was that I didn't actually want the defaults to be static RGB codes. I wanted them to change to match a given theme, and that meant somehow figuing out how to tie them to my CSS variables.

The solution I settled on was this:

const style = window.getComputedStyle(document.documentElement);

const mainText   = "rgb(" + style.getPropertyValue('--main-text') + ")";
const colorList  = "rgb(" + style.getPropertyValue('--color-list') + ")";
const colorLink  = "rgb(" + style.getPropertyValue('--color-link') + ")";
const colorBlqt  = "rgb(" + style.getPropertyValue('--color-blockquote') + ")";
const colorBg    = "rgb(" + style.getPropertyValue('--color-bg') + ")";
const colorNav   = "rgb(" + style.getPropertyValue('--color-nav') + ")";
const colorCode  = "rgb(" + style.getPropertyValue('--color-code') + ")";
const colorCard  = "rgb(" + style.getPropertyValue('--color-card') + ")";
const colorTable = "rgb(" + style.getPropertyValue('--color-table') + ")";

and then the $o array looked like this:

const $o = [colorList, colorLink, colorBlqt, colorBg, colorNav, colorCode, colorCard, colorTable], Yo = $o.map((t => t.replace("rgb(", "rgba(").replace(")", ", 0.5)")));

In addition to making it so that the default chart will match the theme colors (as long as you reload the page between switching themes), this also means that I can use these variables in specific charts. This is extremely convenient, and I've already made use of it.

I am exceptionally pleased with the result here. Stylish charts, here I come.