0

I'm trying to make a Zoom Out Function for my mschart chart. My idea is to have a click method for the chart and each time the chart is clicked with the right mouse button the zoom value should change. Therefore the chart should response and have room for more values. I’ve made 4 zoom steps: 240 values, 3600 values, 43’200 values, 86’400. The chart click methodic looks like this:

void chart_holder_Click(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            if (counter < 3)
            {
                counter++;
            }
            else
            {
                counter = 0;
            }

            switch (counter)
            {
                default:
                    //zoomsize -> 240s | 4min
                    zoomSize = 0;
                    graphSizing = 240;
                    TempBuffer = new DataPoint[graphSizing];
                    file = new DataPoint[graphSizing];
                    TempbufferValuesTOZero();
                    FileValuesTOZero();
                    break;

                case 0:
                    //zoomsize -> 240s | 4min
                    zoomSize = 0;
                    graphSizing = 240;
                    TempBuffer = new DataPoint[graphSizing];
                    file = new DataPoint[graphSizing];
                    TempbufferValuesTOZero();
                    FileValuesTOZero();
                    break;
                case 1:
                    //zoomsize -> 3'600s | 1h
                    zoomSize = 1;
                    graphSizing = 3600;
                    TempBuffer = new DataPoint[graphSizing];
                    file = new DataPoint[graphSizing];
                    TempbufferValuesTOZero();
                    FileValuesTOZero();
                    break;

                case 2:
                    //zoomsize -> 43'200s | 12h
                    zoomSize = 2;
                    graphSizing = 43200;
                    TempBuffer = new DataPoint[graphSizing];
                    file = new DataPoint[graphSizing];
                    TempbufferValuesTOZero();
                    FileValuesTOZero();
                    break;

                case 3:
                    //zoomsize -> 86'400s | 24h
                    zoomSize = 3;
                    graphSizing = 86400;
                    TempBuffer = new DataPoint[graphSizing];
                    file = new DataPoint[graphSizing];
                    TempbufferValuesTOZero();
                    FileValuesTOZero();
                    break;
            }
        }
    }

The AxisX.Maximum is defined with the property public static int graphSizing { get; set; }. The chart that I’ve got is a real time chart, so each second there are new values being added etc. TempbufferValuesTOZero, FileValuesTOZero fills the whole array with 0/0.

Before I add the values to the chart I prepare them in this method: I got a switch statement that checks the zoomSize to know how to prepare the Data

public void prepareData()
        {
            switch (zoomSize)
            {
                default:
                    prepData1();
                    break;

                case 0:
                    prepData1();
                    break;

                case 1:
                    prepData2();
                    break;

                case 2:
                    prepData3();
                    break;

                case 3:
                    prepData4();
                    break;
            }
        }

example how its prepared

public void prepData1()
    {
        graphSizing = 240;
        Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;

        for (double i = unixTimestamp; unixTimestamp - graphSizing < i; i--)
        {
            bool exists = true;
            DateTime x = UnixTODateTime(i);

            if (exists != (Array.Exists(file, element => element.XValue == i)))
            {
                TempBuffer = TempBuffer.Skip(1).Concat(new DataPoint[] { new DataPoint(x.ToOADate(), 0) }).ToArray();
            }
            else
            {
                DataPoint point = Array.Find(file, element => element.XValue == i);
                TempBuffer = TempBuffer.Skip(1).Concat(new DataPoint[] { new DataPoint(x.ToOADate(), point.YValues) }).ToArray();
            }
        }
    }

After that this method is called to display the values in the chart:

public void fileRead()
        {
            chart_holder.Series[0].Points.Clear();

            foreach (DataPoint a in TempBuffer)
            {
                chart_holder.Series[0].Points.Add(a);
                if (a.YValues[0] == 9999)
                {
                    a.Color = Color.Red;
                }
            }
        }

TempBuffer is an DataPoint Array where I store the values (public DataPoint[] TempBuffer = new DataPoint[graphSizing];).

But it’s not quiet working like expected. Only the default / 0 case are working perfectly as planned. But as soon as I want to zoom out, it’s not working out anymore. On case 2 the AxisX Values are completely wrong and AxisY Values aren’t even showing up. And on case 3 and 4 the program is crashing. Also the CPU Usage is going very high.

Any idea why the other cases aren’t working out like default / 1? And how can I improve the performance and minimize the high cpu usage?

Also for better visualization of the chart: 240 Values: enter image description here

3600 Values: enter image description here

Thanks for help
Greetings C.User

C.User
  • 153
  • 18
  • 1
    You shouldn't need to change your data to zoom on a graph - you should only need to change the `.AxisX.Minimum` and `.AxisX.Maximum` values, and it will do the rest for you. – Matthew Watson Jun 29 '18 at 13:02
  • @MatthewWatson thanks for the quick hint! But I'm already using it, .AxisX.Maximum is set to graphSizing and I'm changing the value of that while right clicking. – C.User Jun 29 '18 at 13:10
  • 1
    What happens if you *only* change the axis min/max? – Matthew Watson Jun 29 '18 at 13:17
  • @MatthewWatson since I'm loading data from a datapoint array, I can't "only change the axis max/min. Because otherwise it would give me a null exception because the datapoint array would be still just 240 length and the maximum at 3600 for example - now im chaning both the length of the array to 3600 and the axis to 3600 – C.User Jun 29 '18 at 13:39
  • Can you explain just what you don't like about the [built-in zooming](https://stackoverflow.com/questions/29985796/chart-zoom-in-to-show-more-precise-data/29986941#29986941)? – TaW Jul 01 '18 at 07:25
  • @TaW as far as i know you can use the mschart zoom only to zoom in. but my data starts with less data and i would like to zoom out to show more. – C.User Jul 02 '18 at 06:56
  • 1
    Which are working default&0 or default&0&1? Also; where does the program crash? Can you test where the bottleneck is? I suspect it is in the prepDataX where you do operations (Array.Exists & Array.Find ) which get more and more expensive with larger amounts of data. Can't you find the 1st and last point only and then add all those inbetween without further testing? – TaW Jul 02 '18 at 09:58

0 Answers0