binning.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. function displayBinning(scope, dimensions, projection, path) {
  2. /**
  3. * Hexbin-specific setup
  4. */
  5. var hexbin = d3.hexbin()
  6. .size(dimensions)
  7. .radius(scope.panel.display.binning.hexagonSize);
  8. var binPoints = [];
  9. //primary field is just binning raw counts
  10. //secondary field is binning some metric like mean/median/total. Hexbins doesn't support that,
  11. //so we cheat a little and just add more points to compensate.
  12. //However, we don't want to add a million points, so normalize against the largest value
  13. if (scope.panel.display.binning.areaEncodingField === 'secondary') {
  14. var max = Math.max.apply(Math, _.map(scope.data, function(k,v){return k;})),
  15. scale = 50/max;
  16. _.map(scope.data, function (k, v) {
  17. var decoded = geohash.decode(v);
  18. return _.map(_.range(0, k*scale), function(a,b) {
  19. binPoints.push(projection([decoded.longitude, decoded.latitude]));
  20. })
  21. });
  22. } else {
  23. binPoints = scope.projectedPoints;
  24. }
  25. //bin and sort the points, so we can set the various ranges appropriately
  26. var binnedPoints = hexbin(binPoints).sort(function(a, b) { return b.length - a.length; });;
  27. //clean up some memory
  28. binPoints = [];
  29. var radius = d3.scale.sqrt()
  30. .domain([0, binnedPoints[0].length])
  31. .range([0, scope.panel.display.binning.hexagonSize]);
  32. var color = d3.scale.linear()
  33. .domain([0,binnedPoints[0].length])
  34. .range(["white", "steelblue"])
  35. .interpolate(d3.interpolateLab);
  36. /**
  37. * D3 Drawing
  38. */
  39. scope.g.selectAll("hexagon")
  40. .data(binnedPoints)
  41. .enter().append("path")
  42. .attr("d", function (d) {
  43. if (scope.panel.display.binning.areaEncoding === false) {
  44. return hexbin.hexagon();
  45. } else {
  46. return hexbin.hexagon(radius(d.length));
  47. }
  48. })
  49. .attr("class", "hexagon")
  50. .attr("transform", function (d) {
  51. return "translate(" + d.x + "," + d.y + ")";
  52. })
  53. .style("fill", function (d) {
  54. if (scope.panel.display.binning.colorEncoding === false) {
  55. return color(binnedPoints[0].length / 2);
  56. } else {
  57. return color(d.length);
  58. }
  59. })
  60. .attr("opacity", scope.panel.display.binning.hexagonAlpha);
  61. }