User Tools

Site Tools


download-csv-js

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
download-csv-js [2022/05/10 11:57] emozolyakdownload-csv-js [2023/10/15 18:07] (current) – [Script text] emozolyak
Line 1: Line 1:
-====== Example of graph data download with JS for dashbaord ======+====== Example of graph data download with JS for dashboard ======
  
 The standard method of exporting data from graphs to XLS, HTML, CSV files has the resolution of the selected view on the respective graph, not all data - due to performance issues.  The standard method of exporting data from graphs to XLS, HTML, CSV files has the resolution of the selected view on the respective graph, not all data - due to performance issues. 
Line 8: Line 8:
 ===== Dashboard layout ===== ===== Dashboard layout =====
 There are 4 control elements on the dashboard you must provide:  There are 4 control elements on the dashboard you must provide: 
 +{{ ::api:js-csv-dash.png?direct |}}
   -Start time date picker    -Start time date picker 
   -End time date picker   -End time date picker
Line 13: Line 14:
   -Dictionary element for selecting one of the many graphs you may have. E.g. if you have graphs with IDs of 1, 2, 3... you have to create a dictionary of 1, 2, 3.... and bind it with the register that will be used for the element on the dashboard.    -Dictionary element for selecting one of the many graphs you may have. E.g. if you have graphs with IDs of 1, 2, 3... you have to create a dictionary of 1, 2, 3.... and bind it with the register that will be used for the element on the dashboard. 
  
 +===== Script =====
  
 +Put the following script into the 'Script' tab of the dashboard properties (w/o comments)
  
 +{{ :api:js-csv-dash-script-tab.png?direct&800 |}}
  
-{{ ::api:js-csv-dash.png?direct |}} +==== Script text ====
  
 <code javascript> <code javascript>
-const DATA = {  // constant names for accessing the dashboard selection +const DATA = {   
-         TIME: {START: 7, END: 8},   // start and end time register ids +                TIME: {START: 2, END: 3},   // start and end time register ids 
-         DOWNLOAD_BTN: 9,            // register to detect if the button was pressed +                DOWNLOAD_BTN: 4,            // register to detect if the button was pressed 
-         GRAPH_ID: 1,                // placeholder for the graph id that  +                GRAPH_ID: 1,                // placeholder for the graph id that  
-         GRAPH_SELECTION_REG: 11     // will be selected by selection register+                GRAPH_SELECTION_REG: 7      // will be selected by selection register
 }; };
-const MAX_SLICES = 2999            // max number of the slices in the graph data api call +const MAX_SLICES     = 2999            // max number of the slices in the graph data api call 
-const TIMEOUT = 5e3; +      TIMEOUT        15e3, 
-const START_GRAPH_ID = 1           // start number of the range for graphs ids +      START_GRAPH_ID = 1           // start number of the range for graphs ids 
-const END_GRAPH_ID = 2;             // end number  +      END_GRAPH_ID   6;             // end number  
 + 
 let _i; let _i;
-let preventMultiply = false; +var preventMultiply = false, 
-let dataToSend = {}; +    dataToSend = {}, 
-let promises = []; +    promises = []; 
 + 
 App.on('register:newValue', triggerUponRegChange); App.on('register:newValue', triggerUponRegChange);
 + 
 function triggerUponRegChange(newValuesArray) { function triggerUponRegChange(newValuesArray) {
-    let ifButtonPressed = newValuesArray.filter(readVal =>  +    let ifButtonPressed = (newValuesArray.length > 0) 
-                                                    parseInt(readVal.regId) === DATA.DOWNLOAD_BTN  +                           && newValuesArray.filter(readVal => parseInt(readVal.regId) === DATA.DOWNLOAD_BTN  
-                                                    && parseInt(readVal.value) > 0).length > 0;+                                                               && parseInt(readVal.value) > 0) 
 +                                                    .length > 0;
     if (ifButtonPressed && !preventMultiply) {     if (ifButtonPressed && !preventMultiply) {
 +            preventMultiply = true;
 +            console.log('my button is pressed!')
             let selectedGraph = new Register(DATA.GRAPH_SELECTION_REG).getValue();             let selectedGraph = new Register(DATA.GRAPH_SELECTION_REG).getValue();
             selectedGraph = parseInt(selectedGraph.replace(/^.*\((\d)\).*$/, (match, p1) => p1));             selectedGraph = parseInt(selectedGraph.replace(/^.*\((\d)\).*$/, (match, p1) => p1));
             DATA.GRAPH_ID = (selectedGraph >= START_GRAPH_ID && selectedGraph <= END_GRAPH_ID) ? selectedGraph : 1;              DATA.GRAPH_ID = (selectedGraph >= START_GRAPH_ID && selectedGraph <= END_GRAPH_ID) ? selectedGraph : 1; 
-             +  
-            Promise.all(makeApiCall()).then(exportDataAsCSVToBrowser).catch(e => console.log(e));+            Promise.all(makeApiCall()) 
 +            .then(exportDataAsCSVToBrowser) 
 +            .catch(e => console.log(e)) 
 +            .finally(() => {preventMultiply = false console.log('preventMultiply was reset!')})
     }     }
 } }
