Karn Tirasoontorn

April 7, 2021

สร้างกราฟด้วย Chart.js ผ่าน Stimulus

จากประสบการณ์ที่ได้ลองใช้กราฟมาแสดงรายงานอยู่สักพัก ก็พบว่าการจะสร้างกราฟตัวหนึ่งๆ ขึ้นมาได้เราจะต้องกำหนดพื้นที่ในการแสดงผลใน HTML บ้างก็ div บ้างก็ canvas จากนั้นก็ส่งชุดข้อมูลเข้าไปในฟังก์ชันหรือคลาสของ JavaScript สุดท้ายเราก็จะได้กราฟที่ต้องการออกมา

สำหรับในบทความนี้ก็จะใช้ Chart.js มาทำเป็นตัวอย่างให้ดูกัน

<canvas id="myChart" width="400" height="400"></canvas>
<script>
  var ctx = document.getElementById('myChart').getContext('2d');
  var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ['Apple', 'Blue Berry', 'Mango', 'Kiwi', 'Mangosteen', 'Orange'],
      datasets: [{
        data: [12, 19, 3, 5, 2, 3],
        ...
      }]
    },
  });
</script>

จากตัวอย่างโค้ดข้างต้นเป็นอย่างที่กล่าวไว้มั้ยหละครับ ที่นี้เรามาลองเปลี่ยนให้ใช้งานกับ Stimulus ดีกว่า มาเริ่มต้นกันเลย!

  • สร้าง tag helper สำหรับ render กราฟของเรา

module ChartHelper
  def bar_chart(data, options)
    tag.canvas data: { controller: 'chart', 'chart-type-value': type } do
      tag.object "data-type": 'bar', "data-init": data.to_json, "data-options": options.to_json
    end
  end
end

  • สร้าง Stimulus Controller สำหรับจัดการกราฟ

import { Controller } from "stimulus"

export default class extends Controller {  
  static targets = [ 'canvas' ]
  async connect () {    
    await import(/* webpackChunkName: "chart" */  "chart")    
    const obj = this.element.querySelector("object")    
    const type = obj.getAttribute("data-type")    
    const data = JSON.parse(obj.getAttribute("data-init"))    
    const options = JSON.parse(obj.getAttribute("data-options"))    
    const ctx = this.element.getContext('2d')    
    new Chart(ctx, {      
      type,      
      data,      
      options    
    })  
  }
}

  • เมื่อจะใช้งานกราฟ เราก็สามารถเรียกผ่าน tag helper ที่สร้างขึ้น

<%== bar_chart(@data, @options) %>

  • เพียงเท่านี้ เราจะได้กราฟที่สวยงามตามที่ต้องการออกมา
Screen Shot 2021-04-07 at 17.28.08.png


นอกจากจะใช้งานได้ง่ายขึ้น อีกเหตุผลหนึ่งที่พยายามเปลี่ยนมาใช้ Stimulus ก็เพราะปัญหาการใช้งานในโปรแกรม THIP เองมีการแสดงข้อมูลกราฟค่อนข้างเยอะในแต่ละหน้า โดยแต่ละกราฟจะมีคู่ของ HTML กับ Script แปะติดกันไปด้วยเสมอ ซึ่งเปลี่ยนมาใช้วิธีนี้ก็น่าจะทำให้โค้ด clean ขึ้นอีกนิดหนึ่ง
Screen Shot 2021-04-07 at 17.38.32.png