B4J Library [B4X] [XUI] xGraph Class and b4xlib

budakbaru

Member
Licensed User
Longtime User
Yes I expect 1 peak also but different amplitude. I just want to test whether CalcIntegral method can be use for FFT Magnitude signal or not.
The x axis value I just make it. Also for CalcRMSValue, can it be used for FFT Amplitude signal to get the same or almost same value as original sine wave rms.

Thanks.
 

klaus

Expert
Licensed User
Longtime User
In the mean time, I played a little bit with your project.



If you have an integer number of sine cycles in the time window you get one peak.
The amplitude returned by the FFT calculation is the sine amplitude.

I just want to test whether CalcIntegral method can be use for FFT Magnitude signal or not.
What exactly do you mean with this ?
 

Attachments

  • Xgraph2.zip
    25.9 KB · Views: 268
Last edited:

budakbaru

Member
Licensed User
Longtime User
Thanks klaus.
I'm not very good in calculus but I like to learn it. I thought it is ok just to use calcintegral for FFT magnitude.

B4X:
For i = 0 To Samples - 1
        TimeVelocity(i) = xGraph1.CurveY(TimeVelIndex, i)
    Next
this is the secret.

Many thanks Klaus.
 

klaus

Expert
Licensed User
Longtime User
The xGraph library has been updated to version 1.4.

Set CurveStrokeWidth to Public
Added CalcRMSValue, RMS calculation of a curve
Added CalcSmooth, smoothing of a curve
Added CalcSmoothExponentialLag and CalcSmoothExponentialLead smouthing methods, kindly provided by @rgarnett1955.
Added DrawCurve(Index), draws one curve with the given index
Added DrawCurves(Index()), superimposes up to 4 curves with the given indexes
Added SetGraphToSynchronize method, allows to synchronize two xGraph objects.
Added DeSynchronize method
Added UnZoom method
 

budakbaru

Member
Licensed User
Longtime User
Hai Klaus.

Thanks again for you excellent graph plotting.

I would like to know how to clear the label when cursor added or zoom function selected. I mean after the cursor added to the graph then the label disappear.

Thank a lot
 

budakbaru

Member
Licensed User
Longtime User
Dear Klaus,

How to plot 2 curves with different number of index but same scale as below.

Curve 1
index valueX valueY
0 0 0
1 0.1 1
2 0.2 2
3 0.3 1
4 0.4 0
5 0.5 -1
6 0.6 -2
7 0.7 -1
8 0.8 0
9 0.9 1
10 1.0 2

Curve 2
index valueX valueY
0 0 1
1 0.2 0
2 0.4 -1
3 0.6 0
4 0.8 1
5 1.0 0

Curve 1 has many samples than curve 2 but final value of X still same.
 

klaus

Expert
Licensed User
Longtime User
I suppose that you are speaking of the tooltip label on top of the graph.
Can you please explain more in detail what you are doing when it happens.
It probably happens when you have two synchronized graphs and you have selected one, activate the zoom function but move the cursor on the other graph.
You need to finish the method in the selected graph.

How to plot 2 curves with different number of index but same scale as below.
You cannot. The data structure is not made for this.
You can do it with a YXChart, there the data structure is different.
 

budakbaru

Member
Licensed User
Longtime User

In B4A when I want to set a cursor there will be a label appear say select the position of the cursor. After select on the graph, the label still there.
Same for zoom function. The label stay there until exit the apps.
But for B4J the label will disappear immediately after the position of the cursor on the graph selected.

Thanks.
 

klaus

Expert
Licensed User
Longtime User
I see it too.
Thank you for reporting it.
Amended for the next version.
Attached the two files of the current not yet official version 1.5.

EDIT: Removed the two files, they are in the first post.
 
Last edited:

budakbaru

Member
Licensed User
Longtime User
Dear Klaus and all,
Can someone tell me why I got 2 peaks in graph for below code. This is not related directly to xgraph. But maybe Klaus now the answer.

