Skip to content

Commit

Permalink
Add metaMarkers functionality to MarkableMap
Browse files Browse the repository at this point in the history
  • Loading branch information
farazcsk authored and Richard Palmer committed Sep 11, 2017
1 parent 17f6d27 commit 99bd90f
Show file tree
Hide file tree
Showing 5 changed files with 304 additions and 24,752 deletions.
69 changes: 29 additions & 40 deletions components/Map/Map.story.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import React, { Component } from 'react';
import React, { Component, PropTypes } from 'react';
import { storiesOf } from '@kadira/storybook';
import { withKnobs, boolean } from '@kadira/storybook-addon-knobs';
import uniqueId from 'lodash/fp/uniqueId';

import actionWithComplexArgs from '../../.storybook/utils/actionWithComplexArgs';
import MarkableMap from './MarkableMap';
import BaseMap from './BaseMap';
import Marker from './Markers/Marker';
import GroupMarker from './Markers/SpaceGroupMarker';
import SpaceListingCard from '../Cards/SpaceListingCard/SpaceListingCard';

import testGeoJson from './testGeoJson';
import { metaMarkersA, metaMarkersB, metaMarkersC } from './testMetaMarkers';

const SMALL_TEST_GEO_JSON = 'small';
const LARGE_TEST_GEO_JSON = 'large';
const stories = storiesOf('Map', module);
stories.addDecorator(withKnobs);

const SpaceMarker = props => <Marker><SpaceListingCard { ...props } /></Marker>;

const prices = ['£1', '£33', '£420', '£1,000', '£20,000', '£999,999', '1 €', '20 €', '440 €',
'4.040 €', '40.040 €', '120.040 €'];


const generateMarkers = (number = 1, lng, lat) => {
const markers = [];

Expand Down Expand Up @@ -62,13 +63,18 @@ const generateMarkers = (number = 1, lng, lat) => {
};

class TestMap extends Component {
static propTypes = {
metaMarkers: PropTypes.array,
};

static defaultProps = {
metaMarkers: [],
};

constructor(props) {
super(props);
this.state = {
center: [-1.5253180650545346, 52.879078603224315],
zoom: 11,
markers: generateMarkers(10),
heatmapGeoJsonKey: SMALL_TEST_GEO_JSON,
};
}

Expand All @@ -78,51 +84,27 @@ class TestMap extends Component {
});
};

handleMoveEnd = (mapboxUserAction, view) => {
const { center, zoom } = view;
this.setState({
center,
zoom,
});
};

updateGeoJson = () => {
const { heatmapGeoJsonKey } = this.state;

if (heatmapGeoJsonKey === SMALL_TEST_GEO_JSON) {
this.setState({
heatmapGeoJsonKey: LARGE_TEST_GEO_JSON,
});
} else {
this.setState({
heatmapGeoJsonKey: SMALL_TEST_GEO_JSON,
});
}
};

render() {
const { markers, heatmapGeoJsonKey, center, zoom } = this.state;
const { markers } = this.state;
const { metaMarkers } = this.props;

return (
<div style={ { height: '93vh' } }>
<button onClick={ this.toggleMarkers }>Randomise</button>
<button onClick={ this.updateGeoJson }>Update heatmap</button>
<MarkableMap
markers={ markers }
heatmapGeoJson={ testGeoJson[heatmapGeoJsonKey] }
metaMarkers={ metaMarkers }
MarkerComponent={ SpaceMarker }
GroupMarkerComponent={ GroupMarker }
center={ center }
zoom={ zoom }
onClick={ actionWithComplexArgs('map clicked') }
onMoveEnd={ this.handleMoveEnd }
autoFit
/>
</div>
);
}
}

