Embedding a JavaScript Chart Component

Using the BBjHTMLView to embed 3rd Party Components

Embedding 3rd Party Components to BBj is done using the BBjHTMLView component. The concept explained in this paragraph is not limited to DWC, but also works in principle the same way in GUI, which loads a Chromium Engine for that purpose and BUI.

The BBjHTMLView is a widget that acts like an embedded browser. It allows you to load HTML code into it, execute JavaScript and even send Events back to the BBj interpreter from JavaScript.

Before developing a concrete sample, let's have a look at the typical steps required to embed HTML components to BBj:

  1. Add a BBjHTMLView to your BBj Window.
  2. Seed the HTMLView with necessary static HTML code if needed
  3. Load the required JS library
  4. Execute JavaScript to initialize the component
  5. Optionally: in that JavaScript code, register Events that the component can fire and add callback routines to your BBj program

It is important to recognize that step 3 should only be executed once step 2 is finished and that step 4 is executed after 3. To ensure that, we typically implement the following pattern in code:

   
html$ = "<html><<body><div id='myComponent'></div></body></html>"
htmlview! = window!.addHtmlView(102,20,70,760,430,html$,$$)
htmlview!.setCallback(htmlview!.ON_PAGE_LOADED,"handlePageLoaded")
htmlview!.setCallback(htmlview!.ON_SCRIPT_LOADED,"handleScriptLoaded")
process_events

handlePageLoaded:
  rem after the initial HTML is loaded we can inject the library
  htmlview!.clearCallback(htmlview!.ON_PAGE_LOADED)
  url$ = "https://cdn.url.for.libary.js"
  htmlview!.injectUrl(url$,1)
return

handleScriptLoaded:
  rem after the library is loaded we can work with it
  htmlview!.clearCallback(htmlview!.ON_SCRIPT_LOADED)
  js$ = ""
  js$ = js$ + "var chartCanvas = document.getElementById('myComponent');"
  js$ = js" + "/// and further js code to execute...."
  htmlview!.injectScript(js$,1)
return

This cascade of events - one for the page loaded, followed by the script loaded event - ensures that each part that relies on the previous loading is executed only after the previous step has been finished.

Embedding a Chart Component from charts.js


We're going to exercise the embedding of a chart widget to DWC by using the chartjs library. We used a "Getting Started" document under https://www.chartjs.org/docs/latest/getting-started/  to construct this sample. 

This is how the sequence of loading code looks in the program. We start with an <canvas> element and give it an ID we can later address from our JS code. 

html$ = "<html></head><body><canvas id='myChart'></canvas></body></html>"
htmlview! = window!.addHtmlView(102,20,70,760,430,html$,$$)
If you are planning to embed multiple similar components to your page, make sure to give each one a unique ID.
After the page is loaded, the ON_PAGE_LOADED event is fired and the library can be loaded from the CDN:

handlePageLoaded:
  rem after the initial HTML is loaded we can inject the library
  htmlview!.clearCallback(htmlview!.ON_PAGE_LOADED)
  url$ = "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"
  htmlview!.injectUrl(url$,1)
return
If you like to host the library locally, you will need to download it and put it somewhere under BBj's <bbxdir>/htdocs folder. then the URL would look like 

url$ = "http://bbjservername:8888/files/chart.min.js"

Then, after the library is successfully loaded, the ON_SCRIPT_LOADED event is fired, and we can now work with it to instantiate our chart with JavaScript. In this sample the data is hardcoded, but in reality, you would either build the data dynamically into the JavaScript code or later do some executeScript to load the data:

handleScriptLoaded:
  rem after the library is loaded we can work with it
  rem ' https://www.chartjs.org/docs/latest/getting-started/
  
  htmlview!.clearCallback(htmlview!.ON_PAGE_LOADED)
  js$ = ""
  js$ = js$ + "var chartCanvas = document.getElementById('myChart');"
  js$ = js$ + "var ctx = chartCanvas.getContext('2d');"
  js$ = js$ + "var chart = new Chart(ctx, {"
  js$ = js$ + "    type: 'line',"
  js$ = js$ + "    data: {"
  js$ = js$ + "        labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],"
  js$ = js$ + "        datasets: ["
  js$ = js$ + "         {"
  js$ = js$ + "            label: 'Year 2021',"
  js$ = js$ + "            backgroundColor: '#ff1a68',"
  js$ = js$ + "            borderColor: '#ff1a68',"
  js$ = js$ + "            data: [40, 20, 33, 22, 25, 15, 7]"
  js$ = js$ + "         },"  
  js$ = js$ + "         {"
  js$ = js$ + "            label: 'Year 2022',"
  js$ = js$ + "            backgroundColor: '#25c2a0',"
  js$ = js$ + "            borderColor: '#25c2a0',"
  js$ = js$ + "            data: [2, 10, 5, 2, 20, 30, 45]"  
  js$ = js$ + "         },"   
  js$ = js$ + "        ]"
  js$ = js$ + "    }"
  js$ = js$ + "});"
  js$ = js$ + "window.myChart = chart;"
  
  htmlview!.injectScript(js$,1)
return
You can find the complete program under ChartJS_NoEventFromJS.bbj.
Last modified: Friday, 12 July 2024, 8:36 AM