GithubHelp home page GithubHelp logo

google-map-react / google-map-react Goto Github PK

View Code? Open in Web Editor NEW
6.3K 6.3K 833.0 4.08 MB

Google map library for react that allows rendering components as markers :tada:

Home Page: http://google-map-react.github.io/google-map-react/map/main/

License: MIT License

JavaScript 97.64% CSS 0.54% HTML 1.82%
component google map maps react

google-map-react's Introduction

Google Map React · npm version Build Status PRs Welcome

google-map-react is a component written over a small set of the Google Maps API. It allows you to render any React component on the Google Map. It is fully isomorphic and can render on a server. Additionally, it can render map components in the browser even if the Google Maps API is not loaded. It uses an internal, tweakable hover algorithm - every object on the map can be hovered.

It allows you to create interfaces like this example (You can scroll the table, zoom/move the map, hover/click on markers, and click on table rows)

Getting started

In the simple case you just need to add lat and lng props to any child of GoogleMapReact component.

See it in action at jsbin

import React from "react";
import GoogleMapReact from 'google-map-react';

const AnyReactComponent = ({ text }) => <div>{text}</div>;

export default function SimpleMap(){
  const defaultProps = {
    center: {
      lat: 10.99835602,
      lng: 77.01502627
    },
    zoom: 11
  };

  return (
    // Important! Always set the container height explicitly
    <div style={{ height: '100vh', width: '100%' }}>
      <GoogleMapReact
        bootstrapURLKeys={{ key: "" }}
        defaultCenter={defaultProps.center}
        defaultZoom={defaultProps.zoom}
      >
        <AnyReactComponent
          lat={59.955413}
          lng={30.337844}
          text="My Marker"
        />
      </GoogleMapReact>
    </div>
  );
}

My map doesn't appear!

  • Make sure the container element has width and height. The map will try to fill the parent container, but if the container has no size, the map will collapse to 0 width / height. This is not a requirement for google-map-react, its a requirement for google-maps in general.

Installation

npm:

npm install --save google-map-react

yarn:

yarn add google-map-react

Features

Works with your Components

Instead of the default Google Maps markers, balloons and other map components, you can render your cool animated react components on the map.

Isomorphic Rendering

It renders on the server. (Welcome search engines) (you can disable javascript in browser dev tools, and reload any example page to see how it works)

Component Positions Calculated Independently of Google Maps API

It renders components on the map before (and even without) the Google Maps API loaded.

Google Maps API Loads on Demand

There is no need to place a <script src= tag at top of page. The Google Maps API loads upon the first usage of the GoogleMapReact component.

Use Google Maps API

You can access to Google Maps map and maps objects by using onGoogleApiLoaded, in this case you will need to set yesIWantToUseGoogleMapApiInternals to true

...

const handleApiLoaded = (map, maps) => {
  // use map and maps objects
};

...

<GoogleMapReact
  bootstrapURLKeys={{ key: /* YOUR KEY HERE */ }}
  defaultCenter={this.props.center}
  defaultZoom={this.props.zoom}
  yesIWantToUseGoogleMapApiInternals
  onGoogleApiLoaded={({ map, maps }) => handleApiLoaded(map, maps)}
>
  <AnyReactComponent
    lat={59.955413}
    lng={30.337844}
    text="My Marker"
  />
</GoogleMapReact>

PST: Remember to set yesIWantToUseGoogleMapApiInternals to true.

Example here

Internal Hover Algorithm

Now every object on the map can be hovered (however, you can still use css hover selectors if you want). If you try zooming out here example, you will still be able to hover on almost every map marker.

Examples

Documentation

You can find the documentation here:

Contribute

Local development is broken into two parts (ideally using two tabs).

First, run rollup to watch your src/ module and automatically recompile it into dist/ whenever you make changes.

npm start # runs rollup with watch flag

The second part will be running the example/ create-react-app that's linked to the local version of your module.

# (in another tab)
cd example
npm start # runs create-react-app dev server

Now, anytime you make a change to your library in src/ or to the example app's example/src, create-react-app will live-reload your local dev server so you can iterate on your component in real-time.

Manual link-install

If you get the error Module not found: Can't resolve 'google-react-map'... while trying to run the example app, you need to manually link your local development module, try the following steps:

  1. In the root folder:
npm link
  1. Go into example/ and (after installing other dependencies) execute:
npm link google-map-react

License

MIT

Known Issues

!!! We are looking for contributors

We're actively looking for contributors, please send a message to the Owner or any of the Collaborators.

google-map-react's People

Contributors

