Använd ASP.NET Chart med ASP.NET MVC
I .NET 4.0 så ingår webbkontroller för att skapa diagram (så kallade ”charts”) med bland annat ASP.NET. Då det är vanliga webbkontroller så innebär det att de är anpassade för web forms, men de går faktiskt utmärkt att använda för ASP.NET MVC.
Innan vi lägger till diagrammen så börjar vi med att skapa ett ASP.NET MVC-projekt med en ny modell kallad Article. Den har två properties, Name och Category.
Utseendet på den klassen ser ut så här:
namespace MvcChart.Models
{
public class Article
{
public string Name { get; set; }
public string Category { get; set; }
}
}
Vi skapar även en ny ActionResult-metod i HomeController som fyller denna med dummy-data, samt skapar en vy för denna som listar upp datan.
public ActionResult Articles()
{
List<Article> articles = new List<Article>()
{
new Article() { Name = "Artikel 1", Category = "Äpplen" },
new Article() { Name = "Artikel 2", Category = "Äpplen" },
new Article() { Name = "Artikel 3", Category = "Äpplen" },
new Article() { Name = "Artikel 4", Category = "Päron" },
new Article() { Name = "Artikel 5", Category = "Päron" },
new Article() { Name = "Artikel 6", Category = "Bananer" }
};
return View(articles);
}
Om vi kikar på /Home/Articles så får vi nu upp en tabell med namnen på artiklarna samt vilken kategori de tillhör. Vi kan dock ej på ett enkelt sätt se hur många artiklar det finns i varje kategori, så där kan vi ha ett diagram som gör det åt oss.
Diagrammet kommer att finnas under en ny controller kallad ChartController. Här har vi en metod kallad Articles(). I denna controllern skapar vi ett diagram som returneras direkt till vyn som en png-bild.
Chart-funktionaliteten som vi vill åt ligger under System.Web.UI.DataVisualization.Charting, vilket i sin tur ligger i System.Web.DataVisualization.dll. Vi måste skapa en referens till den dll:en i Visual Studio då den inte ingår som standard i projekten. Den finns dock med bland listan med assemblies i GAC:n.
Den fullständiga koden för att returnera diagrammet med samma dummy-data som vi hade i den andra controllern ser ut så här:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using System.Web.UI.DataVisualization.Charting;
using MvcChart.Models;
namespace MvcChart.Controllers
{
public class ChartController : Controller
{
public ActionResult Articles()
{
//Skapa några artiklar
List<Article> articles = new List<Article>()
{
new Article() { Name = "Artikel 1", Category = "Äpplen" },
new Article() { Name = "Artikel 2", Category = "Äpplen" },
new Article() { Name = "Artikel 3", Category = "Äpplen" },
new Article() { Name = "Artikel 4", Category = "Päron" },
new Article() { Name = "Artikel 5", Category = "Päron" },
new Article() { Name = "Artikel 6", Category = "Bananer" }
};
//Skapa en chart
Chart chart = new Chart()
{
Height = 300,
Width = 300,
ImageType = ChartImageType.Png
};
//Visa som 3D
ChartArea chartArea = chart.ChartAreas.Add("Categories");
chartArea.Area3DStyle.Enable3D = true;
//Skapa en serie med grupperna
Series categories = chart.Series.Add("Categories");
categories.ChartType = SeriesChartType.Doughnut;
//Gruppera per CategoryId
IEnumerable<IGrouping<string, Article>> catgroup = articles.GroupBy(a => a.Category);
//Lägg till en ny DataPoint för varje kategori
foreach (IGrouping<string, Article> item in catgroup)
{
categories.Points.Add(new DataPoint()
{
Label = String.Format("{0} ({1})", item.Key, item.Count()),
YValues = new Double[] { item.Count() }
});
}
//Spara ned bilden i en memorystream
MemoryStream ms = new MemoryStream();
chart.SaveImage(ms);
//Returnera bilden direkt till vyn
return File(ms.GetBuffer(), "image/png");
}
}
}
Det första som händer här är att dummydatan skapas upp och läggs i en lista. Sedan skapar vi en instans av Chart, vilket är klassen som används för de olika typerna av diagram. Vi anger även storlek på denna och säger att det ska bli en png-bild.
Nästa steg blir att skapa en ChartArea så att vi kan sätta inställningar för diagrammet. Det enda vi gör här är att sätta det som 3D för att det skall bli snyggare. Det finns även många andra inställningar man kan göra.
Efter det så skapar vi en serie. En serie är en samling data som skall visas upp på ett diagram. Man kan ha flera serier på samma diagram, vilka då visas på samma bild. Just den här serien skall vara av typen ”Doughnut”.
Sedan så grupperar vi alla artiklar efter kategori och lägger till en DataPoint för var och ett. En DataPoint är ett enskilt värde i diagrammet. Vi sätter även en Label på dessa för att kunna se vilken kategori det gäller, samt hur många artiklar det finns för den.
Det sista som händer är att vi sparar ned diagrammet i en memorystream som sedan returneras direkt till sidan som en png-bild.
Om vi surfar direkt till /Chart/Articles nu så får vi upp den här bilden:
Vi kan enkelt se att t.ex. hälften av alla artiklar (tre stycken) ligger i kategorin ”Äpplen”.
De går även att använda andra typer av diagram, så genom att byta ut Doughnut mot Pyramid så kan vi få det här:
Och väljer vi Bar så får vi det här:
Det finns väldigt många olika typer av diagram samt många olika sätt att påverka utseendet på, så för en bra genomgång av detta så rekommenderar jag en titt på exempelsidan som man kan ladda ned här:
http://code.msdn.microsoft.com/mschart/Release/ProjectReleases.aspx?ReleaseId=1591
Samt dokumentationen som finns här:
Då grafen är en vanlig vy så fungerar routing för den precis som för allt annat. Vi kan gå tillbaka till Articles-vyn som vi skapade för HomeControllern och lägga till det här:
<img src="<%=Url.Action("Articles", "Chart") %>" alt="Diagram över artiklar" />
Om vi nu går in på /Home/Articles så ser sidan ut så här:
För att bygga vidare på den här funktionaliteten så skulle man t.ex. kunna göra det möjligt att skicka in variabler till sina ActionResult-metoder i ChartController och därmed göra diagrammen ännu mer dynamiska.