1 Chương 1: giới thiệu package htmlwidgets

1.1 Đặt vấn đến

Trong bối cảnh thế giới hiện nay, việc truyền tải thông tin phân tích và dữ liệu một cách trực quan và tương tác trở nên ngày càng quan trọng. Với sự phát triển của công nghệ thông tin, internet, và các ứng dụng web, người dùng ngày càng có nhu cầu truy cập và tương tác với dữ liệu phân tích một cách dễ dàng và thuận tiện. Việc tích hợp các biểu đồ, bản đồ vào các ứng dụng web hoặc tài liệu HTML giúp cho việc truyền tải thông tin phân tích trở nên dễ dàng và hiệu quả hơn.

1.2 Mục tiêu nghiên cứu

Hiểu được tính năng cốt yếu của gói htmlwidgets là cho phép tích hợp các đối tượng tương tác và trực quan, chẳng hạn như biểu đồ, bản đồ, và đồ thị tạo từ các gói dữ liệu phân tích trong R, vào các ứng dụng web hoặc tài liệu HTML. Điều này giúp làm cho dữ liệu và kết quả phân tích trở nên dễ hiểu và trực quan hơn, cũng như tăng tính tương tác và trải nghiệm người dùng. Qua bài nghiên cứu , người đọc có thể nắm một số vấn đề chính về package này như:

  • Tích hợp với các gói dữ liệu phân tích: Package htmlwidgets được thiết kế để tích hợp dễ dàng với các gói dữ liệu phân tích khác trong RStudio như ggplot2, plotly, dygraphs, leaflet, v.v. Điều này cho phép người dùng sử dụng dữ liệu đã được xử lý và phân tích từ các gói khác và biểu diễn chúng một cách trực quan và tương tác.

  • Hiển thị dữ liệu đa dạng: Package htmlwidgets hướng đến việc hỗ trợ hiển thị các loại dữ liệu đa dạng như dữ liệu địa lý, chuỗi thời gian, dữ liệu đa biến và dữ liệu lớn. Việc hỗ trợ nhiều loại dữ liệu giúp người dùng thích ứng và áp dụng package vào nhiều bối cảnh phân tích khác nhau.

  • Tạo ra các biểu đồ và bản đồ tương tác: Một trong những mục tiêu chính của package htmlwidgets là giúp người dùng tạo ra các biểu đồ và bản đồ tương tác, cho phép người dùng thao tác và khám phá dữ liệu từ nhiều góc độ. Các biểu đồ và bản đồ tương tác giúp người dùng hiểu rõ hơn về sự phụ thuộc và tương quan giữa các biến số trong dữ liệu.

  • Tích hợp với ứng dụng web: Package htmlwidgets hướng đến việc tích hợp các biểu đồ và bản đồ tương tác vào các ứng dụng web. Điều này cho phép người dùng tạo ra các ứng dụng web tương tác để thao tác và hiển thị kết quả phân tích một cách trực quan.

1.3 Giới thiệu package htmlwidgets

Package “htmlwidgets” được đặt tên dựa trên hai yếu tố chính: “HTML” là viết tắt của “HyperText Markup Language” - ngôn ngữ đánh dấu siêu văn bản, và “widgets” đề cập Package “htmlwidgets” được đặt tên dựa trên hai yếu tố chính: “HTML” là viết tắt của “HyperText Markup Language” - ngôn ngữ đánh dấu siêu văn bản, và “widgets” đề cập đến các thành phần tương tác nhỏ hỗ trợ hiển thị và nhập dữ liệu trên các ứng dụng và trang web như biểu đồ, bản đồ và các thành phần tương tác khác.

Tên gọi “htmlwidgets” đã phản ánh rõ ràng chức năng của package, nó tạo ra các “widget” tương tác trong RStudio có khả năng tích hợp với ngôn ngữ HTML. Nhờ vào các “widget” này, người dùng có thể tạo và tùy chỉnh các biểu đồ và bản đồ trực quan, cho phép hiển thị dữ liệu một cách trực quan và tương tác trong môi trường web. Tên package này đồng thời nhấn mạnh tính linh hoạt và tích hợp dễ dàng của các “widget” trong các ứng dụng và trang web.

