5

I have this code:

private void timer_Tick(object sender, EventArgs e)
    {
        timer.Stop();
        for (int i = 0; i < TOTAL_SENSORS; i++)
        {
            DateTime d = DateTime.Now;
            devices[i].Value = float.Parse(serialPort.ReadLine());
            if (chart1.Series[i].Points.Count > MAX_POINTS)
            {
                //see the most recent points
            }
            chart1.Series[i].Points.AddXY(d, devices[i].Value);
        }
        timer.Start();
    }

This part of my code is the timer's tick event where i draw a chart and i need to update it every tick.I keep adding points and when the points count reaches MAX_POINTS(10) it removes the first point and adds a new one at the end.

The problem is when it reaches MAX_POINTS it starts removing points at the end and the graph doesn't autoscroll. All points get deleted and no new points get added.

Please help me and say what I need to change the chart to work as I said.

EDIT 1: I am using Windows Forms.

EDIT 2: AddXY and RemoveAt are not mine they are from the points collection.

EDIT 3: I also want to know how to have a 'scope' and see the data for the last hour or for the last week or for the last month.

EDIT 4: I changed my question a bit, I now want to scale the chart to show the points from the last hour/day

Nick Knowlson
  • 7,185
  • 6
  • 47
  • 63
Bosak
  • 2,103
  • 4
  • 24
  • 43
  • Is this using WinForms or WPF? In WPF you can use DataBinding to an ObservableCollection and then you don't have to worry about updating the UI (only the collection). – Philipp Schmid Aug 17 '11 at 16:33
  • I wondering whether you have own implementation of the Collection/List class? Or RemoveAt it's your own implementation along with AddXY() ? – sll Aug 17 '11 at 16:53
  • @sllev they are from the points collection and I haven't changed anything to the default chart series adn points classes. – Bosak Aug 18 '11 at 07:59
  • Can you post the chart class? – Daniel Aug 19 '11 at 16:39
  • It is from metadata not my own >_< but here is it in MSDN:[chart class](http://msdn.microsoft.com/en-us/library/system.windows.forms.datavisualization.charting.chart.aspx) – Bosak Aug 19 '11 at 16:43
  • @Dani the charts OP is using are from Microsoft's Charting Library. http://www.microsoft.com/download/en/details.aspx?id=14422 – Kyle Trauberman Aug 19 '11 at 16:44
  • @Kyle Trauberman no I use the chart class not this – Bosak Aug 19 '11 at 16:45
  • 2
    Not related to the points, but if you're using `System.Windows.Forms.Timer`, then there's no reason to stop and re-start the timer. The Windows forms timer isn't re-entrant. It won't call the Tick event handler if a tick is already being processed. This is not true of `System.Windows.Timer` or `System.Threading.Timer`. – Jim Mischel Aug 19 '11 at 16:47
  • @Jim Mischel ok thx ilol change that – Bosak Aug 19 '11 at 16:48
  • @bosak, the link I pasted is the download for the charting library (which is included in the framework now, I believe). – Kyle Trauberman Aug 19 '11 at 16:51
  • @bosak your most recent edit completely changes the orginal question. You should ask it as a new question. – Kyle Trauberman Aug 21 '11 at 16:32

2 Answers2

9

Store the points in a separate dictionary as well as the chart. Then you can just query the dictionary when you want the most recent points.

Dictionary<DateTime, float> points = new Dictionary<DateTime, float>();

then add this line directly after your call to AddXY():

points.Add(d, devices[i].Value);

and if you want to keep the dictionary in sync with the chart, remove the first element from the dictionary as well:

points.Remove(points.Keys[0]);

To query the dictionary, you can use linq: Take() Documentation Skip() Documentation

IEnumerable<KeyValuePair<DateTime, float>> mostRecent = points.Skip(points.Count - 10).Take(10);

or you can get a specific point (lets say you want the point from one minute ago)

float value = points[DateTime.Now.AddMinutes(-1)];

or you can loop over the items:

foreach(KeyValuePair<DateTime, float> point in points)
{
    DateTime time = point.Key;
    float value = point.Value;
}
Kyle Trauberman
  • 25,414
  • 13
  • 85
  • 121
  • How to query the dictionary?Exampel please.But this only answers how to see the points from the last hour/day/month etc. – Bosak Aug 19 '11 at 16:54
  • There are a few example of how to query the dictionary. You can do much more with your queries with linq, if you prefer. – Kyle Trauberman Aug 19 '11 at 17:01
  • I stil haven't learned LINQ. So this `points.Take(10);` will get the 10 most reccent points and return a Enumerable? – Bosak Aug 19 '11 at 17:02
  • 1
    Well, actually `Take()` takes the first n elements from the collection, so you would need to `Skip()` the first Count-n elements, sort the collection, or ensure that there are only 10 elements in the list (as you are doing). I'll add some links to documentation into the answer. – Kyle Trauberman Aug 19 '11 at 17:05
5

You need to put this:

chart1.ResetAutoValues();

to adjust X and Y axis scale

j0k
  • 22,600
  • 28
  • 79
  • 90
z-t
  • 51
  • 1
  • 1