I'm playing around with a Mapbox map (written in React) that currently gives me the following output:
My problem: the coloring of the GeoJSON objects is incorrect. It implies that both shapes have values of ~-4. In truth, the left-hand figure has a value of 10, and should be solid blue, while the right-hand figure, with a value of 5, should be blue-green.
Here's the code for the Mapbox GeoJSON layer:
export const COLOR_SCALE = d3
.scaleSequential(d3.interpolateYlGnBu)
.domain([-4, 16])
.range([
[255, 255, 217],
[248, 252, 201],
[239, 249, 189],
[228, 244, 181],
[213, 238, 179],
[193, 231, 181],
[169, 221, 183],
[142, 211, 186],
[115, 201, 189],
[91, 191, 192],
[69, 180, 194],
[52, 167, 194],
[40, 151, 191],
[33, 134, 185],
[32, 115, 178],
[34, 96, 169],
[35, 78, 160],
[34, 62, 149],
[28, 49, 133],
[19, 38, 112],
]);
var layers = [
new GeoJsonLayer({
id: "geojson",
data: data,
filled: true,
getFillColor: (f) => COLOR_SCALE(f.properties.growth),
}),
];
Here's the code for the color scale:
useEffect(() => {
var colorScale1 = d3.scaleSequential(d3.interpolateYlGnBu).domain([-4, 16]);
var svg = continuous("#legend1", colorScale1);
}, []);
Where svg is used as a React component. Finally, if needed, here's how I define continuous:
function continuous(selector_id, colorscale) {
var legendheight = 200,
legendwidth = 80,
margin = { top: 10, right: 60, bottom: 10, left: 2 };
var canvas = d3
.select(selector_id)
.style("height", legendheight + "px")
.style("width", legendwidth + "px")
.style("position", "relative")
.append("canvas")
.attr("height", legendheight - margin.top - margin.bottom)
.attr("width", 1)
.style("height", legendheight - margin.top - margin.bottom + "px")
.style("width", legendwidth - margin.left - margin.right + "px")
.style("border", "1px solid #000")
.style("position", "absolute")
.style("top", margin.top + "px")
.style("left", margin.left + "px")
.node();
var ctx = canvas.getContext("2d");
var legendscale = d3
.scaleLinear()
.range([1, legendheight - margin.top - margin.bottom])
.domain(colorscale.domain());
var image = ctx.createImageData(1, legendheight);
d3.range(legendheight).forEach(function (i) {
var c = d3.rgb(colorscale(legendscale.invert(i)));
image.data[4 * i] = c.r;
image.data[4 * i + 1] = c.g;
image.data[4 * i + 2] = c.b;
image.data[4 * i + 3] = 255;
});
ctx.putImageData(image, 0, 0);
var legendaxis = d3.axisRight().scale(legendscale).tickSize(6).ticks(8);
var svg = d3
.select(selector_id)
.append("svg")
.attr("height", legendheight + "px")
.attr("width", legendwidth + "px")
.style("position", "absolute")
.style("left", "0px")
.style("top", "0px");
svg
.append("g")
.attr("class", "axis")
.attr(
"transform",
"translate(" +
(legendwidth - margin.left - margin.right + 3) +
"," +
margin.top +
")"
)
.call(legendaxis);
}
How can I configure COLOR_SCALE such that the shapes are properly colored? I suspect the error stems from the range values. For context, I got the RGB values from colorScale1 by iterating using console.log(colorScale1(i)).



