Chart.js
JSON Server
/codes/package/chartjs/monitor-app/back/db.json
{
"hosts": [
{
"id": 1,
"name": "Google Search",
"address": "www.google.com"
},
{
"id": 2,
"name": "Google DNS",
"address": "8.8.8.8"
}
],
"pings": [
{
"id": 1,
"createdAt": "2024-01-01T00:00:00Z",
"hostId": 1
},
{
"id": 2,
"createdAt": "2024-01-01T00:00:00Z",
"hostId": 2
}
],
"icmps": [
{
"id": 1,
"seq": 1,
"ttl": 54,
"time": 90,
"pingId": 1
},
{
"id": 2,
"seq": 2,
"ttl": 54,
"time": 95,
"pingId": 1
},
{
"id": 3,
"seq": 3,
"ttl": 54,
"time": 85,
"pingId": 1
},
{
"id": 4,
"seq": 1,
"ttl": 54,
"time": 95,
"pingId": 2
},
{
"id": 5,
"seq": 2,
"ttl": 54,
"time": 80,
"pingId": 2
},
{
"id": 6,
"seq": 3,
"ttl": 54,
"time": 99,
"pingId": 2
}
]
}
/codes/package/chartjs/monitor-app/back/db.json
{
"hosts": [
{
"id": 1,
"name": "Google Search",
"address": "www.google.com"
},
{
"id": 2,
"name": "Google DNS",
"address": "8.8.8.8"
}
],
"pings": [
{
"id": 1,
"createdAt": "2024-01-01T00:00:00Z",
"hostId": 1
},
{
"id": 2,
"createdAt": "2024-01-01T00:00:00Z",
"hostId": 2
}
],
"icmps": [
{
"id": 1,
"seq": 1,
"ttl": 54,
"time": 90,
"pingId": 1
},
{
"id": 2,
"seq": 2,
"ttl": 54,
"time": 95,
"pingId": 1
},
{
"id": 3,
"seq": 3,
"ttl": 54,
"time": 85,
"pingId": 1
},
{
"id": 4,
"seq": 1,
"ttl": 54,
"time": 95,
"pingId": 2
},
{
"id": 5,
"seq": 2,
"ttl": 54,
"time": 80,
"pingId": 2
},
{
"id": 6,
"seq": 3,
"ttl": 54,
"time": 99,
"pingId": 2
}
]
}
Monitor-app (CRUD)
Arquivos
monitor-app
├── back
│ ├── db.json
│ ├── package-lock.json
│ ├── package.json
│ └── src
│ └── server.js
└── front
├── css
│ └── style.css
├── index.html
├── js
│ ├── components
│ │ ├── HostForm.js
│ │ ├── HostTableRow.js
│ │ ├── LineChart.js
│ │ └── Modal.js
│ ├── lib
│ │ ├── dom.js
│ │ └── hosts.js
│ ├── main.js
│ └── services
│ └── storage.js
├── package-lock.json
├── package.json
├── public
│ └── vite.svg
└── vite.config.js
Arquivos
monitor-app
├── back
│ ├── db.json
│ ├── package-lock.json
│ ├── package.json
│ └── src
│ └── server.js
└── front
├── css
│ └── style.css
├── index.html
├── js
│ ├── components
│ │ ├── HostForm.js
│ │ ├── HostTableRow.js
│ │ ├── LineChart.js
│ │ └── Modal.js
│ ├── lib
│ │ ├── dom.js
│ │ └── hosts.js
│ ├── main.js
│ └── services
│ └── storage.js
├── package-lock.json
├── package.json
├── public
│ └── vite.svg
└── vite.config.js
npm i chart.js
npm i chart.js
/codes/package/chartjs/monitor-app/front/js/components/LineChart.js
import Chart from 'chart.js/auto';
let chart;
export function create(canvasId) {
const ctx = document.getElementById(canvasId);
chart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [
{
data: [],
borderWidth: 2,
borderColor: '#1e293b',
},
],
},
options: {
plugins: {
legend: {
display: false,
},
},
scales: {
y: {
beginAtZero: true,
},
},
maintainAspectRatio: false,
},
});
return chart;
}
export function update(times) {
chart.data.labels = Object.keys(times);
chart.data.datasets[0].data = times;
chart.update();
}
/codes/package/chartjs/monitor-app/front/js/components/LineChart.js
import Chart from 'chart.js/auto';
let chart;
export function create(canvasId) {
const ctx = document.getElementById(canvasId);
chart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [
{
data: [],
borderWidth: 2,
borderColor: '#1e293b',
},
],
},
options: {
plugins: {
legend: {
display: false,
},
},
scales: {
y: {
beginAtZero: true,
},
},
maintainAspectRatio: false,
},
});
return chart;
}
export function update(times) {
chart.data.labels = Object.keys(times);
chart.data.datasets[0].data = times;
chart.update();
}
/codes/package/chartjs/monitor-app/front/js/main.js
import 'bootstrap';
import 'iconify-icon';
import HostForm from './components/HostForm';
import Modal from './components/Modal';
import * as LineChart from './components/LineChart';
import Hosts from './lib/hosts';
import 'bootstrap/dist/css/bootstrap.css';
import '../css/style.css';
Hosts.load();
HostForm.create();
Modal.create();
LineChart.create('chart-line');
/codes/package/chartjs/monitor-app/front/js/main.js
import 'bootstrap';
import 'iconify-icon';
import HostForm from './components/HostForm';
import Modal from './components/Modal';
import * as LineChart from './components/LineChart';
import Hosts from './lib/hosts';
import 'bootstrap/dist/css/bootstrap.css';
import '../css/style.css';
Hosts.load();
HostForm.create();
Modal.create();
LineChart.create('chart-line');
/codes/package/chartjs/monitor-app/front/js/components/HostTableRow.js
import { $ } from '../lib/dom';
import Hosts from '../lib/hosts';
import HostForm from './HostForm';
import * as LineChart from './LineChart';
import Storage from '../services/storage';
export function create(host) {
const row = `
<tr id="host-${host.id}">
<td class="host-name">
${host.name}
</td>
<td class="host-address">
${host.address}
</td>
<td class="host-events">
<span
class="icon-pencil"
data-bs-toggle="offcanvas"
data-bs-target="#offcanvasRight"
aria-controls="offcanvasRight"
>
<iconify-icon icon="bx:edit"></iconify-icon>
</span>
<span class="icon-trash" data-bs-toggle="modal" data-bs-target="#modal">
<iconify-icon icon="bx:trash"></iconify-icon>
</span>
<span class="icon-stopwatch">
<iconify-icon icon="bx:stopwatch"></iconify-icon>
</span>
<span class="icon-loading invisible">
<iconify-icon icon="line-md:loading-loop"></iconify-icon>
</span>
</td>
</tr>
`;
$('.table-hosts tbody').insertAdjacentHTML('beforeend', row);
$(`#host-${host.id} .icon-pencil`).onclick = () => {
HostForm.setTitleForm('Atualizar Host');
HostForm.setValues(host);
HostForm.handleSubmit((host) => Hosts.update(host));
};
$(`#host-${host.id} .icon-trash`).onclick = () => {
$(`.modal .host-name`).innerText = host.name;
$(`.modal .remove-host-btn`).onclick = () => Hosts.remove(host);
};
$(`#host-${host.id} .icon-stopwatch`).onclick = async () => {
$(`#host-${host.id} .icon-loading`).classList.remove('invisible');
const pings = await Storage.read(`hosts/${host.id}/pings?_embed=icmps`);
const times = pings[0].icmps.map((icmp) => icmp.time);
LineChart.update(times);
$(`#host-${host.id} .icon-loading`).classList.add('invisible');
};
}
export function update({ id, name, address }) {
$(`#host-${id} .host-name`).innerText = name;
$(`#host-${id} .host-address`).innerText = address;
}
export function remove(id) {
$(`#host-${id}`).remove();
}
/codes/package/chartjs/monitor-app/front/js/components/HostTableRow.js
import { $ } from '../lib/dom';
import Hosts from '../lib/hosts';
import HostForm from './HostForm';
import * as LineChart from './LineChart';
import Storage from '../services/storage';
export function create(host) {
const row = `
<tr id="host-${host.id}">
<td class="host-name">
${host.name}
</td>
<td class="host-address">
${host.address}
</td>
<td class="host-events">
<span
class="icon-pencil"
data-bs-toggle="offcanvas"
data-bs-target="#offcanvasRight"
aria-controls="offcanvasRight"
>
<iconify-icon icon="bx:edit"></iconify-icon>
</span>
<span class="icon-trash" data-bs-toggle="modal" data-bs-target="#modal">
<iconify-icon icon="bx:trash"></iconify-icon>
</span>
<span class="icon-stopwatch">
<iconify-icon icon="bx:stopwatch"></iconify-icon>
</span>
<span class="icon-loading invisible">
<iconify-icon icon="line-md:loading-loop"></iconify-icon>
</span>
</td>
</tr>
`;
$('.table-hosts tbody').insertAdjacentHTML('beforeend', row);
$(`#host-${host.id} .icon-pencil`).onclick = () => {
HostForm.setTitleForm('Atualizar Host');
HostForm.setValues(host);
HostForm.handleSubmit((host) => Hosts.update(host));
};
$(`#host-${host.id} .icon-trash`).onclick = () => {
$(`.modal .host-name`).innerText = host.name;
$(`.modal .remove-host-btn`).onclick = () => Hosts.remove(host);
};
$(`#host-${host.id} .icon-stopwatch`).onclick = async () => {
$(`#host-${host.id} .icon-loading`).classList.remove('invisible');
const pings = await Storage.read(`hosts/${host.id}/pings?_embed=icmps`);
const times = pings[0].icmps.map((icmp) => icmp.time);
LineChart.update(times);
$(`#host-${host.id} .icon-loading`).classList.add('invisible');
};
}
export function update({ id, name, address }) {
$(`#host-${id} .host-name`).innerText = name;
$(`#host-${id} .host-address`).innerText = address;
}
export function remove(id) {
$(`#host-${id}`).remove();
}