d3 venn diagram labels layering - javascript

Im using this great article to produce a venn diagram with D3.
http://www.benfrederickson.com/venn-diagrams-with-d3.js/
It looks great but on occasion I get bubbles overlapping the the labels become hidden. Is there a way to make sure the text element is always on top? (see the picture below.. label A needs to be on top of circle B.
I found this good article but im struggling in how to implement this in the venn.
How can I bring a circle to the front with d3?

You should grab the latest code from master: this commit should fix the issue you had there https://github.com/benfred/venn.js/commit/4cb3bbef65b5b3c3ce02aee7d913e8814e898baf
Instead of having the 'A' label be overtop of the 'B' circle - it willnow move the label so that its in the certain of the 'A' region that isn't overlapped with 'B'. Some details are in this issue here: https://github.com/benfred/venn.js/issues/18

You might find it easier to work in actual layers. You can use g elements to create them. For example:
var lowerLayer = svg.append('g');
var upperLayer = svg.append('g');
Now anything you append to upperLayer will appear above anything you append to lowerLayer because the two g elements have been added to the DOM and are in a specific order.
Also check out this answer I wrote up for a similar question.

Related

Why are the text labels in d3 transforming to zero on pan/zoom?

I'm fairly new at d3 and I've built the code from a couple of sources so it's probably just that I have it initializing incorrectly but I'm not seeing what it is. The page I'm building dynamically fetches geojson from a database and renders a simple map with a label. This works correctly but whe I added code to give the map zoom/pan functionality the map behaves correctly but the transform on the text moves the label to 0 postition with the <g> element and I'm not sure why? When I zoom in the map and text increases in size as expected but the text position stays at 0/0.
Instead of dumping a lot of code here I've put together this fiddle so that it could easily be seen and tested.
I think that anyone more familiar with d3 probably knows what I've got wrong here. I would sure appreciate someone pointing it out to me. Thanks
See your problem saved in the fiddle:
const items = g.selectAll('g.item')
.data(bb.features)
.enter()
.append('g')
.classed('item', true);
items.append('path').attr(...)
items.append('text').attr(...)
Instead of entering path and text elements separately, enter a g container and then append path and text under the g.

Masked element in Snap SVG doesn't come into view when translated

I have a group of elements that are masked by a rect in SnapSVG and I want to translate the elements, bringing new ones into view (and hiding ones that are currently in view). The code is really simple - here's a codepen: http://codepen.io/austinclemens/pen/ZbpVmX
As you can see from the pen, box1, which starts outside the mask element (clip) should cross through it when animated, but it never appears. Moreover, box2, which should move out of the clipping area, remains visible.
This example seems to do a similar thing and has no problems: http://svg.dabbles.info/snaptut-masks2
Here's the code from codepen:
var t = Snap('#target')
var clip=t.rect(200,200,200,200).attr({fill:'#fff'})
var box1=t.rect(300,100,50,50).attr({fill:'#000'})
var box2=t.rect(300,300,50,50).attr({fill:'#000'})
var boxgroup=t.group(box1,box2)
boxgroup.attr({mask:clip})
boxgroup.animate({transform:'t100,300'},2000)
I notice that the svg.dabbles examples translates the clip region by 0,0 at one point, but adding something like that doesn't seem to get me anywhere.
Ok, I figured this out thanks in part to this really great article about SVG transforms: http://sarasoueidan.com/blog/svg-transformations/
The upshot is that when I translate the box group, it takes the mask with it. This is a little confusing to me still - I guess the mask attribute is causing this somehow? Anyways, the solution is to apply an opposite translation to the mask to keep it in place. Check the pen to see it in action but basically I just had to add:
clip.animate({transform:'t-100,-300'},2000)
The tricky part of this is that you now need to synchronize the movement of the mask and the movement of the box group.
edit - I now demonstrate how synchronization can be achieved using snap's set.animate method on the codepen.

Adding c3.js padding without cutting off graph

This is in response to the following question, How to remove padding in c3.js?, where the answer that was provided solves this issue, but also raises another issue -- the buttons on the graph are cut off at the end --
How would I get there to be no padding and the buttons not to be cut off, for example, it should look like:
The dots are getting clipped off because of the clip-path set on the chart layer. You just have to remove it. You can use D3 for this, like so
d3.select(chart.element).select("." + c3.chart.internal.fn.CLASS.chart).attr("clip-path", null);
where chart is your C3 chart object
Fiddle - http://jsfiddle.net/zds67nh1/
However you most probably want the dots to appear above the axis layer. For that you need to detach and attach the chart layer (in SVG, the z-index is determined by the order - the last of the siblings come on top. So you have to basically move it to the end of the siblings list), like so
var chartLayer = d3.select(chart.element).select("." + c3.chart.internal.fn.CLASS.chart);
var chartLayerParentNode = chartLayer.node().parentNode;
var chartLayerNode = chartLayer.remove();
chartLayerParentNode.appendChild(chartLayerNode.node());
chartLayer.attr("clip-path", null);
Fidle - http://jsfiddle.net/7e1eL22f/

Fabric.js insert after group

I have rendered a complex canvas with several layers of Fabric.js Groups, PathGroups and Paths. Many of the elements are selectable and when they are selected they should be highlighted.
Right now I'm rendering all the possible highlights together with the foundation, before the selectable objects. Really what I would prefer is to render the highlight simply when someone clicks on a Group or Path. For this I would need to insert the highlight below the selection, so is there a way of inserting a Path before a Group or another way of doing this?
Please notice, I'm not looking for element.sendBackwards(true); because there is not always the same amount of elements that the highlight should be bellow.
I found out that it is possible to get the index of an element and move an element to a specific index! Problem solved.
var index = canvas.getObjects().indexOf(group1);
canvas.moveTo(group2, index);

missing segments in d3 when putting sunburst on top of pie

(first posted on google group but no response so assuming I should be posting this here).
Am trying to lay a sunburst (coloured arcs) on top of a pie (yellow and white segments).
Here is a js fiddle that shows the problem, the initial green segments are missing:
http://jsfiddle.net/qyCkB/1/:
and a js fiddle without the pie where all the segments are shown correctly:
http://jsfiddle.net/X3sRy/1/
I have checked the nodes variable after it has been created on this line:
var nodes = partition.nodes({'values': data});
and the values appear to be the same in both examples.
On checking the DOM, it is just not drawing the first few segments of the sunburst.
Should this work or is it not possible to put two different layouts on top of each other?
Is there a better approach to achieving the same thing?
Your second-data join is colliding with the first. Your first data-join is on "g.arc", so you should be adding G elements with the class "arc" (not "clock_arc"). Your second data-join is on "path", which is inadvertently selecting the path elements you added previously. Since your second data-join matches the previously-added elements, you're not entering all of the expected elements for the pie.
You need to disambiguate the sunburst path elements from the pie path elements. One way you could do this is to select by class rather than element type, so the second data-join becomes ".pie" rather than "path". Something like this:
var gClock = svg.selectAll(".clock")
.data(clockData)
.enter().append("g")
.attr("class", "clock");
var pathClock = gClock.append("path");
var pathPie = svg.selectAll(".pie")
.data(pieData)
.enter().append("path")
.attr("class", "pie");
I'd also recommend reading these tutorials, if you haven't already: Thinking with Joins, Nested Selections, Object Constancy.

Categories

Resources