I’m currently building an application that shows a line-graph and uses MSChartControl.
Here is the relevant code:
WeatherDatabase _db = new WeatherDatabase(Properties.Settings.Default.SqlConnectionString);
private void AddSensorDataToGraph(int sensorType, string xTitle, string yTitle, string Title)
{
var sensorIdList = (from d in _db.Sensors where d.TypeId == sensorType select d.Id).ToArray();
var startDate = dateTimePickerStart.Value;
var stopDate = dateTimePickerStop.Value;
SetMaxMinValues(dateTimePickerStart.Value.ToOADate(), dateTimePickerStop.Value.ToOADate());
this.Text = chartValues.Titles["Titel"].Text = String.Format("{0} vom {1} bis {2}", Title, startDate, stopDate);
chartValues.ChartAreas[CHARTAREA].AxisX.Title = xTitle;
chartValues.ChartAreas[CHARTAREA].AxisY.Title = yTitle;
// Alte Datensätze löschen
chartValues.Series.Clear();
foreach (var sensorId in sensorIdList)
{
var values = (from d in _db.DeviceIO where d.IdSensor == sensorId && d.Timestamp > startDate && d.Timestamp < stopDate orderby d.Timestamp ascending select d).ToArray();
if (values.Length > 0)
{
var desc = values[0].Sensors.SensorType.Description;
chartValues.Series.Add(GenerateDefaultSeries(String.Format("{0}\r\nSensorId: {1}", desc, sensorId)));
//chartValues.Series.Add("Test" + sensorId);
int seriesId = chartValues.Series.Count - 1;
foreach (var item in values)
{
if (item.Value == null)
{
continue;
}
if ((double)item.Value == NOVALUE)
{
continue;
}
AddPointToChart((DateTime)item.Timestamp, (double)item.Value, seriesId);
}
}
}
}
private void AddPointToChart(DateTime timestamp, double value, int series)
{
DataPoint dataPoint = chartValues.Series[series].Points.Add(value);
dataPoint.XValue = timestamp.ToOADate();
dataPoint.AxisLabel = "dd.MM.yy hh:mm";
}
private void SetMaxMinValues(double min, double max)
{
if (min < max)
{
chartValues.ChartAreas[CHARTAREA].AxisX.Minimum = min;
chartValues.ChartAreas[CHARTAREA].AxisX.Maximum = max;
}
}
private Series GenerateDefaultSeries(string Name)
{
// Grundeinstellungen für die Data-Series setzen
Series series = new Series();
series.ChartType = SeriesChartType.Line;
series.Name = Name;
series.IsValueShownAsLabel = false;
series.IsVisibleInLegend = true;
series.IsXValueIndexed = false;
series.AxisLabel = "dd.MM.yy hh:mm";
// series.LabelFormat = "g";
series.XAxisType = AxisType.Primary;
series.XValueType = ChartValueType.Auto;
series.YValuesPerPoint = 1;
// series.AxisLabel = "dd.MM.yy hh:mm";
return series;
}
If i add a series in designer mode x-axies Labels are correct
Click for pic
But if i start my application and add a series programmatically it loks like this
Anyone knows why the x-axis caption / label is not displayed correctly?
EDIT:
Based on Tom’s help I change some things:
var seriesName = String.Format("{0}\r\nSensorId: {1}", desc, sensorId);
var curSeries = chartValues.Series.Add(seriesName);
UpdateSeriesSettings(ref curSeries);
[...]
AddPointToChart((DateTime)item.Timestamp, (double)item.Value, curSeries);
[…]
private void UpdateSeriesSettings(ref Series series)
{
// Grundeinstellungen für die Data-Series setzen
// Series series = new Series();
series.ChartType = SeriesChartType.Spline;
series.IsValueShownAsLabel = false;
series.IsVisibleInLegend = true;
series.IsXValueIndexed = false;
series.AxisLabel = "dd.MM.yy hh:mm";
// series.LabelFormat = "g";
series.XAxisType = AxisType.Primary;
series.XValueType = ChartValueType.Auto;
series.YValuesPerPoint = 1;
// series.AxisLabel = "dd.MM.yy hh:mm";
}
But my X axis stil ain’t having a label ):
Used the following code:
Fixed my problem.
var desc = values[0].Sensors.SensorType.Description;
var seriesName = String.Format("{0}\r\nSensorId: {1}", desc, sensorId);
curSeries = chartValues.Series.Add(seriesName);
curSeries.ChartType = SeriesChartType.Line;
curSeries.XValueType = ChartValueType.DateTime;
foreach (var item in values)
{
curSeries.Points.AddXY(item.Timestamp, item.Value);
}
It looks like you are adding each point as its own series. Usually, you would add many points into one series.
Do you intend to change seriesId right before you use it?
This happens before you call AddPointToChart() so that is getting a different value than you used in the series
EDIT
The line chartValues.Series.Add(…) will return a variable of type Series which you can add to directly. see http://www.dotnetperls.com/chart
SensorID is your number and I think that there are no guarantees that the system will choose to populate its collection of Series in any particular order.
EDIT
It looks like you’re adding your points to the series before you finish setting them up. Instead, set them all the way up, then add them: