update budget chart component to add rolling average projections and expiration date
This commit is contained in:
parent
5242ab2e2a
commit
9cc8ad75d2
@ -1,14 +1,15 @@
|
|||||||
import { format } from 'date-fns'
|
import { format, isWithinRange, addMonths, isSameMonth, getMonth } from 'date-fns'
|
||||||
import { abbreviateDollars, formatDollars } from '../../lib/dollars'
|
import { abbreviateDollars, formatDollars } from '../../lib/dollars'
|
||||||
|
|
||||||
const TOP_OFFSET = 20
|
const TOP_OFFSET = 20
|
||||||
const BOTTOM_OFFSET = 60
|
const BOTTOM_OFFSET = 70
|
||||||
const CHART_HEIGHT = 360
|
const CHART_HEIGHT = 360
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'budget-chart',
|
name: 'budget-chart',
|
||||||
props: {
|
props: {
|
||||||
currentMonth: String,
|
currentMonth: String,
|
||||||
|
expirationDate: String,
|
||||||
months: Object,
|
months: Object,
|
||||||
budget: String
|
budget: String
|
||||||
},
|
},
|
||||||
@ -46,18 +47,17 @@ export default {
|
|||||||
let lastSpendPoint = ''
|
let lastSpendPoint = ''
|
||||||
|
|
||||||
for (let i = 0; i < this.numMonths; i++) {
|
for (let i = 0; i < this.numMonths; i++) {
|
||||||
const { metrics, budget } = this.displayedMonths[i]
|
|
||||||
|
console.log(this.displayedMonths[i])
|
||||||
|
const { metrics, budget, rollingAverage, cumulativeTotal } = this.displayedMonths[i]
|
||||||
const blockWidth = (this.width / this.numMonths)
|
const blockWidth = (this.width / this.numMonths)
|
||||||
const blockX = blockWidth * i
|
const blockX = blockWidth * i
|
||||||
const spend = budget
|
const spend = budget && budget.spend
|
||||||
? budget.spend || lastSpend
|
? budget.spend
|
||||||
: 0
|
: rollingAverage
|
||||||
const cumulative = budget
|
|
||||||
? budget.cumulative || budget.projected
|
|
||||||
: 0
|
|
||||||
const barHeight = spend / this.heightScale
|
const barHeight = spend / this.heightScale
|
||||||
lastSpend = spend
|
lastSpend = spend
|
||||||
const cumulativeY = this.height - (cumulative / this.heightScale) - BOTTOM_OFFSET
|
const cumulativeY = this.height - (cumulativeTotal / this.heightScale) - BOTTOM_OFFSET
|
||||||
const cumulativeX = blockX + blockWidth/2
|
const cumulativeX = blockX + blockWidth/2
|
||||||
const cumulativePoint = `${cumulativeX} ${cumulativeY}`
|
const cumulativePoint = `${cumulativeX} ${cumulativeY}`
|
||||||
|
|
||||||
@ -77,9 +77,7 @@ export default {
|
|||||||
this.spendPath += this.spendPath === '' ? 'M' : ' L'
|
this.spendPath += this.spendPath === '' ? 'M' : ' L'
|
||||||
this.spendPath += cumulativePoint
|
this.spendPath += cumulativePoint
|
||||||
lastSpendPoint = cumulativePoint
|
lastSpendPoint = cumulativePoint
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if (budget && budget.projected) {
|
|
||||||
this.projectedPath += this.projectedPath === '' ? `M${lastSpendPoint} L` : ' L'
|
this.projectedPath += this.projectedPath === '' ? `M${lastSpendPoint} L` : ' L'
|
||||||
this.projectedPath += cumulativePoint
|
this.projectedPath += cumulativePoint
|
||||||
}
|
}
|
||||||
@ -88,32 +86,76 @@ export default {
|
|||||||
|
|
||||||
_setDisplayedMonths: function () {
|
_setDisplayedMonths: function () {
|
||||||
const [month, year] = this.currentMonth.split('/')
|
const [month, year] = this.currentMonth.split('/')
|
||||||
|
const [expYear, expMonth, expDate] = this.expirationDate.split('-') // assumes format 'YYYY-MM-DD'
|
||||||
const monthsRange = []
|
const monthsRange = []
|
||||||
const monthsBack = this.focusedMonthPosition
|
const monthsBack = this.focusedMonthPosition + 1
|
||||||
const monthsForward = this.numMonths - this.focusedMonthPosition - 1
|
const monthsForward = this.numMonths - this.focusedMonthPosition - 1
|
||||||
const start = new Date(year, month - 1 - monthsBack)
|
|
||||||
|
|
||||||
let previousAmount = 0
|
// currently focused date
|
||||||
|
const current = new Date(year, month)
|
||||||
|
|
||||||
|
// starting date of the chart
|
||||||
|
const start = addMonths(current, -monthsBack)
|
||||||
|
|
||||||
|
// ending date of the chart
|
||||||
|
const end = addMonths(start, this.numMonths + 1)
|
||||||
|
|
||||||
|
// expiration date
|
||||||
|
const expires = new Date(expYear, expMonth-1, expDate)
|
||||||
|
|
||||||
|
// is the expiration date within the displayed date range?
|
||||||
|
const expirationWithinRange = isWithinRange(expires, start, end)
|
||||||
|
|
||||||
|
let rollingAverage = 0
|
||||||
|
let cumulativeTotal = 0
|
||||||
|
|
||||||
for (let i = 0; i < this.numMonths; i++) {
|
for (let i = 0; i < this.numMonths; i++) {
|
||||||
const date = new Date(start.getFullYear(), start.getMonth() + i)
|
const date = addMonths(start, i)
|
||||||
|
const dateMinusOne = addMonths(date, -1)
|
||||||
|
const dateMinusTwo = addMonths(date, -2)
|
||||||
|
const dateMinusThree = addMonths(date, -3)
|
||||||
|
|
||||||
const index = format(date, 'MM/YYYY')
|
const index = format(date, 'MM/YYYY')
|
||||||
|
const indexMinusOne = format(dateMinusOne, 'MM/YYYY')
|
||||||
|
const indexMinusTwo = format(dateMinusTwo, 'MM/YYYY')
|
||||||
|
const indexMinusThree = format(dateMinusThree, 'MM/YYYY')
|
||||||
|
|
||||||
const budget = this.months[index] || null
|
const budget = this.months[index] || null
|
||||||
const spendAmount = budget ? budget.spend || previousAmount : 0
|
const spendAmount = budget ? budget.spend : rollingAverage
|
||||||
const cumulativeAmount = budget ? budget.cumulative || budget.projected : 0
|
const spendMinusOne = this.months[indexMinusOne] ? this.months[indexMinusOne].spend : rollingAverage
|
||||||
previousAmount = spendAmount
|
const spendMinusTwo = this.months[indexMinusTwo] ? this.months[indexMinusTwo].spend : rollingAverage
|
||||||
|
const spendMinusThree = this.months[indexMinusThree] ? this.months[indexMinusThree].spend : rollingAverage
|
||||||
|
|
||||||
|
const isExpirationMonth = isSameMonth(date, expires)
|
||||||
|
|
||||||
|
if (budget && budget.cumulative) {
|
||||||
|
cumulativeTotal = budget.cumulative
|
||||||
|
} else {
|
||||||
|
cumulativeTotal += spendAmount
|
||||||
|
}
|
||||||
|
|
||||||
|
rollingAverage = (
|
||||||
|
spendAmount
|
||||||
|
+ spendMinusOne
|
||||||
|
+ spendMinusTwo
|
||||||
|
+ spendMinusThree
|
||||||
|
) / 4
|
||||||
|
|
||||||
monthsRange.push({
|
monthsRange.push({
|
||||||
budget,
|
budget,
|
||||||
|
rollingAverage,
|
||||||
|
cumulativeTotal,
|
||||||
|
isExpirationMonth,
|
||||||
spendAmount: formatDollars(spendAmount),
|
spendAmount: formatDollars(spendAmount),
|
||||||
abbreviatedSpend: abbreviateDollars(spendAmount),
|
abbreviatedSpend: abbreviateDollars(spendAmount),
|
||||||
cumulativeAmount: formatDollars(cumulativeAmount),
|
cumulativeAmount: formatDollars(cumulativeTotal),
|
||||||
abbreviatedCumulative: abbreviateDollars(cumulativeAmount),
|
abbreviatedCumulative: abbreviateDollars(cumulativeTotal),
|
||||||
date: {
|
date: {
|
||||||
monthIndex: format(date, 'M'),
|
monthIndex: format(date, 'M'),
|
||||||
month: format(date, 'MMM'),
|
month: format(date, 'MMM'),
|
||||||
year: format(date,'YYYY')
|
year: format(date,'YYYY')
|
||||||
},
|
},
|
||||||
|
showYear: isExpirationMonth || (i === 0) || getMonth(date) === 0,
|
||||||
isHighlighted: this.currentMonth === index,
|
isHighlighted: this.currentMonth === index,
|
||||||
metrics: {
|
metrics: {
|
||||||
blockWidth: 0,
|
blockWidth: 0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user