How to extract data <d> in svg through javascript - javascript

I wrote an icon component through reactjs to parse the svg files. I use storybook to show my icon component. Now I need help for writing a command line to parse the svg file to the component. I need to script the element in in a svg file and I have no idea how to achieve it.
I am planning to write it in javascript. And here is one example of my svg files.
<svg viewBox="0 0 1024 1024" p-id="3378" width="200" height="200">
<path d="..." p-id="3379"></path>
</svg>
May anyone gives me some ideas on how to achieve it. I am bad at extracting data from a file.

For the specific question from the title, use the following JS code:
document.querySelector("object")
.contentDocument.querySelectorAll("path[path-id='3379']")[0].getAttribute("d")
The SVG should be referenced using the object element (replace width/height attribute content with proper values):
<object
type="image/svg+xml"
data="./logo.svg"
width="480"
height="240"
></object>
It is assumed that there is a single object element in your html. Otherwise tag them with an id attribute and use #<the_id_goes_here> in the first selector:
document.querySelector("#<the_id_goes_here>")
.contentDocument.querySelectorAll("path[path-id='3379']")[0].getAttribute("d")

Related

Pupeteer generate non tagged SVG path elements in PDF

I generate a PDF from HTML page sent to pupeteer in small nodeJs app. The generation is ok.
My goal is to make that PDF pass the WCAG2 "PAC 2021" testing tool (https://pdfua.foundation/en/pdf-accessibility-checker-pac).
So I had tagged every elements of my html page from WCAG2 specifications.
But it seems that the <path> tag of each SVG raise an error as "non tagged item". As pupeteer generate SVG for many elements (like borders) and also as I want to print highcharts graph, it is a real problem that makes crash the validation of the tool.
So I tried to tag every path object in my HTML page and I also tagged the parent SVG like this :
<svg focusable="false" role="img" aria-describedby="desc_svg" aria-labelledby="title_svg" width="335" height="335" viewBox="0 0 335 335" fill="none" xmlns="http://www.w3.org/2000/svg">
<title id="title_svg">The title of the SVG</title>
<desc id="desc_svg">The description of the SVG</desc>
<path aria-hidden="true" role="presentation" fill-rule="evenodd" clip-rule="evenodd" d="M131" fill="#2E404F"/>
</svg>
I tried to make the SVG compliant by folowing these guidelines :
https://css-tricks.com/accessible-svgs/#aa-2-inline-svg
https://a11y-guidelines.orange.com/en/articles/accessible-svg/
https://www.smashingmagazine.com/2021/05/accessible-svg-patterns-comparison/
Nothing seems to work, accessibility error is still poping on these tagged items.
Is anybody faced the same problem ?

Can JavaScript function outside of the [CDATA[ tag?

From what I read, JavaScript within an SVG must be put into a [CDATA[ tag (the type designation is apparently now optional):
<script type="application/javascript">
<![CDATA[
(JavaScipt stuff here)
]]>
</script>
However, the following markup/code works without that tag even though it looks like JavaScript methods are being used:
<svg width="400px" height="400px" viewBox="0 0 400 400">
<rect id="rect1" x="160" y="10" width="60" height="60" fill="blue"
onmouseenter="evt.target.setAttribute('fill', 'red');"
onmouseout="evt.target.setAttribute('x', '0');"
/>
</svg>
So, are the evt.target.setattribute commands all SVG? I know this is a super newbie question...but I am having a hard time establishing where SVG ends and JavaScript begins. Documentation is very sketchy on the delineation, and I want to learn the total extent of what I can do in SVG before needing to learn another language. Thanks much for any clarification. And if anyone knows of a reference that is very clear on the subject, I'd love to know.
A CDATA section is a feature of XML documents. It's not part of html. You seem to be using SVG in html given that your SVG example has not namespaces so CDATA is neither required nor useful there.
In standalone SVG you need namespaces defined i.e. xmlns="http://www.w3.org/2000/svg" and there you need CDATA to prevent various characters in javascript e.g. < being interpreted as the beginning of a tag. Other characters are problematic too.

Multiple svg with same IDs

Can i put multiple svgs in a html page and use the same IDs in all of them?
<div>
<svg height="0" width="0">
<clipPath id="svgPath"> ........
</svg>
<svg height="0" width="0">
<clipPath id="svgPath"> ........
</svg>
<svg height="0" width="0">
<clipPath id="svgPath"> ........
</svg>
</div>
Since the specs define the id attribute as unique per document, you should refactor the IDs or use an alternative, e.g. embedding via img or object tag.
<img src="my.svg" height="100" alt="alternative Text">
<object type="image/svg+xml" data="my.svg" width="100" height="100"></object>
If you need the SVGs to be inline you should consider using an SVG injector, which changes the IDs to unique strings when inserting the SVGs into the HTML document
SVGInject adds a random string to the end of the ID for elements defined in the <defs> section. For example, svgPath may become something like svgPath-Dcs83KsE. Other SVG injectors add a running number to the ID.
Both methods were developed so the same SVG can be injected multiple times into a HTML document without creating an ID conflict. But of course it also works for different SVGs with conflicting IDs.
You can't write multiple id attribute in your html. Id attribute must be unique in html document.
The id attribute specifies its element's unique identifier (ID). The value must be unique amongst all the IDs in the element's.
https://www.w3.org/TR/2011/WD-html5-20110525/elements.html#the-id-attribute
You need to use class attribute for your purpose.

How to setup data binding to an SVG image using knockout.js?

I'm trying to get a click event on a SVG to fire using knockout.js:
HTML
<img id="the-image" src="img/image.svg" data-bind="????????" />
SVG
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect x="100" fill="#707070"
width="20"
height="200"
data-bind="click: $root.open" />
</svg>
this doesn't work if the SVG file is given as source for the img element, it does however work if I just paste it into the img element.
Is there a way to setup the binding so that the data-context is accessible for the SVG?
SVG elements are not added to the DOM when you use an img element to display the image, therefore knockout.js is unable to bind to those elements. The answers to this question contain some solutions that might help you: How do you access the contents of an SVG file in an <img> element?.

Confused about SVG styling with d3.js

The most d3.js examples use SVG to draw the diagrams, etc. This means for instance rect instead of div. This then again means, that CSS properties like drop-shadow cannot be applied.
The alternative approach is to define filters in <defs>. The same is true if you want to fill the rect with a gradient color. Is that right so far?
So I define some filter and gradients, but it seems very redundant to redefine these definitions for every page again. Wouldn't it be possible to reference all these definitions from a separate svg-file?
I tried things like: filter: url(.../my_file.svg) but it does not seem to work, but isn't that how it's supposed to be?
Say you have a file called filters.svg, and it contains a few filter defitions. It looks something like this:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<filter id="my_filter" x="0%" y="0%" width="100%" height="100%">
...
</filter>
</svg>
If you were using my_filter in that same document, you'd just refer to it using #my_filter. But you're not. You want to use it in another document. What you have to do then is refer to it in those documents as /filters.svg#my_filter. Like this:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="0" y="0" width="100" height="100" fill="url(/filters.svg#my_filter)" />
</svg>
This is of course assuming that both documents are accessible from the same domain, and that they're located in the right places, etc. I don't know if this will work in CSS stylesheets, but it will work across SVG documents. Check out the section on Linking in the SVG Specification for more details.

Categories

Resources