Basic JavaScript function variable access

Discussion in 'Programming & Software Development' started by jars121, May 26, 2018.

  1. jars121

    jars121 Member

    Joined:
    Mar 6, 2008
    Messages:
    1,758
    Location:
    Sydney
    It's been quite a while since I've played in JS, and function variable scope and access has me quite confused. I'm looking to populate a set of Google LineCharts with data and update every x seconds. I'd like to use a single array to store the data for each of the LineCharts, and then update the respective LineChart in another function using its index reference within the array. E.g. lineChart4.data = dataArray[3]. Note that the below sample code uses a single plot for simplicity.

    Code:
    
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
        google.charts.load('current', {'packages':['corechart']});
        google.charts.setOnLoadCallback(initialise);
        function initialise() {
            this.interval = 1000;
            this.dataArray = new Array(1);
            this.plotDataSize = {};
            for (i = 0; i < 1; i++) {
                this.dataArray[i] = new Array();
                this.plotDataSize[i] = new Array();
               
                var tempDT = new google.visualization.DataTable();
                tempDT.addColumn('number', 'x');
                tempDT.addColumn('number', 'Data');
                tempDT.addRows([[0, 0]]);
               
                this.dataArray[i].push(tempDT);
               
                this.plotDataSize[i].push(10 * ((1 / this.interval) * 1000));
               
                window["loadPlot" + (i + 1)]();
            }
           
            setInterval(drawPlots, this.interval);
        }
    
        function drawPlots() {
            for (i = 0; i < 1; i++) {
                //Need to now access initialise.dataArray for plot1 (i.e. dataArray[0])
                initialise.dataArray[i].removeRow(0);
               
                for (j = 0; j < initialise.dataArray[i].getNumberOfRows(); j++) {
                    initialise.dataArray[i].setValue(j, 0, j);
                }
               
                initialise.dataArray[i].insertRows(initialise.dataArray[i].getNumberOfRows(), [[initialise.dataArray[i].getNumberOfRows() - 1, Math.floor(Math.random() * 99) + 1]]);
    
                //Here I also need to access the optionsPlot1 variable from the loadPlot1() function
                chart.draw(initialise.dataArray[i], loadPlot1.optionsPlot1);
            }
        }
    
        function loadPlot1() {
    
            var plotSize = initialise.dataArray[0].getNumberOfRows();
       
            if (plotSize < initialise.plotDataSize[0]) {
                for (i = 0; i < (initialise.plotDataSize[0] - plotSize); i++ ) {
                    initialise.dataArray[0].addRows([[i, 0]]);
                }
            }
    
            this.optionsPlot1 = {
                curveType: 'none',
                lineWidth: 1,
                legend: {
                    position: 'none'
                },
                backgroundColor: '#0b0b0c',
                vAxis: {
                    baselineColor: '#343434',
                    viewWindow: {
                        max: 100,
                        min: 0
                    },
                    gridlines: {
                        color: '#343434'
                    }
                },
                hAxis: {
                    baselineColor: '#343434',
                    textPosition: 'none',
                    gridlines: {
                        color: '#343434'
                    }
                },
                width: 400,
                height: 400,
                chartArea: {
                    width: "90%",
                    height: "90%",
                    top: "2%"
                },
                series: [
                    {color: 'white'}
                ]
            };
            this.chartPlot1 = new google.visualization.LineChart(document.getElementById('plot1ChartDiv'));
        }
    </script>
    
    I've looked into and tried various return() and prototype approaches, but was just confusing myself even further. I'd rather avoid global variables at this stage.

    Any ideas?
     
  2. waltermitty

    waltermitty Member

    Joined:
    Feb 19, 2016
    Messages:
    639
    Location:
    BRISBANE
    Either pass dataArray to draw plots inside a callback e.g. setInterval(function() { drawPlots(dataArray); }, this.interval); or declare dataArray and plotOptions as global, I don't see a problem.
     
  3. OP
    OP
    jars121

    jars121 Member

    Joined:
    Mar 6, 2008
    Messages:
    1,758
    Location:
    Sydney
    Thanks for your input :) Is there not a 'function.variable' approach (e.g. var x = initialise.dataArray)? I'd prefer to use the callback method over global variables, but even then, it's a lot of passing around of variables when a reference would seem cleaner.

    I'll have a play with the callback method in the meantime, thanks!
     
  4. waltermitty

    waltermitty Member

    Joined:
    Feb 19, 2016
    Messages:
    639
    Location:
    BRISBANE
    Create a 'global' object and chuck it in there e.g.

    Code:
    var graphStuff = {
               optionsPlot1 : {
                                          curveType: 'none'.... etc },
               dataArray: { [],[],[] etc }
    }
    Then you'll be able to graphStuff.dataArray etc
     
  5. OP
    OP
    jars121

    jars121 Member

    Joined:
    Mar 6, 2008
    Messages:
    1,758
    Location:
    Sydney
    Are global objects viewed in the same light as global variables? I.e. only use them when you have to, or are they a valid/standard tool in JS? Thanks for your help!
     
  6. waltermitty

    waltermitty Member

    Joined:
    Feb 19, 2016
    Messages:
    639
    Location:
    BRISBANE
    Polluting the window object is frowned upon but if you namespace it e.g. myapp.mystuff.global_var I guess it's okay. Most libraries do this, so it's pretty normal.
     
  7. w0ng

    w0ng Member

    Joined:
    Dec 17, 2006
    Messages:
    125
    Location:
    Sydney
    Your code won't work the way it's currently written. Try to just do everything in one big function and/or use global variables rather than trying to split it up into chunks. Make it work first. Then make it work better.

    Try to avoid using "this.xxx" for variables. It's similar to a an instance variable (if you've done a bit of object-oriented stuff in the past) or a context binding (if you've done a bit of functional programming). Either way, it'll probably end of confusing you.

    You can use "[]" as a shorthand notation for "new Array()". You don't need to predefine a size of an array in JS. Doing a push() will add a value to the array.

    You can pass parameters into "callback" or "async" functions (stuff that will not run immediately) with SomeFunction.bind().

    As a starting point, here's a few fixes that will get you a bit further. Once it starts making a bit of sense, try to figure out why this.chartPlot1 and chart.draw aren't working.

    Code:
    <script type="text/javascript">
      google.charts.load('current', { 'packages': ['corechart'] });
      google.charts.setOnLoadCallback(initialise);
    
      function initialise() {
        var interval = 1000;
        var dataArray = [];
        var plotDataSize = [];
    
        for (i = 0; i < 1; i++) {
    
          var tempDT = new google.visualization.DataTable();
          tempDT.addColumn('number', 'x');
          tempDT.addColumn('number', 'Data');
          tempDT.addRows([[0, 0]]);
    
          dataArray.push(tempDT);
          console.log('dataArray1', dataArray);
    
          plotDataSize.push(10 * ((1 / interval) * 1000));
    
          window["loadPlot" + (i + 1)](dataArray, plotDataSize);
        }
    
        setInterval(drawPlots.bind(null, dataArray), this.interval);
      }
    
      function drawPlots(dataArray) {
        for (i = 0; i < 1; i++) {
          //Need to now access initialise.dataArray for plot1 (i.e. dataArray[0])
          dataArray[i].removeRow(0);
    
          for (j = 0; j < dataArray[i].getNumberOfRows(); j++) {
            dataArray[i].setValue(j, 0, j);
          }
    
          dataArray[i].insertRows(dataArray[i].getNumberOfRows(), [[dataArray[i].getNumberOfRows() - 1, Math.floor(Math.random() * 99) + 1]]);
    
          //Here I also need to access the optionsPlot1 variable from the loadPlot1() function
          chart.draw(dataArray[i], loadPlot1.optionsPlot1);
        }
      }
    
      function loadPlot1(dataArray, plotDataSize) {
        console.log('dataArray', dataArray[0]);
        var plotSize = dataArray[0].getNumberOfRows();
    
        if (plotSize < plotDataSize[0]) {
          for (i = 0; i < (plotDataSize[0] - plotSize); i++) {
            dataArray[0].addRows([[i, 0]]);
          }
        }
        this.chartPlot1 = new google.visualization.LineChart(document.getElementById('plot1ChartDiv'));
      }
    
      loadPlot1.optionsPlot1 = {
        curveType: 'none',
        lineWidth: 1,
        legend: {
          position: 'none'
        },
        backgroundColor: '#0b0b0c',
        vAxis: {
          baselineColor: '#343434',
          viewWindow: {
            max: 100,
            min: 0
          },
          gridlines: {
            color: '#343434'
          }
        },
        hAxis: {
          baselineColor: '#343434',
          textPosition: 'none',
          gridlines: {
            color: '#343434'
          }
        },
        width: 400,
        height: 400,
        chartArea: {
          width: "90%",
          height: "90%",
          top: "2%"
        },
        series: [
          { color: 'white' }
        ]
      };
    </script>
    
     

Share This Page