12/08/2018, 13:49

Highchart Advand with datta (P2)

1.Giới thiệu Xin chào các bạn, Hôm nay mình xin giới thiệu tới các bạn một số kĩ thuật nâng cao tiếp theo trong thư viện highchart và một thư viện mới về vẽ các biểu đồ với dữ liệu lớn đó là Highstock. Với thư viện này các bạn có thể dễ dàng tạo ra các biểu đồ có các thanh scroll để có một cái ...

1.Giới thiệu

Xin chào các bạn, Hôm nay mình xin giới thiệu tới các bạn một số kĩ thuật nâng cao tiếp theo trong thư viện highchart và một thư viện mới về vẽ các biểu đồ với dữ liệu lớn đó là Highstock. Với thư viện này các bạn có thể dễ dàng tạo ra các biểu đồ có các thanh scroll để có một cái nhìn tổng quát và trực quan hơn về toàn bộ dữ liệu mà chúng ta có. Các phần hôm nay tôi định trình bày bao gồm:

  1. Thêm các trục tọa độ mới đối với các biểu đồ tích hợp

  2. Thêm scroll cho biểu đồ dữ liệu lớn.

  3. Demo truyền dữ liệu lớn

2.Nội dung

2.1. Thêm các trục tọa độ mới đối với các biểu đồ tích hợp

Để có thể thêm được cột cho một biểu đồ chúng ta xem ví dụ sau:

VD: Vẽ biểu đồ thể hiện nhiệt độ và lượng mưa trung bình theo tháng của Hà Nội và TP Hồ CHí Minh trong năm 2015 với dữ liệu được cho trong bảng dưới đây:

Tháng 1 2 3 4 5 6 7 8 9 10 11 12
Hà Nội Lượng mưa 6 29 45 161 335 229 366 247 107 8 24 28
Hà Nội Nhiệt độ 17.2 18.1 20.7 24.2 26.6 29.8 29.2 29.1 28.3 26.1 23.1 19.3
TP HCM Lượng mưa 18 14 16 35 110 160 150 145 158 140 55 25
TP HCM Nhiệt độ 26.5 27.5 29 30.5 29.5 28.5 28 28 27.5 27.6 27 26

Như chúng ta thấy ở đây là vẽ biểu đồ nhiệt độ và lượng mưa nên chúng ta cần có 2 trục tung (trục y) chúng ta phải thêm như sau.

    yAxis: [{ // Primary yAxis
            labels: {
                format: '{value}°C',
                style: {
                    color: Highcharts.getOptions().colors[2]
                }
            },
            title: {
                text: 'Temperature',
                style: {
                    color: Highcharts.getOptions().colors[2]
                }
            },
            opposite: true

        }, { // Secondary yAxis
            gridLineWidth: 0,
            title: {
                text: 'Rainfall',
                style: {
                    color: Highcharts.getOptions().colors[0]
                }
            },
            labels: {
                format: '{value} mm',
                style: {
                    color: Highcharts.getOptions().colors[0]
                }
            }

        }],

chart rainfall and temperature.jpeg

>>> Xem demo

Tương tự như trên trong trường hợp ta muốn thêm trục X. Theo như lí thuyết thì chúng ta có thêm không giới hạn số lượng các trục X và Y.

2.2. Thêm scroll cho biểu đồ dữ liệu lớn

Trên thực tế có rất nhiều những biểu đồ cập nhật liên tục với dữ liệu thu được rất lớn và chúng ta không thể hiển thị hết trên một màn hình, trong những trường hợp này chúng ta cần có thêm thanh scroll để có thể theo dõi dễ dàng hơn.

Để có thể add thêm thanh scroll vào biểu đồ của chúng ta cần có thêm thư viện Highstock bằng cách thêm vào file html

<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>

<div id="container" style="min-awidth: 310px; height: 400px; margin: 0 auto"></div>

Chúng ta xem ví dụ sau: Vẽ biểu đồ thể hiện nhiệt độ và lượng mưa trung bình theo tháng của Hà Nội và TP Hồ CHí Minh từ năm 2015 đến nay

