D3.js Highlight an element when hovering over another - javascript

I have a donut chart made using D3.js. I would like to change the color of the arc when hovering over the corresponding text.
I know how to change the color of the first, or all, but the corresponding one.
Here's the code so far. The lines that do the highlighting are the following:
.on("mouseover", function(d,i){
//d3.select(".donutArcSlices").transition().style("fill", "#007DBC");
//d3.selectAll(".donutArcSlices").transition().style("fill", "#007DBC");
div.transition()
.duration(200)
.style("opacity", .9);
div .html(d.name)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
d3.select(".donutArcSlices").transition().style("fill", "#3E4750");
div.transition()
.duration(500)
.style("opacity", 0);
});
If I add the first commented line, when I hover over any of the texts in the arcs, the first arc changes colors. If I remove the comments on the second line, then all of the arcs change colors upon hovering over any of the texts.

Give each path an unique ID:
.attr("id", function(d,i){ return "donut"+i})
And use it when hovering:
d3.select("#donut" + i).transition().style("fill", "#007DBC");
Here is your fiddle: https://jsfiddle.net/d6839s03/
PS: your mouseout function is making everything gray.

You can filter the correct path like this :
d3.selectAll(".donutArcSlices").filter(function(e, j){ return i === j}).style("fill", "#007DBC");
See https://jsfiddle.net/o98b8fsj/

Awesome answer for Gerardo. Anyone trying it with D3js v5 can use the same underlying concept.
I am using D3js V5 + Angular 6 with the following code snippets-
add id attribute to the node or any other element you want to manipulate -
this.svg.append('g').attr('id' ,(d,i)=>'elementname'+i)
then just make the changes on the d3js event of your choice -
.on('mousehover', (d,i)=> d3.select('#elementname'+i).style('fill','red')
.on('mouseout', (d,i)=> d3.select('#elementname'+i).style('fill','black')

Related

Multiple tooltips not showing correctly in react

I am working with react D3 charts, and I have created charts and it is working fine.
What I have done
I have several charts which are updating with in some time intervals, something like live data
So here to achieve this I out use effect and updating my charts every second, and my data in charts updates correctly.
I have given one tooltip on hover over the the bar, so that user can check the data for each bar or line.
Using below code to show the tooltip
.on("mousemove", function (event, d) {
// this whole code is when I hover that perticular bar
d3.select(this)
.transition()
.duration("50")
.attr("opacity", 0.6)
.attr("x", (a) => xScaleBars(a.timeline) - 3)
.attr("width", xScaleBars.bandwidth() + 6)
.style("filter", "url(#glow)");
div.transition().duration(50).style("opacity", 1);
div
.html(
`</text><text"></br> value : ${d.dataToShow}
<br/>
</text><text"></br> Month : ${d.month}
`
)
.style("left", event.pageX - 58 + "px")
.style("top", event.pageY - 140 + "px");
})
.on("mouseout", function (d, i) {
// this is when I move cursor out of that bar
d3.select(this)
.transition()
.duration("50")
.attr("width", xScaleBars.bandwidth())
.attr("x", (a) => xScaleBars(a.timeline))
.style("filter", "none")
.attr("opacity", "1");
div.transition().duration("50").style("opacity", 0);
})
Issue I am facing
The issue is when I hover over one chart component it shows the tooltip, and than when I hover over the other both shows at the same time.
What I am trying to do is to show the tooltip when I hover the one bar of any chart and than hide it,I tried below code
d3.select("svg").selectAll(".tooltipCHart").remove();
But it doesn't resolve my issue, I think I am missing some small part
here is my code sandbox which I tried
The problem is that you're creating a new tooltip div every time you re-render the chart.
A better approach is to have a hidden tooltip div in the beginning (in the render / return from your function component) and then just modify its contents and style (opacity: 1) on mouseover and mouseout. Keep track of the tooltip div using a ref.
See working codesandbox (I only modified chart1, you can make similar changes to chart2)

How to display paths/lines when I'm hovering circles instead of Voronoi cells?

I'm searching a solution. I started from this example : http://mbostock.github.io/d3/talk/20111116/airports.html
Here, you can hover the map, and see the lines appearing at same time.
But, lines are appearing even if you aren't on a circle.
I'm actually searching for a solution where lines (or paths) are displaying only when you hover a circle?
That's why I wrote this part of code :
var c = circles.selectAll("circle")
.data(airports)
.enter().append("svg:circle")
.attr("cx", function(d, i) { return positions[i][0]; })
.attr("cy", function(d, i) { return positions[i][1]; })
.attr("r", function(d) { return d.r })
.style("fill", function(d){ return d.color})
.sort(function(a, b) { return countByAirport[b.iata] - countByAirport[a.iata]; });
c.on("mouseover", function(e){
g.select("path.arc")
.style("display", "inherit")
});
});
c.on("mouseout", function(e){
g.select("path.arc")
.style("display", "none");
});
I'm probably far away from the good way to do this. Here, with my code, I can display all paths when I'm hovering each circles. I take others solutions too, I can leave Voronoi (as I don't want to use cells, maybe you know another way more practicable...).
My ultimate goal would be to find this answer, and then, to display paths which is/are only concerned by the circle which is hovered. I need more precision compared to Voronoi, but it seemed good at first, for paths i.e.).
I could add more code, but globally, it is the same as the example above
Thank you!
Here's a solution to your ultimate goal - display paths related to the hovered circle
https://shashank2104.github.io/d3-Voronoi/
Relevant code changes:
Added a class to the <g> containing the arcs
.enter().append("svg:g").attr('class', function(d) { return d.iata; });
Changed mouseover and mouseout events for the circles to display the arcs basedon the class added in the first step.
circles.on("mouseover", function(d){
console.log(d.iata);
cells.select('g.'+d.iata).selectAll("path.arc")
.style("display", "inherit")
}).on("mouseout", function(d){
cells.select('g.'+d.iata).selectAll("path.arc")
.style("display", "none");
});
Took off the CSS that displayed all arcs:
#cells g:hover path.arc {
display: inherit;
}
I could add more code but I'm guessing you can look at the source code on the github page.
Hope this helps.

