Use element from response text in JS code - javascript

I do some logic to get file content.
I have SVG file and I need to read file in code
I do this by using $.ajax() function
$.ajax({
method: 'get',
url: shapes.svg,
dataType: 'html'
}).then(function (value) {
// HTML code from SVG file.
console.log(value);
});
The problem starts here...
Now I have plain text and I need document in order to be able to use JS functions.
I need exactly getBBox()
So, I want to use something like document.createElment() but it only accepts HTML tag name not all element with its attributes.
below is part of the response from SVG file
<svg x="0" y="0" width="2200" height="2200" version="1.1" xmlns="http://www.w3.org/2000/svg" id="svgimportshapes" xlink="http://www.w3.org/1999/xlink">
<g xmlns="http://www.w3.org/2000/svg" data-paper-data=""unlocked"" id="ShapeLayer" fill="none" fill-rule="nonzero" stroke="none" stroke-width="none" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal">
<text x="1018.68119" y="511.99246" id="text" fill="#000000" stroke="none" stroke-width="1" font-family="helvetica" font-weight="normal" font-size="18" text-anchor="start">Parterre places debout</text>
</svg>

You need to add it to DOM first in order to get the bounding box. Below example uses a temp div which is offset -10000px left of the screen, svg is added there and getBBox() returns the value. Remove the element after you get the bbox. It's not an optimal solution but you get the idea.
$(document).ready(function(){
var svgstr= '<svg x="0" y="0" width="2200" height="2200" version="1.1" xmlns="http://www.w3.org/2000/svg" id="svgimportshapes" xlink="http://www.w3.org/1999/xlink"> <g xmlns="http://www.w3.org/2000/svg" data-paper-data=""unlocked"" id="ShapeLayer" fill="none" fill-rule="nonzero" stroke="none" stroke-width="none" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"> <text x="1018.68119" y="511.99246" id="text" fill="#000000" stroke="none" stroke-width="1" font-family="helvetica" font-weight="normal" font-size="18" text-anchor="start">Parterre places debout</text> </svg>'
var svgElement = $(svgstr)
$("#temp").append(svgElement)
var bbox = svgElement[0].getBBox()
svgElement.remove()
console.log(bbox)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="temp" style="position:absolute;left:-10000px"></div>

Related

My SVG elements are not clickable anymore with Firefox Quantum 67.0

I have an SVG file. There are elements that can be clicked and can call functions from a JavaScript file when clicked. It works perfectly with Google Chrome, IE and earlier versions of Firefox. But I cannot make it work with Firefox 67 or later.
I have already tried to change my onmousedown function to onclick. I have found a website to view my SVG file. It also works fine.
Here is some code:
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
height="106.892mm"
viewBox="0 0 1370.4 484.8"
width="302.154mm">
<g fill="none" fill-rule="evenodd" stroke="black" stroke-linecap="square"
stroke-linejoin="bevel"
stroke-width="1">
<g clip-path="url(#clip464)" cursor="pointer" fill="green" fill-opacity="1"
onmousedown="parent.OpenPane('mGraph');"
opacity="1"
stroke="none"
stroke-opacity="0"
transform="matrix(1,0,0,1,392,262)">
<path d="M0,0 L30,0 L30,32 L0,32 L0,0 z" fill-rule="evenodd" vector-effect="none"/>
</g>
</g>
</svg>
edit1: you can find a spesific code script on this site -> JSFiddle link!
It works with Google Chrome as expected, but not with Firefox v-69.
You have a clip-path that does not exist: clip-path="url(#clip464)"
There is no element with id clip464 in your example.
This is a known bug but you can work around it easily by removing the useless attribute.
I'm not sure you can reference any JS outside the SVG. I tried your code on Chrome. Including all JS code inside the SVG works as expected.
Alternatively, you can also attach event listeners from outside the SVG. Check out the code below:
All JS inside the SVG
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
height="106.892mm"
viewBox="0 0 1370.4 484.8"
width="302.154mm">
<script type="text/ecmascript"><![CDATA[
function OpenPane(str) {
alert(str);
}
]]>
</script>
<g fill="none" fill-rule="evenodd" stroke="black" stroke-linecap="square"
stroke-linejoin="bevel"
stroke-width="1">
<g clip-path="url(#clip464)" cursor="pointer" fill="green" fill-opacity="1"
onmousedown="OpenPane('mGraph');"
opacity="1"
stroke="none"
stroke-opacity="0"
transform="matrix(1,0,0,1,392,262)">
<path d="M0,0 L30,0 L30,32 L0,32 L0,0 z" fill-rule="evenodd" vector-effect="none"/>
</g>
</g>
</svg>
JS outside SVG
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
height="106.892mm"
viewBox="0 0 1370.4 484.8"
width="302.154mm">
<g fill="none" fill-rule="evenodd" stroke="black" stroke-linecap="square"
stroke-linejoin="bevel"
stroke-width="1">
<g clip-path="url(#clip464)" cursor="pointer" fill="green" fill-opacity="1"
id="sample-id"
opacity="1"
stroke="none"
stroke-opacity="0"
transform="matrix(1,0,0,1,392,262)">
<path d="M0,0 L30,0 L30,32 L0,32 L0,0 z" fill-rule="evenodd" vector-effect="none"/>
</g>
</g>
</svg>
<script type="text/ecmascript">
const el = document.getElementById('sample-id');
el.addEventListener('click', () => {
document.getElementById('sample-id').setAttribute('fill', 'red');
});
el.addEventListener('mouseleave', () => {
document.getElementById('sample-id').setAttribute('fill', 'green');
});
</script>
JSFiddle

CSS style addition has stopped javascript function from working

I created this javascript function to change the colour of guitar string in an SVG. Originally, the SVG had 'stroke' colours defined in the markup and at that point the function worked, so that when I pressed the button, the colour of the string 'e-low' changed.
However, I decided I wanted to add CSS default style to the stroke colour (which you can see at the stop of the code) because I intend to have functionality so that when the button is pressed a second time, the colour returns to the default colour defined in the style section. Since I've added this, and changed the colour in the SVG to 'None', the javascript function has stopped working and the colour doesn't change whatsoever, and I don't know why.
Before I added the css style element
function svgMod() {
var s = document.getElementById("e-low");
s.setAttribute("stroke", "#000000");
}
#e-string,
#b-string,
#g-string,
#d-string,
#a-string,
#e-low {
stroke: #adad8b;
}
<svg xmlns="http://www.w3.org/2000/svg" ......... <path id="e-string" stroke="none" fill="none" stroke-width="2" d="M502.583,13.046v411.966" />
<path id="b-string" stroke="none" fill="none" stroke-width="2.5" d="M472.366,13.046v411.966" />
<path id="g-string" stroke="none" fill="none" stroke-width="3" d="M440.134,13.046v411.966" />
<path id="d-string" stroke="none" fill="none" stroke-width="3.3" d="M405.887,13.046v411.966" />
<path id="a-string" stroke="none" fill="none" stroke-width="3.5" d="M373.655,13.042v411.965" />
<path id="e-low" stroke="none" fill="none" stroke-width="4" d="M341.423,13.046v411.966" />
</svg>
<button class="btn" onclick="svgMod(); return false;">Test 1</button>
Make sure you have the right viewBox and a proper sizing for the SVG element, I just added a random viewBox to see the guitar strings.
You can read more about viewBox in this link
The viewBox attribute allows you to specify that a given set of
graphics stretch to fit a particular container element.
Also as #CBroe mentioned using s.style.stroke = '#000000' fits better to modify the styles of a element.
function svgMod() {
var s = document.getElementById("e-low");
s.style.stroke = "#000000";
}
#e-string,
#b-string,
#g-string,
#d-string,
#a-string,
#e-low {
stroke: #adad8b;
}
<svg xmlns="http://www.w3.org/2000/svg" width="210" viewBox="0 0 600 600">
<path id="e-string" stroke="none" fill="none" stroke-width="2" d="M502.583,13.046v411.966"/>
<path id="b-string" stroke="none" fill="none" stroke-width="2.5" d="M472.366,13.046v411.966"/>
<path id="g-string" stroke="none" fill="none" stroke-width="3" d="M440.134,13.046v411.966"/>
<path id="d-string" stroke="none" fill="none" stroke-width="3.3" d="M405.887,13.046v411.966"/>
<path id="a-string" stroke="none" fill="none" stroke-width="3.5" d="M373.655,13.042v411.965"/>
<path id="e-low" stroke="none" fill="none" stroke-width="4" d="M341.423,13.046v411.966"/>
</svg>
<button class="btn" onclick="svgMod(); return false;">Test 1</button>

