Good evening.
I've added a series of d3 points to a leaflet map, and then wanted to use click handlers on those points to drive another panel. But I don't seem to be able to get the handler to pick up. Why?
You can see the file so far:
http://jsbin.com/bewudenide/edit?html,output
The code that generates the circle points on a custom layer on leaflet.js:
var feature = g.selectAll("circle")
.data(collection)
.enter().append("circle")
.style("stroke", "black")
.style("opacity", .6)
.style("fill", "steelblue")
.attr("r", 10);
I thought it would be simple case of adding click handlers for the mouseover and click events thus:
feature.on("click", click);
function click(d) {
console.log(d.name);
}
And:
feature.on("mouseover", mouse_over);
function mouse_over(d) {
d3.select(this)
.transition()
.duration(500)
.style("background", "lightBlue")
.style("color", "white");
}
While the click function registers to console, I'm not clear why the mouse_over function doesn't change the style of the point. I was also expecting to see the pointer to change, but it doesn't.
Please excuse my lack of experience with d3, javascript or leaflet.
EDIT:
I now realise that I hadn't added some of the JSON used by the existing code. It looks like
[{
"index":1,"name":"Adderley Green Surgery","total":276266.2700000001},{
"index":2,"name":"Alton Surgery","total":416559.8999999998},{
"index":3,"name":"Apsley Surgery","total":1023757.89999999998}]
If you are using leaflet 1.0, I think the reason is that leaflet has set "pointer-event" as "none":
Figure showing SVG within leaflet
which makes the click event cannot be fired. So the solution is quite simple, just set "pointer-event" as "all" by using css, then it works! I have tried it by using leaflet 1.0.
pointer-events:
pointer-events description
The problem is that the style attributes are not valid for the svg element.
Try...
feature.on("mouseover", mouse_over);
function mouse_over(d) {
d3.select(this)
.transition()
.duration(500)
.style("fill", "lightBlue")
.style("stroke", "white");
}
Or...
feature.on("mouseover", mouse_over);
function mouse_over(d) {
d3.select(this)
.transition()
.duration(500)
.style({fill: "lightBlue", stroke: "white"});
}
Or...
feature.on("mouseover", mouse_over);
function mouse_over(d) {
d3.select(this)
.transition()
.duration(500)
.attr({fill: "lightBlue", stroke: "white"});
}
Related
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.
I've made a fast stand-alone part of the project I have as to show you my problem. I have this circle that represent a node in my graph and what I want is to have on mouseover a box appearing with some text and image. This far I have the node, the box and the text. My problem is that the image doesn't appear, there is only a border of the space dedicated to the image and nothing inside.
I don't know if I'am using the right order of appending things?
I`m using a div that is created initially and it's invisible, then I create the circle and bind a listener to it for the mouseover event. The listener appends to the div a text field and the image. For the image it gives the href attribute and on mouseout it renders the div invisible again. Would you help me find what is going wrong in all this....thank you!
//the box, invisible for now
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("width","60px")
.style("height","28px")
.style("padding","2px")
.style("font","12px sans-serif")
.style("border","0px")
.style("border-radius","8px")
.style("background", "lightsteelblue")
.style("visibility", "hidden");
//the svg container
var svg = d3.select("body").append("svg")
.attr("width", 500)
.attr("height", 500);
//the node
svg.append("circle")
.attr("class", "logo")
.attr("cx", 225)
.attr("cy", 225)
.attr("r", 20)
.on("mouseover", function(d){
tooltip.text("some text");
tooltip.append("image")
.attr("href","https://github.com/favicon.ico")
.attr("x", -8)
.attr("y", -8)
.attr("width","16px")
.attr("height","12px");
tooltip.style("visibility", "visible");
})
.on("mousemove", function(){return tooltip.style("top", (event.pageY-
10)+"px").style("left",(event.pageX+10)+"px");})
.on("mouseout", function(){return tooltip.style("visibility", "hidden");});
You need to change image to img and href to src. Complete working example here.
In the process of learning D3.js.
Is it possible using a force layout to place a circle within another circle shape as per the picture. I am hoping to transition between a single circle per node to a display showing two circles per node. The size of the effective donut is used to illustrate another variable in the data.
Is this possible?
You don't even need to use anything other than a basic svg circle, as you find in most examples. Just bind the data to it, apply a stroke, and set the stroke-width attr to your other variable. Or r - otherVar, I'm sure you can figure that part out.
If this doesn't satisfy, build your own shape. The 'g' svg element is a container element, and lets you build whatever you like. Add two circles to a g, fill them how you like. Make sure to add them in the right order, since svg has no concept of 'on top', things just get painted in the order that you add them.
edit: okay, quick demo so you can learn some syntax. I didn't add any comments but hopefully the code is very verbose and straightforward. Find it here.
d3/svg is something that you have to just bash your head against for a while. I highly recommend spending some time creating a sandbox environment where you can quickly test new things, save, refresh browser to see results. Minimizing that turnaround time is key.
Thanks to roippi I was able to create a group containing two circle shapes.
var nodeCircles = svg.selectAll("g")
.data(nodes);
// Outer circle
var outer = nodeCircles
.enter()
.append("circle")
.attr("class", "node_circle")
.attr("r", function(d) { return d.radius_plus; })
.style("fill", function(d) { return d.color_plus; })
.style("opacity", 0);
// Inner circle
var inner = nodeCircles
.enter()
.append("circle")
.attr("class", "node_circle")
.attr("r", function(d) { return d.radius; })
.style("fill", function(d) { return d.color; })
.style("stroke", function(d) { return d3.rgb(d.color).darker(2); })
.on("mouseover", mouseOver)
.on("mouseout", mouseOut)
.call(force.drag);
Outer circle visibility is toggled via a button.
As mentioned, I use a desktop based IDE to run/test visualisation languages. Currently the IDE supports studies written in D3.js, Raphael, Processin.js, Paper.js and Dygraphs. Picture below...
I am not sure why my click method is not working. In this test I want to be able to click on one of the circle nodes on the graph and display its number. Hovering over works kind of.
What library's click event am I using, D3? Jquery? normal JS?
ultimately I want to do tooltips when I hover over the nodes, and make them go away when I move the mouse away
http://jsfiddle.net/ericps/b5v4R/
dots.enter()
.append("circle")
//.append("svg:circle")
.attr("class", "dot")
.attr("cx", complete_line.x())
.attr("cy", complete_line.y())
.attr("r",3.5)
.append("title")
.text(function(d){ return d.completed;})
.on("click", function(d) { alert("hello"); });
You've attached the event handler to svg:text element. I think you want to attach it to the svg:circle element:
dots.enter().append("circle")
.attr("class", "dot")
.attr("cx", complete_line.x())
.attr("cy", complete_line.y())
.attr("r",3.5)
.on("click", function(d) { alert("hello"); })
.append("title")
.text(function(d){ return d.completed; });
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");.)