I'm attempting to build a stock chart using Microsoft's charting library.
I'm using this code to create the chart in my view:
@{
System.Web.Helpers.Chart cht = new Chart(600, 400);
cht.AddTitle(ViewData["Symbol"].ToString());
cht.AddSeries(name: "Price",
chartType: "Stock",
chartArea: "Top",
xField: "Date",
xValue: Model,
yFields: "Open,High,Low,Close",
yValues: Model);
cht.Write();
}
When the action to get the chart is invoked, the following exception is thrown:
ArgumentOutOfRangeException: Data points insertion error. Only 1 Y values can be set for this data series.
Parameter name: yFields
System.Web.UI.DataVisualization.Charting.DataPointCollection.DataBindXY(IEnumerable xValue, String xField, IEnumerable yValue, String yFields) +1076598
System.Web.Helpers.Chart.ApplySeries(Chart chart) +508
System.Web.Helpers.Chart.ExecuteChartAction(Action`1 action) +174
System.Web.Helpers.Chart.GetBytes(String format) +144
System.Web.Helpers.Chart.Write(String format) +96
The "Stock" chartType should allow 4 values for Y, and this appears to be confirmed when using reflector to inspect the Chart helper's code. Am I missing something?
I was able to work around this issue by building the chart myself, bypassing the helper.
using (Chart chart = new Chart())
{
chart.Width = 600;
chart.Height = 400;
chart.RenderType = RenderType.BinaryStreaming;
chart.Palette = ChartColorPalette.Bright;
chart.ChartAreas.Add("Top");
chart.ChartAreas.Add("Bottom");
chart.Series.Add("Price");
chart.Series.Add("Volume");
chart.Series["Price"].ChartArea = "Top";
chart.Series["Volume"].ChartArea = "Bottom";
chart.Series["Price"].ChartType = SeriesChartType.Stock;
chart.Series["Volume"].ChartType = SeriesChartType.Column;
for (int x = 0; x < data.Quotes.Count / 2; x++)
{
Quote quote = data.Quotes[x];
chart.Series["Price"].Points.AddXY(quote.Date, quote.Open, quote.High, quote.Low, quote.Close);
chart.Series["Volume"].Points.AddXY(quote.Date, quote.Volume);
}
using (MemoryStream memStream = new MemoryStream())
{
chart.SaveImage(memStream, ChartImageFormat.Jpeg);
return File(memStream.ToArray(), "image/jpeg");
}
}
This code is in my controller, and no view exists for it, because it is returning an actual image resource.
Well, actually the easiest way is just change it to:
yFields: "Open,,High,,Low,,Close",
I fixed this by using the overloaded Series constructor: Series(string name, int yValues)
. See the example below.
Series ohlc = new Series("Ohlc", 4);
...
ohlc.Points.AddXY(xValue, open, high, low, close);
After dealing with the same issue - only being able to add one value to a series - while trying to build a Stacked Column chart with multiple Y axis values - using the Web.Helper.Chart class.
I did not find the one answer anywhere on MSDN or any other forum including StackOverflow. Turns out - it is quite simple: You can add more than one series with the .AddSeries method.
In other words, in plain English, call the .AddSeries method once for each series you want to add to the chart.
This example was used to report daily inventory which is measured in tons, as it would be at a steel plant - production measured in tons of steel in inventory.
new Chart(1000, 500, ChartTheme.Blue)
.AddTitle("Inventory")
.AddSeries(name: "A",
chartType: "StackedColumn",
xValue: intDays,
yValues: dblTons_A)
.AddSeries(name: "B",
chartType: "StackedColumn",
xValue: intDays,
yValues: dblTons_B)
.AddSeries(name: "C",
chartType: "StackedColumn",
xValue: intDays,
yValues: dblTons_C)
.AddSeries(name: "D",
chartType: "StackedColumn",
xValue: intDays,
yValues: dblTons_D)
.Write("png");