Merge pull request #303 from dod-ccpo/to-expiration-projection
Task order expiration projection
This commit is contained in:
commit
6dba46af66
@ -4,151 +4,141 @@ from itertools import groupby
|
||||
MONTHLY_SPEND_AARDVARK = {
|
||||
"LC04": {
|
||||
"Integ": {
|
||||
"10/2018": 284,
|
||||
"11/2018": 1210,
|
||||
"12/2018": 1430,
|
||||
"01/2019": 1366,
|
||||
"02/2019": 1169,
|
||||
"03/2019": 991,
|
||||
"04/2019": 978,
|
||||
"05/2019": 737,
|
||||
"02/2018": 284,
|
||||
"03/2018": 1210,
|
||||
"04/2018": 1430,
|
||||
"05/2018": 1366,
|
||||
"06/2018": 1169,
|
||||
"07/2018": 991,
|
||||
"08/2018": 978,
|
||||
"09/2018": 737,
|
||||
},
|
||||
"PreProd": {
|
||||
"10/2018": 812,
|
||||
"11/2018": 1389,
|
||||
"12/2018": 1425,
|
||||
"01/2019": 1306,
|
||||
"02/2019": 1112,
|
||||
"03/2019": 936,
|
||||
"04/2019": 921,
|
||||
"05/2019": 694,
|
||||
"02/2018": 812,
|
||||
"03/2018": 1389,
|
||||
"04/2018": 1425,
|
||||
"05/2018": 1306,
|
||||
"06/2018": 1112,
|
||||
"07/2018": 936,
|
||||
"08/2018": 921,
|
||||
"09/2018": 694,
|
||||
},
|
||||
"Prod": {
|
||||
"10/2018": 1742,
|
||||
"11/2018": 1716,
|
||||
"12/2018": 1866,
|
||||
"01/2019": 1809,
|
||||
"02/2019": 1839,
|
||||
"03/2019": 1633,
|
||||
"04/2019": 1654,
|
||||
"05/2019": 1103,
|
||||
"02/2018": 1742,
|
||||
"03/2018": 1716,
|
||||
"04/2018": 1866,
|
||||
"05/2018": 1809,
|
||||
"06/2018": 1839,
|
||||
"07/2018": 1633,
|
||||
"08/2018": 1654,
|
||||
"09/2018": 1103,
|
||||
},
|
||||
},
|
||||
"SF18": {
|
||||
"Integ": {
|
||||
"12/2018": 1498,
|
||||
"01/2019": 1400,
|
||||
"02/2019": 1394,
|
||||
"03/2019": 1171,
|
||||
"04/2019": 1200,
|
||||
"05/2019": 963,
|
||||
"04/2018": 1498,
|
||||
"05/2018": 1400,
|
||||
"06/2018": 1394,
|
||||
"07/2018": 1171,
|
||||
"08/2018": 1200,
|
||||
"09/2018": 963,
|
||||
},
|
||||
"PreProd": {
|
||||
"12/2018": 1780,
|
||||
"01/2019": 1667,
|
||||
"02/2019": 1703,
|
||||
"03/2019": 1474,
|
||||
"04/2019": 1441,
|
||||
"05/2019": 933,
|
||||
"04/2018": 1780,
|
||||
"05/2018": 1667,
|
||||
"06/2018": 1703,
|
||||
"07/2018": 1474,
|
||||
"08/2018": 1441,
|
||||
"09/2018": 933,
|
||||
},
|
||||
"Prod": {
|
||||
"12/2018": 1686,
|
||||
"01/2019": 1779,
|
||||
"02/2019": 1792,
|
||||
"03/2019": 1570,
|
||||
"04/2019": 1539,
|
||||
"05/2019": 986,
|
||||
"04/2018": 1686,
|
||||
"05/2018": 1779,
|
||||
"06/2018": 1792,
|
||||
"07/2018": 1570,
|
||||
"08/2018": 1539,
|
||||
"09/2018": 986,
|
||||
},
|
||||
},
|
||||
"Canton": {
|
||||
"Prod": {
|
||||
"01/2019": 28699,
|
||||
"02/2019": 26766,
|
||||
"03/2019": 22619,
|
||||
"04/2019": 24090,
|
||||
"05/2019": 16719,
|
||||
"05/2018": 28699,
|
||||
"06/2018": 26766,
|
||||
"07/2018": 22619,
|
||||
"08/2018": 24090,
|
||||
"09/2018": 16719,
|
||||
}
|
||||
},
|
||||
"BD04": {
|
||||
"Integ": {},
|
||||
"PreProd": {
|
||||
"10/2018": 7019,
|
||||
"11/2018": 3004,
|
||||
"12/2018": 2691,
|
||||
"01/2019": 2901,
|
||||
"02/2019": 3463,
|
||||
"03/2019": 3314,
|
||||
"04/2019": 3432,
|
||||
"05/2019": 723,
|
||||
"02/2018": 7019,
|
||||
"03/2018": 3004,
|
||||
"04/2018": 2691,
|
||||
"05/2018": 2901,
|
||||
"06/2018": 3463,
|
||||
"07/2018": 3314,
|
||||
"08/2018": 3432,
|
||||
"09/2018": 723,
|
||||
},
|
||||
},
|
||||
"SCV18": {"Dev": {"05/2019": 9797}},
|
||||
"Crown": {
|
||||
"CR Portal Dev": {
|
||||
"11/2018": 208,
|
||||
"12/2018": 457,
|
||||
"01/2019": 671,
|
||||
"02/2019": 136,
|
||||
"03/2019": 1524,
|
||||
"04/2019": 2077,
|
||||
"05/2019": 1858,
|
||||
"03/2018": 208,
|
||||
"04/2018": 457,
|
||||
"05/2018": 671,
|
||||
"06/2018": 136,
|
||||
"07/2018": 1524,
|
||||
"08/2018": 2077,
|
||||
"09/2018": 1858,
|
||||
},
|
||||
"CR Staging": {
|
||||
"11/2018": 208,
|
||||
"12/2018": 457,
|
||||
"01/2019": 671,
|
||||
"02/2019": 136,
|
||||
"03/2019": 1524,
|
||||
"04/2019": 2077,
|
||||
"05/2019": 1858,
|
||||
"03/2018": 208,
|
||||
"04/2018": 457,
|
||||
"05/2018": 671,
|
||||
"06/2018": 136,
|
||||
"07/2018": 1524,
|
||||
"08/2018": 2077,
|
||||
"09/2018": 1858,
|
||||
},
|
||||
"CR Portal Test 1": {"03/2019": 806, "04/2019": 1966, "05/2019": 2597},
|
||||
"Jewels Prod": {"03/2019": 806, "04/2019": 1966, "05/2019": 2597},
|
||||
"CR Portal Test 1": {"07/2018": 806, "08/2018": 1966, "09/2018": 2597},
|
||||
"Jewels Prod": {"07/2018": 806, "08/2018": 1966, "09/2018": 2597},
|
||||
"Jewels Dev": {
|
||||
"11/2018": 145,
|
||||
"12/2018": 719,
|
||||
"01/2019": 1243,
|
||||
"02/2019": 2214,
|
||||
"03/2019": 2959,
|
||||
"04/2019": 4151,
|
||||
"05/2019": 4260,
|
||||
"03/2018": 145,
|
||||
"04/2018": 719,
|
||||
"05/2018": 1243,
|
||||
"06/2018": 2214,
|
||||
"07/2018": 2959,
|
||||
"08/2018": 4151,
|
||||
"09/2018": 4260,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
CUMULATIVE_BUDGET_AARDVARK = {
|
||||
"10/2018": {"spend": 9857, "cumulative": 9857},
|
||||
"11/2018": {"spend": 7881, "cumulative": 17738},
|
||||
"12/2018": {"spend": 14010, "cumulative": 31748},
|
||||
"01/2019": {"spend": 43510, "cumulative": 75259},
|
||||
"02/2019": {"spend": 41725, "cumulative": 116984},
|
||||
"03/2019": {"spend": 41328, "cumulative": 158312},
|
||||
"04/2019": {"spend": 47491, "cumulative": 205803},
|
||||
"05/2019": {"spend": 45826, "cumulative": 251629},
|
||||
"06/2019": {"projected": 296511},
|
||||
"07/2019": {"projected": 341393},
|
||||
"08/2019": {"projected": 386274},
|
||||
"09/2019": {"projected": 431156},
|
||||
"02/2018": {"spend": 9857, "cumulative": 9857},
|
||||
"03/2018": {"spend": 7881, "cumulative": 17738},
|
||||
"04/2018": {"spend": 14010, "cumulative": 31748},
|
||||
"05/2018": {"spend": 43510, "cumulative": 75259},
|
||||
"06/2018": {"spend": 41725, "cumulative": 116984},
|
||||
"07/2018": {"spend": 41328, "cumulative": 158312},
|
||||
"08/2018": {"spend": 47491, "cumulative": 205803},
|
||||
"09/2018": {"spend": 45826, "cumulative": 251629},
|
||||
}
|
||||
|
||||
MONTHLY_SPEND_BELUGA = {
|
||||
"NP02": {
|
||||
"Integ": {"02/2019": 284, "03/2019": 1210},
|
||||
"PreProd": {"02/2019": 812, "03/2019": 1389},
|
||||
"Prod": {"02/2019": 3742, "03/2019": 4716},
|
||||
"Integ": {"08/2018": 284, "09/2018": 1210},
|
||||
"PreProd": {"08/2018": 812, "09/2018": 1389},
|
||||
"Prod": {"08/2018": 3742, "09/2018": 4716},
|
||||
},
|
||||
"FM": {"Integ": {"03/2019": 1498}, "Prod": {"03/2019": 5686}},
|
||||
"FM": {"Integ": {"08/2018": 1498}, "Prod": {"09/2018": 5686}},
|
||||
}
|
||||
|
||||
CUMULATIVE_BUDGET_BELUGA = {
|
||||
"02/2019": {"spend": 4838, "cumulative": 4838},
|
||||
"03/2019": {"spend": 14500, "cumulative": 19338},
|
||||
"04/2019": {"projected": 29007},
|
||||
"05/2019": {"projected": 38676},
|
||||
"06/2019": {"projected": 48345},
|
||||
"07/2019": {"projected": 58014},
|
||||
"08/2019": {"projected": 67683},
|
||||
"09/2019": {"projected": 77352},
|
||||
"08/2018": {"spend": 4838, "cumulative": 4838},
|
||||
"09/2018": {"spend": 14500, "cumulative": 19338},
|
||||
}
|
||||
|
||||
|
||||
|
@ -106,6 +106,11 @@ def workspace_reports(workspace_id):
|
||||
prev_month = current_month - timedelta(days=28)
|
||||
two_months_ago = prev_month - timedelta(days=28)
|
||||
|
||||
# lets just say it expires on Christmas... ho ho ho
|
||||
expiration_date = date(2018, 12, 25)
|
||||
remaining_difference = expiration_date - today
|
||||
remaining_days = remaining_difference.days
|
||||
|
||||
return render_template(
|
||||
"workspaces/reports/index.html",
|
||||
cumulative_budget=Reports.cumulative_budget(alternate_reports),
|
||||
@ -114,6 +119,8 @@ def workspace_reports(workspace_id):
|
||||
current_month=current_month,
|
||||
prev_month=prev_month,
|
||||
two_months_ago=two_months_ago,
|
||||
expiration_date=expiration_date,
|
||||
remaining_days=remaining_days,
|
||||
)
|
||||
|
||||
|
||||
|
@ -1,14 +1,15 @@
|
||||
import { format } from 'date-fns'
|
||||
import { format, isWithinRange, addMonths, isSameMonth, getMonth } from 'date-fns'
|
||||
import { abbreviateDollars, formatDollars } from '../../lib/dollars'
|
||||
|
||||
const TOP_OFFSET = 20
|
||||
const BOTTOM_OFFSET = 60
|
||||
const BOTTOM_OFFSET = 70
|
||||
const CHART_HEIGHT = 360
|
||||
|
||||
export default {
|
||||
name: 'budget-chart',
|
||||
props: {
|
||||
currentMonth: String,
|
||||
expirationDate: String,
|
||||
months: Object,
|
||||
budget: String
|
||||
},
|
||||
@ -46,18 +47,15 @@ export default {
|
||||
let lastSpendPoint = ''
|
||||
|
||||
for (let i = 0; i < this.numMonths; i++) {
|
||||
const { metrics, budget } = this.displayedMonths[i]
|
||||
const { metrics, budget, rollingAverage, cumulativeTotal } = 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 spend = budget && budget.spend
|
||||
? budget.spend
|
||||
: rollingAverage
|
||||
const barHeight = spend / this.heightScale
|
||||
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 cumulativePoint = `${cumulativeX} ${cumulativeY}`
|
||||
|
||||
@ -77,9 +75,7 @@ export default {
|
||||
this.spendPath += this.spendPath === '' ? 'M' : ' L'
|
||||
this.spendPath += cumulativePoint
|
||||
lastSpendPoint = cumulativePoint
|
||||
}
|
||||
|
||||
if (budget && budget.projected) {
|
||||
} else {
|
||||
this.projectedPath += this.projectedPath === '' ? `M${lastSpendPoint} L` : ' L'
|
||||
this.projectedPath += cumulativePoint
|
||||
}
|
||||
@ -88,32 +84,76 @@ export default {
|
||||
|
||||
_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
|
||||
const monthsBack = 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++) {
|
||||
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 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 || previousAmount : 0
|
||||
const cumulativeAmount = budget ? budget.cumulative || budget.projected : 0
|
||||
previousAmount = spendAmount
|
||||
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(cumulativeAmount),
|
||||
abbreviatedCumulative: abbreviateDollars(cumulativeAmount),
|
||||
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,
|
||||
|
@ -60,21 +60,39 @@
|
||||
}
|
||||
|
||||
.budget-chart__block {
|
||||
fill: $color-white;
|
||||
fill: transparent;
|
||||
cursor: pointer;
|
||||
|
||||
&--highlighted {
|
||||
fill: $color-aqua-lightest;
|
||||
fill: rgba($color-aqua, .15);
|
||||
}
|
||||
|
||||
&--is-expiration {
|
||||
border-left: 2px dotted $color-gray;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
fill: $color-aqua-lightest;
|
||||
fill: rgba($color-aqua, .15);
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -82,6 +100,15 @@
|
||||
stroke: $color-gray-light;
|
||||
stroke-dasharray: 2px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.filter__text-background {
|
||||
feFlood {
|
||||
flood-color: $color-aqua-lightest;
|
||||
flood-opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,6 +123,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.budget-chart__expiration-line {
|
||||
stroke-width: 2px;
|
||||
stroke: $color-gray-light;
|
||||
stroke-dasharray: 4px;
|
||||
}
|
||||
|
||||
.budget-chart__cumulative__dot {
|
||||
fill: $color-gold;
|
||||
}
|
||||
@ -122,6 +155,7 @@
|
||||
.budget-chart__label {
|
||||
@include small-label;
|
||||
fill: $color-gray;
|
||||
pointer-events: none;
|
||||
|
||||
&--strong {
|
||||
fill: $color-black;
|
||||
|
@ -63,12 +63,17 @@
|
||||
<dl>
|
||||
<div>
|
||||
<dt>Expires</dt>
|
||||
<dd>November 1, 2019</dd>
|
||||
<dd>
|
||||
<local-datetime
|
||||
timestamp='{{ expiration_date }}'
|
||||
format='MMMM D, YYYY'>
|
||||
</local-datetime>
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<dt>Remaining</dt>
|
||||
<dd>200 days</dd>
|
||||
<dd>{{ remaining_days }} days</dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
@ -97,7 +102,12 @@
|
||||
{% set two_months_ago_index = two_months_ago.strftime('%m/%Y') %}
|
||||
{% set reports_url = url_for("workspaces.workspace_reports", workspace_id=workspace.id) %}
|
||||
|
||||
<budget-chart budget={{ budget }} current-month='{{ current_month_index }}' v-bind:months='{{ cumulative_budget.months | tojson }}' inline-template>
|
||||
<budget-chart
|
||||
budget={{ budget }}
|
||||
current-month='{{ current_month_index }}'
|
||||
expiration-date='{{ expiration_date }}'
|
||||
v-bind:months='{{ cumulative_budget.months | tojson }}'
|
||||
inline-template>
|
||||
<div class='budget-chart panel' ref='panel'>
|
||||
<header class='budget-chart__header panel__heading panel__heading--tight'>
|
||||
<h2 class='h3'>Cumulative Budget</h2>
|
||||
@ -127,18 +137,54 @@
|
||||
</header>
|
||||
|
||||
<svg v-bind:height='height' v-bind:width='width'>
|
||||
|
||||
<defs>
|
||||
<filter x="-0.04" y="0" width="1.08" height="1" class='filter__text-background' id="text-background">
|
||||
<feFlood/>
|
||||
<feComposite in="SourceGraphic"/>
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
{# spend/projected budget path lines #}
|
||||
<path class='budget-chart__projected-path' v-bind:d='projectedPath'></path>
|
||||
<path class='budget-chart__spend-path' v-bind:d='spendPath'></path>
|
||||
|
||||
{# max budget line #}
|
||||
<line
|
||||
class='budget-chart__budget-line'
|
||||
x1='0'
|
||||
v-bind:x2='width'
|
||||
v-bind:y1='budgetHeight'
|
||||
v-bind:y2='budgetHeight'></line>
|
||||
|
||||
<g v-for='month in displayedMonths' >
|
||||
|
||||
{# make this clickable to focus on that month #}
|
||||
<a v-bind:href='"{{ reports_url }}?month=" + month.date.monthIndex + "&year=" + month.date.year'>
|
||||
|
||||
<defs>
|
||||
<filter
|
||||
x="-0.04"
|
||||
y="0"
|
||||
width="1.08"
|
||||
height="1"
|
||||
class='filter__text-background'
|
||||
v-bind:class='{ "filter__text-background--highlighted": month.isHighlighted }'
|
||||
v-bind:id="'text-background__' +month.date.month + month.date.year">
|
||||
<feFlood/>
|
||||
<feComposite in="SourceGraphic"/>
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
<title>
|
||||
<span v-html='month.date.month + " " + month.date.year'></span> | <!--
|
||||
--><template v-if='month.budget'><!--
|
||||
--><template v-if='month.budget.spend'>Spend:</template><!--
|
||||
--><template v-if='month.budget.projected'>Projected Spend:</template><!--
|
||||
--><template v-if='month.cumulativeTotal'><!--
|
||||
--><template v-if='month.budget && month.budget.spend'>Spend:</template><!--
|
||||
--><template v-else>Projected Spend:</template><!--
|
||||
--><span v-html='month.spendAmount'></span><!--
|
||||
--> | <!--
|
||||
--><template v-if='month.budget.cumulative'>Total:</template><!--
|
||||
--><template v-if='month.budget.projected'>Projected Total:</template><!--
|
||||
--><template v-if='month.budget'>Total:</template><!--
|
||||
--><template v-else>Projected Total:</template><!--
|
||||
--><span v-html='month.cumulativeAmount'></span><!--
|
||||
--></template><!--
|
||||
|
||||
@ -148,7 +194,7 @@
|
||||
{# container block #}
|
||||
<rect
|
||||
class='budget-chart__block'
|
||||
v-bind:class='{ "budget-chart__block--highlighted": month.isHighlighted }'
|
||||
v-bind:class='{ "budget-chart__block--highlighted": month.isHighlighted, "budget-chart__block-is-expiration": month.isExpirationMonth }'
|
||||
v-bind:width='month.metrics.blockWidth'
|
||||
v-bind:x='month.metrics.blockX'
|
||||
v-bind:height='height'></rect>
|
||||
@ -163,9 +209,36 @@
|
||||
v-bind:x='month.metrics.barX'
|
||||
v-bind:y='month.metrics.barY'></rect>
|
||||
|
||||
{# projected budget bar #}
|
||||
<rect
|
||||
v-if='!month.budget'
|
||||
class='budget-chart__bar budget-chart__bar--projected'
|
||||
v-bind:width='month.metrics.barWidth'
|
||||
v-bind:height='month.metrics.barHeight'
|
||||
v-bind:x='month.metrics.barX'
|
||||
v-bind:y='month.metrics.barY'></rect>
|
||||
|
||||
{# task order expiration line #}
|
||||
<line
|
||||
v-if='month.isExpirationMonth'
|
||||
class='budget-chart__expiration-line'
|
||||
v-bind:x1='month.metrics.cumulativeX'
|
||||
v-bind:x2='month.metrics.cumulativeX'
|
||||
y1='0'
|
||||
v-bind:y2='baseHeight'></line>
|
||||
|
||||
{# task order expiration label #}
|
||||
<text
|
||||
v-bind:filter="'url(#text-background__' + month.date.month + month.date.year + ')'"
|
||||
v-if='month.isExpirationMonth'
|
||||
text-anchor='middle'
|
||||
v-bind:x='month.metrics.cumulativeX'
|
||||
v-bind:y='budgetHeight + 20'
|
||||
class='budget-chart__label'>T.O. Expires</text>
|
||||
|
||||
{# cumulative dot #}
|
||||
<circle
|
||||
v-if='month.budget'
|
||||
v-if='month.cumulativeTotal'
|
||||
class='budget-chart__cumulative__dot'
|
||||
v-bind:r='month.metrics.cumulativeR'
|
||||
v-bind:cx='month.metrics.cumulativeX'
|
||||
@ -173,7 +246,8 @@
|
||||
|
||||
{# abbreviated cumulative label #}
|
||||
<text
|
||||
v-if='month.budget'
|
||||
v-bind:filter="'url(#text-background__' + month.date.month + month.date.year + ')'"
|
||||
v-if='month.cumulativeTotal'
|
||||
v-bind:x='month.metrics.cumulativeX'
|
||||
v-bind:y='month.metrics.cumulativeY - 10'
|
||||
text-anchor='middle'
|
||||
@ -182,6 +256,7 @@
|
||||
|
||||
{# abbreviated spend label #}
|
||||
<text
|
||||
v-bind:filter="'url(#text-background__' + month.date.month + month.date.year + ')'"
|
||||
v-bind:x='month.metrics.cumulativeX'
|
||||
v-bind:y='baseHeight + 20'
|
||||
text-anchor='middle'
|
||||
@ -190,26 +265,25 @@
|
||||
|
||||
{# month label #}
|
||||
<text
|
||||
v-bind:filter="'url(#text-background__' + month.date.month + month.date.year + ')'"
|
||||
v-bind:x='month.metrics.cumulativeX'
|
||||
v-bind:y='baseHeight + 40'
|
||||
text-anchor='middle'
|
||||
class='budget-chart__label budget-chart__label--strong'
|
||||
v-html='month.date.month'></text>
|
||||
|
||||
{# year label #}
|
||||
<text
|
||||
v-bind:filter="'url(#text-background__' + month.date.month + month.date.year + ')'"
|
||||
v-if='month.showYear'
|
||||
v-bind:x='month.metrics.cumulativeX'
|
||||
v-bind:y='baseHeight + 55'
|
||||
text-anchor='middle'
|
||||
class='budget-chart__label budget-chart__label--strong'
|
||||
v-html='month.date.year'></text>
|
||||
</g>
|
||||
</a>
|
||||
|
||||
{# spend/projected budget path lines #}
|
||||
<path class='budget-chart__projected-path' v-bind:d='projectedPath'></path>
|
||||
<path class='budget-chart__spend-path' v-bind:d='spendPath'></path>
|
||||
|
||||
{# max budget line #}
|
||||
<line
|
||||
class='budget-chart__budget-line'
|
||||
x1='0'
|
||||
v-bind:x2='width'
|
||||
v-bind:y1='budgetHeight'
|
||||
v-bind:y2='budgetHeight'></line>
|
||||
|
||||
<text
|
||||
x='20'
|
||||
v-bind:y='budgetHeight + 20'
|
||||
|
Loading…
x
Reference in New Issue
Block a user