Functions and period
-
- Newbie
- Posts: 12
- Joined: Fri Sep 30, 2016 12:00 am
Functions and period
Hi Support,
We have an issue with the function series, we are trying to populate a Add function series on a time series data based on a daily basis for which the code as follows:
Dim funcSeries As New Steema.TeeChart.Styles.FastLine(FChart.Chart)
funcSeries.Title = String.Format("Total ({0})", periodText)
funcSeries.DataSource = _selectedSeries
funcSeries.Marks.Visible = True
Dim chartTotalFunction As New Steema.TeeChart.Functions.Add
Dim period As New TimeSpan
period = New TimeSpan(1, 0, 0, 0)
chartTotalFunction.Period = period.TotalDays
chartTotalFunction.PeriodAlign = Steema.TeeChart.Functions.PeriodAligns.Center
chartTotalFunction.PeriodStyle = Steema.TeeChart.Functions.PeriodStyles.Range
funcSeries.Function = chartTotalFunction.Period
funcSeries.CheckDataSource()
The result of function series is based on intervals of one day from starting point (24 hours from starting), but not on based on the specific date. How to get the resulting values of the function series based on each date rather than a 24 hours day?
We have an issue with the function series, we are trying to populate a Add function series on a time series data based on a daily basis for which the code as follows:
Dim funcSeries As New Steema.TeeChart.Styles.FastLine(FChart.Chart)
funcSeries.Title = String.Format("Total ({0})", periodText)
funcSeries.DataSource = _selectedSeries
funcSeries.Marks.Visible = True
Dim chartTotalFunction As New Steema.TeeChart.Functions.Add
Dim period As New TimeSpan
period = New TimeSpan(1, 0, 0, 0)
chartTotalFunction.Period = period.TotalDays
chartTotalFunction.PeriodAlign = Steema.TeeChart.Functions.PeriodAligns.Center
chartTotalFunction.PeriodStyle = Steema.TeeChart.Functions.PeriodStyles.Range
funcSeries.Function = chartTotalFunction.Period
funcSeries.CheckDataSource()
The result of function series is based on intervals of one day from starting point (24 hours from starting), but not on based on the specific date. How to get the resulting values of the function series based on each date rather than a 24 hours day?
-
- Newbie
- Posts: 12
- Joined: Fri Sep 30, 2016 12:00 am
Re: Functions and period
Hello..
Any input for this?
Any input for this?
-
- Guru
- Posts: 1603
- Joined: Fri Nov 15, 2002 12:00 am
Re: Functions and period
Sorry for the delay in this reply.Seveno Developer wrote:Hello..
Any input for this?
It seems there may be some defects in this area of code - I am looking at this now and will get back to you.
Best Regards,
Christopher Ireland / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
-
- Guru
- Posts: 1603
- Joined: Fri Nov 15, 2002 12:00 am
Re: Functions and period
Hello,
Unfortunately there were two defects in this area of code which have now been fixed and will be available in the next maintenance release. However, these fixes can be used now in a custom Add function class like this:
This class can be used as following:
which gives me this chart:
The above chart is now correct. Can I help you with any specific questions you may have with this?
Unfortunately there were two defects in this area of code which have now been fixed and will be available in the next maintenance release. However, these fixes can be used now in a custom Add function class like this:
Code: Select all
public class MyAdd : Add
{
public override double Calculate(Series source, int first, int last)
{
if (first == -1)
{
first = 0;
last = source.Count - 1;
}
List<double> tmpValues = new List<double>();
ValueList tmpSource = ValueList(source);
for (int i = first; i <= last; i++)
{
if (IncludeNulls || (!source.IsNull(i)))
{
AddValues(tmpValues, tmpSource[i]);
}
}
return CalculateValue(tmpValues.ToArray());
}
protected override void DoCalculation(Series source, ValueList notMandatorySource)
{
if (dPeriod == 0)
CalculateAllPoints(source, notMandatorySource);
else
CalculateByPeriodFix(source, notMandatorySource);
}
private bool HasRegularStep(ValueList list)
{
double step, laststep = 0;
for (int i = 1; i < list.Count; i++)
{
step = list[i] - list[i - 1];
if (i > 1 && Utils.SignificantDifference(laststep, step))
{
return false;
}
laststep = step;
}
return true;
}
private void CalculateByPeriodFix(Series source, ValueList notMandatorySource)
{
double tmpX;
int tmpLast;
double PosFirst;
double PosLast;
bool tmpCalc;
int tmpFirst = 0;
int tmpCount = source.Count;
double tmpBreakPeriod = notMandatorySource[tmpFirst];
DateTimeSteps tmpStep = Axis.FindDateTimeStep(dPeriod);
double actualStep = HasRegularStep(notMandatorySource) ? notMandatorySource[tmpFirst + 1] - tmpBreakPeriod : dPeriod * 0.001;
do
{
PosLast = 0;
if (PeriodStyle == PeriodStyles.NumPoints)
{
tmpLast = tmpFirst + Utils.Round(dPeriod) - 1;
PosFirst = notMandatorySource[tmpFirst];
if (tmpLast < tmpCount) PosLast = notMandatorySource[tmpLast];
}
else
{
tmpLast = tmpFirst;
PosFirst = tmpBreakPeriod;
Axis axis = Series.GetHorizAxis;
Series.GetHorizAxis.DateTimeIncrement(axis.Labels.ExactDateTime && axis.IsDateTime && (tmpStep >= DateTimeSteps.HalfMonth), true, ref tmpBreakPeriod, dPeriod, tmpStep);
PosLast = tmpBreakPeriod - (actualStep);
while (tmpLast < tmpCount - 1)
if (notMandatorySource[tmpLast + 1] < tmpBreakPeriod) tmpLast++;
else
break;
}
tmpCalc = false;
if (tmpLast < tmpCount)
{
/* align periods */
if (PeriodAlign == PeriodAligns.First)
tmpX = PosFirst;
else
if (PeriodAlign == PeriodAligns.Last)
tmpX = PosLast;
else
tmpX = (PosFirst + PosLast) * 0.5;
if ((PeriodStyle == PeriodStyles.Range) && (notMandatorySource[tmpFirst] < tmpBreakPeriod))
tmpCalc = true;
if ((PeriodStyle == PeriodStyles.NumPoints) || tmpCalc)
CalculatePeriod(source, tmpX, tmpFirst, tmpLast);
else
AddFunctionXY(true, tmpX, 0);
}
if ((PeriodStyle == PeriodStyles.NumPoints) || tmpCalc)
tmpFirst = tmpLast + 1;
} while (tmpFirst <= tmpCount - 1);
}
}
Code: Select all
Line series;
FastLine funcSeries;
MyAdd chartTotalFunction;
private void InitializeChart()
{
funcSeries = new FastLine(tChart1.Chart);
funcSeries.Marks.Visible = true;
chartTotalFunction = new MyAdd();
chartTotalFunction.Period = new TimeSpan(0, 12, 0, 0).TotalDays;
chartTotalFunction.PeriodAlign = Steema.TeeChart.Functions.PeriodAligns.Last;
chartTotalFunction.PeriodStyle = Steema.TeeChart.Functions.PeriodStyles.Range;
funcSeries.Function = chartTotalFunction;
series = new Line(tChart1.Chart);
DateTime today = DateTime.Today;
for (int i = 0; i < 20; i++)
{
series.Add(today, i);
today = today.AddHours(3);
}
funcSeries.Marks.Visible = true;
series.Marks.Visible = true;
funcSeries.DataSource = series;
tChart1.Axes.Bottom.Labels.Angle = 90;
tChart1.Axes.Bottom.Increment = new TimeSpan(0, 3, 0, 0).TotalDays;
tChart1.Axes.Bottom.Labels.DateTimeFormat = "dd/MM/yy hh:mm";
}
The above chart is now correct. Can I help you with any specific questions you may have with this?
Best Regards,
Christopher Ireland / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
-
- Newbie
- Posts: 12
- Joined: Fri Sep 30, 2016 12:00 am
Re: Functions and period
Hi Christopher,
Thank you.
Just wondering as we need to implement the other functions too and that we allow the users to add functions at run time from the chart editor, is there any way to modify the code defects so that it reflects for all functions? We do have access to the code for the latest build.
Thank you.
Just wondering as we need to implement the other functions too and that we allow the users to add functions at run time from the chart editor, is there any way to modify the code defects so that it reflects for all functions? We do have access to the code for the latest build.
-
- Guru
- Posts: 1603
- Joined: Fri Nov 15, 2002 12:00 am
Re: Functions and period
Of course. The changes are in Functions/Basic.cs:Seveno Developer wrote:Just wondering as we need to implement the other functions too and that we allow the users to add functions at run time from the chart editor, is there any way to modify the code defects so that it reflects for all functions? We do have access to the code for the latest build.
You already have the code for HasRegularStep().
Best Regards,
Christopher Ireland / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
-
- Newbie
- Posts: 12
- Joined: Fri Sep 30, 2016 12:00 am
Re: Functions and period
Hi Christopher,
Thanks for the code, we have updated the basic.cs accordingly but the results are still incorrect.
It skips values for the first day which has only 1 row.
Screenshot for sample data We are using with chart max and total functions.
Output for total function: Output for maximum function: The results are correct when the subset of data for each day has the same number of data/ same interval (i.e date/time)
Thanks for the code, we have updated the basic.cs accordingly but the results are still incorrect.
It skips values for the first day which has only 1 row.
Screenshot for sample data We are using with chart max and total functions.
Output for total function: Output for maximum function: The results are correct when the subset of data for each day has the same number of data/ same interval (i.e date/time)
-
- Guru
- Posts: 1603
- Joined: Fri Nov 15, 2002 12:00 am
Re: Functions and period
Okay - would you please be so kind as to prepare a Minimal, Complete, and Verifiable example [here] with which I can reproduce your issue here?Seveno Developer wrote: Thanks for the code, we have updated the basic.cs accordingly but the results are still incorrect.
The results are correct when the subset of data for each day has the same number of data/ same interval (i.e date/time)
Best Regards,
Christopher Ireland / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
-
- Newbie
- Posts: 12
- Joined: Fri Sep 30, 2016 12:00 am
Re: Functions and period
Hi Christopher,
We handle mostly time series data for which we need to be able to apply periodic functions. I am trying to make it simple and straight.
The forum does not allow adding text files, so I've sent the data into a .txt to your gmail address. Please use the text file to load the data for the series.
To reproduce the issue, first add a series in run time (it can be done using code too):
1. From the Chart editor, add a new series (i.e: RawDataSeries).
2. Under series Tab's General Tab, set the Horizontal Axis to Bottom and check Date Time checkbox (this is another bug as the date/time field is not recognized automatically, it throws an exception if not set manually)
3. Now under the series tab, click on Datasource, select text file
4. For the file attached here, under fields tab use Number of Header lines: 1, Separator: Tab, X: 0, Y: 1
5. Specify the file location, hit apply to populate the series
Now use the code that I have posted at the beginning. Please note the period we are using is One day and therefore the period = New TimeSpan(1, 0, 0, 0)
The total value should output individual total day's not on a 24 hours basis day. This does not work. In-fact, none of the function series' value for one day period is correct for the data given.
Hope that helps
We handle mostly time series data for which we need to be able to apply periodic functions. I am trying to make it simple and straight.
The forum does not allow adding text files, so I've sent the data into a .txt to your gmail address. Please use the text file to load the data for the series.
To reproduce the issue, first add a series in run time (it can be done using code too):
1. From the Chart editor, add a new series (i.e: RawDataSeries).
2. Under series Tab's General Tab, set the Horizontal Axis to Bottom and check Date Time checkbox (this is another bug as the date/time field is not recognized automatically, it throws an exception if not set manually)
3. Now under the series tab, click on Datasource, select text file
4. For the file attached here, under fields tab use Number of Header lines: 1, Separator: Tab, X: 0, Y: 1
5. Specify the file location, hit apply to populate the series
Now use the code that I have posted at the beginning. Please note the period we are using is One day and therefore the period = New TimeSpan(1, 0, 0, 0)
The total value should output individual total day's not on a 24 hours basis day. This does not work. In-fact, none of the function series' value for one day period is correct for the data given.
Hope that helps
-
- Guru
- Posts: 1603
- Joined: Fri Nov 15, 2002 12:00 am
Re: Functions and period
Thanks.Seveno Developer wrote: The total value should output individual total day's not on a 24 hours basis day. This does not work. In-fact, none of the function series' value for one day period is correct for the data given.
Hope that helps
I think the issue here is that you are expecting the function to group points by Date, whereas what they are doing is by PeriodStyles.Range, that is, the points that fall within a one day Period (in this case). Maybe the difference can be seen in this example:
Code: Select all
private void InitializeChart()
{
Func<string, List<Tuple<DateTime, double>>> GetData = (file) =>
{
List<Tuple<DateTime, double>> result = new List<Tuple<DateTime, double>>();
List<string> lines = File.ReadAllLines(file).ToList();
lines.RemoveAt(0);
foreach (var line in lines)
{
string[] splits = line.Split('\t');
DateTime date = DateTime.Parse(splits[0]);
double value = double.Parse(splits[1]);
result.Add(new Tuple<DateTime, double>(date, value));
}
return result;
};
List<Tuple<DateTime, double>> data = GetData(@"D:\FTP\data.txt");
FastLine funcSeries = new FastLine(tChart1.Chart);
Add chartTotalFunction = new Add();
TimeSpan period = new TimeSpan(1, 0, 0, 0);
chartTotalFunction.Period = period.TotalDays;
chartTotalFunction.PeriodAlign = Steema.TeeChart.Functions.PeriodAligns.Center;
chartTotalFunction.PeriodStyle = Steema.TeeChart.Functions.PeriodStyles.Range;
funcSeries.Function = chartTotalFunction;
Line series = new Line(tChart1.Chart);
for (int i = 0; i < data.Count; i++)
{
DateTime date = data[i].Item1;
double val = data[i].Item2;
series.Add(date, val);
}
funcSeries.Marks.Visible = true;
funcSeries.DataSource = series;
tChart1.Axes.Bottom.Labels.Angle = 90;
tChart1.Axes.Bottom.Labels.DateTimeFormat = "dd/MM/yy hh:mm";
FastLine funcSeriesLINQ = new FastLine(tChart1.Chart);
funcSeriesLINQ.Marks.Visible = true;
funcSeriesLINQ.Marks.Style = MarksStyles.XY;
var group = data.GroupBy(x => x.Item1.Date);
foreach (var item in group)
{
double sum = item.Sum(x => x.Item2);
funcSeriesLINQ.Add(item.Last().Item1, sum); //last date of group, but could calculate center
}
}
In funcSeriesLINQ we group the data by the Date, that is, by a one day (24 hour) period whereby all points are of the same day. The funcSeries, on the other hand, groups points into one day periods but not of the same day, because the first point does not start at 00:00. This is by design, although maybe not what you were expecting.
Best Regards,
Christopher Ireland / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
-
- Newbie
- Posts: 12
- Joined: Fri Sep 30, 2016 12:00 am
Re: Functions and period
Thanks Christopher, the issue is as you pointed it correctly, the first point does not start at 00:00. I have added an overloading function to the datetime increment which solves our problem.In funcSeriesLINQ we group the data by the Date, that is, by a one day (24 hour) period whereby all points are of the same day. The funcSeries, on the other hand, groups points into one day periods but not of the same day, because the first point does not start at 00:00. This is by design, although maybe not what you were expecting.
Thanks heaps for your help. Cheers!