alex-e-leon avatar andersaloof avatar andreyco avatar andries-smit avatar barakplasma avatar cgarvis avatar cheesytim avatar davidfurlong avatar dependabot[bot] avatar deviantony avatar donovandesmedt avatar emilpalsson avatar in15 avatar ipostol avatar istarkov avatar itsmichaeldiego avatar jedwards1211 avatar jooj123 avatar josephfrazier avatar karldanninger avatar kevinramsunder avatar mauriciosoares avatar mbrookes avatar mozmorris avatar rvermootenct avatar shark0der avatar stanislav-ermakov avatar stanleycyang avatar stephenfarrar avatar yoadsn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

google-map-react's Issues

Synchronization issues when having two GoogleMap instances on the same DOM

I haven't found any place in where I can know whether multiple GoogleMap components can be used inside the same DOM. So I gave it a try by putting two maps in different tabs and there are a couple of sync issues:

The two maps are centered in the same geo-position but both of them are located in different places in each tab with different frame sizes as well.

Perceived issues on the second tab:

1.- the second map is not centered properly (the center seems to be a bit offset to the top-left corner.
2.- neighbours tiles from that center point do not appear in the DOM

If I expand a bit the browser window a bit then, neighbour tiles do appear. The offset thing is not fixed though.

Is it multiple map components in the same DOM supported?

Cannot read property '_currentElement' of null, react 0.13.3

I'm getting errors

Uncaught TypeError: undefined is not a function
(3) Uncaught TypeError: Cannot read property '_currentElement' of null

My react component:

var React = require('react/addons');
var GoogleMap = require('google-map-react');


var Map = React.createClass({
    getInitialState: function () {
        return {
        };
    },
    render: function() {
        return (
                <GoogleMap>
            <div lat={59.955413} lng={30.337844} text={'A'}></div>
          </GoogleMap>
        );
    }

});

module.exports = Map;

package.json:

 "dependencies": {
    "react": "^0.13.3",
    "react-router": "^0.13.3",
    "reactify": "0.17.1",
    "superagent": "0.21.0"
  },
  "devDependencies": {
    "envify": "^1.2.1",
    "es6-promise": "^1.0.0",
    "flux": "^2.0.3",
    "google-map-react": "^0.3.1",
    "gulp": "^3.8.0",
    "gulp-browserify": "^0.5.0",
    "gulp-concat": "^2.2.0",
    "gulp-connect": "^2.2.0",
    "gulp-livereload": "^3.8.0",
    "gulp-open": "~0.3.2",
    "gulp-plumber": "^1.0.0",
    "gulp-webserver": "^0.9.1",
    "parse": "^1.4.2",
    "parse-react": "^0.3.1"
  }

Component doesn't work. What's wrong?

Bower version?

Hi, I would like to use this in a Rails project, in which case I would have to copy the source files into my vendors folder or user a Bower version via rails-assets.org. Would it be possible to provide a Bower version? When I tried to copy the source files into my Javascripts directory, it caused a bunch of errors. Suggestions welcome :)

Get map instance

Hi I was trying to work out a way of triggering a resize of the map along the lines of google.maps.event.trigger(map, "resize"); Clearly to do this I would need the map instance. Do you have any ideas at all?

Many thanks for a great library.

Hiding and showing the map

I render GoogleMapReact in a hidden div. When I show the div, the map is absent. How to make it show?

http://jsfiddle.net/L3k4ktdj/1/

As I understand, as the div state (hidden/shown) is in the component state, it is rerendered after the state is updated. However, that doesn't really happen. I am just learning react, so maybe the error on my side. I'd appreciate you help with this, thanks.

bug for set new zoom

i got the following bugs if i try to set zoom in _onGoogleApiLoaded function. any idea?

_onGoogleApiLoaded: function(map){
this.setState({zoom: 13});
}

TypeError: Cannot read property 'getNorthEast' of undefined(…)(anonymous function) @ GoogleMapReact.js:1334

Multiple copies of GoogleMapMarkers get created when map is unmounted/remounted repeatedly

Since I have multiple routes in my app, and a <GoogleMap/> on the home route, the <GoogleMap/> gets unmounted and remounted each time I switch away from the home route and then back to it. It looks like the <GoogleMap/> isn't removing the <GoogleMapMarkers/> each time it unmounts, but each time it mounts it's adding a new one. The following shows what happened after I switched back to the home route 3 times:

image

Grouping Markers

Hi, thanks for the great work on this, really appreciated. I was wondering if you had any ideas for a way to group the markers that are closer together when zoomed farther out. There are existing libraries like (googlemaps/js-marker-clusterer) but I don't think they work very well out of the box with this. Any ideas on how to implement something like that? Thanks again

Simple map example stand alone

hi istarkov,

I try to get the simple map example working as standalone but I can't get it to work.

