diff --git a/src/components/Map.jsx b/src/components/Map.jsx index 9591507..ae340bc 100644 --- a/src/components/Map.jsx +++ b/src/components/Map.jsx @@ -63,7 +63,6 @@ class Map extends React.Component { } initializeMap () { - return /** * Creates a Leaflet map and a tilelayer for the map background */ diff --git a/src/components/Timeline.jsx b/src/components/Timeline.jsx index 9239328..a51da5b 100644 --- a/src/components/Timeline.jsx +++ b/src/components/Timeline.jsx @@ -259,8 +259,8 @@ class Timeline extends React.Component { this.props.methods.onUpdateTimerange(this.state.timerange) } - getDatetimeX (dt) { - return this.state.scaleX(parseDate(dt.timestamp)) + getDatetimeX (timestamp) { + return this.state.scaleX(parseDate(timestamp)) } /** diff --git a/src/components/presentational/Timeline/Events.js b/src/components/presentational/Timeline/Events.js index cd159a7..bcb79c1 100644 --- a/src/components/presentational/Timeline/Events.js +++ b/src/components/presentational/Timeline/Events.js @@ -1,6 +1,7 @@ import React from 'react' import DatetimeDot from './DatetimeDot' import DatetimeBar from './DatetimeBar' +import Project from './Project' import { getEventOpacity } from '../../../common/utilities' import { sizes } from '../../../common/global' @@ -85,7 +86,7 @@ const TimelineEvents = ({ onSelect={() => onSelect(unlocatedEvents)} category={dot.category} events={unlocatedEvents} - x={getDatetimeX(datetime)} + x={getDatetimeX(datetime.timestamp)} y={dims.marginTop} width={sizes.eventDotR} height={dims.trackHeight} @@ -98,7 +99,7 @@ const TimelineEvents = ({ onSelect={() => onSelect(unlocatedEvents)} category={dot.category} events={[ev]} - x={getDatetimeX(datetime)} + x={getDatetimeX(datetime.timestamp)} y={ev.projectOffset >= 0 ? dims.trackHeight - ev.projectOffset : dims.marginTop} width={sizes.eventDotR} height={ev.projectOffset >= 0 ? sizes.eventDotR * 2 : 20} @@ -112,7 +113,7 @@ const TimelineEvents = ({ onSelect={() => onSelect(locatedEvents)} category={dot.category} events={locatedEvents} - x={getDatetimeX(datetime)} + x={getDatetimeX(datetime.timestamp)} y={getCategoryY(dot.category)} r={sizes.eventDotR} styleProps={locatedProps} @@ -125,10 +126,32 @@ const TimelineEvents = ({ }) } + // const projOffsets = {} + // const pEvents = datetimes.filter(dt => dt.events.some(ev => ev.project !== null)) + // pEvents.forEach(({ events }) => { + // events.forEach(ev => { + // if (!projOffsets.hasOwnProperty(ev.project)) { + // projOffsets[ev.project] = ev.projectOffset + // } + // }) + // }) + + let projects + if (process.env.features.ASSOCIATIVE_EVENTS_BY_TAG) { + projects = datetimes[1] + datetimes = datetimes[0] + } + return ( + {projects.map(project => ())} {datetimes.map(datetime => renderDatetime(datetime))} ) diff --git a/src/components/presentational/Timeline/Markers.js b/src/components/presentational/Timeline/Markers.js index 663269e..ee9d1ab 100644 --- a/src/components/presentational/Timeline/Markers.js +++ b/src/components/presentational/Timeline/Markers.js @@ -24,7 +24,7 @@ const TimelineMarkers = ({ stroke-linejoin='round' stroke-dasharray={styles ? styles['stroke-dasharray'] : '2,2'} style={{ - 'transform': `translate(${getEventX(event)}px, ${getCategoryY(event.category)}px)`, + 'transform': `translate(${getEventX(event.timestamp)}px, ${getCategoryY(event.category)}px)`, '-webkit-transition': `transform ${transitionDuration / 1000}s ease`, '-moz-transition': 'none', 'opacity': 0.9 @@ -43,7 +43,7 @@ const TimelineMarkers = ({ stroke-width={styles ? styles['stroke-width'] : 1} stroke-dasharray={styles ? styles['stroke-dasharray'] : '2,2'} style={{ - 'transform': `translate(${getEventX(event)}px, 40px)`, + 'transform': `translate(${getEventX(event.timestamp)}px, 40px)`, '-webkit-transition': `transform ${transitionDuration / 1000}s ease`, '-moz-transition': 'none', 'opacity': 0.9 diff --git a/src/components/presentational/Timeline/Project.js b/src/components/presentational/Timeline/Project.js new file mode 100644 index 0000000..7368d97 --- /dev/null +++ b/src/components/presentational/Timeline/Project.js @@ -0,0 +1,23 @@ +import React from 'react' +import { sizes } from '../../../common/global' + +export default ({ + id, + offset, + start, + end, + getX, + dims, + colour +}) => { + const length = getX(end) - getX(start) + return alert('TODO: associate all events')} + className='project' + x={getX(start)} + y={dims.trackHeight - offset} + width={length} + style={{ fill: colour, fillOpacity: 0.1 }} + height={2 * sizes.eventDotR} + /> +} diff --git a/src/selectors/index.js b/src/selectors/index.js index e634cba..6ca51b2 100644 --- a/src/selectors/index.js +++ b/src/selectors/index.js @@ -149,13 +149,16 @@ export const selectLocations = createSelector( events: [...] } */ +const IS_PROJ = 'ASSOCIATIVE_EVENTS_BY_TAG' in process.env.features && process.env.features.ASSOCIATIVE_EVENTS_BY_TAG export const selectDatetimes = createSelector( [selectEvents], events => { const projects = {} const datetimes = {} events.forEach(event => { - if (process.env.features.ASSOCIATIVE_EVENTS_BY_TAG) { + const { timestamp } = event + const dtKey = `${timestamp}_1` + if (IS_PROJ) { const project = event.tags.length >= 1 ? event.tags[0] : null event = { ...event, project } if (project !== null) { @@ -167,11 +170,16 @@ export const selectDatetimes = createSelector( } } } - const { timestamp } = event - if (datetimes.hasOwnProperty(timestamp)) { - datetimes[timestamp].events.push(event) + const tsExists = datetimes.hasOwnProperty(dtKey) + const isLocated = !!event.latitude && !!event.longitude + if (IS_PROJ && !isLocated && event.project !== null && tsExists) { + if (tsExists) { + alert('not yet handling cases with multiple... talk to lk@forensic-architecture.org') + } + } else if (tsExists) { + datetimes[dtKey].events.push(event) } else { - datetimes[timestamp] = { + datetimes[dtKey] = { timestamp: event.timestamp, date: event.date, time: event.time, @@ -179,27 +187,47 @@ export const selectDatetimes = createSelector( } } }) - // console.log(projects) - // console.log(datetimes) const projKeys = Object.keys(projects) function checkActive (pj, dt) { return dt >= projects[pj].start && dt <= projects[pj].end } + const output = [] let sortedDts = Object.keys(datetimes) - sortedDts.sort((a, b) => new Date(a) - new Date(b)) + sortedDts.sort((a, b) => { + const x = a.substring(0, a.length - 2) + const y = b.substring(0, b.length - 2) + return new Date(x) - new Date(y) + }) sortedDts.forEach(dt => { const activeProjects = [] projKeys.forEach((k, idx) => { if (checkActive(k, dt)) activeProjects.push(k) }) - datetimes[dt].events = datetimes[dt].events.map(ev => ({ - ...ev, - projectOffset: (activeProjects.indexOf(ev.project)) * (2 * sizes.eventDotR + 5) - })) + output.push({ + ...datetimes[dt], + events: datetimes[dt].events.map(ev => { + let projectOffset = (activeProjects.indexOf(ev.project) + 1) * (2.5 * sizes.eventDotR) + if (ev.project !== null && !projects[ev.project].hasOwnProperty('offset')) { + projects[ev.project].offset = projectOffset + projects[ev.project].category = ev.category + } else if (ev.project !== null) { + projectOffset = projects[ev.project].offset + } + return { + ...ev, + projectOffset + } + }) + }) }) - - // TODO: calculate Y offset based on projects - return Object.values(datetimes) + const projectsOut = [] + Object.keys(projects).forEach(projId => { + projectsOut.push({ ...projects[projId], id: projId }) + }) + if (IS_PROJ) { + return [output, projectsOut] + } + return output } )