react-app/src/reducers/reducer-active-country.js
import {
combine_vectors
} from '../helpers/helper-general'
import {
get_diagonal
} from '../helpers/helper-general'
import {
getMatrix
} from '../helpers/helper-general'
import {
get_scores
} from '../helpers/helper-general'
const config = require('../config.js')
let country_admins = {}
let admin_index = {}
// List of scores to represent mobility toward each admin
// Order is by geoFeature index
let scores = []
let combined_vectors = []
// Keep a running tally of admins that user wants to compare
let selected_admins = {}
let geojson = {
'properties': {
'alpha2': null,
'alpha3': null
},
'type': 'FeatureCollection',
'features': []
}
let initial_state = {
polygons: geojson,
points: geojson,
selectedCountry: null,
selectedCountryName: " . ",
selectedCountryNumSchools: null,
selectedCountryAvgMbps: null,
usingSpeed: false
}
/**
* Returns style for leaflet polygon
* @param {object} state state
* @param {object} action action
* @return {boolean} boolean
*/
function activeCountryReducer(state = initial_state, action) {
switch (action.type) {
case 'COUNTRY_SELECTED':
if (config.mode !== 'schools') {
country_admins = action.payload
let admin_index = country_admins.features.reduce((h, f, i) => {
h[f.properties.admin_id] = i;
return h;
}, {});
return Object.assign({}, state, {
polygons: action.payload,
admin_index: admin_index
})
} else {
return Object.assign(action.payload, {
polygons: geojson
})
}
case 'ADMIN_SELECTED':
let admin_id = action.payload.target.feature.properties.admin_id
// Add or remove admin_id to selected_admins object
if (selected_admins[admin_id]) {
delete selected_admins[admin_id]
} else {
selected_admins[admin_id] = 1
}
// If there are no selected admins
// return scores: null
// Admin styles will default to diagonal
if (Object.keys(selected_admins).length == 0) {
diagonal = state.diagonal
scores = get_scores(diagonal)
return Object.assign({}, state, {
polygons: Object.assign({}, country_admins),
scores: scores,
selected_admins: selected_admins
})
}
// USE THIS LATER TO ENABLE USER TO CLICK ADMIN MULTIPLE TIMES
// TO INCREASE INTENSITY
// selected_admins[admin_id] = selected_admins[admin_id] ?
// selected_admins[admin_id] + 1 : 1
// Combines all vectors for clicked admins
combined_vectors = combine_vectors(
state.admin_index,
state.matrix,
selected_admins
)
// Reduce scores to between 0 and 1
scores = get_scores(combined_vectors, [])
return Object.assign({}, state, {
polygons: Object.assign({}, country_admins),
scores: scores,
selected_admins: selected_admins
})
// On date select, there may be admins selected from
// from a previous date fetch
case 'DATE_SELECTED':
// Create dictionary of admin_id to index feature in geojson
let lookup = state.admin_index
let mobility = action.payload.mobility;
let matrix = getMatrix(mobility, lookup);
// Diagonal is each admin_id and the num people
// who only made calls within that admin
let diagonal = get_diagonal(matrix)
// IN CASE MORE THAN ONE ADMIN IS ALREADY CLICKED
// Combines all vectors for clicked admins
// Check selected admins exist from previous date select
if (Object.keys(selected_admins).length > 0) {
admin_index = state.admin_index || admin_index
selected_admins = state.selected_admins || selected_admins
combined_vectors = combine_vectors(admin_index, matrix, selected_admins)
scores = get_scores(combined_vectors, [])
} else {
// Map values to scores between 0 and 1
scores = get_scores(diagonal)
}
return Object.assign({}, state, {
polygons: Object.assign({}, country_admins),
diagonal: diagonal,
matrix,
// Set scores to null in case admins were previously selected
scores: scores
})
default:
return state
}
}
export default activeCountryReducer