Linking to SVG templates in external files - html

I'm using the yFiles for HTML chart library, which supports rendering nodes using SVG templates. According to the documentation, this is done by embedding a special <script> tag in the main HTML file with somewhat SVG elements in it (without the enclosing <svg> container).
<script type="text/yfiles-template">
<g id="expand_icon" transform="translate(21 6)">
<polygon stroke="#FFFFFF" stroke-width="3" fill="none"
points="6,17 6,12 1,12 1,6 6,6 6,1 12,1 12,6 17,6 17,12 12,12 12,17"/>
</g>
</script>
The problem is that putting all my templates in the main HTML file is messy, and I would rather split them into several external SVG files. However, if I simply copy the <script>'s contents into an external file and try changing the script tag like this:
<script type="text/yfiles-template" src="images/nodeTemplates.svg"></script>
doesn't seem to work. No error is displayed, but my templates aren't shown.
I can't find anything else in the docs about it, and it's entirely possible that it's hardcoded to look for it in the main HTML, but I was wondering if anyone managed to get it to read the templates from an external file.

I suggest you use the StringTemplateNodeStyle where you just pass the svg snippet as a string to the style. You can then use your own loading mechanism to retrieve the snippets.
Note that if you don't need all the data binding features of the TemplateNodeStyle, but just want to dynamically include an svg file as an image, you can just as well use the ImageNodeStyle and point it directly to your SVG resource. Alternatively implementing your own style as shown in the custom style tutorial is also a very feasible and flexible solution.

The node has and image property you can use for a valid .svg file aka:
<svg height="100" width="100">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
The above will give you the ability to put each svg in a different .svg file.

Related

How can I set the "preserveAspectRatio" attribute in a nested SVG?

We have a server generated SVG which cannot be modified and which needs to be displayed nested inside of another, larger, SVG.
It is necessary to modify the "preserveAspectRatio" attribute of the contained (inner) SVG to
preserveAspectRatio="none"
for it to display correctly.
The current approach is to define the nested SVG inside of a DEFS tag as follows:
<defs>
<svg id="serverSetID"
viewBox="0 0 200 200"
>
svg content here
</svg>
</defs>
and then reference it as follows:
<use
xlink:href="#serverSetID#svgView(preserveAspectRatio(none))"
x="0"
y="0"
width="200"
height="200"
/>
Note: the nested SVG has a server generated ID attribute that is unique for that page.
If I leave out the "#svgView(preserveAspectRatio(none))" then it displays although not the way I want it to.
But if I include "#svgView(preserveAspectRatio(none))" then it does not display at all.
I have looked into other strategies such as directly including the code of the inner SVG within the body of the outer SVG without using the DEFS tag. But the problem with that strategy is that there does not appear to be a way to manipulate the "preserveAspectRatio" attribute since, as far as I can tell by experimentation and research, that attribute is not exposed to CSS in an SVG.
We are anxious NOT to use JavaScript for this because the page already has a LOT of very complex JS and we are trying to pare it down where possible.
Does anybody have any suggestions please?
PS. If I overlooked something (highly likely) or if "preserveAspectRatio" is indeed manipulable by CSS I will be humbly grateful for somebody to point out my error.

How to use the whole SVG with a <use> tag?

I have an SVG file freshly exported from Figma.
I don't want to inline it because it's used on multiple places.
I can't specify it as <img src="..."> because I need to style its parts.
So, I tried to include it like this:
<svg>
<use xlink:href="http://example.com/myshape.svg"></use>
</svg>
But it doesn't work. MDN states:
The <use> element takes nodes from within the SVG document, and duplicates them somewhere else.
It takes nodes from the document. With SVG sprites, you have <symbol> tags with id attributes and you reference them with <use> by adding xlink:href="mysprite.svg#symbolid". However, here I need to use the whole document, I.E. the root node. Is there a way to do that?
It would also be great if I don't have to edit the source SVG file, as it's uploaded via an admin panel by the user. It's just a file exported from any vector graphics program.
SVG 2 (when implemented in browsers) will allow to reference another SVG file without any fragment identifier:
New in SVG 2: An href without a fragment allows an entire SVG document to be referenced without having to ensure that it has an ID on its root element.
Before:
<!-- my-vector.svg -->
<svg id="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<circle r="10" cx="12" cy="12" />
</svg>
<use href="my-vector.svg#icon"></use>
After (there will be no need to define id="..." on the svg):
<!-- my-vector.svg -->
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<circle r="10" cx="12" cy="12" />
</svg>
<use href="my-vector.svg"></use>
SVG 2 seems to be in the process of development in major browsers (see this Chrome feature and specifically this Chromium issue: Issue 366545: [SVG2] Allow to reference entire files).

Most efficient way to add inline SVG?

