avance dashboard
parent
645166bf0b
commit
ee4051e7ef
|
@ -0,0 +1,97 @@
|
||||||
|
<script>
|
||||||
|
import { getCountBuses } from "$/services/lineas";
|
||||||
|
import { createEventDispatcher, onMount } from "svelte";
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
let canvasChart = null;
|
||||||
|
let data = []
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
// @ts-ignore
|
||||||
|
const { Chart, theme } = globalThis || {};
|
||||||
|
|
||||||
|
dispatch('loading', true)
|
||||||
|
const result = await getCountBuses()
|
||||||
|
data = result.sort((a,b) => a.route_short_name < b.route_short_name ? -1 : 1)
|
||||||
|
|
||||||
|
const resumen = []
|
||||||
|
for (const row of data) {
|
||||||
|
const servicio = row.route_short_name.substring(0,2)
|
||||||
|
const elem = resumen.find(el => el.servicio === servicio) || null;
|
||||||
|
if (elem) {
|
||||||
|
elem.count += row.count
|
||||||
|
} else {
|
||||||
|
resumen.push({ servicio, count: row.count })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const labels = resumen.map(el => `Servicio ${el.servicio}`)
|
||||||
|
const values = resumen.map(el => el.count)
|
||||||
|
const colors = resumen.map((el, index) => {
|
||||||
|
const valor = index % 4;
|
||||||
|
if (valor === 0) {
|
||||||
|
const color = parseInt(theme.primary.replace('#','0x'))
|
||||||
|
return '#' + Number(color + ((valor + index) * 150)).toString(16)
|
||||||
|
} else if (valor === 1) {
|
||||||
|
const color = parseInt(theme.success.replace('#','0x'))
|
||||||
|
return '#' + Number(color + ((valor + index) * 150)).toString(16)
|
||||||
|
} else if (valor === 2) {
|
||||||
|
const color = parseInt(theme.warning.replace('#','0x'))
|
||||||
|
return '#' + Number(color + ((valor + index) * 150)).toString(16)
|
||||||
|
} else {
|
||||||
|
const color = parseInt('0xdee2e6')
|
||||||
|
return '#' + Number(color + ((valor + index) * 150)).toString(16)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
dispatch('loading', false)
|
||||||
|
|
||||||
|
new Chart(canvasChart, {
|
||||||
|
type: "pie",
|
||||||
|
data: {
|
||||||
|
labels,
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
data: values,
|
||||||
|
backgroundColor: colors,
|
||||||
|
borderColor: "transparent",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
cutoutPercentage: 65,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="card flex-fill w-100">
|
||||||
|
<div class="card-header">
|
||||||
|
<h5 class="card-title mb-0">Buses en recorrido por línea</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body d-flex">
|
||||||
|
<div class="align-self-center w-100">
|
||||||
|
<div class="py-3">
|
||||||
|
<div class="chart chart-sm">
|
||||||
|
<canvas bind:this={canvasChart}></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-responsive border" style="max-height: 400px;">
|
||||||
|
<table class="table mb-0 table-hover">
|
||||||
|
<tbody>
|
||||||
|
{#each data as row}
|
||||||
|
<tr>
|
||||||
|
<td>{row.route_short_name}</td>
|
||||||
|
<td class="text-end">{row.count}</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,32 @@
|
||||||
|
<script>
|
||||||
|
import { getCountBusesRecorridos } from "$/services/lineas";
|
||||||
|
|
||||||
|
import { createEventDispatcher, onMount } from "svelte";
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
dispatch('loading', true)
|
||||||
|
getCountBusesRecorridos()
|
||||||
|
.then(data => count = data.count)
|
||||||
|
.finally(() => dispatch('loading', false))
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col mt-0">
|
||||||
|
<h5 class="card-title">Buses en recorrido</h5>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-auto">
|
||||||
|
<div class="stat text-primary">
|
||||||
|
<i class="bi bi-speedometer2 fs-4"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h1 class="mt-1 mb-3">{count}</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,32 @@
|
||||||
|
<script>
|
||||||
|
import { getCount } from "$/services/lineas";
|
||||||
|
|
||||||
|
import { createEventDispatcher, onMount } from "svelte";
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
dispatch('loading', true)
|
||||||
|
getCount({ vigente: 1 })
|
||||||
|
.then(data => count = data.count)
|
||||||
|
.finally(() => dispatch('loading', false))
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col mt-0">
|
||||||
|
<h5 class="card-title">Cantidad de Líneas</h5>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-auto">
|
||||||
|
<div class="stat text-primary">
|
||||||
|
<i class="bi bi-bus-front fs-4"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h1 class="mt-1 mb-3">{count}</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<script>
|
||||||
|
import { createEventDispatcher, onMount } from "svelte";
|
||||||
|
import { getCount } from "$/services/paraderos";
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
dispatch('loading', true)
|
||||||
|
getCount({ vigente: 1 })
|
||||||
|
.then(data => count = data.count)
|
||||||
|
.finally(() => dispatch('loading', false))
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col mt-0">
|
||||||
|
<h5 class="card-title">Cantidad de Paraderos</h5>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-auto">
|
||||||
|
<div class="stat text-primary">
|
||||||
|
<i class="bi bi-question-octagon fs-4"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h1 class="mt-1 mb-3">{count}</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,32 @@
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col mt-0">
|
||||||
|
<h5 class="card-title">Paraderos por comuna</h5>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-auto">
|
||||||
|
<div class="stat text-primary">
|
||||||
|
<i class="bi bi-geo-alt fs-4"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h1 class="mt-1 mb-3">2.382</h1>
|
||||||
|
<table class="table mb-0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Chrome</td>
|
||||||
|
<td class="text-end">4306</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Firefox</td>
|
||||||
|
<td class="text-end">3801</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>IE</td>
|
||||||
|
<td class="text-end">1689</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -1,16 +1,44 @@
|
||||||
<script>
|
<script>
|
||||||
import PageTitle from "$/components/PageTitle.svelte";
|
import PageTitle from "$/components/PageTitle.svelte";
|
||||||
|
import CantidadParaderos from "./CantidadParaderos.svelte";
|
||||||
|
import CantidadLineas from "./CantidadLineas.svelte";
|
||||||
|
import CantidadParaderosComuna from "./CantidadParaderosComuna.svelte";
|
||||||
|
import CantidadBusesRecorrido from "./CantidadBusesRecorrido.svelte";
|
||||||
|
import CantidadBusesLinea from "./CantidadBusesLinea.svelte";
|
||||||
|
|
||||||
|
let loading1 = false
|
||||||
|
let loading2 = false
|
||||||
|
let loading3 = false
|
||||||
|
let loading4 = false
|
||||||
|
let loading5 = false
|
||||||
</script>
|
</script>
|
||||||
<PageTitle>Inicio</PageTitle>
|
|
||||||
|
<PageTitle
|
||||||
|
loading={loading1 || loading2 || loading3 || loading4 || loading5 }
|
||||||
|
><strong>Análisis</strong> de datos</PageTitle>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-xs-12 col-md-7">
|
||||||
<div class="card">
|
<div class="row">
|
||||||
<div class="card-header">
|
<div class="col">
|
||||||
<h5 class="card-title mb-0">Empty card</h5>
|
<CantidadLineas on:loading={ev => loading1 = ev.detail} />
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="col">
|
||||||
|
<CantidadParaderos on:loading={ev => loading2 = ev.detail} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<CantidadParaderosComuna on:loading={ev => loading3 = ev.detail} />
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<CantidadBusesRecorrido on:loading={ev => loading4 = ev.detail} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="col-xs-12 col-md-5">
|
||||||
|
<CantidadBusesLinea on:loading={ev => loading5 = ev.detail} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -62,3 +62,33 @@ export async function getBusesLinea(id_linea) {
|
||||||
if (!res.ok) throw await res.text()
|
if (!res.ok) throw await res.text()
|
||||||
return res.json()
|
return res.json()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function getCount(params) {
|
||||||
|
const query = !params ? '' : '?' + (new URLSearchParams(params).toString());
|
||||||
|
const res = await fetch(`${base}/lineas/count/${query}`, {
|
||||||
|
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||||
|
})
|
||||||
|
if (!res.ok) throw await res.text()
|
||||||
|
return res.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function getCountBuses(params) {
|
||||||
|
const query = !params ? '' : '?' + (new URLSearchParams(params).toString());
|
||||||
|
const res = await fetch(`${base}/lineas/count_buses/${query}`, {
|
||||||
|
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||||
|
})
|
||||||
|
if (!res.ok) throw await res.text()
|
||||||
|
return res.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function getCountBusesRecorridos(params) {
|
||||||
|
const query = !params ? '' : '?' + (new URLSearchParams(params).toString());
|
||||||
|
const res = await fetch(`${base}/lineas/count_buses_recorridos/${query}`, {
|
||||||
|
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||||
|
})
|
||||||
|
if (!res.ok) throw await res.text()
|
||||||
|
return res.json()
|
||||||
|
}
|
|
@ -121,3 +121,15 @@ export async function getInfoPublic(id_paradero) {
|
||||||
if (!res.ok) throw await res.text()
|
if (!res.ok) throw await res.text()
|
||||||
return res.json()
|
return res.json()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export async function getCount(params) {
|
||||||
|
const query = !params ? '' : '?' + (new URLSearchParams(params).toString());
|
||||||
|
const res = await fetch(`${base}/paraderos/count/${query}`, {
|
||||||
|
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||||
|
})
|
||||||
|
if (!res.ok) throw await res.text()
|
||||||
|
return res.json()
|
||||||
|
}
|
Loading…
Reference in New Issue