Add description text and links in zoomable circle packing graph with d3 - javascript

I am still new at d3 and want to create a zoomable circle graph with title text, description text and links (the links only displayed in the leafs) that can be clicked and open a new page.
I have figured out how I can add those in a normal circle pack, but I can't implement it with the zoomable circle graph (not displayed)
It would be so great if someone could help me with it because I am so stuck with this.
Here my full working example at CodePen https://codepen.io/Lea12/pen/ExvoEgx
And the not working code
var description = g.selectAll("text")
.append("text")
.attr("class","description")
.attr("dy", +80)
.style("display", function(d) {
return d.parent === root ? "inline" : "none";
})
.text(function(d) {
return d.data.description;
});
var url = g.selectAll("text")
.append("text")
.attr("class","description")
.attr("dy", +120)
.text("click for more information")
.on("click", function(d) {
window.open(d.data.url,"_blank")
})

Related

Hovering over a selected path on chart

I have a donut chart that I want to use, which is based on this.
I'm trying to create a function, when a user hovers over a certain path of the donut chart, the stroke color appears.
Nevertheless, I tried to edit a portion of the code but somehow the "mouseover" and "mouseout" handlers are ignored (not working)? I tried researching the Internet, but I couldn't find a solution.
Below is a portion of the code:
var path =
svg.select('.slices')
.datum(data)
.selectAll('path')
.data(pie)
.enter().append('path')
.attr('fill', function(d) {
return colour(d.data[category]);
})
.attr('d', arc)
.on('mouseover', function() {
console.log("mouseOver");
})
.on('mouseout', function(d) {
console.log("mouseOver");
});

D3 Stacked Bar Chart add Data Labels and solving D3 Label Placement

I have two questions.
I want to add data labels to a stacked bar chart.
I try to change the Code of this Example StackedBarChart, but I am not able to add data labels.
if the labels are added I need to prevent overlapping. I hope I can do this like John Williams in his blog for pie charts www.safaribooksonline.com/blog/2014/03/11/solving-d3-label-placement-constraint-relaxing/ or with the d3 extension D3-Labeler //tinker10.github.io/D3-Labeler/.
I found this jsfiddle http://jsfiddle.net/3a5Wk/1/ code and I am very grateful if you can also put the answers in a jsfiddle or explain your code in more detail as I am just starting on d3-Charts.
I have solved the issue of the first question by adding the Label code. I have added:
var dataText = svg.selectAll(".dtext")
.data(layers)
.enter().append("g")
.attr("class", "g")
dataText.selectAll("rect")
.data(function(d) { return d; })
.enter().append("text")
.attr("x", function(d) { return x(d.x) +18; })
.attr("y", function(d) { return y(d.y + d.y0) +10; })
.style("text-anchor", "middle")
.style("font-size", "10px")
.style("color", "white")
.text(function (d) {return (d.y);});
Now I still got the Problem that the labels overlap.
How can I change the position of the labels in a way that they don't overlap?

Tooltips for nested circles in D3 circle pack layout

I'm banging my head here. I want to display tooltips for the leaf nodes in a structure such as Zoomable Pack Layout. The leaf nodes are the brown ones. If I used the standard code for tooltips:
vis.selectAll("circle")
.data(nodes)
.enter()
.append("svg:circle")
.attr("class", function(d) {
return d.children ? "parent" : "child";
})
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", function(d) {
return d.r;
})
.on("click", function(d) {
zoom(node == d ? root : d);
})
.append("svg:title")
.text("test"); \\ Browser uses this for tooltips
I get tooltips on the primary circles but not on the leaf nodes. I tried:
.append("svg:title")
.text(function(d) {
if(d.size){return 'test';}
});
...hoping that by returning something only when a varaible contained by leaf nodes is present may prevent the parent nodes from showing a tooltip but I'm afraid all it did was allow a hidden tooltip taht silently prevents anything from displaying.
Any thoughts? I figure I either need to stack the svg:circles so that the leaf nodes are in front of the others or attach svg:titles only to the leaf nodes but I'm not sure how to do that.
Here is a fiddle of the tooltips:
Fiddle
The problem is in fact not the code, but the CSS that prevents the leaf node circles from receiving pointer events. Simply remove
circle.child {
pointer-events: none;
}
and it works fine. Complete example here.

D3.js Force Layout: Dynamically added node doesn't move with rest of graph

