multiple select

This commit is contained in:
louai98 2024-06-04 15:00:39 +02:00
parent c969bb351b
commit 18c1cf0b25
5 changed files with 351 additions and 108 deletions

View File

@ -1,12 +1,12 @@
import React, { createRef, useContext } from "react";
import Stack from "react-bootstrap/Stack";
import { MapContainer, GeoJSON, Marker, Tooltip } from "react-leaflet";
import L, { control } from "leaflet";
import L from "leaflet";
import Africa from "../../../Data/ControlinAfrica.geojson";
import "../../../Styles/main.scss";
import { CountryStyle, CountrySelectedStyle } from "./countryStyles";
import MapInfoBox from "./MapInfoBox"; // Import the InfoBox component
import MarkerIcon, { iconMarker } from "./MarkerIcon";
import Container from "react-bootstrap/Container";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
@ -54,13 +54,22 @@ class ControlInAfricaMap extends React.Component {
zoom: 4,
scrollWheelZoom: false,
selectedCountry: "",
openedTooltipLayer: null,
selectedCountriesNames: [],
selectedCountriesFeatures: [],
selectedCountryColor: "yellow",
selectedCountry: "",
selectedRegion: "",
prevStatues: "",
selectedTreaty: "",
selectedCountriesNamesRegions: [],
selectedCountriesNamesTreaties: [],
selectedCountriesFeaturesRegions: [],
selectedCountriesFeaturesTreaties: [],
selectedCountriesIntersections: [],
selectedCountryColor: "yellow",
prevStatuesRegion: "",
prevStatuesTreaty: "",
infoBox: [],
showInfoBox: false,
@ -256,6 +265,7 @@ class ControlInAfricaMap extends React.Component {
direction: "top",
className: "tooltip-custom",
}).setContent(popupContent);
layer.bindTooltip(tooltip).openTooltip();
// Update the state to store the currently opened tooltip
@ -263,77 +273,205 @@ class ControlInAfricaMap extends React.Component {
};
onMouseClick = (e) => {
this.setState({
selectedCountriesNames: [],
selectedCountryColor: "yellow",
showInfoBox: false,
});
const countryName = e.target.feature.properties.name;
if (countryName === this.state.selectedCountry) {
this.setState({ selectedCountry: "" });
this.setState({
selectedCountry: "",
selectedRegion: "",
selectedTreaty: "",
selectedCountriesNamesRegions: [],
selectedCountriesNamesTreaties: [],
selectedCountriesFeaturesRegions: [],
selectedCountriesFeaturesTreaties: [],
selectedCountriesIntersections: [],
selectedCountryColor: "yellow",
prevStatuesRegion: "",
prevStatuesTreaty: "",
infoBox: [],
showInfoBox: false,
});
this.props.updateCountryID(null);
return;
}
this.setState({ selectedCountry: countryName });
this.setState({
selectedCountry: countryName,
selectedRegion: "",
selectedTreaty: "",
selectedCountriesNamesRegions: [],
selectedCountriesNamesTreaties: [],
selectedCountriesFeaturesRegions: [],
selectedCountriesFeaturesTreaties: [],
selectedCountriesIntersections: [],
selectedCountryColor: "yellow",
prevStatuesRegion: "",
prevStatuesTreaty: "",
infoBox: [],
showInfoBox: false,
});
this.props.updateCountryID(e.target.feature.properties.id);
};
handleOrganizationClick = (name, status, color) => {
const { selectedRegion, prevStatues, africaCountries } = this.state;
const {
selectedRegion,
prevStatuesRegion,
prevStatuesTreaty,
africaCountries,
} = this.state;
if (selectedRegion === name && prevStatues === status) {
if (selectedRegion === name && prevStatuesRegion === status) {
console.log("same");
this.setState({
selectedCountriesNames: [],
selectedCountriesNamesRegions: [],
selectedCountriesNamesTreaties: [],
selectedCountryColor: "yellow",
selectedCountry: "",
selectedRegion: "",
prevStatues: "",
prevStatuesRegion: "",
showInfoBox: false,
});
return;
}
let selectedCountriesNames = [];
let selectedCountriesFeatures = [];
if (prevStatuesTreaty) {
console.log("change");
this.setState({
selectedCountriesNamesTreaties: [],
selectedCountry: "",
});
}
let selectedCountriesNamesRegions = [];
let selectedCountriesFeaturesRegions = [];
africaCountries.forEach((feature) => {
if (feature.properties[name] === 1) {
selectedCountriesNamesRegions.push(feature.properties.name);
selectedCountriesFeaturesRegions.push(feature);
}
});
this.setState({
selectedCountriesNamesRegions,
selectedCountryColor: color,
selectedCountry: "",
selectedRegion: name,
prevStatuesRegion: status,
selectedCountriesFeaturesRegions,
selectedTreaty: "",
showInfoBox: true,
});
};
handleTreatiesClick = (name, status, color) => {
const {
selectedRegion,
selectedTreaty,
selectedCountriesNamesRegions,
prevStatuesTreaty,
africaCountries,
} = this.state;
// if the same treaty is selected previously and the region is not selected
// then the treaty will be deselected
if (
selectedTreaty === name &&
prevStatuesTreaty === status &&
selectedRegion === ""
) {
console.log("1");
this.setState({
selectedCountriesNamesRegions: [],
selectedCountriesNamesTreaties: [],
selectedCountryColor: "yellow",
selectedCountry: "",
selectedTreaty: "",
prevStatuesTreaty: "",
prevStatuesRegion: "",
showInfoBox: false,
});
return;
}
// if the same treaty is selected previously and the region is selected
// then the treaty will be deselected
if (selectedTreaty === name && prevStatuesTreaty === status) {
console.log("2");
this.setState({
selectedCountriesNamesTreaties: [],
selectedCountry: "",
selectedTreaty: "",
prevStatuesTreaty: "",
showInfoBox: true,
});
return;
}
let selectedCountriesNamesTreaties = [];
let selectedCountriesFeaturesTreaties = [];
africaCountries.forEach((feature) => {
if (
feature.properties[name] === 1 ||
feature.properties[name] === status
) {
selectedCountriesNames.push(feature.properties.name);
selectedCountriesFeatures.push(feature);
selectedCountriesNamesTreaties.push(feature.properties.name);
selectedCountriesFeaturesTreaties.push(feature);
}
});
this.setState(
{
selectedCountriesNames,
selectedCountryColor: color,
selectedCountry: "",
selectedRegion: name,
prevStatues: status,
selectedCountriesFeatures,
},
if (selectedRegion) {
console.log("intersect");
const intersection = selectedCountriesNamesTreaties.filter((country) =>
selectedCountriesNamesRegions.includes(country)
);
if (this.regional_organisations.some(org => org.name === name)) {
this.setState({
selectedCountriesNamesTreaties: intersection,
//selectedCountryColor: "yellow",
selectedCountry: "",
selectedTreaty: name,
prevStatuesTreaty: status,
showInfoBox: true,
},
this.regionalOrganisationStatistics
)
});
return;
}
else{
this.setState({
showInfoBox: false,
})
selectedCountriesNamesTreaties,
selectedCountry: "",
selectedTreaty: name,
prevStatuesTreaty: status,
selectedCountriesFeaturesTreaties,
});
// if region and treaty selected
if (
this.state.selectedRegion &&
this.regional_treaties.some((org) => org.name2 === name)
) {
this.setState({
//selectedCountriesNamesRegions,
//selectedCountryColor: color,
//selectedCountry: "",
//selectedRegion: name,
//prevStatuesRegion: status,
//selectedCountriesFeaturesRegions,
selectedTreaty: name,
});
}
};
regionalOrganisationStatistics = () => {
const { selectedCountriesFeatures } = this.state;
const { selectedCountriesFeaturesRegions } = this.state;
// Helper function to process treaties
const processTreaties = (treaties) => {
@ -342,7 +480,7 @@ class ControlInAfricaMap extends React.Component {
let countriesEligible = 0;
let countriesRatified = 0;
selectedCountriesFeatures.forEach((feature) => {
selectedCountriesFeaturesRegions.forEach((feature) => {
const status = feature.properties[org.name2];
if (status === "Signed") {
countriesSigned++;
@ -370,7 +508,7 @@ class ControlInAfricaMap extends React.Component {
);
const organisationsInstruments = this.intsruments.map((instrument) => {
const countris = selectedCountriesFeatures.filter(
const countris = selectedCountriesFeaturesRegions.filter(
(feature) => feature.properties[instrument.name2] === 1
);
return {
@ -386,6 +524,41 @@ class ControlInAfricaMap extends React.Component {
};
};
// Define the function to determine the style
getFeatureStyle = (
feature,
selectedCountry,
selectedCountriesNamesRegions,
selectedCountriesNamesTreaties,
selectedCountryColor
) => {
if (feature.properties.name === selectedCountry) {
console.log("one country selected");
return CountrySelectedStyle(selectedCountryColor);
} else if (
selectedCountriesNamesRegions.includes(feature.properties.name) &&
selectedCountriesNamesTreaties.length === 0
) {
console.log("region selected");
return CountrySelectedStyle(selectedCountryColor);
} else if (
selectedCountriesNamesRegions.includes(feature.properties.name) &&
selectedCountriesNamesTreaties.includes(feature.properties.name) === false
) {
console.log("region and treaty selected 1");
return CountrySelectedStyle(selectedCountryColor);
} else if (
selectedCountriesNamesRegions.includes(feature.properties.name) &&
selectedCountriesNamesTreaties.includes(feature.properties.name)
) {
console.log("region and treaty selected 2");
return CountrySelectedStyle(selectedCountryColor, 0.7);
} else {
console.log("default");
return CountryStyle();
}
};
render() {
const findColorByName = (name) => {
const org = this.regional_organisations.find((org) => org.name === name);
@ -398,9 +571,11 @@ class ControlInAfricaMap extends React.Component {
error,
countriesNames,
selectedCountry,
selectedCountriesNames,
selectedCountriesNamesRegions,
selectedCountriesNamesTreaties,
selectedCountryColor,
selectedRegion,
selectedTreaty,
} = this.state;
if (loading) {
@ -464,10 +639,7 @@ class ControlInAfricaMap extends React.Component {
srcSet=""
className="icon"
onClick={() =>
this.handleOrganizationClick(
treaty.name2,
"Eligible"
)
this.handleTreatiesClick(treaty.name2, "Eligible")
}
/>
)}
@ -479,7 +651,7 @@ class ControlInAfricaMap extends React.Component {
srcSet=""
className="icon"
onClick={() =>
this.handleOrganizationClick(treaty.name2, "Signed")
this.handleTreatiesClick(treaty.name2, "Signed")
}
/>
)}
@ -491,10 +663,7 @@ class ControlInAfricaMap extends React.Component {
srcSet=""
className="icon"
onClick={() =>
this.handleOrganizationClick(
treaty.name2,
"Ratified"
)
this.handleTreatiesClick(treaty.name2, "Ratified")
}
/>
)}
@ -517,7 +686,7 @@ class ControlInAfricaMap extends React.Component {
srcSet=""
className="icon-2"
onClick={() =>
this.handleOrganizationClick(treaty.name2, "Eligible")
this.handleTreatiesClick(treaty.name2, "Eligible")
}
/>
)}
@ -529,7 +698,7 @@ class ControlInAfricaMap extends React.Component {
srcSet=""
className="icon-2"
onClick={() =>
this.handleOrganizationClick(treaty.name2, "Signed")
this.handleTreatiesClick(treaty.name2, "Signed")
}
/>
)}
@ -541,7 +710,7 @@ class ControlInAfricaMap extends React.Component {
srcSet=""
className="icon-2"
onClick={() =>
this.handleOrganizationClick(treaty.name2, "Ratified")
this.handleTreatiesClick(treaty.name2, "Ratified")
}
/>
)}
@ -563,7 +732,7 @@ class ControlInAfricaMap extends React.Component {
alt=""
className="icon-2"
onClick={() =>
this.handleOrganizationClick("UNProgrammeofAction")
this.handleTreatiesClick("UNProgrammeofAction")
}
/>
</div>
@ -576,9 +745,7 @@ class ControlInAfricaMap extends React.Component {
alt=""
className="icon-2"
onClick={() =>
this.handleOrganizationClick(
"InternationalTracingInstrument"
)
this.handleTreatiesClick("InternationalTracingInstrument")
}
/>
</div>
@ -594,7 +761,7 @@ class ControlInAfricaMap extends React.Component {
src={Icon1}
alt=""
className="icon-2"
onClick={() => this.handleOrganizationClick("StG-PoA")}
onClick={() => this.handleTreatiesClick("StG-PoA")}
/>
</div>
</div>
@ -617,12 +784,13 @@ class ControlInAfricaMap extends React.Component {
onEachFeature={this.onEachFeature}
id="africa-map"
style={(feature) =>
feature.properties.name === selectedCountry ||
selectedCountriesNames.find(
(item) => item === feature.properties.name
this.getFeatureStyle(
feature,
selectedCountry,
selectedCountriesNamesRegions,
selectedCountriesNamesTreaties,
selectedCountryColor
)
? CountrySelectedStyle(selectedCountryColor)
: CountryStyle()
}
key="africa-map"
data={africaCountries}
@ -729,6 +897,27 @@ class ControlInAfricaMap extends React.Component {
}
})}
{selectedTreaty &&
selectedCountriesNamesTreaties &&
africaCountries.map((feature, index) => {
if (
selectedCountriesNamesTreaties.includes(
feature.properties.name
)
) {
return (
<MarkerIcon
key={index}
position={[
feature.properties.y,
feature.properties.x,
]}
icon={Icon20}
></MarkerIcon>
);
}
})}
<div className="custom-zoom-control">
<button onClick={this.zoomIn}>+</button>
<button onClick={this.zoomOut}>-</button>

View File

@ -4,13 +4,14 @@ const MapInfoBox = (props) => {
const regional_treaties = props.info.organisationsRegionalTreaties;
const international_treaties = props.info.organisationsInternationalTreaties;
const instruments = props.info.organisationsInstruments;
console.log(regional_treaties);
return (
<div className={props.className}>
<h3>{props.selectedRegion}</h3>
<p>Number of countries</p>
<div className="table-responsive-sm">
<table className="table table-sm table-striped">
<thead>
<tr>
<th className="text-center" scope="col"></th>
<th className="text-center" scope="col">
@ -23,6 +24,7 @@ const MapInfoBox = (props) => {
Ratified
</th>
</tr>
</thead>
<tbody>
{regional_treaties &&
regional_treaties.map((item, index) => {

View File

@ -0,0 +1,49 @@
import React from "react";
import L from "leaflet";
import { Marker } from "react-leaflet";
import Icon1 from "../../../Icons/icon1.svg";
import Icon2 from "../../../Icons/icon2.svg";
import Icon3 from "../../../Icons/icon3.svg";
import Icon4 from "../../../Icons/icon4.svg";
import Icon5 from "../../../Icons/icon5.svg";
import Icon6 from "../../../Icons/icon6.svg";
import Icon7 from "../../../Icons/icon7.svg";
import Icon8 from "../../../Icons/icon8.svg";
import Icon9 from "../../../Icons/icon9.svg";
import Icon10 from "../../../Icons/icon10.svg";
import Icon11 from "../../../Icons/icon11.svg";
import Icon12 from "../../../Icons/icon12.svg";
import Icon13 from "../../../Icons/icon13.svg";
import Icon14 from "../../../Icons/icon14.svg";
import Icon15 from "../../../Icons/icon15.svg";
import Icon16 from "../../../Icons/icon16.svg";
import Icon17 from "../../../Icons/icon17.svg";
import Icon18 from "../../../Icons/icon18.svg";
import Icon19 from "../../../Icons/icon19.svg";
import Icon20 from "../../../Icons/icon20.svg";
import Icon21 from "../../../Icons/icon21.svg";
import Icon22 from "../../../Icons/icon22.svg";
import Icon23 from "../../../Icons/icon23.svg";
import Icon24 from "../../../Icons/icon24.svg";
import Icon25 from "../../../Icons/icon25.svg";
import Icon26 from "../../../Icons/icon26.svg";
const MarkerIcon = (props) => {
return (
<Marker
key={props.index}
position= {props.position}
icon={
new L.Icon({
iconUrl: props.icon,
iconRetinaUrl: props.icon,
iconSize: [35, 35],
className: "leaflet-div-icon",
})
}
></Marker>
);
};
export default MarkerIcon;

View File

@ -8,13 +8,14 @@ export const CountryStyle = () => {
};
};
export const CountrySelectedStyle = (color) => {
export const CountrySelectedStyle = (color, opacity = 0.3) => {
return {
fillColor: color,
color: "black",
weight: 3,
fillOpacity: opacity,
};
};
}
export const CountryHighlightStyle = () => {
return {
@ -22,4 +23,4 @@ export const CountryStyle = () => {
color: "black",
weight: 3,
};
}
};

View File

@ -5,19 +5,21 @@ import Title from "../Layout/ControlInAfrica/Title";
import DetailsSection from "../Layout/ControlInAfrica/DetailsSection";
const ControlInAfrica = (props) => {
const [countryID, setCountryID] = useState(null);
const updateCountryID = (countryID) => {
setCountryID(countryID)
}
setCountryID(countryID);
};
return (
<Container fluid className="p-5">
<Title></Title>
<ControlInAfricaMap updateCountryID={updateCountryID}></ControlInAfricaMap>
<ControlInAfricaMap
updateCountryID={updateCountryID}
></ControlInAfricaMap>
{countryID !== null && (
<DetailsSection countryID={countryID}></DetailsSection>
)}
</Container>
);
};