mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-13 05:48:36 +03:00
Feature/handle cluster select from timeline (#175)
* Updating some styles for cover; updating copy * Wrote up getSelectedClusters function; testing * Working on select with clusters being highlighted; rendering highlight around both clusters and individual points, so there's a little overlap * Removed extraneous props being passed down to cluster Co-authored-by: efarooqui <efarooqui@pandora.com>
This commit is contained in:
@@ -261,7 +261,7 @@ class Dashboard extends React.Component {
|
||||
}
|
||||
|
||||
const popupStyles = {
|
||||
fontSize: 24,
|
||||
fontSize: 20,
|
||||
height: `calc(100vh - ${app.timeline.dimensions.height}px)`,
|
||||
width: '40vw',
|
||||
bottom: app.timeline.dimensions.height
|
||||
|
||||
@@ -17,7 +17,7 @@ import Narratives from './presentational/Map/Narratives'
|
||||
import DefsMarkers from './presentational/Map/DefsMarkers.jsx'
|
||||
import LoadingOverlay from '../components/Overlay/Loading'
|
||||
|
||||
import { mapClustersToLocations, isIdentical, isLatitude, isLongitude } from '../common/utilities'
|
||||
import { mapClustersToLocations, isIdentical, isLatitude, isLongitude, calculateTotalClusterPoints, calcClusterSize } from '../common/utilities'
|
||||
|
||||
// NB: important constants for map, TODO: make statics
|
||||
const supportedMapboxMap = ['streets', 'satellite']
|
||||
@@ -183,6 +183,29 @@ class Map extends React.Component {
|
||||
return []
|
||||
}
|
||||
|
||||
getSelectedClusters () {
|
||||
const { selected } = this.props.app
|
||||
const selectedIds = selected.map(sl => sl.id)
|
||||
|
||||
if (this.state.clusters && this.state.clusters.length > 0) {
|
||||
return this.state.clusters.reduce((acc, cl) => {
|
||||
if (cl.properties.cluster) {
|
||||
const children = this.getClusterChildren(cl.properties.cluster_id)
|
||||
if (children && children.length > 0) {
|
||||
children.forEach(child => {
|
||||
const clusterPresent = acc.findIndex(item => item.id === cl.id) >= 0
|
||||
if (selectedIds.includes(child.id) && !clusterPresent) {
|
||||
acc.push(cl)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
return acc
|
||||
}, [])
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
alignLayers () {
|
||||
const mapNode = document.querySelector('.leaflet-map-pane')
|
||||
if (mapNode === null) return { transformX: 0, transformY: 0 }
|
||||
@@ -341,10 +364,35 @@ class Map extends React.Component {
|
||||
}
|
||||
|
||||
renderSelected () {
|
||||
const selectedClusters = this.getSelectedClusters()
|
||||
const totalMarkers = []
|
||||
|
||||
this.props.app.selected.forEach(s => {
|
||||
const { latitude, longitude } = s
|
||||
totalMarkers.push({
|
||||
latitude,
|
||||
longitude,
|
||||
radius: this.props.ui.eventRadius
|
||||
})
|
||||
})
|
||||
|
||||
const totalClusterPoints = calculateTotalClusterPoints(this.state.clusters)
|
||||
|
||||
selectedClusters.forEach(cl => {
|
||||
if (cl.properties.cluster) {
|
||||
const { coordinates } = cl.geometry
|
||||
totalMarkers.push({
|
||||
latitude: String(coordinates[1]),
|
||||
longitude: String(coordinates[0]),
|
||||
radius: calcClusterSize(cl.properties.point_count, totalClusterPoints)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<SelectedEvents
|
||||
svg={this.svgRef.current}
|
||||
selected={this.props.app.selected}
|
||||
selected={totalMarkers}
|
||||
projectPoint={this.projectPoint}
|
||||
styles={this.props.ui.mapSelectedEvents}
|
||||
/>
|
||||
|
||||
@@ -8,7 +8,8 @@ import {
|
||||
isLatitude,
|
||||
isLongitude,
|
||||
calculateColorPercentages,
|
||||
zipColorsToPercentages } from '../../../common/utilities'
|
||||
zipColorsToPercentages,
|
||||
calculateTotalClusterPoints } from '../../../common/utilities'
|
||||
|
||||
const DefsClusters = () => (
|
||||
<defs>
|
||||
@@ -74,14 +75,10 @@ function ClusterEvents ({
|
||||
isRadial,
|
||||
svg,
|
||||
clusters,
|
||||
filterColors
|
||||
filterColors,
|
||||
selected
|
||||
}) {
|
||||
const totalPoints = clusters.reduce((total, cl) => {
|
||||
if (cl && cl.properties) {
|
||||
total += cl.properties.point_count
|
||||
}
|
||||
return total
|
||||
}, 0)
|
||||
const totalPoints = calculateTotalClusterPoints(clusters)
|
||||
|
||||
const styles = {
|
||||
fill: isRadial ? "url('#clusterGradient')" : colors.fallbackEventColor,
|
||||
|
||||
@@ -3,10 +3,10 @@ import { Portal } from 'react-portal'
|
||||
import colors from '../../../common/global.js'
|
||||
|
||||
class MapSelectedEvents extends React.Component {
|
||||
renderMarker (event) {
|
||||
const { x, y } = this.props.projectPoint([event.latitude, event.longitude])
|
||||
renderMarker (marker) {
|
||||
const { x, y } = this.props.projectPoint([marker.latitude, marker.longitude])
|
||||
const styles = this.props.styles
|
||||
const r = styles ? styles.r : 24
|
||||
const r = marker.radius ? marker.radius + 5 : 24
|
||||
return (
|
||||
<g
|
||||
className='location-marker'
|
||||
|
||||
Reference in New Issue
Block a user