Trong package “htmlwidgets” có một số hàm chính để tạo và tùy chỉnh các widget html. Dưới đây là những hàm chính có trong package này:

  • createWidget: Hàm này dùng để tạo một widget html từ một đối tượng R. Nó là hàm cốt lõi trong package “htmlwidgets” và cho phép bạn tạo các widget tương tác từ dữ liệu và phân tích trong R.

  • saveWidget: Hàm này dùng để lưu widget html vào một tệp tin html. Khi bạn muốn chia sẻ widget tương tác với người khác hoặc tích hợp vào các trang web, bạn có thể sử dụng hàm này để lưu widget vào một trang web.

  • onRender: Hàm này cho phép bạn thêm mã JavaScript tùy chỉnh để thực hiện các tác vụ đặc biệt sau khi widget được hiển thị trên trang web. Điều này giúp bạn tùy chỉnh hành vi của widget sau khi nó đã được tạo.

  • sizingPolicy: Hàm này cho phép bạn xác định các chính sách kích thước cho widget, giúp điều chỉnh kích thước của widget trên trang web. Điều này đảm bảo widget hiển thị đúng kích thước và tỷ lệ trên các môi trường và thiết bị khác nhau.

  • getDependency: Hàm này dùng để truy xuất các phụ thuộc (dependencies) của widget, bao gồm các file CSS và JavaScript cần thiết. Điều này giúp đảm bảo widget hoạt động chính xác và đáng tin cậy.

  • prependContent: Hàm này cho phép bạn thêm nội dung tùy chỉnh vào widget trước khi hiển thị. Điều này giúp bạn tùy chỉnh giao diện và hiển thị của widget theo ý muốn.

  • setWidgetIdSeed: Hàm này cho phép bạn thiết lập hạt giống cho việc tạo các ID duy nhất cho các widget, đảm bảo tính duy nhất và không trùng lặp cho các widget trong ứng dụng.

2 Chương 2: Phân tích package htmlwidgets

2.1 Các function chính

2.1.1 Function createWidget

Hàm createWidget trong gói htmlwidgets của ngôn ngữ lập trình R có công dụng là tạo một widget tương tác từ một đối tượng biểu đồ hoặc đối tượng tương tác được tạo bởi các gói dữ liệu phân tích, ví dụ như highcharter, plotly, dygraphs, leaflet và nhiều gói khác.

Cấu trúc và cách sử dụng của hàm createWidget() như sau:

createWidget( name, x, width = NULL, height = NULL, sizingPolicy = htmlwidgets::sizingPolicy(), package = name, dependencies = NULL, elementId = NULL, preRenderHook = NULL)

Trong đó:

  • name: Tên của widget, nên trùng với tên của đối tượng biểu đồ hoặc tương tác
  • x: Đối tượng biểu đồ hoặc tương tác mà bạn muốn tạo widget. Đây thường là một biểu đồ tạo ra bởi các gói dữ liệu phân tích như highcharter, plotly, dygraphs, leaflet, v.v.
  • widthheight: Kích thước của widget, có thể được đặt bằng giá trị pixel hoặc theo tỷ lệ phần trăm. Mặc định là NULL, cho phép tự động điều chỉnh kích thước dựa trên kích thước của vùng chứa widget.
  • sizingPolicy: Các tùy chọn quy định cách widget được tự động điều chỉnh kích thước trong các vùng chứa khác nhau.
  • package: Tên gói dữ liệu phân tích mà đối tượng biểu đồ hoặc tương tác thuộc về. Mặc định là tên của widget.
  • dependencies: Các phụ thuộc HTML bổ sung cho widget, có thể là các file CSS, JavaScript hoặc các gói dữ liệu liên quan.
  • elementId: Xác định một ID cụ thể cho widget, hữu ích nếu bạn muốn tương tác với widget thông qua JavaScript.
  • preRenderHook: Một hàm được chạy trước khi widget được hiển thị, cho phép bạn tùy chỉnh các thuộc tính của widget trước khi nó xuất hiện.

