d3 selection merge with multiple elements - javascript

I want to update a circle and text element at the same time. I was able to make it work with only the circle:
https://plnkr.co/edit/FckQcVd1EkYLoZggmJN4
However, when I try adding a wrapping g to contain the circle and text it doesn't update properly.
https://plnkr.co/edit/EtL11O5qQph0xAeu88mu?p=preview
Any insight how to fix it?

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.

Javascript, textarea, best way to detect line been changed

I'm trying to make something like adding WYSIWYG editing sigins on images.
So, I got textarea for text. I generate (in real time) <svg> text there. Text can be inside <svg><rect>. On every line break its a new line and new <rect>. I set rect size (witdth, height) depends on what returns text.getBBox() function, storing data about each rect sizes in some array by index.
Now, if I change some text in middle line, i want to change size of rectangle where this text is placed.
How should i detect, which line has been changed by it size?
Ofc I can store old textarea data, compare with changed data every time on textinput, find changed line etc but seems like its a bad solution
UPD:
I assume there is workaround to redraw ALL text I got in <textarea>, line by line, every time it changes, but it looks like not good solution too

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.

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);

d3 venn diagram labels layering

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.

Categories

Resources