SVG tooltip disappears immediately

I've got a map with several regions and want to show a tooltip with its name when hovering over it.
The tooltip will display but disappears immediately. It doesn't matter where I put the tooltip (g, a or polygon), but I believe the g-node is the right place.
Example with three circles:
https://codepen.io/suntrop/pen/BmLZzN
<svg width="246px" height="64px" viewBox="0 0 246 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
<desc>Created with Sketch.</desc>
<defs></defs>
<g class="testtooltip" title="My Tooltip" id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="Oval" fill="#D8D8D8" cx="32" cy="32" r="32"></circle>
</g>
<g class="testtooltip" title="Will Show" id="Page-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="Oval" fill="#B8E986" cx="123" cy="32" r="32"></circle>
</g>
<g class="testtooltip" title="And Hide" id="Page-3" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="Oval" fill="#D8D8D8" cx="214" cy="32" r="32"></circle>
</g>
</svg>
The JS
$(function() {
UIkit.tooltip('.testtooltip').show();
});
When I use the tooltip on a P or IMG element the tooltip stays while hovering the element.
Looks like UIkit doesn't support tooltips on SVG elements. To decide whether an open tooltip should remain open, UIkit regularly calls an isVisible() function which in turn reads the target element's offsetHeight. SVG elements don't have an offsetHeight: https://www.chromestatus.com/features/5724912467574784
Thus, UIkit thinks the element is hidden and immediately hides the tooltip too.

