1

Я только начал изучать скрипт/JavaScript для Google Apps и хотел бы знать, как изменить форму, манипулировать многомерными данными из Google Spreadsheets. Я прочитал некоторые сообщения, например, this one, говорящие, что GAS не является гибким с манипуляциями с данными. Но пост немного устарел, поэтому я задаюсь вопросом, есть ли какие-либо новые изменения/дополнения к функциям GAS.Манипулирование данными таблицы для визуализации

Ниже приведен функциональный код. Он может успешно провести диаграмму ниже. Но то, что я действительно хочу это:

  1. группы по "Weekday" (dayOfWeek(toDate(A))) и "Пункт" (column B)
  2. использования "Пункт" в качестве фильтра

    enter image description here.

Я попытался с помощью PIVOT B, GROUP BY dayOfWeek(toDate(A)), но он вернулся либо One or more participants failed to draw()× сообщения об ошибке или неожиданный формат.

<html> 
    <head> 
    <title> 
     Test 
    </title> 
    <!--Load the AJAX API--> 
    <script type="text/javascript" src="https://www.google.com/jsapi"></script> 
    <script type="text/javascript"> 
     google.load('visualization', '1', {'packages': ['table', 'controls', 'corechart']}); 
     google.setOnLoadCallback(initialize); 

     function initialize() { 

       var url = 'https://docs.google.com/spreadsheets/d/1_mSbT87MVWOiX2cfKX_x3dgTnToY5ulCWeGGCVn13iQ/gviz/tq?sheet=Sheet1&tq=' 

       var queryStringDaily = encodeURIComponent("SELECT dayOfWeek(toDate(A)), sum(C), sum(D), sum(E), sum(F), sum(G), sum(H) GROUP BY dayOfWeek(toDate(A)) LABEL dayOfWeek(toDate(A)) 'Weekday' "); 

       var queryDaily = new google.visualization.Query(url+ queryStringDaily); 
       queryDaily.send(drawDaily); 
     } 

     function drawDaily(dailyTicket) { 

       //prepare data 
       var dailyTicket_table = dailyTicket.getDataTable(firstRowIsHeader = true); 

       // Create a dashboard. 
       var dashboard = new google.visualization.Dashboard(
        document.getElementById('dashboard_div2')); 

       // Create a filter 
       var categoryFilter = new google.visualization.ControlWrapper({ 
        'controlType': 'CategoryFilter', 
        'containerId': 'filter_div2', 
        'options': { 
        'filterColumnLabel': 'Weekday' 
        } 
       }); 

       //create chart 
       var dailyChart = new google.visualization.ChartWrapper({ 
        'chartType': 'LineChart', 
        'containerId': 'current_day', 
        'options': { 
        'title': 'Tickets by Rep, Item, and Weekday', 
        'legend': {position: 'right'}, 
        //reformat x-axis tickmarks 
        'hAxis': {'viewWindow': {'min': 1.5, 'max': 6.5}, 
           'ticks': [//{v: 1, f: 'Sunday'}, 
             {v: 2, f: 'Monday'}, 
             {v: 3, f: 'Tuesday'}, 
             {v: 4, f: 'Wednesday'}, 
             {v: 5, f: 'Thursday'}, 
             {v: 6, f: 'Friday'}, 
             //{v: 7, f: 'Saturday'} 
             ] 
          },      
        } 
       }); 

       // bind charts and controls to dashboard 
       dashboard.bind(categoryFilter, dailyChart); 

       // Draw the dashboard. 
       dashboard.draw(dailyTicket_table); 

     } 


    </script> 
    </head> 

    <body> 
    <!--Div that will hold the dashboard--> 
    <div id="dashboard_div2"></div> 
    <!--Divs that will hold each control and chart--> 
    <div id="filter_div2"></div> 
    <div id="current_day" style="align: center; width: 500px; height: 250px;"></div> 

    </body> 
</html> 

ответ

0

