removes numbers, increases opacity for more events instead

This commit is contained in:
Lachlan Kermode
2020-02-24 05:55:00 +13:00
parent 8bf783b30e
commit afc84e61ac
6 changed files with 38 additions and 28 deletions

View File

@@ -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)))
}

View File

@@ -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 () {

View File

@@ -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 () {

View File

@@ -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)

View File

@@ -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>
)
})
}

View File

@@ -189,12 +189,6 @@
stroke-width: 2px;
}
.location-count {
z-index: 100;
font-weight: 900;
fill: #d0d0d0;
}
.no-hover {
cursor: grab;
}