Android Question xChart on xCustomListView trouble

peacemaker

Expert
Licensed User
Longtime User
HI, All

If to use xChart on a Layout that should be loaded into items of xCustomListView - i have the error
B4X:
java.lang.IllegalArgumentException: width and height must be > 0
at
B4X:
Sub CreateListItem(Text As Map, Width As Int, Height As Int) As Panel
    Dim p As Panel
    p.Initialize("")
    p.SetLayout(0, 0, Width, Height)
    p.LoadLayout("cell_vote")    'HERE DURING Initialization

'Here in the class
xcvsGraph.Initialize(xBase)

Any help ?
 

peacemaker

Expert
Licensed User
Longtime User
a small project
Attached.

Also tried the run-time creation of xChart, but it's imposible, as it's not a View object type.

B4X:
Sub Activity_Refresh
    clv.Clear

    For i = 0 To 5
        Dim m As Map
        m.Initialize
        Dim p As B4XView = CreateListItem(m, clv.AsView.Width, 95dip)
        clv.Add(p, i)
        Dim BarChart2 As xChart
        BarChart2.Initialize(Me, "BarChart2")
        p.AddView(BarChart2, 0, 0, p.Width, p.Height)

Error:
B4X:
Compiling generated Java code.    Error
B4A line: 45
p.AddView(BarChart2, 0, 0, p.Width, p.Height)
javac 1.8.0_151
src\xChart\xCustomListView\main.java:442: error: incompatible types: xchart cannot be converted to View
_p.AddView((android.view.View)(mostCurrent._barchart2),(int) (0),(int) (0),_p.getWidth(),_p.getHeight());
                              ^

And tried loading by extra Layout after the parent is created:
B4X:
    For i = 0 To 5
        Dim m As Map
        m.Initialize
        Dim p As Panel = CreateListItem(m, clv.AsView.Width, 95dip)
        clv.Add(p, i)
        p.LoadLayout("cell_xchart")


'Again error:
java.lang.IllegalArgumentException: width and height must be > 0
 

Attachments

  • sample_to_debug.zip
    30 KB · Views: 235
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
Here you are.
The main problem was the vertical anchor of BarChart2 set to both and the use of an old version of CustomListView.
I replaced the CustomListView by the xCustomListView library.
There were also some problems in the xChart module.
Attached a modified project.
The height of each panel in the CustomListView is calculated in the CreateListItem routine according to the layout.
 

Attachments

  • sample_to_debug1.zip
    25.3 KB · Views: 248
Upvote 0

klaus

Expert
Licensed User
Longtime User
so xChart class is not changed\updated
Will come soon, in the project in post #4, the xChart module is updated.
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
in the project in post #4, the xChart module is updated.
I tried to run the example that @klaus fixed in post #4. It runs well for bar graph. But if I try to run it for line graph, it returns this error:
Error occurred on line: 470 (xChart)
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.RectF.round(android.graphics.Rect)' on a null object reference
All i did is:
Replace this line:
B4X:
BarChart2.AddBar("", color)
With:
B4X:
BarChart2.AddLine("", color)
And Replace this line:
B4X:
BarChart2.AddBarPointData($"${j}"$, Rnd(0, 200))
With:
B4X:
BarChart2.AddLinePointData($"${j}"$, Rnd(0, 200), False)
Anything else I need to do to make it work for a line graph?
Thank you
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
You should use the last update in the xChart thread, which includes a demo program.
There you will see how to generate a LINE chart.
For a line chart you must:
Set the Chart type to LINE.
Add a line with Chart1.AddLine
Add points either with
Chart1.AddLineMultiplePoints(... for multiple lines
or
Chart1.AddLinePointData(... for a single line
You can also use Chart1.AddLineMultiplePoints(... for a single line with one value in the points array.
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
You should use the last update in the xChart thread
Even after updating the project in post #4 to the 2.60 xChart class, I get the same error. Please see attached project
Error occurred on line: 544 (xChart)
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.RectF.round(android.graphics.Rect)' on a null object reference
Please check it out. Thanks
 

Attachments

  • xCustomeListViewxChart110618.zip
    26.5 KB · Views: 193
Upvote 0

klaus

Expert
Licensed User
Longtime User
Thank you for reporting this.
There was a problem in the class.
Attached the modified project.
I will update the class tomorrow.
 

Attachments

  • xCustomeListViewxChart110618_1.zip
    26.1 KB · Views: 190
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Attached the modified project.
The modified class and project in post #12 allowed me to get a line graph. But, if I increase the number from 5 to say 75 as in this line:
For i = 0 To 75 instead of For i = 0 To 5 I get out of mem error with 75 or 100.
Maybe, using lazy loading here which I could not figure out may remove that error.
java.lang.OutOfMemoryError: Failed to allocate a 677156 byte allocation with 165332 free bytes and 161KB until OOM

Thank you
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
Maybe, using lazy loading here which I could not figure out may remove that error.
Probably yes.
I tested the program from post #12 with 200 xCharts and get no error on my Samsung S8.
It takes some time to get the screen filled.
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
I tested the program from post #12 with 200 xCharts and get no error on my Samsung S8.
I tested it on a Galaxy S6 phone and it crashes with 100 charts. So it depends on the device's memory. Having a poor understanding of lazy loading, I could not integrate it in an xCustomListView with xCharts. Maybe someone with a better grasp of lazy loading can help us below:
B4X:
Sub clv_VisibleRangeChanged (FirstIndex As Int, LastIndex As Int)
    Dim ExtraSize As Int = 20
    For i = 0 To clv.Size - 1
        Dim p As B4XView = clv.GetPanel(i)
        If i > FirstIndex - ExtraSize And i < LastIndex + ExtraSize Then
            'visible+
            If p.NumberOfViews = 0 Then
'                'missing code
                Dim mp As Map=clv.GetValue(i)
                p.LoadLayout("cell_vote")
                'missing code
            End If
        Else
            If p.NumberOfViews > 0 Then
                p.RemoveAllViews
            End If
        End If
    Next
End Sub
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Example with lazy loading is attached.

The charts are reused. Note that I've made xBase a public variable.

The layout itself, without the chart, is eagerly loaded. It shouldn't be too difficult to change it and only load the layout when needed. The "heavy" view however is the chart.

Tested with 1000 charts, it takes some time to load all the layouts but once loaded the list performs nicely.
 

Attachments

  • xCLVXChart.zip
    27.3 KB · Views: 254
Upvote 0

klaus

Expert
Licensed User
Longtime User
Wow! Amazing!
I made just a few changes, because there is no need to set the chart properties in the code, I set them directly in the Designer.
 

Attachments

  • xCLVXChart1.zip
    27.4 KB · Views: 336
Upvote 0
Top