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

klaus

Expert
Licensed User
Longtime User
I have installed iOS 16 on my iPad and your test project still woks OK.

Anyway, to me it looks strange that this line could be the problem.
B4X:
pnlBarCharts.AddBarPointData("2022-11-1" & i,68113.49)
Because AddBarPointData expects a Double and 68113.49 is a Double.
 

bigbadfred

Member
Licensed User
Longtime User
Hi Klaus, a very happy New Year to u!
Is my assumption right that in the line chart the CursorPointIndex in the xChart_CursorTouch event does not change anymore AFTER setting the zoom indexes?
I want to zoom in and zoom in until the user sees fit.
Only after unzooming the chart I can zoom in again, but only ONCE.
 

klaus

Expert
Licensed User
Longtime User
Is my assumption right that in the line chart the CursorPointIndex in the xChart_CursorTouch event does not change anymore AFTER setting the zoom indexes?
Thank you for reporting this.
I see it too.
It will be updated tomorrow.
 

bigbadfred

Member
Licensed User
Longtime User
Thank you for reporting this.
I see it too.
It will be updated tomorrow.
Thanks, Klaus, I was a bit afraid that I hadn't read the forums thoroughly enough, but apparently I had ;-)
I love your xChart library!
 

bigbadfred

Member
Licensed User
Longtime User
@bigbadfred
Can you please test the attached xChart.b4xlib.
Unfortunately that didn't do the trick, Klaus.
I log CursorPointIndex in the xChart1_CursorTouch event during action 2, and after having zoomed in once the CursorPointIndex doesn't change anymore.
The first time zooming in is ok, after that it shows a non-changing value which I think is the left x-value of the data points shown in the chart.

EDIT:Before your update I was working with version 9.20.
However, I see that you are working on a lot of properties & events that might benefit me.
Perhaps it's best to wait until you have finished your latest library update?
 

bigbadfred

Member
Licensed User
Longtime User
Can you post your project ?
Before posting my previous post, i checked it in a B4J test project.
My project is way too big to post.
I'll experiment a little away with this new library and will try to find a solution for what I'm looking for.
Whenever I have a working solution I'll let you know.
Thank you very much till so far!
 

bigbadfred

Member
Licensed User
Longtime User
Can you post your project ?
Before posting my previous post, i checked it in a B4J test project.
Hi Klaus,
I made the following changes in xChart.bas which work for me.
As I am only using the Line Chart, I don't know if this will interfere with other charts or functionality.
The result is that I can drag my finger over the chart to zoom in and zoom in and zoom in again.
I have a lower limit of 7 (days), because my fat finger clicks were interpreted as a move instead of a click (I have almost 2000 data points).
In "xChart1_CursorTouch (Action As Int, CursorPointIndex As Int)" I determine the starting and ending point using actions up, down and move.
That enables me to zoom in between those 2 values.

B4X:
Private Sub GetCursorIndex(X As Float, Y As Float) As Int
    Private Index As Int

    If Graph.ChartType <> "PIE" Then
        Select Graph.ChartType
            Case "BAR", "STACKED_BAR", "CANDLE", "WATERFALL"
                Index =(x - Graph.Left - Graph.XOffset) / Graph.XInterval
            Case "LINE", "AREA", "STACKED_AREA"
                Index = (x - Graph.Left) / Scale(sX).Scale + 0.5
            Case "RADAR"
                Private Angle As Double
                Angle = ATan2D(y - Graph.CenterY, x - Graph.CenterX)
                If Angle < 0 Then
                    Angle = Angle + 360
                End If
                Index = Angle * Zoom.NbVisiblePoints / 360 + 0.5
                Angle = 360 / Zoom.NbVisiblePoints * Index
                Angle = (ATan2D(y - Graph.CenterY, x - Graph.CenterX) + 360 - Graph.RadarStartAngle)
                If Angle < 0 Then
                    Angle = Angle + 360
                Else If Angle > 360 Then
                    Angle = Angle - 360
                End If
                Index = Angle * Zoom.NbVisiblePoints / 360 + 0.5
        End Select
        '20230103 I want the exact coordinates within the entire chart returned to me
'        Index = Max(Index, Zoom.BeginIndex)
'        Index = Min(Index, Zoom.EndIndex)
        Index = Min(Points.Size-1, Index + Zoom.BeginIndex)
        If Index < 0 Then Index = 0
    End If
    
    Return Index
    
End Sub

Public Sub SetZoomIndexes(BeginIndex As Int, EndIndex As Int)
    Private Val As Int
    
    If BeginIndex = Zoom.BeginIndex And EndIndex = Zoom.EndIndex Then
        Return
    End If
    