https://github.com/joostaafjes/simplemap-with-react

Do you have any idea what I am doing wrong?

What I have done?

  1. Created a react project with react 0.14, webpack, babel, etc.
  2. Put in your simple map code and modified the example code to remove some errors I got
  3. installed google-map-react with npm

But all errors are gone now and get a blank screen (in a split second the markers are visible, after that they are gone).

Thanks very much,
Joost

Please add a license file

The package.json says it's MIT, but could you please add a separate license file and/or refer to the license in the readme.

Invoking a fitBounds on initialization

How to execute a method fitBounds once the map object initialized?

Where am I so far (terribly wrong, but most of the time works):

  render() {
    var center = [59.938043, 30.337157];
    var zoom = 8;

    return (
      <div className="search-map">
        <GoogleMap
          center={center}
          zoom={zoom}
          ref="googleMap">
          {this.renderMarkers()}
        </GoogleMap>
      </div>
    );
  },
  componentDidUpdate() {
    var map = this.refs.googleMap.map_;
    if (map) {
      var maps = this.refs.googleMap.maps_;
      var bounds = new maps.LatLngBounds();
      each(this.props.places, (place) => {
        var latLng = new maps.LatLng(place.lat, place.lng);
        bounds.extend(latLng);
      });
      map.fitBounds(bounds);
    }
  }

Most of the time it works, but sometimes an update happens before the map mounted, or in other words googleMapLoader is resolved.

I believe the correct solution is to invoke props callback in componentDidMount GoogleMap component.

build with bower install.

any idea how to build this library with bower install?

src folder is missing after bower install. any idea?

doc for map margin

How do we use the margin prop? Assuming this adds a margin to the bounds.

Better Documentation

