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

Current version 1.6

The xGraph Class and B4XLib allows graphic analysis of signals.
It works on all three products: B4A, B4i and B4J.

The graph holds a given number of curves (10 by default) with a given number of samples (10000 by default) these values can be defined in the Designer.
All curves have the same number of samples with the same X signal.

What can be done:
- Draw up to 4 curves on the same graph.
- Show values when moving the cursor on the graph.
- Zooming, either with the cursor or setting in the code.
- Different scale modes.
- Different methods on curves.
-- Copy a curve to another location.
-- Add a value to a curve.
-- Multiply a curve by a value.
-- Add two curves and save the result in another curve.
-- Multiply two curves and save the result in another curve.
-- Calculate the integral of a curve and save the result in another curve.
-- Calculate the derivative of a curve and save the result in another curve.

Attached the xGraphDemo.zip file contains three demo program using the xGraph.b4xlib library,
the xGraph.b4xlib library file, the xGraph.bas file and the xGraph.xml file.

The xGraph library needs the XUI, iXUI, or jXUI libraries.
The xGraphDemo programs need the XUI Views.b4xlib library.

EDIT: Version 1.6 2021.09.11
Amended some bugs

EDIT: Version 1.5 2021.03.19
Amended problem with tooltip label remaining visible.

EDIT: Version 1.4 2021.02.22
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

EDIT: 2020.06.23 Version 1.3
Added GraphWithMissingData and MissingDataValue properties
Updated the Tag property according to Erels recommandation:
Added two cursors with display of the curvevalues.
Added a Touch event which return
Added a CursorPositionChanged event returning the CursoorIndex and XIndex.
Added these properties XIndexBegin, XIndexEnd. GraphLeft, GraphTop, GraphWidth and GraphHeight
Version 1.2 2020.02.23
Set CurveColor to Public

EDIT: 2019.12.14 Version 1.1
Amended bug reported HERE

upload_2019-8-18_20-47-1.gif


1592918602205.png


1614016874650.png


Two synchronized graphs, the upper one zoomed, the bottom one not zoomed.
You see the zoomed part of the upper graph in the bottom one, light greaed.

xGraph

