Javascript D3 position tooltip to chart - javascript

I try to build a tooltip like it is explained here:
D3 Tooltip Example
But I want to have a div as a tooltip.
Now I have the problem to position the div to the chat line.
My code:
var div = d3.select("#chart").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var path = svg.append("path") // Add the line path.
.data(data)
.attr("class", "line")
.attr("d", line(data));
var focus = svg.append("g")
.attr("class", "focus")
.style("display", "none");
focus.append("text")
.attr("x", 9)
.attr("dy", ".35em");
svg.append("rect")
.attr("class", "overlay")
.attr("width", width)
.attr("height", height)
.on("mouseover", function() {
focus.style("display", null);
})
.on("mouseout", function(d) {
div.transition()
.duration(50)
.style("opacity", 1e-6);
})
.on("mousemove", mousemove);
function mousemove() {
var x0 = x.invert(d3.mouse(this)[0]),
i = bisectDate(data, x0, 1),
d0 = data[i - 1],
d1 = data[i],
d = x0 - d0.date > d1.date - x0 ? d1 : d0;
//move focus around
focus.attr("transform", "translate(" + x(d.date) + "," + y(d.equity) + ")");
div.transition()
.duration(50)
.style("opacity", .9);
div.html("<strong><table><tr><th>Datum: </th><th>" + formatTime(d.date) + "</th></tr><tr><th>Equity:</th><th>" + Euro(d.equity) + "</th></tr></table></strong>")
// .style("left", (d3.event.pageX) + "px")
// .style("top", (d3.event.pageY - 1100) + "px");
;
}
The full example on Fiddle
Is it possible to position the div relatively to the svg line, where the mouse is?

Changing the div position using left and top is best for HTML tooltips: https://jsfiddle.net/da3nx51L/
div.transition()
.duration(50)
.style('left', d3.event.clientX + "px")
.style('top', d3.event.clientY + "px")
.style('display', 'inline-block')
.style("opacity", .9);

uncomment the last two lines, and remove the -1100 from the top
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY) + "px");

Related

D3js: How do I make my tooltip appear next to the selection?

