improve project graph

This commit is contained in:
Lachlan Kermode
2020-03-27 17:44:52 +01:00
parent 85476ee6fb
commit 421af5e60c
7 changed files with 99 additions and 59 deletions

View File

@@ -34,9 +34,12 @@ export function fetchDomain () {
.then(response => response.json())
.catch(() => handleError(domainMsg('categories')))
const narPromise = fetch(NARRATIVE_URL)
.then(response => response.json())
.catch(() => handleError(domainMsg('narratives')))
let narPromise = Promise.resolve([])
if (process.env.features.USE_CATEGORIES) {
narPromise = fetch(NARRATIVE_URL)
.then(response => response.json())
.catch(() => handleError(domainMsg('narratives')))
}
let sitesPromise = Promise.resolve([])
if (process.env.features.USE_SITES) {

View File

@@ -69,7 +69,7 @@ class TimelineAxis extends React.Component {
/>
<g
ref={this.xAxis1Ref}
transform={`translate(0, ${this.props.dims.trackHeight + 35})`}
transform={`translate(0, 10)`}
clipPath={`url(#clip)`}
className={`axis axisHourText`}
/>

View File

@@ -94,6 +94,7 @@ function MapEvents ({ getCategoryColor, categories, projectPoint, styleLocation,
longitude: '32.2'
}
*/
if (!location.latitude || !location.longitude) return null
const { x, y } = projectPoint([location.latitude, location.longitude])
// in narrative mode, only render events in narrative

View File

@@ -21,5 +21,3 @@ export default ({
height={height}
/>
)
// export default () => null

View File

@@ -136,22 +136,27 @@ const TimelineEvents = ({
// })
// })
let projects
let renderProjects = () => null
if (process.env.features.ASSOCIATIVE_EVENTS_BY_TAG) {
projects = datetimes[1]
const projects = datetimes[1]
datetimes = datetimes[0]
renderProjects = function () {
return <React.Fragment>
{projects.map(project => <Project
{...project}
getX={getDatetimeX}
dims={dims}
colour={getCategoryColor(project.category)}
/>)}
</React.Fragment>
}
}
return (
<g
clipPath={'url(#clip)'}
>
{projects.map(project => (<Project
{...project}
getX={getDatetimeX}
dims={dims}
colour={getCategoryColor(project.category)}
/>))}
{renderProjects()}
{datetimes.map(datetime => renderDatetime(datetime))}
</g>
)

View File

@@ -23,7 +23,7 @@ const eventSchema = Joi.object().keys({
narrative___stepStyles: Joi.array()
})
.and('latitude', 'longitude')
.and('date', 'time', 'timestamp')
.and('date', 'timestamp')
.or('timestamp', 'latitude')
export default eventSchema

View File

@@ -60,6 +60,9 @@ export const selectEvents = createSelector(
export const selectNarratives = createSelector(
[getEvents, getNarratives, getSources],
(events, narrativesMeta, sources) => {
if (!process.env.features.USE_NARRATIVES) {
return []
}
const narratives = {}
const narrativeSkeleton = id => ({ id, steps: [] })
@@ -157,7 +160,16 @@ export const selectDatetimes = createSelector(
const datetimes = {}
events.forEach(event => {
const { timestamp } = event
const dtKey = `${timestamp}_1`
/** Create timestamp with fresh dtKey always by default */
let dtIdx = 1
let dtKey = `${timestamp}_${dtIdx}`
let tsExists = datetimes.hasOwnProperty(dtKey)
while (tsExists) {
dtIdx += 1
dtKey = `${timestamp}_${dtIdx}`
tsExists = datetimes.hasOwnProperty(dtKey)
}
if (IS_PROJ) {
const project = event.tags.length >= 1 ? event.tags[0] : null
event = { ...event, project }
@@ -170,64 +182,85 @@ export const selectDatetimes = createSelector(
}
}
}
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')
/** We need to work out whether we can add the event to an existing
* timestamp, or whether we need to create a new one. What determines
* this is whether or not ALL events in a timestamp have a matching
* project. We not only need to check the current dtKey, but also all
* dtKeys that have the same timestamp.
*
* It's a pretty whack algorithm, but I think it does what it's supposed
* to. This is only run when projects are showing.
* TODO: find a more module way to interface with this code.
*/
let shouldCreate = true
if (IS_PROJ && dtIdx >= 2 && !(!!event.latitude && !!event.longitude) && event.project !== null) {
const allExistingIdxs = [...Array(dtIdx - 1).keys()].map(k => k + 1)
let foundMatching = false
allExistingIdxs.forEach(_idx => {
const _dtKey = `${timestamp}_${_idx}`
const isSameTimestampAndAllSameProjects = datetimes[_dtKey].events.every(ev => ev.project === event.project)
if (isSameTimestampAndAllSameProjects) {
dtKey = _dtKey
foundMatching = true
}
})
if (!foundMatching) {
shouldCreate = true
}
} else if (tsExists) {
datetimes[dtKey].events.push(event)
} else {
}
if (shouldCreate) {
datetimes[dtKey] = {
timestamp: event.timestamp,
date: event.date,
time: event.time,
events: [event]
}
} else {
datetimes[dtKey].events.push(event)
}
})
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) => {
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)
if (IS_PROJ) {
const projKeys = Object.keys(projects)
let sortedDts = Object.keys(datetimes)
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)
})
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
}
sortedDts.forEach(dt => {
const activeProjects = []
projKeys.forEach((k, idx) => {
if (dt >= projects[k].start && dt <= projects[k].end) activeProjects.push(k)
})
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
}
})
})
})
})
const projectsOut = []
Object.keys(projects).forEach(projId => {
projectsOut.push({ ...projects[projId], id: projId })
})
if (IS_PROJ) {
const projectsOut = []
Object.keys(projects).forEach(projId => {
projectsOut.push({ ...projects[projId], id: projId })
})
return [output, projectsOut]
}
return output
return Object.values(datetimes)
}
)