Module: ChartJsGadget

Share your advanced knowledge/code with the community.
User avatar
Peter
Posts: 1086
Joined: Mon Feb 24, 2014 10:17 pm
Location: 127.0.0.1:9080
Contact:

Module: ChartJsGadget

Post by Peter »

Hello,

here is a basic implementation of Chart.js (http://www.chartjs.org/)

Image

Code: Select all

DeclareModule ChartJs
  
  EnableExplicit
  
  Enumeration
    #ChartJsData
    #ChartJsOptions
  EndEnumeration
  
  #ChartJsTypeLine = "line"
  #ChartJsTypeBar = "bar"
  #ChartJsTypeRadar = "radar"
  #ChartJsTypePolarArea = "polarArea"
  #ChartJsTypePie = "pie"
  #ChartJsTypeDoughnut = "doughnut"
  #ChartJsTypeBubble = "bubble"
  
  Global IsInitialized
  
  Declare Init(Callback)
  Declare Gadget(Gadget, x, y, Width, Height, ChartType.s)
  
  Declare SetGadgetAttribute_(Gadget, Attribute, Value)
  
  Macro SetGadgetAttribute(Gadget, Attribute, Value)
    ChartJs::SetGadgetAttribute_(Gadget, Attribute, Value)
  EndMacro  
  
EndDeclareModule

Module ChartJs
  
  EnableExplicit

  Procedure Init(Callback)
    ! require(["https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"],
    !   function() {
    IsInitialized = #True
    !      v_callback();
    !   }
    ! );
  EndProcedure
  
  Procedure Gadget(Gadget, x, y, Width, Height, ChartType.s)
    
    If Gadget = #PB_Any
      Gadget = CanvasGadget(Gadget, x, y, Width, Height)
    Else
      CanvasGadget(Gadget, x, y, Width, Height)
    EndIf
    
    ! var selector = $(spider_GadgetID(v_gadget).div).find('canvas');
    ! var myChart = new Chart(selector, { type: v_charttype });
    
    ! selector.data("ChartJs", myChart);
    
    ProcedureReturn Gadget

  EndProcedure
  
  Procedure SetGadgetAttribute_(Gadget, Attribute, Value)
    
    ! var selector = $(spider_GadgetID(v_gadget).div).find('canvas');
    ! var myChart = selector.data("ChartJs");
    
    Select Attribute
        
      Case #ChartJsData
        
        ! myChart.config.data = v_value;
        ! myChart.update();
        
      Case #ChartJsOptions
        
        ! myChart.config.options = v_value;
        ! myChart.update();
        
    EndSelect
    
  EndProcedure
  
EndModule

CompilerIf #PB_Compiler_IsMainFile = 1
  
  EnableExplicit
  
  ; Demo
  
  Enumeration
    #Window
  EndEnumeration
  Enumeration
    #ChartJsGadget
  EndEnumeration
  
  Procedure Main()
    
    OpenWindow(#Window, #PB_Ignore, #PB_Ignore, 400, 300, "ChartJsGadget-Example", #PB_Window_ScreenCentered)
    
    ChartJs::Gadget(#ChartJsGadget, 10, 10, WindowWidth(#Window) - 20, WindowHeight(#Window) - 20, ChartJs::#ChartJsTypeBar)
    
    Protected myData
    
    ! v_mydata= {
    !   labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    !   datasets: [{
    !     label: '# of Votes',
    !     data: [12, 19, 3, 5, 2, 3],
    !     backgroundColor: [
    !       'rgba(255,  99, 132, 0.5)',
    !       'rgba( 54, 162, 235, 0.5)',
    !       'rgba(255, 206,  86, 0.5)',
    !       'rgba( 75, 192, 192, 0.5)',
    !       'rgba(153, 102, 255, 0.5)',
    !       'rgba(255, 159,  64, 0.5)'
    !     ],
    !     borderColor: [
    !       'rgba(255,99,132,1)',
    !       'rgba(54, 162, 235, 1)',
    !       'rgba(255, 206, 86, 1)',
    !       'rgba(75, 192, 192, 1)',
    !       'rgba(153, 102, 255, 1)',
    !       'rgba(255, 159, 64, 1)'
    !     ],
    !     borderWidth: 1
    !   }]
    ! };
    
    ChartJs::SetGadgetAttribute(#ChartJsGadget, ChartJs::#ChartJsData, myData)
    
    Protected myOptions
    
    ! v_myoptions = {
    !   scales: {
    !     yAxes: [{
    !       ticks: {
    !         beginAtZero:true
    !       }
    !     }]
    !   }
    ! };
    
    ChartJs::SetGadgetAttribute(#ChartJsGadget, ChartJs::#ChartJsOptions, myOptions)
    
  EndProcedure
  
  ChartJs::Init(@Main())
  
CompilerEndIf
Greetings ... Peter

// Edit 2017-01-03: Made a few changes
Last edited by Peter on Wed Jan 03, 2018 9:17 am, edited 1 time in total.
Fred
Site Admin
Posts: 1506
Joined: Mon Feb 24, 2014 10:51 am

Re: Module: ChartJsGadget

Post by Fred »

What do you prefer between GoogleChart and ChartJS ?
User avatar
Peter
Posts: 1086
Joined: Mon Feb 24, 2014 10:17 pm
Location: 127.0.0.1:9080
Contact:

Re: Module: ChartJsGadget

Post by Peter »

Fred wrote:What do you prefer between GoogleChart and ChartJS ?
both have pros and cons:
  • GoogleChart has more ChartTypes.
  • ChartJs is lightweight and looks more beautiful.
  • ChartJs can be used 'offline'; GoogleChart not.
  • Some people do not like Google.
  • ...
After all i think it is a matter of taste.

Greetings ... Peter
bbanelli
Posts: 107
Joined: Mon Jul 13, 2015 7:40 am

Re: Module: ChartJsGadget

Post by bbanelli »

What is the proper way to use these methods, say, "dynamically"?

For example, my application loads, it has background windows with container. But say I don't know how many charts I want deployed and I want to populate them depending on certain user choices?

I tried fiddling but with no great success, it seems Init() method has no effect when called from HTTP callback, for example. Do I have to call different Init() methods for each change of data? What is the exact purpose of that Init() with callback in the first place? Why can't those charts be placed like "normal" gadgets?

Any clue or hint greatly appreciated!
"If you lie to the compiler, it will get its revenge."
Henry Spencer
http://www.pci-z.com/
User avatar
Peter
Posts: 1086
Joined: Mon Feb 24, 2014 10:17 pm
Location: 127.0.0.1:9080
Contact:

Re: Module: ChartJsGadget

Post by Peter »

bbanelli wrote:What is the exact purpose of that Init() with callback in the first place?
the Init()-Procedure of this module ensures, that the ChartJs-Library is loaded completely, before you can use the Chart-Functionalities.
You have to call this function only once (at startup). After that you can call the Gadget()-Procedure as often as you like.

Another Demo:

Code: Select all

! function getRandomInt(min, max) { return Math.floor(Math.random()*(max-min+1)+min); }  
! window.getRandomInt = getRandomInt;

Procedure RandomData() ; only for demonstration: returns random data
  Protected myData
  ! v_mydata= {
  !   labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
  !   datasets: [{
  !     label: '# of Votes',
  !     data: [getRandomInt(5,20), getRandomInt(5,20), getRandomInt(5,20), getRandomInt(5,20), getRandomInt(5,20), getRandomInt(5,20)],
  !     backgroundColor: [
  !       'rgba(255,  99, 132, 0.5)',
  !       'rgba( 54, 162, 235, 0.5)',
  !       'rgba(255, 206,  86, 0.5)',
  !       'rgba( 75, 192, 192, 0.5)',
  !       'rgba(153, 102, 255, 0.5)',
  !       'rgba(255, 159,  64, 0.5)'
  !     ],
  !     borderColor: [
  !       'rgba(255,99,132,1)',
  !       'rgba(54, 162, 235, 1)',
  !       'rgba(255, 206, 86, 1)',
  !       'rgba(75, 192, 192, 1)',
  !       'rgba(153, 102, 255, 1)',
  !       'rgba(255, 159, 64, 1)'
  !     ],
  !     borderWidth: 1
  !   }]
  ! };
  ProcedureReturn myData
EndProcedure

Procedure Chart1()
  
  Protected myWindow = OpenWindow(#PB_Any, 10, 10, 400, 300, "ChartJs1")
  Protected myChart = ChartJs::Gadget(#PB_Any, 10, 10, WindowWidth(myWindow) - 20, WindowHeight(myWindow) - 20, ChartJs::#ChartJsTypeBar)
  ChartJs::SetGadgetAttribute(myChart, ChartJs::#ChartJsData, RandomData())
  
EndProcedure

Procedure Chart2()
  
  Protected myWindow = OpenWindow(#PB_Any, 30, 30, 400, 300, "ChartJs2")
  Protected myChart = ChartJs::Gadget(#PB_Any, 10, 10, WindowWidth(myWindow) - 20, WindowHeight(myWindow) - 20, ChartJs::#ChartJsTypeBar)
  ChartJs::SetGadgetAttribute(myChart, ChartJs::#ChartJsData, RandomData())
  
EndProcedure

Procedure Chart3()
  
  Protected myWindow = OpenWindow(#PB_Any, 50, 50, 400, 300, "ChartJs3")
  Protected myChart = ChartJs::Gadget(#PB_Any, 10, 10, WindowWidth(myWindow) - 20, WindowHeight(myWindow) - 20, ChartJs::#ChartJsTypeBar)
  ChartJs::SetGadgetAttribute(myChart, ChartJs::#ChartJsData, RandomData())
  
EndProcedure

Procedure Main()
  
  Chart1()
  Chart2()
  Chart3()
  
EndProcedure

ChartJs::Init(@Main())
Please note that I made a change of the code above in the first posting.

Greetings ... Peter
bbanelli
Posts: 107
Joined: Mon Jul 13, 2015 7:40 am

Re: Module: ChartJsGadget

Post by bbanelli »

Hi Peter,

I've slowly begun to grasp those concepts, thanks for the help.

Do you know why I can't get a single chart to display title?

For example, when adding this part of code to data in SetGadgetAttribure, it doesn't show in any of charts.

Code: Select all

Procedure RandomData() ; only for demonstration: returns random data
  Protected myData
  ! v_mydata= {
  !   labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
  !   datasets: [{
  !     label: '# of Votes',
  !     data: [getRandomInt(5,20), getRandomInt(5,20), getRandomInt(5,20), getRandomInt(5,20), getRandomInt(5,20), getRandomInt(5,20)],
  !     backgroundColor: [
  !       'rgba(255,  99, 132, 0.5)',
  !       'rgba( 54, 162, 235, 0.5)',
  !       'rgba(255, 206,  86, 0.5)',
  !       'rgba( 75, 192, 192, 0.5)',
  !       'rgba(153, 102, 255, 0.5)',
  !       'rgba(255, 159,  64, 0.5)'
  !     ],
  !     borderColor: [
  !       'rgba(255,99,132,1)',
  !       'rgba(54, 162, 235, 1)',
  !       'rgba(255, 206, 86, 1)',
  !       'rgba(75, 192, 192, 1)',
  !       'rgba(153, 102, 255, 1)',
  !       'rgba(255, 159, 64, 1)'
  !     ],
  !     borderWidth: 1
  !   }],
  ! options: {
  !         title: {
  !               position: 'top',
  !               display: true,
  !               text: 'Title'
  !               }
  !           }  
  ! };
  ProcedureReturn myData
EndProcedure
https://imgur.com/a/HcXoM
"If you lie to the compiler, it will get its revenge."
Henry Spencer
http://www.pci-z.com/
User avatar
Peter
Posts: 1086
Joined: Mon Feb 24, 2014 10:17 pm
Location: 127.0.0.1:9080
Contact:

Re: Module: ChartJsGadget

Post by Peter »

bbanelli wrote:For example, when adding this part of code to data in SetGadgetAttribure, it doesn't show in any of charts.
did you also copy the two lines above the procedure?

Code: Select all

! function getRandomInt(min, max) { return Math.floor(Math.random()*(max-min+1)+min); }  
! window.getRandomInt = getRandomInt;
Greetings ... Peter
Post Reply