Added color scale support to main page indicators
This commit is contained in:
parent
fdd6fc3d72
commit
74928aee46
1 changed files with 62 additions and 13 deletions
|
@ -39,7 +39,7 @@
|
||||||
<strong>{{ m.title }}</strong>
|
<strong>{{ m.title }}</strong>
|
||||||
<span class="text-right">{{ m.value(company) }}{{ m.symbol ?? '' }}</span>
|
<span class="text-right">{{ m.value(company) }}{{ m.symbol ?? '' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<v-progress-linear :color="m.color" :model-value="m.percentage(company)"></v-progress-linear>
|
<v-progress-linear :color="m.color(company)" :model-value="m.percentage(company)"></v-progress-linear>
|
||||||
</div>
|
</div>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
|
|
||||||
|
@ -134,52 +134,101 @@ const setSearch = (text: string) => searchText.value = text;
|
||||||
|
|
||||||
watch(filteredCompanies, () => loading.value = false);
|
watch(filteredCompanies, () => loading.value = false);
|
||||||
|
|
||||||
|
type ColorScale = { gt?: number, color: string }[];
|
||||||
|
|
||||||
interface Metric {
|
interface Metric {
|
||||||
title: string,
|
title: string,
|
||||||
color: string,
|
|
||||||
minValue: number,
|
minValue: number,
|
||||||
maxValue: number,
|
maxValue: number,
|
||||||
value: (c: Company) => number // in [0, 100],
|
value: (c: Company) => number // in [0, 100],
|
||||||
symbol?: string,
|
symbol?: string,
|
||||||
decimals?: number
|
decimals?: number
|
||||||
|
scale: ColorScale
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// COLORS from Pietro:
|
||||||
|
// Valuation: < 1 ( GREEN); > 1 (RED); = 1 (ORANGE)
|
||||||
|
// Financial Health: < 1 (GREEN); > 1 (RED); = 1 (ORANGE)
|
||||||
|
// Growth: < 0 (RED); 0 < x < 8% (ORANGE); < 8 % (GREEN)
|
||||||
|
// Past performance: -100 < x < 0 (RED); = 0 (ORANGE); 0 < x < 100 (GREEN)
|
||||||
|
|
||||||
|
const COLORS = {
|
||||||
|
good: 'success',
|
||||||
|
warning: 'warning',
|
||||||
|
bad: 'error'
|
||||||
|
};
|
||||||
|
|
||||||
const metricsData = reactive<Metric[]>([
|
const metricsData = reactive<Metric[]>([
|
||||||
{
|
{
|
||||||
title: 'Valuation',
|
title: 'Valuation',
|
||||||
color: 'secondary',
|
|
||||||
minValue: 0,
|
minValue: 0,
|
||||||
maxValue: 150,
|
maxValue: 150,
|
||||||
value: c => c['Valuation']
|
value: c => c['Valuation'],
|
||||||
|
scale: [
|
||||||
|
{ gt: 1.1, color: COLORS.bad },
|
||||||
|
{ gt: 0.9, color: COLORS.warning },
|
||||||
|
{ color: COLORS.good }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Financial Health',
|
title: 'Financial Health',
|
||||||
color: 'secondary',
|
|
||||||
minValue: 0,
|
minValue: 0,
|
||||||
maxValue: 500,
|
maxValue: 500,
|
||||||
value: c => c['Financial Health']
|
value: c => c['Financial Health'],
|
||||||
|
scale: [
|
||||||
|
{ gt: 1.1, color: COLORS.bad },
|
||||||
|
{ gt: 0.9, color: COLORS.warning },
|
||||||
|
{ color: COLORS.good }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Estimated Growth',
|
title: 'Estimated Growth',
|
||||||
color: 'secondary',
|
|
||||||
minValue: 0,
|
minValue: 0,
|
||||||
maxValue: 200,
|
maxValue: 200,
|
||||||
value: c => c['Estimated Growth'],
|
value: c => c['Estimated Growth'],
|
||||||
symbol: ' %'
|
symbol: ' %',
|
||||||
|
scale: [
|
||||||
|
{ gt: 8, color: COLORS.good },
|
||||||
|
{ gt: 0, color: COLORS.warning },
|
||||||
|
{ color: COLORS.bad }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Past Performance',
|
title: 'Past Performance',
|
||||||
color: 'secondary',
|
minValue: -100,
|
||||||
minValue: 0,
|
|
||||||
maxValue: 200,
|
maxValue: 200,
|
||||||
value: c => c['Past Performance']
|
value: c => c['Past Performance'],
|
||||||
|
symbol: ' %',
|
||||||
|
scale: [
|
||||||
|
{ gt: 5, color: COLORS.good },
|
||||||
|
{ gt: -5, color: COLORS.warning },
|
||||||
|
{ gt: -Infinity, color: COLORS.bad }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const metrics = computed<(Metric & { percentage: (c: Company) => number })[]>(() => metricsData.map(e => ({
|
type ExtendedMetric = Metric & {
|
||||||
|
percentage: (c: Company) => number,
|
||||||
|
color: (c: Company) => string
|
||||||
|
}
|
||||||
|
|
||||||
|
const metrics = computed<ExtendedMetric[]>(() => metricsData.map(e => ({
|
||||||
...e,
|
...e,
|
||||||
percentage: (c: Company) => (e.value(c) - e.minValue) * 100 / (e.maxValue - e.minValue),
|
percentage: (c: Company) => (e.value(c) - e.minValue) * 100 / (e.maxValue - e.minValue),
|
||||||
value: (c: Company) => roundTo(e.value(c), e.decimals ?? 2)
|
value: (c: Company) => roundTo(e.value(c), e.decimals ?? 2),
|
||||||
|
color: (c: Company) => {
|
||||||
|
console.log(JSON.parse(JSON.stringify(e.scale)));
|
||||||
|
const value = e.value(c);
|
||||||
|
console.log(c.ticker, value);
|
||||||
|
for (const s of e.scale) {
|
||||||
|
console.log('checking', s.gt, s.color);
|
||||||
|
if (typeof s.gt !== 'number' || value > s.gt) {
|
||||||
|
console.log(s.gt, s.color);
|
||||||
|
return s.color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'blue-grey' // default value, should never be displayed
|
||||||
|
}
|
||||||
})));
|
})));
|
||||||
|
|
||||||
getCompanies().then(cs => {
|
getCompanies().then(cs => {
|
||||||
|
|
Reference in a new issue