I'm trying to apply a mouseover function that adds opacity to the elements that are not hovered on.
I have an SVG map with regions and my current function applies 0.8 opacity to the selected region.
I'm trying to invert that so the other regions are the ones that get the applied 0.8 opacity
Here is my code:
function render(svg) {
d3.select("body").node().append(svg.documentElement)
data.forEach(d => {
d3.selectAll(`g[aria-label="${d.id}"]`)
.datum(data)
.selectAll('path')
.style("fill", colorScale(d.value))
.on('mouseover', function() {
d3.selectAll(`g[aria-label="${d.id}"]`)
.filter(function(e) {
return e.id !== d.id
})
.style('opacity', 0.8)
})
.on('mouseout', function() {
d3.selectAll(`g[aria-label="${d.id}"]`)
.style('opacity', 1)
})
})
I thought by adding e.id !==d.id
would do this but is has the opposite effect
My fiddle: jsfiddle
CodePudding user response:
e.id
is undefined
because e
is bound to data
. Consider the use of this selector:
g[aria-label]:not([aria-label="${d.id}"])
Which says select all g
elements with an aria-label
but not those with an aria-label
equalling the d.id
Working example - I've used mouseenter
to minimise the events firing and also 0.5 opacity for effect:
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
}
];
var colorScale = d3
.scaleLinear()
.domain(d3.extent(data, (d) => d.value))
.range(["#5C4D87", "#EC4E6B"])
.interpolate(d3.interpolateHcl)
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);
data.forEach(d => {
d3.selectAll(`g[aria-label="${d.id}"]`)
.datum(data)
.selectAll('path')
.style("fill", colorScale(d.value))
.on('mouseenter', function() {
d3.selectAll(`g[aria-label]:not([aria-label="${d.id}"])`)
.style('opacity', 0.5)
})
.on('mouseout', function() {
d3.selectAll(`g[aria-label]:not([aria-label="${d.id}"])`)
.style('opacity', 1)
})
});
}
.amcharts-bg {
fill: #EEF1FA
}
.amcharts-map-image {
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
Because the hex shapes are slightly separated we see a lot of flicker. This can be mititgated by a update to the example above where the downside is that once a hex is hovered then the map won't go back to the default position of all hexes have opacity of 1:
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
}
];
var colorScale = d3
.scaleLinear()
.domain(d3.extent(data, (d) => d.value))
.range(["#5C4D87", "#EC4E6B"])
.interpolate(d3.interpolateHcl)
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);
data.forEach(d => {
d3.selectAll(`g[aria-label="${d.id}"]`)
.datum(data)
.selectAll('path')
.style("fill", colorScale(d.value))
.on('mouseenter', function() {
d3.selectAll(`g[aria-label]:not([aria-label="${d.id}"])`)
.style('opacity', 0.5)
d3.selectAll(`g[aria-label="${d.id}"]`)
.style('opacity', 1)
})
.on('mouseout', function() {
})
});
}
.amcharts-bg {
fill: #EEF1FA
}
.amcharts-map-image {
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>