Я думаю, что сегодня утром у меня было прозрение момент.После обучения и заимствования кодов из других сообщений (отмеченных ниже в сценарии) я смог создать диаграмму, которую я хочу.

  1. Как предложил @Mogsdad, я переместил столбцы B (Issue) в начало элементов «SELECT», а затем использовал этот столбец для аннотаций и фильтрации. Текст аннотации оказался безумно выше каждого отдельного бара, но я смог скрыть их, установив fontsize of annotated.textStyle на 0.
  2. Я также настраиваю всплывающую подсказку, так что Weekday (формат номера) не отображается.

Я думаю, что это проблема вокруг моей проблемы. Если у вас есть лучшие предложения, я был бы признателен учиться.

<html> 
 
    <head> 
 
    <title> 
 
     Test 
 
    </title> 
 
    <!--Load the AJAX API--> 
 
    <script type="text/javascript" src="https://www.google.com/jsapi"></script> 
 
    <script type="text/javascript"> 
 
     google.load('visualization', '1', {'packages': ['table', 'controls', 'corechart']}); 
 
     google.setOnLoadCallback(initialize); 
 

 
     function initialize() { 
 

 
       var url = 'https://docs.google.com/spreadsheets/d/1_mSbT87MVWOiX2cfKX_x3dgTnToY5ulCWeGGCVn13iQ/gviz/tq?sheet=Sheet1&tq=' 
 
       
 
       var queryStringDaily = encodeURIComponent("SELECT B, dayOfWeek(toDate(A)), sum(C), sum(D), sum(E), sum(F), sum(G), sum(H) GROUP BY dayOfWeek(toDate(A)), B LABEL dayOfWeek(toDate(A)) 'Weekday' , B '{role: \"annotation\"}' "); 
 

 
       var queryDaily = new google.visualization.Query(url+ queryStringDaily); 
 
       queryDaily.send(drawDaily); 
 
     } 
 

 
     function drawDaily(dailyTicket) { 
 

 
       //prepare data 
 
       var dailyTicket_table = dailyTicket.getDataTable(firstRowIsHeader = true); 
 
       
 
       //NEW!!! create tooltip 
 
       //inspired by http://stackoverflow.com/questions/17924826/add-tooltips-to-a-google-line-chart-with-multiple-data-series-with-simplified 
 
       var columns = [2]; // jump to the value columns 
 
       for (var i = 2; i < dailyTicket_table.getNumberOfColumns(); i++) { 
 
        columns.push(i); 
 
        columns.push({ 
 
         type: 'string', 
 
         properties: { 
 
          role: 'tooltip' 
 
         }, 
 
         calc: (function (j) { 
 
          return function (dt, row) { 
 
           return dt.getColumnLabel(j) //+ ': Weekday:' + dt.getValue(row, 1) 
 
           + ' Tickets:' + dt.getValue(row, j) 
 
          } 
 
         })(i) 
 
        }); 
 

 
        columns.push({sourceColumn: 0, 
 
         //calc: getValueAt.bind(undefined, 1) 
 
         type: "string", 
 
         role: "annotation", 
 
         label: "Issue"}); 
 
       } 
 
       columns = [1].concat(columns); 
 

 
       var view = new google.visualization.DataView(dailyTicket_table); 
 
       view.setColumns(columns) 
 

 
       // Create dashboard. 
 
       var dashboard = new google.visualization.Dashboard(
 
        document.getElementById('dashboard_div2')); 
 

 
       // Create filter 
 
       var issueFilter = new google.visualization.ControlWrapper({ 
 
        'controlType': 'CategoryFilter', 
 
        'containerId': 'issue-div', 
 
        'options': { 
 
        'filterColumnLabel': 'Issue', 
 
        'ui': { 
 
        'allowMultiple': false, 
 
        'allowNone': false, 
 
        } 
 
        }, 
 
        //Set default filter value 
 
        'state': {'selectedValues': [dailyTicket_table.getValue(1, 1)]} 
 
       }); 
 

 
       //create chart 
 
       var dailyChart = new google.visualization.ChartWrapper({ 
 
        'chartType': 'ColumnChart', 
 
        'containerId': 'current_day', 
 
        'options': { 
 
         'legend': {position: 'right'}, 
 
         //Set the fontsize of labels so they don't show up crazily 
 
         'annotations': {textStyle: {'fontsize': 0}, 
 
            //use 'line' style so to remove the line pointer 
 
             style: 'line'}, 
 
         'hAxis': {'viewWindow': {'min': 1.5, 'max': 6.5}, 
 
           'ticks': [//{v: 1, f: 'Sunday'}, 
 
              {v: 2, f: 'Monday'}, 
 
              {v: 3, f: 'Tuesday'}, 
 
              {v: 4, f: 'Wednesday'}, 
 
              {v: 5, f: 'Thursday'}, 
 
              {v: 6, f: 'Friday'}, 
 
              //{v: 7, f: 'Saturday'} 
 
              ] 
 
           }, 
 
        } 
 
       }); 
 

 
       // bind charts and controls to dashboard 
 
       dashboard.bind(issueFilter, dailyChart); 
 

 
       // Draw the dashboard. 
 
       dashboard.draw(view); 
 
     } 
 

 
    </script> 
 
    </head> 
 

 
    <body> 
 
    <!--Div that will hold the dashboard--> 
 
    <div id="dashboard_div2"></div> 
 
    <!--Divs that will hold each control and chart--> 
 
    <div id="filter_div2"></div> 
 
    <div id="issue-div"></div> 
 
    <div id="current_day" style="align: center; width: 1100px; height: 500px;"></div> 
 

 
    </body> 
 
