B4J Question ABMATERIAL & Google Chart

juvanum

Active Member
Licensed User
Longtime User
Hello community,
I'm looking for a small complete example of how to integrate ABMaterial with Google chart.
(I found examples in the forum but did not find a complete project)
can someone help me?
thank you
 

Harris

Expert
Licensed User
Longtime User
Not complete, but a start. See this as well - https://www.b4x.com/android/forum/threads/abmaterial-abmcustomcomponent-google-charts.73028/

The Build Page:
B4X:
public Sub BuildPageExample()
    ' The important bits... I trimmed the rest from my example
   
    Dim myLineChart As CustomGoogleChart2  ' put myLineChart in class_globals
    '                                       - CustomGoogleChart2 is another class provided later...
    BuildTheme
   
    ' add the extra java script file - loader.js
    page.AddExtraJavaScriptFile("custom/loader.js")
   
    ' All below is standard stuff.....
    page.InitializeWithTheme(Name, "/ws/" & ABMShared.AppName & "/" & Name, False, ABMShared.SessionMaxInactiveIntervalSeconds, theme)
    page.ShowLoader=True
    page.ShowLoaderType=ABM.LOADER_TYPE_MANUAL ' NEW
       
    ABMShared.BuildNavigationBar(page,  Page_name, "../images/logo.png", "", "Apps", Page_name)
   
    page.AddRowsM( 1,False,  10,  3, "rowtheme").AddCellsOSMP(1,0,0,0, 2,2,2,   5 , 5, 0,0,"cnter").AddCellsOSMP(1,0,0,0,3,3,3,  5,5,30,10,"cnter").AddCellsOSMP(1,0,0,0,3,3,3,  5 ,  5,30,10,"cnter").AddCellsOSMP(1,0,0,0,2,2,2 ,   15,   5,30, 10,"cnter").AddCellsOSMP(1,0,0,0,2,2,2 ,   10,   5,30, 10,"cnter")
    page.AddRows(1,False, "") .AddCellsOSMP(1,0,0,0,3,3,3,0 ,0, 10,0,  "").AddCellsOSMP(1,0,0,0,9,9,9,  20 ,0, 0 ,0,  "")

    page.AddRowsM(1, True, 10,0,"").AddCells12(1,"")
    page.BuildGrid 'IMPORTANT once you loaded the complete grid AND before you start adding components

Log("    BuildPage was built")
End Sub


The Connect Page:
B4X:
Sub ConnectPageExample
   
    ABMShared.ConnectNavigationBar(page)
   
    myLineChart.Initialize(page,  "myLinechart")  ' init myLinechart
   
    page.Cell(2,2).AddComponent(myLineChart.ABMComp)  ' add the Component to a cell on your page


    ' standard stuff below...

    page.FinishedLoading 'IMPORTANT   
   
    Log(" Finished loading and connecting page")
   
    page.RestoreNavigationBarPosition
    page.NavigationBar.Title = "Google Line Chart"
   
    page.Refresh

End Sub

The CustomGoogleChart2 class module (as messy as it is)....

B4X:
'Class module
Sub Class_Globals
    Dim ABM As ABMaterial 'ignore
    Dim ABMComp As ABMCustomComponent   ' important!!!
    Dim Title As String
    Dim Subtitle As String 'ignore 'only used for a google material chart - material charts are slow.....
    Dim Columns As List
    Dim Rows As List
    Dim pngi As Boolean = True
    Dim selected As String = ""
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(InternalPage As ABMPage, ID As String)
    ABMComp.Initialize("ABMComp",  Me, InternalPage,  ID)
   
    ABMComp.Visibility = ABM.VISIBILITY_HIDE_ALL ' hide the chart while loading
    ' the automatic events will be raised on the page e.g. if the id = "mycomp" then the event will be mycomp_Click(params as Map)
    ' future: we'll see if some other mechanisme is needed for non automatic events
    Columns.Initialize
    Rows.Initialize
   
    ABM.InsertHTMLAfter( InternalPage,ID, $"<div id='png'></div> "$ )  ' don't know why we have this but....
       
End Sub

