Skip to content

Commit

Permalink
Member map clustering (#1109)
Browse files Browse the repository at this point in the history
* Install react leaflet cluster and add temporary icon

* Adjust temporary icon size and import leaflet styles

* Add custom cluster icon and styling

* Remove console.logs

* Remove remaining console logs and comments

* install leaflet.markercluster

* apply type to cluster param

* update colors

* update classname to share

* use member avatars when available

* add a bit of shadow

---------

Co-authored-by: Dan Ott <dan@dtott.com>
  • Loading branch information
ARodriguezHacks and danieltott authored Jan 5, 2024
1 parent 67cf073 commit 7756b7d
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 19 deletions.
81 changes: 62 additions & 19 deletions app/components/MemberMap.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
import type { MappableMember } from 'members/types';
import { useEffect } from 'react';
import L from 'leaflet';
import { MapContainer, Marker, TileLayer, Popup, useMap } from 'react-leaflet';
import MarkerClusterGroup from 'react-leaflet-cluster';
import 'leaflet/dist/leaflet.css';

const defaultCustomIcon = require('../../public/assets/images/virtual-coffee-mug-circle.svg');

const createClusterCustomIcon = function (cluster: L.MarkerCluster) {
return L.divIcon({
html: `<span>${cluster.getChildCount()}</span>`,
className: 'leaflet-custom-marker',
iconSize: L.point(33, 33, true),
});
};

const createCustomIcon = function (avatarUrl?: string) {
return new L.Icon.Default({
iconUrl: avatarUrl || defaultCustomIcon,
iconSize: new L.Point(33, 33, true),
className: 'leaflet-custom-marker',
});
};

function Markers({ members }: { members: MappableMember[] }) {
const map = useMap();
Expand All @@ -16,42 +37,64 @@ function Markers({ members }: { members: MappableMember[] }) {
);
}, [members, map]);

// avatarUrl

return (
<>
{members.map((member) => (
<Marker
key={member.github}
position={[member.location?.latitude, member.location?.longitude]}
>
<Popup>
<a href={`#member_${member.github}`}>{member.name}</a>
{member.location?.title && (
<>
{' - '}
{member.location?.title}
</>
)}
</Popup>
</Marker>
))}
{members.map((member) => {
const customIcon = createCustomIcon(member.avatarUrl);

return (
<Marker
key={member.github}
position={[member.location?.latitude, member.location?.longitude]}
icon={customIcon}
>
<Popup>
<a href={`#member_${member.github}`}>{member.name}</a>
{member.location?.title && (
<>
{' - '}
{member.location?.title}
</>
)}
</Popup>
</Marker>
);
})}
</>
);
}

export default function MemberMap({ members }: { members: MappableMember[] }) {
return (
<div style={{ aspectRatio: '16/6', minHeight: 400, position: 'relative' }}>
<div>
<MapContainer
center={[36.674222, -39.082187]}
zoom={1}
scrollWheelZoom={false}
scrollWheelZoom={true}
style={{ aspectRatio: '16/6', minHeight: 400, position: 'relative' }}
>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Markers members={members} />
<MarkerClusterGroup
chunkedLoading
iconCreateFunction={createClusterCustomIcon}
maxClusterRadius={150}
spiderfyOnMaxZoom={true}
polygonOptions={{
fillColor: '#ffffff',
color: '#d9376e',
weight: 5,
opacity: 1,
fillOpacity: 0.8,
}}
showCoverageOnHover={true}
>
<Markers members={members} />
</MarkerClusterGroup>
</MapContainer>
</div>
);
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"hast-util-to-string": "^2.0.0",
"hastscript": "^8.0.0",
"leaflet": "^1.9.4",
"leaflet.markercluster": "^1.5.3",
"luxon": "^3.4.3",
"markdown-it": "^13.0.2",
"mdast-util-toc": "^7.0.0",
Expand All @@ -80,6 +81,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-leaflet": "^4.2.1",
"react-leaflet-cluster": "^2.1.0",
"react-router": "^6.17.0",
"react-router-dom": "^6.17.0",
"rehype-autolink-headings": "^6.1.1",
Expand All @@ -104,6 +106,7 @@
"@tailwindcss/forms": "^0.5.6",
"@tailwindcss/typography": "^0.5.10",
"@types/leaflet": "^1.9.7",
"@types/leaflet.markercluster": "^1.5.4",
"@types/luxon": "^3.3.3",
"@types/react": "^18.2.32",
"@types/react-dom": "^18.2.14",
Expand Down
38 changes: 38 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions styles/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,22 @@ ul {
background: none;
justify-content: flex-end;
}

.text-sm {
font-size: 0.8rem;
}

.leaflet-custom-marker {
background: #ffffff;
border-radius: 50%;
color: #000000;
height: 33px;
// line-height: 37px;
text-align: center;
width: 33px;
border: 3px solid $pink;
display: flex !important;
justify-content: center;
align-items: center;
box-shadow: 1px 1px 5px 0px $pink;
}

0 comments on commit 7756b7d

Please sign in to comment.