Author:
Klaus CHRISTL (klaus)
Version: 1.6
  • xGraph
    • Events
      • CursorPositionChanged (CursorIndex As Int, XIndex As Int)
      • Touch (Parameters() As TouchParameters)
        TouchParameters (Action As Int, X As Int, Y As Int, XIndex As Int)
        X and Y are screen coordinates.
    • Methods:
      • AddCursor (Color As Int)
        Adds a cursor with the given color by touching the graph
      • CalcAddValue (CurveIndex As Int, Value As Double, ZoomedPartOnly As Boolean)
        Adds a value to the given cuve
        ZoomedPartOnly = True calculates only the zoomed part if the curve is zoomed
      • CalcDerivative (SourceIndex As Int, DestinationIndex As Int, ZoomedPartOnly As Boolean)
        Calculates the derivative of the source curve and copies the result in the destination curve
        ZoomedPartOnly = True calculates only the zoomed part if the curve is zoomed
      • CalcDevide2Curves (SourceIndex1 As Int, SourceIndex2 As Int, DestinationIndex As Int, ZoomedPartOnly As Boolean)
        Devides two curves and copies the result in the destination curve
        Curve(DestinationIndex) = Curve(SourceIndex1) / Curve(SourceIndex2)
        ZoomedPartOnly = True calculates only the zoomed part if the curve is zoomed
      • CalcIntegral (SourceIndex As Int, DestinationIndex As Int, InitilalCondition As Double, ZoomedPartOnly As Boolean)
        Calculates the integral of the source curve and copies the result in the destination curve
        ZoomedPartOnly = True calculates only the zoomed part if the curve is zoomed
      • CalcMeanValue (CurveIndex As Int, ZoomedPartOnly As Boolean) As Double
        Returns the mean value of the given curve
        ZoomedPartOnly = True calculates only the zoomed part if the curve is zoomed
      • CalcMultiplyByValue (CurveIndex As Int, Value As Double, ZoomedPartOnly As Boolean)
        Multiplies the curve by the given value
        ZoomedPartOnly = True calculates only the zoomed part if the curve is zoomed
      • CalcMutiply2Curves (SourceIndex1 As Int, SourceIndex2 As Int, DestinationIndex As Int, ZoomedPartOnly As Boolean)
        Multiplies two curves and copies the result in the destination curve
        Curve(DestinationIndex) = Curve(SourceIndex1) * Curve(SourceIndex2)
        ZoomedPartOnly = True calculates only the zoomed part if the curve is zoomed
      • CalcRMSValue (CurveIndex As Int, ZoomedPartOnly As Boolean)
        Returns the RMS value of the given curve.
        ZoomedPartOnly = True calculates only the zoomed part if the curve is zoomed.
      • CalcSmooth (SourceIndex As Int, DestinationIndex As Int, Span As Int, ZoomedPartOnly As Boolean, SmoothType As String)
        Smooths the source curve and saves the result in the destination curve.
        The Smooth method takes the mean value of the number of samples given in Span around a sample and saves it at the same index.
        Number of samples must be an odd number, if an even number is enterd its value is incremented by 1.
        Documentation: https://en.wikipedia.org/wiki/Moving_average.
        ZoomedPartOnly = True calculates only the zoomed part if the curve is zoomed.
        SmoothType = "MEAN" or "RMS".
        Be aware that with RMS smothing, and nagative values, you will get wrong data.
        Example code:

        xGraph1.CalcSmooth(2, 4, 5, False, "MEAN")
      • CalcSmoothExponentialLag (SourceIndex As Int, DestinationIndex As Int, Kt As Double, ZoomedPartOnly As Boolean)
        Smooths the source curve and saves the result in the destination curve, sort of low pass filter.
        The smoothing algorithm is a first order lag which implements an exponential response to a step input Kt must be smaller than 1.0
        yd[t] = yd[t-1] + Kt (ys[t] - yd[t-1])
        yd = destination ys = source
        Documentation:
        https://en.wikipedia.org/wiki/Exponential_smoothing
        Routine kindly provided by rgarnett
        Example code:

        xGraph1.CalcSmoothExponentialLag(2, 4, 0.5, False)
      • CalcSmoothExponentialLead (SourceIndex As Int, DestinationIndex As Int, Kt As Double, ZoomedPartOnly As Boolean)
        Smooths the source curve and saves the result in the destination curve, sort of high pass filter.
        The smoothing algorithm is a first order lead which implements an step response and exponential decay to a step input. Kt must be smaller than 1.0.
        yd = Kt (ys[t]- yd[t-1])
        ydLast = y[t-1] + yt
        yd = destination ys = source.
        Routine kindly provided by rgarnett1955.
        Example code:

        xGraph1.CalcSmoothExponentialLead(2, 4, 0.5, False)
      • CalcSubtract2Curves (SourceIndex1 As Int, SourceIndex2 As Int, DestinationIndex As Int, ZoomedPartOnly As Boolean)
        Substracts two curves and copies the result in the destination curve
        Curve(DestinationIndex) = Curve(SourceIndex1) - Curve(SourceIndex2)
        ZoomedPartOnly = True calculates only the zoomed part if the curve is zoomed
      • CalcSum2Curves (SourceIndex1 As Int, SourceIndex2 As Int, DestinationIndex As Int, ZoomedPartOnly As Boolean)
        Adds two curves and copies the result in the destination curve
        Curve(DestinationIndex) = Curve(SourceIndex1) + Curve(SourceIndex2)
        ZoomedPartOnly = True calculates only the zoomed part if the curve is zoomed
      • CopyCurve (SourceIndex As Int, DestinationIndex As Int)
        Copies the curve with SourceIndex to the DestinationIndex curve.
      • DeSynchronize
        Desynchronizes two synchronized xGraph objects.
      • DrawCurve (Index As Int)
        Draws the curve with the given index.
        Example code:

        xGraph1.DrawCurve(2)
      • DrawCurves (Indexes() As Int)
        Draws the curves with the given indexes.
        Example code:

        xGraph1.DrawCurves(Array As Int(0,1,2,3))
      • DrawGraph
        Draws a graph
      • GetScaleAuto (CurveIndex As Int) As ScaleValues
        Gets the automatic scale for the given curve
      • GetScaleManu (CurveIndex As Int) As ScaleValues
        Gets the manual scale for the given curve
      • Initialize (Callback As Object, EventName As String)
      • NumberFormat3 (Number As Double, MaxDigits As Int) As String
        Formats numbers with a fixed number of digits and scientific notation
      • RemoveCursor (Index As Int)
        Removes one or both cursors.
        Set 0 or 1 as cursor index to delete one cursor.
        Set 2 to delete both cursors.
        When you remove cursor(0) cursor(1) becomes cursor(0), it is removed from the list.
        If there is only one Cursor, then any index value will remove the cursor.
      • SelectGraph (Selected As Boolean)
        Sets the xGraph object to Selected or not.
        Selected = True, draws a colored line at the right side.
        Selected = False, removes the colored line.
        Used when two xGraph objects are synchronized.
        Draws a line at the right side of the graph.
      • SetCursor (XIndex As Int, CursorIndex As Int, Color As Int)
        Sets one of the two cursors.
        XIndex = sample index, in the curve array.
        CursorIndex = 0 or 1, index of the cursor.
      • SetCurveName (CurveIndex As Int, Name As String, UpdateGraph As Boolean)
        Sets the a new name for the curve with the given index
        UpdateGraph = True redraws the graph
      • SetCurveUnit (CurveIndex As Int, Unit As String, UpdateGraph As Boolean)
        Sets a new unit for the curve with the given index
        UpdateGraph = True redraws the graph
      • SetGraphToSynchronize (GraphToSynchronize As XGraph, SelectedGraphShow As Boolean, SelectedGraphColor As Int, SynchronizeZoom As Boolean, DisplaySynchronizedZoomArea As Boolean)
        If you have two xGraph objects you can synchronize them.
        Condition: the X scales must be the same.
        Cursors and zoom are active on both objects.
        GraphToSynchronize = xGraph object to synchronize.
        SelectedGraphShow = True shows a line at the right side of the graph, with the SelectedGraphColor.
        SelectedGraphColor = color of the line at the right side of the graph.
        SynchronizeZoom = True synchronizes the zoom in both graphs.
        = False you can have two different zoom levels in the two graphs.
        DisplaySynchronizedZoomArea = True, when one graph is zoomed and the other not, displays the zoomed area in the other graph.
        = False, does not display the zoomed area.
        Example code:

        xGraph1.SetGraphToSynchronize(xGraph2, True, xui.Color_Red, True)
        xGraph2.SetGraphToSynchronize(xGraph1, True, xui.Color_Blue, True)

        To synchronize two xGraph objects, you need to add the two lines above in your code.
      • SetSameScale (SameScaleCurveIndex As Int)
        Sets the scale of curve SameScaleCurveIndex for all curves
      • SetScaleManu (CurveIndex As Int, MinVal As Double, MaxVal As Double)
        Sets a manual scale for a given curve
      • SetZoomIndexes (BeginIndex As Int, EndIndex As Int)
        Sets the begin and end indexes for zoom diaplay
      • SetZoomMode
        Sets the zooming mode
        The user selects with the curor the left limit and then the right limit
      • UnZoom
    • Properties:
      • AutomaticYScales
        Gets or sets the automatic scales mode
        True displays automatic Y sacales for all curves
        False displays the manual scales
      • CurvesToDisplay
        Gets or sets the curves to display
      • DisplayCurveIndex
        Gets or sets the DisplayCurveIndex property
        True displays the curve index before the curve name
        Example: 3 : Speed
      • DisplayCurveUnit
        Gets or sets the DisplayCurveUnit property
        True displays the curve unit after the curve name
        Example: Speed [m/s]
      • DisplaySynchronizedZoomArea
        When two xGraph objects are synchronized and when one graph is zoomed and the other not,
        True > displays the zoomed area in the other graph
        False > does not display the zoomed area in the other graph.
      • DrawCursorValues
        gets or sets the DrawCursorValues property
        Displays the values of the cuves at the cursor position
      • GraphColor
        Gets or sets the graph background color
      • GraphHeight
        Gets the GraphHeight property
        The height of the Graph in pixels
      • GraphLeft
        Gets the GraphLeft property
        The left position of the Graph in pixels
      • GraphTop
        Gets the GraphTop property
        The top position of the Graph in pixels
      • GraphWidth
        Gets the GraphWidth property
        The width of the Graph in pixels
      • GraphWithMissingData
        Gets or sets the GraphWithMissingDat property
        Manages curves with missing data, it is necessary to enter the MissingDataValue in place.
      • GridColor
        Gets or sets the graph grid color
      • GridFrameColor
        Gets or sets the graph grid frame color
      • Height
        Gets or sets the Height property
      • Left
        Gets or sets the Left property
      • MissingDataValue
        Gets or sets the MissingDataValue property
        Used when GraphWithMissingData = True, the missing data must be replaced by this value
      • NbMaxCurves
        Gets or sets the max number of curves
      • NbMaxSamples
        Gets or sets the max number of samples
      • NbSamples
        Gets or sets the current number of samples
      • NbXIntervals
        Gets or sets the number of x axis intervals
      • NbYIntervals
        Gets or sets the number of y axis intervals
      • NumberOfCursors
        Gets the current number of cursors.
      • OuterFrame
        Gets or sets the graph outer frame property
        True = draws an outer frame around the graph
      • OuterFrameColor
        Gets or sets the graph outer frame color
      • ScaleXValues
        Gets or sets the ScaleValues property
        it is a string with the different scale values separated by an exclamation mark.
        it must begin with 1! and end with !10
        Example: the default property 1!2!2.5!5!10
        These values can be selected in the Designer: 1!2!2.5!5!10|1!1.2!1.5!1.8!2!2.5!3!4!5!6!7!8!9!10
      • ScaleYValues
        Gets or sets the ScaleValues property
        used for automatic scales
        it is a string with the different scale values separated by the exclamation mark.
        it must begin with 1! and end with !10
        Example: the default property 1!2!2.5!5!10
        These values can be selected in the Designer: 1!2!2.5!5!10|1!1.2!1.5!1.8!2!2.5!3!4!5!6!7!8!9!10
      • Snapshot
        Returns a B4XBitmap object of the graph (read only)
      • SynchronizeZoom
        When two xGraph objects are synchronized.
        Synchronize the zoom in both graphs.
      • Title
        Gets or sets the graph title
      • Top
        Gets or sets the Top property
      • UseCustomColors
        Gets or sets the UseCustomColors property.
        UseCustomColors = False, 4 colors and widths are used for superimpositions they remain the same independant of the curves displayed.
        UseCustomColors = True, one specific color and width can be defined for each curve.
      • Width
        Gets or sets the Width property
      • XAxisName
        Gets or sets the x axis name
      • XAxisUnit
        Gets or sets the x axis uni
      • XIndexBegin
        Gets the XIndexBegin property
        Index of the first visible item
      • XIndexEnd
        Gets the XIndexBegin property
        Index of the last visible item
 

