Example #1
0
initCanvas: function(){

	var w = this.$el.width();
	var h = this.$el.height();
	this.w = w;
	this.h = h;
	var innerRadius = Math.min(w, h) * 0.35;
	var outerRadius = innerRadius * 1.05;

    this.projection = d3.geo.orthographic()
        .scale(248)
        .clipAngle(90);

    var yawScale = d3.scale.linear()
        .domain([-(w/2), w/2])
        .range([-210, 210]);

    var pitchScale = d3.scale.linear()
        .domain([-(h/2), h/2])
        .range([60, -60]);

	var div = d3.select(this.el);
	this.canvas = div.append('canvas')
		.attr('width', w)
		.attr('height', h)
		.attr('id', 'globe')
		.classed('draggable', true);

	this.context = this.canvas.node().getContext('2d');

	var me = this;

	this.drag = d3.behavior.drag()
		.on('drag', function(d){
			if ( me.mouseStart ) {
				var mouse = d3.mouse(me.canvas.node());
				var dx = mouse[0] - me.mouseStart[0];
				var dy = mouse[1] - me.mouseStart[1];

				var yaw = me.currentRotation[0] + yawScale(dx);
				var pitch = me.currentRotation[1] + pitchScale(dy);
				me.projection.rotate([yaw, pitch, 0]);
				me.drawGlobe();
			}
		}).on('dragstart', function(d){
			me.currentRotation = me.projection.rotate();
			me.mouseStart = d3.mouse(me.canvas.node());
			me.canvas.classed({'dragging': true, 'draggable': false});
		}).on('dragend', function(){
			me.canvas.classed({'draggable': true, 'dragging': false});
		});


	this.canvas.call(this.drag);

	// this doesn't currently work. Why not?
	this.canvas.on('click', function(d){
		var mouse = d3.mouse(me.canvas.node());
		var lonlat = me.projection.invert(mouse);
	});
},
Example #2
0
function renderlocation(name, lon, lat, width, height) {

    var document = jsdom.jsdom();
    var overview_projection = d3.geo.orthographic()
        .scale(150)
        .translate([width / 2, height / 2])
        .rotate([-lon, -lat, -3])
        .clipAngle(90)
        .precision(.1);

    var overview_path = d3.geo.path()
        .projection(overview_projection)
        .pointRadius(function(d) {return 3;});

    var overview_graticule = d3.geo.graticule();

    var projection = d3.geo.satellite()
        .distance(1.1)
        .scale(2500)
        .rotate([-lon, -lat, -3])
        .center([0, 0])
        .tilt(20)
        .clipAngle(Math.acos(1 / 1.1) * 180 / Math.PI - 1e-7)
        .precision(.1);

    var graticule = d3.geo.graticule()
        .step([2, 2]);

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

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


    var graticuleStyle = {'fill':'none', 'stroke': '#777', 'stroke-width': '.5px', 'stroke-opacity': '.5'};
    var boundaryStyle = {'fill': 'none', 'stroke': '#fff', 'stroke-linejoin': 'round', 'stroke-linecap': 'round', 'stroke-width': '.5px'};
    var boundaryBigStyle = {'fill': 'none', 'stroke': '#666', 'stroke-linejoin': 'round', 'stroke-linecap': 'round', 'stroke-width': '1.5px'};
    var landStyle = {'fill': '#222'};
    var landContextStyle = {'fill': '#aaa'};
    var dotStyle = {'fill': '#c7141a'};
    var ringStyle = {'fill': 'none', 'stroke':'#c7141a'};
    var oceanStyle = {'fill': '#fff'};
    var oceanBigStyle = {'fill': '#eee'};
    var bboxStyle = {'fill':'#B10000', 'fill-opacity':.3, 'stroke-wdith':0.5, 'stroke':'#B10000', 'stroke-linejoin':'round'};
    var markerOuterStyle = {'fill':'#B10000', 'fill-opacity':0.3, 'stroke-wdith':0.5, 'stroke':'#B10000', 'stroke-linejoin':'round'};
    var markerInnerStyle = {'fill':'#B10000', 'fill-opacity':1, 'stroke-wdith':0.5, 'stroke':'#B10000', 'stroke-linejoin':'round'};



    svg.append("path")
        .datum(graticule)
        //.attr("class", "graticule")
        .style(graticuleStyle)
        .attr("d", path);



    points = []
    interpolationPoints = 200;

    //sample projection to find what's visible
    xStep = width / interpolationPoints;
    yStep = height / interpolationPoints;

    for (var x = 0; x < interpolationPoints; x++){
        xVal = xStep * x;
        for (var y = 0; y < interpolationPoints; y++){
            yVal = yStep * y;
            coord = projection.invert([xVal, yVal]);
            if (!isNaN(coord[0]) && !isNaN(coord[1])){
                points.push(coord);
            }
        }
    }

    hull = convexHull(points);
    hull.push(hull[0]);



    //d3.json("./admin12.json", function (error, world)


    svg.append("path")
        .datum({type: "Sphere"})
        //.attr("class", "ocean")
        .style(oceanBigStyle)
        .attr("d", path)


    svg.append("path")
        .datum(topojson.feature(admin12, admin12.objects.land, function (a, b) {
            return a !== b;
        }))
        //.attr("class", "land-context")
        .style(landContextStyle)
        .attr("d", path);

    svg.append("path")
        .datum(topojson.feature(admin12, admin12.objects.states, function (a, b) {
            return a !== b;
        }))
        //.attr("class", "boundary")
        .style(boundaryStyle)
        .attr("d", path);

    svg.append("path")
        .datum(topojson.mesh(world50m, world50m.objects.countries))
        .style(boundaryBigStyle)
        .attr("d", path);

    svg.append("path")
        .datum({type: "Sphere"})
        //.attr("class", "ocean")
        .style(oceanStyle)
        .attr("d", overview_path)
        .attr("transform", "translate("+ -width / 4 +"," + height / 5 + ")");

    //d3.json("./world-50m.json", function (error, world) {


    svg.append("path", ".graticule")
        .datum(overview_graticule)
        //.attr("class", "graticule")
        .style(graticuleStyle)
        .attr("d", overview_path)
        .attr("transform", "translate("+ -width / 4 +"," + height / 5 + ")");

    svg.append("path", ".graticule")
        .datum(topojson.feature(world50m, world50m.objects.countries))
        //.attr("class", "land")
        .style(landStyle)
        .attr("d", overview_path)
        .attr("transform", "translate("+ -width / 4 +"," + height / 5 + ")");

    svg.append("path", ".graticule")
        .datum(topojson.mesh(world50m, world50m.objects.countries))
        //.attr("class", "boundary")
        .style(boundaryStyle)
        .attr("d", overview_path)
        .attr("transform", "translate("+ -width / 4 +"," + height / 5 + ")");



    svg.append("path")
        .datum({type: "LineString", coordinates: hull})
        .attr("class", "bbox")
        .attr("d", overview_path)
        //.style({'fill':'#B10000', 'fill-opacity':.3})
        //.style({'stroke-wdith':0.5, 'stroke':'#B10000', 'stroke-linejoin':'round'})
        .style(bboxStyle)
        .attr("transform", "translate("+ -width / 4 +"," + height / 5 + ")");

    svg.append("circle")
        //.style({'fill':'#B10000', 'fill-opacity':0.3})
        //.style({'stroke-wdith':0.5, 'stroke':'#B10000', 'stroke-linejoin':'round'})
        .style(markerOuterStyle)
        .attr("transform", "translate(" + projection([lon, lat]) + ")")
        .attr("r", 14);

    svg.append("circle")
        //.style({'fill':'#B10000', 'fill-opacity':1})
        //.style({'stroke-wdith':0.5, 'stroke':'#B10000', 'stroke-linejoin':'round'})
        .style(markerInnerStyle)
        .attr("transform", "translate(" + projection([lon, lat]) + ")")
        .attr("r", 3);

    svg.selectAll("g")
        .data(name)
        .enter().append("g")
        .attr("transform", "translate(" + projection([lon, lat]) + ")")
        .append("text")
        .text(name)
        .attr("x", 14)
        .attr("y", -14)
        .attr("dy", ".35em");

    svg.append("text")
        .data(name)
        .attr("transform", function(d) {return "translate(" + projection([lon, lat]) + ")"})

    svg.append("path")
        .datum({type: "Point", coordinates: [lon, lat]})
        .attr("d", overview_path)
        //.style({'fill':'#B10000', 'fill-opacity':1})
        //.style({'stroke-wdith':0.5, 'stroke':'#B10000', 'stroke-linejoin':'round'})
        .style(markerInnerStyle)
        .attr("transform", "translate("+ -width / 4 +"," + height / 5 + ")");



    ret =  '<?xml version="1.0"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' + d3.select(document.body).html();

    return ret.replace('<svg ', '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" ');
}
        d3.select(ReactDOM.findDOMNode(this))
            .on('mousemove', this.onMouseMove)
            .on('mouseup', this.onMouseUp);
    },
    componentWillUnmount: function ()
    {
        GlobeViewStore.removeChangeDataListener(this._onChange);

        d3.select(ReactDOM.findDOMNode(this))
            .on('mousemove', null)
            .on('mouseup', null);

        d3.select(this.svg).on('mousedown', null);
    },
    buildChart() {
        this.proj = d3.geo.orthographic().clipAngle(90);
        this.sky = d3.geo.orthographic().clipAngle(90);

        this.path = d3.geo.path().projection(this.proj).pointRadius(2);

        let d3svg = d3.select(this.svg)
            .style('width', '100%')
            .style('height', '100%')
            .on('mousedown', this.onMouseDown);

        this.createDefiniions();
        this.createMap();

        d3svg.append('g').attr('class', 'flyers');
        d3svg.append('g').attr('class', 'arcs');
        d3svg.append('g').attr('class', 'src-points');
Example #4
0
worldGlobe.go = function(countryObject) {
  // Map configuration

  if(!worldGlobe.loaded){
    width  = 925;
    height = 820;
    sens = 0.25;
    // var rScale = d3.scale.sqrt();
    // var peoplePerPixel = 50000;
    // var max_population = [];

  // Configuration for the spinning effect
  time = Date.now();
  rotate = [0, 0];
  velocity = [0.005, -0];

  // Tool tip div
  countryTooltip = d3.select("body").append("div").attr("class", "countryTooltip");

  // Parse country data
  countries = topojson.feature(world, world.objects.countries).features;

  // set projection type and parameters
  projection = d3.geo.orthographic(3)
    .scale(300)
    .translate([(width / 2) + 10, (height / 2) ])
    .clipAngle(90)
    .precision(0.3);

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

  svg = d3.select(".globe").append("svg")
    .attr("width", "900")
    .attr("height", "720")
  g = svg.append("g")


  g.append("path")
    .datum({type: "Sphere"})
    .attr("class", "sphere")
    .attr("d", path)
    .attr("fill", "#1C6BA0")
    .attr("transform", "translate(0, -20)");


  worldPath = svg.selectAll("path.land")
    .data(countries)
    .enter().append("path")
    .attr("class", "land")
    .attr("d", path)
    .attr("fill", "#C1B398")
    .attr("transform", "translate(0, -20)")


  // Parse names for tool tip
  names.forEach(function(d){
    countryById[d.localeId] = d.countryName;
  });

  worldGlobe.loaded = true;
}

ready(null, world);

function ready(error, world) {

// spinning_globe();
//   //  TODO: work on making the globe spin and stop when the globe dragged
//    function spinning_globe(val){
//
//      d3.timer(function() {
//        rotate = [0, 0];
//        velocity = [0.005, -0];
//        // get current time
//        var dt = Date.now() - time;
//        // get the new position from modified projection function
//        projection.rotate([rotate[0] + velocity[0] * dt, rotate[1] + velocity[1] * dt]);
//        // update cities position = redraw
//        svg.selectAll("path.land").attr("d", path);
//        pause = val;
//        return pause;
//      });
//    }



    // Drag event
    worldPath.call(d3.behavior.drag()
    .origin(function() { var r = projection.rotate(); return {x: r[0] / sens, y: -r[1] / sens}; })
    .on("dragstart", function() {
      // d3.event.sourceEvent.stopPropagation();
      // console.log("Drag start");
      //  pause = true;
      //  spinning_globe(pause);
    })
    .on("drag", function() {
      var rotate = projection.rotate();
      projection.rotate([d3.event.x * sens, -d3.event.y * sens, rotate[2]]);
      svg.selectAll("path.land").attr("d", path);
      svg.selectAll(".focused").classed("focused", focused = false);
    })
    .on("dragend", function() {
      //  pause = false;
      //  spinning_globe(pause)
    })
 );
   //  Mouse events
   worldPath.on("mouseover", function(d) {
     countryTooltip.text(countryById[d.id])
     .style("left", (d3.event.pageX + 7) + "px")
     .style("top", (d3.event.pageY - 15) + "px")
     .style("display", "block")
     .style("opacity", 1);
   })
   .on("mouseout", function(d) {
     countryTooltip.style("opacity", 0)
     .style("display", "none");
   })
   .on("mousemove", function(d) {
     countryTooltip.style("left", (d3.event.pageX + 7) + "px")
     .style("top", (d3.event.pageY - 15) + "px");
   });

    //  // Zoom behavior
    // worldPath.call(d3.behavior.zoom()
    //    .scaleExtent([100, 800])
    //    .on("zoom", function(){
    //     //  worldPath.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
    //    }));

    // Click event from Country On Globe
    worldPath.on("click", function(d) {
      console.log("this is on click: ", d);
      var saved = d3.select("#c" + d.id);
      saved[0][0].click()
    });


    // rotate country when country is selected
    if(countryObject !== null && countryObject !== undefined){

      var rotate = projection.rotate(),
      focusedCountry = country(countries, countryObject);
      var p = d3.geo.centroid(focusedCountry);

      svg.selectAll(".focused").classed("focused", focused = false);
      if (focusedCountry){
        transition();
      } else {
        console.log("There is no Country!!");
      }
      //  Globe rotating
      function transition() {
        d3.transition()
        .duration(2500)
        .tween("rotate", function() {
          var r = d3.interpolate(projection.rotate(), [-p[0], -p[1]]);
          return function(t) {
            projection.rotate(r(t));
            svg.selectAll("path").attr("d", path)
            .classed("focused", function(d, i) {
                return d.id == focusedCountry.id ? focused = d : false;
             });
          };
        });
      };
    }
      // });

    function country(cnt, sel) {
      for(var i = 0, l = cnt.length; i < l; i++) {
        if(cnt[i].id == sel.localeId) {return cnt[i];}
      }
    }
  }

};
Example #5
0
define(function(require){
	"use strict";
	/*
	const options = {
        hostname: 'localhost',
        port: 443,
        path: '/',
        method: 'post',
        key: fs.readFileSync('privatekey.pem'),
        cert: fs.readFileSync('certificate.pem'),
        rejectUnhauthorized: false,
        agent: false // 从连接池中指定挑选一个当前连接状态为关闭的https.Agent
    },
    req = https.request(options);
	*/
	//require 
	const  topojson = require('topojson');
	const  d3          = require('d3');
	const  io           = require('socket');
	const  jQuery    = require('jquery');

	// HTML element
	//console.log("enter content !");
	//document.documentElement.style.overflowY = 'hidden';
	var width               = $('.twitter-tour-canvas').width();
	var height              = $('.twitter-tour-canvas').height();
	var $textSection     = $('#text-section');
	var $mediaimage   = $('#media-image');
	var $avatar             = $('#avatar');
	
	//speech variables
	var   speech, final_transcript ,velocity_index = 1;
	
	//D3  Geo variables
	var projection, path, λ, φ, canvas,context,sphere,graticule,grid,land,countries,borders,angle,rotate;
	var start                   = false;
	var curCoordinates   = [];
	var index                  = 0;
	var diameter = parseInt(height),
		radius = diameter>> 1,
		velocity = 0.005*velocity_index,
		then = Date.now(),
		angle_cache = 0;
	var circle = d3.geo.circle(); 
	var curLong;
	//tweets variables
	var tweetStats          = [];
	var tweetImgStats    = [];
	var textBeginx = Math.round(width*0.7),
		textBeginy = 0,
		textEndx = Math.round(width*0.96),
		textEndy = Math.round(height*0.96);
	var maxWidth = Math.round(width*0.26),
		lineHeight = 30,
		textMetrics,
		textHeight,
		FONT_HEIGHT = 128;	

	//    D3  Geo initialize
	projection = d3.geo.orthographic().scale(radius-2)
							.translate([parseInt(width*0.35), parseInt(height / 2)]).clipAngle(90);
	path         = d3.geo.path().projection(projection);
	λ              =  d3.scale.linear().domain([0, width]).range([-180, 180]);
	canvas     =  d3.select(".twitter-tour-canvas")
							.append("canvas")
							.attr("class", "canvas")
							.attr("width", width)
							.attr("height", height);
	context    = canvas.node().getContext("2d");
//////////////////////////////////////////////
/////////// star back ground//////////////
/////////////////////////////////////////////
/*
	var   w =width ,
	  h = height ,
	  hue = 217,
	  stars = [],
	  count = 0,
	  maxStars = 1200;

	var canvas2 = document.createElement('canvas'),
	  ctx2 = canvas2.getContext('2d');
	canvas2.width = 100;
	canvas2.height = 100;
	var half = canvas2.width / 2,
	  gradient2 = ctx2.createRadialGradient(half, half, 0, half, half, half);
	gradient2.addColorStop(0.025, '#fff');
	gradient2.addColorStop(0.1, 'hsl(' + hue + ', 61%, 33%)');
	gradient2.addColorStop(0.25, 'hsl(' + hue + ', 64%, 6%)');
	gradient2.addColorStop(1, 'transparent');

	ctx2.fillStyle = gradient2;
	ctx2.beginPath();
	ctx2.arc(half, half, half, 0, Math.PI * 2);
	ctx2.fill();

	// End cache

	function random(min, max) {
	  if (arguments.length < 2) {
		max = min;
		min = 0;
	  }

	  if (min > max) {
		var hold = max;
		max = min;
		min = hold;
	  }

	  return Math.floor(Math.random() * (max - min + 1)) + min;
	}

	function maxOrbit(x, y) {
	  var max = Math.max(x, y),
		diameter = Math.round(Math.sqrt(max * max + max * max));
	  return diameter / 2;
	}

	var Star = function() {

	  this.orbitRadius = random(maxOrbit(w, h));
	  this.radius = random(60, this.orbitRadius) / 12;
	  this.orbitX = w / 2;
	  this.orbitY = h / 2;
	  this.timePassed = random(0, maxStars);
	  this.speed = random(this.orbitRadius) / 900000;
	  this.alpha = random(2, 10) / 10;

	  count++;
	  stars[count] = this;
	}

	Star.prototype.draw = function() {
	  var x = Math.sin(this.timePassed) * this.orbitRadius + this.orbitX,
		y = Math.cos(this.timePassed) * this.orbitRadius + this.orbitY,
		twinkle = random(10);

	  if (twinkle === 1 && this.alpha > 0) {
		this.alpha -= 0.05;
	  } else if (twinkle === 2 && this.alpha < 1) {
		this.alpha += 0.05;
	  }

	  context.globalAlpha = this.alpha;
	  context.drawImage(canvas2, x - this.radius / 2, y - this.radius / 2, this.radius, this.radius);
	  this.timePassed += this.speed;
	}

	for (var i = 0; i < maxStars; i++) {
	  new Star();
	}

	function animation() {
	  context.globalCompositeOperation = 'source-over';
	  context.globalAlpha = 0.8;
	  context.fillStyle = 'hsla(' + hue + ', 64%, 6%, 1)';
	  context.fillRect(0, 0, w, h)

	  context.globalCompositeOperation = 'lighter';
	  for (var i = 1, l = stars.length; i < l; i++) {
		stars[i].draw();
	  };

	  window.requestAnimationFrame(animation);
	}
animation();
*/	

///////////////////////////////////////////
//////////star back ground/end ///////
//////////////////////////////////////////
	//  depict
	d3.json("data/world-110m.json", function(error, world) {
		sphere = {type: "Sphere"};
		graticule = d3.geo.graticule();
		grid = graticule();
		land = topojson.feature(world, world.objects.land),
		countries = topojson.feature(world, world.objects.countries).features,
		borders = topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; });

		//  rotate
		d3.timer(function() {
            
			//angle = velocity * (Date.now() - then);
			angle = angle_cache + 0.005*velocity_index * (Date.now() - then);
			then = Date.now();
			angle_cache = angle ;
			
			rotate = [0, 0, 0]; 
			rotate[0] = angle;
			projection.rotate(rotate);
			
			context.clearRect(0, 0, width, height);
			
			//globe
			path(sphere);
			context.lineWidth = 1;
			context.strokeStyle = "#000";
			context.stroke();
			context.fillStyle = "#fff";
			context.fill();
			//project the back of the globe
			projection.clipAngle(180);
			context.beginPath();
			path(land);
			context.fillStyle = "#dadac4";
			context.fill();
			//project the front of the globe
			projection.clipAngle(90);
			context.beginPath();
			path(grid);
			context.lineWidth = .5;
			context.strokeStyle = "rgba(119,119,119,.5)";
			context.stroke();
			//land
			context.beginPath();
			path.context(context)(land);
			context.fillStyle = "#434338";
			context.fill();
			context.lineWidth = .5;
			context.strokeStyle = "#000";
			context.stroke();
			//border
			context.beginPath();
			path(borders);
			context.strokeStyle = "#fff";
			context.lineWidth = .5;
			context.stroke();
			//twinkle
			if(angle % 360 <180){
				curLong = -angle % 360;
			}else{
				curLong = 360 - (angle % 360);
			}
			if(start && (curCoordinates[0] < curLong+75)){
				context.save();
				context.beginPath();
				path(circle.origin(curCoordinates).angle(0.9)());
				context.fillStyle = '#FF0000';
				context.fill();
				context.lineWidth = '25';
				context.strokeStyle = 'rgba(255,'+Math.round(255*Math.cos(angle))+','+Math.round(255*Math.cos(angle))+', 0.4)';
				context.stroke();
				context.restore();
			}
		});		
	});		


		
	function renderData(){
		$avatar.attr('src',"");
		$avatar.hide();
		$textSection.hide();
		$mediaimage.attr('src','');
		$mediaimage.css('display','none');
	
		try{
			if(tweetStats.length > 0){
				console.log('we have '+tweetStats.length+' tweets !');
				var dataToRender;
				//select right tweet
				if(tweetStats && tweetStats.length >0){
					for(var i=0;i<tweetStats.length;i++){
						var curangle;
						
						if(angle % 360 <180){
							curangle = -angle % 360;
						}else{
							curangle = 360 - (angle % 360);
						}
						
						var longitude = tweetStats[i].coordinates.coordinates[0];
						
						if(longitude < curangle+90 &&  longitude > curangle-90 && (tweetStats[i].user) ) {
							dataToRender = tweetStats[i];
							tweetStats.splice(i,1); 
							start = true ;
							break;
						}else{
							start = false ;
						}
					}
				}		
				
				var tweetlink = 'https://twitter.com/'+ dataToRender.user.screen_name +'/status/'+ dataToRender.id_str;
				//longitude latitude
				curCoordinates = [dataToRender.coordinates.coordinates[0],dataToRender.coordinates.coordinates[1]];
				var  tweet_text = dataToRender.text.replace(/(\b(http|https)+\S*\b)*/g,'');
				//console.log("curangle is "+(angle%360)+" ,and coordinates is "+curCoordinates);
		
				//$avatar.attr('src',dataToRender.user.profile_image_url);
				$avatar.attr('src',dataToRender.user.profile_image_url_https);
				$avatar.load(function(){
					$avatar.show();	
					$textSection.html("<p>" + tweet_text + "<a href='" + tweetlink + "' target='_blank'> @</a></p>");
					$textSection.show();
				});
				
				if( dataToRender.entities && dataToRender.entities.media && dataToRender.entities.media.length ){
					if( window.location.protocol == 'http:'){
						$mediaimage.attr('src',dataToRender.entities.media[0]['media_url']);
						//console.log("getting img !");
					} else {
						$mediaimage.attr('src',dataToRender.entities.media[0]['media_url_https']);
						//console.log("getting img !");
					}
					$mediaimage.show(500);	
				}	
			}	
		}catch(err){
			console.log(err.message);
		}
		setTimeout(renderData,5000);
	}	

	function makeDataRequest_socket(){
		console.log(" a new  socket  request at  "+(new Date()).toString().substring(16,24));
		/*
		if(window.location.protocol = 'https:'){
			var url = window.location.protocol + '//104.224.166.80:443';
		}else{
			var url = window.location.protocol + '//104.224.166.80:80';
		}
		*/
        
        //  
		//var url = window.location.href;
        var url = window.location.protocol +"//"+ window.location.host;

		var socket = io.connect(url);
		socket.emit('tweets_request', { 'new': 'data_request !' });
		socket.on('tweets_response',function(data){
			if( data && data.length > 0) {	
				console.log("new "+data.length +" tweets get !");	
				//tweetStats = data;	
				if( tweetStats.length < 10) {	
					for(var j=0;j<data.length;j++){
						tweetStats.push(data[j]);
                        preload_img(data[j].user.profile_image_url_https);
						if( data[j].entities && data[j].entities.media && data[j].entities.media.length ){
                            // preload img      
                            preload_img(data[j].user.profile_image_url_https);
                            if( window.location.protocol == 'http:'){
                                console.log("loading img ");
                                preload_img(data[j].entities.media[0]['media_url']);
                            } else {
                                preload_img(data[j].entities.media[0]['media_url_https']);
                            }
                            
						}
					}
				}else{
					for(var k=0;k<data.length;k++){
						/*if(/(instagram)+/i.test(data[k])){
							tweetStats.push(data[k]);
						}else  */
						if( data[k].entities && data[k].entities.media && data[k].entities.media.length ){
							tweetStats.push(data[k]);
                            // preload img      
                            preload_img(data[k].user.profile_image_url_https);
                            if( window.location.protocol == 'http:'){
                                console.log("loading img ");
                                preload_img(data[k].entities.media[0]['media_url']);
                            } else {
                                preload_img(data[k].entities.media[0]['media_url_https']);
                            }
                            
						}
					}
				}	
			}
		});
		setTimeout(makeDataRequest_socket,100000);
	}
	
	renderData();
	makeDataRequest_socket();
    

//  preload img 

function preload_img(img_url){
    
    var newimages=new Image();
    newimages.src=img_url;
    newimages.onload=function(){
        console.log(img_url+" loaded !");
    }
    newimages.onerror=function(){
        console.log(img_url+" load error !");
    }
}
// preload img end  
    
    
    
    
    
/////////////////////////////////////////
//  speech interface
////////////////////////////////////////

//    velocity_index
//   velocity = .005



if ('webkitSpeechRecognition' in window) {
	//var timeout , result;
	var  last_time_stamp = Date.now();
	var  threshold = 2000;
	
	function speech_recognition_initialize() {
	  speech = new webkitSpeechRecognition();
	  speech.continuous = true;
	  speech.maxAlternatives = 5;
	  speech.interimResults = true;
	  speech.lang =  "cmn-Hans-CN";
	  speech.start();
	  //    speech.stop();
	}
	   
	speech_recognition_initialize();

	speech.onresult = function(e) {
		
		if (typeof(e.results) == 'undefined') {
			return;
		}
		//console.log(e);
		for (var i = e.resultIndex; i < e.results.length; ++i) {
			var val = e.results[i][0].transcript;
			//console.log(val);	
			if ( e.results[i].isFinal ) {
				final_transcript =   val;
				console.log(val);

			} 
		}
		if(final_transcript){
/*			
			if (timeout) {
				clearTimeout(timeout);
			}
			timeout = setTimeout(change_velocity_index, 500);
*/
			
			if(Date.now() - last_time_stamp  > threshold){
				change_velocity_index();
				last_time_stamp = Date.now();
			}
			
			//if(voice_interface_keywords.some(function(item, index, arr){})){}
			function change_velocity_index(){
				if((/快+/).test(final_transcript)){
					console.log("快");
					velocity_index *= 2;
				}else if((/慢|卖+/).test(final_transcript)){
					console.log("慢");
					velocity_index /= 2;
				}else if((/停|请+/).test(final_transcript)){
					console.log("停");
					velocity_index = 0;
				}else if((/(倒|反|返)+/).test(final_transcript)){
					console.log("反");
					velocity_index = velocity_index ? velocity_index*(-1) : -1;
				}else if((/(常|正)+/).test(final_transcript)){
					console.log("正常");
					velocity_index = 1;
				}
			}
				
			
		}
		//console.log(final_transcript);
		//console.log(interim_transcript);

	};

	speech.onerror = function(e) {
		var msg = e.error + " error";
		if (e.error === 'no-speech') {
			msg =  "No microphone  detected ";
		} else if (e.error === 'audio-capture') {
			msg =  "Please ensure your microphone is connected ";
		} else if (e.error === 'not-allowed') {
			msg = " Please allow Microphone access ";
		}
		console.log(e.error);
		console.log(msg);
	};

} 







	function  debounce(func, wait, immediate) {
			var timeout, result;

			var later = function (context, args) {
				timeout = null;
				if (args) result = func.apply(context, args);
			};

			var debounced = restArgs(function (args) {
				// 一旦存在timeout, 意味之前尝试调用过func
				// 由于debounce只认最新的一次调用, 所以之前等待执行的func都会被终止
				if (timeout) clearTimeout(timeout);
				// 如果允许新的调用尝试立即执行,
				if (immediate) {
					// 如果之前尚没有调用尝试,那么此次调用可以立马执行,否则一定得等待之前的执行完毕
					var callNow = !timeout;
					// 刷新timeout
					timeout = setTimeout(later, wait);
					// 如果能被立即执行,立即执行
					if (callNow) result = func.apply(this, args);
				} else {
					// 否则,这次尝试调用会延时wait个时间
					timeout = delay(later, wait, this, args);
				}
				return result;
			});
			debounced.cancel = function () {
				clearTimeout(timeout);
				timeout = null;
			};
			return debounced;
	};

	function  throttle (func, wait, options) {

        var timeout, context, args, result;
        // 最近一次func被调用的时间点
        var previous = 0;
        if (!options) options = {};

        // 创建一个延后执行的函数包裹住func的执行过程
        var later = function () {
            // 执行时,刷新最近一次调用时间
            previous = options.leading === false ? 0 : new Date();
            // 清空定时器
            timeout = null;
            result = func.apply(context, args);
            if (!timeout) context = args = null;
        };

        // 返回一个throttled的函数
        var throttled = function () {
            // ----- 节流函数开始执行----
            // 我们尝试调用func时,会首先记录当前时间戳
            var now = new Date();
            // 是否是第一次调用
            if (!previous && options.leading === false) previous = now;
            // func还要等待多久才能被调用 =  预设的最小等待期-(当前时间-上一次调用的时间)
            // 显然,如果第一次调用,且未设置options.leading = false,那么remaing=0,func会被立即执行
            var remaining = wait - (now - previous);
            // 记录之后执行时需要的上下文和参数
            context = this;
            args = arguments;

            // 如果计算后能被立即执行
            if (remaining <= 0 || remaining > wait) {
                // 清除之前的“最新调用”
                if (timeout) {
                    clearTimeout(timeout);
                    timeout = null;
                }
                // 刷新最近一次func调用的时间点
                previous = now;
                // 执行func调用
                result = func.apply(context, args);
                // 如果timeout被清空了,
                if (!timeout) context = args = null;

            } else if (!timeout && options.trailing !== false) {
                // 如果设置了trailing edge,那么暂缓此次调用尝试的执行
                timeout = setTimeout(later, remaining);
            }
            return result;
        };

        // 可以取消函数的节流化
        throttled.cancel = function () {
            clearTimeout(timeout);
            previous = 0;
            timeout = context = args = null;
        };

        return throttled;
    };





/////////////////////////////////////////
//  speech interface  end
////////////////////////////////////////

/*	
	function makeDataRequest_ajax(){
		console.log("        makeDataRequest  ");
		$.ajax({
			method: 'GET',
			//url: window.location.protocol + '//amormaid.tk:8080',
			url: window.location.protocol + '//127.0.0.1:80/tweets',
			contentType: 'application/json',
			success: function(data){
				if( data.length && data.length > 0) {	
				console.log("new "+data.length +" tweets get !");	
					//tweetStats = data;	
					if( tweetStats.length < 10) {	
						for(var j=0;j<data.length;j++){
							tweetStats.push(data[j]);
						}
						data = [];
					}else{
						for(var k=0;k<data.length;k++){
							if( data[k].entities && data[k].entities.media && data[k].entities.media.length ){
								tweetImgStats.push(data[k]);
							}
						}
						data = [];
					}	
				}
			},
			error: function(){
				console.log("makedatarequest error !");
			}
		});
		
		if(tweetStats.length < 50){
			setTimeout(makeDataRequest_ajax,10000);
		}else{
			setTimeout(makeDataRequest_ajax,100000);
		}
	}

*/

	
/*
	(function(){
		makeDataRequest();
		setTimeout(renderData,6000);
	})();
*/	
});
Example #6
0
var actionVisualization = function (container_selector, service) {

    var information =
        [
            "Breathe deeply and be thankful that your city is one of of those where the average air quality meets the WHO recommendation for fine particulate pollution.<br><br>Keep in mind that pollution values can vary significantly day to day and in different locations within a city, so you there may still be times where the air you breathe is damaging to your health.  Children, those with heart or lung diseases and asthma sufferers are at high risk and should monitor  <a href='http://aqicn.org/map/world/'>air quality</a> before undertaking any strenuous exercise.",
            "Unfortunately the air your breathe is more polluted that the WHO guideline for average fine particulate pollution.  Checking the <a href='http://aqicn.org/map/world/'>air quality</a> in your city should be part of your daily routine so you can protect your health, and the health of your family from the harmful health effects of polluted air <br><br> Keep in mind that pollution values can vary significantly day to day and in different locations within a city, so there may be times where the air you breathe is highly damaging to your health.  Children, those with heart or lung diseases and asthma sufferers are at high risk and should refrain from any strenuous exercise on days with high levels of pollution. <br><br> Purchasing an air pollution mask will allow you to reduce your exposure when you need to be outside during days with poor air quality.  Only masks rated as N95 or higher by the NIOSH are considered effective at filtering the finest and most damaging pollution particles.",
            "Unfortunately you live in a city where the air is polluted with high concentrations of fine particulate matter.  Most likely you are already aware of the problem and may have experienced side effects from breathing this air on a regular basis. Symptoms include irritation of the eyes, nose, and throat; coughing; phlegm; chest tightness; and shortness of breath.<br><br>Checking the <a href='http://aqicn.org/map/world/'>air quality</a> in your city before you go out is essential so you can protect your health, and the health of your family from the harmful health effects of polluted air.  You should stay indoors and reduce physical acting on days with very poor air quality.  Special care should be taken to ensure vulnerable groups including children, those with heart or lung diseases and asthma sufferers are monitored. Particle exposure can cause serious problems in a short period of time, with no warning signs.  <br><br>All citizens should carry an air pollution mask, allowing you to reduce your exposure when you need to be outside during days with poor air quality.  Only masks rated as N95 or higher by the <abbr title='National Institute for Occupational Safety and Health'>NIOSH</abbr> are considered effective at filtering the finest and most damaging pollution particles.  Home air filters fitted with a true HEPA filter may also help reduce long-term exposure."
        ]; 

    var model = this;
    model.service = service;
    model.topo = service.getActiveDataset("mapTopoJson");
    model.coords = service.getActiveDataset("coords");

    // init data
    var width = 800,
        height = 500,
        radius = 240;

    model.rotate = [0, 0, 0];

    var projection = d3.geo.orthographic()
        .scale(radius)
        .clipAngle(90);

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


    // UNCOMMENT FOR MANUAL DRAG
    model.drag = d3.behavior.drag()
        .origin(function () {
            model.transition = false;
            return {x: model.rotate[0], y: -model.rotate[1]};
        })
        .on("drag", function () {
            model.rotate[0] = d3.event.x;
            model.rotate[1] = -d3.event.y;

            // limit y axis to make it easier to navigate
            if (model.rotate[1] > 50) {
                model.rotate[1] = 50;
            }

            if (model.rotate[1] < -50) {
                model.rotate[1] = -50;
            }

            projection.rotate(model.rotate);
            path = d3.geo.path().projection(projection);
            var path2 = d3.geo.path().projection(projection).pointRadius(4);
            var path3 = d3.geo.path().projection(projection).pointRadius(1.5);
            model.land.selectAll("path").attr("d", path);
            model.points.selectAll("path").attr("d", path3);
            model.countryspot.selectAll("path").attr("d", path2);
        })
        .on("dragstart", function () {
            model.svg.attr("class", "dragstart");
        })
        .on("dragend", function () {
            model.svg.attr("class", "dragend");
            model.transition = true;
        });

    // init SVG
    model.svg = d3.select(container_selector).append("svg")
        .attr("width", width)
        .attr("height", height)
        .append("g")
        // Add for Manual drag
        .attr("class", "dragend")
        .call(model.drag);

    model.water = model.svg.append("g");
    model.land = model.svg.append("g");
    model.points = model.svg.append("g");
    model.countryspot = model.svg.append("g");
    model.shadow = model.svg.append("g");
    model.shadow = model.shadow.append("ellipse")
        .attr("cx", width / 2 + 80)
        .attr("cy", height - 10)
        .attr("rx", 150)
        .attr("ry", 10)
        .style("opacity", 0.1);


    // set background
    var globe = {type: "Sphere"};


    model.water = model.water.append("path")
        .datum(globe)
        .attr("class", "water")
        .attr("d", path);

    // set land
    model.land.selectAll("path")
        .data(topojson.feature(model.topo, model.topo.objects.countries).features)
        .enter().append("path")
        .attr("d", path)
        .attr("class", "feature2");


    model.startRotate = function () {


        var velocity = 0.5;

        d3.timer(function () {


            if (model.transition === false) {
                return;
            }


            // UNCOMMENT TO ROTATE TO CITY

            //var y = Math.abs(model.rotate[0] - model.oldrotate[0]);
            //var x = Math.abs(model.rotate[1] - model.oldrotate[1]);
            //if (x < (velocity * 2) - 0.1 && y < (velocity * 2) - 0.1) {
            //    model.transition = false;
            //    return;
            //}
            //if (x > (velocity * 2)) {
            //
            //    if (model.rotate[1] > model.oldrotate[1]) {
            //        model.oldrotate[1] += velocity;
            //    }
            //    else if (model.rotate[1] < model.oldrotate[1]) {
            //        model.oldrotate[1] -= velocity;
            //    }
            //}
            //if (y > (velocity * 2)) {
            //    if (model.rotate[0] > model.oldrotate[0]) {
            //        model.oldrotate[0] += velocity;
            //    }
            //    else if (model.rotate[0] < model.oldrotate[0]) {
            //        model.oldrotate[0] -= velocity;
            //    }
            //}

            // AUTO ROTATION
            model.oldrotate[0] += velocity;

            projection.rotate(model.oldrotate);
            path = d3.geo.path().projection(projection);
            var path3 = d3.geo.path().projection(projection).pointRadius(1.5);
            var path2 = d3.geo.path().projection(projection).pointRadius(4);
            model.land.selectAll("path").attr("d", path);
            model.points.selectAll("path").attr("d", path3);
            model.countryspot.selectAll("path").attr("d", path2);


        });


    }
    ;

// set city
    model.update = function () {
        

        var cityString = model.service.getSelectedCityData();


        cityString = (cityString.city + ", " + cityString.country);


        model.points.selectAll(".pin").remove();

        var datapoints = [];

        var select = null;
        model.points.selectAll(".pin").data(model.coords).enter().append("path")
            .datum(function (d) {

                if (datapoints[d.region]) {
                    datapoints[d.region]++;
                }
                else {
                    datapoints[d.region] = 1;
                }


                return {
                    type: "Point",
                    coordinates: [d.longitude, d.latitude],
                    val: d.city,
                    color: service.regionScale(d.region)
                };
            })
            .attr("class", "notShown")
            .style("fill", function (d) {
                return d.color;
            })
            .transition()
            .delay(function (d, i) {
                return 3 + 3 * i;
            })

            .attr("class", function (d) {
                if (d.val === cityString) {
                    select = d;
                }
                return "pin notSelected";

            })
        ;

        if (model.country !== null) {
            model.countryspot.selectAll(".pin").remove();
        }

        model.country = model.countryspot.append("path")
            .datum(function () {
                return select;
            })
            .attr("class", "pin selected");


        model.oldrotate = model.rotate;

        // UNCOMMENT FOR ROTATE TO CITY
        //projection.rotate([-city.coordinates[0], -city.coordinates[1]]);
        //model.rotate = projection.rotate();
        //if (model.rotate[1] > 50) {
        //    model.rotate[1] = 50;
        //}
        //if (model.rotate[1] < -50) {
        //    model.rotate[1] = -50;
        //}


        if (!model.transition) {

            model.startRotate(model.oldrotate, model.rotate);
        }
        model.transition = true;


        var table = $("#datapoints");
        table.empty();

        for (var key in datapoints) {
            if (key !== "undefined")
                if (datapoints.hasOwnProperty(key)) {

                    var row = "<tr><td>" + key + "</td><td>" + datapoints[key] + "</td></tr>";
                    table.append(row);

                }
        }


        var data = model.service.getSelectedCityData()["pm2.5Mean"];

        var i = 0;
        if (data <= 10) {
            i = 0;
        }
        else if (data <= 30) {
            i = 1;
        }
        else {
            i = 2;
        }

        $("#protection").html(information[i]);
    };


};