D3 Display elements of inner list on tool tip as different lines

A quick and short question in d3. I have the following data in json:
{"KMAE":[-120.12,36.98,"MADERA MUNICIPAL AIRPORT",[26,1,2,5,6,3,2,1,2,7,29,12,3]]}
I am plotting this point on a google map and applying a tool tip on the point. On the tool tip what I have given now is
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div .html(d.value[3])
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
Well what now I am getting when mouse over happens is 26,1,2,5,6,3,2,1,2,7,29,12,3.
How can we make this in different lines inside the tool tip? Say like:
26 on top, 1 below that, 2 below that and so on.
In my actual application this inner list's length wont be the same for many points like KMAE.
Thanks
Since you're using HTMl for the tooltip, it's easy -- join the array elements with <br>:
div.html(d.value[3].join("<br>"))

Unable to get drop-shadow on the bars

I am working on a bar chart and I need to get the chart to look like this:
Here is what I tried:
.attr("id", "drop-shadow")
.attr("height", "130%");
but it did not work.
jsfiddle
How do I fix this?
Try this fiddle.
Chart looks like that same as the image.
But i didn't do it adding a drop shadow.
Added ellipse before the bar being created and that gives the same effect as above.
svg.selectAll(".ellipse")
.data(data)
.enter()
.append("ellipse")
.attr("cx", function(d) { return x(d.age) + 30; })
.attr("cy", function(d) { return y(0); })
.attr("rx", 35)
.attr("ry", 5)
.style("fill", function(d) { return d.color2; })
This is very simple. You need to create a ellipse before the bar is created.
When we position the ellipse it acts like a drop shadow.
Sorry that i don't have time to get the contrasting colors of the bar. But you can amend it of course.
If you'd like to do it with a drop shadow.
Here's a link that requires a javascript library for the drop shadow of the svg elements.
Hope this helps.

Show box on mousehover

I am beginning with d3.js and I would like to know the simplest way to show a box containing text (a tooltip) when my the mouse is over a node of my force-directed graph. Moreover, the text contained in this box must be custom for each node (something like function(d){return d.fullName;}))
Here is a sample code of what I have for now.
var node = vis.selectAll("g.node")
.data(json.nodes)
.enter().append("svg:g")
.attr("class", "node");
node.append("circle")
.attr("r", 12)
.style("fill", "orange");
Thanks in advance
By box, do you mean a tooltip? In Mike's examples, he uses this idiom:
node.append("title")
.text(function(d) { return d.fullName: });
(With other types of elements (divs only?) you can just use element.setAttribute("title", "title");.)

Categories