Remove budget chart
This commit is contained in:
parent
06600a8237
commit
e685b32193
@ -1,189 +0,0 @@
|
|||||||
import {
|
|
||||||
format,
|
|
||||||
isWithinRange,
|
|
||||||
addMonths,
|
|
||||||
isSameMonth,
|
|
||||||
getMonth,
|
|
||||||
} from 'date-fns'
|
|
||||||
import { abbreviateDollars, formatDollars } from '../../lib/dollars'
|
|
||||||
|
|
||||||
const TOP_OFFSET = 20
|
|
||||||
const BOTTOM_OFFSET = 70
|
|
||||||
const CHART_HEIGHT = 360
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'budget-chart',
|
|
||||||
props: {
|
|
||||||
currentMonth: String,
|
|
||||||
expirationDate: String,
|
|
||||||
months: Object,
|
|
||||||
budget: String,
|
|
||||||
},
|
|
||||||
|
|
||||||
data: function() {
|
|
||||||
const heightScale =
|
|
||||||
this.budget / (CHART_HEIGHT - TOP_OFFSET - BOTTOM_OFFSET)
|
|
||||||
return {
|
|
||||||
numMonths: 10,
|
|
||||||
focusedMonthPosition: 4,
|
|
||||||
height: CHART_HEIGHT,
|
|
||||||
heightScale,
|
|
||||||
budgetHeight: CHART_HEIGHT - BOTTOM_OFFSET - this.budget / heightScale,
|
|
||||||
baseHeight: CHART_HEIGHT - BOTTOM_OFFSET,
|
|
||||||
width: 0,
|
|
||||||
displayedMonths: [],
|
|
||||||
spendPath: '',
|
|
||||||
projectedPath: '',
|
|
||||||
displayBudget: formatDollars(parseFloat(this.budget)),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted: function() {
|
|
||||||
this._setDisplayedMonths()
|
|
||||||
this._setMetrics()
|
|
||||||
addEventListener('load', this._setMetrics)
|
|
||||||
addEventListener('resize', this._setMetrics)
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
_setMetrics: function() {
|
|
||||||
this.width = this.$refs.panel.clientWidth
|
|
||||||
this.spendPath = ''
|
|
||||||
this.projectedPath = ''
|
|
||||||
|
|
||||||
let lastSpend = 0
|
|
||||||
let lastSpendPoint = ''
|
|
||||||
|
|
||||||
for (let i = 0; i < this.numMonths; i++) {
|
|
||||||
const {
|
|
||||||
metrics,
|
|
||||||
budget,
|
|
||||||
rollingAverage,
|
|
||||||
cumulativeTotal,
|
|
||||||
} = this.displayedMonths[i]
|
|
||||||
const blockWidth = this.width / this.numMonths
|
|
||||||
const blockX = blockWidth * i
|
|
||||||
const spend = budget && budget.spend ? budget.spend : rollingAverage
|
|
||||||
const barHeight = spend / this.heightScale
|
|
||||||
lastSpend = spend
|
|
||||||
const cumulativeY =
|
|
||||||
this.height - cumulativeTotal / 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
|
|
||||||
} else if (lastSpendPoint !== '') {
|
|
||||||
this.projectedPath +=
|
|
||||||
this.projectedPath === '' ? `M${lastSpendPoint} L` : ' L'
|
|
||||||
this.projectedPath += cumulativePoint
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_setDisplayedMonths: function() {
|
|
||||||
const [month, year] = this.currentMonth.split('/')
|
|
||||||
const [expYear, expMonth, expDate] = this.expirationDate.split('-') // assumes format 'YYYY-MM-DD'
|
|
||||||
const monthsRange = []
|
|
||||||
const monthsBack = this.focusedMonthPosition + 1
|
|
||||||
const monthsForward = this.numMonths - this.focusedMonthPosition - 1
|
|
||||||
|
|
||||||
// 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++) {
|
|
||||||
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 indexMinusOne = format(dateMinusOne, 'MM/YYYY')
|
|
||||||
const indexMinusTwo = format(dateMinusTwo, 'MM/YYYY')
|
|
||||||
const indexMinusThree = format(dateMinusThree, 'MM/YYYY')
|
|
||||||
|
|
||||||
const budget = this.months[index] || null
|
|
||||||
const spendAmount = budget ? budget.spend : rollingAverage
|
|
||||||
const spendMinusOne = this.months[indexMinusOne]
|
|
||||||
? this.months[indexMinusOne].spend
|
|
||||||
: rollingAverage
|
|
||||||
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({
|
|
||||||
budget,
|
|
||||||
rollingAverage,
|
|
||||||
cumulativeTotal,
|
|
||||||
isExpirationMonth,
|
|
||||||
spendAmount: formatDollars(spendAmount),
|
|
||||||
abbreviatedSpend: abbreviateDollars(spendAmount),
|
|
||||||
cumulativeAmount: formatDollars(cumulativeTotal),
|
|
||||||
abbreviatedCumulative: abbreviateDollars(cumulativeTotal),
|
|
||||||
date: {
|
|
||||||
monthIndex: format(date, 'M'),
|
|
||||||
month: format(date, 'MMM'),
|
|
||||||
year: format(date, 'YYYY'),
|
|
||||||
},
|
|
||||||
showYear: isExpirationMonth || i === 0 || getMonth(date) === 0,
|
|
||||||
isHighlighted: this.currentMonth === index,
|
|
||||||
metrics: {
|
|
||||||
blockWidth: 0,
|
|
||||||
blockX: 0,
|
|
||||||
barHeight: 0,
|
|
||||||
barWidth: 0,
|
|
||||||
barX: 0,
|
|
||||||
barY: 0,
|
|
||||||
cumulativeY: 0,
|
|
||||||
cumulativeX: 0,
|
|
||||||
cumulativeR: 0,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.displayedMonths = monthsRange
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
@ -17,7 +17,6 @@ import ApplicationEnvironments from './components/forms/new_application/environm
|
|||||||
import MultiStepModalForm from './components/forms/multi_step_modal_form'
|
import MultiStepModalForm from './components/forms/multi_step_modal_form'
|
||||||
import uploadinput from './components/upload_input'
|
import uploadinput from './components/upload_input'
|
||||||
import Modal from './mixins/modal'
|
import Modal from './mixins/modal'
|
||||||
import BudgetChart from './components/charts/budget_chart'
|
|
||||||
import SpendTable from './components/tables/spend_table'
|
import SpendTable from './components/tables/spend_table'
|
||||||
import LocalDatetime from './components/local_datetime'
|
import LocalDatetime from './components/local_datetime'
|
||||||
import { isNotInVerticalViewport } from './lib/viewport'
|
import { isNotInVerticalViewport } from './lib/viewport'
|
||||||
@ -49,7 +48,6 @@ const app = new Vue({
|
|||||||
textinput,
|
textinput,
|
||||||
checkboxinput,
|
checkboxinput,
|
||||||
ApplicationEnvironments,
|
ApplicationEnvironments,
|
||||||
BudgetChart,
|
|
||||||
SpendTable,
|
SpendTable,
|
||||||
LocalDatetime,
|
LocalDatetime,
|
||||||
MultiStepModalForm,
|
MultiStepModalForm,
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
@import "components/progress_menu.scss";
|
@import "components/progress_menu.scss";
|
||||||
@import "components/forms";
|
@import "components/forms";
|
||||||
@import "components/selector";
|
@import "components/selector";
|
||||||
@import "components/budget_chart";
|
|
||||||
@import "components/audit_log";
|
@import "components/audit_log";
|
||||||
@import "components/usa_banner";
|
@import "components/usa_banner";
|
||||||
@import "components/dod_login_notice.scss";
|
@import "components/dod_login_notice.scss";
|
||||||
|
@ -1,169 +0,0 @@
|
|||||||
.budget-chart {
|
|
||||||
svg {
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
.filter__text-background {
|
|
||||||
feFlood {
|
|
||||||
flood-color: $color-white;
|
|
||||||
flood-opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--highlighted {
|
|
||||||
feFlood {
|
|
||||||
flood-color: $color-aqua-lightest;
|
|
||||||
flood-opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
outline: none;
|
|
||||||
stroke: $color-gray-light;
|
|
||||||
stroke-dasharray: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.filter__text-background {
|
|
||||||
feFlood {
|
|
||||||
flood-color: $color-aqua-lightest;
|
|
||||||
flood-opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__header {
|
|
||||||
border-bottom: 1px solid $color-gray-light;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__legend {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
dl {
|
|
||||||
margin: 0 0 0 ($gap * 2);
|
|
||||||
|
|
||||||
> div {
|
|
||||||
margin: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
dt {
|
|
||||||
@include small-label;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__dot {
|
|
||||||
width: $gap;
|
|
||||||
height: $gap;
|
|
||||||
border-radius: $gap / 2;
|
|
||||||
margin: 0 $gap;
|
|
||||||
|
|
||||||
&.accumulated {
|
|
||||||
background-color: $color-gold;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.monthly {
|
|
||||||
background-color: $color-blue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__line {
|
|
||||||
height: 2px;
|
|
||||||
width: $gap * 3;
|
|
||||||
border-top-width: 2px;
|
|
||||||
border-top-style: dashed;
|
|
||||||
margin: $gap;
|
|
||||||
|
|
||||||
&.spend {
|
|
||||||
border-color: $color-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.accumulated {
|
|
||||||
border-color: $color-gold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__block {
|
|
||||||
fill: transparent;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&--highlighted {
|
|
||||||
fill: rgba($color-aqua, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
&--is-expiration {
|
|
||||||
border-left: 2px dotted $color-gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
fill: rgba($color-aqua, 0.15);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__bar {
|
|
||||||
fill: $color-blue;
|
|
||||||
|
|
||||||
&--projected {
|
|
||||||
fill: transparent;
|
|
||||||
stroke-width: 2px;
|
|
||||||
stroke: $color-blue;
|
|
||||||
stroke-dasharray: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__expiration-line {
|
|
||||||
stroke-width: 2px;
|
|
||||||
stroke: $color-gray-light;
|
|
||||||
stroke-dasharray: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__cumulative {
|
|
||||||
&__dot {
|
|
||||||
fill: $color-gold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__projected-path {
|
|
||||||
stroke-width: 1px;
|
|
||||||
stroke: $color-gold;
|
|
||||||
stroke-dasharray: 4px;
|
|
||||||
fill: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__spend-path {
|
|
||||||
stroke-width: 1px;
|
|
||||||
stroke: $color-gold;
|
|
||||||
fill: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__budget-line {
|
|
||||||
stroke-width: 2px;
|
|
||||||
stroke: $color-gray-light;
|
|
||||||
stroke-dasharray: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__label {
|
|
||||||
@include small-label;
|
|
||||||
|
|
||||||
fill: $color-gray;
|
|
||||||
pointer-events: none;
|
|
||||||
|
|
||||||
&--strong {
|
|
||||||
fill: $color-black;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user