Attachments

  • xGraphDemoV1_6.zip
    198.3 KB · Views: 17
  • xGraph.b4xlib
    16.9 KB · Views: 18
  • xGraph.bas
    94.4 KB · Views: 19
  • xGraph.xml
    34.3 KB · Views: 17
Last edited:

rgarnett1955

Active Member
Licensed User
I could add two new properties GraphWithMissingSamples and MissingSampleValue.

GraphWithMissingSamples, when set to True, tests for missing samples. When set to False avoids wasting time to check for missing sample values.
Two different DrawCurves routines.

MissingSampleValue = a specific value representing a missing sample. Default value = 1000000000

It would look like this:

View attachment 86434


Hi Klaus,

Sorry I didn't reply, I'm still getting to grips with the forum. I have trouble finding stuff I've put in.

I think your solution is exactly what I need. Could the missing sample value be set to NaN by 0/0?

I like using NaN's as they show up in tables and stand out from other numeric data, but this is not essential.

On another related topic would it be possible to provide a callback function for the cursor values. Reason being I use charts with a lot of date/time for the x axis.

I will create another post for this.


Best regards

Rob
 

klaus

Expert
Licensed User
The xGraph library has been updated to version 1.3 in the first post.

EDIT: 2020.06.23 Version 1.3
Added GraphWithMissingData and MissingDataValue properties
Updated the Tag property according to Erels recommandation:
https://www.b4x.com/android/forum/t...lv-or-any-other-container.117992/#post-738358
Added two cursors with display of the curvevalues.
Added a Touch event which return
Added a CursorPositionChanged event returning the CursoorIndex and XIndex.
Added these properties XIndexBegin, XIndexEnd. GraphLeft, GraphTop, GraphWidth and GraphHeight
Version 1.2 2020.02.23
Set CurveColor to Public
 
