Скрипт Google: создание диаграммы HTML с помощью триггера UrlFetchApp - PullRequest
1 голос
/ 17 июня 2020

Впервые публикую здесь, и я учусь как go с Javascript и возможностями сценариев Google, поэтому извиняюсь, если я недостаточно ясен или пропустил еще одну ветку с ответом, похожим на мой.

Просто чтобы дать небольшую справку о том, что я пытаюсь сделать на случай, если я пропустил более простое решение. Я работаю над скриптом Google, создающим сводный отчет для Google do c из отправки формы Google для клиента, и он хотел бы получить график, включающий краткое изложение нескольких вариантов линейного масштаба, поэтому мне нужно найти способ сгенерировать диаграмму, вывести ее в файл (или получить blob) и затем вставляем в аннотацию do c. Сначала я посетил Charts API (изнутри скрипта Google), который, кажется, больше подходит для метода, к которому я стремлюсь, но визуализация кажется довольно ограниченной, поэтому с тех пор я перешел к исследованию html на основе Версия диаграммы google.visualisation, которая дает лучшие результаты.

На сегодняшний день мне удалось создать веб-приложение Google, которое выводит прилично выглядящую диаграмму для моих целей (пока я использую плоские данные, пока я ' m, тестирующий материал) и вывод на место на диске Google для последующего перехода в Google do c (код ниже), который отлично работает, когда я открываю приложение-скрипт в своем браузере. Проблема, с которой я сталкиваюсь, заключается в том, что это часть более широкого рабочего процесса. Я пытаюсь понять, как запустить создание диаграммы, запустив ее как функцию в моем более широком сценарии или используя функцию UrlFetchApp для вызова существующее веб-приложение для построения диаграммы с использованием запроса на получение, что, похоже, не нравится сценарию ... лучшее, что я могу понять, это то, что он выплевывает html из веб-приложения, но не запускает функции в приложении , и я не могу понять, является ли это преднамеренной блокировкой со стороны Google или я неправильно вызываю скрипт для запуска генерации диаграммы.

Извините, если я не очень хорошо объяснил это, и Я счастлив, если я пропустил какие-либо биты, но я был бы признателен за любую помощь в этом, если кто-то преодолеет подобную проблему.

Спасибо, Найл

Код: Скрипт. js

function doGet(e) {
    
    var template = HtmlService.createTemplateFromFile('html');
    
    return template.evaluate('Web App Window Title').setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
    
}

function doSomething(base64Blob) {

    strDataURI = base64Blob.replace("data:image/png;base64,", "");
    
    var str = Utilities.base64Decode(strDataURI);
    var fileBlob = Utilities.newBlob(str).setContentType('image/png').setName("graph.png");
    var file = DriveApp.createFile(fileBlob);
    
}

html. html

<html>
    <head>
        <!--Load the AJAX API-->
        <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
        <script type="text/javascript">

      // Load the Visualization API and the piechart package.
      google.charts.load('current', {'packages':['corechart']});
      runDrawChart();

      // Set a callback to run when the Google Visualization API is loaded.
      
      function runDrawChart() {
      google.charts.setOnLoadCallback(drawChart);
      }
      
      // Callback that creates and populates a data table, 
      // instantiates the pie chart, passes in the data and
      // draws it.
      function drawChart() {

      // Create the data table.
      var data = new google.visualization.DataTable();
      data.addColumn('string', 'EXCERCISE');
      data.addColumn('number', 'SCORE');
      data.addRows([["1. Call", 5],
["2.1. Character A-1", 3],
["2.1. Character A-2", 1.2],
["2.2. Character B", 4.3],
["3. Chemistry", 6.7],
["4.1. Competencies-1", 9.3],
["4.2. Competencies-2", 8.9],
["4.3. Competencies-3", 4.5],
["4.4. Competencies-4", 2],
["4.5. Competencies-5", 1.4],
["4.6. Competencies-6", 8.7],
["4.7. Competencies-7", 5],
["4.8. Competencies-8", 7.4],
["4.9. Competencies-9", 9],
["4.10. Competencies-10", 3.3]]);

      // Set chart options
      var options = {
        width: 1200,
        height: 700,
        bar: {groupWidth: "22%"},
        fontSize: 22,
        legend: { position: "none" },
        chartArea:{left:600,right:20,top:0,bottom:50,width:'100%',height:'100%'}
      };
      
      // Instantiate and draw our chart, passing in some options.
      var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
      
      google.visualization.events.addListener(chart, 'ready', function () {
        chart_div.innerHTML = '<img src="' + chart.getImageURI() + '">';
        
        google.script.run.doSomething(chart.getImageURI());
      });

      chart.draw(data, options);
    }
    </script>
    </head>

    <body> //Div that will hold the pie chart <div id="chart_div" style="width:400; height:300"
        ></div>
    </body>
</html>

А вот код другой функции, которую я попытался вызвать, чтобы получить изображение диаграммы:

function doGet(e) {
  
  try {
        var url = 'https://script.google.com/macros/s/[ID]]/exec';
        
        var options = {
            "method": "GET",
            "followRedirects": true,
            "muteHttpExceptions": true
        };
        
        var result = UrlFetchApp.fetch(url, options);
    }
    catch (e) {
    Logger.log(e);
    }
    
    Logger.log(result);

}

Ответы [ 2 ]

1 голос
/ 18 июня 2020

Вот что я в итоге придумал на тот случай, если он будет кому-то полезен ... это немного похоже на взлом, но он работает в соответствии с условиями моего исходного вопроса.

В В конце я не смог найти сценарий для вызова страницы диаграммы html, как это было бы при открытии в браузере, поэтому я нашел обходной путь, когда я вызываю веб-приложение, строящее диаграмму, с помощью службы Google Pagespeedonline, которая вызывает веб-приложение и строит для меня изображение диаграммы (не часть его предполагаемого использования, но помогает) ... опять же, конечно, есть более элегантный способ добиться этого, но пока это работает.

Я пробовал комментируя все сценарии, чтобы описать работу сценария, но извиняюсь, если что-то неясно:

Первый код Google Script с исходными данными, которые я хочу превратить в диаграмму:

Код.gs

//can be run as part of a larger workflow in a script if you need to pass the chart data from elsewhere
function doGet(e) {
    
    //assign a unique identifier to know what the chart will be called when picking up later on
    var thisUuid = Utilities.getUuid();
    
    //data stored as part of the example here, but you can reconfigure to your liking as long as you
    //alter the chart generation java accordingly in the html page: https://developers.google.com/chart/interactive/docs/examples#mouseover-tooltip-example
    var jsonData = [[" Tarantella (1989)", 7.2],
                ["Larceny (1996)", 7.8],
                ["Doodlebug (1997)", 7.1],
                ["Following (1998)", 7.5],
                ["Memento (2000)", 8.4],
                ["Insomnia (2002)", 7.2],
                ["Batman Begins (2005)", 8.2],
                ["The Prestige (2006)", 8.5],
                ["The Dark Knight (2008)", 9.0],
                ["Inception (2010)", 8.8],
                ["The Dark Knight Rises (2012)", 8.4],
                ["Interstellar (2014)", 8.6],
                ["Quay (2015)", 6.8],
                ["Dunkirk (2017)", 7.9],
                ["Tenet (2020)", 0]];
    
    //specify a folder id where you'd like your file to end up (can be avoided but might make tracking the output file a little more difficult)
    var outputFolderId = //[put drive folder id here]
    
    //uri encode the parameters for passing as part of url in pagespeedonline url fetch
    var timestampEncoded = encodeURIComponent(thisUuid);
    var jsonDataEncoded = encodeURIComponent(JSON.stringify(jsonData));
    var folderIdEncoded = encodeURIComponent(outputFolderId);
    
    //declare the id of the google app with the chart building function in it
    var chartBuildAppId = //[insert app id here];
    
    //builds the url you'll be calling including the parameters it needs to build the chart
    var url = 'https://script.google.com/macros/s/' + chartBuildAppId + '/exec?thisUuid=' + thisUuid + '&jsonData=' + jsonDataEncoded + '&folderId=' + folderIdEncoded;
    
    //url encode so it can be included as part of the pagespeedonline url
    var urlEncoded = encodeURIComponent(JSON.stringify(url));
    
    //get your API key here: https://developers.google.com/speed/docs/insights/v5/get-started
    var pageSpeedOnlineApiKey = //[insert pagespeedonline API Key here];
    
    //call the pagespeedonline link to trigger the chart generation with the parameters fron above
    try {
        var url = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=' + encodeURIComponent(url) + '&key=' + pageSpeedOnlineApiKey;
        
        var options = {
            'method': 'get',
            "contentType": "application/json",
            'muteHttpExceptions': false
        };
        
        var result = UrlFetchApp.fetch(url);
        
        //providing the fetch is successful we can grab the file by name using uuid above (used as it will be unique) and retrieve the file ID for editing/using as needing
        outputImageId = DriveApp.getFolderById(outputFolderId).getFilesByName(thisUuid + '.png').next().getId();
    }
    catch (e) {
        Logger.log(e);
    }
    
    //all being well we now have the id of the outputted chart image and can do what we like with it as part of a broader workflow
    Logger.log(outputImageId);
}

Второй скрипт Google, который получает запрос на получение и строит диаграмму

Code.gs

function doGet(e) {

//take the parameters from the first script and parse in the case of the json
var passedUuid = e.parameter.thisUuid;
var passedJson = e.parameter.jsonData.toString();
var parsedJson = JSON.parse(passedJson);
var passedFolderId = e.parameter.folderId;

//declare the html chart builder and pass the parameters over
var template = HtmlService.createTemplateFromFile('html')
template.jsonChartData = passedJson;
template.fileNameUuid = passedUuid;
template.folderId = passedFolderId;

//call the chart builder
return template.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);

}

