2025年5月31日 星期六

AppSheet 教學:如何透過 QuickChart.io 實現動態雷達圖

今天我們要來解決一個 AppSheet 使用者常遇到的問題:如何在 AppSheet 中製作「雷達圖」(Radar Chart)?AppSheet 本身內建的圖表功能中並沒有直接支援雷達圖,但別擔心!我們可以透過一個強大的免費 API 服務——QuickChart.io——來實現這個功能,並且能將其動態嵌入到我們的 AppSheet 應用程式中。

為什麼選擇 QuickChart.io?

AppSheet 雖然提供了多種圖表類型,但在某些特定視覺化需求上,例如雷達圖,我們就需要尋求外部工具的協助。QuickChart.io 是一個開源的圖表生成服務,它允許我們透過 API(簡單來說就是一個網址)傳遞圖表設定和數據,然後它會回傳一張圖表圖片。這種方式非常適合嵌入到 AppSheet 中。

實作步驟

我們的目標是根據 AppSheet 中的數據(例如:每日血壓記錄中的高壓、低壓、心跳數值)動態生成雷達圖。

1. 準備雷達圖的 JSON 設定 (在 QuickChart.io 網站)

首先,我們需要到 QuickChart.io 網站來「設計」我們的雷達圖。

  • 前往 QuickChart.io 網站: https://quickchart.io/

  • 找到雷達圖範例或使用 Chart Maker:

    • 你可以在其 Docs -> Chart Types -> Radar chart 找到雷達圖的 JSON 設定範例。

    • 或者直接使用 Chart Maker (https://quickchart.io/chart-maker/),在左側編輯區修改圖表設定。

    一個基本的雷達圖 JSON 結構如下(影片範例):

    {
      type: 'radar', // 圖表類型為雷達圖
      data: {
        labels: ['高壓', '低壓', '心跳'], // 雷達圖的軸標籤
        datasets: [{
          label: '健康狀況', // 圖例標籤
          data: [120, 80, 60] // 對應的數據,順序需與 labels 一致
        }]
      }
    }
    Json

    你可以先在 QuickChart.io 的編輯器中調整這些設定,直到預覽的雷達圖符合你的基本需求。

2. 取得圖表模板的短網址 (Template URL)

當你在 QuickChart.io 的 Chart Maker 中調整好圖表後,它會提供一個「Chart URL」。但為了方便在 AppSheet 中動態修改數據,我們需要的是一個「模板短網址」。

  • 在 Chart Maker 編輯好圖表後,點擊下方的 "Save as template" 按鈕。

  • 系統會彈出一個視窗,提供一個類似這樣的短網址:
    https://quickchart.io/chart/render/sf-xxxxxxxxxxxxxxxxx (後面的 sf-xxxx 是一組唯一的 ID)
    這個網址就是我們雷達圖的「基底模板」。

3. 理解動態數據傳遞方式

QuickChart.io 允許我們在模板網址後面附加參數來動態修改圖表數據。對於單一數據集的雷達圖,最常用的參數是 data1

  • 格式:模板短網址?data1=[數值1,數值2,數值3]

  • 例如,如果我們的模板短網址是 https://quickchart.io/chart/render/sf-32d96ffe-8d2b-4e1b-be04-b642a6bbb094,而我們想傳入高壓 130、低壓 70、心跳 80 的數據,那麼完整的圖片網址就會是:
    https://quickchart.io/chart/render/sf-32d96ffe-8d2b-4e1b-be04-b642a6bbb094?data1=[130,70,80]

4. 在 AppSheet 中設定虛擬欄位 (Virtual Column)

現在回到你的 AppSheet 應用程式編輯器。

  • 新增虛擬欄位: 在你存放數據的資料表 (Table) 中,新增一個虛擬欄位 (Add Virtual Column)。

  • 欄位命名: 例如取名為「雷達圖」。

  • 設定欄位類型 (Type): 將類型設定為 Image

  • 設定公式 (App formula):
    假設你的模板短網址是 https://quickchart.io/chart/render/sf-32d96ffe-8d2b-4e1b-be04-b642a6bbb094 (請替換成你自己的短網址 ID),並且你的資料表中有 [高壓][低壓][心跳] 這三個欄位。
    公式將會是:

    "https://quickchart.io/chart/render/sf-32d96ffe-8d2b-4e1b-be04-b642a6bbb094?data1=" & LIST([高壓], [低壓], [心跳])
    • 說明:

      • 前半部分 "..." 是固定的模板網址和 data1= 參數,用雙引號包起來表示字串。

      • & 是字串連接符號。

      • LIST([高壓], [低壓], [心跳]) 會將這三個欄位的值組合成一個列表,例如 [121,74,74],AppSheet 在連接時會自動將其轉換成 QuickChart.io 需要的格式 [121,74,74](注意,AppSheet 的 LIST() 函數輸出結果會自動符合 QuickChart 的數組格式要求,若直接字串連接則需要手動添加 [ ] 和 ,)。

  • 儲存設定: 按下 "Done" 和 "Save"。

成果展示

完成以上設定後,當你在 AppSheet 中檢視每一筆資料的詳細視圖 (Detail View) 時,你就會看到一個根據該筆資料的「高壓」、「低壓」、「心跳」數值動態生成的雷達圖圖片。

![alt text](https://i.imgur.com/Y9A9cM6.png)


(示意圖:AppSheet 中顯示的動態雷達圖)

進階客製化

QuickChart.io 還支援許多其他的客製化選項,例如:

  • 圖表大小: 可以在 Chart Maker 設定,或透過 URL 參數 (如 &width=500&height=300)。

  • 背景顏色: 可以在 Chart Maker 設定,或透過 URL 參數 (如 &backgroundColor=green)。

  • 多組數據 (datasets): 雷達圖也可以比較多組數據,這時 JSON 結構會更複雜,URL 參數也會變成 data1data2 等。

你可以參考 QuickChart.io 的官方文件來探索更多可能性。

總結

透過 QuickChart.io,我們成功地為 AppSheet 應用程式加入了原本不支援的動態雷達圖功能。這種方法不僅免費,而且彈性很高,可以應用到各種需要圖表視覺化的場景。希望今天的教學對你有幫助!


資源連結:

希望這篇文章對您有所幫助!



2025年5月30日 星期五

AppSheet 教學:如何使用 List 相減找出「有上班打卡但未下班打卡」的人員

今天我們要來解決一個在製作出勤打卡系統時常遇到的問題:如何快速找出今天有哪些人已經打了上班卡,但還沒有打下班卡?這對於人事管理或主管即時掌握同仁狀況非常有用。

這個問題是一位網友提出的,他的情境是:

  • 有兩個獨立的資料表:一個記錄「上班打卡 (CheckIn)」,另一個記錄「下班打卡 (CheckOut)」。

  • 他希望能有一個列表,只顯示那些「今天有上班打卡,但還沒打下班卡」的人員。

解決這個問題的關鍵在於 AppSheet 的「List 相減」功能。我們的思路是:

  1. 取得今天所有「上班打卡」的人員ID列表。

  2. 取得今天所有「下班打卡」的人員ID列表。

  3. 將第一個列表減去第二個列表,剩下的就是我們需要的「有上班打卡但未下班打卡」的人員ID。

  4. 最後,我們使用這個結果ID列表來篩選我們的人員主資料表。

操作步驟:

假設我們有以下資料表:

  • People: 儲存所有人員的基本資料,包含 PeopleID (人員ID,Key值) 和 PeopleName (人員姓名)。

  • CheckIn: 儲存上班打卡紀錄,包含 PeopleID (關聯到 People 表) 和 CheckInDate (打卡日期)。

  • CheckOut: 儲存下班打卡紀錄,包含 PeopleID (關聯到 People 表) 和 CheckOutDate (打卡日期)。

我們要建立一個 Slice (資料表切片) 來顯示結果:

  1. 進入 Slice 設定

    • 在 AppSheet 編輯器中,到 Data > Slices

    • 點擊 New Slice

  2. 設定 Slice 基本資料

    • Slice Name:例如「有上班卡沒下班卡人員」

    • Source Table:選擇 People (因為我們最終要顯示的是人員列表)。

  3. 設定 Row filter condition (列篩選條件)
    這就是核心公式所在。請貼上以下公式:

    IN(
        [PeopleID],
        SELECT(CheckIn[PeopleID], [CheckInDate] = TODAY())
        -
        SELECT(CheckOut[PeopleID], [CheckOutDate] = TODAY())
    )
    Excel

    讓我們來解析這個公式:

    • SELECT(CheckIn[PeopleID], [CheckInDate] = TODAY()):

      • 這個部分會從 CheckIn 資料表中選出所有 PeopleID

      • 篩選條件是 [CheckInDate] = TODAY(),也就是只選取打卡日期為「今天」的紀錄。

      • 結果會是一個今天有上班打卡的人員ID列表 (List)。

    • SELECT(CheckOut[PeopleID], [CheckOutDate] = TODAY()):

      • 同理,這個部分會從 CheckOut 資料表中選出所有 PeopleID

      • 篩選條件是 [CheckOutDate] = TODAY(),只選取下班打卡日期為「今天」的紀錄。

      • 結果會是一個今天有下班打卡的人員ID列表 (List)。

    • - (減號):

      • 這是 AppSheet 中的 List subtraction (列表相減) 運算子。它會從第一個列表中移除所有同時也存在於第二個列表中的項目。

      • 所以,(今日上班打卡人員ID列表) - (今日下班打卡人員ID列表) 的結果,就是那些今天有上班打卡、但還沒有下班打卡的人員ID列表。

    • IN([PeopleID], ...):

      • [PeopleID] 是指目前 People 資料表 (Slice 的來源資料表) 中每一列的人員ID。

      • IN() 函數會檢查目前的 [PeopleID] 是否存在於後面經過相減運算後產生的人員ID列表中。

      • 如果存在,則該列人員資料就會顯示在這個 Slice 中。

  4. 儲存 Slice 與 App

    • 點擊 Slice 設定右下角的 Save

    • 再點擊 AppSheet 編輯器右上角的 Save 按鈕儲存整個 App 的變更。

驗證結果:

現在,你可以到 App 中查看名為「有上班卡沒下班卡人員」的視圖 (如果沒有自動產生,可以手動建立一個基於此 Slice 的 View)。

  • 當「蔡明和」和「一整天」今天都打了上班卡,但都還沒打下班卡時,這個列表會顯示他們兩人。

  • 如果「蔡明和」打了下班卡,列表中就只會剩下「一整天」。

  • 如果「一整天」也打了下班卡,列表就會變成空的。

如此一來,就能輕鬆掌握哪些同仁上班打了卡卻還沒打下班卡了!

相關官方說明:



[教學] MySQL 如何匯入大型 SQL 資料檔?利用 EmEditor 分割檔案與 phpMyAdmin 匯入實戰

在網站維運的過程中,資料庫的備份與還原是家常便飯。但當資料庫成長到一定規模時,單純的匯出匯入就可能變成一場惡夢。這次,我們將分享一個處理大型 MySQL 資料庫(超過 1GB)的實戰經驗,特別是在有資源限制的虛擬主機環境(如 GoDaddy)中,如何巧妙地完成匯入工作。 前言:我...