另一种方法是使用图像标签上的base64编码源代码将图表直接嵌入HTML(通过
src=data:image/base64
);这还有一个优点,即不需要任何进一步的HTTP请求来从Web服务器获取图像。
例如
<img src='data:image/png;base64,src='data:image/png;base64,[base64data==]'>
要做到这一点,需要做很多事情。
用于获取作为操作结果的图像数据的控制器:
public ActionResult SomeChart(SomeViewModel model, int width, int height)
{
model.ChartKey = "SomeChart";
return Content(getChartImage(() => CreateSomeChart(model, width, height), model, width, height));
}
这将使用如下方法创建图表:
private Chart CreateSomeChart(SomeViewModel vm, int width, int height)
{
int Id = vm.Id;
System.Web.UI.DataVisualization.Charting.Chart Chart1 = new System.Web.UI.DataVisualization.Charting.Chart();
// usual code to draw a chart here...
return Chart1;
}
在Razor视图中编写代码以获取图表;在我的视图模型中,我有一个图表列表,这些图表只是要呈现的控制器中的操作结果方法。使用呈现操作将在HTML发送到浏览器并导致图表以base64编码方式内联之前发生。
它是
public ActionResult SomeChart
应该由html.renderAction方法调用的控制器,对于此示例model.chartList[]=“someChart”
if (Model.ChartList.Count() > 1)
{
xs = 450;
ys = 300;
}
foreach(var chart in Model.ChartList)
{
Html.RenderAction(chart, "SomeController", new { model = Model, width = xs, height = ys });
}
最后一个将它联系在一起的位是getchartimage方法。
private string getChartImage(Func<Chart> getChart, object routevals, int width, int height, string chartKey="")
{
string name = "Chart";
if (routevals is SomeViewModel)
{
var cvm = routevals as SomeViewModel;
chartKey = cvm.ChartKey;
name = cvm.ChartKey;
}
using (var stream = new MemoryStream())
{
var Chart1 = getChart();
Chart1.ImageType = ChartImageType.Png;
Chart1.Palette = ChartColorPalette.BrightPastel;
Chart1.SuppressExceptions = true;
// Set chart custom palette
Chart1.Palette = ChartColorPalette.None;
Chart1.PaletteCustomColors = Dashboard.Support.ChartPalettes.ColorsBigList;
Chart1.Width = width;
Chart1.Height = height;
Chart1.RenderType = RenderType.ImageTag;
Chart1.BackColor = Color.White;
Chart1.BackImageAlignment = ChartImageAlignmentStyle.BottomLeft;
Chart1.BorderSkin.SkinStyle = BorderSkinStyle.None;
Chart1.BorderSkin.BorderWidth = 0;
//Chart1.BackImageTransparentColor
Chart1.BorderColor = System.Drawing.Color.FromArgb(26, 59, 105);
Chart1.BorderlineDashStyle = ChartDashStyle.Solid;
Chart1.BorderWidth = 0;
Chart1.SaveImage(stream, ChartImageFormat.Png);
string encoded = Convert.ToBase64String(stream.ToArray());
if (Request != null && Request.Browser != null && Request.Browser.Browser == "IE" && Request.Browser.MajorVersion <= 8)
{
/*
* IE8 can only handle 32k of data inline so do it via the cached getChart
* method - i.e. store the chart in the cache and return a normal image.
*/
if (encoded.Length > 32000)
{
StringBuilder result = new StringBuilder();
if (string.IsNullOrEmpty(chartKey))
chartKey = String.Format("{0}{1}", name, Guid.NewGuid());
System.Web.Helpers.WebCache.Set(chartKey, stream.ToArray());
result.Append(String.Format("<img width='{0}' height='{1}' src='{3}' alt='' usemap='#ImageMap{2}'>", width, height, name,
Url.Action("getChart", new { key = chartKey })));
return result.ToString() + Chart1.GetHtmlImageMap("ImageMap" + name); ;
}
}
/*
* render using data inline for speed
*/
string img = String.Format("<img width='{0}' height='{1}' src='data:image/png;base64,{{0}}' alt='' usemap='#ImageMap{2}'>", Chart1.Width, Chart1.Height, name);
return String.Format(img, encoded) + Chart1.GetHtmlImageMap("ImageMap" + name);
}
}