render one dot per category in a datetime

This commit is contained in:
Lachlan Kermode
2019-01-09 15:15:04 +00:00
parent 899e06d560
commit 1506c62f50
3 changed files with 88 additions and 49 deletions

View File

@@ -0,0 +1,27 @@
import React from 'react'
export default ({
category,
events,
x,
y,
styleProps,
extraRender
}) => (
<g
className='datetime'
transform={`translate(${x}, ${y})`}
onClick={() => onSelect(datetime.events)}
>
<circle
className="event"
cx={0}
cy={0}
style={styleProps}
r={5}
>
</circle>
{ extraRender ? extraRender() : null }
</g>
)

View File

@@ -1,27 +1,38 @@
import React from 'react';
import DatetimeDot from './DatetimeDot'
// return a list of lists, where each list corresponds to a single category
function getDotsToRender(events) {
// each datetime needs to render as many dots as there are distinct
// categories in the events contained by the datetime.
// To this end, eventsByCategory is an intermediate data structure that
// groups a datetime's events by distinct categories
const eventsByCategory = {}
events.forEach(ev => {
if (eventsByCategory[ev.category]) {
eventsByCategory[ev.category].events.push((ev))
} else {
eventsByCategory[ev.category] = {
category: ev.category,
events: [ ev ]
}
}
})
return Object.values(eventsByCategory)
}
const TimelineEvents = ({
datetimes,
narrative,
getDatetimeX,
getDatetimeY,
getCategoryY,
getCategoryColor,
onSelect,
transitionDuration,
styleDatetime
}) => {
function renderDatetime(datetime) {
const customStyles = styleDatetime ? styleDatetime(datetime) : null
const extraStyles = customStyles[0]
const extraRender = customStyles[1]
const styleProps = ({
fill: getCategoryColor(datetime.events[0].category),
fillOpacity: 1,
transition: `transform ${transitionDuration / 1000}s ease`,
...extraStyles
});
if (narrative) {
const { steps } = narrative
const isInNarrative = steps.map(s => s.id).includes(event.id)
@@ -31,23 +42,31 @@ const TimelineEvents = ({
}
}
return (
<g
className='datetime'
transform={`translate(${getDatetimeX(datetime)}, ${getDatetimeY(datetime)})`}
onClick={() => onSelect(datetime.events)}
>
<circle
className="event"
cx={0}
cy={0}
style={styleProps}
r={5}
>
</circle>
{ extraRender ? extraRender() : null }
</g>
)
const dotsToRender = getDotsToRender(datetime.events)
return dotsToRender.map(dot => {
const customStyles = styleDatetime ? styleDatetime(datetime, dot.category) : null
const extraStyles = customStyles[0]
const extraRender = customStyles[1]
const styleProps = ({
fill: getCategoryColor(dot.category),
fillOpacity: 1,
transition: `transform ${transitionDuration / 1000}s ease`,
...extraStyles
})
return (
<DatetimeDot
category={dot.category}
events={dot.events}
x={getDatetimeX(datetime)}
y={getCategoryY(dot.category)}
styleProps={styleProps}
extraRender={extraRender}
/>
)
})
}
return (