Em termos gerais, Sails.js é um gerador de códigos JavaScript que entrega, em poucos minutos, um protótipo executável de uma Aplicação WEB do tipo backend robusta, segura e escalável. Diz-se backend porque todo o processamento ocorre do lado do servidor e depois disso é retornado ao navegador páginas HTML5 + CSS + JavaScript dinâmicas ao Cliente Web.
Se o Sails renderiza as páginas no lado do servidor, como posso incorporar um recurso Pure JavaScript como Chart.js no meu protótipo??
Este passo-a-passo demonstra como utilizar o gerador de gráficos Chart.js como solução de frontend em sincronia com as funcionalidades do Sails.js no backend.
Se esta é sua primeira vez aqui, recomendamos a leitura dos conteúdos abaixo antes de continuar:
npm i sails -g
sails new primeiro-prototipo
Choose a template for your new Sails app: 1. Web App · Extensible project with auth, login, & password recovery 2. Empty · An empty Sails app, yours to configure (type "?" for help, or <CTRL+C> to cancel) ? 1
cd primeiro-prototipo
sails lift
você verá:
info: Starting app... info: Initializing project hook... (`api/hooks/custom/`) info: Initializing `apianalytics` hook... (requests to monitored routes will be logged!) info: ·• Auto-migrating... (alter) info: Hold tight, this could take a moment. info: ✓ Auto-migration complete. debug: Running v0 bootstrap script... (looks like this is the first time the bootstrap has run on this computer) info: info: .-..-. info: info: Sails <| .-..-. info: v1.5.8 |\ info: /|.\ info: / || \ info: ,' |' \ info: .-'.-==|/_--' info: `--'-------' info: __---___--___---___--___---___--___ info: ____---___--___---___--___---___--___-__ info: info: Server lifted in `C:\Users\rogeriorfs\git\passo-a-passo` info: To shut down Sails, press <CTRL> + C at any time. info: Read more at https://sailsjs.com/support. debug: ------------------------------------------------------- debug: :: Mon Jul 17 2023 08:15:43 GMT-0300 (Horário Padrão de Brasília) debug: Environment : development debug: Port : 1337 debug: Local : http://localhost:1337 debug: ------------------------------------------------------->
http://localhost:1337
.
O navegador deve apresentar algo do tipo:
Existem três maneiras diferentes de fazer isso:
<script src="https://cdnjs.com/libraries/Chart.js"></script>
ao arquivo views/layouts/layout.ejs
<script src="https://www.jsdelivr.com/package/npm/chart.js?path=dist"></script>
ao arquivo views/layouts/layout.ejs
npm install chart.js
. Mas se você escolheu esta última opção (recomendada), continue e...
...node_modules/chart.js
...node_modules/chart.js/dist
com todo seu conteúdo para o subdiretório assets/dependencies
.
Se desejar, renomeie de dist
para chartjs
.sails lift
e verifique se as seguintes linhas foram adicionadas (automaticamente) ao seu arquivo .../layout.ejs
<script src="/dependencies/chartjs/chart.js"></script> <script src="/dependencies/chartjs/chart.umd.js"></script> <script src="/dependencies/chartjs/chunks/helpers.segment.js"></script> <script src="/dependencies/chartjs/helpers.js"></script>
Qualquer uma das páginas .EJS do protótipo será capaz de exibir um gráfico Chart.js, mas como exemplo,
escolhemos a página welcome.ejs
views/pages/dashboard/welcome.ejs
<div id="welcome"> <account-notification-banner></account-notification-banner> <div class="container pt-5 pb-5"> <h1>Welcome!</h1> <hr/> <p>This is a page that only logged-in people can visit. Don't you feel special? Try clicking on a button below to do some things you can't do when you're logged out.</p> <div class="buttons"> <a class="btn btn-info" href="/account/profile">Update my email</a> <button class="btn btn-outline-info ml-2" @click="clickOpenExampleModalButton()">Open a modal</button> </div> </div> <router-view></router-view> ...
router-view
o seguinte conteúdo:
<div class="border border-1"> <canvas id="myChart"></canvas> </div>
assets/js/pages/dashboard/welcome.page.js
e adicione ao método mounted()
o seguinte conteúdo:
... mounted: async function() { const ctx = document.getElementById('myChart'); _.extend(this, window.SAILS_LOCALS); const dados = this.resultado; // eslint-disable-next-line no-undef new Chart(ctx, { type: 'pie', data: { datasets: [{ label: 'Financial Movement', data: dados }], labels: ['Sales', 'Purchases', 'Losts'] }, options: { parsing: { xAxisKey: 'costCenter', yAxisKey: 'cost', key: 'cost' } } }); }, ...
api/controllers/dashboard/view-welcome.js
e adicione ao método fn()
o seguinte conteúdo:
... fn: async function () { return {resultado: [{costCenter: 'Sales', cost: 1500}, {costCenter: 'Purchases', cost: 500},{costCenter: 'Losts', cost: 199}]}; } ...
sails lift
.Neste exemplo, fizemos o backend api/controllers/dashboard/view-welcome.js
retornar um Array (lista)
de dados estática (return {resultado: [{costCenter: 'Sales', cost: 1500}, {costCenter: 'Purchases', cost: 500},{costCenter: 'Losts', cost: 199}]};
)
, mas poderíamos, tranquilamente, retornar o resultado de uma consulta a Base de Dados. Neste caso...
const dados = this.resultado
faria com que a variável dados recebesse o resultado da consulta a base de dados e
aqueles dados seriam enviados para o Gráfico Pizza que você está montando.data.datasets.label
ficaria sem sentidodata.labels
também não corresponderia ao conteúdo passado no conjunto de dadosoptions.parsing
para os eixos x e y (_AxisKey) não encontrariam correspondência e o dado não seria mostradoPortanto, ao modificar os dados passados como resposta do backend (neste caso view-welcome.js) para o frontend (neste caso welcome.page.js) é preciso modificar também os labels e parsings do componente Chart.js responsável pela renderização
Uma forma mais inteligênte de fazer isso seria...
mounted: async function() { const ctx = document.getElementById('myChart'); _.extend(this, window.SAILS_LOCALS); const dados = this.resultado; //passado como parametro pelo backend const label = this.titulo; //passado como parametro pelo backend // eslint-disable-next-line no-undef new Chart(ctx, { type: 'bar', data: { datasets: [{ label: label, data: dados }], //labels: _.values(dados[0]) //somente para circulares (ex. pizza) }, options: { parsing: { xAxisKey: _.keys(dados[0])[0], yAxisKey: _.keys(dados[0])[1], //key: _.keys(dados[0])[1] //somente para tipo central (ex. radar) } } }); },
Resultando em:
Um gráfico dinâmico cujos dados e demais parâmetros adicionais são obtidos da base de dados
Um recurso visual leve e responsivo (que se adapta a resolução do cliente que visualiza)
Um código limpo e de fácil manutenção
Consulte o Site Oficial do Chart.js para saber mais sobre as customizações possíveis e os tipos de gráficos que podes utilizar.