Siguiendo con la entrada anterior, supongamos ahora que queremos actualizar los datos de la página en función de, por ejemplo, que se seleccione un rango de fechas u otro. Y clara está, esta actualización queremos hacerla sin tener que recargar la página, es decir, mediante AJAX. Tendremos que hacer las siguientes modificaciones:
- Nueva función TopMarcasJson en el controlador VentasController que retorne un objeto de tipo JsonResult que será consumido directamente por la función $.plot desde la vista
- Modificar la función Top del controlador VentasController para que pase la colección TopMarcas a la vista (será la vista la que vaya a buscar los datos del modelo con la función anterior).
- Modificar la vista Ventas/Top para que la función $.plot tome los datos mediante AJAX.
Nueva función TopMarcasJson en VentasController
/// <summary>
/// Retorna JSON que se consume mediante AJAX desde la función $.plot de la vista Ventas/Top
/// </summary>
/// <returns></returns>
[HttpGet]
public JsonResult TopMarcasJson(int año)
{
var currentUserId = User.Identity.GetUserId();
var currentUser = _userManager.FindById(User.Identity.GetUserId());
var currentUserZonas = currentUser.Zonas.Select(z => z.ZonaId);
var ventasPorMarca = _ctx.Ventas
.Where(v => v.Año == año)
.Where(v => currentUserZonas.Contains(v.Zona)) // Incluir sólo los de las zonas del comercial logado
.GroupBy(v => v.Marca)
.Select(v => new VentaMarcaViewModel()
{
Marca = v.FirstOrDefault().Marca,
Gama = v.FirstOrDefault().Gama,
Importe = v.Sum(g => g.Importe),
Cantidad = v.Sum(g => g.Cantidad)
})
.OrderByDescending(c => c.Importe);
// Top 10 ventas por marca
var topVentasPorMarca = ventasPorMarca
.Take(10) // Top 10
.ToList();
// Resto: consolidar como uno sólo
var restoTopVentasPorMarca = ventasPorMarca
.Skip(10)
.Select(v => new { Marca = "Resto", v.Importe, v.Cantidad })
.GroupBy(v => v.Marca) // Agrupar el resto
.Select(v => new VentaMarcaViewModel()
{
Marca = "Resto",
Gama = "",
Importe = v.Sum(g => g.Importe),
Cantidad = v.Sum(g => g.Cantidad)
})
.ToList() // Lista con un único el elemento, el consolidado
.FirstOrDefault(); // Coge el primer (y único elemento).
// Añadir a top ventas el consolidado con el resto.
if (restoTopVentasPorMarca != null)
topVentasPorMarca.Add(restoTopVentasPorMarca);
// Convertir a Json de tipo array de {label, data}
return Json(
topVentasPorMarca.Select(v => new { label = v.Marca, data = v.Importe }),
JsonRequestBehavior.AllowGet
);
}
Modificar la función Top de VentasController
Ya no hará falta pasar la colección TopMarcas desde esta función, por lo que podemos suprimir el fragmento de código que hace referencia a eso y retornar la vista vacía (sin modelo).
Modificar script de la vista Ventas/Top
Debemos sustituir el fragmento bajo /** Recoger datos y dibujar **/ por el nuevo:
function drawPieChart(placeholder, data0, position) {
$.getJSON("TopMarcasJson", function (data) {
//succes - data loaded, now use plot:
$.plot(placeholder, data, {
series: {
pie: {
show: true,
tilt: 0.8,
highlight: {
opacity: 0.25
},
stroke: {
color: '#fff',
width: 2
},
startAngle: 2
}
},
legend: {
show: true,
position: position || "ne",
labelBoxBorderColor: null,
margin: [-30, 15]
},
grid: {
hoverable: true,
clickable: true
}
})
});
}
drawPieChart(placeholder);
Obsérvese cómo se llama a la función $.getJSON y el retorno obtenido se le pasa a $.plot.
No hay comentarios:
Publicar un comentario