0

I am working on a tree diagram where an SVG path is connecting the nodes. This is calculated and added to the DOM with an absolute start point en endpoint. The actual path is added to:

<svg id="svg1" width="0" height="0" ></svg>

If I let the SVG paths render inside the page it is visible inside the DOM but not on the page itself. If I cut the SVG and repaste is to the exact same place within the developer tool DOM it shows up in the website.

I have tried using z-index to make it show up because I thought it was behind an other element. This was not the case.

<svg id="svg1" width="734.7778133786011" height="200">
<path id="Path0" d="M432.77778286102296 165.55556 V170.722226 A5.1666659999999975 5.1666659999999975 0 0 1 427.61111686102294 175.888892 H137.92709198846435 A5.1666659999999975 5.1666659999999975 0 0 0 132.76042598846436 181.05555800000002 V200" stroke-width="2px" style="stroke:#555; fill:none;  "></path>
<path id="Path1" d="M432.77778286102296 165.55556 V170.722226 A5.1666659999999975 5.1666659999999975 0 0 1 427.61111686102294 175.888892 H287.9270996178589 A5.1666659999999975 5.1666659999999975 0 0 0 282.7604336178589 181.05555800000002 V200" stroke-width="2px" style="stroke:#555; fill:none;  "></path>
<path id="Path2" d="M432.77778286102296 165.55556 V165.55556 A0 0 0 0 0 432.77778286102296 165.55556 H432.77778286102296 A0 0 0 0 1 432.77778286102296 165.55556 V200" stroke-width="2px" style="stroke:#555; fill:none;  "></path>
<path id="Path3" d="M432.77778286102296 165.55556 V170.722226 A5.1666659999999975 5.1666659999999975 0 0 0 437.944448861023 175.888892 H577.6111473786011 A5.1666659999999975 5.1666659999999975 0 0 1 582.7778133786011 181.05555800000002 V200" stroke-width="2px" style="stroke:#555; fill:none;  "></path>
<path id="Path4" d="M432.77778286102296 165.55556 V170.722226 A5.1666659999999975 5.1666659999999975 0 0 0 437.944448861023 175.888892 H727.6111473786011 A5.1666659999999975 5.1666659999999975 0 0 1 732.7778133786011 181.05555800000002 V200" stroke-width="2px" style="stroke:#555; fill:none;  "></path>
</svg>

I am trying to understand what exactly happens when you add something inside the DOM within the console.

This code will append unique SVG files to the DOM

$("#svg1").append('<path id="myNewPath' + x + '" d="M0 0" stroke-width="2px" stroke-width="0.3em" style="stroke:#555; fill:none;  "/>')

Here is the function to call the SVG render/calculate function (in an other JS file)

function connectAll(xCounterEachBox) {
for(i = 0; xCounterEachBox >= i; i++){
    connectElements($("#svg1"), $("#myNewPath" + i + ""), $("#parentBoxID"),  $("#box" + i + ""));
}

The code for rendering the SVG points (Different JS file):

function signum(x) {
    return (x < 0) ? -1 : 1;
}
function absolute(x) {
    return (x < 0) ? -x : x;
}

function drawPath(svg, path, startX, startY, endX, endY) {
    // get the path's stroke width (if one wanted to be  really precize, one could use half the stroke size)
    var stroke =  parseFloat(path.attr("stroke-width"));
    // check if the svg is big enough to draw the path, if not, set heigh/width
    if (svg.attr("height") <  endY)                 svg.attr("height", endY);
    if (svg.attr("width" ) < (startX + stroke) )    svg.attr("width", (startX + stroke));
    if (svg.attr("width" ) < (endX   + stroke) )    svg.attr("width", (endX   + stroke));

    var deltaX = (endX - startX) * 0.15;
    var deltaY = (endY - startY) * 0.15;
    // for further calculations which ever is the shortest distance
    var delta  =  deltaY < absolute(deltaX) ? deltaY : absolute(deltaX);

    // set sweep-flag (counter/clock-wise)
    // if start element is closer to the left edge,
    // draw the first arc counter-clockwise, and the second one clock-wise
    var arc1 = 0; var arc2 = 1;
    if (startX > endX) {
        arc1 = 1;
        arc2 = 0;
    }
    // draw tha pipe-like path
    // 1. move a bit down, 2. arch,  3. move a bit to the right, 4.arch, 5. move down to the end 
    path.attr("d",  "M"  + startX + " " + startY +
                    " V" + (startY + delta) +
                    " A" + delta + " " +  delta + " 0 0 " + arc1 + " " + (startX + delta*signum(deltaX)) + " " + (startY + 2*delta) +
                    " H" + (endX - delta*signum(deltaX)) + 
                    " A" + delta + " " +  delta + " 0 0 " + arc2 + " " + endX + " " + (startY + 3*delta) +
                    " V" + endY );
}

function connectElements(svg, path, startElem, endElem) {
    var svgContainer= $("#svgContainer");

    // if first element is lower than the second, swap!
    if(startElem.position().top > endElem.position().top){
        var temp = startElem;
        startElem = endElem;
        endElem = temp;
    }

    // get (top, left) corner coordinates of the svg container   
    var svgTop  = svgContainer.position().top;
    var svgLeft = svgContainer.position().left;

    // get (top, left) coordinates for the two elements
    var startCoord = startElem.position();
    var endCoord   = endElem.position();

    // calculate path's start (x,y)  coords
    // we want the x coordinate to visually result in the element's mid point
    var startX = startCoord.left + 0.5*startElem.outerWidth() - svgLeft;    // x = left position + 0.5*width - svg's left position
    var startY = startCoord.top  + startElem.outerHeight() - svgTop;        // y = top position + height - svg's top position

        // calculate path's end (x,y) coords
    var endX = endCoord.left + 0.5*endElem.outerWidth() - svgLeft;
    var endY = endCoord.top  - svgTop;

    // call function for drawing the path
    drawPath(svg, path, startX, startY, endX, endY);

}
user234562
  • 631
  • 9
  • 20

1 Answers1

-1

I found the solution.

Because SVG needs to be renderd/calculated when its read by the browser. The append function wont work if the is already in the DOM and you appending to it.

It wont show because its already been calculated.

user234562
  • 631
  • 9
  • 20
  • 1
    That's not true. Robert told you your problem : NameSpace. jQuery doesn't know you want to create an SVG element, so it will create an HTMLUnkownElement with its name set to `'path'`, but it won't be recognized as an SVGPath element, since it won't be. To append an SVG node in the DOM, you need to create it with `document.createElementNS('http://www.w3.org/2000/svg', 'path')`. – Kaiido Apr 28 '17 at 08:27
  • I see :) Thanks for this feedback, I didnt know that appending SVG was different than HTML. Makes sense though! – user234562 Apr 28 '17 at 08:45