Search code examples
javascriptthree.jsaframewebgl-globe

Why objects overlap although they are far from each other in A-Frame


I have created some charts which are showing in front of another object (globe) as shown below:

how objects look like in the A-Frame inspector

but when I am using a camera and move in the scene the order of the objects change and the bar charts are not visible anymore (overlap). Not sure what causing this and how to resolve it.

Here are some screenshots from this issue:

overlay screenshot 1

overlay screenshot 2

overlay screenshot 3

and the code

const globeEntity = document.getElementById('globe');


const getAlt = d => d.MMS / 2500
//const catColor = d3.scaleOrdinal(d3.schemeCategory10.map(col => polished.transparentize(0.2, col)));
// const catColor = d3.scaleOrdinal(d3.schemeCategory10.map(col => polished.transparentize(0.2, col)));
const colorArray = ['#fb0511', '#fa4400', '#f56500', '#eb8100', '#dd9a00', '#cbb100', '#b4c700', '#97db00', '#6fed00', '#05ff34']
//https://colordesigner.io/gradient-generator
var assd = "sjdhdh"
globeEntity.setAttribute('globe', {
  pointLat: 'lat',
  pointLng: 'long',
  pointAltitude: getAlt,
  pointRadius: function(d) {
    return d.Population / 3000000
  },
  pointColor: function(d) {
    return colorArray[d.Dep]
  },
  labelLat: 'lat',
  labelLng: 'long',
  labelAltitude: d => getAlt(d),
  labelDotRadius: function(d) {
    return d.Population / 3000000
  },
  labelDotOrientation: () => 'bottom',
  labelColor: function(d) {
    return colorArray[d.Dep]
  },
  labelText: 'NAME',
  labelSize: 0.05,
  labelResolution: 0.15,
  onHover: hoverObj => {
    let label = '',
      desc = '';
    if (hoverObj) {
      const d = hoverObj.data;
      label = `${d.NAME}; Pop.:${new Intl.NumberFormat().format(d.Population)}; Dep:${d.Dep}`;
      desc = `Market Share: ${d.MMS}% `
    }
    document.querySelector('#globe-tooltip').setAttribute('value', label);
    document.querySelector('#globe-tooltip-details').setAttribute('value', desc);
    //  document.querySelector('#textentity').setAttribute('text', desc)
    //document.querySelector('#globe-tooltip-details').setAttribute('visible', 'true');
  },
  onClick: clickObj => {
    let label = '',
      desc = '';
    if (clickObj) {
      const d = clickObj.data;
      label = `${d.NAME}; Pop.:${new Intl.NumberFormat().format(d.Population)}; Dep:${d.Dep} clicked`;
      desc = `Market Share: ${d.MMS}% Clk`
    }


    document.querySelector('#globe-tooltip').setAttribute('value', label);
    document.querySelector('#globe-tooltip-details').setAttribute('value', desc);
  }
});


fetch('https://cdn.glitch.global/c153e3cf-7430-444d-9897-4e97f1ef8d35/TAJSON.json?v=1658396524027').then(res => res.json()).then(pt => {
  globeEntity.setAttribute('globe', {
    pointsData: pt,
    labelsData: pt
  });
});









// default alpha for bars
var alpha = 0.9


function getRandomArbitrary(min, max) {
  return Math.random() * (max - min) + min;
}


function colorPicker(v) {
  console.log(v)
  if (v <= 30) {
    return "#F96B4D";
  } else if (v < 50 & v > 30) {
    return "yellow"
  } else if (v > 50) {
    return "#73FA28 ";
  }
}



// d3.csv('https://drive.google.com/file/d/1PT6mwPM42mZvhrLYdC8WmwEjwusr0AfZ', function(data){

var X_x = -0.23865 - 10.379
var Y_y = 2.2
var Z_z = -2.21058

