#44 Adding Portfolio Plan Percentages And A Little Bit Of Color
Saturday, April 4, 2020
In this article we will start by displaying the components of the selected portfolio plan by showing the percentages that the plan calls for based on category as well as calculating the difference in percentages between the plan percentage and the actual percentages. We will also start to address some usability issues by making it a little bit easier to determing what category a give security belonged to using a dynamically set background color.
Parts
- Part 45: Adjusting Shares
- Part 44: Plan Percentages
- Part 43: Home Securities
- Part 42: Updating Plans
- Part 41: Plan Details View
- Part 40: Portfolio Getters
- Part 39: Portfolio Plan
- Part 38: Portfolio Category
- Part 37: Account Securities
- Part 36: Account Transfer
- Part 35: View Account Security
- Part 34: Updating Deposit
- Part 33: View Account Deposit
- Part 32: Display Account Details
- Part 31: Account Getters
- Part 30: Deposits And Securities
- Part 29: Add Accounts Details
- Part 28: Refactoring Accounts
- Part 27: Add Security Models
- Part 26: Edit Security Details
- Part 25: View Security Details
- Part 24: Navigating To Details
- Part 23: Getters Validation
- Part 22: Query Parameters
- Part 21: Tab Entries
- Part 20: Tab Header
- Part 19: List View
- Part 18: Vuex Getters
- Part 17: End Domain Model
- Part 16: Start Domain Model
- Part 15: Pop Routes
- Part 14: Push Routes
- Part 13: Removing Accounts
- Part 12: Vuex (Decorators)
- Part 11: Vuex (Accounts)
- Part 10: The App Bar (Settings)
- Part 9: Remove Consumer Rxjs
- Part 8: The App Bar (Back)
- Part 7: Structuring Our App
- Part 6: Animation Between Views
- Part 5: Navigation Fade
- Part 4: Navigation Requests
- Part 3: Fade Animations (cont.)
- Part 2: Fade Animations
- Part 1: Splash Screen
Code Snippets
index.ts (1:30)
...
export * from "@/store/functions";
...
Home.vue (1:55)
<script lang="ts">
...
import {
...
sort,
} from "@/store";
...
export default class Home extends Vue {
...
private mounted() {
...
this.selectedPlan.categories.forEach((x) => {
...
groups[x.category.abbreviation] = sort(groups[x.category.abbreviation], (x) => x.security.symbol);
});
...
}
}
</script>
Home.vue (3:16)
<script lang="ts">
...
import {
...
PortfolioCategoryModel,
...
} from "@/store";
...
export default class Home extends Vue {
...
private get totalValue() {
return this.accountSecurities.reduce(
(pre, cur) => pre + cur[1].reduce((pre1, cur1) => pre1 + cur1.value, 0),
0,
);
}
...
private categoryPercent(portfolioCategory: PortfolioCategoryModel) {
return (this.categoryValue(portfolioCategory.category.abbreviation) / this.valueTotal) * 100;
}
private categoryValue(category: string) {
return this.accountSecurities
.filter((x) => x[0] === category)
.map((x) => x[1])
.reduce((pre, cur) => pre + cur.reduce((pre1, cur1) => pre1 + cur1.value, 0), 0);
}
}
</script>
Home.vue (8:07)
<template lang="pug">
div.home
div
select(v-model="selectedPlan")
option(
v-for="plan in plans"
v-bind:key="plan.id"
v-bind:value="plan") {{plan.name}}
div(v-if="selectedPlan")
ul
li.row
label Category
label Plan
label Actual
label Difference
li.row(v-for="portfolioCategory in selectedPlan.categories")
div {{portfolioCategory.category.abbreviation}}
div {{portfolioCategory.percent.toFixed(1)}}
div {{categoryPercent(portfolioCategory).toFixed(1)}}
div {{(categoryPercent(portfolioCategory) - portfolioCategory.percent).toFixed(1)}}
...
</template>
TheRouterOutlet.vue (11:39)
<style lang="sass" scoped>
...
.router-view-animatable
...
overflow: auto
</style>
Home.vue (12:18)
<style lang="sass" scoped>
...
.home
display: grid
@include padding(0.25rem)
height: 100%
grid-template-rows: auto 1fr
.account-securities
overflow: auto
...
</style>
Advertisement
security-category-model.ts (13:58)
...
export interface ISecurityCategoryModelConfig {
color: string;
...
}
export class SecurityCategoryModel {
private _color: string;
...
public get color() {
return this._color;
}
public set color(color: string) {
this._color = color;
}
...
constructor(config: ISecurityCategoryModelConfig) {
this._color = config.color;
...
}
...
public toPersistObj = (): ISecurityCategoryModelConfig => {
return {
color: this._color,
...
};
};
}
security-category-initial-state.ts (14:48)
...
index = createCategory({
color: "#fc8279",
id: index,
segmentId: largeCap.id,
territoryId: domestic.id,
typeId: equity.id,
});
index = createCategory({
color: "#fcb479",
id: index,
segmentId: midCap.id,
territoryId: domestic.id,
typeId: equity.id,
});
index = createCategory({
color: "#fcf579",
id: index,
segmentId: smallCap.id,
territoryId: domestic.id,
typeId: equity.id,
});
index = createCategory({
color: "#c5fc79",
id: index,
segmentId: developed.id,
territoryId: international.id,
typeId: equity.id,
});
index = createCategory({
color: "#79fcd7",
id: index,
segmentId: emerging.id,
territoryId: international.id,
typeId: equity.id,
});
index = createCategory({
color: "#79dbfc",
id: index,
segmentId: developed.id,
territoryId: domestic.id,
typeId: fixedIncome.id,
});
index = createCategory({
color: "#b679fc",
id: index,
segmentId: developed.id,
territoryId: international.id,
typeId: fixedIncome.id,
});
index = createCategory({
color: "#fc79dd",
id: index,
segmentId: developed.id,
territoryId: domestic.id,
typeId: specialty.id,
});
...
Home.vue (15:21)
<template lang="pug">
div.home
div
...
div(v-if="selectedPlan")
ul
li.row
label.color
...
li.row(v-for="portfolioCategory in selectedPlan.categories")
div.color(v-bind:style="{ 'background-color': portfolioCategory.category.color }")
...
...
</template>
Home.vue (16:32)
<style lang="sass" scoped>
...
.color
height: 1.5rem
max-width: 0.75rem
margin-right: 0.25rem
...
</style>
Home.vue (17:14)
<template lang="pug">
div.home
...
ul.account-securities
...
li(
v-for="acctSecurityArray in accountSecurities"
v-bind:key="acctSecurityArray[0]")
ul
li(
v-for="acctSecurity in acctSecurityArray[1]"
v-bind:key="acctSecurity.id"
v-bind:style="{ 'background-color': acctSecurity.security.category.color }")
...
</template>
Exciton Interactive LLC