Drawing a graph with images and arrows with d3 issues - d3.js

I'm trying to draw a graph with d3 inserting images in node circles and drawing arrows on the target node. Nodes with images and edges are properly drawn, but the arrows are missing, although the marker is defined and used in links.
When I change the way nodes are attached to "g", arrows are drawn, but circle and images disappear. Can't figure out where the mistake stays.
D3 code is the following:
// define marker for the arrow
svg.append("defs").selectAll("marker")
.data(["arrow"])
.enter().append("marker")
.attr("id", function(d) { return d; })
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5");
// add links
var link = svg.append("g").selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link")
.attr("marker-end", function(d) { return "url(#arrow)"; })
.style("stroke", "#FF3300");
// add nodes
var node = svg.append("g").selectAll(".node")
.data(nodes)
.enter().append("svg:g")
.attr("class", "node")
.on("dblclick", dblclick)
.call(force.drag);
node.append("svg:circle")
.attr("r", 50)
.style("fill", "#FFEBE6")
.style("stroke", "#FF3300")
.style("stroke-width", 3);
// add images - from base64
node.append("image")
.attr("xlink:href", function(d){
if (d.imgB64) {
return 'data:image/png;base64, ' + d.imgB64 ;
}
})
.attr("x", -40)
.attr("y", -40)
.attr("width", 80)
.attr("height", 80)
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0.0);
})

Nothing wrong with the code, arrows seems to be hidden/overlaid by the node circle and image. Changing the refX and refY attributes to 65 and 0 respectively addresses the issue.

Related

Adding background color to axis labels in D3 parallel coordinates

I'm working on a modified version of this D3 code for parallel coordinates. I would like to add a background color for the axis labels. I realize I cannot set a background color using CSS styles because this is SVG text, so I tried to append rectangles but to no avail. Here is what I wrote but it's not drawing anything:
d3.selectAll(".label")
.append("rect")
.attr("x", function(d){ return d3.select(this).node().getBBox().x - 5;})
.attr("y", function(d){ return d3.select(this).node().getBBox().y - 5;})
.attr("width", function(d){ return d3.select(this).node().getBBox().width;})
.attr("height", function(d) {return d3.select(this).node().getBBox().height;})
.style("stroke", "black")
.style("fill", "yellow");
What am I doing wrong?
EDIT:
based on comments, I appended to the parent g rather than the text label itself. Now the code looks like this:
// Add an axis and title.
var gsvg= g.append("svg:g")
.attr("class", "axis")
.attr("id", "gsvg")
.each(function(d) { d3.select(this).call(axis.scale(yscale[d])); })
.attr("transform", "translate(0,0)");
d3.selectAll("#gsvg")
.append("rect")
.attr("x", function(d){ return this.parentNode.getBBox().x - 5;})
.attr("y", function(d, i){ return i%2 === 0 ? this.parentNode.getBBox().y - 20: this.parentNode.getBBox().y - 35;})
.attr("width", function(d){ return this.parentNode.getBBox().width;})
.attr("height", function(d) {return 20;})
.style("stroke", "lightgrey")
.style("stroke-width", 2)
.style("fill", function(d){
return self.fcolorMap[d];
})
.style("opacity", 0.5);
gsvg.append("svg:text")
.style("text-anchor", "middle")
.attr("y", function(d,i) { return i%2 == 0 ? -14 : -30 } )
.attr("x",0)
.attr("class", "axis-label")
.text(function(d) {
var s = d.split("|");
return s[s.length-1]; });
The only problem is now I need to figure out how to get the bounding boxes of the labels rather than those of the axes.

Placing circles in Sunburst arcs

I need to place circles in the sunburst arcs, close to the outer radius either in the middle or in the sides as in the mock-up in the B Unit slice.
Please use this sunburst example to play around: jsfiddle
var circles = g.append("circle")
.attr("cx",
function(d) {
return arc.centroid(d)[0];
})
.attr("cy",
function(d) {
return arc.centroid(d)[1];
})
.attr("r", 8)
.attr("stroke", "black")
.attr("stroke-width", 2)
.style("fill", "blue");