storiesOf('Map', module)
stories
.add('Default', () => (
<div style={ { height: '96vh' } }>
<BaseMap
Expand All @@ -131,9 +113,16 @@ storiesOf('Map', module)
/>
</div>
))
.add('MarkableMap', () => (
<TestMap />
))
.add('MarkableMap', () => <TestMap />)
.add('MarkableMap w/Meta markers', () => {
const metaMarkers = [
(boolean('Meta Markers A', true) && metaMarkersA),
(boolean('Meta Markers B', true) && metaMarkersB),
(boolean('Meta Markers C', true) && metaMarkersC),
].filter(metaMarker => metaMarker);

return <TestMap metaMarkers={ metaMarkers } />;
})
.add('Grouped Space Marker', () => (
<div style={ { height: '96vh' } }>
<MarkableMap
Expand Down
82 changes: 51 additions & 31 deletions components/Map/MarkableMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import uniqueId from 'lodash/fp/uniqueId';
import flattenDeep from 'lodash/fp/flattenDeep';
import find from 'lodash/fp/find';
import cx from 'classnames';
import HexgridHeatmap from '@appearhere/hexgrid-heatmap';

import lngLatType from '../../utils/propTypeValidations/lngLat';
import minLngLatBounds from '../../utils/geoUtils/minLngLatBounds';
Expand All @@ -28,13 +27,8 @@ import {
HIGHLIGHTED_MARKER_LAYER,
CLUSTER_LAYER,
HIGHLIGHTED_CLUSTER_LAYER,
HEATMAP_LAYER,
MOVE_TO_MARKER_MAX_LAT_OFFSET,
DEFAULT_MARKER_CONFIG,
DEFAULT_HEATMAP_COLOR_STOPS,
DEFAULT_HEATMAP_INTENSITY,
DEFAULT_HEATMAP_SPREAD,
DEFAULT_HEATMAP_CELL_DENSITY,
} from '../../constants/mapbox';

import css from './MarkableMap.css';
Expand All @@ -52,10 +46,7 @@ export default class MarkableMap extends Component {
props: PropTypes.object,
})
),
heatmapGeoJson: PropTypes.shape({
type: PropTypes.string,
features: PropTypes.array,
}),
metaMarkers: PropTypes.array,
colorStops: PropTypes.arrayOf(PropTypes.array),
intensity: PropTypes.number,
spread: PropTypes.number,
Expand All @@ -68,10 +59,7 @@ export default class MarkableMap extends Component {

static defaultProps = {
markers: [],
colorStops: DEFAULT_HEATMAP_COLOR_STOPS,
intensity: DEFAULT_HEATMAP_INTENSITY,
cellDensity: DEFAULT_HEATMAP_CELL_DENSITY,
spread: DEFAULT_HEATMAP_SPREAD,
metaMarkers: [],
autoFit: false,
};

Expand All @@ -91,16 +79,15 @@ export default class MarkableMap extends Component {
}

componentDidUpdate(prevProps, prevState) {
const { markers: prevMarkers, heatmapGeoJson: prevHeatmapGeoJson } = prevProps;
const { markers: prevMarkers, metaMarkers: prevMetaMarkers } = prevProps;
const { activeFeature: prevActiveFeature } = prevState;
const { markers, autoFit, heatmapGeoJson } = this.props;
const { markers, autoFit, metaMarkers } = this.props;
const { activeFeature } = this.state;

this.updateMapboxMarkerSource();

if (prevHeatmapGeoJson !== heatmapGeoJson) {
this.heatmap.setData(heatmapGeoJson);
this.heatmap.update();
if (!isEqual(prevMetaMarkers, metaMarkers)) {
this.updateMetaMarkerSource(prevMetaMarkers);
}

if (!activeFeature || !this.getActiveFeaturedMarker()) {
Expand Down Expand Up @@ -149,7 +136,6 @@ export default class MarkableMap extends Component {

handleMapLoad = () => {
const mapbox = this.getMapboxGL();
const { colorStops, intensity, spread, cellDensity, heatmapGeoJson } = this.props;

mapbox.addSource(MARKER_SOURCE, {
type: 'geojson',
Expand Down Expand Up @@ -257,16 +243,7 @@ export default class MarkableMap extends Component {
});

this.updateMapboxMarkerSource();

if (heatmapGeoJson) {
this.heatmap = new HexgridHeatmap(mapbox, HEATMAP_LAYER, MARKER_LAYER);
this.heatmap.setIntensity(intensity);
this.heatmap.setSpread(spread);
this.heatmap.setCellDensity(cellDensity);
this.heatmap.setColorStops(colorStops);
this.heatmap.setData(heatmapGeoJson);
this.heatmap.update();
}
this.updateMetaMarkerSource();
};

updateMapboxMarkerSource = () => {
Expand Down Expand Up @@ -295,6 +272,50 @@ export default class MarkableMap extends Component {
});
};

updateMetaMarkerSource = (prevMetaMarkers) => {
const { metaMarkers } = this.props;
const mapbox = this.getMapboxGL();

if (prevMetaMarkers) {
prevMetaMarkers.forEach((prevMetaMarker) => {
const prevMetaMarkerSource = mapbox.getSource(prevMetaMarker.id);
const prevMetaMarkerLayer = mapbox.getLayer(prevMetaMarker.id);

if (
(prevMetaMarkerSource && prevMetaMarkerLayer) &&
!metaMarkers.includes(prevMetaMarker)
) {
mapbox.removeSource(prevMetaMarker.id);
mapbox.removeLayer(prevMetaMarker.id);
}
});
}

metaMarkers.forEach((metaMarker, index) => {
const metaMarkerSource = mapbox.getSource(metaMarker.id);
const metaMarkerLayer = mapbox.getLayer(metaMarker.id);

if (!metaMarkerSource && !metaMarkerLayer) {
mapbox.addSource(metaMarker.id, {
type: 'geojson',
data: metaMarker,
});
mapbox.addLayer({
id: metaMarker.id,
type: DEFAULT_MARKER_CONFIG.type,
source: metaMarker.id,
layout: {
'icon-image': `meta-${index + 1}`,
'text-field': metaMarker.label,
'text-font': DEFAULT_MARKER_CONFIG.layout.textFont,
'text-size': DEFAULT_MARKER_CONFIG.layout.textSize,
},
paint: DEFAULT_MARKER_CONFIG.paint,
});
}
});
};

handleMapClick = (e) => {
const { originalEvent, point } = e;
if (originalEvent.target !== this.getMapboxGL().getCanvas()) return;
Expand Down Expand Up @@ -389,7 +410,6 @@ export default class MarkableMap extends Component {
this.map.zoomOut();
};


renderMarkerPopup = (activeFeature) => {
const { MarkerComponent, GroupMarkerComponent, markers } = this.props;
const lngLat = activeFeature.geometry.coordinates;
Expand Down
Loading

0 comments on commit 99bd90f

Please sign in to comment.