Merge branch '7-display-company-logo-in-companies-page' into 'master'

Resolve "Display company logo in companies page"

Closes #7

See merge request usi-si-teaching/msde/2022-2023/visual-analytics-atelier/group-projects/group-1!7
This commit is contained in:
Claudio Maggioni 2023-05-15 09:50:24 +00:00
commit 5bf9ac01e4
4 changed files with 37 additions and 15 deletions

1
company_generic.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 96 960 960" width="48"><path d="M80 976V495l280-119v80l200-81v121h320v480H80Zm60-60h680V556.199H500V464l-200 80v-79l-160 71v380Zm310-100h60V656h-60v160Zm-160 0h60V656h-60v160Zm320 0h60V656h-60v160Zm270-320H700l40-320h100l40 320ZM140 916h680-680Z"/></svg>

After

Width:  |  Height:  |  Size: 317 B

View file

@ -13,7 +13,11 @@ export interface Company {
tags: string[]; tags: string[];
ticker: string; ticker: string;
website: string; website: string;
logoSrc: string
} }
export const getCompanies = (): Promise<Company[]> => export const getCompanies = (): Promise<Company[]> =>
fetch(BACKEND_URL + '/companies').then(r => r.json()) fetch(BACKEND_URL + '/companies').then(r => r.json()).then(list => list.map((e: Company) => ({
...e,
logoSrc: `${BACKEND_URL}/companies/logos/${e.ticker}`
})));

View file

@ -9,10 +9,16 @@
<template v-else v-for="company in companies" :key="company.ticker"> <template v-else v-for="company in companies" :key="company.ticker">
<v-col cols="12" md="6" lg="4"> <v-col cols="12" md="6" lg="4">
<v-card class="ma-1 fill-height"> <v-card class="ma-1 fill-height">
<v-card-item>
<div class="d-flex stretch align-center">
<div class="flex-0 pa-3">
<img style="max-height: 36px; min-height: 24px;" :src="company.logoSrc"/>
</div>
<v-card-item style="flex: 1 !important">
<v-card-title>{{ company['short name'] }}</v-card-title> <v-card-title>{{ company['short name'] }}</v-card-title>
<v-card-subtitle>{{ company['company name'] }}</v-card-subtitle> <v-card-subtitle>{{ company['company name'] }}</v-card-subtitle>
</v-card-item> </v-card-item>
</div>
<v-card-text> <v-card-text>
<p class="text--primary"> <p class="text--primary">
@ -21,9 +27,9 @@
<div class="pt-2 pb-2" v-for="m in metrics" :key="m.title"> <div class="pt-2 pb-2" v-for="m in metrics" :key="m.title">
<div class="d-inline-flex justify-space-between" style="width: 100%"> <div class="d-inline-flex justify-space-between" style="width: 100%">
<strong>{{ m.title }}</strong> <strong>{{ m.title }}</strong>
<span class="text-right">{{ m.value }}{{ m.symbol ?? '' }}</span> <span class="text-right">{{ m.value(company) }}{{ m.symbol ?? '' }}</span>
</div> </div>
<v-progress-linear :color="m.color" v-model="m.percentage"></v-progress-linear> <v-progress-linear :color="m.color" :model-value="m.percentage(company)"></v-progress-linear>
</div> </div>
</v-card-text> </v-card-text>
@ -59,7 +65,7 @@ interface Metric {
color: string, color: string,
minValue: number, minValue: number,
maxValue: number, maxValue: number,
value: number // in [0, 100], value: (c: Company) => number // in [0, 100],
symbol?: string symbol?: string
} }
@ -69,21 +75,21 @@ const metricsData = reactive<Metric[]>([
color: 'green', color: 'green',
minValue: 0, minValue: 0,
maxValue: 100, maxValue: 100,
value: 20 value: _ => 20
}, },
{ {
title: 'Metric 2', title: 'Length of ticker',
color: 'orange', color: 'orange',
minValue: 0, minValue: 0,
maxValue: 100, maxValue: 5,
value: 60, value: c => c.ticker.length,
symbol: '%' symbol: ' chars'
}, },
]); ]);
const metrics = computed<(Metric & { percentage: number })[]>(() => metricsData.map(e => ({ const metrics = computed<(Metric & { percentage: (c: Company) => number })[]>(() => metricsData.map(e => ({
...e, ...e,
percentage: (e.value - e.minValue) * 100 / (e.maxValue - e.minValue) percentage: (c: Company) => (e.value(c) - e.minValue) * 100 / (e.maxValue - e.minValue)
}))); })));

View file

@ -26,6 +26,17 @@ def companies() -> object:
return jsonify(get_companies(ROOT_DIR)) return jsonify(get_companies(ROOT_DIR))
@app.route('/companies/logos/<ticker>')
def get_company_logo(ticker: str):
logo_dir: str = os.path.join(ROOT_DIR, 'scraper', 'logos', 'logos')
logo_name: str = str(ticker).upper() + '.png'
if os.path.exists(os.path.join(logo_dir, logo_name)):
return send_from_directory(logo_dir, logo_name)
return send_from_directory(ROOT_DIR, 'company_generic.svg')
if __name__ == '__main__': if __name__ == '__main__':
build_frontend() build_frontend()
app.run() app.run()