public Sub AddColumn(varType As String, text As String)
    Columns.add($"data.addColumn('${varType}', '${text}');"$)
End Sub

public Sub AddRow(Day() As Int , Guardians As Double, Avengers As Double, Transformers As Double, Lastcol As Double, numcols As Int)

Select numcols
    Case 1
        If Rows.Size > 0 Then ' with comma
            Rows.Add($",[ [${Day(0)},${Day(1)},${Day(2)}], ${Guardians} ]"$)
        Else ' first one, does not need a comma
            Rows.Add($"[ [${Day(0)},${Day(1)},${Day(2)}], ${Guardians}  ]"$)
        End If
       
    Case 2
        If Rows.Size > 0 Then ' with comma
            Rows.Add($",[ [${Day(0)},${Day(1)},${Day(2)}], ${Guardians}, ${Avengers} ]"$)
        Else ' first one, does not need a comma
            Rows.Add($"[ [${Day(0)},${Day(1)},${Day(2)}], ${Guardians}, ${Avengers} ]"$)
        End If
       
    Case 3
        If Rows.Size > 0 Then ' with comma
            Rows.Add($",[ [${Day(0)},${Day(1)},${Day(2)}], ${Guardians}, ${Avengers}, ${Transformers} ]"$)
        Else ' first one, does not need a comma
            Rows.Add($"[ [${Day(0)},${Day(1)},${Day(2)}], ${Guardians}, ${Avengers}, ${Transformers} ]"$)
        End If
       
    Case 4
        If Rows.Size > 0 Then ' with comma
            Rows.Add($",[ [${Day(0)},${Day(1)},${Day(2)}], ${Guardians}, ${Avengers}, ${Transformers}, ${Lastcol} ]"$)
        Else ' first one, does not need a comma
            Rows.Add($"[ [${Day(0)},${Day(1)},${Day(2)}], ${Guardians}, ${Avengers}, ${Transformers}, ${Lastcol} ]"$)
        End If
                   
End Select


End Sub


private Sub Getprn As Boolean   ' ignore
   
    Return pngi
End Sub


private Sub GetColumns() As String
    Dim s As String
    For i = 0 To Columns.Size-1
        s = s & Columns.Get(i)
    Next
    Return s
End Sub

private Sub GetRows() As String
    Dim s As String
    For i = 0 To Rows.Size-1
        s = s & Rows.Get(i)
    Next
    Return s
End Sub

' runs when an object is created for the first time. Expects a valid html string
Sub ABMComp_Build(internalID As String) As String
    
    Return $"<div id="${internalID}"></div>"$   
End Sub


' Is useful to run some initalisation script.
Sub ABMComp_FirstRun(InternalPage As ABMPage, internalID As String)
    ' this is for a classic google chart
   
    ABM.InsertHTMLAfter( InternalPage,internalID, $"<div id='png'></div> "$ )
   
    Dim script As String = $"google.charts.load('current', {'packages':['corechart']});
    google.charts.setOnLoadCallback(drawChart);
   
    function drawChart() {
   
         // Define the chart to be drawn.
         var data = new google.visualization.DataTable();
         ${GetColumns}
        
          data.addRows([${GetRows}]);
     
          var options = {  
            title: '${Title}',        
//           width: '100%',
//           height: 700,
//            vAxis: {title: "ECM", minValue:0, maxValue:50},
//             hAxis: {title: "Time of Day"},       
            lineWidth: 1.3,               
            explorer: {
                actions: ['dragToZoom', 'rightClickToReset'],
                axis: 'horizontal',
                keepInBounds: true,
                maxZoomIn: 100.0
            },           
              legend: { position: 'bottom' }
          };

          // Instantiate and draw the chart.
         var chart = new google.visualization.LineChart(document.getElementById('${internalID}'));
//         var chart = new google.charts.Line(document.getElementById('${internalID}'));
       
          chart.draw(data, options);     
     
          // added this because on firefox google charts can give errors
          google.visualization.events.addListener(chart, 'error', function (err) {
             google.visualization.errors.removeError(err.id);
          });
     
          // added this so the chart becomes visible
          document.getElementById('${internalID}').className="";   
          // I force a second redraw by calling chart.draw(data, options); again (forces the width to fit)      
          chart.draw(data, options);
     }
    
     // make it resposive on resize
     $(window).resize(function(){
          drawChart(); 
     });
     "$
   
     InternalPage.ws.Eval(script, Array As Object(ABMComp.ID))
    
     Log(" ran first run")
    ' flush not needed, it's done in the refresh method in the lib