Hàm createWidget() giúp biến đổi một biểu đồ tĩnh hoặc tương tác thành một widget tương tác mạnh mẽ và đa dạng. Sau khi tạo widget, ta có thể tích hợp nó vào các ứng dụng web, giao diện người dùng hoặc bất kỳ trình soạn thảo tương tác nào hỗ trợ HTML và JavaScript. Điều này giúp ta tạo ra các ứng dụng tương tác phong phú và trực quan, cho phép người dùng tùy chỉnh và khám phá dữ liệu một cách dễ dàng.

Ví dụ minh họa :

library(htmlwidgets)


sigma <- function(gexf, drawEdges = TRUE, drawNodes = TRUE,
                  width = NULL, height = NULL) {
  
  # đọc dữ liệu GEXF
  data <- paste(readLines(gexf), collapse="\n")
  

  settings <- list(
    drawEdges = drawEdges,
    drawNodes = drawNodes
  )
  
  # tạo danh sách x
  x <- list(
    data = data,
    settings = settings
  )
  
  # tạo widget 
  htmlwidgets::createWidget("sigma", x, width = width, height = height)
}

Đoạn mã sigma tạo và hiển thị một biểu đồ mạng sử dụng thư viện sigma.js, dựa trên dữ liệu và cài đặt từ tệp GEXF, và cho phép tương tác với biểu đồ thông qua widget HTML mà widget này được tạo bởi câu lệnh của hàm createwidget trong đoạn mã tạo sigma trên.

2.1.2 Function getDependency

Khi tạo một widget, việc xác định và đính kèm các tệp phụ thuộc cần thiết giúp đảm bảo rằng widget hoạt động đúng cách và đáng tin cậy khi được sử dụng trong môi trường khác nhau và với các dự án khác nhau. Hàm getDependency trong gói htmlwidgets được sử dụng để lấy thông tin về các tệp phụ thuộc từ các gói R đã được cài đặt, đồng thời cho phép đính kèm các tệp phụ thuộc này vào widget. Mô tả: Hàm getDependency được sử dụng để lấy các tệp tin JavaScript và CSS cần thiết để thực hiện một htmlwidget.

  • Cấu trúc hàm : getDependency(name, package = name)

  • Tham số:

    • name: Tên của htmlwidget bạn muốn lấy tệp tin JavaScript và CSS.
    • package: Tên của package chứa htmlwidget. Nếu không cung cấp, hàm sẽ sử dụng tên htmlwidget làm package mặc định.

Hàm getDependency trả về một đối tượng chứa các thông tin về các tệp tin JavaScript và CSS cần thiết để tích hợp htmlwidget vào ứng dụng web một cách đúng đắn. Việc này đảm bảo rằng htmlwidget hoạt động đúng và hiển thị dữ liệu một cách chính xác trong môi trường web.

library(ggplot2)
library(htmlwidgets)

data <- data.frame(
  x = rnorm(100),
  y = rnorm(100)
)

scatter_plot <- ggplot(data, aes(x = x, y = y)) +
  geom_point() +
  labs(title = "Scatterplot")

widget <- createWidget(
  name = "scatter_plot_widget",
  x = scatter_plot,
  dependencies = list(
    getDependency("ggplot2")
  )
)

2.1.3 function onRender

Trong gói htmlwidgets, hàm onRender được sử dụng để thực hiện các thao tác tùy chỉnh sau khi một widget đã được tạo và hiển thị. Hàm này cho phép bạn viết mã JavaScript tùy chỉnh để thay đổi hành vi hoặc giao diện của widget dựa trên các dữ liệu hoặc cài đặt khác.

