Declaration
Code extract: Cards are declared in `data.html`
<div class="card col-sm-12">
<div class="card-number" id="numEvents"></div>
<div class="card-label"># Events</div>
</div>
FSI
Fills the fsi total value and the corresponding risk.
Code extract: Fillinng value and color
// FSI Score and Risk
const fsiScoreElement = document.getElementById('fsiScore');
const fsiRiskElement = document.getElementById('fsiRisk');
if (fsiScoreElement) {
fsiScoreElement.textContent = Math.round(data.fsi[0].total);
fsiScoreElement.style.color = getColorFSI(data.fsi[0].total)
fsiRiskElement.textContent = getRiskFSI(data.fsi[0].total);
fsiRiskElement.style.color = getColorFSI(data.fsi[0].total)
}
function getColorFSI(num){
switch (true) {
case (num>=90):
return 'rgba(151, 49, 49,1)';
case (num>=60 && num<90):
return 'rgba(223, 88, 58,1)';
case (num>=30 && num<60):
return 'rgb(246, 198, 4)';
case (num<30):
return 'rgba(44, 162, 95,1)';
default:
return 'rgba(204, 204, 204,0.5)'; // default color if none of the conditions match
}
}
function getRiskFSI(num){
console.log('num:', num);
switch (true) {
case (num>=90):
return 'Alert';
case (num>=60 && num<90):
return 'Warning';
case (num>=30 && num<60):
return 'Stable';
case (num<30):
return 'Sustainable';
default:
return 'No data'
}
}
Update ACLED Numbers
Numbers are calculated in data.js. The cardAcledDataOnMap function is called when the map is moved, or a filter is applied.
Code extract: Filter for Violence Against Civilians and fill cards
function cardAcledDataOnMap(filteredData) {
const features = filteredData.features;
// Calculate the number of unique events
const numEvents = new Set(features.map(feature => feature.properties.event_id_cnty)).size;
// Calculate the total number of fatalities
const numFatalities = features.reduce((sum, feature) => sum + feature.properties.fatalities, 0);
// Calculate the number of unique actors
const actors = new Set(features.flatMap(feature => [feature.properties.actor1, feature.properties.actor2].filter(actor => actor)));
const numActors = actors.size;
// Calculate the number of VAC events and fatalities, both number and percentage
const VACFatalities = features.reduce((sum, feature) => feature.properties.civilian_targeting === 'Civilian targeting' ? sum + feature.properties.fatalities : sum, 0);
const VACEvents = new Set(features.filter(feature => feature.properties.civilian_targeting === 'Civilian targeting').map(feature => feature.properties.event_id_cnty)).size;
const percVACEvents = Math.round((VACEvents / numEvents) * 100) + '%';
const percVACFatalities = Math.round((VACFatalities / numFatalities) * 100) + '%';
// Update the card elements with the calculated values and colors
document.getElementById('numEvents').textContent = numEvents;
document.getElementById('numEvents').style.color = 'rgba(0, 69, 128,1)';
document.getElementById('numFatalities').textContent = numFatalities;
document.getElementById('numFatalities').style.color = 'rgba(151, 49, 49,1)';
document.getElementById('numActors').textContent = numActors;
document.getElementById('numActors').style.color = 'rgba(120, 29, 125,1)';
document.getElementById('VACEvents').textContent = VACEvents + " (" + percVACEvents + ")";
document.getElementById('VACEvents').style.color = 'rgba(0, 69, 128,1)';
document.getElementById('VACFatalities').textContent = VACFatalities + "(" + percVACFatalities + ")";
document.getElementById('VACFatalities').style.color = 'rgba(151, 49, 49,1)';
}
Style
The card class style is declared in the CSS file
Code extract: CSS card class definition
.card {
border: 1px solid #f8f9fa;
border-radius: 8px;
padding: 16px;
margin: 16px;
text-align: center;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.card-number {
font-size: 2em;
font-weight: bold;
}
.card-label {
font-size: 1em;
}
Each card color is declared in data.js, see code above