mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-12 21:38:35 +03:00
removes numbers, increases opacity for more events instead
This commit is contained in:
@@ -174,3 +174,11 @@ export function typeForPath (path) {
|
||||
export function selectTypeFromPathWithPoster (path, poster) {
|
||||
return { type: typeForPath(path), path, poster }
|
||||
}
|
||||
|
||||
export function getEventOpacity (events) {
|
||||
/* Events have opacity 0.5 by default, and get added to according to how many
|
||||
* other events there are in the same render. The idea here is that the
|
||||
* overlaying of events builds up a 'heat map' of the event space, where
|
||||
* darker areas represent more events with proportion */
|
||||
return 0.3 + (Math.min(0.5, 0.08 * (events.length - 1)))
|
||||
}
|
||||
|
||||
@@ -193,16 +193,11 @@ class Map extends React.Component {
|
||||
* also has full access to the domain and redux state to derive values if
|
||||
* necessary. The function should return an array, where the value at the
|
||||
* first index is a styles object for the SVG at the location, and the value
|
||||
* at the second index is an optional function that renders additional
|
||||
* components in the <g/> div.
|
||||
* at the second index is an optional additional component that renders in
|
||||
* the <g/> div.
|
||||
*/
|
||||
styleLocation (location) {
|
||||
const noEvents = location.events.length
|
||||
|
||||
return [
|
||||
null,
|
||||
() => noEvents > 1 ? <text className='location-count' dx='-3' dy='4'>{noEvents}</text> : null
|
||||
]
|
||||
return [null, null]
|
||||
}
|
||||
|
||||
renderEvents () {
|
||||
|
||||
@@ -254,20 +254,16 @@ class Timeline extends React.Component {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines additional styles on the <circle> for each timestamp. Note that
|
||||
* timestamp visualisation functions slightly differently from locations, as
|
||||
* a timestamp can be shown as multiple <circle>s (one per category of the
|
||||
* events contained therein). Thus the function below has a category as an
|
||||
* argumnent as well, in case timestamps ought to be styled per category.
|
||||
* A datetime consists of an array of events (see selectors). The function
|
||||
* Determines additional styles on the <circle> for each location.
|
||||
* A location consists of an array of events (see selectors). The function
|
||||
* also has full access to the domain and redux state to derive values if
|
||||
* necessary. The function should return an array, where the value at the
|
||||
* first index is a styles object for the SVG at the location, and the value
|
||||
* at the second index is an optional function that renders additional
|
||||
* components in the <g/> div.
|
||||
* at the second index is an optional additional component that renders in
|
||||
* the <g/> div.
|
||||
*/
|
||||
styleDatetime (timestamp, category) {
|
||||
return []
|
||||
return [null, null]
|
||||
}
|
||||
|
||||
render () {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react'
|
||||
import { Portal } from 'react-portal'
|
||||
import colors from '../../../common/global.js'
|
||||
import { getEventOpacity } from '../../../common/utilities'
|
||||
|
||||
function MapEvents ({ getCategoryColor, categories, projectPoint, styleLocation, selected, narrative, onSelect, svg, locations }) {
|
||||
function getCoordinatesForPercent (radius, percent) {
|
||||
@@ -33,7 +34,7 @@ function MapEvents ({ getCategoryColor, categories, projectPoint, styleLocation,
|
||||
fill: getCategoryColor(locCategory),
|
||||
stroke: colors.darkBackground,
|
||||
strokeWidth: 0,
|
||||
fillOpacity: 0.85,
|
||||
fillOpacity: getEventOpacity(location.events),
|
||||
...extraStyles
|
||||
})
|
||||
|
||||
@@ -108,7 +109,11 @@ function MapEvents ({ getCategoryColor, categories, projectPoint, styleLocation,
|
||||
}
|
||||
|
||||
const customStyles = styleLocation ? styleLocation(location) : null
|
||||
const extraRender = (customStyles) ? customStyles[1] : null
|
||||
const extraRender = () => (
|
||||
<React.Fragment>
|
||||
{customStyles[1]}
|
||||
</React.Fragment>
|
||||
)
|
||||
|
||||
const isSelected = selected.reduce((acc, event) => {
|
||||
return acc || (event.latitude === location.latitude && event.longitude === location.longitude)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react'
|
||||
import DatetimeDot from './DatetimeDot'
|
||||
import { getEventOpacity } from '../../../common/utilities'
|
||||
|
||||
// return a list of lists, where each list corresponds to a single category
|
||||
function getDotsToRender (events) {
|
||||
@@ -55,16 +56,26 @@ const TimelineEvents = ({
|
||||
return dotsToRender.map(dot => {
|
||||
const customStyles = styleDatetime ? styleDatetime(datetime, dot.category) : null
|
||||
const extraStyles = customStyles[0]
|
||||
const extraRender = customStyles[1]
|
||||
|
||||
// const isLocated = dot.events.map(ev => !ev.latitude || !ev.longitude)
|
||||
|
||||
// TODO: work out smarter way to manage opacity w.r.t. length
|
||||
// i.e. render (count - 1) extra dots with a bit of noise in position
|
||||
// and that, when clicked, all open the same events.
|
||||
const styleProps = ({
|
||||
fill: getCategoryColor(dot.category),
|
||||
fillOpacity: 1,
|
||||
fillOpacity: getEventOpacity(dot.events),
|
||||
transition: `transform ${transitionDuration / 1000}s ease`,
|
||||
...extraStyles
|
||||
})
|
||||
|
||||
return (
|
||||
const extraRender = () => (
|
||||
<React.Fragment>
|
||||
{customStyles[1]}
|
||||
</React.Fragment>
|
||||
)
|
||||
|
||||
return (<React.Fragment>
|
||||
<DatetimeDot
|
||||
onSelect={onSelect}
|
||||
category={dot.category}
|
||||
@@ -74,6 +85,7 @@ const TimelineEvents = ({
|
||||
styleProps={styleProps}
|
||||
extraRender={extraRender}
|
||||
/>
|
||||
</React.Fragment>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -189,12 +189,6 @@
|
||||
stroke-width: 2px;
|
||||
}
|
||||
|
||||
.location-count {
|
||||
z-index: 100;
|
||||
font-weight: 900;
|
||||
fill: #d0d0d0;
|
||||
}
|
||||
|
||||
.no-hover {
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user