I am building a graph with D3 and represent the links between nodes as paths. I want to add a label for each path by using the following code:
path_labels = path_labels.data(links);
path_labels.enter().append("text")
.attr("class", "linklabel")
.style("font-size", "12px")
.attr("text-anchor", "start")
.append("textPath")
.attr("xlink:href", function (d) {
return "#linkId_0";
})
.text(function (d) {
return "my text";
});
When I look at the result, text is appended, but not the textPath inside the text element.
Can someone help?
The full code can be found at http://jsfiddle.net/3u0oage7/
I found the answer to the problem. The code I posted works as supposed. The problem was that in my code I had this:
svg.selectAll('text').
text(function (d) {
return d.label;
});
This code was changing all the text elements. I changed the selector so it selects only the text elements corresponding to a circle.
Related
I try to add labels to map done with d3-geomap, but can't make it work.
The choropleth map itself gets painted correctly, but adding the labels doesn't work out right. The labels show up on the wrong position.
After painting the map I loaded again the topojson file again and then add text blocks like that:
d3.json("https://d3-geomap.github.io/d3-geomap/topojson/countries/ESP.json").then(function(es) {
let path = d3.geoPath().projection(d3.geoMercator());
svg.select("svg").append("g")
.selectAll("labels")
.data(topojson.feature(es, es.objects.units).features)
.enter().append("text")
.attr("class", "place-label")
.attr("x", function(d) { return path.centroid(d)[0]; })
.attr("y", function(d) { return path.centroid(d)[1]; })
.attr("text-anchor","middle")
.text(function(d) { return d.properties.name; });
});
The problem here is that I can't figure out the correct position of the labels. I also tried to apply the same transform as to the polygons, but then have all the same y position.
Here is the example on bl.ocks.
I made some changes to your code and published it in this gist. When testing it locally, the map displayed like the image below. At this size, labels don't work well, but if you resize the map and/or show fewer labels it should be okay.
Some info on the changes. Whenever you want to draw something on top of a map with d3-geomap, it should go in the postUpdate function. This way the map is already rendered and its SVG elements, the geo data and the path object are accessible via the map object you created. No need to load the Topojson file a second time. The function passed to postUpdate looks like follows:
function drawLabels() {
map.svg.append("g").attr('class', 'zoom')
.selectAll("text")
.data(topojson.feature(map.geo, map.geo.objects.units).features)
.enter().append("text")
.attr("class", "place-label")
.attr("x", function(d) { return map.path.centroid(d)[0]; })
.attr("y", function(d) { return map.path.centroid(d)[1]; })
.attr("text-anchor","middle")
.text(function(d) { return d.properties.name; })
.on('click', map.clicked.bind(map));
}
This page of the documentation shows the available map attributes and accessor functions. Hope this helps.
I have a cluster force layout which works fine, and I can add text to the circles. However, when I try to add a hypertext link, nothing is displayed.
What is the problem with my code?
The code for the text is
node.append("a")
.text(function(d){
return d.name;
})
.attr("href", function(d){
return '/profile/'+d.name;
})
.attr("dx", -10)
.text(function(d){
return d.name;
})
.style("stroke", "white");
In SVGs you are not allowed to put textual content into the <a> itself. For an overview of what is actually allowed in an <a> element have a look at the Content model section of the spec.
You need to wrap another text element around your link labels:
node.append("a")
.attr("xlink:href", function(d){
return '/profile/'+d.name;
})
.append("text") // <-- Wrap <text> element around link label
.text(function(d){
return d.name;
})
.attr("dx", -10)
.style("stroke", "white");
I following this tutorial (http://blog.ashokalella.com/neo4j/d3/2015/04/27/neo4j-and-d3/).
How can I add name on the graph?
Like this (http://bl.ocks.org/mbostock/1153292).
Please help me.
Thank you.
Here is a detailed how-to on data visualization:
http://neo4j.com/developer/guide-data-visualization/
In d3 you would then add another function to return the label/caption of the node accessing the node itself like shown in the blocks:
var text = svg.append("g").selectAll("text")
.data(force.nodes())
.enter().append("text")
.attr("x", 8)
.attr("y", ".31em")
.text(function(d) { return d.name; });
I'm trying to learn d3 library and include a list to a tree. Something like:
JSFiddle: link
I don't think I understand the concept of adding data to a node well. Did go through this link: How selection work in d3?
You can do this with a subselection:
// keep reference to appended text elements
var someText = nodeEnter.append("text")
.attr("class", "properties")
.attr("text-anchor", "middle")
.attr("y", 52)
.style("fill-opacity", 1);
// sub-select them with properties array
someText.selectAll('tspan')
.data(function(d) {
return d.properties || []; // catch situation where child has no properties
})
.enter()
.append('tspan')
.attr("x", 0)
.attr('dy', "0.9em")
.text(function(d) {
return d;
});
Updated fiddle.
I am just starting to learn D3 and currently working through understanding this example.
I am trying to get text to display next to each node in the graph. In the JSON data, there is a key named name, which contains the name of a character from Les Misérables. I am trying to display this text next to each node using this code:
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", "black")
.text(function(d) { return d.name;}).style("font-family", "Arial").style("font-size", 12)
.call(force.drag);
I've basically just altered the .text to try and display text. Can anyone explain how I can get text to display? Thanks in advance.
The SVG <circle> element will not display any text that you place inside it using the .text function. A way to display the text would be to make the nodes of the graph SVG <g> elements. These can then contain a <circle> and a <text> child elements.
This could look like this :
\\create graph nodes using groups
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("g").call(force.drag);
node.append("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", function (d) { return color(d.group); });
node.append("text")
.text(function (d) { return d.name; });
You would also need to change the force so that it transforms the group <g> on a tick.
force.on("tick", function () {
...
node.attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; });
});
You can see it in action for a small graph at http://jsfiddle.net/vrWDc/19/. This method may not be very efficient when applied to a large graph due to the amount of text that needs to be rendered.