0

My objective is to place d3 circles in the svg behind the text that I've appended to the svg. So far, I have tried placing the code appending the text after the code appending the circles but this method does not work.

I am unfamiliar with how to order elements using d3 and would appreciate any suggestions.

Here is a snippet demonstrating the issue:

// create data
var data = [];
for (var i=0; i < 108; i++) {
 data.push(i);
}

// Scale for radius
var xr = d3.scale
        .linear()
        .domain([0, 108])
        .range([0, 27]);

// Scale for random position
var randomPosition = function(d) {
    return Math.random() * 1280;
}

var tcColours = ['#FDBB30', '#EE3124', '#EC008C', '#F47521', '#7AC143', '#00B0DD'];
var randomTcColour = function() {
  return Math.floor(Math.random() * tcColours.length);
};

// SVG viewport
var svg = d3.select('body')
  .append('svg')
    .attr('width', 1280)
    .attr('height', 512);

    svg.append("text")
    .attr("x", 100)             
    .attr("y", 100)
    .attr("text-anchor", "middle")  
    .style("font-size", "36px") 
    .style('fill', 'white')
    .text("Lorem ipsum");

var update = function() {
    var baseCircle = svg.selectAll('circle');
    // Bind data
    baseCircle = baseCircle.data(data);

    // set the circles
    baseCircle.transition()
            .duration(40000)
            .attr('r', xr)
            .attr('cx', randomPosition)
            .attr('cy', randomPosition)
            .attr('fill', "none")
            .attr("stroke-width", 4)
            .style('stroke', tcColours[randomTcColour()])
 
    baseCircle.enter()
            .append('circle')
            .attr('r', xr)
            .attr('cx', randomPosition)
            .attr('cy', randomPosition)
            .attr('fill', "none")
            .attr("stroke-width", 4)
            .style('stroke', tcColours[randomTcColour()])
            .style('opacity', 1);


}

setTimeout(function () { update();
  //do something once
}, 500);

window.onload = function() { update(); setInterval(update, 50000); };
html, body, main {
            height: 100%;
            background-color: #130C0E;
            padding: 0;
            margin: 0;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
        }

        svg {
            width: 100%;
            height: 99%;
           /* gets rid of scrollbar */
        }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
iskandarblue
  • 7,208
  • 15
  • 60
  • 130

1 Answers1

3

The quick and easy way is to append the text last. The layer order in SVG is based on the document order. I'm not sure why it's not working for you -- it's working for me in the following snippet (maybe you didn't put it in the update function?).

For more details there are some good answers that reference the spec here: How to use z-index in svg elements?

// create data
var data = [];
for (var i=0; i < 108; i++) {
 data.push(i);
}

// Scale for radius
var xr = d3.scale
        .linear()
        .domain([0, 108])
        .range([0, 27]);

// Scale for random position
var randomPosition = function(d) {
    return Math.random() * 1280;
}

var tcColours = ['#FDBB30', '#EE3124', '#EC008C', '#F47521', '#7AC143', '#00B0DD'];
var randomTcColour = function() {
  return Math.floor(Math.random() * tcColours.length);
};

// SVG viewport
var svg = d3.select('body')
  .append('svg')
    .attr('width', 1280)
    .attr('height', 512);


var update = function() {
    var baseCircle = svg.selectAll('circle');
    // Bind data
    baseCircle = baseCircle.data(data);

    // set the circles
    baseCircle.transition()
            .duration(40000)
            .attr('r', xr)
            .attr('cx', randomPosition)
            .attr('cy', randomPosition)
            .attr('fill', "none")
            .attr("stroke-width", 4)
            .style('stroke', tcColours[randomTcColour()])
 
    baseCircle.enter()
            .append('circle')
            .attr('r', xr)
            .attr('cx', randomPosition)
            .attr('cy', randomPosition)
            .attr('fill', "none")
            .attr("stroke-width", 4)
            .style('stroke', tcColours[randomTcColour()])
            .style('opacity', 1);
 
     svg.append("text")
           .attr("x", 100)             
    .attr("y", 100)
    .attr("text-anchor", "middle")  
    .style("font-size", "36px") 
    .style('fill', 'white')
    .text("Lorem ipsum");



}

setTimeout(function () { update();
  //do something once
}, 500);

window.onload = function() { update(); setInterval(update, 50000); };
html, body, main {
            height: 100%;
            background-color: #130C0E;
            padding: 0;
            margin: 0;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
        }

        svg {
            width: 100%;
            height: 99%;
           /* gets rid of scrollbar */
        }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Mark
  • 90,562
  • 7
  • 108
  • 148