Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically added SVG g tags are not showing

I dynamically added circle tags in g tag using jQuery.append() and got the following result.(server side language is php)

JSFiddle

However, the circles are not displayed when I load it from my local server.
Specifically, browser does not display circles in g tag at first load, then when I copy the part of g tag from chrome developer tool and paste it to separate html file (or jsfiddle etc.), it shows correctly.

What is the problem?

This is the JS code:

    var dataset = new Array();

    <?php
     // data is added to dataset
    ?>

    var day = dataset[dataset.length - 1].date - dataset[0].date + 1;

    for(var i = 0; i < dataset.length; i++){
        var count = dataset[i].date - dataset[0].date; 

        if(dataset[i].like == true) $('g.like').append("<circle  cx='"+ (count * 100) + "' cy='" + dataset[i].num/max * 300 +"' r = '4.5'  fill='red'>s</circle>");
        else $('g.dislike').append("<circle  cx='"+ (count * 100) + "' cy='" + dataset[i].num/max * 300 +"' r = '4.5'  fill='red'>s</circle>");
        }
like image 875
soonoo Avatar asked Dec 24 '22 12:12

soonoo


1 Answers

The problem you are facing is that SVG elements are different from HTML elements. jQuery only creates HTML elements. This problem has already been discussed in this thread. Here is a working solution that makes use of the makeSVG function that has been proposed (blue circles are added with JavaScript). Notice that I didn't used at all jQuery as it is superfluous here.

function makeSVGEl(tag, attrs) {
    var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
    for (var k in attrs) {
      el.setAttribute(k, attrs[k]);
    }
    return el;
}

var dataset = [
  { x: 100, y: 33  },
  { x: 200, y: 133 },
  { x: 300, y: 100 },
  { x: 400, y: 100 },
  { x: 500, y: 100 },
  { x: 600, y: 100 }
];

var svg = document.querySelector("svg.progress-chart");
var g = makeSVGEl("g", { class: "dislike" });
svg.appendChild(g);

dataset.forEach(function(coords){
  g.appendChild(makeSVGEl("circle", {
    cx: coords.x,
    cy: coords.y,
    fill: "blue",
    r: 4.5
  }));
});
<svg class="progress-chart" width="600" height="400">
    <g class="like">
        <circle cx="0" cy="266.66666666666663" r="4.5" fill="red"></circle>
        <circle cx="100" cy="200" r="4.5" fill="red"></circle>
        <circle cx="200" cy="233.33333333333334" r="4.5" fill="red"></circle>
        <circle cx="300" cy="200" r="4.5" fill="red"></circle>
        <circle cx="400" cy="133.33333333333331" r="4.5" fill="red"></circle>
        <circle cx="500" cy="166.66666666666669" r="4.5" fill="red"></circle>
        <circle cx="600" cy="300" r="4.5" fill="red"></circle>
        <circle cx="700" cy="33.33333333333333" r="4.5" fill="red"></circle>
    </g>
</svg>
like image 154
Quentin Roy Avatar answered Dec 27 '22 05:12

Quentin Roy