B4X:
#Region  Project Attributes
    #ApplicationLabel: B4A XGraph Integral
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: False
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Private xui As XUI
    Private Samples As Int
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    Private xGraph1 As xGraph
    Private FFT As xFFT
    Private TimeAccelleration(256), TimeVelocity(256) As Double
    Private FFTMagAccelleration(), FFTMagVelocity() As Double
    Private SineAmplitude, SineCyclesNumber, Omega As Double
    Private TimeAccIndex = 0 As Int
    Private TimeVelIndex = 2 As Int
    Private FFTAccIndex = 1 As Int
    Private FFTVelIndex = 3 As Int
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Layout")
    FFT.Initialize
    
    InitGraph
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Private Sub InitGraph
    Private i As Int
    
    xGraph1.CurveYName(TimeAccIndex) = "Time Acceleration"
    xGraph1.CurveYUnit(TimeAccIndex) = "m/s^2"
    xGraph1.CurveYName(TimeVelIndex) = "Time Velocity"
    xGraph1.CurveYUnit(TimeVelIndex) = "m/s"
    xGraph1.CurveYName(FFTAccIndex) = "FFT Acceleration"
    xGraph1.CurveYUnit(FFTAccIndex) = "m/s^2"
    xGraph1.CurveYName(3) = "FFT Velocity"
    xGraph1.CurveYUnit(3) = "m/s"
    
    xGraph1.CurvesToDisplay.Initialize2(Array As Int(0, 1, 2, 3))

    Samples = 256
    xGraph1.NbSamples = Samples
    
    ' number of sines in the time window (256 samples)
    ' you can play with NumberOfSines
    ' setting an integer number gives 1 frequency peak.
    ' with the values below you can see in the graph that:
    ' the frequency peak is at 9, which is the SineCyclesNumber
    ' the amplitude of the peak is 10, which is the SineAmplitude.
    ' setting a non integer value for the SineCyclesNumber will lower  the amplitude a bit and 'spread' the peak
'    SineCyclesNumber = 9.0
    SineCyclesNumber = 100.0
    SineAmplitude = 10
    Omega = 360 * SineCyclesNumber / Samples
    For i = 0 To Samples - 1
        TimeAccelleration(i) = SineAmplitude * CosD(i * Omega)
        xGraph1.CurveY(TimeAccIndex, i) = TimeAccelleration(i)
        xGraph1.CurveX(i) = i
    Next
    
    xGraph1.CalcIntegral(TimeAccIndex, TimeVelIndex, 0, False)

    For i = 0 To Samples - 1
        TimeVelocity(i) = xGraph1.CurveY(TimeVelIndex, i)
    Next
    
'    FFTMagAccelleration = FFT.Forward(TimeAccelleration)
    FFTMagVelocity = FFT.Forward(TimeVelocity)
    
    For i = 0 To Samples / 2 - 1
'        xGraph1.CurveY(FFTAccIndex, i) = FFTMagAccelleration(i)
        xGraph1.CurveY(FFTVelIndex, i) = FFTMagVelocity(i)
    Next
    

    xGraph1.CurveYName(TimeVelIndex) = "Time Velocity"
    xGraph1.CurveYUnit(TimeVelIndex) = "m/s"
    xGraph1.DrawCurves(Array As Int(FFTVelIndex))
End Sub
 

klaus

Expert
Licensed User
Longtime User
You need to give more explanation and information on what you want to achieve, what you have done and how !

Looking deeper on your question I remembered that you had already had some questions.

So, the problem is the numeric integration with a very very low number of data for one period of the sine curve !
You have 256 time samples and 100 sine periods which means that you have 2.5 points per sine period and this is by far not enough.
To get correct results you must have at least 10 points per sine period.

Image of the acceleration with 100 sine periods, zoomed.



This signal looks more like a random signal rather than a pure sine.

Image of the acceleration and the integration, velocity, zoomed.



Image with 30 sine periods ~10 points per sine period with the same zoom.



And the four signals unzoomed, and here you have only 1 peak as expected !



Attached the test project.

Now, what exactly do you want to achieve ?
I really do not understand your approach of this subject !?
 

Attachments

  • Xgraph3.zip
    27.9 KB · Views: 259
Last edited:

budakbaru

Member
Licensed User
Longtime User
Thanks Klaus. So I need to increase no of samples. Understand.
I'm reading about FFT conversion and try to see the result using what B4A function and library have.

Thanks for you long explanation and sample program.
 

kimstudio

Active Member
Licensed User
Longtime User
Dear klaus, thank you so much for sharing this, exactly what I need for a signal processing app.

I found the data and plot are coupling together so I am wondering if it is possible to decouple them and only a pointer of data saved in the xgraph? since usually the main app will load/process and manage data, then we have to copy that data to xgraph again. There are several curves in xgraph I don't know how to define an array of array reference.

For example:

B4X:
main.bas

dim datax() as double = array(1,...1000000000) 'manage data in main.bas, not directly operate data in xgraph
dim datay1() as double = func(datax)
dim datay2() as double = func(datay1)

Graph.CurveX = datax  'reference, can just define dim curvex() as double in xgraph I think
Graph.CurveY(0) = datay1  'how to define CurveY in xGraph? dim curvey(10, ?) as double??
Graph.CurveY(1) = datay2

Graph.DrawGraph
 

klaus

Expert
Licensed User
Longtime User
The default definitions in the xGraph module are the following.
B4X:
    Public CurveX(1000) As Double
    Public CurveY(10, 1000) As Double
You can change these settings in your code.
You cannot set a curve in xGraph like this: Graph.CurveY(0) = datay1
But, you can use Graph.CurveY(0) instead of datay1 anywhere in your code.
 

kimstudio

Active Member
Licensed User
Longtime User
Thanks klaus, you are right that I can use data in xGraph. I think my question is not directly related to xGraph so I will start a new thread about it.
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…