I have a search box that highlights all circles when they have the same name and fades out the circles that don't match. All working as expected.
<input class="highlight" name="searchbox" id="searchbox" type="text" list="initname-datalist" placeholder="Search Project/Initiative.." onInput="initiativeSearch(this.value)">
<datalist id="initname-datalist"></datalist>
function initiativeSearch(initSelection) {
circles.transition()
.delay(0)
.duration(500)
.style("opacity", function(d) {
return d.data.initiative_name !== initSelection ? 0.5 : 1;
})
.style("stroke", function(d) {
return d.data.initiative_name === initSelection ? "black" : "grey";
});
}
initiative_name is a column name in my CSV. I want to do a similar thing but using mouseover, so when a user mouseover a circle all other circles with the same name will be highlighted.
I have a current mouseover in place that adds a yellow stroke to the circle being moused over and also a tool tip. I don't necessarily need to retain the yellow stroke.
.on("mouseover", function(d) {
d3.select(this) // highlight the circle that the tooltip relates to
.transition()
.delay(0)
.duration(100)
.style("stroke", "yellow")
.style("stroke-width", 5);
tooltip.transition()
.duration(200)
.style("opacity", .95);
tooltip.html("<strong>" + d.data.initiative_name + "</strong>)
.style("left", d3.select(this).attr("cx") + "px")
.style("top", d3.select(this).attr("cy") + "px");
})
.on("mouseout", function(d) {
d3.select(this)
.transition()
.delay(0)
.duration(500)
.style("stroke", "grey")
.style("stroke-width", 1);
tooltip.transition()
.duration(500)
.style("opacity", 0);
});
Any ideas how I can highlight all circles with the same initiative_name using mouseover?
It's hard to write a solution without actually testing it with the data, but this is a possible one:
.on("mouseover", function(d) {
circles.style("opacity", function(e) {
return d.data.initiative_name !== e.data.initiative_name ? 0.5 : 1;
});
//etc...
Call initiativeSearch() on mouseover like this
.on("mouseover", function(d) {
initiativeSearch(d.data.initiative_name);
}
Related
'''
#Parent svg
svg.append('g')
.selectAll("dot")
.data(storage)
.join("circle")
.attr("cx", function (d) { return x(d.x); })
.attr("cy", function (d) { return y(d.y); })
.attr("r", .5)
.style("fill", "green")
.on("mouseover", function (e, d) {
d3.select(this).transition()
.duration(200)
div.style("left", (e.pageX) + "px")
.style("top", (e.pageY - 28) + "px");
console.log(e, d);
div.transition()
.duration(500)
.style("opacity", 0);
div.transition()
.duration(200)
.style("opacity", .9);
div.html(
'X, Y: ' + d.x + ", "+ d.y +
"<br>Pin: " + d.pinName +
"<br>Net: " + d.netName);
s_data = storage.filter(a => a.netName ===d.netName);
#Child svg
svg.append('g')
.selectAll("dot")
.data(s_data)
.join("circle")
.attr("cx", function (d) { return x(d.x); })
.attr("cy", function (d) { return y(d.y); })
.attr("r", .5)
.style("fill", "red")
})
.on('mouseout', function(d,i){
d3.select(this).transition()
.duration('200')
.style('fill', 'green');
})
'''
Initially all dots are green when I mouseover any one of the dots, the set of dots with common netName will highlight, after this I can't go back to normal, i,e I want all dots to be green again so that I can highlight other dots and check for there grouping. The data is basically a JSON object
Take a look at this example: https://codepen.io/ccasenove/pen/RwyzZrV
I have a unique id key on each dot and a netId attribute shared by some dots. If you specify a key function when you bind the data to a d3 selection, then you can obtain a sub selection of dots with the same netId like this:
const _data = data.filter(da => da.netId == d.netId);
svg.selectAll("circle")
.data(_data, d => d.id)
.style("fill", "red")
the d3 data function will return the update selection, i.e. dots that already exist with the ids in the filtered data. So you can change the color of this update selection in mouseover and mouseout functions.
I'm trying to add a tooltip with data on a choropleth map. It already appears on mouse over but I'm stuck trying to show the data that's in the csv file I used to create the map. I'd like to show the "name" + "pop" + "%".
Here's how I loaded the data:
d3.queue()
.defer(d3.json, "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson")
.defer(d3.csv, "https://raw.githubusercontent.com/lcercos/geojson/main/eurostat_data-map.csv", function(d) { data.set(d.code, +d.pop); })
.await(ready);
Here's the on mouse over function:
function ready(error, topo) {
var div = d3.select("body").append("div") // calling tooltip
.attr("class", "tooltip")
.style("opacity", 0);
let mouseOver = function(d) {
d3.selectAll(".Country")
.transition()
.duration(100)
.style("opacity", .5)
d3.select(this)
.transition()
.duration(100)
.style("opacity", 1)
.style("stroke", "black");
div.transition()
.duration(50)
.style("opacity", 1);
div.html(d.name + d.value + "%") // html data <- Is here the problem?
.style("left", (d3.event.pageX + 15) + "px")
.style("top", (d3.event.pageY - 10) + "px");
}
let mouseLeave = function(d) {
d3.selectAll(".Country")
.transition()
.duration(0)
.style("opacity",)
d3.select(this)
.transition()
.duration(0)
.style("stroke", "transparent");
div.transition()
.duration("50")
.style("opacity", 0);
}
I would like to ask if anyone know how to get the code to do similar chart like this https://www.theguardian.com/world/interactive/2013/feb/12/state-of-the-union-reading-level
It is written in D3 but I couldn't find similar codes online.
Thanks
I think this is just a fairly involved tooltip on a scatter plot. Here's a simpler example:
// Define the div for the tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// Add the scatterplot
svg.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("r", 5)
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.close); })
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div .html(formatTime(d.date) + "<br/>" + d.close)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
You might also find this other example useful.
I have some circles that I want to change fill when I hover over them. I give them "pins" class and here's the CSS for them:
.pin {
fill: #9ecae1;
stroke:#3182bd;
}
.pin:hover{
fill:steelblue;
}
Each pin has a value and I want to include some transition so that if there is a change in that value, the circles will momentarily flash some other color, green for instance. They work fine without the update. After the update, the hover no longer works.
Here is my code for the transition:
d[2] is just some key name.
svg.selectAll("circle").data(points, function(d) {return d[2];})
.transition()
.duration(500)
.style("fill", "green")
.attr("r", function(d) {return 5 + 10*Math.ceil(radius(d[3]));})
.each("end", function(d){
d3.select(this).transition()
.style("fill", "#9ecae1");
});
I was able to pinpoint that setting style("fill", xxx) disables the hover but why? And is there a way to get the momentary transition while still maintaining the hover?
I understood the problem, that is in the below code
svg.selectAll("circle").data(points, function(d) {return d[2];})
.transition()
.duration(500)
.style("fill", "green")
.attr("r", function(d) {return 5 + 10*Math.ceil(radius(d[3]));})
.each("end", function(d){
d3.select(this).transition()
.style("fill", "#9ecae1");
});
we are applying the color by using inline style, this inline is more priority than external css, So don't apply the color by using inline style instead use the attribute(fill) to fill the color, the line of code we have to change is remove .style("fill", "green") and replace it with attr("fill", "green")
and .style("fill", "#9ecae1") with .attr("fill", "#9ecae1")
Below is the modified code
svg.selectAll("circle").data(points, function(d) {return d[2];})
.transition()
.duration(500)
.attr("fill", "green")
.attr("r", function(d) {return 5 + 10*Math.ceil(radius(d[3]));})
.each("end", function(d){
d3.select(this).transition()
.attr("fill", "#9ecae1");
});
:)
I made a line graph with d3.js (see the attached image1).
I managed to insert tooltips on graph dots when mouseover.
I'd like to change color and size of dots too. I tried in many ways but it seems really difficult. Any help?
Here is the piece of code:
svg.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("r", 5.5)
.style("fill", "#fff8ee")
.style("opacity", .8) // set the element opacity
.style("stroke", "#f93") // set the line colour
.style("stroke-width", 3.5)
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.close); })
.on("mouseover", function(d) {
div.transition()
.duration(70)
.style("opacity", .7)
;
div .html(formatTime(d.date) + "<br/>" + d.close)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(200)
.style("opacity", 0);
});
Just set color and size in the handlers:
.on("mouseover", function(d) {
d3.select(this).attr("r", 10).style("fill", "red");
})
.on("mouseout", function(d) {
d3.select(this).attr("r", 5.5).style("fill", "#fff8ee");
});
I don't know why, but while d3.select(this) used to work, it doesn't anymore. I now use d3.select(event.currentTarget).
So, if we consider svg as the graph and all its circles being red by default, we can change the color of the circles to green on mouseover and return the color to red on mouseout like this:
svg.on("mouseover", function(d){
d3.select(event.currentTarget)
.style("fill", "green");
})
.on("mouseout", function(d){
d3.select(event.currentTarget)
.style("fill", "red");
});