d3.csv('https://docs.google.com/spreadsheets/d/e/2PACX-1vS8opHDQ6I1QQbwtS3oxSk4ZNZr5MGsqJnmRMX9xGKcClEhbkCYWP_tsQKF2Y8JWaO6FXkTyqDVNIJt/pub?gid=0&single=true&output=csv', function(data) {
  let dataVariable = 'MMS'
  //   let dataVariable = 'Diff 2008-2012'
  data.forEach(function(d) {
    d[dataVariable] = +d[dataVariable];
    console.log("I am in ")
    console.log(d)
  });
  console.log(data)
  let yScale = d3.scale.linear()
    .range([3, 5]) //[0, 3]
    .domain([0, 70]);

  let xScale = d3.scale.linear()
    .range([-1, 2]) //[0, 3]
    .domain([0, 30]);
  console.log(yScale.domain())

  let scene = d3.select('a-scene')
  console.log(scene)
  let bars = scene.selectAll('a-box.bar')
    .data(data)
    .enter().append('a-box')
    .classed('bar', true);

  bars.attr({
    // src:"https://cdn.glitch.global/c153e3cf-7430-444d-9897-4e97f1ef8d35/Person.jpg",
    // normalmap:"#PersonAsset_NRM",
    // normalTextureRepeat:"2 2",
    position: function(d, i) {
      var x = xScale((i * 2) + X_x);
      var y = (yScale(d[dataVariable]) / 2) + Y_y - 1.5;
      var z = Z_z
      return x + " " + y + " " + z
    },
    width: function(d) {
      return 0.07
    },
    depth: function(d) {
      return 0.03
    },
    height: function(d) {
      return d3.max([yScale(d[dataVariable]) - 3, 0.01])
    },
    opacity: alpha,
    material: "shader: standard",
    roughness: 0.1,
    //repeat: function(d) {return (1,getRandomArbitrary(1,8))},
    //  scale:"1 1 1",
    color: function(d) {
      return colorPicker(d['MMS']); // call the color picker to get the fill.

    }
  });


  let text = scene.selectAll('a-text .desc')
    .data(data)
    .enter().append('a-text')
    .classed('desc', true);

  text.attr({
    position: function(d, i) {
      var x = xScale((i * 2) + X_x)
      var y = 2.2
      var z = Z_z
      return x + " " + y + " " + z
    },
    value: function(d) {
      return d['AREA_NAME'].replace(' ', '\n');
    },
    color: '#faf443',
    align: 'center',
    baseline: 'top',
    width: 1,
  })

  let numFormat = d3.format("s")
  let numText = scene.selectAll('a-text .num')
    .data(data)
    .enter().append('a-text')
    .classed('num', true);

  numText.attr({
    position: function(d, i) {
      var x = xScale((i * 2) + X_x)
      var y = yScale(d[dataVariable]) + Y_y - 2.8
      var z = Z_z
      return x + " " + y + " " + z
    },
    value: function(d) {
      return numFormat(d[dataVariable]);
    },
    color: 'red',
    align: 'center',
    width: 1.5,
  })


  scene.append('a-text')
    .attr({
      position: '5 5 0',
      value: 'MMS (each person is equal to 50k cutomers!)',
      color: 'green',
      align: 'center',
      width: 5,
    })





});
<meta charset="utf-8">
<title>A-Frame 3D Globe Component Example</title>
<meta name="description" content="Example for 3D Globe component."></meta>
<!-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions-->
<!-- from https://r105.threejsfundamentals.org/threejs/lessons/threejs-load-gltf.html-->
<script src="https://r105.threejsfundamentals.org/threejs/resources/threejs/r105/three.min.js"></script>
<script src="https://r105.threejsfundamentals.org/threejs/resources/threejs/r105/js/controls/OrbitControls.js"></script>
<script src="https://r105.threejsfundamentals.org/threejs/resources/threejs/r105/js/loaders/GLTFLoader.js"></script>
<script src="https://r105.threejsfundamentals.org/threejs/../3rdparty/dat.gui.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>


