budget chart vue component

This commit is contained in:
Andrew Croce 2018-09-07 15:43:07 -04:00
parent d882c552dc
commit 22dc20ab73

View File

@ -1,39 +1,90 @@
import * as d3 from 'd3' import * as d3 from 'd3'
import { format } from 'date-fns' import { format } from 'date-fns'
import { abbreviateDollars, formatDollars } from '../../lib/dollars'
const TOP_OFFSET = 20
const BOTTOM_OFFSET = 60
const CHART_HEIGHT = 360
export default { export default {
name: 'budget-chart', name: 'budget-chart',
props: { props: {
currentMonth: String, currentMonth: String,
months: Object months: Object,
budget: String
}, },
data: function () { data: function () {
const heightScale = this.budget / (CHART_HEIGHT - TOP_OFFSET - BOTTOM_OFFSET)
return { return {
numMonths: 10, numMonths: 10,
focusedMonthPosition: 4, // 5th spot in zero-based index, focusedMonthPosition: 4,
height: 300, height: CHART_HEIGHT,
heightScale,
budgetHeight: CHART_HEIGHT - BOTTOM_OFFSET - (this.budget / heightScale),
baseHeight: CHART_HEIGHT - BOTTOM_OFFSET,
width: 0, width: 0,
displayedMonths: [] displayedMonths: [],
spendPath: '',
projectedPath: '',
displayBudget: formatDollars(parseFloat(this.budget))
} }
}, },
computed: {
},
mounted: function () { mounted: function () {
console.log(this.displayedMonths)
this._setDisplayedMonths() this._setDisplayedMonths()
this._setMetrics() this._setMetrics()
addEventListener('resize', this._setMetrics)
}, },
methods: { methods: {
_setMetrics: function () { _setMetrics: function () {
this.width = this.$refs.panel.clientWidth this.width = this.$refs.panel.clientWidth
// for (let i = 0; i < this.numMonths; i++) { this.spendPath = ''
// this.displayedMonths[i].metrics.x = (this.width / this.numMonths) this.projectedPath = ''
// }
let lastSpend = 0
let lastSpendPoint = ''
for (let i = 0; i < this.numMonths; i++) {
const { metrics, budget } = this.displayedMonths[i]
const blockWidth = (this.width / this.numMonths)
const blockX = blockWidth * i
const spend = budget
? budget.spend || lastSpend
: 0
const cumulative = budget
? budget.cumulative || budget.projected
: 0
const barHeight = spend / this.heightScale
lastSpend = spend
const cumulativeY = this.height - (cumulative / this.heightScale) - BOTTOM_OFFSET
const cumulativeX = blockX + blockWidth/2
const cumulativePoint = `${cumulativeX} ${cumulativeY}`
this.displayedMonths[i].metrics = Object.assign(metrics, {
blockWidth,
blockX,
barHeight,
barWidth: 30,
barX: blockX + (blockWidth/2 - 15),
barY: this.height - barHeight - BOTTOM_OFFSET,
cumulativeR: 2.5,
cumulativeY,
cumulativeX
})
if (budget && budget.spend) {
this.spendPath += this.spendPath === '' ? 'M' : ' L'
this.spendPath += cumulativePoint
lastSpendPoint = cumulativePoint
}
if (budget && budget.projected) {
this.projectedPath += this.projectedPath === '' ? `M${lastSpendPoint} L` : ' L'
this.projectedPath += cumulativePoint
}
}
}, },
_setDisplayedMonths: function () { _setDisplayedMonths: function () {
@ -43,22 +94,43 @@ export default {
const monthsForward = this.numMonths - this.focusedMonthPosition - 1 const monthsForward = this.numMonths - this.focusedMonthPosition - 1
const start = new Date(year, month - 1 - monthsBack) const start = new Date(year, month - 1 - monthsBack)
let previousAmount = 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 = new Date(start.getFullYear(), start.getMonth() + i)
const index = format(date, 'MM/YYYY') const index = format(date, 'MM/YYYY')
const budget = this.months[index] || null
const spendAmount = budget ? budget.spend || previousAmount : 0
const cumulativeAmount = budget ? budget.cumulative || budget.projected : 0
previousAmount = spendAmount
monthsRange.push({ monthsRange.push({
budget,
spendAmount: formatDollars(spendAmount),
abbreviatedSpend: abbreviateDollars(spendAmount),
cumulativeAmount: formatDollars(cumulativeAmount),
abbreviatedCumulative: abbreviateDollars(cumulativeAmount),
date: { date: {
monthIndex: format(date, 'M'),
month: format(date, 'MMM'), month: format(date, 'MMM'),
year: format(date,'YYYY') year: format(date,'YYYY')
}, },
budget: this.months[index] || null,
isHighlighted: this.currentMonth === index, isHighlighted: this.currentMonth === index,
metrics: { metrics: {
x: 0, blockWidth: 0,
width: 0 blockX: 0,
barHeight: 0,
barWidth: 0,
barX: 0,
barY: 0,
cumulativeY: 0,
cumulativeX: 0,
cumulativeR: 0
} }
}) })
} }
console.log(monthsRange)
this.displayedMonths = monthsRange this.displayedMonths = monthsRange
} }
} }