'    BeginIndex = Max(BeginIndex, 0)
'    EndIndex = Min(EndIndex, Points.Size - 1)
    '20230103 I already determine the allowed values
    'BeginIndex = Max(BeginIndex, Zoom.BeginIndex)
    'EndIndex = Min(EndIndex, Zoom.EndIndex)
    ........................................................ etc
 

klaus

Expert
Licensed User
Longtime User
I made the following changes in xChart.bas which work for me.
I had a closer look at the problem.
There was a problem in the GetCursorIndex. i missed that one when i tested it.
To get the right values i added + Zoom.BeginIndex in line #9 below.
B4X:
Private Sub GetCursorIndex(X As Float, Y As Float) As Int
    Private Index As Int

    If Graph.ChartType <> "PIE" Then
        Select Graph.ChartType
            Case "BAR", "STACKED_BAR", "CANDLE", "WATERFALL"
                Index =(x - Graph.Left - Graph.XOffset) / Graph.XInterval
            Case "LINE", "AREA", "STACKED_AREA"
                Index = (x - Graph.Left) / Scale(sX).Scale + 0.5 + Zoom.BeginIndex
            Case "RADAR"

Can you please test the attached library, thank you in advance.

EDIT: Removed the file.
 
Last edited:

bigbadfred

Member
Licensed User
Longtime User
Yep, this one is working perfectly!

Thanks, Klaus!
 

dlh_007

Member
Licensed User
在计算自动比例时,如果Axis为sX,且最小值为0时,X轴最小值出现了负值。我增加了两个属性:XZeroAxis,XZeroAxisHighlight,强制X轴的最小值为零,
出错位置:
B4X:
If (Scale(Axis).MinAuto >= 0 And Scale(Axis).YZeroAxis = False) Or (Scale(Axis).MaxAuto <= 0 And Scale(Axis).YZeroAxis = False) Or (Scale(Axis).MinAuto < 0 And Scale(Axis).MaxAuto > 0) Then
        If ValMinMax(0) < 0 And ValMinMax(1) > 0 Then
            NbUsedIntervalsTop = Ceil(ValMinMax(1) / Scale(Axis).IntervalAuto - 0.00000000000001)
            NbUsedIntervalsBottom = Ceil(Abs(ValMinMax(0)) / Scale(Axis).IntervalAuto - 0.00000000000001)
            NbUsedIntervals = NbUsedIntervalsTop + NbUsedIntervalsBottom
            If NbUsedIntervalsTop - NbUsedIntervalsBottom = 1 Then
                NbIntervalsToMove = Scale(Axis).NbIntervals / 2 - NbUsedIntervalsBottom
            Else
                NbIntervalsToMove = (Scale(Axis).NbIntervals - NbUsedIntervals) / 2
            End If
        Else
            NbUsedIntervals = Ceil(ValDiff / Scale(Axis).IntervalAuto - 0.00000000000001)
            NbIntervalsToMove = (Scale(Axis).NbIntervals - NbUsedIntervals) / 2
        End If
        Scale(Axis).MinAuto = Scale(Axis).MinAuto - Scale(Axis).IntervalAuto * NbIntervalsToMove
    End If
改进方案:
B4X:
#DesignerProperty: Key: XZeroAxis, DisplayName: XZeroAxis, FieldType: Boolean, DefaultValue: True, Description: Sets automatically the min value to 0 if all values are > 0 and max valule to 0 if all values are < 0.
#DesignerProperty: Key: XZeroAxisHighlight, DisplayName: XZeroAxisHighlight, FieldType: Boolean, DefaultValue: True, Description: Highlights the X zero axis if its value is beolw the top line and above the bottom line.

Public Sub DesignerCreateView (Base As Object, Lbl As Label, Props As Map)
'.........
    Scale(sX).YZeroAxis = Props.GetDefault("XZeroAxis", True)
    Scale(sX).YZeroAxisHighlight = Props.GetDefault("XZeroAxisHighlight", True)
End Sub

'Gets or sets the XZeroAxis property for LINE and BAR charts.
'If all values are positive, sets the lower X scale to zero.
'If all values are negative, sets the upper X scale to zero.
Public Sub getXZeroAxis As Boolean
    Return Scale(sX).YZeroAxis
End Sub

Public Sub setXZeroAxis (XZeroAxis As Boolean)
    Scale(sX).YZeroAxis = XZeroAxis
End Sub

'Gets or sets the XZeroAxisHighlight property.
'If True draws the X Zero axis 2dip thick otherwise with 1dip.
Public Sub getXZeroAxisHighlight As Boolean
    Return Scale(sX).YZeroAxisHighlight
End Sub

Public Sub setXZeroAxisHighlight (XZeroAxisHighlight As Boolean)
    Scale(sX).YZeroAxisHighlight = XZeroAxisHighlight
End Sub
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…