Nested g vs svg - d3.js

I'm building out some responsive SVG-based components (based around Backbone views). The convention I'm using is that when a component is created, it is provided with a DOM element to render itself into. When rendering, the component checks the size of the DOM element and fills the entire available space.
I was using g elements, but they don't have their own width and height; they just match their contents. So I made a hack where I would append a rect that was the size I needed. This works pretty well, but it is hacky.
Today I discovered that svg elements can be nested just like g, but they're also able to have their own width and height. I just tested it out and it seems to work great. Are there any downsides I'm missing creating a bunch of nested svg elements like this?

No. There shouldn't be any downsides to using nested <svg> elements. But your description of what you are doing is rather vague, so I can't guarantee that you won't strike any in your particular use case.

Related

Connected text bubbles in D3.js?

How would I create such a view in D3.js -- a central node with self-positioning outer bubbles, all containing text? I'm browsing their gallery but haven't found anything specifically like this. I understand it's good StackOverflow practice to show what one already tried, but I just don't know with which model I'm supposed to start; I played around with a Force Directed Tree with really big radii but it doesn't seem super appropriate.
PS: Icing on the cake would be to have the following connection descriptors as well, but I can also do without. Thanks!
I agree with the suggestion to extend the force-directed graph demo. Here's a quick and dirty fork of that example: https://observablehq.com/#yousefamar/connected-text-bubbles
The text in each bubble is a foreignObject for flexibility, since I found it easier to put a p in the bubbles than svg text. This way you can also use overflow scrolling if there's too much text. pointer-events: none is so that the text can't be selected, and so that you can therefore drag the bubble through the text.
There is probably a lot you can improve there too, e.g. in order to create a gap in the lines, I put a white rect behind the text, but it's an arbitrary width. I remember however that there is some getComputedTextLength function to get the exact width of the label text, which is probably better.

Multiple SVGs interaction performance

Does SVG performance degrade with the number of separate SVG elements in the DOM ?
I would like the draw a whole bunch of little SVG images which will not need any interaction, but I also have one "main" SVG which will need interaction. As I add more non-interactive SVGs, will the performance of the main one get worse ?
OK I made two SVGs, one with hundreds of elements and one with nothing. Interaction with the blank SVG was noticeably slow when the 2nd SVG was in the DOM, even if it was hidden.

Benefits of using SVG 'use' tag [duplicate]

Assuming a relatively modern, SVG-supporting desktop browser and an SVG consisting of hundreds of similar, simple nodes:
The document could be set up as many individual shape elements (<circle>, <line>, etc.) with their own attributes defined.
The document could be set up as a few <symbol> elements and many individual <use> instances that place them and size them appropriately (W3 spec).
I understand the semantic and code-maintenance reasons to use <symbols>/<use>, but I'm not concerned with those now, I'm strictly trying to optimize rendering, transformation and DOM update performance. I could see <symbol> working similar to reusing sprites in Flash, conserving memory and being generally a good practice. However, I'd be surprised if browser vendors have been thinking this way (and this isn't really the intent of the feature).
Edit: I am not expecting the base symbols to be changed or added to over the life-cycle of the SVG, only the instance locations, sizes, etc
Are there any clear patterns to <symbol>/<use> performance?
How idiosyncratic is it to individual browser implementations?
Are there differences between reusing <symbol> vs <g> vs nested <svg>?
Rohit Kalkur compared rendering speed of the creation of 5000 SVG symbols using use against directly creating the SVG symbol's shapes, see here. It turns out that rendering SVG shapes using use was almost 50% slower. He reasons that:
The use element takes nodes from within the SVG document, and
duplicates them in a non-exposed DOM
Given this, I assume that using SVG symbols is at best as performant as manually creating the symbolss shape.
I would advise you to not nest <use> elements deeply. That is known to cause slowdowns in most browsers, see here and here.
In the general case though it should be fast, at least as long as the template itself isn't changed much (since if you do then each of the instances need to be updated too, and each of them can differ from the rest due to CSS inheritance).
Between <svg> and <symbol> there isn't that big of a difference on a functional level, they both allow you to define a coordinate system (via the 'viewBox' attribute). A <g> element doesn't let you do that. Note that <symbol> elements are invisible unless referenced by a <use>, whereas <svg> and <g> are both visible per default. However, in most cases it's advisable to make the template be a child of a <defs> element.
If you change the contents of a g or svg element then a UI can look at the area the old contents were drawn in and where the update will be drawn to and simply redraw those two areas, even redraw only once if they are the same e.g. changing the colour of a shape.
If you update the contents of a symbol then all the instances must be redrawn. It's harder to do that by calculating for each instance where the old and new parts to redraw are as the areas may be affected by transforms and simpler to just redraw all parts of all instances. Some browsers may do the former and some the latter.
In either case, a UI must at a minimum track the changes in the symbol and propagate those changes to all the instances. That's more than likely to have some overhead.
Of course, if you're just moving individual symbol instances and the contents are static then no tracking is required and performance is likely to be similar.