Use tag in svg's not working

I'm pretty new to SVG. I have set of icons created using SVG. I'm trying to use <use> tag to render a particular part of SVG. But everything goes in vain. Not able to figure out what's the mistake i'm doing. Here is the code which i tried and also refer the fiddle. You can see that overall svg is rendered, But trying to render particular part of the SVG failed. Any help will be appreciated
<svg width="303px" height="30px" viewBox="0 0 303 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Pivot" transform="translate(253.232000, 6.247500)">
<path d="M0.833,15.4105 L0.833,11.662 L3.7485,11.662 L3.7485,11.2455 L0.833,11.2455 L0.833,7.9135 L3.7485,7.9135 L3.7485,7.497 L0.833,7.497 L0.833,4.5815 L0,4.5815 L0,16.2435 L0.833,16.2435 L0.833,15.827 L3.7485,15.827 L3.7485,15.4105 L0.833,15.4105 Z M18.8036328,16.2435 L4.5815,16.2435 L4.5815,15.6124537 L8.7465,15.6124537 L8.7465,12.7095463 L4.5815,12.7095463 L4.5815,12.0785 L8.7465,12.0785 L8.7465,8.12804634 L4.5815,8.12804634 L4.5815,7.497 L8.7465,7.497 L8.7465,4.5815 L3.7485,4.5815 L3.7485,4.4408921e-16 L19.5755,4.4408921e-16 L19.5755,4.5815 L17.3516962,4.5815 L14.5775,4.5815 L14.5775,7.497 L18.7425,7.497 L18.7425,4.5815 L19.5755,4.5815 L19.5755,16.2435 L18.8036328,16.2435 Z M18.7425,15.6124537 L14.5775,15.6124537 L14.5775,12.7095463 L18.7425,12.7095463 L18.7425,15.6124537 Z M18.7425,12.0785 L14.5775,12.0785 L14.5775,8.12804634 L18.7425,8.12804634 L18.7425,12.0785 Z M13.7445,4.5815 L9.5795,4.5815 L9.5795,7.497 L13.7445,7.497 L13.7445,4.5815 Z M13.7445,8.12804634 L9.5795,8.12804634 L9.5795,12.0785 L13.7445,12.0785 L13.7445,8.12804634 Z M13.7445,12.7095463 L9.5795,12.7095463 L9.5795,15.6124537 L13.7445,15.6124537 L13.7445,12.7095463 Z M3.7485,4.5815 L4.5815,4.5815 L4.5815,16.2435 L3.7485,16.2435 L3.7485,4.5815 Z M0,3.7485 L3.7485,3.7485 L3.7485,4.165 L0,4.165 L0,3.7485 Z" id="Combined-Shape" fill="#AAAAAA"></path>
<rect id="Rectangle-324" fill="#FAC10C" x="0" y="3.7485" width="4.5815" height="12.495"></rect>
<rect id="Rectangle-324-Copy" fill="#FAC10C" transform="translate(11.733102, 2.290750) rotate(90.000000) translate(-11.733102, -2.290750) " x="9.44235203" y="-5.73533321" width="4.5815" height="16.0521664"></rect>
</g>
<g id="Filter" transform="translate(232.407000, 6.247500)">
<rect id="Rectangle-108" fill="#3BA3F8" x="4.73505679e-14" y="0" width="12.9115" height="1.2495"></rect>
<rect id="Rectangle-109" fill="#3BA3F8" x="4.73505679e-14" y="2.499" width="12.9115" height="1.2495"></rect>
<path d="M6.33160096,10.829 L6.45575,10.9678333 L6.57989904,10.829 L6.33160096,10.829 Z M4.8418125,9.163 L4.73505679e-14,3.7485 L12.9115,3.7485 L8.0696875,9.163 L4.8418125,9.163 Z" id="Combined-Shape" fill="#8EC9FB"></path>
<path d="M4.5815,9.163 L7.9135,9.163 L7.9135,18.326 L4.74601819,14.5516554 L4.5815,9.163 Z" id="Rectangle-111" fill="#8EC9FB"></path>
</g>
<g id="Sort" transform="translate(206.167500, 1.666000)">
<rect id="Rectangle-120" fill="#E2A364" x="10.829" y="4.165" width="2.0825" height="17.9095"></rect>
<path d="M15.5828281,14.5775 L17.1391718,15.7502891 L12.3853437,22.0588321 L10.829,20.886043 L15.5828281,14.5775 Z" id="Rectangle-121" fill="#E2A364"></path>
<text id="A" font-family="SFUIDisplay-Semibold, SF UI Display" font-size="11.902719" font-weight="500" letter-spacing="-0.107586779" fill="#19AF5C">
<tspan x="0.4165" y="11">A</tspan>
</text>
<text id="Z" font-family="SFUIDisplay-Semibold, SF UI Display" font-size="11.902719" font-weight="500" letter-spacing="-0.107586779" fill="#19AF5C">
<tspan x="0.4165" y="22.662">Z</tspan>
</text>
</g>
</svg>
<svg>
<use xlink:href="Pivot"></use>
</svg>
You want to know why the "Pivot" element is not showing up in your second SVG? Is that right?
The reason is because you are not referencing it correctly. You should have written:
<svg>
<use xlink:href="#Pivot"></use>
</svg>
Note the missing hash ("#") symbol.

