Skip to content

Commit

Permalink
Merge pull request #68 from icssc/feat/updated-clustering
Browse files Browse the repository at this point in the history
feat: updated clustering
  • Loading branch information
NwinNwin authored Jan 14, 2025
2 parents b9d9ea9 + 1266519 commit d681c22
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 1 deletion.
5 changes: 5 additions & 0 deletions packages/web/src/components/Map/Map.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,8 @@
z-index: 0;
}
}

.custom-cluster-icon {
background: none;
border: none;
}
16 changes: 15 additions & 1 deletion packages/web/src/components/Map/Map.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import axios from "axios";

import { filterItem } from "../../utils/Utils.js";
import MarkerClusterGroup from 'react-leaflet-cluster'
import { createClusterCustomIcon } from './MapIcons';

/**
* Map is uses react-leaflet's API to communicate user actions to map entities and information
Expand Down Expand Up @@ -334,6 +335,16 @@ export default function Map({
) : null;
};

const createCluster = useMemo(() => {
// console.log("Current colorMode:", colorMode); // Debug log
return {
chunkedLoading: true,
iconCreateFunction: (cluster) => {
return createClusterCustomIcon(cluster, colorMode);
}
};
}, [colorMode]); // Make sure colorMode is in dependency array

return (
<div>
{/* Styles applied to MapContainer don't render unless page is reloaded */}
Expand All @@ -355,7 +366,10 @@ export default function Map({
<MapFocusLocation location={focusLocation} search={search} />
)}
{!isEdit && (
<MarkerClusterGroup chunkedLoading>
<MarkerClusterGroup
key={colorMode} // Force re-render when colorMode changes
{...createCluster}
>
{allMarkers}
</MarkerClusterGroup>
)}
Expand Down
75 changes: 75 additions & 0 deletions packages/web/src/components/Map/MapIcons.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,78 @@ export const iconsMap = {
false: resolvedIcon,
},
};

export const createClusterCustomIcon = (cluster, colorMode) => {
const count = cluster.getChildCount();
let size;

if (count < 5) size = 'small';
else if (count < 20) size = 'medium';
else size = 'large';

// Define color schemes for different count ranges
const options = {
light: {
small: {
background: 'rgba(255, 255, 255, 0.8)', // white with opacity
border: '#4299E1', // blue.400
color: '#4299E1'
},
medium: {
background: 'rgba(255, 255, 255, 0.8)',
border: '#48BB78', // green.400
color: '#48BB78'
},
large: {
background: 'rgba(255, 255, 255, 0.8)',
border: '#F56565', // red.400
color: '#F56565'
}
},
dark: {
small: {
background: 'rgba(45, 55, 72, 0.8)', // gray.800 with opacity
border: '#90CDF4', // blue.200
color: '#90CDF4'
},
medium: {
background: 'rgba(45, 55, 72, 0.8)',
border: '#9AE6B4', // green.200
color: '#9AE6B4'
},
large: {
background: 'rgba(45, 55, 72, 0.8)',
border: '#FEB2B2', // red.200
color: '#FEB2B2'
}
}
};

const mode = colorMode === 'dark' ? 'dark' : 'light';
const colors = options[mode][size];

const sizeMap = {
small: 40,
medium: 50,
large: 60
};

return L.divIcon({
html: `<div style="
background-color: ${colors.background} !important;
border: 2px solid ${colors.border};
color: ${colors.color};
width: ${sizeMap[size]}px;
height: ${sizeMap[size]}px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
font-weight: bold;
font-size: ${size === 'small' ? '14px' : '16px'};
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
">${count}</div>`,
className: `custom-cluster-icon ${mode}-mode`,
iconSize: L.point(sizeMap[size], sizeMap[size], true)
});
};

0 comments on commit d681c22

Please sign in to comment.