- + 
-function getSlicesFromTS() { +
-    let paramsSet = []; +
-    calcSlices(parseInt(new Register(DATA.TIME.START).getValue()), +
-               parseInt(new Register(DATA.TIME.END).getValue())); +
-     +
-    function calcSlices(s, e)  +
-        if (s > e) {  +
-            console.log('startTS >= endTS') ; return ;   +
-        } +
-        if (e - s <= MAX_SLICES)   +
-            paramsSet.push({start:s, end: e, slices: e - s + 1}); +
-        else { +
-            let newEnd = s + MAX_SLICES - 1; +
-            paramsSet.push({start: s, end: newEnd, slices: MAX_SLICES}); +
-            calcSlices(newEnd + 1, e); +
-        } +
-    } +
-    return paramsSet; +
-+
 function makeApiCall() { function makeApiCall() {
-    let slicesParams = getSlicesFromTS();+     
 +    let slicesParams = getSlicesFromTS(); // preventMultiply = true
     dataToSend = {};     dataToSend = {};
-    promises = []; +    promises = [];  
-    preventMultiply = true; + 
-    setTimeout(function(){clearTimeout(_i); preventMultiply = false;}, TIMEOUT); +
-    +
     slicesParams.forEach(function(paramsSet, i) {     slicesParams.forEach(function(paramsSet, i) {
         let promise = new Promise(function(resolve, reject) {         let promise = new Promise(function(resolve, reject) {
Line 87: Line 75:
                     "X-WH-END": paramsSet.end,                     "X-WH-END": paramsSet.end,
                     "X-WH-SLICES": paramsSet.slices,                     "X-WH-SLICES": paramsSet.slices,
-                    "X-WH-REGISTERS": DATA.GRAPH_ID 
                 },                 },
                 dataType: 'json',                 dataType: 'json',
Line 102: Line 89:
         promises.push(promise);         promises.push(promise);
     });     });
-    + 
     return promises;     return promises;
 } }
 + 
 function exportDataAsCSVToBrowser() { function exportDataAsCSVToBrowser() {
     let response = [];     let response = [];
Line 125: Line 112:
             rep.push(row);             rep.push(row);
         });         });
-        + 
         if (window.navigator.msSaveBlob) { // IE         if (window.navigator.msSaveBlob) { // IE
             let blobObject = new Blob([rep.join("\r\n")]);             let blobObject = new Blob([rep.join("\r\n")]);
Line 141: Line 128:
 } }
  
 +function getSlicesFromTS() {
 +    let paramsSet = [];
 +    calcSlices(parseInt(new Register(DATA.TIME.START).getValue()),
 +               parseInt(new Register(DATA.TIME.END).getValue()));
 + 
 +    function calcSlices(s, e)  {
 +        if (s > e) { 
 +            console.log('startTS >= endTS') ; return ;  
 +        }
 +        if (e - s <= MAX_SLICES)  
 +            paramsSet.push({start:s, end: e, slices: e - s + 1});
 +        else {
 +            let newEnd = s + MAX_SLICES - 1;
 +            paramsSet.push({start: s, end: newEnd, slices: MAX_SLICES});
 +            calcSlices(newEnd + 1, e);
 +        }
 +    }
 +    return paramsSet;
 +}
 +
 +</code>
 +
 +==== Button release script ====
 +
 +Because the dashboard expects the register change be greater than 0, we have to reset this register after each use. 
 +The following script can do that:
 +<code lua>
 +BUTTON_REG_ID = 9
 +
 +function main (userId)
 +    
 +    local cur_value = R(BUTTON_REG_ID)
 +    
 +    if (not resetDemand and cur_value > 0) then 
 +        resetDemand = true                        -- postpone reset for one scan for JS to detect change
 +        return 
 +    end 
 +    
 +    if (resetDemand) then 
 +        reset(BUTTON_REG_ID)                     -- now real reset 
 +        resetDemand = false 
 +    end 
 +    
 +end
 +
 +function reset(reg) 
 +    local cur_value = R(reg)
 +    if cur_value and cur_value ~= 0 then 
 +        W(reg, 0)
 +    end 
 +end  
 </code> </code>
  
download-csv-js.1652183848.txt.gz · Last modified: 2022/05/10 11:57 by emozolyak

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki