I have an SVG hex map that I've joined to my dataset using a foreach function.
Dataset:
var data = [
{ "id": "Scotland ", "value": 5000 },
{ "id": "Wales ", "value": 3000 },
{ "id": "Ireland ", "value": 750 },
{ "id": "North West ", "value": 1250 },
{ "id": "North East ", "value": 4500 },
{ "id": "East Midlands ", "value": 2000 },
{ "id": "South East ", "value": 350 },
{ "id": "South West ", "value": 6000 },
{ "id": "East of England ", "value": 4000 },
{ "id": "West Midlands ", "value": 2500 },
{ "id": "Northern Ireland ", "value": 1000},
{ "id": "Isle of Man ", "value": 3000 },
{ "id": "Yorkshire and the Humber ", "value": 1500 },
{ "id": "Greater London ", "value": 5000 }
];
SVG Sample:
<g role="menuitem" aria-label="South East " transform="translate(445.5384524232801,-18.74937119481314)" cursor="pointer">
<path cs="100,100" d="M5.5,3.5 L0.5,6.5 L-4.5,3.5 L-4.5,-2.5 L0.5,-5.5 L5.5,-2.5 Z" fill="#ffffff" stroke="#ffffff" fill-opacity="1" stroke-width="0.01" stroke-opacity="1" transform="translate(0,0) scale(1)" ></path>
</g>
<g role="menuitem" aria-label="South East " transform="translate(409.5336486154187,-18.74937119481314)" cursor="pointer">
<path cs="100,100" d="M5.5,3.5 L0.5,6.5 L-4.5,3.5 L-4.5,-2.5 L0.5,-5.5 L5.5,-2.5 Z" fill="#ffffff" stroke="#ffffff" fill-opacity="1" stroke-width="0.01" stroke-opacity="1" transform="translate(0,0) scale(1)" ></path>
</g>
<g role="menuitem" aria-label="Greater London " transform="translate(457.534160443724,22.32951986709005)">
<path cs="100,100" d="M5.5,3.5 L0.5,6.5 L-4.5,3.5 L-4.5,-2.5 L0.5,-5.5 L5.5,-2.5 Z" fill="#ffffff" stroke="#ffffff" fill-opacity="1" stroke-width="0.01" stroke-opacity="1" transform="translate(0,0) scale(1)" ></path>
</g>
The function iterates through my dataset and maps the IDs to the respective IDs in the SVG. The IDs within the SVG are contained with the aria-label attribute of g (eg "Scotland", "South East", "Wales"...etc
Function
const ids = data.map(d => d.id);
ids.forEach(id =>
d3.selectAll(`g[aria-label="${id}"]`)
My data contains a Value against each ID/Region. What I'm trying to do is use a colour scale like this:
var colorScale = d3
.scaleLinear()
.domain(d3.extent(data, (d) => d.value))
.range(["#5C4D87", "#EC4E6B"])
.interpolate(d3.interpolateHcl)
...and apply that colour to my SVG based on the value assigned to the Region.
This is what I've tried so far:
const svgUrl = "https://raw.githubusercontent.com/gangrel11/samplefiles/main/amCharts.pixelMap.svg";
d3.xml(svgUrl).then(render);
function render(svg) {
d3.select("body").node().append(svg.documentElement)
const ids = data.map(d => d.id);
ids.forEach(id =>
d3.selectAll(`g[aria-label="${id}"]`)
.select('path')
.style("fill", function(d) {
return colorScale(d)
})
);
CodePudding user response:
Iterate over your initial data not the map of ids.
data.forEach(d => {
d3.selectAll(`g[aria-label="${d.id}"]`)
.selectAll('path')
.style("fill",colorScale(d.value))
})