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 -gsails 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-prototiposails 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.ejsnpm 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.