End Sub

' runs when a refresh is called
Sub ABMComp_Refresh(InternalPage As ABMPage, internalID As String)
   
   
   
    ' use these methods to adjust the object
    'ABM.HasClass
    ' ABM.AddClass
    ' ABM.RemoveClass
    ' ABM.AddHTML
     'ABM.InsertHTMLAfter(
     'ABM.RemoveHTML(
     'ABM.GetProperty(
    ' ABM.SetProperty
    ' ABM.RemoveProperty
    ' ABM.GetStyleProperty
    ' ABM.SetStyleProperty
   
    ' do some script stuff like you do in RunJavaScript   
    'Dim script As String = $""$   
   
    'Dim sc As String = $"<div id='png'>Print Chart</div>"$
'     ABM.RemoveHTML(InternalPage,  "png" )
'   ABM.InsertHTMLAfter( InternalPage,internalID,   "<div id='png'></div> " )
   
   
    Dim script As String = $"
         // Define the chart To be drawn.
         var data = new google.visualization.DataTable();
         ${GetColumns}
          data.addRows([${GetRows}]);
     
          var options = { 
              width: '100%',
              height: 700,
            backgroundColor:  'transparent',
              chartArea: {backgroundColor    :  '#E3F2FD'},

            title: '${Title}',  
            vAxis: {title: "ECM Data Collected (for this hour)", minValue:0, gridlines: {count:20, color: 'gray'} },
              hAxis: {title: "Time of Day", gridlines: {count:20,  color: 'gray'} },       
            lineWidth: 1.3,               
            explorer: {
                actions: ['dragToZoom', 'rightClickToReset'],
                axis: 'horizontal',
                keepInBounds: true,
                maxZoomIn: 100.0
            },           
              legend: { position: 'bottom' },
           
          };

          // Instantiate And draw the chart.
          var chart = new google.visualization.LineChart(document.getElementById('${internalID}'));

          chart.draw(data, options);   
     
          // added this because on firefox google charts can give errors
          google.visualization.events.addListener(chart, 'error', function (err) {
             google.visualization.errors.removeError(err.id);
          });
     
        google.visualization.events.addListener(chart, 'select', selectHandler);
       
        function selectHandler() {
          var selection = chart.getSelection();
          var message = '';
          for (var i = 0; i < selection.length; i++) {
            var item = selection[i];
            if (item.row != null && item.column != null) {
              var str = data.getFormattedValue(item.row, item.column);
              message += '{row:' + item.row + ',column:' + item.column + '} = ' + str + '\n';
            } else if (item.row != null) {
              var str = data.getFormattedValue(item.row, 0);
              message += '{row:' + item.row + ', column:none}; value (col 0) = ' + str + '\n';
            } else if (item.column != null) {
              var str = data.getFormattedValue(0, item.column);
              message += '{row:none, column:' + item.column + '}; value (row 0) = ' + str + '\n';
            }
          }
          if (message == '') {
            message = 'nothing';
          }
             b4j_raiseEvent('page_parseevent', {'eventname': 'chart' + '_chartitemclicked','eventparams': 'message', 'message': message});         
    //      alert('You selected ' + message);
        //  ${selected} = message;
         
        };
          // added this so the chart becomes visible
          document.getElementById('${internalID}').className="";   
          // I force a second redraw by calling chart.draw(data, options); again (forces the width to fit)      
          chart.draw(data, options);
    
     "$
   
    InternalPage.ws.Eval(script, Null)   
    'Log(" selected: "&selected)
   
End Sub

' do the stuff needed when the object is removed

Sub ABMComp_CleanUp(InternalPage As ABMPage, internalID As String)
  ' don't know what to put here...    
End Sub
 
Upvote 0
Top