<script src="//unpkg.com/polished@3.5.2/dist/polished.js"></script>
<script src="//unpkg.com/aframe"></script>
<script src="//unpkg.com/aframe-extras/dist/aframe-extras.min.js"></script>
<script src="https://cdn.rawgit.com/tizzle/aframe-orbit-controls-component/v0.1.14/dist/aframe-orbit-controls-component.min.js"></script>
<script src="https://cdn.statically.io/gh/vasturiano/aframe-globe-component/c23c2a7e/dist/aframe-globe-component.min.js"></script>
<script src="https://unpkg.com/aframe-look-at-component@0.8.0/dist/aframe-look-at-component.min.js"></script>
</head>

<body>
  <a-scene>
    <a-assets>
      <img id="skyTexture" src="https://cdn.glitch.global/c153e3cf-7430-444d-9897-4e97f1ef8d35/clear-sunny-sky.jpg?v=1657244930844">
      <a-asset-item id="Person1" src="https://cdn.glitch.global/c153e3cf-7430-444d-9897-4e97f1ef8d35/scenePerson1.gltf"></a-asset-item>
      <img id="skyNight" src="https://cdn.glitch.global/c153e3cf-7430-444d-9897-4e97f1ef8d35/Solarsystemscope_texture_2k_stars_milky_way.jpg?v=1658390858400">
    </a-assets>


    <a-entity position="0 0 0" movement-controls="fly: true; speed: 0.5">
      <a-entity cursor="rayOrigin: mouse; mouseCursorStylesEnabled: true;" raycaster="objects: [globe]; interval: 100"></a-entity>
      <a-entity laser-controls="hand: left" raycaster="objects: [globe]; interval: 100; lineColor: yellow; lineOpacity: 1;showLine:true "></a-entity>
      <a-entity laser-controls="hand: right" raycaster="objects: [globe]; interval: 100; lineColor: red; lineOpacity: 1;showLine:true "></a-entity>

      <a-entity id="globe" scale="0.1 0.1 0.1" globe="
                globe-image-url: https://cdn.glitch.global/c153e3cf-7430-444d-9897-4e97f1ef8d35/8k_earth_daymap.jpg;
        bump-image-url: https://upload.wikimedia.org/wikipedia/commons/f/fb/Solarsystemscope_texture_8k_earth_normal_map.tif" rotation="48.202939304356164 179.81249076149652 0.6153566719705041" position="0.43949 -0.25848 -12.17506"></a-entity>
      <!-- 0 -175 0 -->
      <!-- https://www.h-schmidt.net/map/download/world_shaded_43k.jpg -->

      <a-camera id="cam" look-controls wasd-controls="acceleration:10; ">
        <!--wsAxis:y;wsInverted:true -->

        <a-cursor></a-cursor>

        <a-text id="globe-tooltip" position="0 -0.4 -1" width="2" align="center" color="lavender"></a-text>
        <a-text id="globe-tooltip-details" position="0 -0.5 -1" width="1" align="center" color="lavender"></a-text>
      </a-camera>
    </a-entity>
    <a-sky src="#skyNight"></a-sky>
    <a-entity id="moon" class="collidable" position="13.202 14.175 2.96" scale="0.05 0.05 0.05" globe="globe-image-url: https://cdn.glitch.global/c153e3cf-7430-444d-9897-4e97f1ef8d35/2k_moon.jpg?v=1658444439177;">

    </a-entity>



    <a-text id="moontooltip" position="10.5605 3.75316 -1.37718" rotation="0 -59.99999999999999 -0.5" width="22" align="center" color="lavender" text="value: 3D vis of MMS (hight), \n
                  Dep (Color),\n Pop (radious). \n
                  and TAs, \nPOC" look-at="#cam" opacity="0.8" scale="1 1 1"></a-text>
  </a-scene>

and the order of objects in the scene, enter image description here


Solution

  • You have two movement systems:

    • the movement-controls at the rig which has the entire globe as a child object
    • the wasd-controls attached to the camera which is also a child of the rig.

    So when You try moving the camera, You also independantly move the globe with the movement controls, positioning the bar chart inside the globe.

    Here's a glitch with the wasd-controls removed