I am trying to have a tooltip for each square on my heatmap visualization. However, I am not able to position it next to the cursor correctly. This is what happens:
My code is this:
const margin = {
top: 20,
right: 20,
bottom: 30,
left: 150,
};
const width = 960 - margin.left - margin.right;
const height = 2500 - margin.top - margin.bottom;
let chart = d3
.select("#chart2")
.append("div")
// Set id to chartArea
.attr("id", "chartArea")
.classed("chart", true)
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Make sure to create a separate SVG for the XAxis
let axis = d3
.select("#chart2")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", 40)
.append("g")
.attr("transform", "translate(" + margin.left + ", 0)");
// Load the data
d3.csv("https://raw.githubusercontent.com/thedivtagguy/files/main/land_use.csv").then(function(data) {
// console.log(data);
const years = Array.from(new Set(data.map((d) => d.year)));
const countries = Array.from(new Set(data.map((d) => d.entity)));
countries.reverse();
const x = d3.scaleBand().range([0, width]).domain(years).padding(0.01);
// create a tooltip
var tooltip = d3
// Select all boxes in the chart
.select("#chart2")
.append("div")
.classed("tooltip", true)
.style("opacity", 0)
.attr("class", "tooltip")
.style("background-color", "white")
.style("border", "solid")
.style("border-width", "2px")
.style("border-radius", "5px")
.style("padding", "5px");
const mouseover = function(event, d) {
tooltip.style("opacity", 1);
d3.select(this).style("stroke", "black").style("opacity", 1);
};
const mousemove = function(event, d) {
tooltip
.html("The exact value of<br>this cell is: " + d.value)
// Position the tooltip next to the cursor
.style("left", event.x + "px")
.style("top", event.y / 2 + "px");
};
const mouseleave = function(event, d) {
tooltip.style("opacity", 0);
d3.select(this).style("stroke", "none").style("opacity", 0.8);
};
const y = d3.scaleBand().range([height, 0]).domain(countries).padding(0.01);
// Only 10 years
axis
.call(d3.axisBottom(x).tickValues(years.filter((d, i) => !(i % 10))))
.selectAll("text")
.style("color", "black")
.style("position", "fixed")
.attr("transform", "translate(-10,10)rotate(-45)")
.style("text-anchor", "end");
chart
.append("g")
.call(d3.axisLeft(y))
.selectAll("text")
.style("color", "black")
.attr("transform", "translate(-10,0)")
.style("text-anchor", "end");
const colorScale = d3
.scaleSequential()
.domain([0, d3.max(data, (d) => d.change)])
.interpolator(d3.interpolateInferno);
// add the squares
chart
.selectAll()
.data(data, function(d) {
return d.year + ":" + d.entity;
})
.join("rect")
// Add id-s
.attr("id", function(d) {
return d.year + ":" + d.entity;
})
.attr("x", function(d) {
return x(d.year);
})
.attr("y", function(d) {
return y(d.entity);
})
.attr("width", x.bandwidth())
.attr("height", y.bandwidth())
.style("fill", function(d) {
return colorScale(d.change);
console.log(d.change);
})
.style("stroke-width", 4)
.style("stroke", "none")
.style("opacity", 0.8)
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseleave", mouseleave);
});
#chart2 .chart {
width: 960px;
max-height: 900px;
overflow-y: scroll;
overflow-x: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
<div id="chart2" class="mx-auto"></div>
I think I have some idea of why this is happening. Since I am appending the tooltip iv to chart2 div like this, all positioning is happening relative to that div, which means it'll inevitably be below the entire chart and not on top of it:
// create a tooltip
var tooltip = d3
// Select all boxes in the chart
.select("#chart2")
.append("div")
.classed("tooltip", true)
.style("opacity", 0)
.attr("class", "tooltip")
.style("background-color", "white")
.style("border", "solid")
.style("border-width", "2px")
.style("border-radius", "5px")
.style("padding", "5px");
const mousemove = function(event, d) {
tooltip
.html("The exact value of<br>this cell is: " + d.value)
// Position the tooltip next to the cursor
.style("left", event.x + "px")
.style("top", event.y / 2 + "px");
};
But how else would I do this? I have tried trying to select by the hovered-on rect element but that hasn't been working. I am trying to do something like this.
How can I fix this?
A live version can be found here
Just add in the mousemove function .style("position","absolute"); and change top style to .style("top", event.y + "px")
const margin = {
top: 20,
right: 20,
bottom: 30,
left: 150,
};
const width = 960 - margin.left - margin.right;
const height = 2500 - margin.top - margin.bottom;
let chart = d3
.select("#chart2")
.append("div")
// Set id to chartArea
.attr("id", "chartArea")
.classed("chart", true)
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Make sure to create a separate SVG for the XAxis
let axis = d3
.select("#chart2")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", 40)
.append("g")
.attr("transform", "translate(" + margin.left + ", 0)");
// Load the data
d3.csv("https://raw.githubusercontent.com/thedivtagguy/files/main/land_use.csv").then(function(data) {
// console.log(data);
const years = Array.from(new Set(data.map((d) => d.year)));
const countries = Array.from(new Set(data.map((d) => d.entity)));
countries.reverse();
const x = d3.scaleBand().range([0, width]).domain(years).padding(0.01);
// create a tooltip
var tooltip = d3
// Select all boxes in the chart
.select("#chart2")
.append("div")
.classed("tooltip", true)
.style("opacity", 0)
.attr("class", "tooltip")
.style("background-color", "white")
.style("border", "solid")
.style("border-width", "2px")
.style("border-radius", "5px")
.style("padding", "5px");
const mouseover = function(event, d) {
tooltip.style("opacity", 1);
d3.select(this).style("stroke", "black").style("opacity", 1);
};
const mousemove = function(event, d) {
tooltip
.html("The exact value of<br>this cell is: " + d.value)
// Position the tooltip next to the cursor
.style("left", event.x + "px")
.style("top", event.y + "px")
.style("position","absolute");
};
const mouseleave = function(event, d) {
tooltip.style("opacity", 0);
d3.select(this).style("stroke", "none").style("opacity", 0.8);
};
const y = d3.scaleBand().range([height, 0]).domain(countries).padding(0.01);
// Only 10 years
axis
.call(d3.axisBottom(x).tickValues(years.filter((d, i) => !(i % 10))))
.selectAll("text")
.style("color", "black")
.style("position", "fixed")
.attr("transform", "translate(-10,10)rotate(-45)")
.style("text-anchor", "end");
chart
.append("g")
.call(d3.axisLeft(y))
.selectAll("text")
.style("color", "black")
.attr("transform", "translate(-10,0)")
.style("text-anchor", "end");
const colorScale = d3
.scaleSequential()
.domain([0, d3.max(data, (d) => d.change)])
.interpolator(d3.interpolateInferno);
// add the squares
chart
.selectAll()
.data(data, function(d) {
return d.year + ":" + d.entity;
})
.join("rect")
// Add id-s
.attr("id", function(d) {
return d.year + ":" + d.entity;
})
.attr("x", function(d) {
return x(d.year);
})
.attr("y", function(d) {
return y(d.entity);
})
.attr("width", x.bandwidth())
.attr("height", y.bandwidth())
.style("fill", function(d) {
return colorScale(d.change);
console.log(d.change);
})
.style("stroke-width", 4)
.style("stroke", "none")
.style("opacity", 0.8)
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseleave", mouseleave);
});
#chart2 .chart {
width: 960px;
max-height: 900px;
overflow-y: scroll;
overflow-x: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
<div id="chart2" class="mx-auto"></div>

