D3: Mouseover to display data in top right corner - d3.js

I'm working in D3 with a tooltip in a mouseover event. What I have is the data displayed slightly to the right and above the dot. However, it's a line graph and this is sometimes unreadable. What I would like is the data displayed in some fixed position (I've decided the upper right hand corner is free of clutter). Can anyone give me some advice? Code below
.on("mouseover", function(d) {
d3.select(this).attr("r", 5.5).style("fill", "red");
tooltip.transition()
.duration(200)
.style("opacity", .9);
tooltip.html("(" + xTemp(d)
+ ", " + yTemp(d)+ ")")
.style("left", (d3.event.pageX + 5) + "px")
.style("top", (d3.event.pageY - 28) + "px");

I assume your tooltip is a <div> with position: absolute.
In that case, you can wrap your SVG in a container div (since SVGs don't support offsetTop and offsetLeft) and set the position of your tooltip using offsetTop and offsetLeft.
Here is a simple demo. I put two paragraphs ("Foo" and "Bar"), so you can see that the position of the <div> is correct, even if the SVG is not the first element on the page:
var svg = d3.select("svg");
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
svg.selectAll(null)
.data(d3.range(50, 300, 50))
.enter()
.append("circle")
.attr("cx", Number)
.attr("cy", 100)
.attr("r", 20)
.style("fill", "teal")
.on("mouseover", function(d) {
d3.select(this).style("fill", "red");
tooltip.html(d)
.style("top", svg.node().parentNode.offsetTop + 10 + "px")
.style("left", svg.node().parentNode.offsetLeft + 270 + "px")
.style("opacity", .9);
})
.on("mouseout", function() {
d3.select(this).style("fill", "teal")
tooltip.style("opacity", 0)
})
svg {
border: 1px solid gray;
}
.tooltip {
position: absolute;
broder: 1px solid black;
background-color: tan;
padding: 2px;
border-radius: 2px;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<p>Foo</p>
<p>Bar</p>
<div>
<svg id="svg"></svg>
</div>

Related

Starting point of x-axis in d3.js bar chart is not aligned with the y-intercept

Created a d3.js bar chart based on some examples I've seen online and I've come across a problem. I'd like to align the starting datapoint based on the x-axis with the y-intercept. However, I can't seem to do so correctly even after various changes (changing scale.ordinal to scale.linear, adding transform to y-axis, etc.).
Likewise, I'd like the ending point in the x-axis to be aligned with the last data point. There's like an invisible padding before and after the range of starting and beginning of the datapoints in the chart.
I've consulted this question here as it seems similar to my problem but came up short with my expected results: D3Js Bar Chart Bars Starting Way After beginning of X-Axis
Here's the current code that I have:
var dataUrl = 'https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/GDP-data.json';
// set the dimensions of the canvas
var margin = {
top: 20,
right: 20,
bottom: 70,
left: 40
},
width = 1500 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
// Define the div for the tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// set the ranges
var x = d3.scale.ordinal().rangeRoundBands([0, width], 0.01, 1);
var y = d3.scale.linear().range([height, 0]);
// define the axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
// Added for the vertical lines (need to remove later)
.innerTickSize(-height)
.outerTickSize(0)
.tickPadding(10);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
var svg = d3.select(".chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// load the data
d3.json(dataUrl, function(error, data) {
data.data.forEach(function(d) {
d.GDP = d[0];
d.Year = +d[1];
});
// scale the range of the data
x.domain(data.data.map(function(d) {
return d.GDP;
}));
y.domain([0, d3.max(data.data, function(d) {
return d.Year;
})]);
// add axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)");
svg.append("g")
.attr("class", "y axis")
// .attr("transform", "translate(" + margin.left + ", 0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 5)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Gross Domestic Product, USA");
// Add bar chart with tooltip
svg.selectAll("bar")
.data(data.data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) {
return x(d.GDP);
})
.attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.Year);
})
.attr("height", function(d) {
return height - y(d.Year);
})
.on("mouseover", function(d) {
var monthNameFormat = d3.time.format("%b-%Y")
var gdp_date = monthNameFormat(new Date(d[0]))
var formatDecimalComma = d3.format(",.2f")
var curr = formatDecimalComma(d[1])
div.transition()
.duration(200)
.style("opacity", .9);
div.html(gdp_date + "<br/> $" + curr + " Billion")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
});
.chart rect {
fill: steelblue;
}
.chart text {
fill: black;
font: 10px sans-serif;
text-anchor: middle;
}
bar {
fill: steelblue;
}
.bar:hover {
fill: red;
}
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
div.tooltip {
position: absolute;
text-align: center;
width: 130px;
height: 30px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<!-- Source: https://bost.ocks.org/mike/bar/3/ -->
<div id="chart" align="center">
<svg class="chart"></svg>
</div>
Change rangeRoundBands to rangeBands and remove all the paddings:
var x = d3.scale.ordinal().rangeBands([0, width]);
Here is your code with that change:
var dataUrl = 'https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/GDP-data.json';
// set the dimensions of the canvas
var margin = {
top: 20,
right: 20,
bottom: 70,
left: 40
},
width = 1500 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
// Define the div for the tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// set the ranges
var x = d3.scale.ordinal().rangeBands([0, width]);
var y = d3.scale.linear().range([height, 0]);
// define the axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
// Added for the vertical lines (need to remove later)
.innerTickSize(-height)
.outerTickSize(0)
.tickPadding(10);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
var svg = d3.select(".chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// load the data
d3.json(dataUrl, function(error, data) {
data.data.forEach(function(d) {
d.GDP = d[0];
d.Year = +d[1];
});
// scale the range of the data
x.domain(data.data.map(function(d) {
return d.GDP;
}));
y.domain([0, d3.max(data.data, function(d) {
return d.Year;
})]);
// add axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)");
svg.append("g")
.attr("class", "y axis")
// .attr("transform", "translate(" + margin.left + ", 0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 5)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Gross Domestic Product, USA");
// Add bar chart with tooltip
svg.selectAll("bar")
.data(data.data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) {
return x(d.GDP);
})
.attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.Year);
})
.attr("height", function(d) {
return height - y(d.Year);
})
.on("mouseover", function(d) {
var monthNameFormat = d3.time.format("%b-%Y")
var gdp_date = monthNameFormat(new Date(d[0]))
var formatDecimalComma = d3.format(",.2f")
var curr = formatDecimalComma(d[1])
div.transition()
.duration(200)
.style("opacity", .9);
div.html(gdp_date + "<br/> $" + curr + " Billion")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
});
.chart rect {
fill: steelblue;
}
.chart text {
fill: black;
font: 10px sans-serif;
text-anchor: middle;
}
bar {
fill: steelblue;
}
.bar:hover {
fill: red;
}
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
div.tooltip {
position: absolute;
text-align: center;
width: 130px;
height: 30px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<!-- Source: https://bost.ocks.org/mike/bar/3/ -->
<div id="chart" align="center">
<svg class="chart"></svg>
</div>

Adding tooltip to donut slices

I'm trying to add a tooltip to my donut's slices on moues over as follow:
var tooltip = select("g.arc--first")
//.append("div") // if I add this div here it stops working
.append("text")
firstSlice.append('path')
.attr('d', coolArc(firstRadius, thickness))
.attr('class', d => `fill_${weightScale(d.data.weight)}`)
.on('mouseover', (d) => {
tooltip.style("visibility", "visible")
.text(this.nodeByName.get(d.data.name)["Short Description"])
.style("fill", "red")
.style("position", "absolute")
.style("text-align", "center")
.style("width", "60px")
.style("height", "28px")
.style("padding", "2px")
.style("background", "lightsteelblue")
.style("border", "10px")
})
My goal is to have a tooltip similar to http://bl.ocks.org/d3noob/a22c42db65eb00d4e369 , but right now it only shows a red text at the middle of the page. I think I need to have a new div but when I try to add append("div") it stops working and doesn't show the text anymore. How should I fix it?
The tooltip from the example that you mentioned works pretty simply. It is appended as a child element for body (you try to append it as a child for g element, but you cannot append html elements into svg). So you should change you code:
var tooltip = select('body')
.append('div')
.attr('class', 'tooltip');
I also recommend you style this tooltip in your css (add appropriate class name and rules in your css file) you can avoid chaining many .style methods in this case. You should set position: absolute; rule - you can update top and left styles and position the tooltip where you need. Also set visibility: hidden rule - your tooltip should be hidden by default.
In mouseover event handler you need to change:
visibility style to show the tooltip
left and top styles to position the tooltip
text to update text on the tooltip
.on('mouseover', (d) => {
tooltip
.style('visibility', 'visible')
.style('left', d3.event.pageX + 'px')
.style('top', d3.event.pageY + 'px')
.text(d);
})
In mouseout event handler you should just hide the tooltip:
.on('mouseout', (d) => {
tooltip
.style('visibility', 'hidden')
});
See simplified demo in the hidden snippet below:
var tooltip = d3.select("body")
.append("div")
.attr('class', 'tooltip');
d3.selectAll('circle')
.data(['one', 'two', 'three'])
.on('mouseover', (d) => {
tooltip
.style('visibility', 'visible')
.style('left', d3.event.pageX + 'px')
.style('top', d3.event.pageY + 'px')
.text(d);
})
.on('mouseout', (d) => {
tooltip
.style('visibility', 'hidden')
})
.tooltip {
background-color: lightblue;
font-weight: bold;
padding: 5px;
border-radius: 9px;
position: absolute;
display: inline-block;
margin-top: -50px;
visibility: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.js"></script>
<svg width="720" height="120">
<circle cx="20" cy="60" r="10"></circle>
<circle cx="180" cy="60" r="10"></circle>
<circle cx="340" cy="60" r="10"></circle>
</svg>

Trying to add an id to a circle

I am doing research for a professor at my school and I am coding in d3. I am creating a graph that has tool tips and you can toggle the graph by clicking on the legend. However, when I toggle the lines disappears but I can't get the tool tips associated to that line. I know I need to somehow add an id to these circles but I have no idea how. I have included my code below to show what I have so far. Any help would be appreciated!
<!DOCTYPE html>
<meta charset="utf-8">
<style> /* set the CSS */
body { font: 12px Arial;}
path {
stroke: white;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
div.tooltip {
position: absolute;
text-align: center;
width: 170px;
height: 500px;
padding: 1px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 5px;
pointer-events: none;
}
.legend {
font-size: 16px;
font-weight: bold;
text-anchor: middle;
}
</style>
<body>
<!-- load the d3.js library -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
// Set the dimensions of the canvas / graph
var margin = {top: 20, right: 150, bottom: 60, left: 80},
width = 1160 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// Parse the date / time
// Set the ranges
var x = d3.scaleTime().range([0, width-100]);
var formatxAxis=d3.format('.0f');
var y = d3.scaleLinear().range([height, 0]);
// Define the axe
var xAxis = d3.axisBottom().scale(x)
.tickFormat(formatxAxis).ticks(20);
var yAxis = d3.axisLeft().scale(y)
.ticks(5);
// Define the line
var valueline = d3.line()
.curve(d3.curveMonotoneX)
.x(function(d) { return x(d.year); })
.y(function(d) { return y(d.count); });
// Define the div for the tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// Adds the svg canvas
var svg = d3.select("body")
.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 + ")");
// Get the data
d3.json("satisfaction.json", function(error, data) {
data.forEach(function(d) {
d.year = +d.year;
d.count = +d.count;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.year; }));
y.domain([0, d3.max(data, function(d) { return d.count; })]);
//nest the entries by symbol
var dataNest = d3.nest()
.key(function(d) {
return d.word;
})
.entries(data);
//define colors for the lines
var color = d3.scaleOrdinal(d3.schemeCategory10);
// spacing for the legend
legendSpace = width/dataNest.length;
var circleid = svg.selectAll("circle")
.data(dataNest)
.enter()
.append("g")
.attr("id", function(d){
return "circle" + d.key.replace(/\s+/g, '');
});
// Loop through each symbol / key
dataNest.forEach(function(d,i) {
svg.append("path")
.attr("class", "line")
.style("stroke", function() { // Add the colours dynamically
return d.color = color(d.key); })
.attr("id", 'tag'+d.key.replace(/\s+/g, '')) // assign ID
.attr("d", valueline(d.values));
// Add the Legend
svg.append("text")
.attr("x", width - margin.left + 50)
.attr("y", legendSpace/4 + i*(legendSpace/6))
.attr("class", "legend") // style the legend
.style("fill", function() { // Add the colours dynamically
return d.color = color(d.key); })
.on("click", function(){
// Determine if current line is visible
var active = d.active ? false : true,
newOpacity = active ? 0 : 1;
// Hide or show the elements based on the ID
d3.select("#tag"+d.key.replace(/\s+/g, ''))
.transition().duration(100)
.style("opacity", newOpacity);
// Update whether or not the elements are active
d.active = active;
// Hide or show the elements based on the ID
d3.select("circle" + d.key.replace(/\s+/g, ''))
.transition().duration(100)
.style("opacity", newOpacity);
})
.text(d.key);
});
// Add the scatterplot
svg.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("r", 5)
.attr("cx", function(d) { return x(d.year); })
.attr("cy", function(d) { return y(d.count); })
.on("click", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div .html(d.word + "<br/>" + d.count + "<br/>" + d.songs)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 25) + "px");
})
.on("dblclick", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
})
;
// Add the X Axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
});
</script>
</body>
Right now, you are trying to set your id before you have added the circles to the graph. Instead, you can set the id when you're appending the circles to your graph.
// Add the scatterplot
svg.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("id", function(d){ return "circle" + d.key.replace(/\s+/g, ''); })
// ^---- add the id here when you're appending the circles
.attr("r", 5)
.attr("cx", function(d) { return x(d.year); })
.attr("cy", function(d) { return y(d.count); })
.on("click", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div .html(d.word + "<br/>" + d.count + "<br/>" + d.songs)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 25) + "px");
})
.on("dblclick", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
})
;

