MapBox.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. "use strict";
  2. exports.__esModule = true;
  3. exports.default = exports.DEFAULT_POINT_RADIUS = exports.DEFAULT_MAX_ZOOM = void 0;
  4. var _react = _interopRequireDefault(require("react"));
  5. var _propTypes = _interopRequireDefault(require("prop-types"));
  6. var _reactMapGl = _interopRequireDefault(require("react-map-gl"));
  7. var _immutable = _interopRequireDefault(require("immutable"));
  8. var _viewportMercatorProject = _interopRequireDefault(require("viewport-mercator-project"));
  9. var _ScatterPlotGlowOverlay = _interopRequireDefault(require("./ScatterPlotGlowOverlay"));
  10. require("./MapBox.css");
  11. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  12. function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  13. const NOOP = () => {};
  14. const DEFAULT_MAX_ZOOM = 16;
  15. exports.DEFAULT_MAX_ZOOM = DEFAULT_MAX_ZOOM;
  16. const DEFAULT_POINT_RADIUS = 60;
  17. exports.DEFAULT_POINT_RADIUS = DEFAULT_POINT_RADIUS;
  18. const propTypes = {
  19. width: _propTypes.default.number,
  20. height: _propTypes.default.number,
  21. aggregatorName: _propTypes.default.string,
  22. clusterer: _propTypes.default.object,
  23. globalOpacity: _propTypes.default.number,
  24. hasCustomMetric: _propTypes.default.bool,
  25. mapStyle: _propTypes.default.string,
  26. mapboxApiKey: _propTypes.default.string.isRequired,
  27. onViewportChange: _propTypes.default.func,
  28. pointRadius: _propTypes.default.number,
  29. pointRadiusUnit: _propTypes.default.string,
  30. renderWhileDragging: _propTypes.default.bool,
  31. rgb: _propTypes.default.array,
  32. bounds: _propTypes.default.array
  33. };
  34. const defaultProps = {
  35. width: 400,
  36. height: 400,
  37. globalOpacity: 1,
  38. onViewportChange: NOOP,
  39. pointRadius: DEFAULT_POINT_RADIUS,
  40. pointRadiusUnit: 'Pixels'
  41. };
  42. class MapBox extends _react.default.Component {
  43. constructor(props) {
  44. super(props);
  45. const {
  46. width,
  47. height,
  48. bounds
  49. } = this.props; // Get a viewport that fits the given bounds, which all marks to be clustered.
  50. // Derive lat, lon and zoom from this viewport. This is only done on initial
  51. // render as the bounds don't update as we pan/zoom in the current design.
  52. const mercator = new _viewportMercatorProject.default({
  53. width,
  54. height
  55. }).fitBounds(bounds);
  56. const {
  57. latitude,
  58. longitude,
  59. zoom
  60. } = mercator;
  61. this.state = {
  62. viewport: {
  63. longitude,
  64. latitude,
  65. zoom
  66. }
  67. };
  68. this.handleViewportChange = this.handleViewportChange.bind(this);
  69. }
  70. handleViewportChange(viewport) {
  71. this.setState({
  72. viewport
  73. });
  74. const {
  75. onViewportChange
  76. } = this.props;
  77. onViewportChange(viewport);
  78. }
  79. render() {
  80. const {
  81. width,
  82. height,
  83. aggregatorName,
  84. clusterer,
  85. globalOpacity,
  86. mapStyle,
  87. mapboxApiKey,
  88. pointRadius,
  89. pointRadiusUnit,
  90. renderWhileDragging,
  91. rgb,
  92. hasCustomMetric,
  93. bounds
  94. } = this.props;
  95. const {
  96. viewport
  97. } = this.state;
  98. const isDragging = viewport.isDragging === undefined ? false : viewport.isDragging; // Compute the clusters based on the original bounds and current zoom level. Note when zoom/pan
  99. // to an area outside of the original bounds, no additional queries are made to the backend to
  100. // retrieve additional data.
  101. const bbox = [bounds[0][0], bounds[0][1], bounds[1][0], bounds[1][1]];
  102. const clusters = clusterer.getClusters(bbox, Math.round(viewport.zoom));
  103. return _react.default.createElement(_reactMapGl.default, _extends({}, viewport, {
  104. mapStyle: mapStyle,
  105. width: width,
  106. height: height,
  107. mapboxApiAccessToken: mapboxApiKey,
  108. onViewportChange: this.handleViewportChange
  109. }), _react.default.createElement(_ScatterPlotGlowOverlay.default, _extends({}, viewport, {
  110. isDragging: isDragging,
  111. locations: _immutable.default.fromJS(clusters),
  112. dotRadius: pointRadius,
  113. pointRadiusUnit: pointRadiusUnit,
  114. rgb: rgb,
  115. globalOpacity: globalOpacity,
  116. compositeOperation: "screen",
  117. renderWhileDragging: renderWhileDragging,
  118. aggregation: hasCustomMetric ? aggregatorName : null,
  119. lngLatAccessor: location => {
  120. const coordinates = location.get('geometry').get('coordinates');
  121. return [coordinates.get(0), coordinates.get(1)];
  122. }
  123. })));
  124. }
  125. }
  126. MapBox.propTypes = propTypes;
  127. MapBox.defaultProps = defaultProps;
  128. var _default = MapBox;
  129. exports.default = _default;