iskandarblue
iskandarblue

Reputation: 7526

Positioning svg element over div

I have a d3 animation that is contained in an svg and a div containing a map that I would like to display together - with the d3 design on top of the map itself. Both the map and the svg should cover the entire screen.

When I change the map's position to absolute, only the map appears and the d3 animation disappears behind it. When it the position is relative, the map disappears behind the svg even though the opacity is set to 0.5. In fact, changing the opacity of either the svg or the body does not make the map visible. In addition, changing the z-index of the map to 10101010 does not make it visible either.

What should I do to make the d3 appear above the map? I am not skilled in CSS and any suggestions would be appreciated.

Here is a snippet demonstrating the problem and the full code below:

// 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); };

mapboxgl.accessToken = 'pk.eyJ1Ijoic29jaWFsYmljeWNsZXMiLCJhIjoiTlBhano1cyJ9.1k53PW_xMIrcu3TKku4Tzg';
var map = new mapboxgl.Map({
    container: 'map', // container id
    style: 'mapbox://styles/mapbox/streets-v9', // stylesheet location
    center: [-74.50, 40], // starting position [lng, lat]
    zoom: 9 // starting zoom
});
html, body, main {
            height: 100%;
            background-color: #130C0E;
            opacity: 0.5;
            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 */
        }

        #map { position:relative; top:0; bottom:0; width:100%; z-index: 10101010 }
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.39.1/mapbox-gl.css" rel="stylesheet"/>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.39.1/mapbox-gl.js"></script>
<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>


<div id='map'></div>

Upvotes: 0

Views: 988

Answers (1)

Andrew
Andrew

Reputation: 13853

First, you do not specify a height for your map. That is why it does not appear. Once you do that, you can just absolutely position both and they will appear overlapping.

// 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);
};

mapboxgl.accessToken = 'pk.eyJ1Ijoic29jaWFsYmljeWNsZXMiLCJhIjoiTlBhano1cyJ9.1k53PW_xMIrcu3TKku4Tzg';
var map = new mapboxgl.Map({
  container: 'map', // container id
  style: 'mapbox://styles/mapbox/streets-v9', // stylesheet location
  center: [-74.50, 40], // starting position [lng, lat]
  zoom: 9 // starting zoom
});
html,
body,
main {
  height: 100%;
  background-color: #130C0E;
  opacity: 0.5;
  padding: 0;
  margin: 0;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

svg {
  position: absolute;
  width: 100%;
  height: 99%;
  /* gets rid of scrollbar */
}

#map {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
}
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.39.1/mapbox-gl.css" rel="stylesheet" />
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.39.1/mapbox-gl.js"></script>
<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>


<div id='map'></div>

Upvotes: 1

Related Questions