mermaid/src/diagrams/gantt/ganttDb.js

387 lines
8.7 KiB
JavaScript
Raw Normal View History

2017-09-10 19:41:34 +08:00
import moment from 'moment'
import { logger } from '../../logger'
2017-04-11 22:14:25 +08:00
2017-09-14 20:59:58 +08:00
let dateFormat = ''
let axisFormat = ''
2019-02-06 16:54:09 -02:00
let excludes = []
2017-09-14 20:59:58 +08:00
let title = ''
let sections = []
let tasks = []
let currentSection = ''
2017-04-11 22:14:25 +08:00
2017-09-10 21:23:04 +08:00
export const clear = function () {
2017-04-11 22:14:25 +08:00
sections = []
tasks = []
currentSection = ''
title = ''
taskCnt = 0
lastTask = undefined
lastTaskID = undefined
rawTasks = []
}
export const setAxisFormat = function (txt) {
axisFormat = txt
}
export const getAxisFormat = function () {
return axisFormat
}
2017-09-10 21:23:04 +08:00
export const setDateFormat = function (txt) {
2017-04-11 22:14:25 +08:00
dateFormat = txt
}
2019-02-06 16:54:09 -02:00
export const setExcludes = function (txt) {
excludes = txt.split(' ')
}
2017-09-10 21:23:04 +08:00
export const setTitle = function (txt) {
2017-04-11 22:14:25 +08:00
title = txt
}
2017-09-10 21:23:04 +08:00
export const getTitle = function () {
2017-04-11 22:14:25 +08:00
return title
}
2017-09-10 21:23:04 +08:00
export const addSection = function (txt) {
2017-04-11 22:14:25 +08:00
currentSection = txt
sections.push(txt)
}
2017-09-10 21:23:04 +08:00
export const getTasks = function () {
2017-09-14 20:59:58 +08:00
let allItemsPricessed = compileTasks()
const maxDepth = 10
let iterationCount = 0
2017-04-11 22:14:25 +08:00
while (!allItemsPricessed && (iterationCount < maxDepth)) {
allItemsPricessed = compileTasks()
iterationCount++
}
tasks = rawTasks
return tasks
}
2015-02-08 20:07:15 +01:00
2019-02-06 16:54:09 -02:00
const getNextValidDate = function (date, dateFormat, excludes) {
2019-02-06 17:09:59 -02:00
const excludeWeekends = excludes.indexOf('weekend') >= 0 || excludes.indexOf('weekends') >= 0
2019-02-06 16:54:09 -02:00
const trimmedDateFormat = dateFormat.trim()
2019-02-06 17:09:59 -02:00
let mDate = moment.isMoment(date) ? date : (moment.isDate(date) ? moment(date) : moment(date, dateFormat, true))
const isInvalidDate = function (d) {
return (excludeWeekends && d.isoWeekday() >= 6) || (excludes.indexOf(d.format(trimmedDateFormat)) >= 0)
}
while (isInvalidDate(mDate)) {
2019-02-06 16:54:09 -02:00
mDate = mDate.add(1, 'd')
}
2019-02-06 17:09:59 -02:00
return mDate.toDate()
2019-02-06 16:54:09 -02:00
}
const getStartDate = function (prevTime, dateFormat, excludes, str) {
2017-04-11 22:14:25 +08:00
str = str.trim()
2017-04-16 23:48:36 +08:00
// Test for after
2017-09-14 20:59:58 +08:00
const re = /^after\s+([\d\w-]+)/
const afterStatement = re.exec(str.trim())
2015-10-21 21:14:41 +02:00
2017-04-11 22:14:25 +08:00
if (afterStatement !== null) {
2017-09-14 20:59:58 +08:00
const task = findTaskById(afterStatement[1])
2017-04-11 22:14:25 +08:00
if (typeof task === 'undefined') {
2017-09-14 20:59:58 +08:00
const dt = new Date()
2017-04-11 22:14:25 +08:00
dt.setHours(0, 0, 0, 0)
return dt
2015-02-08 20:07:15 +01:00
}
2017-04-11 22:14:25 +08:00
return task.endTime
}
2017-04-16 23:48:36 +08:00
// Check for actual date set
2019-02-06 17:09:59 -02:00
let mDate = moment(str, dateFormat.trim(), true)
2019-02-06 16:54:09 -02:00
if (mDate.isValid()) {
return getNextValidDate(mDate, dateFormat, excludes)
2017-04-11 22:14:25 +08:00
} else {
2017-09-10 19:41:34 +08:00
logger.debug('Invalid date:' + str)
logger.debug('With date format:' + dateFormat.trim())
2017-04-11 22:14:25 +08:00
}
2017-04-16 23:48:36 +08:00
// Default date - now
2019-02-06 16:54:09 -02:00
return getNextValidDate(new Date(), dateFormat, excludes)
2017-04-11 22:14:25 +08:00
}
2015-02-08 20:07:15 +01:00
2019-02-06 16:54:09 -02:00
const getEndDate = function (prevTime, dateFormat, excludes, str) {
2017-04-11 22:14:25 +08:00
str = str.trim()
2017-04-16 23:48:36 +08:00
// Check for actual date
2019-02-06 17:09:59 -02:00
let mDate = moment(str, dateFormat.trim(), true)
2019-02-06 16:54:09 -02:00
if (mDate.isValid()) {
return mDate.toDate()
2017-04-11 22:14:25 +08:00
}
2017-09-14 20:59:58 +08:00
const d = moment(prevTime)
2017-04-16 23:48:36 +08:00
// Check for length
2017-09-14 20:59:58 +08:00
const re = /^([\d]+)([wdhms])/
const durationStatement = re.exec(str.trim())
2017-04-11 22:14:25 +08:00
if (durationStatement !== null) {
switch (durationStatement[2]) {
case 's':
d.add(durationStatement[1], 'seconds')
break
case 'm':
d.add(durationStatement[1], 'minutes')
break
case 'h':
d.add(durationStatement[1], 'hours')
break
case 'd':
d.add(durationStatement[1], 'days')
break
case 'w':
d.add(durationStatement[1], 'weeks')
break
2015-02-08 20:07:15 +01:00
}
2017-04-11 22:14:25 +08:00
}
2017-04-16 23:48:36 +08:00
// Default date - now
2019-02-06 16:54:09 -02:00
return getNextValidDate(d, dateFormat, excludes)
2017-04-11 22:14:25 +08:00
}
2017-09-14 20:59:58 +08:00
let taskCnt = 0
const parseId = function (idStr) {
2017-04-11 22:14:25 +08:00
if (typeof idStr === 'undefined') {
taskCnt = taskCnt + 1
return 'task' + taskCnt
}
return idStr
}
2015-02-08 20:07:15 +01:00
// id, startDate, endDate
// id, startDate, length
// id, after x, endDate
// id, after x, length
// startDate, endDate
// startDate, length
// after x, endDate
// after x, length
// endDate
// length
2017-09-14 20:59:58 +08:00
const compileData = function (prevTask, dataStr) {
let ds
2017-04-11 22:14:25 +08:00
if (dataStr.substr(0, 1) === ':') {
ds = dataStr.substr(1, dataStr.length)
} else {
ds = dataStr
}
2017-09-14 20:59:58 +08:00
const data = ds.split(',')
2017-09-14 20:59:58 +08:00
const task = {}
2017-04-16 23:48:36 +08:00
// Get tags like active, done cand crit
2017-09-14 20:59:58 +08:00
let matchFound = true
2017-04-11 22:14:25 +08:00
while (matchFound) {
matchFound = false
if (data[0].match(/^\s*active\s*$/)) {
task.active = true
data.shift(1)
matchFound = true
2015-02-08 20:07:15 +01:00
}
2017-04-11 22:14:25 +08:00
if (data[0].match(/^\s*done\s*$/)) {
task.done = true
data.shift(1)
matchFound = true
2015-10-21 21:14:41 +02:00
}
2017-04-11 22:14:25 +08:00
if (data[0].match(/^\s*crit\s*$/)) {
task.crit = true
data.shift(1)
matchFound = true
2015-10-21 21:14:41 +02:00
}
2017-04-11 22:14:25 +08:00
}
2017-09-14 20:59:58 +08:00
for (let i = 0; i < data.length; i++) {
2017-04-11 22:14:25 +08:00
data[i] = data[i].trim()
}
switch (data.length) {
case 1:
task.id = parseId()
task.startTime = prevTask.endTime
2019-02-06 16:54:09 -02:00
task.endTime = getEndDate(task.startTime, dateFormat, excludes, data[0])
2017-04-11 22:14:25 +08:00
break
case 2:
task.id = parseId()
2019-02-06 16:54:09 -02:00
task.startTime = getStartDate(undefined, dateFormat, excludes, data[0])
task.endTime = getEndDate(task.startTime, dateFormat, excludes, data[1])
2017-04-11 22:14:25 +08:00
break
case 3:
task.id = parseId(data[0])
2019-02-06 16:54:09 -02:00
task.startTime = getStartDate(undefined, dateFormat, excludes, data[1])
task.endTime = getEndDate(task.startTime, dateFormat, excludes, data[2])
2017-04-11 22:14:25 +08:00
break
default:
}
return task
}
2017-09-14 20:59:58 +08:00
const parseData = function (prevTaskId, dataStr) {
let ds
2017-04-11 22:14:25 +08:00
if (dataStr.substr(0, 1) === ':') {
ds = dataStr.substr(1, dataStr.length)
} else {
ds = dataStr
}
2017-09-14 20:59:58 +08:00
const data = ds.split(',')
2017-04-11 22:14:25 +08:00
2017-09-14 20:59:58 +08:00
const task = {}
2015-10-21 21:14:41 +02:00
2017-04-16 23:48:36 +08:00
// Get tags like active, done cand crit
2017-09-14 20:59:58 +08:00
let matchFound = true
2017-04-11 22:14:25 +08:00
while (matchFound) {
matchFound = false
if (data[0].match(/^\s*active\s*$/)) {
task.active = true
data.shift(1)
matchFound = true
2015-10-21 21:14:41 +02:00
}
2017-04-11 22:14:25 +08:00
if (data[0].match(/^\s*done\s*$/)) {
task.done = true
data.shift(1)
matchFound = true
2015-10-21 21:14:41 +02:00
}
2017-04-11 22:14:25 +08:00
if (data[0].match(/^\s*crit\s*$/)) {
task.crit = true
data.shift(1)
matchFound = true
2015-10-21 21:14:41 +02:00
}
2017-04-11 22:14:25 +08:00
}
2017-09-14 20:59:58 +08:00
for (let i = 0; i < data.length; i++) {
2017-04-11 22:14:25 +08:00
data[i] = data[i].trim()
}
switch (data.length) {
case 1:
task.id = parseId()
2017-04-16 23:48:36 +08:00
task.startTime = { type: 'prevTaskEnd', id: prevTaskId }
task.endTime = { data: data[0] }
2017-04-11 22:14:25 +08:00
break
case 2:
task.id = parseId()
2017-04-16 23:48:36 +08:00
task.startTime = { type: 'getStartDate', startData: data[0] }
task.endTime = { data: data[1] }
2017-04-11 22:14:25 +08:00
break
case 3:
task.id = parseId(data[0])
2017-04-16 23:48:36 +08:00
task.startTime = { type: 'getStartDate', startData: data[1] }
task.endTime = { data: data[2] }
2017-04-11 22:14:25 +08:00
break
default:
}
return task
}
2017-09-14 20:59:58 +08:00
let lastTask
let lastTaskID
let rawTasks = []
const taskDb = {}
2017-09-10 21:23:04 +08:00
export const addTask = function (descr, data) {
2017-09-14 20:59:58 +08:00
const rawTask = {
2017-04-11 22:14:25 +08:00
section: currentSection,
type: currentSection,
processed: false,
2017-04-16 23:48:36 +08:00
raw: { data: data },
2017-04-11 22:14:25 +08:00
task: descr
}
2017-09-14 20:59:58 +08:00
const taskInfo = parseData(lastTaskID, data)
2017-04-11 22:14:25 +08:00
rawTask.raw.startTime = taskInfo.startTime
rawTask.raw.endTime = taskInfo.endTime
rawTask.id = taskInfo.id
rawTask.prevTaskId = lastTaskID
rawTask.active = taskInfo.active
rawTask.done = taskInfo.done
rawTask.crit = taskInfo.crit
2017-09-14 20:59:58 +08:00
const pos = rawTasks.push(rawTask)
2017-04-11 22:14:25 +08:00
lastTaskID = rawTask.id
2017-04-16 23:48:36 +08:00
// Store cross ref
2017-04-11 22:14:25 +08:00
taskDb[rawTask.id] = pos - 1
}
2017-09-10 21:23:04 +08:00
export const findTaskById = function (id) {
2017-09-14 20:59:58 +08:00
const pos = taskDb[id]
2017-04-11 22:14:25 +08:00
return rawTasks[pos]
}
2017-09-10 21:23:04 +08:00
export const addTaskOrg = function (descr, data) {
2017-09-14 20:59:58 +08:00
const newTask = {
2017-04-11 22:14:25 +08:00
section: currentSection,
type: currentSection,
description: descr,
task: descr
}
2017-09-14 20:59:58 +08:00
const taskInfo = compileData(lastTask, data)
2017-04-11 22:14:25 +08:00
newTask.startTime = taskInfo.startTime
newTask.endTime = taskInfo.endTime
newTask.id = taskInfo.id
newTask.active = taskInfo.active
newTask.done = taskInfo.done
newTask.crit = taskInfo.crit
lastTask = newTask
tasks.push(newTask)
}
2017-09-14 20:59:58 +08:00
const compileTasks = function () {
const compileTask = function (pos) {
const task = rawTasks[pos]
let startTime = ''
2017-04-11 22:14:25 +08:00
switch (rawTasks[pos].raw.startTime.type) {
case 'prevTaskEnd':
2017-09-14 20:59:58 +08:00
const prevTask = findTaskById(task.prevTaskId)
2017-04-11 22:14:25 +08:00
task.startTime = prevTask.endTime
break
case 'getStartDate':
2019-02-06 16:54:09 -02:00
startTime = getStartDate(undefined, dateFormat, excludes, rawTasks[pos].raw.startTime.startData)
2017-04-11 22:14:25 +08:00
if (startTime) {
rawTasks[pos].startTime = startTime
2015-10-21 21:14:41 +02:00
}
2017-04-11 22:14:25 +08:00
break
}
2015-10-21 21:14:41 +02:00
2017-04-11 22:14:25 +08:00
if (rawTasks[pos].startTime) {
2019-02-06 16:54:09 -02:00
rawTasks[pos].endTime = getEndDate(rawTasks[pos].startTime, dateFormat, excludes, rawTasks[pos].raw.endTime.data)
2017-04-11 22:14:25 +08:00
if (rawTasks[pos].endTime) {
rawTasks[pos].processed = true
}
}
2017-04-11 22:14:25 +08:00
return rawTasks[pos].processed
}
2015-10-21 21:14:41 +02:00
2017-09-14 20:59:58 +08:00
let allProcessed = true
for (let i = 0; i < rawTasks.length; i++) {
2017-04-11 22:14:25 +08:00
compileTask(i)
2017-04-11 22:14:25 +08:00
allProcessed = allProcessed && rawTasks[i].processed
}
return allProcessed
}
2017-09-10 21:51:48 +08:00
export default {
clear,
setDateFormat,
setAxisFormat,
getAxisFormat,
2017-09-10 21:51:48 +08:00
setTitle,
getTitle,
addSection,
getTasks,
addTask,
findTaskById,
2019-02-06 16:54:09 -02:00
addTaskOrg,
setExcludes
2017-09-10 21:51:48 +08:00
}