• Arminder Gill Feb-12-2019 07:15:50 AM ( 5 days ago )

I have a map I've created with d3-tile. I've added code to show hexbins gathered from the dataset based on longitude and latitude. But the hexbins are not showing. I've only found examples that plot plain cartesian data in hexbins, not latitude longitudes with hexbins laid over a map made with d3-tile. Why are my hexbins not showing?

Here's how I define the projection, tiles and hexbins:

``````var projection = d3.geo.mercator()
.scale((1 << 22) / 2 / Math.PI)
.translate([width / 2, height / 2]);

var tile = d3.geo.tile()
.size([width, height]);

// define hexbins
var hexbin = d3.hexbin()
.size([width, height])

And here's how I process my data and add hexbins to the map:

``````data.forEach(function (d) {
d.lat = +d.lat;
d.lon = +d.lon;
});

points = [];

// x,y maps to lng,lat - ref[2]
data.forEach(function (d) {
d.lat = +d.lat;
d.lon = +d.lon;
var x = projection([d.lon, d.lat])[0];
var y = projection([d.lon, d.lat])[1];
points.push([x, y]);
});

// bin coords
var bins = hexbin(points);
var bins_n = []; // points per hexbin
bins.forEach(function (d) {
bins_n.push(d.length);
});

// second of two scales for linear hexagon fill - ref[1]
var extent = d3.extent(bins_n);
var fill_scale2 =
``````
``` ```
• ``` Nageshwer Reddy Feb-12-2019 07:17:22 AM ( 5 days ago ) That's a very large value for a scale - if you log the projected x,y coordinates (or points in your case), you'll probably see coordinates that aren't within the bounds of your svg. The scale for d3-tile is usually 1/Math.PI/2: it projects the world to a one pixel square and then uses the zoom to translate and scale it across the screen. It is not the most intuitive method. The projection is causing your issues, but with the zoom, the hexagon is a little bit more complex than usual. I'm a bit busy at the moment, but will take a closer look in a bit. Apoorva Saxena Feb-12-2019 07:18:19 AM ( 5 days ago ) I'll use this example to build my answer. This zoomable example, as opposed to this example one, is zoomable. Projection Scale First, I'll just explain the scale using the above example. It uses a projection that has a starting scale of 1/tau: the 2 π radians of the world are stretched over one pixel. The translate is [0,0], so that 0°N, 0°E is at [0,0] of the SVG. The scale and translate of the map is managed by d3.zoom: projection.scale(transform.k / Math.PI / 2) .translate([transform.x, transform.y]); As k represents the zoom factor, and our starting map width was 1, k represents map width and height. Dividing by tau we get how many pixels of the map correspond to each radian of the earth. The translate centers the map. The reason why you can't see any hexbins in your example is because you use a scale of that stretches the earth over and area 4194304 pixels wide (1<<22), but your hexbins only stretch over an area the size of your SVG. You see no hexagons because the extent of your SVG represents only a small geographic extent - some area of ocean north of the Bering Sea. Also for reference: The relationship between map scale and map width is not consistent across all map projections Adding hexbins (fixed) If we want hexagonal binning with bins that remain the same geographical size regardless of zoom, we can set the radius and extent to reflect our initial projection (before applying the zoom): var hexbin = d3.hexbin() .radius(0.01) .extent([[-0.5, -0.5], [0.5, 0.5]]); We can then pass it projected points, using the initial projection, and transform the hexagons based on the zoom while scaling the stroke width of the hexagons based on zoom scale:   Show code snippet   Adding hexbins (updated with zoom) However, if we want to change the bins scale as we zoom in the code is potentially a bit easier, but computationally more complex. To do so we recalculate the hexbins each zoom based on the projected coordinates of the points after applying the current projection: var hexbin = d3.hexbin() .radius(30) .extent([[0,0], [width,height]]) // extent of projected data (displayed) .x(function(d) { return projection(d)[0]; }) .y(function(d) { return projection(d)[1]; }) The extent and radius reflect the entire SVG extent - the visible extent to which we are projecting the data after the zoom is applied - the extent we want to add hexagons to. Below I recalculate the hexes each zoom/pan:   Show code snippet   Both examples randomly create some data over land masses, this is the primary reason for the slow load Last thoughts Both examples leave a fair amount to be desired, the method of organizing coordinate spaces with d3-tile and the hexagons is a bit less intuitive than possible - and can take a bit to get used to. But, for the moment there aren't a lot of alternatives.   ```
``` ```
``` Please login ```
``` ```
``` Similar Discussion How do I convert an existing callback API to promises? Posted By: Jai Khanna Bugs & Fixes Feb-15-2019 10:53:01 AM ( 2 days ago ) 14 AngularJS: Service vs provider vs factory Posted By: Ekta Singhania Bugs & Fixes Feb-15-2019 09:33:46 AM ( 2 days ago ) 4 How to allow CORS? Posted By: Shreya Bansal Bugs & Fixes Feb-15-2019 07:42:37 AM ( 2 days ago ) 9 Retrieve only the queried element in an object array in MongoDB collection Posted By: Liza Sain Bugs & Fixes Feb-15-2019 06:50:51 AM ( 2 days ago ) 13 Recommended For You Jobs Internships Services Projects Courses Trainings Workshops Addmissions Study Abroad Question Bank Pre-Assessment Affiliate Marketing Webinars var owl = \$("#jobseeker-slide, #similar-courses-slider,#similar-admission-slider,#study-abroad-slider,#similar-training-slider,#similar-workshop-slider,#similar-projects-slider"); owl.owlCarousel({ itemsCustom : [ [0, 1], [450, 1], [600, 1], [700, 1], [1024, 2], [1200, 2], [1400, 2], [1600, 3] ],navigationText: [ "<i class='fa fa-angle-left'></i>", "<i class='fa fa-angle-right'></i>" ], navigation:true, loop:true, autoPlay: true, autoplayTimeout: 100, stopOnHover : true, autoHeight:true }); var owl2 = \$("#courses-slide,#train-slide,#wshop-slide,#intern-slide,#sjobs-slide,#sprojects-slide,#services-slider,#similar-internship-slider,#similar-shortjobs-slider"); owl2.owlCarousel({ itemsCustom : [ [0, 1], [450, 1], [600, 1], [700, 1], [1024, 4], [1200, 4], [1400, 4], [1600, 4] ], navigationText: [ "<i class='fa fa-angle-left'></i>", "<i class='fa fa-angle-right'></i>" ], navigation:true, loop:true, autoPlay: false, autoplayTimeout: 100, stopOnHover : true }); ```
``` ```
``` ```
``` ```
``` ```
``` TuteeHUBBeta A Gateway of Opportunities Sign In Alert Please Sign In To Continue. TuteeHUBBeta A Gateway of Opportunities TuteeHUB is a technology driven cloud platform to "Learn, Work & Earn" through learning products, self-development services, employment and remote work options with integrated marketing & promotions opportunities. 011-42427761 info[@]tuteehub[.]com Social Connect Help & Support Forum Help Desk FAQ Insights Career News Articles Feeds Our Services Pre Assessment Exclusive Services Courses & Admissions Trainings & Workshops Jobs Internships Projects Services Affiliate Marketing Webinars Our Community Scholars Corporates Consultants Campus Institutes Affiliates App Download Latest Article National Fertilizers Limi... February 15, 2019 National Fertilizers Limited (... Andhra Pradesh Public Ser... February 15, 2019 Applications are invited throu... The Job Interview Cheat S... February 14, 2019 Your CV can get you shortliste... Newsletter App Download        Social Connect About Us How It Works Privacy Policy Terms & Conditions Contact Us   Copyright © 2018 TuteeHUB. All Right Reserved. TuteeHUBBeta A Gateway of Opportunities Plan Upgrade Alert! Please Upgrade Your Plan! GET LATEST OPENINGS IN YOUR INBOX Jobs | Project | Services | Internship | Courses | Career News /* alert(position); */ var isshow =sessionStorage.getItem('isshow'); /* if (isshow== null) { sessionStorage.setItem('isshow', 1); setTimeout(function(){\$('#get-response-modal').modal();},1500); } */ /* \$(document.ready(function(){ if (\$.cookie('test_status') != '1') { \$('#get-response-modal').modal(); \$.cookie('test_status', '1', { expires: 6000}); } }) */ var position=\$('footer').offset().top; // \$(window).scroll(function(){ // var ws=\$(window).scrollTop(); // var newp=position+40; // if(ws>position && ws<newp) // { // sessionStorage.setItem('isshow', 'null'); // \$('#get-response-modal').modal(); // }}) function checkAccess() { /* \$('#accessMessage').html('Please Upgrade Your Plan'); */ \$('#accessModule').modal(); } \$('i[data-toggle="popover"]').popover(); \$(".left-side-bar").niceScroll({ cursorcolor:"rgba(0,0,0,0.5)", cursorwidth:"8px" }); function INAuth(){ IN.User.authorize(function(){ InLoad(); }); } // Setup an event listener to make an API call once auth is complete function InLoad() { IN.Event.on(IN, "auth", InProfileData); } // Handle the successful return from the API call function InSuccess(profile) { \$('.loaders').show(); var email = profile.values[0].emailAddress; var fname = profile.values[0].firstName; var lname = profile.values[0].lastName; var siteurl = \$('meta[name=siteurl]').attr('content'); var CSRF_TOKEN = \$('meta[name=_token]').attr('content'); if(email != '' && fname != '') { \$.ajax({ url: siteurl+'/user/register', dataType: "json", type: "POST", data: { '_token': CSRF_TOKEN, 'email': email, 'fname': fname, 'lname': lname, 'registerVia': 'socialMedia', 'socialMediaName': 'linkedin' }, success: function(response) { \$('.loaders').hide(); if(response == 'IsLoggedin') { window.location = siteurl+'/user/dashboard'; } } }); } else { InError('error'); } \$('.InloginButton').remove(); InLogout(); } function InLogout() { // if (IN.User.isAuthorized()) // { // IN.User.logout(); // } } // Handle an error response from the API call function InError(error) { \$('.InloginButton').remove(); InLogout(); alert('Something Went wrong, Please Try another Login/Register Option'); } // Use the API call wrapper to request the member's basic profile data function InProfileData() { IN.API.Profile("me").fields(["firstName","lastName", "emailAddress", "phone-numbers"]).result(InSuccess).error(InError); } function FBAuth(){ FB.login(checkLoginState, {scope: 'email,public_profile', return_scopes: true}); } function checkLoginState() { FB.getLoginStatus(function(response) { statusChangeCallback(response); }); } function statusChangeCallback(response) { if (response.status === 'connected') { FBProfileData(); } else {} } function FBProfileData() { FB.api('/me?fields=id,name,email', function(response) { var name = response.name; var username = name.split(' '); var firstName = username[0]; var lastName = username[username.length - 1]; \$('.loaders').show(); var email = response.email; var fname = firstName; var lname = lastName; var siteurl = \$('meta[name=siteurl]').attr('content'); var CSRF_TOKEN = \$('meta[name=_token]').attr('content'); if(email != '' && fname != '') { \$.ajax({ url: siteurl+'/user/register', dataType: "json", type: "POST", data: { '_token': CSRF_TOKEN, 'email': email, 'fname': fname, 'lname': lname, 'registerVia': 'socialMedia', 'socialMediaName': 'facebook' }, success: function(response) { \$('.loaders').hide(); if(response == 'IsLoggedin') { window.location = siteurl+'/user/dashboard'; } } }); } }); } function onSignIn(googleUser) { var profile = googleUser.getBasicProfile(); var name = profile.getName(); var username = name.split(' '); var firstName = username[0]; var lastName = username[username.length - 1]; \$('.loaders').show(); var email = profile.getEmail(); var fname = firstName; var lname = lastName; var siteurl = \$('meta[name=siteurl]').attr('content'); var CSRF_TOKEN = \$('meta[name=_token]').attr('content'); if(email != '' && fname != '') { \$.ajax({ url: siteurl+'/user/register', dataType: "json", type: "POST", data: { '_token': CSRF_TOKEN, 'email': email, 'fname': fname, 'lname': lname, 'registerVia': 'socialMedia', 'socialMediaName': 'google' }, success: function(response) { \$('.loaders').hide(); if(response == 'IsLoggedin') { window.location = siteurl+'/user/dashboard'; } } }); } } function googleTranslateElementInit() { new google.translate.TranslateElement({pageLanguage: 'en'}, 'google_translate_element'); } if (window.location.href.indexOf("user/login") <= -1){ window.fbAsyncInit = function(){ FB.init({ appId:'1123210154481974', status:true, cookie:true, xfbml:true}); FB.getLoginStatus(function(response){ if (response.status != "unknown") { show_login_status("Facebook", true); }else{ show_login_status("Facebook", false); } }); }; // Load the SDK Asynchronously (function(d){ var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;} js = d.createElement('script'); js.id = id; js.async = true; js.src = "//connect.facebook.net/en_US/all.js"; d.getElementsByTagName('head')[0].appendChild(js); }(document)); } /*<![CDATA[*/window.zE||(function(e,t,s){var n=window.zE=window.zEmbed=function(){n._.push(arguments)}, a=n.s=e.createElement(t),r=e.getElementsByTagName(t)[0];n.set=function(e){ n.set._.push(e)},n._=[],n.set._=[],a.async=true,a.setAttribute("charset","utf-8"), a.src="https://static.zdassets.com/ekr/asset_composer.js?key="+s, n.t=+new Date,a.type="text/javascript",r.parentNode.insertBefore(a,r)})(document,"script","0506877a-b916-4374-9217-21354c508ed8");/*]]>*/ ```