Cú pháp của hàm onRender như sau: onRender(x, jsCode, data = NULL) Trong đó: - x: Đối tượng HTML Widget. Đây là đối tượng được tạo bởi hàm createWidget hoặc một widget tương thích khác. - jsCode: Một chuỗi ký tự chứa mã JavaScript tùy chỉnh. Mã JavaScript này sẽ được thực thi sau khi widget được hiển thị. - data: Đối số bổ sung để truyền vào hàm jsCode. Điều này cho phép bạn truyền dữ liệu từ môi trường R sang mã JavaScript để sử dụng trong tùy chỉnh.

Khi hàm onRender được thực thi, các tham số được truyền vào trong jsCode sẽ cung cấp thông tin về widget và dữ liệu liên quan. Trong mã JavaScript của bạn, bạn có thể tùy chỉnh các yếu tố của widget, thêm sự kiện hoặc thay đổi giao diện theo ý muốn.

Ví dụ minh họa:

library(leaflet)
# (1)
meh <- "&#x1F610;";
yikes <- "&#x1F628;";
df <- data.frame(
lng = quakes$long,
lat = quakes$lat,
html = ifelse(quakes$mag < 5.5, meh, yikes),
stringsAsFactors = FALSE
)
# (2)
map<- leaflet() %>% addTiles() %>%
fitBounds(min(df$lng), min(df$lat), max(df$lng), max(df$lat)) %>%
onRender("
function(el, x, data) {
for (var i = 0; i < data.lng.length; i++) {
var icon = L.divIcon({className: '', html: data.html[i]});
L.marker([data.lat[i], data.lng[i]], {icon: icon}).addTo(this);
}
}
", data = df)
map

Giải thích câu lệnh: ở câu lệnh (1) : tạo dữ liệu dụng để vẽ bản đồ được lấy từ cột lng (kinh độ) và lat (vĩ độ) của bộ dữ liệu quakes, và chúng ta tạo thêm cột html dựa trên giá trị cột mag (độ lớn) của quakes. Nếu giá trị trong cột mag nhỏ hơn 5.5, thì giá trị tương ứng trong cột html sẽ là meh (mặt cười) và nếu không, nó sẽ là yikes (khuôn mặt kinh hoàng). ở các câu lệnh (2): Sau đó, chúng ta sử dụng leaflet() để khởi tạo một bản đồ và thêm các lớp tiles bằng addTiles(). Tiếp theo, chúng ta sử dụng fitBounds() để điều chỉnh khung bản đồ sao cho bao gồm tất cả các điểm dữ liệu. Sử dụng onRender() để thêm đoạn mã JavaScript tùy chỉnh vào widget của bản đồ. Đoạn mã này sẽ được thực thi sau khi widget được hiển thị. Trong đoạn mã JavaScript, chúng ta sử dụng vòng lặp for để thêm điểm đánh dấu lên bản đồ dựa trên dữ liệu trong data frame df. Điểm đánh dấu được tạo ra bằng cách sử dụng L.marker() và sử dụng biểu tượng là biểu tượng HTML được tạo bởi L.divIcon() với nội dung là giá trị của cột html trong data frame df.

Như vậy, với đoạn mã này, chúng ta sẽ có một bản đồ hiển thị các điểm đánh dấu, mỗi điểm có biểu tượng tùy thuộc vào giá trị của cột mag trong dữ liệu quakes. Nếu giá trị mag nhỏ hơn 5.5, thì biểu tượng sẽ là “meh”, ngược lại nếu lớn hơn hoặc bằng 5.5 thì biểu tượng sẽ là “yikes”.

Một số lợi ích khi sử dụng hàm onRender này :

  1. Tùy chỉnh và tăng cường tính tương tác: Hàm onRender cho phép bạn thực hiện các tùy chỉnh tùy ý trong quá trình hiển thị biểu đồ hoặc widget. Bạn có thể sử dụng JavaScript để thêm các tương tác, hiệu ứng hoặc tính năng động vào widget, giúp tăng tính tương tác và trải nghiệm người dùng.
library(htmlwidgets)
library(leaflet)
library(magrittr)
library(dplyr)

# Dữ liệu
df <- data.frame(
  lng = c(-122.4194, -122.3478, -122.3809),
  lat = c(37.7749, 37.8085, 37.7833),
  name = c("San Francisco", "Oakland", "Berkeley"),
  stringsAsFactors = FALSE
)

# Tạo bản đồ leaflet với các điểm đánh dấu
map <- leaflet(df) %>% 
  addTiles() %>%
  addCircleMarkers(lng = ~lng, lat = ~lat, data = df,
             popup = ~paste(name, lat, lng, sep = "<br/>"))
# Thêm popup với thông tin chi tiết khi click vào điểm đánh dấu
map <- onRender(map,
  "
  function(el, x) {
    // tạo  tương tác khi click trên điểm đánh dấu
    this.on('click', function(e) {
      // Lấy thông tin từ dữ liệu
      var name = e.target.options.popup;
      var lat = e.latlng.lat;
      var lng = e.latlng.lng;
    
      
      // Hiển thị popup
      e.target.bindPopup(popupContent).openPopup();
    });
  }
  "
)

# Hiển thị bản đồ
map

Trong ví dụ này, chúng ta sử dụng hàm onRender để thêm mã JavaScript tùy chỉnh vào bản đồ. Khi người dùng nhấp vào một điểm đánh dấu trên bản đồ, một popup sẽ hiển thị với thông tin chi tiết về điểm đó, bao gồm tên, vĩ độ và kinh độ. Điều này giúp tăng tính tương tác và trải nghiệm người dùng khi sử dụng bản đồ.

  1. Đồng bộ hóa dữ liệu R và JavaScript: Hàm onRender cho phép bạn chuyển dữ liệu từ R sang JavaScript một cách dễ dàng thông qua các biến và tham số. Điều này giúp đồng bộ hóa dữ liệu giữa hai môi trường và cho phép bạn sử dụng dữ liệu R để tạo các biểu đồ và hiển thị dữ liệu trong widget.

  2. Tùy chỉnh giao diện người dùng: Bằng cách sử dụng hàm onRender, bạn có thể tùy chỉnh giao diện người dùng của widget bằng cách thêm CSS hoặc các phần tử HTML tùy chỉnh. Điều này giúp bạn tạo ra các widget có giao diện đẹp mắt và phù hợp với nhu cầu sử dụng.

  3. Tăng khả năng mở rộng: Khi sử dụng hàm onRender, bạn có thể thêm các tính năng và chức năng tùy chỉnh vào widget mà không cần thay đổi mã nguồn chính của gói hay widget. Điều này giúp tăng khả năng mở rộng của gói và giúp bạn dễ dàng bổ sung tính năng mới sau này.

Tóm lại, hàm onRender là một công cụ mạnh mẽ trong gói htmlwidgets và leaflet, cho phép bạn tùy chỉnh và mở rộng tính năng của widget một cách linh hoạt và dễ dàng. Nó giúp bạn tạo ra các widget độc đáo và tương tác, cung cấp trải nghiệm người dùng tốt hơn.

2.1.4 prependContent

  • prependContent cho phép người dùng thêm nội dung HTML bổ sung (chủ yếu là JavaScript và/hoặc CSS) vào một widget, để hiển thị ở chế độ độc lập (tức là in ra bảng điều khiển R) hoặc trong một tài liệu knitr.

  • Cách dùng hàm này là bạn cần truyền vào một đối tượng htmlwidget x, và một hoặc nhiều tham số … là các thẻ, văn bản hoặc HTML hợp lệ. Hàm này sẽ trả về một đối tượng htmlwidget đã được sửa đổi.

library(htmlwidgets)
library(dygraphs)
library(htmltools)
dygraph(nhtemp, main = "New Haven Temperatures") %>%
  htmlwidgets::prependContent(
    tags$style(HTML(".dygraph-title { color: red; }")),
    tags$h1("This is a custom title")
  )

This is a custom title

  • Đoạn mã trên sẽ tạo ra một widget dygraph hiển thị biểu đồ nhiệt độ của New Haven, và sau đó sử dụng hàm prependContent để thêm một đoạn mã CSS để thay đổi màu sắc của tiêu đề biểu đồ thành màu đỏ, và một thẻ h1 để thêm một tiêu đề tùy chỉnh cho widget.

-> Tóm lại, hàm prependContent là cho phép người dùng thêm nội dung HTML bổ sung vào một widget. Bạn có thể sử dụng hàm này để tùy biến giao diện, kiểu dáng, hoặc chức năng của widget theo ý muốn của bạn.

2.1.5 saveWidget

  • saveWidget cho phép người dùng lưu một widget tương tác thành một tệp HTML độc lập, có thể được mở bằng trình duyệt web hoặc nhúng vào các trang web khác.

  • Người dùng cần truyền vào một đối tượng htmlwidget x, và một tên tệp file hoặc một kết nối để lưu widget. Ngoài ra cũng có thể truyền vào các tham số khác để tùy chỉnh widget, như selfcontained (cho biết liệu widget có được lưu thành một tệp HTML duy nhất hay không), libdir (cho biết thư mục để lưu các tệp phụ thuộc), background (cho biết màu nền của widget), và knitrOptions (cho biết các tùy chọn knitr cho widget).

library(htmlwidgets)
library(leaflet)
widget <- leaflet() %>% addTiles()
saveWidget(widget, file = "leaflet.html", selfcontained = TRUE)
  • Đoạn mã trên sẽ tạo ra một widget leaflet hiển thị bản đồ, và sau đó sử dụng hàm saveWidget để lưu widget thành một tệp HTML duy nhất có tên là leaflet.html. Tệp này có thể được mở bằng trình duyệt web hoặc nhúng vào các trang web khác.

-> Tóm lại, hàm saveWidget có tác dụng lưu một widget tương tác thành một tệp HTML độc lập, có thể được mở bằng trình duyệt web hoặc nhúng vào các trang web khác.

2.1.6 setWidgetIdSeed

  • Hàm setWidgetIdSeed dùng để đặt một giá trị ngẫu nhiên cho việc tạo ra các id phần tử cho widget HTML. Dùng hàm này sẽ giúp các id widget ổn định qua các phiên làm việc, không bị thay đổi mỗi lần chạy lại code. Hàm này có ba tham số: seed, kind và normal.kind, để điều chỉnh cách sinh ra các id ngẫu nhiên cho widget. Hàm này trả về một danh sách chứa các thông tin về seed, kind và normal.kind đã được đặt.

  • Đây là một ví dụ về cách sử dụng hàm createWidget để tạo ra một widget HTML từ một đối tượng plotly:

library(shiny)

# Thiết lập hạt giống
setWidgetIdSeed(123)

ui <- fluidPage(
  textOutput("random_number")
)

server <- function(input, output) {
  output$random_number <- renderText({
    # Tạo một giá trị ngẫu nhiên
    random_value <- runif(1)
    paste("Random number:", random_value)
  })
}

shinyApp(ui, server)
Shiny applications not supported in static R Markdown documents

Trong ví dụ trên, hàm setWidgetIdSeed(123) được sử dụng để thiết lập hạt giống cho việc tạo ID của các widget trong giao diện người dùng. Kết quả là mỗi lần bạn chạy ứng dụng Shiny, các ID sẽ được tạo dựa trên hạt giống này, đảm bảo tính nhất quán giữa các lần chạy.

2.1.7 sizingPolicy

  • sizingPolicy cho phép người dùng định nghĩa cách mà các widget HTML sẽ được điều chỉnh kích thước trong các bối cảnh khác nhau, như trình duyệt web, RStudio Viewer, R Markdown, Shiny, v.v. Bạn có thể sử dụng hàm này để tùy biến chiều rộng, chiều cao, đệm, và các tùy chọn khác cho widget của bạn.

  • Giả sử tạo một widget HTML để hiển thị một biểu đồ cột và muốn widget này có chiều rộng và chiều cao cố định là 500 pixel, không phụ thuộc vào kích thước của cửa sổ trình duyệt. Ta có thể sử dụng hàm sizingPolicy như sau:

library(htmlwidgets)
library(ggplot2)

# create a bar chart using ggplot2
data <- data.frame(
  x = c("A", "B", "C", "D"),
  y = c(10, 20, 15, 25)
)
p <- ggplot(data, aes(x, y)) + geom_col()

# convert the plot to a HTML widget
widget <- htmlwidgets::createWidget(
  name = "bar_chart",
  x = list(p = as.list(p)), # convert p to a list
  width = 500,
  height = 500,
  sizingPolicy = htmlwidgets::sizingPolicy(
    defaultWidth = "500px",
    defaultHeight = "500px"
  )
)

2.2 giới thiệu một số package được tích hợp vào R thông qua htmlwidgets

2.2.1 package leaflet

Gói leaflet là một gói trong R được sử dụng để tạo và hiển thị các bản đồ tương tác. Nó dựa trên thư viện Leaflet.js, một thư viện mã nguồn mở được viết bằng JavaScript cho việc tạo bản đồ địa lý tương tác trên web. Gói leaflet cho phép người dùng tạo các bản đồ đa dạng với các điểm đánh dấu, đường đi, khu vực,… Tích hợp gói leaflet vào htmlwidgets cho phép người dùng tạo các bản đồ tương tác và tích hợp chúng vào các ứng dụng Shiny hay các web khác nhau một cách dễ dàng. Điều này giúp cải thiện trải nghiệm người dùng và tạo ra các ứng dụng dữ liệu địa lý tương tác chất lượng cao trong môi trường R.

# ui.R
library(shiny)
library(leaflet)

ui <- fluidPage(
  titlePanel("Leaflet example"),
  leafletOutput("map")
)

# server.R
library(shiny)
library(leaflet)

cities <- data.frame(
  lng = c(-122.4194, -122.3478, -122.3809),
  lat = c(37.7749, 37.8085, 37.7833),
  name = c("San Francisco", "Oakland", "Berkeley"),
  stringsAsFactors = FALSE
)

server <- function(input, output, session) {
  output$map <- renderLeaflet({
    leaflet() %>%
      addTiles() %>%
      addMarkers(lng = ~lng, lat = ~lat, data = df,
                 popup = ~paste(name, lat, lng, sep = "<br/>"))
  })
}

shinyApp(ui = ui, server = server)
Shiny applications not supported in static R Markdown documents

Đoạn mã trên tạo ra một ứng dụng Shiny hiển thị bản đồ gồm ba điểm đánh dấu trên bản đồ cho ba địa điểm khác nhau (San Francisco, Oakland và Berkeley). Khi di chuyển con trỏ chuột vào các điểm đánh dấu, sẽ hiển thị thông tin popup với tên của các địa điểm. Trong đoạn mã trên, gói htmlwidgets không được sử dụng trực tiếp, nhưng gói này đóng vai trò cơ bản trong việc đảm bảo tích hợp và hiển thị tương tác giữa các biểu đồ và bản đồ được tạo bởi gói leaflet và giao diện người dùng của ứng dụng Shiny.

2.2.2 package networkD3

Gói networkD3 trong ngôn ngữ lập trình R là một công cụ đáng chú ý giúp tạo ra các biểu đồ mạng 3D tương tác một cách dễ dàng. Với sự hỗ trợ của thư viện d3.js, gói này cho phép người dùng tạo ra các biểu đồ mạng phức tạp đồng thời cung cấp khả năng tùy chỉnh linh hoạt về màu sắc, kích thước, hình dáng và nhãn. Một trong những điểm mạnh của networkD3 chính là khả năng tích hợp dễ dàng với các ứng dụng web thông qua gói htmlwidgets. Điều này cho phép người dùng tích hợp các biểu đồ mạng vào các ứng dụng Shiny, R Markdown hoặc các dự án web khác một cách thuận tiện và linh hoạt. Sự tích hợp này giúp tạo ra các biểu đồ mạng tương tác hấp dẫn và có tính tương tác cao, giúp người dùng khám phá và hiểu rõ hơn về mối quan hệ và cấu trúc mạng.

ví dụ:

# Tải các gói cần thiết
library(networkD3)
library(htmlwidgets)

nodes <- data.frame(name = c("Sâu", "Chim", "Rắn", "Hải âu", "Cá", "Cá mập", "Cá voi", "Thực vật", "Động vật ăn cỏ", "Động vật ăn thịt"), group = c(1, 2, 3, 2, 4, 5, 4, 6, 7, 8))

links <- data.frame(source = c(1, 2, 3, 4, 5, 6, 7, 8, 9), target = c(2, 3, 4, 5, 6, 7, 8, 9, 10), value = c(2, 2, 2, 1, 3, 1, 1, 1, 2))

# Trừ đi 1 cho các cột source, target và name
links$source <- links$source - 1
links$target <- links$target - 1
nodes$group <- nodes$group - 1

# Vẽ biểu đồ chuỗi thức ăn
forceNetwork(Links = links, Nodes = nodes,
             Source = "source", Target = "target",
             Value = "value", NodeID = "name",
             Group = "group", opacity = 0.8) %>%
  htmlwidgets::onRender("
    function(el, x) {
      d3.select(el).selectAll('.node').on('mouseover', function(d) {
        d3.select(this).style('fill', 'red');
      }).on('mouseout', function(d) {
        d3.select(this).style('fill', null);
      });
    }
  ")

Đoạn mã trên sử dụng gói networkD3 và htmlwidgets để tạo và hiển thị một biểu đồ lực đẩy thể hiện mối quan hệ trong chuỗi thức ăn trong tự nhiên. Các nút biểu thị cho các loài trong chuỗi thức ăn và các liên kết thể hiện mối quan hệ ăn uống giữa chúng. Câu lệnh với hàm onRender để thêm sự kiện tương tác cho các nút trên biểu đồ. Khi người dùng di chuột qua một nút, nút đó sẽ được tô màu đỏ. Khi di chuột ra khỏi nút, màu sẽ được khôi phục về màu ban đầu.

2.2.3 package dygraphs

Gói dygraph trong ngôn ngữ lập trình R là một công cụ hữu ích và mạnh mẽ cho việc tạo và hiển thị biểu đồ tương tác thời gian. Dựa trên thư viện JavaScript Dygraphs, gói này cung cấp khả năng tạo biểu đồ thời gian một cách dễ dàng và tùy chỉnh, cho phép người dùng tương tác với dữ liệu một cách trực quan.

Một trong những điểm đáng chú ý của gói dygraph là khả năng tích hợp linh hoạt với dữ liệu R và chuyển chúng thành biểu đồ Dygraphs một cách thuận tiện thông qua các hàm và cú pháp đơn giản. Các tính năng mạnh mẽ như di chuột qua dữ liệu, di chuyển, zoom và lựa chọn phạm vi thời gian cho phép người dùng khám phá và phân tích dữ liệu thời gian một cách hiệu quả.

Bên cạnh đó, gói dygraph cho phép tùy chỉnh linh hoạt về nhiều khía cạnh của biểu đồ như màu sắc, kiểu đường, tiêu đề và hiển thị thông tin chi tiết. Với khả năng hỗ trợ nhiều loại dữ liệu thời gian và tính năng phong phú, gói này thực sự là một công cụ hữu ích trong việc thể hiện và phân tích dữ liệu thời gian một cách trực quan và thông qua giao diện tương tác.

ví dụ:

library(dygraphs)
lungDeaths <- cbind(mdeaths, fdeaths)
dygraph(lungDeaths)|> dyRangeSelector()

biểu đồ tương tác sử dụng dữ liệu thống kê về tử vong từ các nguyên nhân khác nhau theo thời gian, và người dùng có thể tương tác với biểu đồ để xem chi tiết các khoảng thời gian khác nhau qua câu lệnh dyRangeSelector() được sử dụng để thêm thanh điều khiển lựa chọn phạm vi thời gian vào biểu đồ, cho phép người dùng dễ dàng chọn khoảng thời gian để xem chi tiết.

3 Kết luận