我有一个MVC应用程序,它在业务逻辑中创建一个Chart,如下所示:
StatisticsModel.Chart.Width = 150
StatisticsModel.Chart.Height = 300
StatisticsModel.Chart.Attributes.Add("align", "left")
StatisticsModel.Chart.Titles.Add("Statistics for: " + StatisticsModel.ProductNumbers)
StatisticsModel.Chart.ChartAreas.Add(New ChartArea)
StatisticsModel.Chart.Series.Add(New Series)
StatisticsModel.Chart.Series(0).ChartType = SeriesChartType.Column
StatisticsModel.Chart.Series(0).Points.DataBindXY(StatisticsModel.FailedTPDescriptionList, "key", StatisticsModel.FailedTPDescriptionList, "value")
现在,我正在尝试在View中实现它,但我已阅读了很多文章,他们建议我将图表放在不同的控制器中。但这意味着我必须在那里发送Chart对象,因为我有很多函数需要图表,我认为最简单的方法是在模型中实现它,然后从那里渲染它。
我尝试使用:http://code-inside.de/blog-in/2008/11/27/howto-use-the-new-aspnet-chart-controls-with-aspnet-mvc/
但是:
@Code
Dim writer As New HtmlTextWriter(Page.Response.Output)
End Code
对我不起作用。我正在使用VB.NET
任何人都可以帮助我吗?建议非常欢迎。
答案 0 :(得分:2)
在MVC中创建和显示图表有很多种方法,你提到的链接是相当不错的恕我直言。我正在使用c#,但我这样做的方法是在视图中使用img-tag并将src-attribute指向Controller操作:
<img id="diagram" src="<%=Url.Action("DrawChartImage", "Home") %>" alt="Chart Diagram" />
控制器操作返回FileContentResult:
public ActionResult DrawChartImage()
{
using (var chartHelper = new ChartHelper())
{
//get data
var data = GetSomeDataForTheChart();
//draw chart
chartHelper.Draw(data);
//return chart as png image
return File(chartHelper.Image, "image/png");
}
}
ChartHelper类实现了IDisposable并且有一个帮助器属性(Image),它将图表作为文件返回,注意这只是示例/代码片段来显示我的意思:
public class ChartHelper : IDisposable
{
private readonly Chart _chart;
public Chart Chart
{
get
{
return _chart;
}
}
public byte[] Image
{
get
{
using (var ms = new MemoryStream())
{
_chart.SaveImage(ms);
return ms.GetBuffer();
}
}
}
public ChartHelper()
{
_chart = new Chart();
_chart.Height = 300;
_chart.Width = 800;
_chart.ImageType = ChartImageType.Png;
_chart.Titles.Add("some title");
_chart.Legends.Add("some legend");
_chart.ChartAreas.Add("some chart area");
}
public void Draw(List<Data> data)
{
var dataArrays = GetDataArrays(data); //another helper method...
var series = new Series(tag);
series.Name = tag;
series.Legend = "tags";
series.ChartType = SeriesChartType.Spline;
series.BorderWidth = 4;
//sample way to add data below...
series.Points.DataBindXY(dataArrays.Item1, dataArrays.Item2);
_chart.Series.Add(series);
}
public void Dispose()
{
_chart.Dispose();
}
}
对我来说效果很好,希望即使它在C#中也有帮助。
编辑如果您想要在“主”控制器操作中调用业务逻辑中创建图像/图表,也许您可以在生成图像/图表的位置执行此操作,然后将其保存到磁盘,缓存或数据库,并从图像渲染控制器操作中选择它:
public ActionResult Index()
{
//this is call to your business logic or similar which generates the chart
byte[] image = GenerateImage();
//save image to cache, disk or from database
HttpContext.Cache["image"] = image;
return View();
}
public ActionResult Image()
{
//get image from cache, disk or from database
var image = HttpContext.Cache["image"] as byte[];
return File(image, "image/png");
}
//some sample/dummy code to generate image from a template
private byte[] GenerateImage()
{
using (var ms = new MemoryStream())
{
using (var image = System.Drawing.Image.FromFile(@"c:/temp/template.png"))
using (var brush = new SolidBrush(System.Drawing.Color.Black))
using (var bmp = new System.Drawing.Bitmap(image, image.Width, image.Height))
using (var g = System.Drawing.Graphics.FromImage(bmp))
{
g.DrawString(DateTime.Now.ToLongTimeString(), new Font("Consolas", 10), brush, 10, 10);
bmp.Save(ms, ImageFormat.Png);
}
return ms.ToArray();
}
}
视图将是:
<img src="@Url.Action("Image")"/>