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

rgarnett1955

Active Member
Licensed User
Longtime User


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
Longtime 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
Longtime User
Please help me to save a graph snapshot to a root directory named "DPF Graph Snapshots".
 

laviniut

Active Member
Licensed User
Longtime 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
Longtime 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
Longtime 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
Longtime 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.



 

klaus

Expert
Licensed User
Longtime 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
Longtime 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
Longtime 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
Longtime 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
Longtime 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: 240

klaus

Expert
Licensed User
Longtime User
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)



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)



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: 231

Peter Meares

Member
Licensed User
Longtime 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
Longtime 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: 225

budakbaru

Member
Licensed User
Longtime 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
Longtime 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?
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…