Last edited:

laviniut

Active Member
Licensed User
Please help me to save a graph snapshot to a root directory named "DPF Graph Snapshots".
 

laviniut

Active Member
Licensed User
I used this code
B4X:
Sub savesnapshot
    Dim bmp As B4XBitmap = SingleLine1.Snapshot
    Dim out As OutputStream
    out = File.OpenOutput(File.DirInternal, "mybitmap.png", False)
    bmp.WriteToStream(out, 100, "PNG")
    out.Close
End Sub
and i have no errors but i need to save it to dirrootexternal "DPF Graph Snapshots" directory.
 

laviniut

Active Member
Licensed User
Thank you, i used this code
B4X:
Sub savesnapshot
    Dim rp As RuntimePermissions
    rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result Then
        'access here
        Dim bmp As B4XBitmap = SingleLine1.Snapshot
        Dim out As OutputStream

        Dim mydir As String
        mydir = File.DirRootExternal & "/DPF Graph Snapshots/"
'    out = File.OpenOutput(File.DirRootExternal, "snap.png", False)
        out = File.OpenOutput(mydir, "snap.png", False)
        bmp.WriteToStream(out, 100, "PNG")
        out.Close
    Else
        'no permission
    End If
    
End Sub
and i get an error
java.lang.Exception: Sub activity_permissionresult was not found.
 

