cristiandley / react-gl-maps

Based on "tomchentw/react-google-maps" but with cool features added
MIT License
6 stars 5 forks source link

Multi Char Markers?? #1

Closed eamonpenland closed 8 years ago

eamonpenland commented 8 years ago

I'm looking for a react google maps implementation where you can do multi char strings on markers. Have you added this functionality into your version? I came from here https://github.com/tomchentw/react-google-maps/issues/256

cristiandley commented 8 years ago

@eamonpenland SVG icons is not a solution ?

maybe we could wrap a solution with SVG

eamonpenland commented 8 years ago

could you elaborate? I thought the Marker api only showed the 1st character in string label?

jwdotjs commented 8 years ago

@eamonpenland here is a snippet from my map file that is using SVG and allowing multiple characters. Let me know if this helps or if you need a more robust example!

import _ from 'lodash';
import React from 'react';
import {GoogleMapLoader, GoogleMap, Marker} from 'react-gl-maps';

export class GMap extends React.Component {

  static propTypes = {
    onMarkerClick: React.PropTypes.func,
    markers: React.PropTypes.arrayOf(
      React.PropTypes.shape({
        label: React.PropTypes.string,
        position: React.PropTypes.shape({
          lat: React.PropTypes.number.isRequired,
          lng: React.PropTypes.number.isRequired,
        }).isRequired,
      }),
    ),
  }

  static defaultProps = {
    onMarkerClick: _.noop,
  }

  getMarkerIcon(attr) {
    const svg = this.generateIcon(attr.label);

    return {
      url: 'data:image/svg+xml;base64,' + window.btoa(svg),
      size: new google.maps.Size(42.7, 27.77),
      scaledSize: new google.maps.Size(260, 150),
      anchor: new google.maps.Point(10.5, 30),
    };
  }

  getFillColor() {
    return '#209e91';
  }

  generateIcon(label, opts = {}) {
    const fillColor = this.getFillColor();
    _.defaults(opts, {
      fontSize: '13px',
      fontColor: 'white',
      strokeColor: '#ffffff',
      fillColor,
    });

    return `
      <svg xmlns="http://www.w3.org/2000/svg">
        <defs>
          <style>
            .marker-label {
              font-size:${opts.fontSize};
              font-family:'Lato';
              fill:${opts.fontColor};
            }
          </style>
        </defs>
        <path class="marker-icon" stroke="${opts.strokeColor}" fill="${opts.fillColor}" d="M.3.3v22.9h13.81l6.09 6.71 6.1-6.71h22.4V.3H.3z"/>
        <text class="marker-label" fill="white" text-anchor="middle" transform="translate(24 16)" >${label}</text>
      </svg>
    `;
  }

  renderContainer() {
    return <div {...this.props} style={{height: '300px'}} />;
  }

  renderMarkers() {
    return this.props.markers.map((attr, index) => {
      const position = attr.position;
      const icon = this.getMarkerIcon(attr);
      return (
        <Marker
          key={index}
          position={position}
          icon={icon}
          onClick={e => this.props.onMarkerClick(attr)} />
      );
    });
  }

  renderMap() {
    return (
      <GoogleMap
        defaultZoom={3}
        defaultCenter={{lat: 37.09024, lng: -95.712891}}>
        {this.renderMarkers()}
      </GoogleMap>
    );
  }

  render() {
    return (
      <GoogleMapLoader
        containerElement={this.renderContainer()}
        googleMapElement={this.renderMap()} />
    );
  }
}
eamonpenland commented 8 years ago

@jwdotjs thanks a lot! very helpful!

cristiandley commented 8 years ago

Thanks @jwdotjs , @eamonpenland