Search code examples
c#visualizationdotnetcharting

Why does this code throw ' Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index' exception?


I have a WinForm (let's call it Form2) with the following code to generate a chart:

public void InitializeChartEKG() 
{
    Chart chartEKG = new Chart();

    Series series1 = new Series 
           {
                Color = Color.LawnGreen,
                IsVisibleInLegend = false,
                IsXValueIndexed = true,
                ChartType = SeriesChartType.FastLine
            };

    chartEKG.Series.Clear();
    chartEKG.Series.Add(series1);

    chartEKG.ChartAreas[0].AxisX.Title = "Time";
    chartEKG.ChartAreas[0].AxisX.MajorTickMark.Enabled = true;
    chartEKG.ChartAreas[0].AxisX.MinorTickMark.Enabled = true;
    chartEKG.ChartAreas[0].AxisX.IsStartedFromZero = true;

    chartEKG.ChartAreas[0].CursorX.LineColor = Color.LawnGreen;
    chartEKG.ChartAreas[0].CursorY.LineColor = Color.LawnGreen;

    chartEKG.ChartAreas[0].AxisX.MajorGrid.Enabled = true;
    chartEKG.ChartAreas[0].AxisX.MajorGrid.Interval = 100;
    chartEKG.ChartAreas[0].AxisX.IsStartedFromZero = true;
    chartEKG.ChartAreas[0].AxisX.MajorTickMark.Enabled = true;
    chartEKG.ChartAreas[0].AxisX.Minimum = 0;

    chartEKG.ChartAreas[0].AxisY.Maximum = 1000;
    chartEKG.ChartAreas[0].AxisY.Minimum = -600;
    chartEKG.ChartAreas[0].AxisX.Interval = 10000;
    chartEKG.ChartAreas[0].AxisY.Title = "mV";

    chartEKG.Series[0].XValueType = ChartValueType.DateTime;
    chartEKG.Series[0].YValueType = ChartValueType.Int32;

    chartEKG.ChartAreas[0].AxisX.IntervalType = DateTimeIntervalType.Auto;
    chartEKG.ChartAreas[0].AxisX.LabelStyle.IntervalType = DateTimeIntervalType.Auto;
    chartEKG.ChartAreas[0].AxisX.LabelStyle.Format = "HH:mm:ss tt";

    chartArea = chartEKG.ChartAreas[0];

    chartArea.AxisX.ScaleView.SizeType = DateTimeIntervalType.Auto;

    int position = 0;
    int blockSize = 10000;
    int size = blockSize;
    chartArea.AxisX.ScaleView.Zoom(position, size);
    // chartArea.AxisX.ScaleView.Zoom(200, 200);
    chartEKG.ChartAreas[0].AxisX.ScaleView.Position = chartEKG.ChartAreas[0].AxisX.Maximum;
    chartArea.AxisX.ScaleView.SmallScrollSize = blockSize;
    chartArea.CursorX.AutoScroll = true;
    chartArea.AxisX.ScrollBar.BackColor = Color.LightGray;
    chartArea.AxisX.ScrollBar.ButtonColor = Color.LightSteelBlue;
    chartArea.AxisX.ScrollBar.LineColor = Color.DarkBlue;
    chartArea.AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
    chartArea.AxisX.ScrollBar.Size = 20;

    CultureInfo culture = new CultureInfo("en-US");
}

This works fine on that form. What I do on that form is generate a chart then save it as an image to import into an iTextSharp pdf.

But this is no bueno because the user has to know that they have to open Form2 from it's parent form (Form1) in order to have it generate the image which will then show up in the pdf which they access from Form1.

So, to avoid confusing the user I want to programmatically parse the points in the chart series and output the chart to an image file that is then imported into the iTextSharp pdf on Form1. Something like the following:

        chartEKG2.Series["ChartEKG2"].Points.DataBindXY(xValues, yValues);
        chartEKG2.Width = 600; 
        chartEKG2.Height = 200; 
        string path;
        Assembly assembly = Assembly.GetExecutingAssembly();
        path = assembly.Location.ToString();
        path = System.IO.Path.GetDirectoryName(path) + "\\EKG.png";
        chartEKG2.SaveImage(path, ChartImageFormat.Png);

But when I try to create the chart on Form1, I get

Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index' on this line:

chartEKG.ChartAreas[0].AxisX.Title = "Time";

I can't figure out why?


Solution

  • Right now you have no chart areas in your chart, so it throws the exception when accessing the zero index [0]. Just like how you did it for series in InitializeChartEKG(), you need to initialize and add your ChartAreas to your chart like:

    ChartArea chartArea = new ChartArea {
      // Initialize your properties here if you want, or just use new ChartArea();
    }
    
    chartEKG.ChartAreas.Add(chartArea);