Better Documentation on how to use (or at least more comments in your examples explaining what you're doing) would be greatly appreciated.

How to add a draggable circle?

Hey there! I'm using google-map-react with GeoFire and need to implement a draggable circle as in this demo.

I didn't see any documentation on doing something like this, so decided to try to use the Google Maps API directly. The circle shows up and the hand cursor changes to a pointer when hovering over it, but unfortunately, once I start dragging, the entire map is dragged rather than just the circle. Is there a workaround for this? (example code and screenshot below).

Thanks for the help and for making this great component!

Best,
-Jedidiah

  initDraggableCircle({ map, maps }) {
    let circle = new maps.Circle({
      strokeColor: '#6D3099',
      strokeOpacity: 0.7,
      strokeWeight: 1,
      fillColor: '#B650FF',
      fillOpacity: 0.35,
      map: map,
      center: new google.maps.LatLng(...this.props.mapConfig.center),
      radius: this.props.mapConfig.radius * 1000,
      draggable: true
    });
    maps.event.addListener(circle, 'drag', ::this.onCircleDragged);
  }
  render() {
    return (
      <div>
        <h2>Welcome to the map!</h2>
        <div style={{height:"500px"}}>
          <GoogleMap center={this.props.mapConfig.center}
                     defaultZoom={this.props.mapConfig.zoom}
                     onGoogleApiLoaded={::this.initDraggableCircle}
                     yesIWantToUseGoogleMapApiInternals={true}>
            {this.geofireMarkers()}
          </GoogleMap>
        </div>
      </div>
    );
  }

image

layout issue when resize the window.

i have tried to run the following function when resize window and it will screw up the map position accuracy after resize. i have noticed only change the height will cause this issue. only idea?

_performLayoutFrame: function(){
  this.height = window.clientHeight;
  this.width =  window.clientWidth;

this.refs.map_container.style.width= (this.width) + 'px';
this.refs.map_container.style.height = (this.height) + 'px';
},

Better isomorphic experience.

I am wonder if you guys have thought of using the static google maps api to render the map's image statically and then replace it when in the browser?

Currently only the markers will render isomorphically, but this would allow for everything to work (except obviously navigation and such).

Marker component always placed in top-left of map

Not sure what I'm doing wrong, but my marker component (a material-icons icon) is being placed in the top left, regardless of the marker or map coordinates. It does then scroll with the map, but zooming the map makes the icon jump back to the corner.

(I also had to wrap the map in a fixed height div to get it to display within a flex container, otherwise it collapsed to 0 height, but that's a different issue.)

Here's my code:

SimpleMap = React.createClass({

  getDefaultProps: function() {
    return {
      center: {lat: 59.938043, lng: 30.337157},
      zoom: 12,
      greatPlaceCoords: {lat: 59.724465, lng: 30.080121}
    }
  },

  render() {
    return (
      <div style={{height: "400px", display: "-webkit-flex"}}>
      <GoogleMap
        defaultCenter={this.props.center}
        defaultZoom={this.props.zoom}>
        <i className="material-icons"
           lat={this.props.greatPlaceCoords.lat}
           lng={this.props.greatPlaceCoords.lng} >
          face</i>
      </GoogleMap>
      </div>
    );
  }
});

Any pointers appreciated. Thanks!

(React 0.13.x)

Modal example

Privet Ivan, awesome lib! I am new to react and was looking for an example of using inside of a Modal body. Can you point me to one? I am using react 0.14.

Changing the position of controls makes them disappear

If I set the position in either zoomControlOptions or mapTypeControlOptions, which is passed to the GoogleMap component in through the options prop, they disappear. When the attribute is not set they render fine to their default positions.

I've followed followed the control position class documentation, using values like: 'BOTTOM_RIGHT', 'TOP_RIGHT', and 'LEFT_CENTER', none of which work.
https://developers.google.com/maps/documentation/javascript/reference#ControlPosition

This is how I'm using it:

import GoogleMap from 'google-map-react';
import OfficeMarker from './markers/OfficeMarker';

let mapOptions = {
  scrollwheel: false,
  zoomControlOptions: {
      //   position: 'RIGHT_CENTER',    // as long as this is not set it works
      style: 'SMALL'
  },
  mapTypeControlOptions: {
      position: 'BOTTOM_RIGHT'     // this makes the map type control disappear
  },
  draggable: false,
  rotateControl: false,
  scaleControl: false,
  streetViewControl: false,
  panControl: false,
};

const Map = React.createClass({
  render() {
    return (
      <div className="map-container" style={{height: '400px'}}>
        <GoogleMap
          options={mapOptions}
          center={this.props.center}
          zoom={this.props.zoom}>
          <OfficeMarker lat={this.props.officeCoords.lat} lng={this.props.officeCoords.lng} />
        </GoogleMap>
      </div>
  );
});

Simple click events

Need a way to make click event on map and get something like LatLng,
I only see an onChildClick event in the library and no examples like this way,
it seems like could not easy to dynamic add new markers since no feedback when user click on the map,
or maybe am I missing something?

Marker Taps Inconsistent (iOS)

Hi, it seems there is an issue with the onChildClick function on iOS, when tapping on a marker it doesn't register all the taps and rather than deselecting a selected marker and selecting a new one when tapping a new marker it seems to open and close the same balloon. I am experiencing this on the examples included here on all the browsers I've tested running iOS 8 on an iPhone 5 and 6+ (latest versions of Chrome, Safari, Opera mini). The problem exists on the iPad as well but to a lesser degree and becomes even less of a problem the larger the iPad is (iPad mini 1 is affected significantly also). Chrome on Android seems to work fine. Can anyone else confirm this?

Weird issue where visible marker is away from invisible hover/click area

I couldn't replicate this issue, but it is persistently present in an app I am developing. Creating this issue in case you've encountered this earlier and might know what's up. I've been trying for hours but couldn't figure out even the cause of this.

So the issue is that my marker is rendered on the map in the right place. But when I hover/click it, onChildClick/onMouseEnter(Leave) won't get triggered. However they do get triggered at some distance below the visible part. I position the marker {top: -height/2, left: -width/2} but it doesn't matter. Even if I position the marker to fix hover/click area, on refresh/re-render the hover/click area moves below the marker again.

Again, I couldn't replicate this in any simpler example. I am sorry I can't share the source code of the app in which I am facing this issue (it's a client's app). For all examples I created it works as expected. Do you have any idea what might be going on here?

jsFiddle with more advanced examples

For @mozmorris,

Would it be possible to put up a jsFiddle with the more advanced examples? I am trying to go through the example source code and finding it difficult to transfer to the var Map = React.createClass({}), etc. syntax.

I got the first simple example working, but I am confused about the absolute positioning of the marker in the top left corner of the map. Could not get the marker to render anywhere except the top left corner :/.

Appreciate the help!

Plans to add direction-service support?

Totally dig this package. However, in order for my team to use this, we need google direction-service to get distances between places. Do you have plans to add this into your google-maps abstraction?

Where can I find map markers in the Elements tree?

Sometimes changes I make to map markers cause them to have zero size. I can find the markers in the React plugin for Chrome, but I can't seem to find them anywhere in the HTML Elements tab. Where does the GoogleMapMarkers component get mounted?

onIdle callback [feature request]

Hi,

Is it possible to add an onIdle callback, that will get this.map_ this.maps_ as arguments - it will be easier for those who want to work with the map instance and not only:

this.props.onIdle(this.map_, this.maps_);

I used to work with the map instance to enable some functionality that's not implemented in this component, and I had to create a loop to make sure I'll always get it.

Thanks,
Raul.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.