ASP.NET MVC 3 MSChart Error: Only 1 Y values can b

2019-01-27 01:37发布

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?

4条回答
何必那么认真
2楼-- · 2019-01-27 01:59

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");
查看更多
神经病院院长
3楼-- · 2019-01-27 02:10

Well, actually the easiest way is just change it to:

yFields: "Open,,High,,Low,,Close",
查看更多
太酷不给撩
4楼-- · 2019-01-27 02:12

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.

查看更多
祖国的老花朵
5楼-- · 2019-01-27 02:13

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);
查看更多
登录 后发表回答