Why is each boxplot in d3.box placed in its own svg element?

At the risk of asking a silly question, why is each boxplot in d3.box (code and demo) placed in its own svg element? (more generally, placed in its own container element.) Or to put the question another way, why does d3.box only render one component of a chart, rather than all components of a chart? (given that each boxplot is likely to share a common y axis.)
Thanks in advance for any suggestions. I'm sure there's a sensible rationale for this; it's just not clear to me!
Technically, there is no reason to put everything into its own SVG. I don't know why it was done like this in the example, but usually you would have everything in a single SVG and group elements using svg:g elements.
The reason that most d3 components usually only do one thing is that is makes it easier to combine them. If, for example, d3.box rendered x and y axes (or just one of them), you would have to provide options for people who wanted no axes, or a different axis layout, or anything else that isn't covered by how the implementer designed it.
If you're looking for something more high-level that takes care of everything, check out nvd3.js.

Does reusing symbols improve SVG performance?

Assuming a relatively modern, SVG-supporting desktop browser and an SVG consisting of hundreds of similar, simple nodes:
The document could be set up as many individual shape elements (<circle>, <line>, etc.) with their own attributes defined.
The document could be set up as a few <symbol> elements and many individual <use> instances that place them and size them appropriately (W3 spec).
I understand the semantic and code-maintenance reasons to use <symbols>/<use>, but I'm not concerned with those now, I'm strictly trying to optimize rendering, transformation and DOM update performance. I could see <symbol> working similar to reusing sprites in Flash, conserving memory and being generally a good practice. However, I'd be surprised if browser vendors have been thinking this way (and this isn't really the intent of the feature).
Edit: I am not expecting the base symbols to be changed or added to over the life-cycle of the SVG, only the instance locations, sizes, etc
Are there any clear patterns to <symbol>/<use> performance?
How idiosyncratic is it to individual browser implementations?
Are there differences between reusing <symbol> vs <g> vs nested <svg>?
Rohit Kalkur compared rendering speed of the creation of 5000 SVG symbols using use against directly creating the SVG symbol's shapes, see here. It turns out that rendering SVG shapes using use was almost 50% slower. He reasons that:
The use element takes nodes from within the SVG document, and
duplicates them in a non-exposed DOM
Given this, I assume that using SVG symbols is at best as performant as manually creating the symbolss shape.
I would advise you to not nest <use> elements deeply. That is known to cause slowdowns in most browsers, see here and here.
In the general case though it should be fast, at least as long as the template itself isn't changed much (since if you do then each of the instances need to be updated too, and each of them can differ from the rest due to CSS inheritance).
Between <svg> and <symbol> there isn't that big of a difference on a functional level, they both allow you to define a coordinate system (via the 'viewBox' attribute). A <g> element doesn't let you do that. Note that <symbol> elements are invisible unless referenced by a <use>, whereas <svg> and <g> are both visible per default. However, in most cases it's advisable to make the template be a child of a <defs> element.
If you change the contents of a g or svg element then a UI can look at the area the old contents were drawn in and where the update will be drawn to and simply redraw those two areas, even redraw only once if they are the same e.g. changing the colour of a shape.
If you update the contents of a symbol then all the instances must be redrawn. It's harder to do that by calculating for each instance where the old and new parts to redraw are as the areas may be affected by transforms and simpler to just redraw all parts of all instances. Some browsers may do the former and some the latter.
In either case, a UI must at a minimum track the changes in the symbol and propagate those changes to all the instances. That's more than likely to have some overhead.
Of course, if you're just moving individual symbol instances and the contents are static then no tracking is required and performance is likely to be similar.

Resources