Labeling and adding an icon to D3 SVG nodes - d3.js

I am trying to add the label and icon in this codepen as per this example Labeled Force Layout
In my restart method, I have added the code
node.append("image")
.attr("xlink:href", "https://github.com/favicon.ico")
.attr("x", -8).attr("y", -8).attr("width", 16).attr("height", 16)
.on("mousedown", mousedownNode);
node.append("text").attr("dx", 12).attr("dy", ".35em").text(function(d) { return d.id });
after my existing code :
node.enter().insert("circle", ".cursor")
.attr("class", "node").attr("r", 10).on("mousedown", mousedownNode);
I understand that I am making the node as circle first then trying to add an icon to it, which is the issue here but I am not sure how to fix it.

You cannot append a <text> element to a <circle> element.
The idiomatic solution here is converting node into a group selection, just like Mike Bostock has in the example you shared:
node.enter().insert("g", ".cursor")
.attr("class", "node");
Then, appending the circles and the texts to node:
node.append("circle")
.attr("r", 10)
.on("mousedown", mousedownNode);
node.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(function(d) {
return d.id
});
And, finally, changing the tick function:
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"
});
Here is the updated CodePen: https://codepen.io/anon/pen/VBepoo?editors=0010
Of course, this is just a quick refactor: you have to change other parts of your code for having node as a group selection.

Thank you Gerardo for this very helpful CodePen entry. Apparently, the CSS overrides the JS and must be modified in order for the icon to appear, for example:
From: .node { fill: #000; }
To: .node { fill: none; stroke: <some color so the labels appear>;}
My update of your update on CodePen

Related

On click of parent node in tree layout, Like link and node, linkText should also exit

On click of parent node in tree layout, link and linktext should exit. Link is exiting but not the linktext. Here is the jsfiddle project. I tried the code - svg.selectAll(".line-label").remove(); which was deleting the linkText from all the labels that should not happen. What i am expecting is on click of node it exits the linkText like link and node from the current branch of the tree not from the whole tree itself.
You can do this by
Adding link like this in update:
//add text to the link
svg.selectAll(".line-label").data(links).enter().append("text")
.attr("font-family", "Arial, Helvetica, sans-serif")
.attr("fill", "Black")
.attr("class", "line-label")
.style("font", "normal 12px Arial")
.attr("transform", function (d) {
return "translate(" + (d.target.y - 30) + "," + (d.target.x - 10) + ")";
})
.attr("text-anchor", "middle")
.text(function (d) {
return d.target.label;
});
//remove the link text in update
svg.selectAll(".line-label").data(links).exit().remove();
Full running code here
Hope this clarifies your concern! :)

Unable to add text on link in d3 collapsible tree

in the above code my .append("text") dosent work.I do not get any text inserted on my links.
i tried using link.append("path")..using this i can see the text but not the links. I want to use
link.insert("path") and still be able to add text and be able to collapse and expand nodes along with the link
text. Pls help
var link = svg.selectAll("path.link")
.data(links, function (d) { return d.target.id; });
// Enter any new links at the parent's previous position.
// var link1=link.enter();
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", function (d) {
var o = { x: source.x0, y: source.y0 };
return diagonal({ source: o, target: o });
});
link.enter()
.append("g")
.attr("class", "link")
.append("text")
.attr("font-family", "Arial, Helvetica, sans-serif")
.attr("fill", "Black")
.style("font", "normal 12px Arial")
.attr("transform", function(d) {
return "translate(" +
((d.source.y + d.target.y)/2) + "," +
((d.source.x + d.target.x)/2) + ")";
})
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function(d) {
console.log(d.target.name);
return d.target.name;
});
This was difficult to answer without a fiddle or a link to working code, but I think this is maybe what you were after: http://jsfiddle.net/henbox/82pepd2a/9/
You should see red text on the links that corresponds to the node text (in black) and these should transition as nodes \ links move.
I created a new variable var linktext to handle the text separate from the links (path elements) themselves, since this was what was causing you paths not to show.
I also used insert("g") instead of append("g") to add a completely new g element, rather than placing the g and text inside each path. Here's the important stuff:
// Update the link text
var linktext = svg.selectAll("g.link")
.data(links, function (d) {
return d.target.id;
});
linktext.enter()
.insert("g")
.attr("class", "link")
.append("text")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function (d) {
//console.log(d.target.name);
return d.target.name;
});
Finally I added 'update' and 'remove' blocks for linktext using a similar approach used for links. Note that I also moved the styling to CSS for tidyness

Link inside the node to expand it

I am trying to create a collapsible tree having a link to expand the current node (in stead of clicking the node using on.("click",clicked) method). Here is the jsfiddle
nodeEnter.append("foreignObject")
.attr("width", rectW)
.attr("height", rectH)
.append("xhtml:body")
.style("font", "14px 'Helvetica Neue'")
.html(function (d) { return "<a href='#' onclick=\x22clicked(" + source + ")\x22>"+d.name+"</a>"});
Problem is that your source variable is converted to string, so you don't actually pass object to clicked function;
You can rewrite this to append link like this:
nodeEnter.append("foreignObject")
.attr("width", rectW)
.attr("height", rectH)
.append("xhtml:body")
.style("font", "14px 'Helvetica Neue'")
.append("a").html(function(d){return d.name;})
.attr('href', '#')
.on('click', function(){
clicked(source);
});
see updated fiddle
To make it work for clicked node (instead of always parent node) you can replace source by clicked function argument
.on('click', function(d){
clicked(d);
});
another updated fiddle

Adding tool tip to collapse graph

I'm trying to add tooltip to a collapse graph. And i was able to add the tooltip using the mouseon and mouseout event.But the challenge is i am unable to apply my own css on that tool tip .my code is
function mouseover(d) {
d3.select(this).append("text")
.attr("class", "hover")
.attr('transform', function(d){
return 'translate(5, -10)';
})
.text(d.name + ": " + d.id);
}
Just add the necessary css:
.hover{
fill: red;
}
Example here.

d3.js axis - making it have 0 ticks and no markings

Is it possible to create a d3.js axis and have there be no tick marks and no numbering scheme? Basically, can I make the axis invisible? I'm using the code below to create my axes:
svg.selectAll("axis")
.data(d3.range(angle.domain()[1]))
.enter().append("g")
.attr("class", "axis")
.attr("transform", function(d) { return "rotate(" + angle(d) * 180 / Math.PI + ")"; })
.call(d3.svg.axis()
.scale(radius.copy().range([0,0]))
.ticks(1)
.orient("left"))
.append("text")
.style("color", "white")
.attr("y",
function (d) {
if (window.innerWidth < 455){
console.log("innerWidth less than 455: ",window.innerWidth);
return -(0);
}
else{
console.log("innerWidth greater than 455: ",window.innerWidth);
return -(0);
}
})
.attr("dy", "0em");
If you don't want your axis to be visible, just don't draw them (basically comment out this code).
If you really just want to turn them white, you can use the following classes:
.axis line, .axis text, .axis path {
color: white;
}
This would be the easiest way to manipulate them to turn them 'on' and 'off'. Also, if you ever need to figure out how to style a d3 diagram, you can navigate through the SVG just like you do html and style with CSS the same way too.
For example, here is the SVG for the tick marks in the axis.
<line class="tick" y2="6" x2="0"></line>
You can see that I targeted the element (line) but you could also target (.tick) as well.

Resources