D3.js heatmap with color

Hi I am trying to add in a color scale for my heat map. I Specifically want to use d3.schemeRdYlBu this color scheme but I am having a hard time implementing it. At the moment it just does black. I also have a hover feature with this so I would like that to still work but i am more concerned with just getting the color to work. Obviously having the lower numbers be blue and the higher numbers be red to indicate temp
<!DOCTYPE html>
<meta charset="utf-8">
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>
<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>
<!-- Load color palettes -->
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src="https://d3js.org/d3.v4.js"></script>
<script>
// set the dimensions and margins of the graph
var margin = {top: 80, right: 25, bottom: 30, left: 40},
width = 1000 - margin.left - margin.right,
height = 1000 - margin.top - margin.bottom;
// append the svg object to the body of the page
var svg = d3.select("#my_dataviz")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
//Read the data
d3.csv("https://raw.githubusercontent.com/Nataliemcg18/Data/master/NASA_Surface_Temperature.csv", function(data) {
// Labels of row and columns -> unique identifier of the column called 'group' and 'variable'
var myGroups = d3.map(data, function(d){return d.group;}).keys()
var myVars = d3.map(data, function(d){return d.variable;}).keys()
// Build X scales and axis:
var x = d3.scaleBand()
.range([ 0, width ])
.domain(myGroups)
.padding(0.05);
svg.append("g")
.style("font-size", 15)
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).tickSize(0))
.select(".domain").remove()
// Build Y scales and axis:
var y = d3.scaleBand()
.range([ height, 0 ])
.domain(myVars)
.padding(0.05);
svg.append("g")
.style("font-size", 15)
.call(d3.axisLeft(y).tickSize(0))
.select(".domain").remove()
// Build color scale
var myColor = (d3.schemeRdYlBu[2])
// create a tooltip
var tooltip = d3.select("#my_dataviz")
.append("div")
.style("opacity", 0)
.attr("class", "tooltip")
.style("background-color", "white")
.style("border", "solid")
.style("border-width", "2px")
.style("border-radius", "5px")
.style("padding", "5px")
// Three function that change the tooltip when user hover / move / leave a cell
var mouseover = function(d) {
tooltip
.style("opacity", 1)
d3.select(this)
.style("stroke", "green")
.style("opacity", 1)
}
var mousemove = function(d) {
tooltip
.html("The exact value of this cell is: " + d.value, )
.style("left", (d3.mouse(this)[0]+70) + "px")
.style("top", (d3.mouse(this)[1]) + "px")
}
var mouseleave = function(d) {
tooltip
.style("opacity", 0)
d3.select(this)
.style("stroke", "none")
.style("opacity", 0.8)
}
// add the squares
svg.selectAll()
.data(data, function(d) {return d.group+':'+d.variable;})
.enter()
.append("rect")
.attr("x", function(d) { return x(d.group) })
.attr("y", function(d) { return y(d.variable) })
.attr("rx", 4)
.attr("ry", 4)
.attr("width", x.bandwidth() )
.attr("height", y.bandwidth() )
.style("fill", function(d) { return myColor(d.value)} )
.style("stroke-width", 4)
.style("stroke", "none")
.style("opacity", 0.8)
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseleave", mouseleave)
})
// Add title to graph
svg.append("text")
.attr("x", 0)
.attr("y", -50)
.attr("text-anchor", "left")
.style("font-size", "22px")
.text("A d3.js heatmap");
// Add subtitle to graph
svg.append("text")
.attr("x", 0)
.attr("y", -20)
.attr("text-anchor", "left")
.style("font-size", "14px")
.style("fill", "grey")
.style("max-width", 400)
.text("A short description of the take-away message of this chart.");
</script>
You can use arrow function instead of the regular function to use your own binding of this for accessing myColor variable.
<!DOCTYPE html>
<meta charset="utf-8" />
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>
<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>
<!-- Load color palettes -->
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src="https://d3js.org/d3.v4.js"></script>
<script>
// set the dimensions and margins of the graph
var margin = { top: 80, right: 25, bottom: 30, left: 40 },
width = 1000 - margin.left - margin.right,
height = 1000 - margin.top - margin.bottom;
// append the svg object to the body of the page
var svg = d3
.select("#my_dataviz")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
//Read the data
d3.csv(
"https://raw.githubusercontent.com/Nataliemcg18/Data/master/NASA_Surface_Temperature.csv",
function (data) {
// Labels of row and columns -> unique identifier of the column called 'group' and 'variable'
var myGroups = d3
.map(data, function (d) {
return d.group;
})
.keys();
var myVars = d3
.map(data, function (d) {
return d.variable;
})
.keys();
// Build X scales and axis:
var x = d3.scaleBand().range([0, width]).domain(myGroups).padding(0.05);
svg
.append("g")
.style("font-size", 15)
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).tickSize(0))
.select(".domain")
.remove();
// Build Y scales and axis:
var y = d3.scaleBand().range([height, 0]).domain(myVars).padding(0.05);
svg
.append("g")
.style("font-size", 15)
.call(d3.axisLeft(y).tickSize(0))
.select(".domain")
.remove();
// Build color scale
var myColor = d3.schemeRdYlBu[3][2];
// create a tooltip
var tooltip = d3
.select("#my_dataviz")
.append("div")
.style("opacity", 0)
.attr("class", "tooltip")
.style("background-color", "white")
.style("border", "solid")
.style("border-width", "2px")
.style("border-radius", "5px")
.style("padding", "5px");
// Three function that change the tooltip when user hover / move / leave a cell
var mouseover = function (d) {
tooltip.style("opacity", 1);
d3.select(this).style("stroke", "green").style("opacity", 1);
};
var mousemove = function (d) {
tooltip
.html("The exact value of this cell is: " + d.value)
.style("left", d3.mouse(this)[0] + 70 + "px")
.style("top", d3.mouse(this)[1] + "px");
};
var mouseleave = function (d) {
tooltip.style("opacity", 0);
d3.select(this).style("stroke", "none").style("opacity", 0.8);
};
// add the squares
svg
.selectAll()
.data(data, function (d) {
return d.group + ":" + d.variable;
})
.enter()
.append("rect")
.attr("x", function (d) {
return x(d.group);
})
.attr("y", function (d) {
return y(d.variable);
})
.attr("rx", 4)
.attr("ry", 4)
.attr("width", x.bandwidth())
.attr("height", y.bandwidth())
.style("fill", (d) => {
return myColor;
})
.style("stroke-width", 4)
.style("stroke", "none")
.style("opacity", 0.8)
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseleave", mouseleave);
}
);
// Add title to graph
svg
.append("text")
.attr("x", 0)
.attr("y", -50)
.attr("text-anchor", "left")
.style("font-size", "22px")
.text("A d3.js heatmap");
// Add subtitle to graph
svg
.append("text")
.attr("x", 0)
.attr("y", -20)
.attr("text-anchor", "left")
.style("font-size", "14px")
.style("fill", "grey")
.style("max-width", 400)
.text("A short description of the take-away message of this chart.");
</script>
This is another way to get the desired results
var myColor = d3.scaleSequential()
.interpolator( d3.interpolateRdYlBu)
.domain([1.37, -.81])