SVG linking rect in different SVG files and animate them

I search everywhere and I didn't understand/found how to do what I want.
I Have 2 svg files who represent somes UML diagrams generated by Visual Paradigm for UML, they have similar objects. For exemple 'FileSource.svg' and 'FileDestination.svg', both of them have an object 'A' who is on differents positions for each.
I would like that when you click on 'A' in 'FileSource.svg' that return 'A' in 'FileDestination.svg' with an hightlight on 'A' to see where it's in the diagram 'FileDestination.svg.
Here is the jsfiddle : http://jsfiddle.net/jim987/rJk54/
But I don't find how to create 2 files with jsfiddle, so the linking part don't work..
First I tried to link the similar objects, there is the code for one object in diagram :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'>
<svg fill-opacity="0" xmlns:xlink="http://www.w3.org/1999/xlink" color-rendering="auto" color-interpolation="auto" stroke="rgb(0,0,0)" text-rendering="auto" stroke-linecap="square" width="1267" stroke-miterlimit="10" stroke-opacity="0" shape-rendering="auto" fill="rgb(0,0,0)" stroke-dasharray="none" font-weight="normal" stroke-width="1" height="626" xmlns="http://www.w3.org/2000/svg" font-family="&apos;Dialog&apos;" font-style="normal" stroke-linejoin="miter" font-size="12" stroke-dashoffset="0" image-rendering="auto">
<defs id="genericDefs"/>
<g>
<defs id="defs1">
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath7">
<path d="M-7 -7 L101 -7 L101 51 L-7 51 L-7 -7 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath10">
<path d="M0 0 L90 0 L90 15 L0 15 L0 0 Z"/>
</clipPath>
</defs>
<g font-size="11" transform="translate(1173,2)" fill-opacity="1" fill="rgb(255,192,255)" text-rendering="geometricPrecision" font-family="sans-serif" stroke="rgb(255,192,255)" font-weight="bold" stroke-opacity="1">
<a xlink:href="FileDestination.svg#A_Object_FileDestination" xlink:title="object definition">
<rect x="0" width="90" height="40" y="0" clip-path="url(#clipPath7)" stroke="none"/>
</a>
</g>
<g font-size="11" stroke-linecap="butt" transform="translate(1173,2)" fill-opacity="1" fill="black" text-rendering="geometricPrecision" font-family="sans-serif" stroke-linejoin="round" stroke="black" font-weight="bold" stroke-opacity="1" stroke-miterlimit="0">
<rect fill="none" x="0" width="90" height="40" y="0" clip-path="url(#clipPath7)"/>
</g>
<g font-size="11" transform="translate(1173,2)" fill-opacity="1" fill="black" text-rendering="geometricPrecision" font-family="sans-serif" stroke="black" font-weight="bold" stroke-opacity="1">
<a xlink:title="object def">
<text x="21" xml:space="preserve" y="12" clip-path="url(#clipPath10)" stroke="none">Object A</text>
</a>
<line y2="12" fill="none" x1="21" clip-path="url(#clipPath10)" x2="66" y1="12"/>
</g>
</g>
</svg>
Object A in FileDestination.svg :
<g font-size="11" transform="translate(712,44)" fill-opacity="1" fill="rgb(255,192,255)" text-rendering="geometricPrecision" font-family="sans-serif" stroke="rgb(255,192,255)" font-weight="bold" stroke-opacity="1">
<rect id="A_Object_FileDestination" x="0" width="90" height="40" y="0" clip-path="url(#clipPath13)" stroke="none"/>
</g>
The problem is : when I creates this link my rectangle color become black.. do you know why ?
Also is it possible to link my object with the transform defined ? (I saw it in the doc)
like this :
FileDestination.svg#svgView(transform(translate(712,44)))
Because I added the id for each rectangle, when svg files are generate there isn't any ids, just the transforms.
The translate corresponding at the transform of A in FileDestination, but when I tried it, I just have a blank before my diagram..
And Finally, I have no idea, how to do my animation to target the destination of the link. Certainly in JavaScript or with d3.js ? with actionListener ? but how ? because objects are not in the same page. And I do not how to handle the fact that the objects aren't in the same page.
Thanks by advance for yours answers :))

Categories