516 lines
14 KiB
HTML
516 lines
14 KiB
HTML
{% extends 'h_tmp_usr/z_tmp.html' %}
|
|
|
|
{% block css %}
|
|
|
|
{% endblock css %}
|
|
|
|
{% block body %}
|
|
|
|
<style>
|
|
main{
|
|
place-items: center;
|
|
}
|
|
|
|
canvas {
|
|
width: 100% !important;
|
|
height: auto !important;
|
|
max-height: 300px;
|
|
}
|
|
</style>
|
|
|
|
<div>
|
|
|
|
<div class="container-fluid">
|
|
<div class="row g-4" data-aos="fade-right" data-aos-delay="0" data-aos-duration="800" data-aos-easing="ease-in-out">
|
|
<div class="col-12 col-sm-6" >
|
|
<div class="p-3 bg-light rounded shadow-sm">
|
|
<canvas id="dbContacts"></canvas>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-sm-6">
|
|
<div class="p-3 bg-light rounded shadow-sm">
|
|
<canvas id="dbEdos"></canvas>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-sm-6">
|
|
<div class="p-3 bg-light rounded shadow-sm">
|
|
<canvas id="dbSize"></canvas>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-sm-6">
|
|
<div class="p-3 bg-light rounded shadow-sm">
|
|
<canvas id="dbRol"></canvas>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-sm-6">
|
|
<div class="p-3 bg-light rounded shadow-sm">
|
|
<canvas id="dbIndustry"></canvas>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-sm-6">
|
|
<div class="p-3 bg-light rounded shadow-sm">
|
|
<canvas id="dbStatus"></canvas>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-sm-6">
|
|
<div class="p-3 bg-light rounded shadow-sm">
|
|
<canvas id="dbTopTenPosts"></canvas>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-sm-6">
|
|
<div class="p-3 bg-light rounded shadow-sm">
|
|
<canvas id="dbTop3Autores"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{% endblock body %}
|
|
|
|
{% block js %}
|
|
|
|
<!-- {# aos script #} -->
|
|
{% include 'z_comps/aos_script.html' %}
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
|
|
<script>
|
|
let acronym = {
|
|
'Aguascalientes' : 'Ags.',
|
|
'Baja California' : 'B.C.',
|
|
'Baja California Sur' : 'B.C.S.',
|
|
'Campeche' : 'Camp.',
|
|
'Chiapas' : 'Chis.',
|
|
'Chihuahua' : 'Chih.',
|
|
'Ciudad de México' : 'Coah.',
|
|
'Coahuila' : 'Col.',
|
|
'Colima' : 'CDMX',
|
|
'Durango' : 'Dgo.',
|
|
'Estado de México' : 'Gto.',
|
|
'Guanajuato' : 'Gro.',
|
|
'Guerrero' : 'Hgo.',
|
|
'Hidalgo' : 'Jal.',
|
|
'Jalisco' : 'Méx.',
|
|
'Michoacán' : 'Mich.',
|
|
'Morelos' : 'Mor.',
|
|
'Nayarit' : 'Nay.',
|
|
'Nuevo León' : 'N.L.',
|
|
'Oaxaca' : 'Oax.',
|
|
'Puebla' : 'Pue.',
|
|
'Querétaro' : 'Qro.',
|
|
'Quintana Roo' : 'Q.R.',
|
|
'San Luis Potosí' : 'S.L.P.',
|
|
'Sinaloa' : 'Sin.',
|
|
'Sonora' : 'Son.',
|
|
'Tabasco' : 'Tab.',
|
|
'Tamaulipas' : 'Tamps.',
|
|
'Tlaxcala' : 'Tlax.',
|
|
'Veracruz' : 'Ver.',
|
|
'Yucatán' : 'Yuc.',
|
|
'Zacatecas' : 'Zacs.'
|
|
}
|
|
|
|
</script>
|
|
|
|
<script>
|
|
|
|
|
|
|
|
function getColor(i) {
|
|
const palette = [
|
|
"#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF", "#FF9F40", "#8AC249", "#EA5F89", "#00BFFF", "#FDB45C", "#32CD32", "#9370DB", "#FF69B4", "#20B2AA", "#FF4500", "#6A5ACD", "#DA70D6", "#1E90FF", "#FFD700", "#8B4513", "#A2D6F9", "#FFB6C1", "#98FB98", "#E6E6FA", "#FFDEAD", "#2F4F4F", "#696969", "#483D8B", "#556B2F", "#8B0000", "#00FA9A", "#9400D3",
|
|
"#FF6B6B", "#4ECDC4", "#45B7D1", "#FFBE0B", "#FB5607", "#8338EC", "#3A86FF", "#FF006E", "#6A994E", "#A7C4BC",
|
|
"#E9C46A", "#F4A261", "#E76F51", "#264653", "#2A9D8F", "#B5838D", "#FFCDB2", "#FFB4A2", "#E5989B", "#B5838D",
|
|
"#A5A58D", "#83C5BE", "#EDF6F9", "#FFDDD2", "#5E548E", "#9F86C0", "#231942", "#BE95C4", "#5E60CE", "#6930C3",
|
|
"#7400B8", "#3C096C",
|
|
'#3cb44b', '#ffe119', '#4363d8', '#f58231', '#911eb4', '#46f0f0', '#f032e6', '#bcf60c', '#fabebe', '#008080',
|
|
"#e6b0aa", "#f9e79f", "#f1948a", "#76d7c4", "#85c1ae", "#f5b7b1", "#f7dc6f", "#f4d03f", "#f39c12", "#e67e22",
|
|
'#4dc9f6', '#f67019', '#f53794', '#537bc4', '#acc236', '#166a8f', '#00a950', '#58595b', '#8549ba', '#e6194b',
|
|
|
|
];
|
|
return palette[i % palette.length];
|
|
}
|
|
|
|
|
|
function custom_chart(varCanvas, str_type, lst_labels, lst_values, lst_colors, str_title){
|
|
new Chart(varCanvas, {
|
|
// "bar"
|
|
type: str_type,
|
|
data: {
|
|
labels: lst_labels,
|
|
datasets: [{
|
|
label: lst_labels,
|
|
data: lst_values,
|
|
backgroundColor: lst_colors, // Color diferente por barra
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true
|
|
}
|
|
},
|
|
responsive: true,
|
|
plugins: {
|
|
legend: {
|
|
display: false // No es necesario si ya se diferencian por label
|
|
},
|
|
title: {
|
|
display: true,
|
|
text: str_title
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
|
|
fetch('/user/metrics/data')
|
|
.then(data => data.json())
|
|
.then(data => {
|
|
let count_monthly = data.count_monthly;
|
|
let labels_monthy = count_monthly.map(e => `${e[0]} [ ${e[2]}% ]` );
|
|
let values_monthy = count_monthly.map(e => e[1]);
|
|
let colors_monthy = count_monthly.map((_, i) => getColor(i)); // Genera colores distintos
|
|
let ctx = document.getElementById('dbContacts');
|
|
|
|
// line
|
|
// gráfica de contactos
|
|
new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: labels_monthy,
|
|
datasets: [
|
|
{
|
|
label: labels_monthy,
|
|
data: values_monthy,
|
|
backgroundColor: colors_monthy,
|
|
borderWidth: 1
|
|
},
|
|
]
|
|
},
|
|
options: {
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true
|
|
}
|
|
},
|
|
responsive: true,
|
|
plugins: {
|
|
legend: {
|
|
position: 'top',
|
|
},
|
|
title: {
|
|
display: true,
|
|
text: 'Solicitudes de Contacto por Mes'
|
|
}
|
|
}
|
|
},
|
|
});
|
|
|
|
// gráfica de estados por solicitud
|
|
let states = data.count_state;
|
|
let lbl_state = states.map(e => `${acronym[e[0]]} [ ${e[2]}% ]`);
|
|
let val_state = states.map(e => e[1]);
|
|
let colors_state = states.map((_, i) => getColor(i)); // Genera colores distintos
|
|
let ctx2 = document.getElementById('dbEdos');
|
|
|
|
|
|
new Chart(ctx2, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: lbl_state,
|
|
datasets: [{
|
|
label: 'Contactos',
|
|
data: val_state,
|
|
backgroundColor: colors_state, // Color diferente por barra
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true
|
|
}
|
|
},
|
|
responsive: true,
|
|
plugins: {
|
|
legend: {
|
|
display: false // No es necesario si ya se diferencian por label
|
|
},
|
|
title: {
|
|
display: true,
|
|
text: 'Solicitudes Agrupadas por Estado'
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
// gráfica por tamaño de la empresa
|
|
let sizes = data.size_co;
|
|
let val_size = sizes.map(e => e[1]);
|
|
let total = val_size.reduce((acc, val) => acc + val, 0);
|
|
// let colors_sizes = sizes.map((_, i) => getColor(i));
|
|
// let lbl_size = sizes.map(e => `${e[0]} | x`);
|
|
|
|
let lbl_size = sizes.map(e => `${e[0]} [ ${(e[1] / total * 100).toFixed(1)}% ]` );
|
|
|
|
let ctx3 = document.getElementById('dbSize');
|
|
|
|
|
|
|
|
new Chart(ctx3, {
|
|
type: 'pie',
|
|
data: {
|
|
labels: lbl_size,
|
|
datasets: [{
|
|
label: 'Contactos',
|
|
data: val_size,
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
|
|
options: {
|
|
responsive: true,
|
|
plugins: {
|
|
legend: {
|
|
position: 'top',
|
|
},
|
|
title: {
|
|
display: true,
|
|
text: 'Solicitudes Agrupadas por Tamaño de la Empresa'
|
|
}
|
|
}
|
|
},
|
|
|
|
});
|
|
|
|
// agrupación por rol del contacto
|
|
let rol_contact = data.rol_contact;
|
|
let lbl_rol = rol_contact.map(e => `${e[0]} [ ${e[2]}% ]` );
|
|
let values_rol = rol_contact.map(e => e[1]);
|
|
let colors_rol = rol_contact.map((_, i) => getColor(i)); // Genera colores distintos
|
|
let ctx4 = document.getElementById('dbRol');
|
|
|
|
new Chart(ctx4, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: lbl_rol,
|
|
datasets: [{
|
|
label: 'Contactos',
|
|
data: values_rol,
|
|
backgroundColor: colors_rol,
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
indexAxis: 'y',
|
|
// Elements options apply to all of the options unless overridden in a dataset
|
|
// In this case, we are setting the border of each horizontal bar to be 2px wide
|
|
elements: {
|
|
bar: {
|
|
borderWidth: 2,
|
|
}
|
|
},
|
|
responsive: true,
|
|
plugins: {
|
|
legend: {
|
|
display: false // No es necesario si ya se diferencian por label
|
|
// position: 'right',
|
|
},
|
|
title: {
|
|
display: true,
|
|
text: 'Registros Agrupados por el Rol del Contacto'
|
|
}
|
|
}
|
|
},
|
|
})
|
|
|
|
// agrupación por el tipo de industria
|
|
let industry_type = data.industry_type;
|
|
let lbl_industry = industry_type.map(e => `${e[0]} [ ${e[2]}% ]` );
|
|
let val_indutry = industry_type.map(e => e[1]);
|
|
let colors_industry = industry_type.map((_, i) => getColor(i)); // Genera colores distintos
|
|
let ctx5 = document.getElementById("dbIndustry");
|
|
|
|
new Chart(ctx5, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: lbl_industry,
|
|
datasets: [{
|
|
label: 'Contactos',
|
|
data: val_indutry,
|
|
backgroundColor: colors_industry,
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
indexAxis: 'y',
|
|
// Elements options apply to all of the options unless overridden in a dataset
|
|
// In this case, we are setting the border of each horizontal bar to be 2px wide
|
|
elements: {
|
|
bar: {
|
|
borderWidth: 2,
|
|
}
|
|
},
|
|
responsive: true,
|
|
plugins: {
|
|
legend: {
|
|
display: false // No es necesario si ya se diferencian por label
|
|
// position: 'right',
|
|
},
|
|
title: {
|
|
display: true,
|
|
text: 'Registros Agrupados por Tipo de Industria'
|
|
}
|
|
}
|
|
},
|
|
})
|
|
|
|
// agrupación por el estatus del contacto
|
|
let group_status = data.group_status;
|
|
let lbl_status = group_status.map(e => `${e[0]} [ ${e[2]}% ]` );
|
|
let val_status = group_status.map(e => e[1]);
|
|
let colors_status = states.map((_, i) => getColor(i)); // Genera colores distintos
|
|
let ctx6 = document.getElementById("dbStatus");
|
|
|
|
new Chart(ctx6, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: lbl_status,
|
|
datasets: [{
|
|
label: 'Agrupación por Estatus',
|
|
data: val_status,
|
|
backgroundColor: colors_status,
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// dbTopTenPosts
|
|
let top_ten = data.top_ten;
|
|
let lbl_top_ten = top_ten.map(e => `${e[0]}`);
|
|
let val_top_ten = top_ten.map(e => e[1]);
|
|
let colors_top_ten = top_ten.map((_, i) => getColor(i));
|
|
let ctx7 = document.getElementById("dbTopTenPosts");
|
|
|
|
new Chart(ctx7, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: lbl_top_ten,
|
|
datasets: [{
|
|
label: 'Visto',
|
|
data: val_top_ten,
|
|
backgroundColor: colors_top_ten,
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
indexAxis: 'x',
|
|
elements: {
|
|
bar: {
|
|
borderWidth: 2,
|
|
cursor: 'pointer' // Cursor de pointer para indicar interactividad
|
|
}
|
|
},
|
|
responsive: true,
|
|
onClick: (evt, elements) => { // Moved to root options
|
|
if (elements.length > 0) {
|
|
const index = elements[0].index;
|
|
const id = top_ten[index][0];
|
|
let dinamic_url = window.location.origin + `/blog/${id}`;
|
|
window.open(dinamic_url, '_blank');
|
|
}
|
|
},
|
|
plugins: {
|
|
tooltip: {
|
|
callbacks: {
|
|
label: function (tooltipItem) {
|
|
return tooltipItem.dataset.label + ': ' + tooltipItem.raw;
|
|
}
|
|
}
|
|
},
|
|
legend: {
|
|
display: false
|
|
},
|
|
title: {
|
|
display: true,
|
|
text: 'Top 10 de posts más vistos'
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// dbTop3Autores dbTop3Autores
|
|
let top_3 = data.top_three_authors;
|
|
console.log(top_3);
|
|
let lbl_top_3 = top_3.map(e => `${e[0]}`);
|
|
let val_top_3 = top_3.map(e => e[1]);
|
|
let colors_top_3 = top_3.map((_, i) => getColor(i));
|
|
let ctx8 = document.getElementById("dbTop3Autores");
|
|
new Chart(ctx8, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: lbl_top_3,
|
|
datasets: [{
|
|
label: 'Visto',
|
|
data: val_top_3,
|
|
backgroundColor: colors_top_3,
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
indexAxis: 'x',
|
|
elements: {
|
|
bar: {
|
|
borderWidth: 2,
|
|
cursor: 'pointer' // Cursor de pointer para indicar interactividad
|
|
}
|
|
},
|
|
responsive: true,
|
|
plugins: {
|
|
tooltip: {
|
|
callbacks: {
|
|
label: function (tooltipItem) {
|
|
return tooltipItem.dataset.label + ': ' + tooltipItem.raw;
|
|
}
|
|
}
|
|
},
|
|
legend: {
|
|
display: false
|
|
},
|
|
title: {
|
|
display: true,
|
|
text: 'Top 3 de autores más vistos'
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
})
|
|
</script>
|
|
{% endblock js %} |