I am new to C# winform. As title, my problem is how to make the points more compact in fastpoint chart. To make it clear, how to proportionally reduce the distance of the blue points like the red line segments shown in the image; that is, make the X axis more compact:
I have searched and found a lot of information about control the interval of X or Y axis labels but which is not the situation here.
You can control the range of data values for each Axis by setting their Minimum and Maximum values.
The syntax is:
someChart.ChartAreas[CAIndexOrName].AxisX.Minimum = someDoubleValue;
Let's prepare a chart to show one day:
Axis ax = chart.ChartAreas[0].AxisX; // a short reference
ax.IntervalType = DateTimeIntervalType.Hours;
ax.Interval = 1;
To set the properties to some DateTime values you need to convert them to doubles; for this conversion there are two built-in functions: DateTime.ToOADate and, to reverse DateTime.FromOADate
This makes the x-axis display 24 hours:
DateTime dt = DateTime.Today;
ax.Minimum = dt.ToOADate();
ax.Maximum = (dt.AddHours(24)).ToOADate();
ax.LabelStyle.Format = "H:mm"; // optional
You also may want to control the data type of the series values:
Series s = chart.Series[0];
s.XValueType = ChartValueType.DateTime; // or some other type, maybe Time
Note you you can also control both the Interval of the Labels and TickMarks and Gridlines on each axis but also set an Offset to start them a little earlier or later..
Related
I want to use a datetimeaxis for the Y-axis of an Oxyplot heatmapseries (in winforms). The API allows me to add the axis to the PlotModel, but does not do much good since the y-value is mapped off of the integral column index of a matrix of doubles - the y values come out to around Jan. 1900.
How can I use times for the y data on the heat map?
The workaround to make this happen is not too difficult. When setting up the chart, create 2 axes: one for the time, and another for the integral index of the HeatMapSeries input.
DateTimeAxis dateTimeAxis;
HeatMapSeries series;
....
//set up the time axis for y
dateTimeAxis = new DateTimeAxis();
dateTimeAxis.Position = AxisPosition.Left;
dateTimeAxis.Key = "dateTimeAxis";
plotModel.Axes.Add(dateTimeAxis);
//set up a shadow axis for the HeatMapSeries
var linearAxis = new LinearAxis();
linearAxis.Position = AxisPosition.Left;
linearAxis.Key = "linearAxis";
plotModel.Axes.Add(linearAxis);
series.YAxisKey = linearAxis.Key;
Next, the assigned y-axis will have to be hidden - but we can't access the YAxis property until the plot has been updated:
//hide the linear axis
plotModel.Updated += (sender, e) =>
{
series.YAxis.IsAxisVisible = false;
};
Finally, when setting the heat map data, simply create the desired mapping from the matrix index to time. Then adjust the y-scale. For example:
public void UpdateData(double[,] data)
{
series.Data = data;
//adjust date/time axis
int numOfMinutes = data.GetLength(1);
dateTimeAxis.Minimum = DateTimeAxis.ToDouble(DateTime.Now);
dateTimeAxis.Maximum DateTimeAxis.ToDouble(DateTime.Now.AddMinutes(numOfMinutes));
}
I have not yet seen a way to do this directly in OxyPlot
I am trying to figure out how to my start the X axis in my line chart at the first date in stored in an object. I have been trying for quite some time now, and I am not sure what I am doing wrong. Any help would be appreciated.
It simply says that I can't convert from DateTime to Double, which makes sense, but I have no clue how to get around this.
I have indented the part of the code I am trying to make work. Thanks in advance!
private void loadChart(List<Temperatur> templist)
{
// clear charts
this.chart1.Series.Clear();
this.chart2.Series.Clear();
// add Data to charts
Series series = this.chart1.Series.Add((templist.ElementAt(0).Date).ToString());
Series series2 = this.chart2.Series.Add((templist.ElementAt(0).Date).ToString());
// defines type of chart
series.ChartType = SeriesChartType.Line;
series2.ChartType = SeriesChartType.Line;
// sets line thickness
series.BorderWidth = 3;
series2.BorderWidth = 3;
// sets chart limits and intervals
chart1.ChartAreas[0].AxisY.Maximum = 42;
chart1.ChartAreas[0].AxisY.Minimum = 35;
chart1.ChartAreas[0].AxisY.Interval = 0.5;
//sets X axis labels
chart1.ChartAreas[0].AxisX.IntervalType = DateTimeIntervalType.Days;
chart1.ChartAreas[0].AxisX.Minimum = Convert.ToDouble(templist.ElementAt(0).Date);
// removes legend from chart
chart1.Legends[0].Enabled = false;
chart2.Legends[0].Enabled = false;
foreach (Temperatur tempObj in templist)
{
// Add point.
series.Points.Add(Convert.ToDouble(tempObj.Temp));
}
foreach (Temperatur tempObj in templist)
{
// Add point.
series2.Points.Add(Convert.ToInt32(tempObj.Puls.ToString()));
}
}
You can add DataPoints in several formats.
You want them to have a X-Value of type DateTime and an Y-Value of type double, so use a call like this:
series.Points.AddXY(tempObj.Date, tempObj.Temp);
If you want to start the display at a Minimum you need to use the key of the Points collection, if the X-Values are dates it will be a date, if they are numbers (doubles by default) you use a number.
If you never have set the X-Values they will start at 0 by default (which will be shown as 1899 when cast to a DateTime..)
Doing so is a little tricky, as the Minimum only accepts doubles; that's because even when your type is set to DateTime and even though you have added DateTime X-Values, internally they still are stored as double.
To set the Minimum etc after you have added the DataPoints with their X-Values as DateTimes you can use :
int yourStartIndex = 1;
chart1.ChartAreas[0].AxisX.Minimum = series.Points.ElementAt(yourStartIndex).XValue;
To control the displayed X-Axis label set its Format; here is an example:
chart1.ChartAreas[0].AxisX.LabelStyle.Format = "dd.MM.\\'yy hh\\h";
Note the added 'h' and the added apostrophe resulting in something like: 21.03'15 12h
I have an MS chart control with several StepLine series and one column series.
All series are plotted by doing:
double yvalue = ...;
Series[seriesName].Points.AddXY(DateTime.Now, new object[] {yvalue});
the series in question is defined in the designer:
series31.ChartArea = "ChartArea1";
series31.Color = System.Drawing.Color.BlueViolet;
series31.CustomProperties = "EmptyPointValue=Zero, MaxPixelPointWidth=1";
series31.Legend = "Legend1";
series31.MarkerSize = 1;
Step lines plot fine, however the column series is displayed with a line going from the bottom of the chart to the value (in the screen cap below, the value is typically around 2.0).
How can I get the series to just draw a line that starts at 0 on the y-axis?
I assume you want a chart that will start from zero in Y-Axis at the bottom.
chartArea.AxisY.Minimum = 0;
if you do so,then you will not see the value less then zero in chart.you can also set the Maximum of
Y-Axis.
chartArea.AxisY.Minimum = 0;
chartArea.AxisY.Maximum = 10;
above code will show only the values from 0 to 10.
I'm adding my points to the chart like this:
var point = new DataPoint(xValue.TimeStamp.Ticks, yValue);
point.AxisLabel = "someString";
series.Points.Add(point);
But the AxisLabel doesn't appear on my chart.
When I'm using this code the labels appear but as double and not as i want:
series.Points.AddXY(xValue.TimeStamp.Ticks, yValue);
My AxisValueTyp is set to double.
Is there something i miss? Do I have to set something within the labelsettings of the chartArea X Axis?
Ticks are of type long. If you are using Ticks for your X-Axis you can use the
series.Points.AddXY(xValue.TimeStamp.Ticks, yValue);
format to add the data points.
You didn't say what format you want. To set the format from the standard axis format double to a more suitable number format use e.g.
yourChartArea.AxisX.LabelStyle.Format = "###,###,###,##0";
for the X-Axis of yourChartArea.
I am using C# Excel API to generate some reports. However, Excel leaves gaps between the first axis point and minimum value in data set, and between last axis point and maximum value in data set. My data set is sorted by datetime. How do I force excel to set the lower and upper bounds of axes precisely to minimum and maximum values in my data set so that I don't see any gaps? I can do that in excel by manually setting min/max axis points in excel chart.
But is there a way to have excel do this automatically, or otherwise set min/max points from my C# application using the data set?
Example (marked gaps)
Hope it makes sense.
thanks
[Edited] OK, I did some playing, and I've figured out how to set the vertical and horizontal axis range. This is working with Excel 2010.
Here, I clear all charts on the page and create a new one (_resultsSheet is an Excel.Worksheet):
var resultCharts = (ChartObjects)_resultsSheet.ChartObjects();
foreach (ChartObject ch in resultCharts)
{
ch.Delete();
}
ChartObject resultChart = resultCharts.Add(150, 40, 300, 200);
_resultChartPage = resultChart.Chart;
Now set up the source - I've just used a predefined range of fixed values. You could scan your source to find the actual min and max values:
_resultChartRange = _resultsSheet.get_Range("J5", "K15");
_resultChartPage.SetSourceData(_resultChartRange);
_resultChartPage.ChartType = Excel.XlChartType.xlXYScatterLines;
_resultChartPage.HasLegend = false;
Now for the vertical axis setup:
Axis vertAxis = (Axis)resultChart.Chart.Axes(XlAxisType.xlValue, XlAxisGroup.xlPrimary);
vertAxis.HasMajorGridlines = true; // change this to whatever you wish
vertAxis.HasTitle = true;
vertAxis.AxisTitle.Text = "up the side";
vertAxis.MaximumScaleIsAuto = false;
vertAxis.MaximumScale = 500; // you can pick this based on your input
vertAxis.MinimumScaleIsAuto = false;
vertAxis.MinimumScale = 5;
now for the other axis. Note here I've used fixed times. To convert a time to an axis scale, just use the 24 hour time in decimal, divided by 24. Eg. 9:30pm is 21:30 which is 21.5 hours. Don't forget the (double) cast just in case you use to ints.
Axis horizAxis = resultChart.Chart.Axes(XlAxisType.xlCategory, XlAxisGroup.xlPrimary);
horizAxis.MaximumScaleIsAuto = false;
horizAxis.MaximumScale = (double)21.5 / 24; // 9:30 pm
horizAxis.MinimumScaleIsAuto = false;
horizAxis.MinimumScale = (double)13 / 24; // 1:00 pm
horizAxis.HasTitle = true;
horizAxis.AxisTitle.Text = "across the bottom";
and for those who "like to watch":
_resultsSheet.Activate();
_workBook.Application.Visible = true;