Google sheet, apps script, webapp | Load và Hiển thị biểu đồ theo năm chọn từ List box

Giáo án link (giaoan.link) chia sẻ tiếp đến các bạn trong chuyên mục Google sheet, apps script, webapp. Trong bài này, mình cùng các bạn tìm hiều về project ” Load và Hiển thị biểu đồ theo năm chọn từ List box“. Với project này, bạn dễ dàng load dữ liệu từ sheet của spreadsheet và hiển thị dưới dạng biểu đồ (chart) lên nền tảng webapp. Đặc biệc ở đây, bạn có thể chọn lọc (filter) theo năm để load biểu đồ. Dưới đây là code và video hướng dẫn bạn thực hiện.

Bạn xem và tìm kiếm các project ở trang tổng hợp project này: truy cập

Các project excel, google sheet ngẫu nhiên:

Ở trên trang Apps script “Load chart” gồm có 2 trang nhỏ là “Coge.gs” và “loadchart.html”

Mã trang “Code.gs” của Loadchart

function doGet() {
return HtmlService.createTemplateFromFile('loadchart')
.evaluate()
.addMetaTag('viewport', 'width=device-width, initial-scale=1') 
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
}

function getData(){
let ws = SpreadsheetApp.openById("10x6U6xZjDB4TQqZOo20OQsTPpER2lo49Cmas77TKxqI")
let ss = ws.getSheetByName('Data');
let dataset = ss.getDataRange().getDisplayValues()
let data1 = dataset.map(r => [r[1],r[2],r[3],r[4],r[5]])
let name = dataset.map(r => [r[0]])
let header = data1.shift()
let chosedata_year = ss.getRange("G2").getValue();  
let chosedata_month = chosedata_year -1;
Logger.log(data1)
//NAME USE CHOSE YEAR OF DATA TO SHOW ON CHART
return {name: name[chosedata_year],header: header, data:data1[chosedata_month]}
}

Mã trang “loadchart.html” của Loadchart


<!DOCTYPE html>
<html>
  <head> 
    <!--https://youtube.com/netmediacctv--> 
    <base target="_top">    
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
    .border {  
     border: 2px solid black;
     border-radius: 10px;  
    }
    </style>
  </head>
  <body>
    <div class="border" >
       <canvas id="myChart"></canvas>        
    </div> 
  <script>
 
  google.script.run.withSuccessHandler(output).getData()  

  function output(res) {
      const ctx = document.getElementById('myChart') ;
      new Chart(ctx, {
        type: 'line',
        data: {
          labels: res.header,
          datasets: [{
            label: res.name,
            data: res.data.map(Number),            
            backgroundColor: [
              '#f20808',
              '#08f23f',
              '#FF6390',
              '#086bf2',
              '#f29708',
            ],
            borderColor: '#000000',
            borderWidth: 1
            }]
        },
        options: {
          scales: {
            y: {
              beginAtZero: true
              }
          }
        }
    });
  }
</script>
</body>
</html>

Ở trên trang Apps script “Filter chart” gồm có 2 trang nhỏ là “Coge.gs” và “index.html”

Code trên trang “Code.gs”

function doGet() {
return HtmlService.createTemplateFromFile('index')
.evaluate()
.addMetaTag('viewport', 'width=device-width, initial-scale=1') 
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
}

function processForm(formObject) {
  const ss = SpreadsheetApp.getActive();
  const dataSheet = ss.getSheetByName("Data");  
  var value1 = formObject.choose_year;
  var chosedata1 = dataSheet.getRange("H2").setValue(value1);
  console.log(chosedata1);  
}

Code trên trang “index.html”

<!DOCTYPE html>
<html>
  <head>     
    <!--https://youtube.com/netmediacctv--> 
    <base target="_top">    
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.1/font/bootstrap-icons.css">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet"
      integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css" />
  
    <style>  
 
    button{
      border: none;
      padding: .7em .8em;
      margin: 0px;
      background-color: #ffc107;
      color: black;
      border-radius: 5px;
      font: inherit;
      text-transform: uppercase;
      font-weight: bold;
      cursor: pointer;
    }
    </style>
  </head>
  <body >
     <div class="container" style="border: solid 2px #aafe7d; background-color: green; border-radius: 10px" >   
      <h1 style="margin: 10px; text-align: center; color: white; font-weight: bold">XEM BIỂU ĐỒ THỐNG KÊ THEO NĂM</h1>  
      <form id="InventoryForm" onsubmit="handleFormSubmit(this)">  
          <div class="div1 mb-3 input-group">        
            <span class="input-group-text bg-primary text-white"><i class="bi bi-bar-chart-steps"></i></span>
            <select class="form-select" id="choose_year" name="choose_year" required>       
              <option value="">-- Chọn năm để xem thống kê --</option>
              <option value="2020">2020</option>
              <option value="2021">2021</option>
              <option value="2022">2022</option>
              <option value="2023">2023</option>
              <option value="2024">2024</option>  
            </select>
            <button type="submit" id="btn" >Submit</button> 
          </div>  
      </form>
      <iframe id="iframeid" src="https://script.google.com/macros/s/AKfycby6-sFxmEDmIRxsq_wweGasIWzaym-d0HAN_czP9hJJh4W2q2kTHM7D_tmAWXqcew1PJg/exec" style="border:0px solid blue;  height:650px; width: 100%;"></iframe>
    </div>

  <script>
    window.addEventListener("load", functionInit, true); 

    //Initialize functions onload
    function functionInit(){
      preventFormSubmit();
    };

    // Prevent forms default behaviour (Prevent reloading the page)
    function preventFormSubmit() {
      var forms = document.querySelectorAll('form');
      for (var i = 0; i < forms.length; i++) {
        forms[i].addEventListener('submit', function(event) {
        event.preventDefault();
        });
      }
    }   
  
    function handleFormSubmit(formObject) {    
      google.script.run.processForm(formObject);    
      document.getElementById("InventoryForm").reset();
    }

    document.getElementById("btn").addEventListener("click", (event) => {     
      setTimeout(function() {  
        event.preventDefault()   
        //document.getElementById("choose_year").value =""           
        document.getElementById('iframeid').src += '';
      }, 0000);    
    }) 

  </script>
</body>
</html>