95

I want to create a rectangle inside an HTML page, then write some text on that rectangle. I also need that text to be a hyperlink. This is what I did but it is not working:

    <!DOCTYPE html>
<html>
<body>

<script>

    var svg   = document.documentElement;
    var svgNS = svg.namespaceURI;

    var rect = document.createElementNS(svgNS,'rect');
    rect.setAttribute('x',5);
    rect.setAttribute('y',5);
    rect.setAttribute('width',500);
    rect.setAttribute('height',500);
    rect.setAttribute('fill','#95B3D7');
    svg.appendChild(rect);
    document.body.appendChild(svg);

    var h=document.createElement('a');
    var t=document.createTextNode('Hello World');
    h.appendChild(t);
    document.body.appendChild(h);


</script>

</body>
</html>

Can you help please? Thanks.

Erik Dahlström
  • 59,452
  • 12
  • 120
  • 139
user2746087
  • 1,069
  • 1
  • 8
  • 6
  • 1
    Possible duplicate of [Create SVG tag with JavaScript](http://stackoverflow.com/questions/8215021/create-svg-tag-with-javascript) – Zeimyth May 29 '16 at 14:24
  • 2
    OP, you're supposed to accept an answer or explain what's missing. – Denys Séguret Jul 19 '16 at 04:58
  • 2
    Please see the comment of @DenysSéguret https://www.google.com/search?q=stackexchange+how+to+accept+an+answer&ie=utf-8&oe=utf-8 – Alan Aug 04 '16 at 13:44

5 Answers5

139

Change

var svg   = document.documentElement;

to

var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");

so that you create a SVG element.

For the link to be an hyperlink, simply add a href attribute :

h.setAttributeNS(null, 'href', 'http://www.google.com');

Demonstration

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 1
    Ok I will. The text works, but I want to change its position. I want it to be displayed on the rectangle like in the middle of the rect for example. – user2746087 Dec 15 '13 at 04:37
  • Note that the link is an html anchor tag, if you want it to be inside the svg you need to create an element (in the svg namespace), and an element, and then append these to the svg. See e.g http://stackoverflow.com/questions/19132443/dynamic-creation-of-svg-links-in-javascript. – Erik Dahlström Mar 21 '14 at 14:17
56

To facilitate svg editing you can use an intermediate function:

function getNode(n, v) {
  n = document.createElementNS("http://www.w3.org/2000/svg", n);
  for (var p in v)
    n.setAttributeNS(null, p, v[p]);
  return n
}

Now you can write:

svg.appendChild( getNode('rect', { width:200, height:20, fill:'#ff0000' }) );

Example (with an improved getNode function allowing camelcase for property with dash, eg strokeWidth > stroke-width):

function getNode(n, v) {
  n = document.createElementNS("http://www.w3.org/2000/svg", n);
  for (var p in v)
    n.setAttributeNS(null, p.replace(/[A-Z]/g, function(m, p, o, s) { return "-" + m.toLowerCase(); }), v[p]);
  return n
}

var svg = getNode("svg");
document.body.appendChild(svg);

var r = getNode('rect', { x: 10, y: 10, width: 100, height: 20, fill:'#ff00ff' });
svg.appendChild(r);

var r = getNode('rect', { x: 20, y: 40, width: 100, height: 40, rx: 8, ry: 8, fill: 'pink', stroke:'purple', strokeWidth:7 });
svg.appendChild(r);
Joseph Merdrignac
  • 3,510
  • 2
  • 19
  • 16
  • 2
    Notice that the "camelcase to dash feature" screws things up for you if you try to set the attribute "viewBox". – Chris K Feb 17 '17 at 10:01
  • you're right, we should handle some exception to make it works well – Joseph Merdrignac Apr 28 '17 at 14:28
  • 5
    @chris we can just write `"stroke-width":2`, [tested it](https://jsfiddle.net/ht6phnt9/2/), works great. omit the `replace` before v[p] and use quotes in the attribute name if there is a dash in it. mixing unquoted simple attributes and quoted-dashed ones works too. – Cee McSharpface Jan 30 '18 at 11:31
44

Add this to html:

<svg id="mySVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"/>

Try this function and adapt for you program:

var svgNS = "http://www.w3.org/2000/svg";  

function createCircle()
{
    var myCircle = document.createElementNS(svgNS,"circle"); //to create a circle. for rectangle use "rectangle"
    myCircle.setAttributeNS(null,"id","mycircle");
    myCircle.setAttributeNS(null,"cx",100);
    myCircle.setAttributeNS(null,"cy",100);
    myCircle.setAttributeNS(null,"r",50);
    myCircle.setAttributeNS(null,"fill","black");
    myCircle.setAttributeNS(null,"stroke","none");

    document.getElementById("mySVG").appendChild(myCircle);
}     
urish
  • 8,943
  • 8
  • 54
  • 75
Alex Moanga
  • 503
  • 5
  • 9
-1

Elements can easily be added using the fragment.

Example

<input style="width:300px" type="text" placeholder="Input something to change the text." /><br>
<script>
const frag = document.createRange().createContextualFragment(`
<svg width="250" height="250">
  <rect x="0" y="0" width="250" height="250" fill="#95B3D7"></rect>
  <a href="https://www.google.com" style="cursor: pointer" target="_blank">
    <text x="10" y="130" style="
      font-size: 48px;
      fill:#faff00;">
      Hello world</text>
  </a>
</svg>
      `)
      const textElem = frag.querySelector("text")
      document.querySelector("input").onchange = (e) => {
        textElem.textContent = e.target.value
      }
      document.body.append(frag)
</script>
Carson
  • 6,105
  • 2
  • 37
  • 45
-4

function getNode(n, v) {
  n = document.createElementNS("http://www.w3.org/2000/svg", n);
  for (var p in v)
    n.setAttributeNS(null, p.replace(/[A-Z]/g, function(m, p, o, s) { return "-" + m.toLowerCase(); }), v[p]);
  return n
}

var svg = getNode("svg");
document.body.appendChild(svg);

var r = getNode('rect', { x: 10, y: 10, width: 100, height: 20, fill:'#ff00ff' });
svg.appendChild(r);

var r = getNode('rect', { x: 20, y: 40, width: 100, height: 40, rx: 8, ry: 8, fill: 'pink', stroke:'purple', strokeWidth:7 });
svg.appendChild(r);
Szin
  • 1
  • 1
  • 1
    Welcome to Stack Overflow. Code without any explanation are rarely helpful. Stack Overflow is about learning, not providing snippets to blindly copy and paste. Please edit your question and explain how it answers the specific question being asked. See [How to Answer](https://stackoverflow.com/help/how-to-answer). – Sfili_81 Jun 16 '21 at 14:23
  • Remove this answer . This got added incorrectly while Szin clicked on "Copy snippet to answer" button above on the page. – Shashank Bodkhe Apr 19 '23 at 07:44