laviniut

Active Member
Licensed User
I put this
B4X:
Sub Activity_PermissionResult (Permission As String, Result As Boolean)
    
End Sub
and error was the same
java.lang.Exception: Sub activity_permissionresult was not found.
 

rgarnett1955

Active Member
Licensed User
Can it be used to display real-time data (Dynamic Graph) ?

Hi,

I am not sure why Klaus says that you cannot use xGraph for real time.

I use xGraph to display real time data at slow sample rates (see below). I am using xGraph with two charts of 7200 samples each with a number of curves on each plot and can update it at 1 to 2 second intervals with no problems and very small processor impact (negligible) I haven't tried faster than that, but I reckon 200 ms would be feasible. The underlying graphics engine of xGraph seems to be double buffered so there is no screen flicker on update. The curves just slowly increment across the screen.

It's an excellent package. I've used a lot of line plot realtime graph packages in my work and xGraph is one of the best I've used. I reckon xGraph is as good as Matlab's plotting function and is more flexible.



mMon.png
 

klaus

Expert
Licensed User
Thank you for your nice comments.

I am not sure why Klaus says that you cannot use xGraph for real time.
For me, when people speak of real time acquisition, it means with high to very high sampling rates.
That's the reason of my answer.

BTW, have you seen this post?
 

rgarnett1955

Active Member
Licensed User
Thank you for your nice comments.


For me, when people speak of real time acquisition, it means with high to very high sampling rates.
That's the reason of my answer.

