2

I have been able to follow the source code and get my WebGL globe to work like the example. I am trying to customize this Globe. I have more than one metric that I need to show on the globe. e.g. Instead of showing just the whole population on the globe, I want to show female population as well as male population from the same vertex point. I have been reading through every line in Globe.js but am still confused on how I can achieve this. Can someone point me towards the right direction?

gman
  • 100,619
  • 31
  • 269
  • 393
caramelslice
  • 359
  • 1
  • 4
  • 16

1 Answers1

2

Mh, nice expansion of this demo. The approach coming to my mind would be to change the for-loops in addData()...

function addData(data, opts) {
  var lat, lng, size, color, i, step, colorFnWrapper;
  // NEW:
  var pointsAtPosition = {};
  var offsetAtPosition = {};
  var pointPosition = '';
  var offset = 0;

  ...

The construction of this._baseGeometry seems to set the color, so there is some heavy rewriting here. Why do I handle location indexing with an object and stringifying my lat/long? I tried nested objects first and it was a performance disaster! But maybe there is something even smarter?

  if (this._baseGeometry === undefined) {
    this._baseGeometry = new THREE.Geometry();

    for (i = 0; i < data.length; i += step) {
      lat = data[i];
      lng = data[i + 1];
      size = 0;
      offset = 0;

    pointPosition = '' + lat + '/' + lng;

    if (!pointsAtPosition[pointPosition]) {
        pointsAtPosition[pointPosition] = 1;
        color = {r: 255, g: 0, b: 0};
    } else {
        pointsAtPosition[pointPosition] += 1;
        // set color according to point count
        switch (pointsAtPosition[pointPosition]) {
        default:
            color = {r: 0, g: 0, b: 0};
            break;
        case 2:
            color = {r: 0, g: 255, b: 0};
            break;
        case 3:
            color = {r: 0, g: 0, b: 255};
            break;
        }
    }

      addPoint(lat, lng, size, offset, color, this._baseGeometry);
    }
  }

... looping the second time we set the positions... we improve upon the original code by adding an offset that adds up with each entry for the same lat/lng.

for (i = 0; i < data.length; i += step) {
    lat = data[i];
    lng = data[i + 1];

    size = data[i + 2];
    size = size * 200;

    color = 0;

    pointPosition = '' + lat + '/' + lng;

    if (offsetAtPosition[pointPosition] === undefined) {
        offsetAtPosition[pointPosition] = 0;
    }

    offset = offsetAtPosition[pointPosition];
    offsetAtPosition[pointPosition] += size;

    addPoint(lat, lng, size, offset, color, subgeo);
}

Now all that's left is to adjust addPoint() so that it takes offset as an argument.

function addPoint(lat, lng, size, offset, color, subgeo) {
  var phi = (90 - lat) * Math.PI / 180;
  var theta = (180 - lng) * Math.PI / 180;

  point.position.x = (200 + offset) * Math.sin(phi) * Math.cos(theta);
  point.position.y = (200 + offset) * Math.cos(phi);
  point.position.z = (200 + offset) * Math.sin(phi) * Math.sin(theta);

  ...

Changing the data JSON file we are now able to display multiple entries per location!

[
 ["1990",[6,9,0.1,6,9,0.2,6,9,0.2]],
 ["1995",[-35,-64,0.001,21,76,0.001,6,9,0.2]],
 ["2000",[6,159,0.001,21,76,0.001,6,9,0.2]]
]

enter image description here

  • Thanks so much Jonas for posting this. I see. It looks like there will be a quite bit of work to do. I will try out your suggestion and post an update my progress here in some time. – caramelslice Jun 02 '16 at 15:04
  • Just came back to it and made it work. Hope you didn't spent time on my first draft... =D Thanks for pointing to this demo, 'twas much fun! – Jonas M. Schlatter Jun 02 '16 at 17:19
  • Wow. I did not expect such a quick and detailed response. It took me a while to understand this. I did a lot of console.log()... Assign each metric a position, and then offset them on the same vertex base on its position. Very clever. Thanks again for sharing this. Marking this as solved. – caramelslice Jun 02 '16 at 22:12
  • 1
    Reading this post over and over. It's almost like reading a poem. Beautifully written. Thanks again! Because I store the data in the local file, I might tweak the JSON and the code a bit to reduce the data size and also for better performance. Something like ["1990",[6,9,0.1,0.2,0.3,6,10,0.1,0.2,0.3]]... – caramelslice Jun 02 '16 at 23:30
  • Happy to hear that you used this to log() your way through! :) Tweaking the JSON is a nice touch... definitly a good idea! Thanks for the kind words and have fun with the project! – Jonas M. Schlatter Jun 03 '16 at 05:46