$(function () {
    $('#container').highcharts({
    		rangeSelector: {
                selected: 1
        },
        title: {
            text: 'Biểu đồ thể hiện nhiệt độ và lượng mưa theo từng tháng của Hà Nội và TP.HCM',
            align: 'left',
            margin: 60,
            x: 20
        },
        plotOptions: {
            series: {
                pointPadding: 0, // Defaults to 0.1
                groupPadding: 0.2 // Defaults to 0.2
            }
        },
        scrollbar: {
                barBackgroundColor: 'gray',
                barBorderRadius: 7,
                barBorderWidth: 0,
                buttonBackgroundColor: 'gray',
                buttonBorderWidth: 0,
                buttonBorderRadius: 7,
                trackBackgroundColor: 'none',
                trackBorderWidth: 1,
                trackBorderRadius: 8,
                trackBorderColor: '#CCC',
                enabled: true
        },
        xAxis: {
            categories: [ '01-2015','02-2015', '03-2015','04-2015', '05-2015','06-2015', '07-2015','08-2015', '09-2015','10-2015', '11-2015','12-2015', '01-2016','02-2016', '03-2016','04-2016', '05-2016','06-2016', '07-2016','08-2016'],
            min: 0,
            max: 8
        },
        yAxis: [{ // Primary yAxis
            labels: {
                format: '{value}',
                style: {
                    color: Highcharts.getOptions().colors[1]
                }
            },
            title: {
                text: 'Lượng mưa',
                style: {
                    color: Highcharts.getOptions().colors[1]
                }
            }
        }, { // Secondary yAxis
            title: {
                text: 'Nhiệt độ',
                style: {
                    color: Highcharts.getOptions().colors['red']
                }
            },
            labels: {
                format: '{value}',
                style: {
                    color: Highcharts.getOptions().colors['red']
                }
            },
            opposite: true
        }],
        legend: {
            align: 'top',
            x: 20,
            verticalAlign: 'top',
            y: 30,
            floating: true,
        },

        series: [{
            type: 'column',
            name: 'Lượng mưa Hà Nội',
            data: [6, 29, 45, 161, 335, 229, 366, 247, 107, 8, 24, 28, 6, 29, 45, 161, 335, 229, 366, 247],
            color: '#3366CC'
        }, {
            type: 'column',
            name: 'Lượng mưa TP.HCM',
            data: [18, 14, 16, 35, 110, 160, 150, 145, 158, 140, 55, 25, 18, 14, 16, 35, 110, 160, 150, 145],
            color: '#b3b3ff'
        }, {
            type: 'line',
            name: 'Nhiệt độ Hà Nội',
            yAxis: 1,
            data: [17.2, 18.1, 20.7, 24.2, 26.6, 29.8, 29.2, 29.1, 28.3, 26.1, 23.1, 19.3, 17.2, 18.1, 20.7, 24.2, 26.6, 29.8, 29.2, 29.1],
            color: '#109618',
            marker: {
            	enabled: false
            }
        }, {
            type: 'line',
            name: 'Nhiệt độ TP.HCM',
            yAxis: 1,
            data: [26.5, 27.5, 29, 30.5, 29.5, 28.5, 28, 28, 27.5, 27.6, 27, 26, 26.5, 27.5, 29, 30.5, 29.5, 28.5, 28, 28],
            color:  '#e6e600',
            marker: {
            	enabled: false
            }
        }]
    });
});

Ta thu được biểu đồ như sau:

chart rainfall with highstock.jpeg

>>> Xem demo

Trong đó:

Thẻ scrollbar cho phép chúng ta khai báo các thuộc tính của thanh Scroll

Thẻ xAxis với các thẻ min, max để qui định số lượng dữ liệu hiển thị tối thiểu và tối đa trên một khung hình.

    xAxis: {
                min: 0,
                max: 8
    }

2.3. Demo truyền dữ liệu lớn

Ví dụ: Vẽ biểu đồ so sánh nhiệt độ trung bình theo ngày giữa hai thành phố Hồ Chí Minh và Tokyo trong 1000 ngày gần đây.

Ta sử dụng lại project trong phần 1 có link tại đây.

>>> Download Project Demo

  1. Tạo thêm một bảng dữ liệu Temperature
#db/migrate/20160829034821_create_temperatures.rb

