I'm creating a diverging scale using D3.js with:
scaleDiverging = d3.scaleDivergingSymlog(d3.interpolateBrBG)
.domain([-0.1, 0, 0.1])
I can then call scaleDiverging(0.05)
and I'll get back a value of 'rgb(87, 175, 165)'
. This works great except that I need to fill a canvas
image with RGB integers. So I have to parse those strings returned from scaleDiverging
:
const parseRgb = color =>
color.substring(4, color.length - 1).split(', ')
.map(n => parseInt(n))
Easy solution, but this is the problematic part where my application spends most of its time and is the reason why my interactive graph is not smooth. You move a slider and 2 seconds later the image changes. If I replace parseRgb
with a simple function that inaccurately returns back an array of numbers, the graph is smooth! I need the array of RGB values for Canvas' putImageData
function:
const context = canvas.node().getContext('2d'),
imageData = context.getImageData(0, 0, width, height),
data = imageData.data
for (int i = 0; i < width * height * 4; i += 4) {
const color = parseRgb(scaleDiverging(calcVal(i)))
data[i] = color[0]
data[i + 1] = color[1]
data[i + 2] = color[2]
data[i + 3] = 255
}
context.putImageData(imageData, 0, 0)
Can I get the scaleDivergingSymlog
functionality from D3.js where I don't have to parse the resulting string? I know I can look up the code and implement it myself, but, in addition to avoiding that work, I'd like to know how to properly use D3.js in the future for interactive graphs.
Someone else on stackoverflow had a similar issue and the only answer was to use d3.color
. This is essentially the same as my parseRgb
function above, but has even worse performance :(.