BTW, have you seen this post?

Hi Klaus,

I understand, but that's a little bit arbitrary and not the correct definition of real time. A real time system is one where the calculations for each output are completed and displayed/stored/acted on, within a deterministic time which may be the fundamental sample time of the inputs or some higher ratio thereof.

Of course sample times vary considerably depending on the bandwidth of the physical system being monitored; for example in a thermal power station sample times are typically
  • Boiler turbine thermal and flow 0.1 to 1000 seconds
  • Turbine governor 10 to 20 mS
  • Vibration monitoring 5 kHz to 40 kHz
  • Pressure parts crack detection 100 kHz
  • Video 1 to 10 MHz depending on resolution and frame rate
  • Weather (Ambt temp, humidity) 300 s to 1800 s
  • Radar fluid level detection 1 to 10 MHz
An interesting example is the display of an audio spectrum. Forgetting about powers of two; to simplify lets say we have a 1000 point FFT of an audio signal sampled at 40 KHz. We will get a spectra calculated at a rate of 40 Hz. (25 ms). There would be no point in displaying these spectra at 40 Hz into a line or bar graph. It would compete with the display unit's frame rate. It would be a flickering blurr to the human eye.

What you would do is perform some sort of average of each FFT bin and display that at a a much lower rate. Usually for dynamically changing spectra this is a first order difference equation usually termed exponential filtering. Bin amplitude peak detection with slow decay is also often used. The bandwidth of the output is usually reduced by a factor of ten or more using these methods so you would have an output every 100 to 400 ms. Thus the graphics program to display this spectra only has to handle 500 pts (nFFT / 2) every 100 to 400 ms. I think that both xGraph and xChart could handles these sort of data rates, even though the audio sample rates can be up to 96 k.

In a sense, graphs display information, not data and as the human is limited in cognitive bandwidth, high visual information rates for graphs are of little use.

Of course it's a different case for video, but that's beyond the scope of this particular issue.

Anyway that's my take on it. I hope this may be useful for people designing systems for real-time data display.

Best regards
Rob
 
Last edited:

klaus

Expert
Licensed User
I understand all this, no problem.
I just gave the reason why I answered this.
And because there is no build-in function in the class to acquire real time data.

But you have not answered my second question:
BTW, have you seen this post?
It is in a thread you opened.
 

rgarnett1955

Active Member
Licensed User
Hi Klaus,

I was pretty sure that you did understand all this, but a lot of people don't so I tried to explain for them. I am retired so I have plenty of time to write stuff so I try to use the forum to help less experienced people not so much with programming, but with the use of code in engineering type apps. I have got a lot from B4X so I try to give something back. I have tried a lot of different languages for use in the PC environment with decent UI's and B4X is the only one that makes sense. Before I tried B4X I used Python and Qt, but both of them are resource hungry and didn't have very good support. I spent more time Googling than writing! B4X is lightweight, is robust and the library system is dead easy to use. I did use Matlab a lot in my job, but it's prohibitively expensive for home use. If you want the compiler for Matlab to produce stand alone apps you are up for $10,000 Aus. for the compiler and its not a very robust.

Sorry I didn't answer your second question, but I am not sure what point you were making with it so I kind of skipped over it.

I haven't been able to do the testing on the latest xGraph as I had a knee replacement early December, it was worn out from, skiing and volleyball and I have been trying to wrap up some other projects I was working on. I hope to get to it in a couple of weeks.

Best regards
Rob
 
Last edited:

budakbaru

Member
Licensed User
Dear Klaus,
Sorry to bother you with these problems.

As file attached, I set curve name for 1st curve as acceleration and 2nd curve as velocity. 2nd curve is created using integral function of 1st curve.
I would to have the curve name for 2nd curve as set in the code as "velocity" but it displayed as integral acceleration. Can it be changed to that please.

Another one is about the integral. As in the attached file 2nd curve has 0 as the lowest value. How to determine suitable value for initialcondition in the integral fucnction. I expect the the curve will have plus minus value for the amplitudes.

Thanks in advance.
 

