Axiom custom controls
Is it possible to add custom controls (beyond simple symbols or images) in Axiom?
I'm looking to integrate interactive UI elements—such as dropdown menus, radio buttons, and flags—typically implemented using HTML5/JavaScript. The goal is to enhance user interaction by supporting data selection, navigation, and form input directly within the interface.
2 replies
-
Hi ,
Unfortunately not. We're not sure how how we would integrate something like that.
-
It is possible to interact with Axiom via Javascript if you use the IFrame component and set the UrlSource to a file hosted on the Canary server within the Axiom file structure so that the IFrame does not violate the same-origin policy.
Where to place the file depends on your intallation.For v23 and below, it would be in C:\Program Files\Canary\Axiom\WebFiles
For v24 and above, it would be in C:\Program Files\Canary\Axiom\wwwroot
It might be helpful to create a new folder called "custom" to keep these custom components organized.
Within the IFrame, you can use:
window.parent
and within that you can use all of the Javascript functions available in Axiom.
Most of what you need is in:
window.parent.App
An example custom component is a time picker for all controls on the same page.
The radio buttons let you choose between Day, Week, Month, and Year.
When you click on a time span, each control get set to the same AggregateInterval and AggregateStartTime.
Here is the how the component looks with two value boxes, one showing the Timestamp and the other getting the average of the CpuLoad%.
Below is the source of timepicker.html, which you can copy to the custom components folder.
<!DOCTYPE html> <!-- Timepicker - Custom component to set the aggregate times for all components on the screen --> <html> <head> <!-- Include references to standard Axiom stylesheets to match style of components --> <link rel="stylesheet" type="text/css" href="../css/axiom.min.css"> <link rel="stylesheet" type="text/css" href="../css/vendors.min.css"> <link rel="stylesheet" type="text/css" href="../theme/default.dark.css" id="css-theme"> <style type="text/css"> body { margin: 0px; } body :not(h4):not(h3):not(h2):not(h1) { font-size: 16px; } #timelist { background: rgba(var(--color-control-primary-background-default),1); color: rgba(var(--color-control-primary-foreground-default),var(--opacity-control-foreground-default)); fill: rgba(var(--color-control-primary-foreground-default),var(--opacity-control-foreground-default)); } </style> <script src="../js/vendors.min.js"></script> </head> <body> <!-- Create a ListBox to contain the radio buttons --> <div id="timelist" class="control-list-box no-select editor-move-and-resize radio" style="left: 12px; top: 36px; height: 130px; width: 100px;"> <ul> <li> <i class="material-icons checked">check_box</i> <i class="material-icons unchecked">check_box_outline_blank</i> <i class="material-icons radio checked">radio_button_checked</i> <i class="material-icons radio unchecked">radio_button_unchecked</i> <span>Day</span> </li> <li> <i class="material-icons checked">check_box</i> <i class="material-icons unchecked">check_box_outline_blank</i> <i class="material-icons radio checked">radio_button_checked</i> <i class="material-icons radio unchecked">radio_button_unchecked</i> <span>Week</span> </li> <li> <i class="material-icons checked">check_box</i> <i class="material-icons unchecked">check_box_outline_blank</i> <i class="material-icons radio checked">radio_button_checked</i> <i class="material-icons radio unchecked">radio_button_unchecked</i> <span>Month</span> </li> <li> <i class="material-icons checked">check_box</i> <i class="material-icons unchecked">check_box_outline_blank</i> <i class="material-icons radio checked">radio_button_checked</i> <i class="material-icons radio unchecked">radio_button_unchecked</i> <span>Year</span> </li> </div> <script type="text/javascript"> //Retrieve the last timespan selected from local storage var timeSelected = JSON.parse(localStorage.getItem('timeSelected')); //Make sure the appropriate item in the list of timespans function initSelections(){ $('#timelist li span').toArray().forEach(function(element){ if(timeSelected !== null && timeSelected.length > 0 && timeSelected.some(timespan => timespan == element.innerText)){ $(element).parent().addClass('selected') } else { $(element).parent().removeClass('selected') }}) } function toggle(element){ $('#timelist li.selected').toggleClass('selected'); $(element.currentTarget).toggleClass('selected'); //Run the setTimeFilter after toggling which timespan is selected setTimeFilter(); } //Modify the AggregateInterval and AggregateStartTime of all controls on the screen to use the timespan selected function setTimeFilter(){ timeSelected = $('#timelist li.selected span').toArray().map(element => element.innerText); localStorage.setItem('timeSelected', JSON.stringify(timeSelected)); var filter = timeSelected[0]; //Reference the parent window where Axiom is running //Get the list of all controls using App.Controls2.all() window.parent.App.Controls2.all().forEach(function(control){ //Check if the control has an AggregateInterval property if(control.hasProperty("AggregateInterval")){ //If it has that property, then set the AggregateInterval to the timespan selected control.notifyProperty("AggregateInterval",filter) } //Check if the control has an AggregateInterval property if(control.hasProperty("AggregateStartTime")){ //If it has that property, then set the AggregateInterval to the timespan selected control.notifyProperty("AggregateStartTime",filter) } }) } //When a radio button is clicked, run the toggle function $('#timelist li').on('click', toggle) initSelections(); setTimeFilter(); </script> </body> </html>
Unfortunately the Javascript API for Axiom is not documented, so you have to use the DevTools available to look for functions you may need.