Successfully created a heatmap using d3.
Here's the FIDDLE.
I have some basic idea on using d3's mouseover events. But now I wanted move a step ahead.
This is what I'm looking for. When I hover on a legend, I wanted the hovered legend's respective data to be highlighted in the chart.
Can someone help me to achieve it?
You're not binding the data to the legend, which makes this task a bit more difficult, but you can still do it fairly easily. The idea is to assign a class defined by the fill color to the rect elements and then select accordingly in the mouseover handler. The code looks like this.
// for the rectangles
.attr("class", function(d) {
return "hour bordered " + "color-" + colorScale(d.value).substring(1);
})
// for the legend
.on("mouseover", function(d, i) {
svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "blue");
})
.on("mouseout", function(d, i) {
svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "white");
});
Complete example here.
Related
I created two different SVGs. One contains a graph with data points, the other one contains three lines. The lines color are supposed to be dependent on the selected data point and I have not managed to get this done yet (more details below). The jsfiddle can be found here: jsfiddle.
What I would like to do is to change the color of the three lines when I mouseover the data points. I managed to change the color of all lines to the same color but would actually like to use the color that is associated to the respective data point but I don't know how I can pass the color data which are stored in myColors to the function where I set the lines' color.
The relevant code is shown below. I add a graph with datapoints to mySvg and when I mouseover the data points, I change their color to black and the color of the lines in the other SVG to green. However, instead of changing all lines' color to green, I would actually like to change their colors to the colors defined in myColors (see the above linked jsfiddle to find the data). How could I do this?
var circles = mySvg.selectAll("circle")
.data(lineData)
.enter()
.append("circle");
var circleAttributes = circles
.attr("cx", function (d) { return xScale(d.x); })
.attr("cy", function (d) { return yScale(d.y); })
.attr("r", 6)
.style("fill", 'red')
.on('mouseover', function(d){
d3.select(this).style("fill", 'black');
d3.select('#myLines').selectAll("line").attr("class","sweepline").style("stroke", 'green');
})
.on('mouseout', function(d){
d3.select(this).style("fill", 'red');
});
As with many d3 problems this one is easily solved using data binding. Your custom colors could be bound to the lines you append to the second SVG. Since your array myColors, consisting of the arrays of custom colors per line, has the same structure as your other arrays like names, x1Val, y1Val and so forth, it can be easily integrated in the data array coords used for binding information to your lines:
var coords = d3.zip(names, x1Val, y1Val, x2Val, y2Val, myColors);
This data per line can later on be used in the mouseover event handler for your circles setting the stroke style on the lines.
.on('mouseover', function(d,i) {
// ...
d3.select('#myLines')
.selectAll("line")
.style("stroke", function(d) {
return d[5][i].color;
});
})
The callback determines the color by
accessing the array of custom colors, which is at position 5 of the data array bound to the lines, hence d[5],
getting the ith object of this array of colors. The i is the index of this circle, which is passed as parameter to the event handler and made available to the stroke callback by a closure,
getting property .color from this object
Check the updated JSFiddle for a working example.
Furthermore, I have updated the mouseout handler to delete the previously set stroke style causing the lines to be reset to their default color set by class sweepline. This behaviour, at least to my eyes, seemed to be missing.
d3.select('#myLines')
.selectAll("line")
.style("stroke", null);
d3js SVG:title tooltip doesn't show up
I have a graph which contains a lot of circles, now I would like to insert to each circle a tooltip but it doesn't work neither as title in circle nor as tooltip box. I cannot find my mistake:
var circleSmall = canvas.append("circle")
.attr("cx", 869)
.attr("cy", 693)
.attr("r", 10)
.attr("fill", "green")
.append("svg:title").text("Your tooltip info")
.on("mouseover", function(){return tooltip.style("visibility", "visible");})
http://jsfiddle.net/WLYUY/57/
The most important obstacle here was your rects. They were appended AFTER the circles and were preventing mouse events from reaching the circles. So, first thing to do is:
/* do this or append circles AFTER appending recs */
rect {
pointer-events: none;
}
I have added the mouseover and mouseout events necessary to show/hide the tooltip.
Complete FIDDLE here.
NOTE: For demonstration, I have painted the one circle receiving the events in large orange with an orange-red border (you can't miss it). This is just an example...normally you would apply the event listeners to all circles. And this brings me to a sanity check: you are currently appending shapes "manually" but I assume you will eventually do it based on data binding, one of the main points of D3.
I'm using this jsfiddle. All of the tooltips are initially correct when I hover over the bars. But when I click the weekview button to change the graph the tooltips don't get updated.
I believe the problem is in this section:
layer.enter()
.append("g")
.attr("class", "layer");
layer.attr("fill", function (d, i) {
return color(i);
})
.append("svg:title")
.text(function(d){
return d[0].s;
});
layer.exit()
.remove();
The append text is where I add the tooltips. I thought the enter and exit would refresh the bars and therefore refresh the tooltips but it isn't doing it correctly.
How do I update the tooltips when my graph changes?
It is because you are appending a new <title> element every time the bars change. The append should be done once on the enter selection and then simply update the value of the title in the update selection.
Here's a modified version of your code with some comments inline (I've removed the parts that aren't relevant to the tool tip):
layer.enter()
.append("g")
.attr("class", "layer")
.append("title"); // add new element under new layer
// add or update the value of the title element
layer.select("title").text(function(d) {
return d[0].s;
});
I would like to create a mashup of the functionalities as seen from
http://bl.ocks.org/4063423 and http://philogb.github.com/jit/static/v20/Jit/Examples/Sunburst/example2.html
I would like to use d3.js or at least a pure javascript solution but a solution that will respond to mouse clicks to display more information about the selected section.
Zooming in and out is not mandatory, but if I can achieve it, it will be good.
Now my question, Is there a framework that can support this or do I have to mash them up on my own.
Disclaimer: google was not that helpful!
It is easy to do with D3 alone: http://bl.ocks.org/4678148 If you click any element, the element will be focused and transitioned to 90 deg with the selected class set on it.
Also, the legend text on the top right changes to the name of the element selected. The part of code which achieves this coupling is:
d3.selectAll("path").on("click", function (d, i) {
var newAngle = - (d.x + d.dx / 2);
innerG
.transition()
.duration(1500)
.attr("transform", "rotate(" + (180 / Math.PI * newAngle) + ")");
// Set the class "selected" on the chosen element.
path
.classed("selected", function (x) { return d.name == x.name; });
// Update the text box with the right context
// This can be arbitrarily complex to show as many details about the
// object as required.
textBox.data(["Clicked: " + d.name])
.text(String);
});
Update
For the zoomable behavior such that the clicked element transitions to the center, you can use almost the same code as used as here or here. I have made small changes to the code to show how to extract information about which item was clicked: http://bl.ocks.org/4747342
The change in code required is simpler than before:
d3.selectAll("path").on("click", function (d, i) {
// Zooming
path.transition()
.duration(750)
.attrTween("d", arcTween(d));
// Update the text box with the right context
// This can be arbitrarily complex to show as many details about the
// object as required.
textBox.data(["Clicked: " + d.name])
.text(String);
});
How do I implement tooltips on mouse over for links in a D3 directed graph layout? I'm adapting the D3 force example, so setting up node tooltips was straightforward using code like this:
node.append("title")
.text(function(n) {
return n.id;
});
Trying a similar technique with the links didn't result in mouse over tool tips:
var link = svg.selectAll("line.link")
.data(json.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) {
return 4;
});
link.append("title")
.text(function(n) {
return n.info;
});
You can find different solutions suggested by Mike Bostock on this Google Groups thread "show value when click or move mouse over on d3.svg.line"
I think what you are looking for is a combination of these two answers:
d3js: _on()_ doesn't send the current datum object to the onmouse function
and
Adding tooltip to bar chart generated using svg path
Both have jsFiddles you can play with.
Setting the link title as shown above does result in mouse over tooltips -- iff you let the mouse hover over any portion of the link a couple of seconds.