// https://github.com/d3/d3-hexbin Version 0.2.2. Copyright 2017 Mike Bostock.
(function (global, factory) {
  typeof exports === "object" && typeof module !== "undefined"
    ? factory(exports)
    : typeof define === "function" && define.amd
    ? define(["exports"], factory)
    : factory((d3 = d3 || {}));
})(this, function (exports) {
  "use strict";

  var thirdPi = Math.PI / 3;
  var angles = [0, thirdPi, 2 * thirdPi, 3 * thirdPi, 4 * thirdPi, 5 * thirdPi];

  function pointX(d) {
    return d[0];
  }

  function pointY(d) {
    return d[1];
  }

  var hexbin = function () {
    var x0 = 0,
      y0 = 0,
      x1 = 1,
      y1 = 1,
      x = pointX,
      y = pointY,
      r,
      dx,
      dy;

    function hexbin(points) {
      var binsById = {},
        bins = [],
        i,
        n = points.length;

      for (i = 0; i < n; ++i) {
        if (
          isNaN((px = +x.call(null, (point = points[i]), i, points))) ||
          isNaN((py = +y.call(null, point, i, points)))
        )
          continue;

        var point,
          px,
          py,
          pj = Math.round((py = py / dy)),
          pi = Math.round((px = px / dx - (pj & 1) / 2)),
          py1 = py - pj;

        if (Math.abs(py1) * 3 > 1) {
          var px1 = px - pi,
            pi2 = pi + (px < pi ? -1 : 1) / 2,
            pj2 = pj + (py < pj ? -1 : 1),
            px2 = px - pi2,
            py2 = py - pj2;
          if (px1 * px1 + py1 * py1 > px2 * px2 + py2 * py2)
            (pi = pi2 + (pj & 1 ? 1 : -1) / 2), (pj = pj2);
        }

        var id = pi + "-" + pj,
          bin = binsById[id];
        if (bin) bin.push(point);
        else {
          bins.push((bin = binsById[id] = [point]));
          bin.x = (pi + (pj & 1) / 2) * dx;
          bin.y = pj * dy;
        }
      }

      return bins;
    }

    function hexagon(radius) {
      var x0 = 0,
        y0 = 0;
      return angles.map(function (angle) {
        var x1 = Math.sin(angle) * radius,
          y1 = -Math.cos(angle) * radius,
          dx = x1 - x0,
          dy = y1 - y0;
        (x0 = x1), (y0 = y1);
        return [dx, dy];
      });
    }

    hexbin.hexagon = function (radius) {
      return "m" + hexagon(radius == null ? r : +radius).join("l") + "z";
    };

    hexbin.centers = function () {
      var centers = [],
        j = Math.round(y0 / dy),
        i = Math.round(x0 / dx);
      for (var y = j * dy; y < y1 + r; y += dy, ++j) {
        for (var x = i * dx + ((j & 1) * dx) / 2; x < x1 + dx / 2; x += dx) {
          centers.push([x, y]);
        }
      }
      return centers;
    };

    hexbin.mesh = function () {
      var fragment = hexagon(r).slice(0, 4).join("l");
      return hexbin
        .centers()
        .map(function (p) {
          return "M" + p + "m" + fragment;
        })
        .join("");
    };

    hexbin.x = function (_) {
      return arguments.length ? ((x = _), hexbin) : x;
    };

    hexbin.y = function (_) {
      return arguments.length ? ((y = _), hexbin) : y;
    };

    hexbin.radius = function (_) {
      return arguments.length
        ? ((r = +_), (dx = r * 2 * Math.sin(thirdPi)), (dy = r * 1.5), hexbin)
        : r;
    };

    hexbin.size = function (_) {
      return arguments.length
        ? ((x0 = y0 = 0), (x1 = +_[0]), (y1 = +_[1]), hexbin)
        : [x1 - x0, y1 - y0];
    };

    hexbin.extent = function (_) {
      return arguments.length
        ? ((x0 = +_[0][0]),
          (y0 = +_[0][1]),
          (x1 = +_[1][0]),
          (y1 = +_[1][1]),
          hexbin)
        : [
            [x0, y0],
            [x1, y1],
          ];
    };

    return hexbin.radius(1);
  };

  exports.hexbin = hexbin;

  Object.defineProperty(exports, "__esModule", { value: true });
});
