import Graph
import vcl
import Gui
def CreateYDistancePtSeries():
FctnIndexesOfPtSeries = FindFctnIndexesOfPtSeries() #find all series that are PtSeries
FctnIndexesOfStdFunc = FindFctnIndexesOfStdFunc() #find all series that are StdFunc
YDistancePtSeries = YDistanceToTrendline(Graph.FunctionList[FctnIndexesOfPtSeries[0]], Graph.FunctionList[FctnIndexesOfStdFunc[0]]) #Creates a new PtSeries that contains the Y-distance between the first existing PtSeries in the FunctionList to the first existing StdFunc.
Graph.FunctionList.append(YDistancePtSeries) #adds the newly created PtSeries to the FunctionList for all to see!
Graph.Redraw()
return 0
def YDistanceToTrendline(ReferencePointSeries, Trendline): #This function extracts the data from the reference point series, evaluates the trendline value at the reference X positions, calculates the difference between Ref and Trendline, then creates a new point series to show the distance.
TrendlineYValuesAtPtSeriesXes = []
YDistanceBetweenRefAndTrend = []
DistancePointsTupleList = []
RefSeriesXValues, RefSeriesYValues = SplitPointsListToXandYLists(ReferencePointSeries.Points) #extracts a list of X values and a list of Y values from the Point Series.
for i in range(len(RefSeriesXValues)):
TrendlineYValuesAtPtSeriesXes.append(Trendline.Eval(RefSeriesXValues[i])[1]) #for each x-value, the trendline y-value is evaluated.
for i in range(len(RefSeriesYValues)):
YDistanceBetweenRefAndTrend.append(RefSeriesYValues[i] - TrendlineYValuesAtPtSeriesXes[i]) #for each y-value, the difference between the point series and trendline is calculated.
for i in range(len(YDistanceBetweenRefAndTrend)):
DistancePointsTupleList.append((RefSeriesXValues[i], YDistanceBetweenRefAndTrend[i])) #A point tuple is created for each value calculated. The points are added to a points list for the creation of the resulting ptseries.
NewPointSeries = Graph.TPointSeries()
NewPointSeries.LegendText = "YDistance of PtSeries to Trendline"
NewPointSeries.ShowInLegend = True
NewPointSeries.Visible = True
NewPointSeries.Points = DistancePointsTupleList #that's where the created points list gets written in the new point series.
return NewPointSeries
def SplitPointsListToXandYLists(PointsList): #basic subroutine that separates the x values and y values of a point series.
PointsXValues = []
PointsYValues = []
for i in range(len(PointsList)):
PointsXValues.append(PointsList[i][0])
PointsYValues.append(PointsList[i][1])
return (PointsXValues, PointsYValues)
def Execute(Sender):
StopVar = CreateYDistancePtSeries()
def FindFctnIndexesOfPtSeries():
ListOfTPtSeriesIndexes = []
for i in range(len(Graph.FunctionList)):
if (type(Graph.FunctionList[i]) == type(Graph.TPointSeries())):
ListOfTPtSeriesIndexes.append(i)
return ListOfTPtSeriesIndexes
def FindFctnIndexesOfStdFunc():
ListOfTStdFuncIndexes = []
for i in range(len(Graph.FunctionList)):
if (type(Graph.FunctionList[i]) == type(Graph.TStdFunc('1'))):
ListOfTStdFuncIndexes.append(i)
return ListOfTStdFuncIndexes
def VerifActiverYDistance(*args):
ListOfIndexesOfPtSeriesInFunctionList = FindFctnIndexesOfPtSeries()
ListOfIndexesOfStdFuncInFunctionList = FindFctnIndexesOfStdFunc()
Action.Enabled = (len(ListOfIndexesOfPtSeriesInFunctionList) >= 1 and len(ListOfIndexesOfStdFuncInFunctionList) >= 1) #Plugin is active when there's at least 1 PtSeries and 1 StdFunc
def VerifActiverYDistanceOnDelete(*args):
ListOfIndexesOfPtSeriesInFunctionList = FindFctnIndexesOfPtSeries()
ListOfIndexesOfStdFuncInFunctionList = FindFctnIndexesOfStdFunc()
if (type(args[0]) == type(Graph.TStdFunc('1'))):
Action.Enabled = (len(ListOfIndexesOfPtSeriesInFunctionList) >= 1 and len(ListOfIndexesOfStdFuncInFunctionList) >= 2) #Plugin is active when there's at least 1 PtSeries and 1 StdFunc available after deletion of an item.
elif (type(args[0]) == type(Graph.TPointSeries())):
Action.Enabled = (len(ListOfIndexesOfPtSeriesInFunctionList) >= 2 and len(ListOfIndexesOfStdFuncInFunctionList) >= 1) #Plugin is active when there's at least 1 PtSeries and 1 StdFunc available after deletion of an item.
Action = Graph.CreateAction(Caption="Calculate Trendline Distance", OnExecute=Execute, Hint="Creates a new point-series that shows the distance between a point-series and its trendline.")
Graph.AddActionToMainMenu(Action)
Graph.OnNew.append(VerifActiverYDistance) #Verification for (de)activating CreateYDistancePtSeries when the grf is opened.
Graph.OnLoad.append(VerifActiverYDistance) #Verification for (de)activating CreateYDistancePtSeries when the grf is opened.
Graph.OnNewElem.append(VerifActiverYDistance) #Verification for (de)activating CreateYDistancePtSeries for each added function.
Graph.OnDelete.append(VerifActiverYDistanceOnDelete) #Verification for (de)activating CreateYDistancePtSeries at each deleted function.