//gets the chart data from the html page and turns into a file for using elsewhere
function saveChartAsImage(base64Blob, fileNameUuid, folderId) {

var graphFolder = DriveApp.getFolderById(folderId);

//take the graph in its raw image format and transform for setting the file content
strDataURI = base64Blob.replace("data:image/png;base64,", "");
var str = Utilities.base64Decode(strDataURI);

//declare the file content and the file name
var fileBlob = Utilities.newBlob(str).setContentType('image/png').setName(fileNameUuid + ".png");

//output to a file
graphFolder.createFile(fileBlob);

}

html. html

<html>
    <head>
        <!--Load the AJAX API-->
        <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
        <script type="text/javascript">
    
    //declare the variables needed from the script.gs page
      var jsonChartData = <?= jsonChartData ?>;
      var fileNameUuid = <?= fileNameUuid ?>;
      var folderId = <?= folderId ?>;
      
      // Load the Visualization API and the piechart package.
      google.charts.load('current', {'packages':['corechart']});
      runDrawChart();

      // Set a callback to run when the Google Visualization API is loaded.
      function runDrawChart() {
      google.charts.setOnLoadCallback(drawChart);
      }
      
      // Callback that creates and populates a data table, 
      // instantiates the pie chart, passes in the data and
      // draws it.
      function drawChart() {

      // Create the data table.
      var data = new google.visualization.DataTable();
      data.addColumn('string', 'EXCERCISE');
      data.addColumn('number', 'SCORE');
      data.addRows(JSON.parse(jsonChartData));

      // Set chart options
      var options = {
        width: 800,
        height: 700,
        bar: {groupWidth: "22%"},
        fontSize: 22,
        legend: { position: "none" },
        chartArea:{left:300,right:20,top:0,bottom:50,width:'100%',height:'100%'}
      };
      
      // Instantiate and draw our chart, passing in some options.
      var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
      
      google.visualization.events.addListener(chart, 'ready', function () {
        
        var chartIm = chart.getImageURI();
        chartIm.ready = true;
        generateChartImage();
        
        function generateChartImage() {
        google.script.run.saveChartAsImage(chartIm, fileNameUuid, folderId);
        }
        
      });

      chart.draw(data, options);
    }
    </script>
    </head>

    <body> //Div that will hold the pie chart <div id="chart_div" style="width:400; height:300"
        ></div>
    </body>
