Telerik has a lot of really nice asp.net controlls, howevery i douby very many of them will work with the mvc framework. One of the nicest controlls is RadChart, that makes charts, and accordint to http://www.telerik.com/community/forums/thread/b311D-badtea.aspx#534484 easy to get to work.
Inspired by http://blog.maartenballiauw.be/category/ASPNET.aspx i wanted to make a more elegant approach, with an action rendering a chart without saving it to disk.
To use an action to render a image, we need to make an url to it. We create a helper extension to help us with that.
public static class ChartResultHelper
{
public static string Chart<T>(this HtmlHelper helper, System.Linq.Expressions.Expression<Action<T>> action, int width, int height, string alt)
where T : Controller
{
string url = helper.BuildUrlFromExpression<T>(action);
return string.Format("<img src=\"{0}\" width=\"{1}\" height=\"{2}\" alt=\"{3}\" />", url, width, height, alt);
}
}
and use it in a regular viewpage
<%= Html.Chart<ReportController>(c => c.Chart(1, 200, 483), 200,483, "Report")%>
Ofcourse some of this could be a parameterized better but shows the point. As you may see, i have mapped this image to the action chart in report controller, lets look at that.
public ActionResult Chart(long id, int h, int w)
{
Telerik.WebControls.RadChart objChart = new Telerik.WebControls.RadChart();
// the data we want to chart
Dictionary<string, double> objValues = new Dictionary<string, double>();
objValues.Add("Svar på foruminnlegg", 4);
objValues.Add("Nye tråder", 100);
objValues.Add("Bilder i foruminnlegg", 20);
// setting some chart parameters
objChart.Height = h;
objChart.Width = w;
objChart.Margins.Right = new Unit(30, UnitType.Percentage);
objChart.Margins.Bottom = new Unit(1, UnitType.Percentage);
objChart.Margins.Left = new Unit(1, UnitType.Percentage);
objChart.Margins.Top = new Unit(1, UnitType.Percentage);
objChart.Background.MainColor = Color.White;
objChart.Background.BorderColor = Color.White;
// creating a series and adding it to the chart
ChartSeries cSeries = new ChartSeries();
cSeries.Name = "Poeng";
cSeries.Type = ChartSeriesType.Pie;
cSeries.LegendDisplayMode = ChartSeriesLegendDisplayMode.ItemLabels;
String[] colorArray = new String[7] { "#00839C", "#E15D1F", "#2AB1C4", "#FFAB13", "#D0FAFF", "#CF8300", "#397BB2" };
int k = 0;
foreach (var entry in objValues)
{
cSeries.Items.Add(new ChartSeriesItem() {Name = entry.Key, YValue = entry.Value, MainColor = ColorTranslator.FromHtml(colorArray[k]) });
k++;
}
objChart.Series.Add(cSeries);
// send the chart to the view engine
return new ChartResult() { Chart = objChart };
}
Looks easy enough, just need to create the view engine part of the soulution.
public class ChartResult : ActionResult
{
public Telerik.WebControls.RadChart Chart { get; set; }
public override void ExecuteResult(ControllerContext context)
{
if (Chart == null)
{
throw new ArgumentNullException("Chart");
}
Image image = Chart.GetBitmap();
ImageCodecInfo encoder;
EncoderParameters encoderParams = null;
context.HttpContext.Response.ExpiresAbsolute = DateTime.Now.AddMinutes(5);
encoder = ImageCodecInfo.GetImageEncoders().Single(c => c.FormatID == ImageFormat.Jpeg.Guid);
encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
context.HttpContext.Response.ContentType = encoder.MimeType;
image.Save(context.HttpContext.Response.OutputStream, encoder, encoderParams);
}
}
1 comment:
your site is very nice ...
this is very helpful and attractive.
visit for asp.net help asp.net help
Post a Comment