Tooltip overwritten for moving images in D3

Here i'm working on moving images dynamically with random x and y, inside a zooming & dragging SVG. And also added tooltip for these images inside the loop itself. When the tooltip appears its content is overwritten with last element's tooltip. Please check out the FIDDLE. In the following code, inside the for loop, I try to display the tooltip as "user tooltip:"+i, but the last tooltip content is displayed for all the images.
for(var i in icons){
var rectx = Math.floor(Math.random()*(max-min+1)+min);
var recty = Math.floor(Math.random()*(max-min+1)+min);
//console.log("i : "+i);
if(icons[i]=="user"){
var tip="user tooltip: "+i;
console.log(tip);
svg.append("image")
.attr("id","user"+i)
.attr('x',rectx)
.attr('y',recty)
.attr('width', 30)
.attr('height', 24)
.attr("xlink:href", "http://www.worryfreelabs.com/wp-content/uploads/2016/06/WFl_logo-2015-icon-only-white-background.png")
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div .html("user tooltip: "+i)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
}
}
The problem is with the scope of the variable. You can resolve this issue by implementing the functionality in a d3 way. Using enter method.
var imgHeight = 1025,
imgWidth = 1538, // Image dimensions (don't change these)
width = 500,
height = 500, // Dimensions of cropped region
translate0 = [-290, -180],
scale0 = 1; // Initial offset & scale
svg = d3.select("body").append("svg")
.attr("width", width + "px")
.attr("height", height + "px");
svg.append("rect")
.attr("class", "overlay")
.attr("width", width + "px")
.attr("height", height + "px");
svg = svg.append("g")
.attr("transform", "translate(" + translate0 + ")scale(" + scale0 + ")")
.call(d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom))
.append("g");
svg.append("image")
.attr("width", imgWidth + "px")
.attr("height", imgHeight + "px")
.attr("xlink:href", "http://www.myfreetextures.com/wp-content/uploads/2015/01/deep-green-grass-texture.jpg");
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
function zoom() {
svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
var max = 400,
min = 200;
var icons = ["user", "user", "table"];
svg.selectAll("image.icon")
.data(icons.filter(function(d) {
return d == "user";
}))
.enter()
.append("image")
.classed("icon", true)
.attr("id", function(d, i) {
return "user" + i;
})
.attr('x', function() {
return Math.floor(Math.random() * (max - min + 1) + min);
})
.attr('y', function() {
return Math.floor(Math.random() * (max - min + 1) + min);
})
.attr('width', 30)
.attr('height', 24)
.attr("xlink:href", "http://www.worryfreelabs.com/wp-content/uploads/2016/06/WFl_logo-2015-icon-only-white-background.png")
.on("mouseover", function(d, i) {
div.transition()
.duration(200)
.style("opacity", .9);
div.html("user tooltip: " + i)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
setInterval(function() {
for (var i in icons) {
if (icons[i] == "user") {
d3.select("#user" + i).transition()
.delay(1000)
.attr('x', function(d) {
return Math.random() * 720 - 29;
})
.attr('y', function(d) {
return Math.random() * 200 - 30;
})
.duration(6000)
}
}
}, 500);
.overlay {
fill: none;
pointer-events: all;
}
div.tooltip {
position: absolute;
text-align: center;
width: 60px;
height: 28px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

D3: display graph in tooltip

I know it is possible to display an image in a D3 tooltip. What I am trying to do is to display a bar graph in a tooltip (i.e when the mouse hovers over the object a bar graph appears). I have adapted code from http://bl.ocks.org/jarobertson/1483052#gistfile1.html and combined it with the bar graph code by Robert Lewand. And well, it doesn't work. I dont even get any errors in the console that could perhaps put me on the right path. Is it possible to do? Here is my code:
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?1.27.1"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<style type="text/css">
div.tooltip {
position: absolute;
text-align: center;
width: 500px;
height: 550px;
padding: 8px;
font: 10px sans-serif;
background: #ddd;
border: solid 1px #aaa;
border-radius: 8px;
pointer-events: none;
}
.chart rect {
fill: steelblue;
}
.chart text {
fill: white;
font: 10px sans-serif;
text-anchor: middle;
}
</style>
</head>
<body>
<script type="text/javascript">
var w = 960,
h = 500;
var svg = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h);
svg.append("svg:g")
.attr("transform", "translate(480,50)rotate(60)scale(2)")
.append("svg:rect")
.attr("width", 140)
.attr("height", 140)
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseout", mouseout);
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 1e-6);
function mouseover() {
div.transition()
.duration(500)
.style("opacity", 1);
}
// where the tooltip previosly contained an image
function mousemove() {
div
.html("<h1>Bar Graph</h1><br> <svg class='chart'></svg>")
.style("left", (d3.event.pageX - 34) + "px")
.style("top", (d3.event.pageY - 12) + "px");
}
function mouseout() {
div.transition()
.duration(500)
.style("opacity", 1e-6);
}
// make bar graph
var width = 300,
height = 300;
var y = d3.scale.linear()
.range([height, 0]);
var chart = d3.select(".chart")
.attr("width", width)
.attr("height", height);
d3.tsv("data.tsv", type, function(error, data) {
y.domain([0, d3.max(data, function(d) { return d.value; })]);
var barWidth = width / data.length;
var bar = chart.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d, i) { return "translate(" + i * barWidth + ",0)"; });
bar.append("rect")
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.attr("width", barWidth - 1);
bar.append("text")
.attr("x", barWidth / 2)
.attr("y", function(d) { return y(d.value) + 3; })
.attr("dy", ".75em")
.text(function(d) { return d.value; });
});
function type(d) {
d.value = +d.value; // coerce to number
return d;
}
</script>
</body>
</html>
Thanks in advance!
apologies, the data.tsv file contains the following:
Sentiment value
Strongly positive 211
Positive 222
Neutral 654
Negative 618
Strongly negative 343
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?1.27.1"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<style type="text/css">
div.tooltip {
position: absolute;
text-align: center;
width: 500px;
height: 550px;
padding: 8px;
font: 10px sans-serif;
background: #ddd;
border: solid 1px #aaa;
border-radius: 8px;
pointer-events: none;
}
.chart rect {
fill: steelblue;
}
.chart text {
fill: white;
font: 10px sans-serif;
text-anchor: middle;
}
</style>
<script type="text/javascript">
var w = 960,
h = 500;
var svg = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h);
svg.append("svg:g")
.attr("transform", "translate(480,50)rotate(60)scale(2)")
.append("svg:rect")
.attr("width", 140)
.attr("height", 140)
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseout", mouseout);
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 1e-6);
function mouseover() {
div.transition()
.duration(500)
.style("opacity", 1);
}
// where the tooltip previosly contained an image
function mousemove() {
div
.html("<h1>Bar Graph</h1><br> <svg class='chart'></svg>")
.style("left", (d3.event.pageX - 34) + "px")
.style("top", (d3.event.pageY - 12) + "px");
}
function mouseout() {
div.transition()
.duration(500)
.style("opacity", 1e-6);
}
// make bar graph
var width = 300,
height = 300;
var y = d3.scale.linear()
.range([height, 0]);
var chart = d3.select(".chart")
.attr("width", width)
.attr("height", height);
d3.tsv("data.tsv", type, function(error, data) {
y.domain([0, d3.max(data, function(d) { return d.value; })]);
var barWidth = width / data.length;
var bar = chart.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d, i) { return "translate(" + i * barWidth + ",0)"; });
bar.append("rect")
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.attr("width", barWidth - 1);
bar.append("text")
.attr("x", barWidth / 2)
.attr("y", function(d) { return y(d.value) + 3; })
.attr("dy", ".75em")
.text(function(d) { return d.value; });
});
function type(d) {
d.value = +d.value; // coerce to number
return d;
}
</script>
'data.tsv' file is not with us,
and we have written only
function mousemove() {
div
.html("<h1>Bar Graph</h1><br> <svg class='chart'></svg>")
.style("left", (d3.event.pageX - 34) + "px")
.style("top", (d3.event.pageY - 12) + "px");
}
above function will place 'Bar Graph' text and one svg element in tooltip.
Hope you will get it.
If not ask for more......

Resources