</html>
0 голосов
/ 17 июня 2020

HTML:

function drawGasTestChart(dt){
      if(dt){
        var hA=dt[0];
        dt.splice(0,1);
        var dA=dt.slice();
        var data = new google.visualization.DataTable();
        for(var i=0;i<hA.length;i++){
          if(i===0){
            data.addColumn('string',hA[i]);
          }else{
            data.addColumn('number',hA[i]);
          }
        }
        data.addRows(dA);
        var options={
        title:'Gas Test Results',
        fontSize: 12,
        fontName: 'Roman',
        width:640,
        height:400,
        hAxis:{slantedText:true,slantedTextAngle:90},
        legend:{position:'bottom'},
        chartArea:{left:75,top:75,width:'60%',height:'50%'},
        series:{0: {targetAxisIndex: 0},1: {targetAxisIndex: 1}, 2: {targetAxisIndex: 1}},
        vAxes: {0: {title: '%LEL'},1: {title: 'PPM'}}
        };
        var chart=new google.visualization.ColumnChart(document.getElementById('GasTest'));
        google.visualization.events.addListener(chart,'ready',function(){
        gdatObj['imagURI']=chart.getImageURI();
        gdatObj.ready=true;
        saveGasTestChartImage();
    });
        chart.draw(data,options);
      }
    }

    google.charts.load('current', {'packages':['corechart']});
    //google.charts.setOnLoadCallback(drawAllCharts);
    console.log('charts.html code');
    </script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...