Tooltip in d3 js (Bullet charts)

d3.json("data.json", function(error, data) {
if (error) throw error;
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var svg = d3.select("body").selectAll("svg")
.data(data)
.enter().append("svg")
.attr("class", "bullet")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom).on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div.html("Tooltip" + "<br/>" + d.measures);
})
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(chart);
Getting below result:
Result what I am expecting:
Is there any error in my code or do I need to do things differently.
You will have to update the position of the tool-tip div on mouse over.
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9)
.style("left", (d3.event.pageX) + "px") //Set X
.style("top", (d3.event.pageY) + "px"); //Set Y
div.html("Tooltip" + "<br/>" + d.measures);
});

Tooltip is not displaying in the exact position in D3.js code

Tooltip is not diaplying in the appropriate area.I'm using D3.js
var divLink = d3.select(el[0]).append("div")
.attr("class", "tooltip")
.style("opacity", 0);
.attr("id",function(d){
return d.linkID;})
.style("stroke-width", 0.7)
.style("fill", "none")
.on("mouseover", function(d) {
var dx = (d.x+30), dy = (d.y+155)-$('#svgWrapper').scrollTop();
divLink.transition()
.duration(200)
.style("opacity", .9);
// When links are hovered, tool tip is created
if(d.source.type.toLowerCase()=="rack" || d.target.type.toLowerCase()=="rack")
{
divLink.html("<b>Link Details: </b><br/><br/>"+"<b>Link Id: </b>"+d.linkID +"<br/>"
+"<b>Device1: </b>"+d.source.name+"<br/>"+ "<b>Device2: </b>"+d.target.name+"<br/>")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
}else{
divLink.html("<b>Link Details: </b><br/><br/>"+"<b>Link Id: </b>"+d.linkID +"<br/>"+"<b>Link Speed: </b>"+d.linkSpeed+"<br/>"
+"<b>Device1: </b>"+d.source.name+"<br/>"+ "<b>Ports at Device1: </b>"+d.sport+"<br/>"+"<b>Device2: </b>"+d.target.name+"<br/>"
+ "<b>Ports at Device2: </b>"+d.tport+"<br/>")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
}
})
.on("mouseout", function(d) {
divLink.transition()
.duration(500)
.style("opacity", 0);
});
Something is in the style, because of that i'm getting this error.
Actually i'm having one more tooltip for another tool there the tooltip is placing in the exact area.
var div = d3.select(el[0]).append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// Device Node Creation
var node = svg.selectAll(".node")
.data(networkObject.nodes)
.enter()
.append("g")
.attr("id",function(d){return d.name;})
.attr("class","node")
.attr("transform", function(d) {
return "translate(" + d.x + "," + (d.y) + ")"; })
.on("mouseover", function(d) {
var dx = (d.x+30), dy = (d.y+155)-$('#svgWrapper').scrollTop();
div.transition()
.duration(200)
.style("opacity", .9);
// Tool tip when hovered on particular device node
if(d.type.toLowerCase()=="rack"){
div.html("<b>Rack Details: </b><br/><br/>"+"<b>Rack Id: </b>"+d.name +"<br/>"+"<b>TOR Switches: </b>"+d.tor+"<br/>"+"<b>Management Switches: </b>"+d.mgmt+"<br/>"+"<b>Hosts: </b>"+d.host+"<br/>"+"<b>Status: </b>"+d.errorst+"<br/>")
.style("left",dx + "px")
.style("top", dy + "px");
}else if(d.type.toLowerCase()=="switch" && d.role.toLowerCase()=="spine"){
div.html("<b>Switch Details: </b><br/><br/>"+"<b>Switch Id: </b>"+d.name +"<br/>"+ "<b>Role: </b>"+d.role+"<br/>"+"<b>IP Address: </b>"+d.ip+"<br/>"+"<b>Status: </b>"+d.errorst+"<br/>")
.style("left", dx + "px")
.style("top", dy + "px");
}else if(d.type.toLowerCase()=="switch"){
div.html("<b>Switch Details: </b><br/><br/>"+"<b>Switch Id: </b>"+d.name +"<br/>"+ "<b>Role: </b>"+d.role+"<br/>"+"<b>Rack: </b>"+d.rack+"<br/>"+"<b>IP Address: </b>"+d.ip+"<br/>"+"<b>Status: </b>"+d.errorst+"<br/>")
.style("left", dx + "px")
.style("top", dy + "px");
}else if(d.type.toLowerCase()=="host"){
div.html("<b>Host Details: </b><br/><br/>"+"<b>Host Id: </b>"+d.name +"<br/>"+"<b>Rack: </b>"+d.rack+"<br/>"+"<b>IP Address: </b>"+d.ip+"<br/>"+"<b>Status: </b>"+d.errorst+"<br/>")
.style("left", dx + "px")
.style("top", dy + "px");
}else if(d.type.toLowerCase()=="corporate"){
div.html("<b>Corporate Network</b><br/><br/>")
.style("left", dx + "px")
.style("top", dy + "px");
}
})
.on("mouseout", function(d) {
div.transition()
.duration(100)
.style("opacity", 0);
});
So actually i found the answer for this, i added the coordinates for the x and y. then the tooltip was working, I don't think, this should be a permanent solution for this.If anyone has any other answers please post that.Thanks
.style("left", (d3.event.pageX-460) + "px")
.style("top", (d3.event.pageY - 50) + "px");