How to make a dashed line legend with d3.js

I usually make a line legend by appending a rect giving it a very small height so that it looks like a line.
But now I need a dashed line legend. I am not able to do it by my old way. Can anyone show me a quick example of how to make a line legend with append('path') with d3.js?
You can make it like this with a line DOM:
var legend = svg.selectAll(".legend")
.data(ageNames.slice().reverse())//data set for legends
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("line")//making a line for legend
.attr("x1", width - 28)
.attr("x2", width)
.attr("y1", 10)
.attr("y2", 10)
.style("stroke-dasharray","5,5")//dashed array for line
.style("stroke", color);
legend.append("text")
.attr("x", width - 44)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
Working example here
Hope this work

d3.js Add labels in Chord diagram

I am new to this kind of chord visualization. I am working on a sample http://bl.ocks.org/mbostock/4062006:
I would like to add "black", "blonde","brown","red" as labels in the respective chord. How is this possible.
I tried something like this but is not working:
var textLabel = d3.scale.ordinal().range(['Black','Blonde','Brown','Red']);
svg.append("g").selectAll("path")
.data(chord.groups)
.enter()
.append("path")
.style("fill", function(d) { return fill(d.index); })
.style("stroke", function(d) { return fill(d.index); })
.attr("d", d3.svg.arc().innerRadius(innerRadius).outerRadius(outerRadius))
svg.append("g").append("svg:text")
.attr("x", 6)
.attr("dy", 15)
.append("svg:textPath")
.text(function(d,i) { return textLabel(i+1); })
.on("mouseover", fade(.1))
.on("mouseout", fade(1));
You have forgotten to use the enter selection and also do not link the svg:textPath to an actual path in the SGV. To do this the path you want the text to follow needs to have been given an id attribute and you need to reference this in the textPath with an href attribute.
So you want to add the id attribute to the path you want the text to follow
.attr("id", function(d, i){return "group-" + i;})
You then want to do something like this to add textPath elements
svg.append("g").selectAll("text")
.data(chord.groups)
.enter()
.append("sgv:text")
.attr("x", 6)
.attr("dy", 15)
.append("svg:textPath")
.attr("xlink:href", function(d, i){return "#group-" + i;})
.text(function(d,i) {return textLabel(i+1);});
Finally with the colour black you will probably want to invert the text so you don't end up with black on black text.
.filter(function(d, i){return i === 0 ? true : false;})
.attr("style", "fill:white;");

D3.js - can clipping paths be used with d3.svg.symbol?

I'm trying to draw multiple 'cross' symbols inside of a circle for use in a visualization. I'd like to draw the crosses in a 'g' tag and then apply a clipping path.
Is it possible to use clip paths with d3.svg.symbol ?
In the below example, the svg circle is masked correctly with the clip path; however the cross (the last part of the code) isn't.
Am I doing something wrong or is this not a feature?
var svg = d3.select("#maskingExample")
.append("svg:svg")
.attr("width", 500)
.attr("height", 200);
svg.append("svg:clipPath")
.attr("id", "clipper")
.append("svg:rect")
.style("stroke", "gray")
.style("fill", "black")
.attr("x", 50)
.attr("y", 25)
.attr("width", 300)
.attr("height", 45);
svg.append("g").append("svg:circle")
.style("stroke", "gray")
.style("fill", "blue")
.attr("cx", 175)
.attr("cy", 55)
.attr("r", 50)
.attr("clip-path", "url(#clipper)");
svg.append("g").append("path")
.attr("d", d3.svg.symbol()
.size( function(d) { return 3000; })
.type( function(d) { return d3.svg.symbolTypes[1]; }))
.attr("transform", "translate(150, 50)")
.attr("clip-path", "url(#clipper")
.style("fill", "black");
You're missing a close paren. Instead of
.attr("clip-path", "url(#clipper")
it should read
.attr("clip-path", "url(#clipper)")

Resources