Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NETMANAGER] map visuals and responsivness fix #1772

Merged
merged 2 commits into from
Dec 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions netmanager/src/assets/css/overlay-map.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
.overlay-map-container {
width: 100%;
height: calc(100vh - 64px);
height: -moz-calc(100vh - 64px);
height: -webkit-calc(100vh - 64px);
position: relative;
}

.map-new-container {
width: 100%;
height: 100%;
position: relative;
}

.map-circular-loader {
position: absolute;
z-index: 120;
left: 0;
top: 0;
width: 100%;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.4);
backdrop-filter: blur(1px);
}

.map-wrapper {
display: flex;
flex-wrap: wrap;
Expand Down Expand Up @@ -404,3 +425,23 @@
opacity: 0;
transition: visibility 0s, opacity 0.2s ease;
}

/* tablet */
@media (max-width: 1279px) {
.overlay-map-container {
width: 100vw;
height: calc(100vh - 64px);
}
}

/* mobile */
@media (max-width: 768px) {
.overlay-map-container {
width: 100vw;
height: calc(100vh - 64px);
}

.air-quality-description {
display: none;
}
}
19 changes: 13 additions & 6 deletions netmanager/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ select {
}

.filter {
z-index: 1000;
z-index: 100;
background-color: rgba(255, 255, 255, 1);
position: absolute;
top: 30px;
Expand Down Expand Up @@ -343,10 +343,9 @@ label {

.indicator {
position: absolute;
/* center position */
left: 50%;
transform: translateX(-50%);
z-index: 1000;
z-index: 100;
bottom: 10px;
display: flex;
flex-wrap: wrap;
Expand Down Expand Up @@ -386,6 +385,10 @@ label {

.indicator .hazardous {
background-color: #81202e;
}

.indicator .Offline {
background-color: #868686;
border-bottom-right-radius: 5px;
border-top-right-radius: 5px;
}
Expand All @@ -402,24 +405,28 @@ label {
margin: 0;
}

@media (max-width: 868px) {
/* tablet */
@media (max-width: 1024px) {
.indicator {
position: absolute;
left: 34%;
transform: translateX(-50%);
z-index: 1000;
z-index: 100;
bottom: 10px;
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-items: center;
bottom: 43px;
}
}

@media (max-width: 868px) {
.indicator .good {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
}
.indicator .hazardous {
.indicator .Offline {
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
Expand Down
22 changes: 22 additions & 0 deletions netmanager/src/views/components/MapIcons/Offline.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';

const Offline = ({ width, height, fill }) => {
return (
<svg
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
fill={fill}>
<g fill="#2e3436">
<path
d="M8 1.992c-2.617 0-5.238.934-7.195 2.809l-.496.48a.999.999 0 00-.032 1.41 1 1 0 001.414.028l.5-.477c3.086-2.953 8.532-2.953 11.618 0l.5.477a1 1 0 001.414-.028.999.999 0 00-.032-1.41l-.496-.48C13.238 2.926 10.617 1.992 8 1.992zM7.969 6c-1.57.012-3.13.629-4.207 1.813l-.5.55a.997.997 0 101.476 1.344l.5-.543c1.242-1.363 3.992-1.492 5.399-.129a1.999 1.999 0 011.777.55l.223.224c.011-.012.023-.02.039-.032a1 1 0 00.062-1.414l-.5-.55C11.113 6.582 9.535 5.988 7.968 6zM8 10a2 2 0 101.871 2.7l-.285-.286a2.014 2.014 0 01-.469-2.07A2.001 2.001 0 008 10zm0 0"
fillOpacity={0.34902}
/>
<path d="M11 10a1 1 0 00-.707 1.707L11.586 13l-1.293 1.293a1 1 0 101.414 1.414L13 14.414l1.293 1.293a1 1 0 101.414-1.414L14.414 13l1.293-1.293a1 1 0 10-1.414-1.414L13 11.586l-1.293-1.293A1 1 0 0011 10zm0 0" />
</g>
</svg>
);
};

export default Offline;
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import Unhealthy from 'views/components/MapIcons/Unhealthy';
import UnhealthySensitive from 'views/components/MapIcons/UnhealthySen';
import VeryUnhealthy from 'views/components/MapIcons/VeryUnhealthy';
import Hazardous from 'views/components/MapIcons/Hazardous';
import Offline from 'views/components/MapIcons/Offline';

const Tooltip = ({ children, text, icon, label }) => {
const [showTooltip, setShowTooltip] = React.useState(false);

return (
<div
className="air-quality-description"
style={{ position: 'relative', outline: 'none', border: 'none', margin: '13px 0' }}
onMouseEnter={() => setShowTooltip(true)}
onMouseLeave={() => setShowTooltip(false)}>
Expand Down Expand Up @@ -107,6 +109,12 @@ const Indicator = () => {
icon={<Hazardous width={30} height={30} fill="#81202e" />}>
<span className="hazardous">Hazardous</span>
</Tooltip>
<Tooltip
label="Offline"
text="Air quality sensor is offline."
icon={<Offline width={30} height={30} fill="#D3D3D3" />}>
<span className="Offline">Offline</span>
</Tooltip>
</div>
)}
</div>
Expand Down
167 changes: 68 additions & 99 deletions netmanager/src/views/pages/Heatmap/HeatMapOverlay.js
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,6 @@ export const OverlayMap = ({ center, zoom, heatMapData, monitoringSiteData }) =>
const mapContainerRef = useRef(null);
const [map, setMap] = useState();
const [showSensors, setShowSensors] = useState(true);
const [showHeatMap, setShowHeatMap] = useState(false);
const [showCalibratedValues, setShowCalibratedValues] = useState(false);

// Initialize showPollutant state with localStorage values
Expand Down Expand Up @@ -395,7 +394,7 @@ export const OverlayMap = ({ center, zoom, heatMapData, monitoringSiteData }) =>
// Initialize map
const map = new mapboxgl.Map({
container: mapContainerRef.current,
style: localStorage.getItem('mapStyle') || lightMapStyle,
style: localStorage.getItem('mapStyle') || streetMapStyle,
center,
zoom,
maxZoom: 20
Expand All @@ -408,7 +407,7 @@ export const OverlayMap = ({ center, zoom, heatMapData, monitoringSiteData }) =>
setMap(map);

// Clean up on unmount
return () => map.remove();
// return () => map.remove();
}, []);

// Update heatmap data when available
Expand Down Expand Up @@ -488,86 +487,74 @@ export const OverlayMap = ({ center, zoom, heatMapData, monitoringSiteData }) =>
}
};

const createMarker = (feature) => {
const [seconds, duration] = getFirstDuration(feature.properties.time);
let pollutantValue = null;
let markerKey = '';

// Loop through the showPollutant object and get the value and key for the selected pollutant
for (const property in showPollutant) {
if (showPollutant[property]) {
markerKey = property;
pollutantValue = feature.properties[property] && feature.properties[property].value;
if (showCalibratedValues) {
pollutantValue =
feature.properties[property] && feature.properties[property].calibratedValue;
}
break;
}
}

const [markerClass, desc] = getMarkerDetail(pollutantValue, markerKey);

const el = document.createElement('div');
el.className = `marker ${seconds >= MAX_OFFLINE_DURATION ? 'marker-grey' : markerClass}`;
el.style.borderRadius = seconds >= MAX_OFFLINE_DURATION ? '10%' : '50%';
el.style.display = 'flex';
el.style.justifyContent = 'center';
el.style.alignItems = 'center';
el.style.fontSize = `${seconds >= MAX_OFFLINE_DURATION ? '10px' : '12px'}`;
el.style.width = seconds >= MAX_OFFLINE_DURATION ? '15px' : '30px';
el.style.height = seconds >= MAX_OFFLINE_DURATION ? '15px' : '30px';
el.style.padding = '10px';
el.innerHTML = pollutantValue ? Math.floor(pollutantValue) : '--';

if (
feature.geometry.coordinates.length >= 2 &&
feature.geometry.coordinates[0] &&
feature.geometry.coordinates[1] &&
pollutantValue !== null
) {
const marker = new mapboxgl.Marker(el)
.setLngLat(feature.geometry.coordinates)
.setPopup(
new mapboxgl.Popup({
offset: 25,
className: 'map-popup'
}).setHTML(MapPopup(feature, showPollutant, pollutantValue, desc, duration, markerClass))
)
.addTo(map);

// Listen to the zoom event of the map
map.on('zoom', function () {
// Get the current zoom level of the map
const zoom = map.getZoom();
// Calculate the size based on the zoom level
const size = (30 * zoom) / 10;
// Set the size of the marker
el.style.width = `${size}px`;
el.style.height = `${size}px`;
});
}
};

return (
<div className="overlay-map-container" ref={mapContainerRef}>
{showSensors &&
map &&
monitoringSiteData.features.length > 0 &&
monitoringSiteData.features.forEach((feature) => {
const [seconds, duration] = getFirstDuration(feature.properties.time);
let pollutantValue =
(showPollutant.pm2_5 && feature.properties.pm2_5 && feature.properties.pm2_5.value) ||
(showPollutant.pm10 && feature.properties.pm10 && feature.properties.pm10.value) ||
(showPollutant.no2 && feature.properties.no2 && feature.properties.no2.value) ||
null;

if (showCalibratedValues) {
pollutantValue =
(showPollutant.pm2_5 &&
feature.properties.pm2_5 &&
feature.properties.pm2_5.calibratedValue &&
feature.properties.pm2_5.calibratedValue) ||
(showPollutant.pm10 &&
feature.properties.pm10 &&
feature.properties.pm10.calibratedValue &&
feature.properties.pm10.calibratedValue) ||
(showPollutant.no2 &&
feature.properties.no2 &&
feature.properties.no2.calibratedValue &&
feature.properties.no2.calibratedValue) ||
null;
}
let markerKey = '';
for (const property in showPollutant) {
if (showPollutant[property]) markerKey = property;
}
const [markerClass, desc] = getMarkerDetail(pollutantValue, markerKey);

const el = document.createElement('div');
el.className = `marker ${seconds >= MAX_OFFLINE_DURATION ? 'marker-grey' : markerClass}`;
el.style.borderRadius = '50%';
el.style.display = 'flex';
el.style.justifyContent = 'center';
el.style.alignItems = 'center';
el.style.fontSize = '12px';
el.style.width = '30px';
el.style.height = '30px';
el.style.padding = '10px';
el.innerHTML = showPollutant.pm2_5
? Math.floor(feature.properties.pm2_5.value)
: showPollutant.pm10
? Math.floor(feature.properties.pm10.value)
: '--';

if (
feature.geometry.coordinates.length >= 2 &&
feature.geometry.coordinates[0] &&
feature.geometry.coordinates[1] &&
pollutantValue !== null
) {
const marker = new mapboxgl.Marker(el)
.setLngLat(feature.geometry.coordinates)
.setPopup(
new mapboxgl.Popup({
offset: 25,
className: 'map-popup'
}).setHTML(
MapPopup(feature, showPollutant, pollutantValue, desc, duration, markerClass)
)
)
.addTo(map);

// Listen to the zoom event of the map
map.on('zoom', function () {
// Get the current zoom level of the map
const zoom = map.getZoom();
// Calculate the size based on the zoom level
const size = (30 * zoom) / 10;
// Set the size of the marker
el.style.width = `${size}px`;
el.style.height = `${size}px`;
});
}
createMarker(feature);
})}

<Filter pollutants={showPollutant} />
Expand Down Expand Up @@ -599,37 +586,19 @@ const HeatMapOverlay = () => {
if (isEmpty(monitoringSiteData.features)) {
dispatch(loadMapEventsData());
}
}, [monitoringSiteData]);
}, [dispatch, monitoringSiteData.features.length]);

return (
<ErrorBoundary>
<div
style={{
position: 'relative',
width: '100%',
height: '100%'
}}>
<div className="map-new-container">
<OverlayMap
center={[22.5600613, 0.8341424]}
zoom={2.4}
zoom={window.innerWidth <= 768 ? 2.0 : window.innerWidth <= 1440 ? 2.4 : 2.4}
heatMapData={heatMapData}
monitoringSiteData={monitoringSiteData}
/>
{monitoringSiteData && isEmpty(monitoringSiteData.features) && (
<div
style={{
position: 'absolute',
zIndex: 100,
top: 0,
left: 0,
width: '100%',
height: '100vh',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(255, 255, 255, 0.4)',
backdropFilter: 'blur(1px)'
}}>
<div className="map-circular-loader">
<CircularLoader loading={true} />
</div>
)}
Expand Down
Loading
Loading