class CreateTemperatures < ActiveRecord::Migration
  def change
    create_table :temperatures do |t|
      t.string :date
      t.integer :temp
      t.string :country

      t.timestamps null: false
    end
  end
end
#db/seed.rb

puts "== Create temperature"
1000.times do |n|
  FactoryGirl.create :temperature, date: Date.today-n,temp: rand(25..36), country: "hcm"
end

1000.times do |m|
  FactoryGirl.create :temperature, date: Date.today-m,temp: rand(2..27), country: "tokyo"
end
  1. Trong controller
#app/controllers/users_controller.rb

def index
    @users = User.all
    @data = User.all_data @users
    @data_temp = Temperature.all_data
 end

  1. Trong Model
#app/models/temperature.rb

class Temperature < ActiveRecord::Base

  scope :hcm_data, ->{where country: :hcm}
  scope :tokyo_data, ->{where country: :tokyo}

  class << self
    def all_data
      data = []
      date = hcm_data.pluck(:date)
      hcm_temp = hcm_data.pluck(:temp)
      tokyo_temp = tokyo_data.pluck(:temp)
      data << {"date" => date, "hcm" => hcm_temp, "tokyo" => tokyo_temp}
    end
  end
end

  1. Trong View

Add thêm thư viện.

#app/views/layout/application.html.erb

<%= javascript_include_tag "https://code.highcharts.com/stock/highstock.js" %>
<%= javascript_include_tag "https://code.highcharts.com/stock/modules/exporting.js" %>

Viết code html với thẻ div có id là "temp_chart"

#app/views/users/index.html.erb

....
<div id="temp_chart" style="awidth: 1000px; height: 400px; margin-bottom: 200px" data-date="<%= @data_temp[0]["date"]%>" data-hcm="<%= @data_temp[0]["hcm"]%>" data-tokyo="<%= @data_temp[0]["tokyo"]%>"></div>
....
  1. Trong Javascript
#app/assets/javascripts/line_chart.js

$(function () {
  $('#temp_chart').highcharts({
    chart: {
      type: 'spline'
    },
    title: {
      text: 'Biểu đồ thể hiện nhiệt độ theo từng ngay của TP.HCM và Tokyo'
    },
    scrollbar: {
      barBackgroundColor: 'gray',
      barBorderRadius: 7,
      barBorderWidth: 0,
      buttonBackgroundColor: 'gray',
      buttonBorderWidth: 0,
      buttonBorderRadius: 7,
      trackBackgroundColor: 'none',
      trackBorderWidth: 1,
      trackBorderRadius: 8,
      trackBorderColor: '#CCC',
      enabled: true
    },
    xAxis: {
      categories: $('#temp_chart').data("date"),
      min: 0,
      max: 19
    },
    yAxis: {
      title: {
        text: 'Nhiệt độ (°C)'
      }
    },
    plotOptions: {
      line: {
        dataLabels: {
          enabled: true
        },
        enableMouseTracking: false
      }
    },
    series: [{
      name: 'Nhiệt độ TP.HCM',
      data: $('#temp_chart').data("hcm"),
      color: '#109618'
    }, {
      name: 'Nhiệt độ Tokyo',
      data: $('#temp_chart').data("tokyo"),
      color:  '#e6e600'
    }]
  });
});

Ở trên chúng ta đã nhận dữ liệu truyền vào từ view ở các dòng có thẻ "data"

Sau khi thực hiện các bước trên chúng ta thu được kết quả hiển thị như sau:

big_data_chart.png

3.Kết luận và tài liệu tham khảo

Như vậy hôm nay tôi đã giới thiệu xong tới các bạn 2 kĩ thuật nâng cao trong thư viện highcharts và highstock. Tất cả source code được upload tại đây:

>>> Source Code

Tất cả tài liệu tham khảo các bạn có thể đọc tại trang chủ của highchart

http://www.highcharts.com/

Nếu bạn có bất kì khó khăn gì trong việc nhúng highchart vào project Rails thì có thể comment bên dưới hoặc inbox cho tôi qua địa chỉ email hoangtrinh.hv92@gmail.com

Hẹn gặp lại lại các bạn trong bài viết tiếp theo với các kĩ thuật nâng cao tiếp theo!

-- Hoàng Văn Trình AS Việt Nhật K55 Đại học Bách Khoa Hà Nội

0