Hi Jens,
This is an interesting problem :-)
This code works as expected:
Code: Select all
private void InitializeChart()
{
tChart1.Aspect.View3D = false;
Steema.TeeChart.Styles.Line lineTemp = new
Steema.TeeChart.Styles.Line(tChart1.Chart);
lineTemp.Add(10000001, 0.1);
lineTemp.Add(10000002, 0.2);
lineTemp.Add(10000003, 0.3);
lineTemp.Add(10000004, 0.4);
lineTemp.Add(10000005, 0.5);
Steema.TeeChart.Styles.Line line = new Steema.TeeChart.Styles.Line(tChart1.Chart);
line.DataSource = lineTemp;
Steema.TeeChart.Functions.TrendFunction trend = new Steema.TeeChart.Functions.TrendFunction();
trend.PeriodAlign = Steema.TeeChart.Functions.PeriodAligns.Center;
trend.PeriodStyle = Steema.TeeChart.Functions.PeriodStyles.NumPoints;
trend.Period = line.Count;
line.Function = trend;
}
Now, adding in another significant digit to the XValues causes an incorrect chart, e.g.
Code: Select all
lineTemp.Add(100000001, 0.1);
lineTemp.Add(100000002, 0.2);
lineTemp.Add(100000003, 0.3);
lineTemp.Add(100000004, 0.4);
lineTemp.Add(100000005, 0.5);
The two lines should coincide, but don't. Adding another significant digit to the XValues causes the chart you showed to us.
The issue here is that the size of the input values causes the internal algorithms to work at a precision beyond that of the System.Double type. The line of code that causes the issue is this one:
here, sumX is the sum of all the XValues, sumX2 is the sum of all the squares of the XValues and count is the number of values in the series. So, feeding the values into this from the chart which gives us the "incorrect" values, we have:
Code: Select all
private void InitializeOther()
{
double divisor, sumX2, sumX;
int count;
sumX2 = 5.00000003E+18;
sumX = 5000000015.0;
count = 5;
divisor = count * sumX2 - sumX * sumX;
MessageBox.Show(divisor.ToString());
}
this calculation gives us zero, which is why the chart displays as it does. Now, one way round this problem would be to use decimals instead of doubles to perform the calculation, however, the decimal type has a low range (±1.0 x 10-28 to ±7.9 x 10+28) and the numbers we use above are already in the area of 10+20. Using decimals would therefore resolve the issue for the specific case in hand, but adding a couple more significant digits would cause the algorithm to reach the limit of decimal's range. We therefore don't see the use of decimals as a viable alternative here.
Our best suggestion, therefore, is that you factor down the input doubles to a range which causes a precise calculation. This can be done using code similar to the following:
Code: Select all
private double factor = 0.01;
private void InitializeChart()
{
tChart1.Aspect.View3D = false;
tChart1.GetAxisLabel += new GetAxisLabelEventHandler(tChart1_GetAxisLabel);
Steema.TeeChart.Styles.Line lineTemp = new
Steema.TeeChart.Styles.Line(tChart1.Chart);
lineTemp.Add(1000000001 * factor, 0.1);
lineTemp.Add(1000000002 * factor, 0.2);
lineTemp.Add(1000000003 * factor, 0.3);
lineTemp.Add(1000000004 * factor, 0.4);
lineTemp.Add(1000000005 * factor, 0.5);
Steema.TeeChart.Styles.Line line = new Steema.TeeChart.Styles.Line(tChart1.Chart);
line.DataSource = lineTemp;
Steema.TeeChart.Functions.TrendFunction trend = new Steema.TeeChart.Functions.TrendFunction();
trend.PeriodAlign = Steema.TeeChart.Functions.PeriodAligns.Center;
trend.PeriodStyle = Steema.TeeChart.Functions.PeriodStyles.NumPoints;
trend.Period = line.Count;
line.Function = trend;
}
void tChart1_GetAxisLabel(object sender, GetAxisLabelEventArgs e)
{
if (sender == tChart1.Axes.Bottom)
{
string text = e.LabelText;
double d = double.Parse(text);
d *= 1 / factor;
e.LabelText = d.ToString(tChart1.Axes.Bottom.Labels.ValueFormat);
}
}