I have a webpage with lots of SVG icons that will be in the HTML. Rather than include them as an IMG tag and possibly slow the page with those HTTP requests, I'm placing the SVG code like this:
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="9" viewBox="0 0 9 9"><path fill="#C5C2BD" fill-rule="nonzero" d="M4.5 3.435L1.286.22A...LOTS OF CODE HERE..."/></svg>
Note: where it says "lots of code here", there is a huge string of numbers/letters that make up the path for this SVG.
The issue this creates is it's very ugly when not easily maintainable in the HTML (to the point where my editor bogs own because these SVG strings are so long).
Is there a cleaner, simpler way to include these SVG icons in my HTML while still eliminating the extra HTTP requests?
Thanks for your time.
The most proven way is to collect all the icons SVG in one file - the sprite SVG
Creating a Sprite and connecting it to HTML
The action plan is as follows:
Creating a Sprite
Connecting it to HTML
Calling SVG images from the sprite
Styling icons
Creating a Sprite
The main task of the sprite is to be a repository for icons that before the call to a specific place HTML pages should be invisible.
To do this,the code for each icon is wrapped with <symbol id =" .. "> ... </ symbol> tags with a unique identifier, which will be followed by the <use>
Template Sprite:
<div id="container">
<svg version="1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 126 126" >
<symbol id="picasa">
<path d="M113.5 57.... 72.8z" />
</symbol>
<symbol id="wordpress" viewBox="0 0 126 126">
<path stroke ="black" d="M113.5 57.7l-8.5-11.4 .. 86.1 62.9z"/>
</symbol>
<symbol id="twitter">
<path d="M113.5 57.6l-8.5-11.4.... 7.4-2.4V85.4z"/>
</symbol>
<symbol id="apple">
<path d="M113.5 57.7l-8.5-11.4... 78.5 78.7 82z"/>
</symbol>
</div>
As you can see, all <path> attributes are removed for later styling of icons from an external CSS file.
Adding a sprite file to HTML
There are several ways to add SVG files to HTML, but the most reliable way is to add it using the <object>
<object type="image/svg+xml" data="Sprite.svg" width="200" height="200">
Your browser does not support SVG
</object>
Adding icons from the sprite
<div id="container">
<svg viewBox="0 0 126 126" >
<use xlink:href="#apple"></use>
</svg>
</div>
The viewBox attributes should be like thesvg icon or change the scaling inside HTML if necessary.
Icons as links
For this, in SVG, unlike HTML, its own form of record
<svg viewBox="0 0 126 126" >
<a xlink:href="https://www.apple.com/ru/"><use xlink:href="#apple"></use></a>
</svg>
Styling icons
When using the <use> command, the icon falls into the shadow DOM and its attributes behave strangely, - there is an icon of the icon, but it can not be controlled from the outside.
In addition, the icon attributes for example: style = "fill: gray; stroke: crimson;" have the highest priority. Therefore, we deleted these attributes. see the example of the sprite above.
To solve the problem of inheritance of parental properties by objects in shadow DOM, you must use forced inheritance
svg path{
fill:inherit;
stroke:inherit;
}
and then to the icons you can already apply CSS rules from the external table
svg path:hover{fill:yellow;}
#picasa{fill:black;}
#apple{fill:purple;}
#twitter{fill:black;}
#wordpress{fill:blue;}
If you go for the first time along this path, then inevitably there will be many questions.
Ask, do not be shy.
All sooner or later it turned out to be done and customized sprite.
The main recommendation is to do everything yourself manually for the first time, to understand how it is arranged, and then you can already openly use special utilities to automatically create sprites.
You should convert all your .svg files to one font file, here is how:
How to convert .svg files to a font?

How to <use> the <svg> element correctly for loading external sources?

I've followed many guides to adding external SVGs to a page... like this one : http://wearejh.com/design/inline-svg-use-element/
The code is like this:
<svg>
<use xlink:href="https://upload.wikimedia.org/wikipedia/commons/5/53/Skull_and_crossbones.svg"></use>
</svg>
It just does not load, example here: http://jsbin.com/cipacitovo/edit?html,output
What am I doing wrong?
Per the SVG specification
Unlike ‘image’, the ‘use’ element cannot reference entire files.
You need to add a fragment identifier to the URL to indicate which item within the image you are trying to display.
Why dont you use svg in img tag.Because you are not generating anything instead you are loading.
Check the example
You forgot to add xmlns:xlink="http://www.w3.org/1999/xlink" in <svg>.
This is how it should be:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="https://upload.wikimedia.org/wikipedia/commons/5/53/Skull_and_crossbones.svg"></use>
</svg>

How to create hoverstates with svg <use> tag

So I recently found this svg technique on csstricks and decided to use it in conjunction with the grunt task grunt-svgstore. I thought this was the perfect thing since you have access to the actual svg with css and javascript without pasting the whole svg code in the html. But I found one major problem I can't solve which is hoverstates (and similar). The problem is the following. If that's my html body (with the svg on top)
<body>
<svg>
<symbol id="arrow">
<path ... />
</symbol>
</svg>
<svg id="icon-arrow">
<use xlink:href="#arrow"></use>
</svg>
</body>
I can access the #icon-arrow svg or the #arrow symbol but neither will give me the ability to create a hoverstate. When doing #icon-arrow I can get a hoverstate but I can't access the actual shape because it is not actually a child of the #icon-arrow so doing #icon-arrow #arrow:hover won't work. On the other hand directly selecting the shape doesn't work because the shape is not actually there but it's only a reference. Is it actually possible to do hoverstates using this technique? Or are there any other solutions?