block by mpmckenna8 def3735b8e1eef5128a7

Turf.js distance first try w/ d3 map topojson data

Full Screen

First attempt at using turf.js client side. Not really terribly useful as is but I had some ideas for setting up the distance information better (w/out commas at the beginning of lines) and with hover events causing their corresponding icons on the map to so something or be highlighted with a like color. For no commas I could have done a good old data or datum enter deal.

This file uses the turf.min.js file so I could have gotten any functionality out of turf I wanted in this page though I only used a one small part of it. I guess the big thing I didn’t see straight up in the documentation for turf.js was how to call one of the functions from it’s library of them.

It was really quite easy you just do turf.thefunction(args) as in:

turf.distance(point1,point2,unit)

It’s so easy and I should start in on the wiki explaining how to do this amazingness client side. With d3 it was cool to get the distances in radians but this is quick nice and easy and returns something I have some conception of rather than radians. I was a little worried that my distances weren’t correct after checking the first few google results for a distance but a viable looking source matched up close to exactly w/ my results. http://dateandtime.info/distance.php?id1=3469058&id2=3390760 It’s also the first one I found which explained at least a little bit about the calculations so I trust it more than the other ones which I have no idea how the distance was calculated.

Now I want to learn how to use turf.js for something actually useful maybe and you should too and share it with me.

index.html

<!DOCTYPE html>
<meta charset="utf-8">
    <style>
svg{
    background:#2379d5;
  }

  .texto{
    font-size:13px;
  }

  .pico{
    height:19;
    width:20;
  }
          /* CSS goes here. */
          .coun { fill: #27ae60;
          opacity:.6;
        stroke:black;
      stroke-width:.8; }

          .grat{
            stroke:grey;
            stroke-width:1px
          }

    .outside{

      fill: grey;
      opacity:.6;
    stroke:black;
  stroke-width:.8;

    }

    .city{
      fill:#fad959;
      r:10;
    }

    .outer{
      fill:black
    }
    .city:hover{
      fill:blue
    }

    .chams{
      height:100;
      width:100;
    }

    .rivs{
      stroke:#c6dbef;
    stroke-width:2.5;
    fill:none;
    //opacity:.5;
    }

    .keyer{
      position:absolute;
      background:#d9d9d9;
      height:120px;
      width:160px;
    }

    .troph{
      position:absolute;
      margin-top:-20px;
      margin-left:40px
    }

    .distan {
      position:absolute;
      margin-left:605px;
    }

    .distan p {
      font-size:.75em;

    }

    .highli{
      width:25px;
      height:25px;
      position:absolute;
    }
        </style>
    <body>
      <div class='highli'></div>
<div class='keyer'></div>
  <div class='distan'></div>

        <script src="//d3js.org/d3.v3.js"></script>
        <script src="//d3js.org/topojson.v1.js"></script>

<script src="turf.min.js" charset="utf-8"></script>


<script>

var height = 475;
var width = 600;

var projection = d3.geo.albers()
  .center([-54,-8.4])
  .parallels( [11.5,-38])
  .scale(550)
  //rotating is long lat and around the origin
  .rotate([55,-5,-5])
  .translate([width/2 - 450,height/2 -40])

  var graticule = d3.geo.graticule();

var svg = d3.select('body').append('svg').attr('width', width).attr('height', height);

var path = d3.geo.path()
.projection(projection);

svg.append('path')
  .datum(graticule)
  .attr('class', "grat")
  .attr('d',path)
  .attr('fill','none')
  ;


//    d3.select('path')        .append('g')

var somewor = 'click on an icon to see </br> distances to other cities';



