This may have been answered before and if so I'm sorry, but I haven't found anything in my searches. I am trying to display a chart with a moving 'window' of values similar to Task Manager's display of CPU and Memory usage. The DataSource of my chart is being constantly updated and I want to only display the last 60 values added to the DataSource. Any help of this would be greatly appreciated.
I recommend removing the first point from the chart's datasource each time a point is added.
it is also possible to achieve this by setting
theChart.Axis.X.RangeType = AxisRangeType.Auto
theChart.Axis.X.RangeMin = 0
theChart.Axis.X.RangeMax = 60
I was hoping there would be a cleaner solution than that. I need to keep a reference of all the values and just show the most recent entries. I guess I will need to maintain a separate DataTable in addition to the DataSource to achieve this?
Feel free to post a code sample that illustrates how you want to manage your datatable while binding it to the chart if the above doesn't answer your question, and we can use that to guide the discussion.
Thanks,
Graham
One way you could handle this is to proxy the dataview to display only the recent items:
ultraChart1.DataSource = new RecentItemsView(_data.DefaultView, 60);
with:
public class RecentItemsView : DataView
{
private int _itemCount;
private DataView _innerView;
private DataTable _sourceTable;
public RecentItemsView(DataView innerView, int itemCount)
_innerView = innerView;
_itemCount = itemCount;
_sourceTable = innerView.Table.Clone();
if (String.IsNullOrEmpty(_sourceTable.TableName))
_sourceTable.TableName = "sourceTable";
}
this.Table = _sourceTable;
if (_innerView.Count > 0)
for (int i = 0; i < _innerView.Count; i++)
AddFromIndex(i);
_innerView.ListChanged += new ListChangedEventHandler(innerList_ListChanged);
private void AddFromIndex(int index)
if (_innerView[index] is DataRowView)
this.Table.Rows.Add((_innerView[index] as DataRowView).Row.ItemArray);
if (this.Count > _itemCount)
this.Table.Rows.RemoveAt(0);
private void innerList_ListChanged(object sender, ListChangedEventArgs e)
if (e.ListChangedType != ListChangedType.ItemAdded)
throw new
NotSupportedException("RecentItemsView only supports items being added to the end of the list it is proxying.");
if (e.NewIndex != _innerView.Count - 1)
AddFromIndex(e.NewIndex);
But there are many ways to achieve this. For one, how are you obtaining this data table? Are you building/updating it in memory? Or are you querying for it from a database table on a timer? In the former case something of the nature I described above may be appropriate, but in the latter case, you may just want to make sure through the formulation of the query you run that the most recent 60 records have a column that counts 1 through 60 and then, if you use this column as the x axis column, and set the axis range as David described above, you can achieve similar results.
What I am basically doing is collecting status updates from a sensor every second and need a way to show what the sensor has looked like over the last 2 minutes, but I also need to keep all the collected values to run metrics on at a later point. It would be awesome if I could save everything in one table and have the graph be smart enough to only display the last 2 minutes worth of information.
There are, of course, other ways to achieve the window movement. For example David was explaining you could accomplish something by hard coding the range of the x axis, and then you would just need to make sure the "current" entries were the only ones to fall in that range and be displayed. If you can provide more information about the format of your data source and how you are obtaining it for this updating display, we could further advise.