From 74928aee46080b74d422e9b1269aaece175a113f Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Fri, 19 May 2023 19:53:13 +0200 Subject: [PATCH] Added color scale support to main page indicators --- stockingly-frontend/src/views/Home.vue | 75 +++++++++++++++++++++----- 1 file changed, 62 insertions(+), 13 deletions(-) diff --git a/stockingly-frontend/src/views/Home.vue b/stockingly-frontend/src/views/Home.vue index 97dd4f4..193ce57 100644 --- a/stockingly-frontend/src/views/Home.vue +++ b/stockingly-frontend/src/views/Home.vue @@ -39,7 +39,7 @@ {{ m.title }} {{ m.value(company) }}{{ m.symbol ?? '' }} - + @@ -134,52 +134,101 @@ const setSearch = (text: string) => searchText.value = text; watch(filteredCompanies, () => loading.value = false); +type ColorScale = { gt?: number, color: string }[]; + interface Metric { title: string, - color: string, minValue: number, maxValue: number, value: (c: Company) => number // in [0, 100], symbol?: string, 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([ { title: 'Valuation', - color: 'secondary', minValue: 0, 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', - color: 'secondary', minValue: 0, 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', - color: 'secondary', minValue: 0, maxValue: 200, value: c => c['Estimated Growth'], - symbol: ' %' + symbol: ' %', + scale: [ + { gt: 8, color: COLORS.good }, + { gt: 0, color: COLORS.warning }, + { color: COLORS.bad } + ] }, { title: 'Past Performance', - color: 'secondary', - minValue: 0, + minValue: -100, 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(() => metricsData.map(e => ({ ...e, 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 => {