d3.json('/mpmckenna8/raw/fcb2c2306c2bf249b719/brazilWor.json', function(err, world){
  if(err){console.log(err)}


  svg.selectAll('path')
    .data(topojson.feature(world,world.objects.countries110).features).enter().append('path')
    .attr('d',path)
    .on('hover',function(){
  //   console.log(this)
    //  return this.style('fill','purple');
    })
    .attr('class',function(d,i){
  //    console.log(i + 'this is for the countries class');
      return 'coun'})




d3.selectAll('.coun')
.attr('class',function(d,i){
//  console.log(i);
// The country data doesn't have any properties so I used the index # for brazil since it's the only thing I was going to change.
if(i===21){
return 'coun'
}
else{
return 'outside'
}
})
.on('click', function(d,i){
console.log(i);
})


d3.json('amaR.geojson',function(err,river){

svg.append('path')
//  .append('g')
.datum(river)
.attr('d',path)
.attr('class', function(d){
return 'rivs'
})


var citi = topojson.feature(world,world.objects.brazilCit).features

svg.selectAll('.shadows')
.data(citi)
.enter()
.append('circle')
.attr('d',path)
.attr('class', 'shadows')
.attr('r',6)
.attr('cx',2)
.attr('cy',2)
.attr("transform", function(d) { return "translate(" + projection(d.geometry.coordinates) + ")"; })
.attr('opacity',.3)
.attr('fill', '#fad959')
//console.log(citi)
//adding stuff all at once w/ datum like w/ graticule everthing it going to be the same.
// So the anonymous function in .attr('class',funct) is worthless more or less because it's all just one big thing.
svg.selectAll('.city')
.data(citi)
.enter()
.append('image')
.attr('d',path)
.attr('class',function(d){

//  console.log(d.properties.coun)
if(d.properties.coun ==="BRA"){

return 'city'
}
else{
return 'outer'

}
})

.attr("transform", function(d) { return "translate(" + projection(d.geometry.coordinates) + ")"; })


//this is where the river was


//adding my hightlight rectangle, need to change opacity to 0 to start when ready
svg.append('rect')
//.attr('d',path)
.attr('height',30)
.attr('width', 30).attr('fill', 'red').attr('opacity', 0).attr('class', 'heli')




var bigCit = 0;
var cupCit = []

d3.selectAll('.city')
.filter(function(d,i){
//  console.log(d.properties)
var namer = d.properties.name;
return namer == 'Fortaleza' || namer == 'Brasilia'|| namer =='Rio de Janeiro'
|| namer == 'Sao Paulo' || namer == 'Belo Horizonte' || namer == 'Salvador'
|| namer == 'Cuiaba'  || namer == 'Manaus' || (namer == 'Natal' && d.properties.pop > 1000000) || namer == 'Porto Alegre'
|| namer == 'Recife' || namer == 'Curitiba'
})


.attr('xlink:href',function(d,i){
cupCit.push(d);
//console.log(i);

// this is the first time i did a turf in a client thing
// console.log(d.properties.name + ' is ' + turf.distance(d,citi[6],'miles'));
if (d.properties.name =='Rio de Janeiro'){return '/mpmckenna8/raw/b87df1c44243aa1575cb/icon_51440.svg'}
else{
return ('/mpmckenna8/raw/b87df1c44243aa1575cb/icon_10684.svg')}})

.attr('height', function(d){
return '19'
})
.attr('width', '29')

// while adding an image to an svg these are the coordinates i think of the top left
.attr('x', '-14.5')
.attr('y', '-9.5')
.on('click',


function(d,i){



//console.log(d.properties.name)
console.log(this)




d3.selectAll('.texto')
.text(d.properties.name);


d3.select('.distan')
.html(function(){
  var copar = [];

  //console.log(cupCit);
  cupCit.forEach(function(opy){


    if (opy != d){
      opy.properties.distance = turf.distance(d,opy,'kilometers');
  //    console.log(opy.properties.name + ' ' + turf.distance(d,opy,'kilometers') + ' km');
      copar.push( opy.properties.name + ' ' + turf.distance(d,opy,'kilometers') + ' km</br>');
console.log(opy.properties.distance)

}
  })
// can do much better than just doing toString() on the array, like sort it based on difference and maybe label stuff or draw lines.
    return copar.toString();
})
.attr('class','distan')


d3.select('.heli')
.attr("transform", function() {
  console.log(d)
  return "translate(" + projection(d.geometry.coordinates) + ")"; })
  .attr('x', -15)
  .attr('y',-15)
  .attr('opacity',.8)



})
.attr('class', function(d){
if(d.properties.name == 'Rio de Janeiro'){
return 'chams'
}
else{
return 'pico'}
})




d3.select('.chams')
.attr('height',40)
.attr('width', 40)
.attr('y',-20)








console.log(bigCit)


})




})




// console.log(projection([-54,-8.4]))

d3.select('.keyer')
.style('margin-left', '415px')
.style('margin-top', '20px')

.append('html')
.html('<p>World Cup 2014</p><p>Brazil<img src=\'/mpmckenna8/raw/91cb9a5bc530bca95fc8/trophy.png\' class=\'troph\'/></p><p class=\'texto\'>'+somewor+'</p>')


// to add the image in the html element <img src=\'./WCtrophy\/trophy.png\' />

            </script>
    </body>