forcelayout text positioning and lines behind text

Hello there … am still relatively new so bear with me if this has a simple solution. I have data from a python program that feeds the forcelayout and my challenges are -

  1. How can position the text around this graph in such a way that it is most visible and reduces the ovelrap. I have cut down the count to a manage-able number around the central point but it would be great if i can position the text on say the left side of this word cloud to further left so that they’re more visible.
  2. Secondly - how can i “send back” these lines and bring the text forward? like we have in powerpoint am looking for a way to send these lines “back” … i can get better colors closer to the background i guess but this would also help improve read-ability.

Standard code that i use from one of the examples is pasted below. Kindly advise.

			var force = d3.layout.force()
				.nodes(d3.values(nodes))
				.links(links)
				.size([width, height])
				.linkDistance(100)
				.charge(-300)
				.on("tick", tick)
				.start();

			// Set the range
			var  v = d3.scale.linear().range([0, 100]);

			// Scale the range of the data
			v.domain([0, d3.max(links, function(d) { return d.value; })]);


		// build the arrow.
			svg.append("svg:defs").selectAll("marker")
				.data(["end"])      // Different link/path types can be defined here
			  .enter().append("svg:marker")    // This section adds in the arrows
				.attr("id", String)
				.attr("viewBox", "0 -5 10 10")
				.attr("refX", 15)
				.attr("refY", -1.5)
				.attr("markerWidth", 4)
				.attr("markerHeight", 4)
				.attr("orient", "auto")
			  .append("svg:path")
			  .attr('fill','grey')
				.attr("d", "M0,-5L10,0L0,5");

			// add the links and the arrows
			var path = svg.append("svg:g").selectAll("path")
				.data(force.links())
			  .enter().append("svg:path")
				.attr("class", function(d) { return "link " + d.type; })
				.attr("marker-end", "url(#end)");

			// define the nodes
			var node = svg.selectAll(".node")
				.data(force.nodes())
			  .enter().append("g")
				.attr("class", "node")
				.on("click", click)
				//.on("dblclick", dblclick)
				.call(force.drag);

			node.append("circle")
			.attr("r", function(d)
			{
				if ((d.type).localeCompare("searchresult")==0)
				{ return 6;  }
				else return 12 ;
			})
			.style("fill", function(d)
			{
				var d3c = "red";
				//console.log('d.type is now:',d.type);
				if ((d.type).localeCompare("searchresult")==0)
				{ d3c = "red";
					//console.log("yes we came here ...");
				}
				else
				{d3c = "green" ;  }
				//return color(d.type);
				//console.log("sending this color now:", d3c);
				return d3c;

			});
1 Like

Here are a couple possibilities:

  • The SVG text element supports dx and dy attributes to shift the text. You could make those attributes functionally dependent on position to, perhaps, push them out radially a bit from the center.
  • You could make much shorter, abbreviated labels and still reveal the full name (and, perhaps, more) on hover.

I’m not quite sure what you mean here but you you might look into d3.selection.raise(). Presumably, this would be done programmatically - perhaps, on hover.


Hope that helps! If you have more specific questions, we usually share code via a link to published notebook (which can be unlisted, if you prefer).

Thanks @mcmcclur … will try these out first. The challenge i ran with the dx, dy on the text element was - i wanted only those on the left side of the pane to go further left but i’ll try some math around that.

As for the “send back” - the intent was to make sure the line doesnt obscure the text - that’s all. Rather i wanted the text OVER the line but like i said - i can always find a color that blends with the background and hopefully if i call the text method after the line call it will render ok. Will try that out.

As for code sharing - the only challenge i had when i tried this was - my data comes from a far away neo4j db … so i may have to create a dummy json on this page just for demo sakes. Will do that next time. Thanks once again.

you could maybe use dx="-4" text-anchor="end" for the points on the left, and dx="4" text-anchor="start" for those on the right?

Thanks @Fil … .tried that but i didnt know which nodes are on the left and which ones are on the right; so i finally decided to cut their size down to just the first 6 to 10 characters and have come up with a table at the bottom of this (outside this svg) to show additional details against an OnClick event.
I also think i should’ve considered a dendogram for this sort of data - on second thoughts :slight_smile:

1 Like