Nos já vimos como criar gráficos usando JavaScript e como passar dados do Python para o JavaScript usando o Flask.
Agora vamos criar nosso primeiro gráfico, que vai ter esta cara:
Vamos acessar este endpoint, que possui informações sobre os casos diários:
https://api.covid19.finspect.me/brcovid19/dayEntão dentro do nosso routes.py, vamos mandar um request para esse endpoint. Vamos também mudar o nome de algumas variáveis:
@app.route("/brasil")
def brazil():
# Fazendo a requisição para a API pra ter os dados da tabela
states_data_for_table = requests.get("h t t p s :/ / ap i. c o v i d 1 9 . finspect.me/brcovid19/map").json()
# Fazendo a nova requisição para ter os casos por dia
daily_cases_data = requests.get("h t t p s : / / a p i . c o v id19.finspect.me/brcovid19/day").json()
# Pegando a data atual
date = datetime.now().strftime(format="%d/%m/%Y")
return render_template("brazil.html", table_data=states_data_for_table, date=date)
Como mudei o nome da variável, também mudei o nome da variável que vai ser repassada para o template do Flask com os dados antigos, da tabela. Antes era "states" e agora é "table_data". Vamos mudar no template:
{% extends "base.html" %}
{% block content %}
<h1 class="text-center">Casos de Covid-19 no Brasil</h1>
<p class="text-center">
Dados por estado da federação, atualizados em {{ date }}
</p>
<!-- Tabela criada já com as classes Bootstrap -->
<div class="row">
<div class="col-lg-8">
<h2>Gráficos</h2>
<div class="chart-container">
<canvas id="chart"></canvas>
</div>
</div>
<div class="col-lg-4">
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Estado</th>
<th scope="col">Número de casos</th>
</tr>
</thead>
<tbody>
<!-- Laço for agora iterando sobre cada estado do JSON -->
{% for state in table_data %}
<tr scope="row">
<!-- Os dados do laço -->
<td>{{ state["name"] }}</td>
<td>{{ state["qtd_confirmation"] }}</td>
</tr>
<!-- No template nós devemos sinalizar o fim do for com um endfor -->
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}
Agora vamos processar os dados do novo endpoint. Vamos abrir um terminal à parte e dar um print no resultado da requisição:
In [1]: import requests
In [2]: data = requests.get('h t t p s : / / a p i . covid19.finspect.me/brcovid19/day').json()
In [3]: print(data)
[{'label': '26/02', 'qtd_confirmation': 1, 'qtd_death': 123}, {'label': '27/02', 'qtd_confirmation': 0, 'qtd_death': 34}, {'label': '28/02', 'qtd_confirmation': 0, 'qtd_death': 35}, {'label': '29/02', 'qtd_confirmation': 1, 'qtd_death': 45}, {'label': '01/03', 'qtd_confirmation': 0, 'qtd_death': 55}, {'label': '02/03', 'qtd_confirmation': 0, 'qtd_death': 67}, {'label': '03/03', 'qtd_confirmation': 0, 'qtd_death': 78}, {'label': '04/03', 'qtd_confirmation': 1, 'qtd_death': 0}, {'label': '05/03', 'qtd_confirmation': 4, 'qtd_death': 0}, {'label': '06/03', 'qtd_confirmation': 6, 'qtd_death': 0}, {'label': '07/03', 'qtd_confirmation': 6, 'qtd_death': 0}, {'label': '08/03', 'qtd_confirmation': 6, 'qtd_death': 0}, {'label': '09/03', 'qtd_confirmation': 0, 'qtd_death': 0}, {'label': '10/03', 'qtd_confirmation': 9, 'qtd_death': 0}, {'label': '11/03', 'qtd_confirmation': 18, 'qtd_death': 0}, {'label': '12/03', 'qtd_confirmation': 25, 'qtd_death': 0}, {'label': '13/03', 'qtd_confirmation': 21, 'qtd_death': 0}, {'label': '14/03', 'qtd_confirmation': 23, 'qtd_death': 0}, {'label': '15/03', 'qtd_confirmation': 79, 'qtd_death': 0}, {'label': '16/03', 'qtd_confirmation': 34, 'qtd_death': 0}, {'label': '17/03', 'qtd_confirmation': 57, 'qtd_death': 0}, {'label': '18/03', 'qtd_confirmation': 137, 'qtd_death': 0}, {'label': '19/03', 'qtd_confirmation': 193, 'qtd_death': 0}, {'label': '20/03', 'qtd_confirmation': 283, 'qtd_death': 0}, {'label': '21/03', 'qtd_confirmation': 224, 'qtd_death': 0}, {'label': '22/03', 'qtd_confirmation': 418, 'qtd_death': 0}, {'label': '23/03', 'qtd_confirmation': 345, 'qtd_death': 0}, {'label': '24/03', 'qtd_confirmation': 310, 'qtd_death': 0}, {'label': '25/03', 'qtd_confirmation': 232, 'qtd_death': 0}, {'label': '26/03', 'qtd_confirmation': 482, 'qtd_death': 0}, {'label': '27/03', 'qtd_confirmation': 502, 'qtd_death': 0}, {'label': '28/03', 'qtd_confirmation': 487, 'qtd_death': 0}, {'label': '29/03', 'qtd_confirmation': 353, 'qtd_death': 0}, {'label': '30/03', 'qtd_confirmation': 323, 'qtd_death': 0}, {'label': '31/03', 'qtd_confirmation': 1138, 'qtd_death': 0}, {'label': '01/04', 'qtd_confirmation': 1119, 'qtd_death': 0}, {'label': '02/04', 'qtd_confirmation': 1076, 'qtd_death': 0}, {'label': '03/04', 'qtd_confirmation': 1146, 'qtd_death': 0}, {'label': '04/04', 'qtd_confirmation': 1222, 'qtd_death': 0}, {'label': '05/04', 'qtd_confirmation': 852, 'qtd_death': 0}, {'label': '06/04', 'qtd_confirmation': 926, 'qtd_death': 0}, {'label': '07/04', 'qtd_confirmation': 1661, 'qtd_death': 0}, {'label': '08/04', 'qtd_confirmation': 2210, 'qtd_death': 0}, {'label': '09/04', 'qtd_confirmation': 1930, 'qtd_death': 0}, {'label': '10/04', 'qtd_confirmation': 1781, 'qtd_death': 0}, {'label': '11/04', 'qtd_confirmation': 1089, 'qtd_death': 0}, {'label': '12/04', 'qtd_confirmation': 1442, 'qtd_death': 0}, {'label': '13/04', 'qtd_confirmation': 1261, 'qtd_death': 0}, {'label': '14/04', 'qtd_confirmation': 1832, 'qtd_death': 0}, {'label': '15/04', 'qtd_confirmation': 3058, 'qtd_death': 0}, {'label': '16/04', 'qtd_confirmation': 2105, 'qtd_death': 0}, {'label': '17/04', 'qtd_confirmation': 3257, 'qtd_death': 0}, {'label': '18/04', 'qtd_confirmation': 2917, 'qtd_death': 0}, {'label': '19/04', 'qtd_confirmation': 2055, 'qtd_death': 0}, {'label': '20/04', 'qtd_confirmation': 1927, 'qtd_death': 0}, {'label': '21/04', 'qtd_confirmation': 2498, 'qtd_death': 0}, {'label': '22/04', 'qtd_confirmation': 2678, 'qtd_death': 0}, {'label': '23/04', 'qtd_confirmation': 3735, 'qtd_death': 0}, {'label': '24/04', 'qtd_confirmation': 3503, 'qtd_death': 0}]
Certo, já temos nossos dados.
Eu poderia passar os dados dessa forma que já estão para o JavaScript, mas vamos processá-los logo no Python e enviar os dados para o JavaScript precisar só pegar os arrays e mostrar os gráficos sem muito trabalho.
E o que eu vou precisar? Como vimos no tópico do D25, eu passo um array de dados para o chart js renderizar os gráficos.
Então podemos simplesmente passar duas listas para o JavaScript, uma contendo as datas e a outra contendo o número de casos. Pode não ser a forma mais organizada mas por enquanto resolve nosso problema.
Vamos fazer no console primeiro antes de passar para o routes.py:
In [4]: cases_list = list()
In [5]: dates_list = list()
In [6]: for daily_data in data:
...: cases_list.append(daily_data['qtd_confirmation'])
...: dates_list.append(daily_data['label'])
Acima eu iterei pela minha lista representada pela variável "data", que é uma lista de dicionários, e adicionei às minhas duas listas criadas mais acima a quantidade de casos por dia e a data, nas listas respectivas, cases_list e dates_list.
Podemos ver o resultado de cada lista abaixo:
In [11]: print(dates_list)
['26/02', '27/02', '28/02', '29/02', '01/03', '02/03', '03/03', '04/03', '05/03', '06/03', '07/03', '08/03', '09/03', '10/03', '11/03', '12/03', '13/03', '14/03', '15/03', '16/03', '17/03', '18/03', '19/03', '20/03', '21/03', '22/03', '23/03', '24/03', '25/03', '26/03', '27/03', '28/03', '29/03', '30/03', '31/03', '01/04', '02/04', '03/04', '04/04', '05/04', '06/04', '07/04', '08/04', '09/04', '10/04', '11/04', '12/04', '13/04', '14/04', '15/04', '16/04', '17/04', '18/04', '19/04', '20/04', '21/04', '22/04', '23/04', '24/04']
In [12]: print(cases_list)
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23, 79, 34, 57, 137, 193, 283, 224, 418, 345, 310, 232, 482, 502, 487, 353, 323, 1138, 1119, 1076, 1146, 1222, 852, 926, 1661, 2210, 1930, 1781, 1089, 1442, 1261, 1832, 3058, 2105, 3257, 2917, 2055, 1927, 2498, 2678, 3735, 3503]
E já podemos passar essas listas para o template, para que o JavaScript pegue esses dados e use nos gráficos.
Vamos alterar nosso routes.py e inserir esse código que fizemos no console. Dessa forma, nosso routes.py vai ficar assim:
@app.route("/brasil")
def brazil():
# Fazendo a requisição para a API pra ter os dados da tabela
states_data_for_table = requests.get("h t t p s : / / a p i.covid19.finspect.me/brcovid19/map").json()
# Fazendo a nova requisição para ter os casos por dia
daily_cases_data = requests.get("h t t p s : / / a p i.covid19.finspect.me/brcovid19/day").json()
cases_list = list()
dates_list = list()
for daily_data in daily_cases_data:
cases_list.append(daily_data['qtd_confirmation'])
dates_list.append(daily_data['label'])
# Pegando a data atual
date = datetime.now().strftime(format="%d/%m/%Y")
return render_template("brazil.html",
table_data=states_data_for_table,
date=date,
cases_list=cases_list,
dates_list=dates_list
)
Será que deu certo? Vamos no nosso template e tentar pegar os dados com o JavaScript, como fizemos anteriormente. Adicionem o script abaixo ao final do template, antes do endblock:

Rodem o projeto com um flask run e vamos ver o resultado no console do browser:

Temos dois arrays de 59 itens cada em nosso console. Se abrirmos no browser cada array, veremos:

Acima, temos o array com os casos por dia.

Acima, temos o array com as datas.
Agora basta passar esses dois arrays para o javascript.
Eu poderia criar um arquivo main.js mas por enquanto vou fazer tudo no template mesmo.
Vamos expandir a tag script que foi criada para receber os dados do Python para o JavaScript e adicionar o código para o gráfico. Vamos adicionar novamente o código do chart js em uma tag script acima. Lembrando que já temos no template uma div com um canvas que irá receber nosso gráfico:
<div class="chart-container">
<canvas id="chart"></canvas>
</div>
Como já explicado no D25, não vou me ater aos detalhes do gráfico, já vimos basicamente tudo que o código abaixo faz no D25.

Vamos atualizar nossa página e ver o resultado:

E voilá, temos nosso primeiro gráfico.