</html>

1

Вы можете добавить несколько фильтров. Для этого с исходными данными:

  1. Вы должны SELECT дополнительный текстовый столбец B и включить его в формулировках GROUP BY и необязательно LABEL.

    var queryStringDaily = encodeURIComponent("SELECT B, dayOfWeek(toDate(A)), sum(C), 
          sum(D), sum(E), sum(F), sum(G), sum(H) 
          GROUP BY dayOfWeek(toDate(A)), B 
          LABEL dayOfWeek(toDate(A)) 'Weekday', B 'Issue' "); 
    

    Обратите внимание, что у нас есть B. Если мы этого не сделаем, мы получим упомянутые вами ошибки. Это потому, что LineChart ожидает столбец меток, а затем столбцы связанных последовательностей. Перемещение текстового столбца в начало SELECT приводит к ошибкам.

  2. Добавить фильтр на «Issue».

    var issueFilter = new google.visualization.ControlWrapper({ 
        'controlType': 'CategoryFilter', 
        'containerId': 'issue-div', 
        'options': { 
        'filterColumnLabel': 'Issue' 
        } 
    }); 
    
  3. Привязать новый фильтр к приборной панели.

    dashboard.bind(issueFilter, dailyChart); 
    

И это все!

Results

... Нет, это не так. Поскольку Issue был нашей первой колонкой, она была выбрана как основная ось, что не так полезно.

На данный момент ваша задача - выбрать подходящую визуализацию, соответствующую вашим данным, потому что LineChart этого не делает.

Примечание: этот снипп возможен.

google.load('visualization', '1', { 
 
    'packages': ['table', 'controls', 'corechart'] 
 
}); 
 
google.setOnLoadCallback(initialize); 
 

 
function initialize() { 
 

 
    var url = 'https://docs.google.com/spreadsheets/d/1_mSbT87MVWOiX2cfKX_x3dgTnToY5ulCWeGGCVn13iQ/gviz/tq?sheet=Sheet1&tq=' 
 

 
    var queryStringDaily = encodeURIComponent("SELECT B, dayOfWeek(toDate(A)), sum(C), sum(D), sum(E), sum(F), sum(G), sum(H) GROUP BY dayOfWeek(toDate(A)),B LABEL dayOfWeek(toDate(A)) 'Weekday', B 'Issue' "); 
 

 
    var queryDaily = new google.visualization.Query(url + queryStringDaily); 
 
    queryDaily.send(drawDaily); 
 
} 
 

 
function drawDaily(dailyTicket) { 
 

 
    //prepare data 
 
    var dailyTicket_table = dailyTicket.getDataTable(firstRowIsHeader = true); 
 
    console.log(JSON.stringify(dailyTicket_table).replace(/\\"/g,"'").replace(/"/g,'')); 
 

 
    // Create a dashboard. 
 
    var dashboard = new google.visualization.Dashboard(
 
    document.getElementById('dashboard-div')); 
 

 
    // Create a filter 
 
    var issueFilter = new google.visualization.ControlWrapper({ 
 
    'controlType': 'CategoryFilter', 
 
    'containerId': 'issue-div', 
 
    'options': { 
 
     'filterColumnLabel': 'Issue' 
 
    } 
 
    }); 
 

 
    var categoryFilter = new google.visualization.ControlWrapper({ 
 
    'controlType': 'CategoryFilter', 
 
    'containerId': 'weekday-div', 
 
    'options': { 
 
     'filterColumnLabel': 'Weekday' 
 
    } 
 
    }); 
 

 
    //create chart 
 
    var dailyChart = new google.visualization.ChartWrapper({ 
 
    'chartType': 'LineChart', 
 
    'containerId': 'linechart-div', 
 
    'options': { 
 
     'title': 'Tickets by Rep, Item, and Weekday', 
 
     'legend': { position: 'right'}, 
 
     //reformat x-axis tickmarks 
 
     'hAxis': { 
 
     'viewWindow': { 'min': 1.5, 'max': 6.5}, 
 
     'ticks': [ 
 
      //{v: 1, f: 'Sunday'}, 
 
      { v: 2, f: 'Monday' }, 
 
      { v: 3, f: 'Tuesday' }, 
 
      { v: 4, f: 'Wednesday'}, 
 
      { v: 5, f: 'Thursday' }, 
 
      { v: 6, f: 'Friday' }, 
 
      //{v: 7, f: 'Saturday'} 
 
     ] 
 
     }, 
 
    } 
 
    }); 
 

 
    // bind charts and controls to dashboard 
 
    dashboard.bind(issueFilter, dailyChart); 
 
    dashboard.bind(categoryFilter, dailyChart); 
 

 
    // Draw the dashboard. 
 
    dashboard.draw(dailyTicket_table); 
 

 
}
<html> 
 
    <head> 
 
    <title> 
 
     Test 
 
    </title> 
 
    <!--Load the AJAX API--> 
 
    <script type="text/javascript" src="https://www.google.com/jsapi"></script> 
 

 
    </head> 
 

 
    <body> 
 
    <!--Div that will hold the dashboard--> 
 
    <div id="dashboard-div"> 
 
     <div id="control-div"> 
 
     <div id="issue-div"> 
 
     </div> 
 
     <div id="weekday-div"> 
 
     </div> 
 
     </div> 
 
     <div id="charts-div"> 
 
     <div id="linechart-div" style="align: center; width: 500px; height: 250px;"> 
 
     </div> 
 
     </div> 
 
    </div>  
 

 
    </body> 
 
</html>

+1

, если все остальное терпит неудачу, и вы не можете построить запрос с помощью GQL (https://developers.google.com/chart/interactive/docs/querylanguage), вы всегда можете получить все данные диапазон и фильтр/группу с javascript. –

+0

Пятно на, Зиг - это техника, которую я использовал чаще всего. – Mogsdad

+0

@Mogsdad, большое спасибо за ваши предложения. Я был вдохновлен вашими комментариями и повторил проблему, используя columnChart. Как было сказано выше, я думаю, что в какой-то степени он решил мою проблему, и я все уши, если вы считаете, что коды могут быть улучшены дальше. Заранее спасибо! – Lily

Смежные вопросы