How do I read and modify axes on an already-drawn Google chart?

后端 未结 2 743
傲寒
傲寒 2021-01-16 11:28

I have a page with several google charts on it, mostly combo charts and line charts. For instance:

chart = new google.visualization.LineChart(chartDiv);


        
相关标签:
2条回答
  • 2021-01-16 12:10

    You'd have to ask @Sjoerd how getChartLayoutInterface() works, since it doesn't seem there is any documentation online.

    In the meantime, what you can do is to get the min and max values of each chart that you're creating, and then take the max and min of the max/min for all charts combined.

    Using those max/min values, you can manually set the min/max for each chart (with some nice rounding). To do the rounding nicely, I suggest the following:

    // Take the Max/Min of all data values in all graphs
    var totalMax = 345;
    var totalMin = -123;
    
    // Figure out the largest number (positive or negative)
    var biggestNumber = Math.max(Math.abs(totalMax),Math.abs(totalMin));
    
    // Round to an exponent of 10 appropriate for the biggest number
    var roundingExp = Math.floor(Math.log(biggestNumber) / Math.LN10);
    var roundingDec = Math.pow(10,roundingExp);
    
    // Round your max and min to the nearest exponent of 10
    var newMax = Math.ceil(totalMax/roundingDec)*roundingDec;
    var newMin = Math.floor(totalMin/roundingDec)*roundingDec;
    
    // Determine the range of your values
    var range = newMax - newMin;
    
    // Define the number of gridlines (default 5)
    var gridlines = 5;
    
    // Determine an appropriate gap between gridlines
    var interval = range / (gridlines - 1);
    
    // Round that interval up to the exponent of 10
    var newInterval = Math.ceil(interval/roundingDec)*roundingDec;
    
    // Re-round your max and min to the new interval
    var finalMax = Math.ceil(totalMax/newInterval)*newInterval;
    var finalMin = Math.floor(totalMin/newInterval)*newInterval;
    

    This is similar to how Google determines max/min values (sometimes if you have, say, -6.2, and 3.1 as values, it will use 3.1 for gridlines even though it is an odd number to use). But by creating your own rounding, you can get around needing to figure out how google rounds (which is a tricky proposition).

    Let me know if you don't understand properly.

    0 讨论(0)
  • 2021-01-16 12:10

    According to the documentation getVAxisValue function has the following signature:

    getVAxisValue(position, optional_axis_index)

    Returns the logical vertical value at position, which is an offset from the chart container's top edge. Can be negative.

    Example: chart.getChartLayoutInterface().getVAxisValue(300).

    Call this after the chart is drawn.

    Return Type: number


    Since your goal is to read the maximum values off of the axes and then redraw the charts so that they all have the same maximum values on their axes, i would suggest the following solution

    calculate min/max values of google.visualization.DataTable:

    function calcMinMax(data, colIndex)
    {
       var totalMin  = data.getValue(0,colIndex);
       var totalMax = data.getValue(0,colIndex);
       for(var i = 0; i < data.getNumberOfRows();i++){
            if ( data.getValue(i, colIndex) < totalMin  ) {
              totalMin  = data.getValue(i, colIndex);
            }          
            if ( data.getValue(i, colIndex) > totalMax ) {
              totalMax = data.getValue(i, colIndex);
            }
       }
       return {'min': totalMin, 'max': totalMax };
    } 
    

    and set viewWindow option:

    var vAxisMinMax = calcMinMax(data,1); 
    options.vAxis = {'viewWindow': {'min': vAxisMinMax.min, 'max': vAxisMinMax.max}};
    

    Example

    google.load('visualization', '1', { packages: ['corechart', 'line'] });
    google.setOnLoadCallback(drawBasic);
    
    function drawBasic() {
    
        var data = new google.visualization.DataTable();
        data.addColumn('number', 'X');
        data.addColumn('number', 'Dogs');
    
        data.addRows([
          [0, 5], [1, 10], [2, 23], [3, 17], [4, 18], [5, 9],
          [6, 11], [7, 27], [8, 33], [9, 40], [10, 32], [11, 35],
          [12, 30], [13, 40], [14, 42], [15, 47], [16, 44], [17, 48],
          [18, 52], [19, 54], [20, 42], [21, 55], [22, 56], [23, 57],
          [24, 60], [25, 50], [26, 52], [27, 51], [28, 49], [29, 53],
          [30, 55], [31, 60], [32, 61], [33, 59], [34, 62], [35, 65],
          [36, 62], [37, 58], [38, 55], [39, 61], [40, 64], [41, 65],
          [42, 63], [43, 66], [44, 67], [45, 69], [46, 69], [47, 70],
          [48, 72], [49, 68], [50, 66], [51, 65], [52, 67], [53, 70],
          [54, 71], [55, 72], [56, 73], [57, 75], [58, 70], [59, 68],
          [60, 64], [61, 60], [62, 65], [63, 67], [64, 68], [65, 69],
          [66, 70], [67, 72], [68, 75], [69, 80]
        ]);
    
        var options = {
            hAxis: {
                title: 'Time'
            },
            vAxis: {
                title: 'Popularity'
            }
        };
    
        var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
    
    
        var vAxisMinMax = calcMinMax(data,1); 
        options.vAxis = {'viewWindow': {'min': vAxisMinMax.min, 'max': vAxisMinMax.max}};
       
    
        chart.draw(data, options);
    
        
    }
    
    
    
    
    
    function calcMinMax(data, colIndex)
    {
       var totalMin  = data.getValue(0,colIndex);
       var totalMax = data.getValue(0,colIndex);
       for(var i = 0; i < data.getNumberOfRows();i++){
            if ( data.getValue(i, colIndex) < totalMin  ) {
              totalMin  = data.getValue(i, colIndex);
            }          
            if ( data.getValue(i, colIndex) > totalMax ) {
              totalMax = data.getValue(i, colIndex);
            }
       }
       return {'min': totalMin, 'max': totalMax };
    }
    <script type="text/javascript" src="https://www.google.com/jsapi"></script> 
    <div id="chart_div"></div>

    0 讨论(0)
提交回复
热议问题