Dynamic SVG Creation From List of Strings [duplicate] - javascript

This question already has answers here:
jquery's append not working with svg element?
(17 answers)
Closed 2 years ago.
I'm trying to use JQuery to create an SVG element. The contents of the SVG is generated from a list of strings which is where I'm having my issues.
I'm populating a variable called 'arr' by looping through several hundred items in my database and creating an svg rect shaped based on that data which then gets appended to 'arr'. How can i append this list of string elements to my main SVG element in order to properly display it?
The main points here are:
Arr is populated with a list of strings, each one representing a shape to go inside the svg
The final Arr will be several hundreds strings
var mapSvg = $.parseHTML('<svg id="tile-map-svg" width="100%" height="300"></svg>');
arr = [
'<rect height="50" width="50" fill="blue"/>',
'<rect height="20" width="20" fill="green"/>'
]
mapSvg[0].append(arr);
$('#tile-map').append(mapSvg);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div style="background:lightblue; padding:10px;">
<div id="tile-map">
</div>
<svg id='tile-map-svg' width="100" height="100">
<rect height="25" width="25" fill="red" class="tile"/>
</svg>
</div>
I also tried this and it didn't work either...
var mapSvg = $.parseHTML('<svg id="tile-map-svg" width="100%" height="600"></svg>');
arr = [
'<rect height="50" width="50" fill="blue"/>',
'<rect height="20" width="20" fill="green"/>'
]
for (var i = 0; i < arr.length; i++) {
var el = $.parseHTML(arr[i])[0];
mapSvg[0].append(el);
}
$('#tile-map').append(mapSvg);

How about looping over all the elements in arr before parsing the html:
let html = '<svg id="tile-map-svg" width="100%" height="300">';
arr.forEach(shape => {
html += shape;
});
html += "</svg>";
const mapSvg = $.parseHTML(html);
$("#tile-map").append(mapSvg);

Or simply copy HTML without jQ for example:
var mapSvg = document.getElementById("tile-map");
var arr = [
'<rect height="50" width="50" fill="blue"/>',
'<rect height="20" width="20" fill="green"/>'
]
var s = "<svg id='tile-map-svg' width=100 height=100>"+
arr.join('\n')+
"</svg>";
mapSvg.innerHTML = s;
mapSvg.innerHTML += s;
mapSvg.parentElement.innerHTML += mapSvg.outerHTML.replace(/</g,'<').replace(/>/g,'>');
<div style="background:lightblue; padding:10px;">
<div id="tile-map">
</div>
</div>

Related

How to convert svg string to svg file using Python?

Using AJAX I send a svg image to Django using the following function:
function uploadSVG(){
var svgImage = document.getElementById("SVG");
var serializer = new XMLSerializer();
var svgStr = serializer.serializeToString(svgImage);
$(document).ready(function(){
$.post("ajax_upload_svg/",
{
csrfmiddlewaretoken: csrftoken,
svgImage: svgStr
},
function(){
console.log('Done')
});
});
}
In Django I end up with the svg image as a string using the following function:
def uploadSVG(request):
svgImg = request.POST.get('svgImage')
return HttpResponse('')
The string I get looks like this:
<svg xmlns="http://www.w3.org/2000/svg" id="SVG" width="460" height="300" style="border:2px solid #000000"><rect x="150" y="70" width="160" height="130" fill="#292b2c"/></svg>
How can I convert this svg string into a svg file?
The solution is:
with open("svgTest.svg", "w") as svg_file:
svg_file.write(svgImg)

How to perform replace in a loop in js

I have a string like this
var string = '<img src="test.jpg'><img src="test2.jpg>';
var dom = new JSDOM(string,{ includeNodeLocations: true });
dom = dom.window.document.querySelectorAll("img");
for(var i = 0;i< dom.length;i++) {
text = string.replace(/<img[^>]*>/g,'<amp-img layout="responsive" class="ampimageheight" src="'+dom[i].getAttribute('src')+'" width="200" height= "100"></amp-img>');
}
But my output is
<amp-img layout="responsive" class="ampimageheight" src="test2.jpg" width="200" height= "100"></amp-img><amp-img layout="responsive" class="ampimageheight" src="test2.jpg" width="200" height= "100"></amp-img>
In which only the second image src is replaced for 2 imags.I think this is because of the asynchronous.Can anyone please help me.Thanks.
Well, if you run replace in a loop, you don't need set the Regex's flag.
Because that replace all img when first time loop.
After first loop is do nothing.
So, you can remove Regex flag, or use a callback replace your function's second arguments, like this.
text = string.replace(/<img[^>]*>/g, function(str, index){
return '<amp-img layout="responsive" class="ampimageheight" src="'+dom[index].getAttribute('src')+'" width="200" height= "100"></amp-img>'
});
And it doesn't need loop;

Node JS grab the first image in an html string