Attachments

  • Xgraph.zip
    4.1 KB · Views: 50

klaus

Expert
Licensed User
As file attached, I set curve name for 1st curve as acceleration and 2nd curve as velocity. 2nd curve is created using integral function of 1st curve.
I would to have the curve name for 2nd curve as set in the code as "velocity" but it displayed as integral acceleration. Can it be changed to that please.
Sure !
Move these two lines
B4X:
    xGraph1.CurveYName(1) = "Velocity"
    xGraph1.CurveYUnit(1) = "m/s"
After the calculation.
You could also use this:
B4X:
    xGraph1.SetCurveName(1, "Velocity", False)
    xGraph1.SetCurveUnit(2, "m/s", False)



Another one is about the integral. As in the attached file 2nd curve has 0 as the lowest value. How to determine suitable value for initialcondition in the integral fucnction. I expect the the curve will have plus minus value for the amplitudes.
If you know the initial value you can directly enter it in the integral calculation method, it is the third parameter :
B4X:
    xGraph1.CalcIntegral(0, 1, 0, False)

In your case you do not know it before the calculation, therefore you need to calculate the mean value and subtract it:
B4X:
    xGraph1.CalcIntegral(0, 1, 0, False)
    Private MeanValue As Double
    MeanValue = xGraph1.CalcMeanValue(1, False)
    xGraph1.CalcAddValue(1, -MeanValue, False)
    xGraph1.CurveYName(1) = "Velocity"
    xGraph1.CurveYUnit(1) = "m/s"
'    xGraph1.SetCurveName(1, "Velocity", False)
'    xGraph1.SetCurveUnit(2, "m/s", False)

1613218020781.png


But, the velocity of your moving object is probably 0 !
Then your acceleration calculation is wrong.
It should be:
B4X:
xGraph1.CurveY(0, i) = 10 * CosD(i * 9)
instead of:
B4X:
xGraph1.CurveY(0, i) = 10 * SinD(i * 9)

1613218046560.png


PS: The xGraph library will be updated today or tomorrow.
I found the problem of point 1. from HERE.
 

Attachments

  • Xgraph1.zip
    9.6 KB · Views: 51

Peter Meares

Member
Licensed User
Klaus
I was just playing with XChart demo and provoked a repeatable error.
Select graph Acceleration, Then Manu and 1.
Great program, thanks.

main._rbtsamescales_selectedchange (java line: 503)
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.rangeCheck(ArrayList.java:657)
at java.util.ArrayList.get(ArrayList.java:433)
at anywheresoftware.b4a.objects.collections.List.Get(List.java:105)
at b4j.xGraphDemo.main._rbtsamescales_selectedchange(main.java:503)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
at anywheresoftware.b4a.BA$1.run(BA.java:216)
at com.sun.javafx.application.PlatformImpl.lambda$null$177(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$178(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$152(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
 

budakbaru

Member
Licensed User
Dear Klaus,
I try using FFT to convert an array to fft spectrum then try to show use xgraph to plot it. But nothing was plotted in the graph.
I put Log in the loop to see the magnitude values, there were values in the magnitude array. Could you please check for me.
I attached the file.
After that I would like to integrate the magnitude using CalcIntegral method and see the result plot.
 

Attachments

  • Xgraph.zip
    19.9 KB · Views: 49

budakbaru

Member
Licensed User
Sorry Klaus,
I made mistake.
graph.nbsamples should be 128.
Then the graph plotted successfully.

But the integration look no good. Or should I integrate the data 1st before do the fft?
 

klaus

Expert
Licensed User
I was looking at the problem, you found the same as I and I was just about answering.

But the integration look no good.
What do you expect ?
I do not understand the purpose of integrating the FFT amplitude signal ?

The acceleration signal in your example is a pure sine signal which gives one frequency line. This is the peak you see in the graph.
If you integrate the acceleration signal to get the velocity and calculate the FFT you will get also one peak with the same frequency but with another amplitude.

Then I do not understand the meaning of the x axis values in your project?
 
Top