I'm working on building a molecule creator in D3 using the original example created by Mike Bostock: http://bl.ocks.org/mbostock/3037015
I'm using a force layout just like in the example. My problem is when I add a new Node/atom dynamically, it doesn't move with the rest of the graph. I've read other questions and implemented everything that is suggested and have made sure that I'm following the proper update/join procedure that D3 requires and yet still the added carbon refuses to move with the rest of the graph.
Here is my update/create function:
function buildMolecule () {
// Update link data
link = link.data(links);
// Create new links
link.enter().append("g")
.attr("class", "link")
.each(function(d) {
d3.select(this)
.insert("line", ".node")
.style("stroke-width", function(d) { return (d.bond * 2 - 1) * 2 + "px"; });
d3.select(this)
.filter(function(d) { return d.bond > 1; }).append("line")
.attr("class", "separator");
d3.select(this)
.on("click", bondClicked);
});
// Delete removed links
link.exit().remove();
// Update node data
node = node.data(nodes);
// Create new nodes
node.enter().append("g")
.attr("class", "node")
.on("click", atomClicked)
.each(function(d) {
console.log('d:', d);
// Add node circle
d3.select(this)
.append("circle")
.attr("r", function(d) { return radius(d.size); })
.style("fill", function(d) { return color(d.atom); });
// Add atom symbol
d3.select(this)
.append("text")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function(d) { return d.atom; });
d3.select(this).call(force.drag);
});
// Delete removed nodes
node.exit().remove();
force.start();
}
JsFiddle: http://jsfiddle.net/2dPMF/1/
Any help would be greatly appreciated!
You're modifying the data structures of the nodes and links beyond adding and deleting nodes, which messes up the force layout. I'm talking about these lines in particular.
function bigBang () {
links = links.concat(linksList);
nodes = nodes.concat(nodesList);
buildMolecule();
}
The first two lines in that function are what I'm talking about. Working jsfiddle here.

How to display names next to bubbles in d3js motion chart

In Mike Bostocks example http://bost.ocks.org/mike/nations/ there is so much data that putting the names of the countries there would make it chaotic, but for a smaller project I would like to display it.
I found this in the source:
var dot = svg.append("g")
.attr("class", "dots")
.selectAll(".dot")
.data(interpolateData(2004))
.enter().append("circle")
.attr("class", "dot")
.style("fill", function(d) { return color(d); })
.text(function(d) { return d.name; })
.call(position)
.sort(order);
dot.append("title")
.text(function(d) { return d.name; });
But somehow a title never shows up. Does anybody have an idea, how to display the name, next to the bubble?
As the other answer suggests, you need to group your elements together. In addition, you need to append a text element -- the title element only displays as a tooltip in SVG. The code you're looking for would look something like this.
var dot = svg.append("g")
.attr("class", "dots")
.selectAll(".dot")
.data(interpolateData(2004))
.enter()
.append("g")
.attr("class", "dot")
.call(position)
.sort(order);
dot.append("circle")
.style("fill", function(d) { return color(d); });
dot.append("text")
.attr("y", 10)
.text(function(d) { return d.name; });
In the call to position, you would need to set the transform attribute. You may have to adjust the coordinates of the text element.
Unfortunately grouping the text and circles together will not help in this case. The bubbles are moved by changing their position attributes (cx and cy), but elements do not have x and y positions to move. They can only be moved with a transform-translate. See: https://www.dashingd3js.com/svg-group-element-and-d3js
Your options here are:
1) rewrite the position function to calculate the position difference (change in x and change in y) between the elements current position and its new position and apply that to the . THIS WOULD BE VERY DIFFICULT.
or 2) Write a parallel set of instructions to setup and move the tags. Something like:
var tag = svg.append("g")
.attr("class", "tag")
.selectAll(".tag")
.data(interpolateData(2004))
.enter().append("text")
.attr("class", "tag")
.attr("text-anchor", "left")
.style("fill", function(d) { return color(d); })
.text(function(d) { return d.name; })
.call(tagposition)
.sort(order);
You will need a separate tagposition function since text needs 'x' and 'y' instead of 'cx', 'cy', and 'r' attributes. Don't forget to update the "displayYear" function to change the tag positions as well. You will probably want to offset the text from the bubbles, but making sure the text does not overlap is a much more complicated problem: http://bl.ocks.org/thudfactor/6688739
PS- I called them tags since 'label' already means something in that example.
you have to wrap the circle element and text together , it should look like
<country>
<circle ></circle>
<text></text>
</country>

Categories