tooltip to show single element of group

I have a bar chart and I have text values at the end of each bar. What I would like to do is set text to invisible, and on mouseover I'd like it to show the number associated with the bar, at the magnitude of that bar. I'm having trouble figuring out how to do this in an efficient manner.
var tooltip = d3.select("body").append("div")
.style("position", "absolute")
.attr("class", "tooltip")
.style("opacity", 0);
var rect = svg.selectAll("rect")
.attr("class", "rect")
.data(dataset)
.enter()
.append("rect")
.attr("y", function(d,i){
return yScale(i);
})
.attr("x", 0)
.attr("width", function(d,i){
return xScale(d);
})
.attr("height", h/dataset.length)
.style("fill", function(d,i){
return colors(d);
})
.on("mouseover", function(d){
d3.select(this).style("opacity", 0.5)
tooltip.transition()
.duration(200)
.style("opacity", 1);
tooltip.html(d)
.style("left", d3.event.pageX + "px")
.style("top", d3.event.pageY + "px")
})
.on("mouseout", function(d){
d3.select(this).style("opacity", 1)
tooltip.transition()
.duration(500)
.style("opacity", 0)
});
Instead of mouseover and mouseout, I recommend doing it with $(this).hover and $(this).mousemove. Try something like this:
$(this).hover(
function() {
tooltip.transition()
.duration(200)
.style("opacity", 1)
// In order to trigger the magnitude or 'width' of the rect:
var rectWidth = $(this).attr("width");
}, function () {
tooltip.transition()
.duration(500)
.style("opacity", 1e-6)
}
);
/*$(this).mousemove(function(event) {
tooltip
.style("left", event.clientX + "px")
.style("top", event.clientY + "px")
});*/

Categories

Resources