I'm trying to grab the first image in an html string like this one
<table border="0" cellpadding="2" cellspacing="7" style="vertical-align:top;"><tr><td width="80" align="center" valign="top"><font style="font-size:85%;font-family:arial,sans-serif"><img src="//t3.gstatic.com/images?q=tbn:ANd9GcQVyQsQJvKMgXHEX9riJuZKWav5U1nI-jdB-i1HwFYQ-7jGvGrbk9N_k0XEDMVH-HAbLxP1wrU" alt="" border="1" width="80" height="80" /><br /><font size="-2">Wall Street Journal</font></font></td><td valign="top" class="j"><font style="font-size:85%;font-family:arial,sans-serif"><br /><div style="padding-top:0.8em;"><img alt="" height="1" width="1" /></div><div class="lh"><b><b>Obama's</b> Letters to Corinthian</b><br /><font size="-1"><b><font color="#6f6f6f">Wall Street Journal</font></b></font><br /><font size="-1">The <b>Obama</b> Administration has targeted for-profit colleges as if they are enemy combatants. And now it has succeeded in putting out of business Santa Ana-based Corinthian Colleges for a dilatory response to document requests. Does the White House plan ...</font><br /><font size="-1" class="p"></font><br /><font class="p" size="-1"><a class="p" href="http://news.google.com/news/more?ncl=dPkBozywrsIXKoM&authuser=0&ned=us"><nobr><b>and more ยป</b></nobr></a></font></div></font></td></tr></table>
here is the tag of the image
<img src="//t3.gstatic.com/images?q=tbn:ANd9GcQVyQsQJvKMgXHEX9riJuZKWav5U1nI-jdB-i1HwFYQ-7jGvGrbk9N_k0XEDMVH-HAbLxP1wrU" alt="" border="1" width="80" height="80">
every images has got this kind of url
//tx.gstatic.com where x is a number i think between 0<x<3
That's what I do without success and I don't understand why this happen
var re = /<img[^>]+src="?([^"\s]+)"?\s*\/>/g;
var results = re.exec(HTMLSTRING);
var img="";
if(results!=null && results.length!=0) img = results[0];
The regular expression you provide indeed is not general enough to capture your <img> tag.
There are two options:
Make a better regular expression. This way lies madness. But in this case, it is sufficient to add the possibility of other attributes after src:
var re = /<img[^>]+src="?([^"\s]+)"?[^>]*\/>/g;
var results = re.exec(HTMLSTRING);
var img="";
if(results) img = results[1];
Note [^>]* replacing your \s*, and also note results[1] instead of results[0] if you want the source and not the tag itself.
Use a DOM parser to handle DOM. This is the easy path.
var jsdom = require("jsdom");
var img_sources = jsdom.env(
HTMLSTRING,
function (errors, window) {
var imgs = window.document.getElementsByTagName('img');
for (var i = 0; i < imgs.length; i++) {
var src = imgs[i].getAttribute('src');
if (src) console.log(src);
}
}
);
You could use the jQuery NPM module and do this:
var jQuery = require('jquery');
try {
var src = jQuery('YOUR_HTML_STRING').find('img')[0].src;
console.log('Output:\nSrc: ' + src + '\nNum: ' + (src.match(/\/\/t[0-3]/)[0])[3]);
} catch (e) {
console.log('Could not find <img>!');
}

Transfer SVG code DIV-input-DIV

I'm just curious - is it possible to send by SVG image code in the following way?
<original div with inline SVG> -> Input field -> <final DIV>
I want to use following code:
Copy-1
<div id="source-1">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="10" y="10" height="100" width="100"
style="stroke:#ff0000; fill: #0000ff"/>
</svg>
</div>
<input name="dynamichidden-637" value="" id="pole" />
<br />
Copy-2
<div id="source-2"></div>
and Jquery:
jQuery( document ).ready(function( $ ) {
$('#copy-1').click(function() {
var value = $('#source-1').html();
var input = $('#pole');
input.val('')
input.val(input.val() + value);
return false;
});
$('#copy-2').click(function() {
$('#pole').appendTo('#source-2');
return false;
});
});
So my question is - is it possible to achieve it in that way? or using somehow other solution which will allow me to transfer svg code from one page to another without storing the data in Database? This is JSfiddle:
http://jsfiddle.net/v2br8/16/
You just need to create the copy using the value of the input:
var value = $('#pole').val();
var copy = $(value);
copy.appendTo('#source-2');
or simply:
$($('#pole').val()).appendTo('#source-2');
DEMO
Try: source-2.innerHTML=source_1.innerHTML

Writing current time to SVG document

I am trying to add current time to an SVG file using ECMAScript.
Following is the code I have. Unfortunately it's not working. How do I fix it?
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="300">
<text x="0" y="15" fill="red">It is now
<script type="text/javascript">
<![CDATA[
var currentTime = new Date();
var month = currentTime.getMonth() + 1;
var day = currentTime.getDate();
var year = currentTime.getFullYear();
document.write(month + "/" + day + "/" + year);
]]>
</script>
</text>
</svg>
Demo: http://jsfiddle.net/M8YXS/
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300">
<text x="0" y="15" fill="red">It is now <tspan id="now">(time)</tspan></text>
<!--
This script block must either be after the element in the source code
or else the code below must be wrapped in a callback that is invoked
only after the DOM is created (e.g. window.onload in a browser)
-->
<script>
// Create whatever string you want
var dateString = (new Date).toDateString();
// Set the string content of the Text Node child of the <tspan>
document.getElementById('now').firstChild.nodeValue = dateString;
</script>
</svg>

Categories

Resources