第 9 章 htmlwidgets (II): integrate with flexdashboard
9.1 Flexdashboard流程
- 如果widgets是在flexdashboard內生成而非
<iframe>
embed, 必需有knitr::opts_chunk$set
設定: https://cran.r-project.org/web/packages/widgetframe/vignettes/widgetframe_and_knitr.html
9.2 客製化面版互動
Plolty自身的互動:modebar, tooltips, etc.
Control panel影響Plotly,分成:
現有SVG element attr.的更改。(無需plotly js重繪)
需plotly js重繪
Plotly影響flexdashboard其他區塊。
9.2.1 面版影響plot
9.2.1.1 改變SVG attribute
- 對面版addEventListener,而handler則對target SVG element進行attribute 改變。
若target SVG element在iframe裡,setAttributes要改setAttrbutesNS(null,…),第一個argument寫null。
9.2.1.2 啟動plotly animation
假設原本要按plotly的play鍵,令該元素id為myPlay。
引入虛擬event js函數(可放在Rmd的include in_header裡):
//假設要對element id 'play3' 虛擬click
function eventFire(el, etype){
if (el.fireEvent) {
el.fireEvent('on' + etype);
} else {
var evObj = document.createEvent('Events');
evObj.initEvent(etype, true, false);
el.dispatchEvent(evObj);
}
}
隱藏play鍵,對該element增加以下attribute:
面版以下方handler來按隱藏之play鍵:
9.2.2 plotly影響面版
善用plotly event會釋出event data的特性。
9.2.3 Events
All interactions involve:
What does a user do to the webpage? (Event)
How to respond? (Handler)
For events, there are:
html basic events: https://www.w3schools.com/jsref/dom_obj_event.asp
other JS supplied events: such as Plotly.js events, https://plot.ly/javascript/plotlyjs-events/
For handlers, they are JavaScripts.
HTML events are “things” that happen to HTML elements.
When JavaScript is used in HTML pages, JavaScript can “react” on these events.
- JS events basic: https://www.w3schools.com/js/js_events.asp
9.2.3.1 Attach event listener
以下二種方法都會讓一個<div>
DOM element可以對滑鼠點擊有反應。
- 直接在DOM element裡寫,如:
<div onclick="JS script">....</div>
- 使用JS的
addEventListener()
method:
<div id="myTarget"> ...</div>
<script>
document.getElementById("myTarget").addEventListener("click",
JSHandler);
</script>
document.getElementById("myTarget")
會取出DOM element中id="myTarget"
的那個,形成一個DOMObject。
document.getElementById("myTarget").addEventListener("click",
JSHandler);
可寫成
var myTarget=document.getElementById("myTarget");
myTarget.addEventListener("click",JSHandler);
Plotly.js使用了jQuery library:
var myTarget=document.getElementById("myTarget");
myTarget.addEventListener("click",JSHandler);
也可以寫成:
var myTarget=document.getElementById("myTarget");
myTarget.on("click",JSHandler);
- 更多關於
.on()
method: https://api.jquery.com/on/
9.2.3.2 Plotly events
Plotly提供了幾個自己的events,它們不只可以使圖形DOMObject對傳統html events有反應,而且DOMObject會自動釋放出JSON資料,可讓Handler有更多有趣的變化。
要查詢每個plotly events會使plotly DOMObject釋放出什麼資料,可以利用以下程式範例:
{R plotly object} %>%
onRender("
function(el) {
el.on('plotly_hover', function(d) {
console.log('Hover: ', d);
});
el.on('plotly_click', function(d) {
console.log('Click: ', d);
});
el.on('plotly_selected', function(d) {
console.log('Select: ', d);
});
}
")
另一個加上plotly event的方式是先把plotly code chunk
<div id='myPlotly'>
會產生plotly object的R code chunk
</div>
包起來,再用
<script>
document.querySelector('#myPlotly > .plotly').on('plotly_hover', function(d) {
console.log('Hover: ', d);
});
</script>
來attach plotly_hover event。
- plotly js有那些客製化events: https://plot.ly/javascript/plotlyjs-events/
9.2.3.3 plotly event to non-Plotly DOM
- Use event data and htmlDOM methods.
9.2.3.4 non-Plotly events to Plotly DOM
- Plotly.js: restyle, …., etc.
9.2.3.5 (放plotly JS)Hover-triggered events
利用hover-fired event所產生的資訊來trigger some action.
dirlib="plotlyExample"
webapp_project_create(dirlib=dirlib, overwrite=T) # 如果出現錯誤,再執行一次(背景下載動作有時會遲滯)
Chart A放上
mtcars %>%
ggplot()+
geom_point(
aes(x=mpg, y=wt,
text=rownames(mtcars))
) -> ggplot_mtcars
ggplot_mtcars %>%
ggplotly()
Chart B放上
9.3 Animation
動態效果可以想成靜態的plot畫很多張(稱為frame),不同張圖的geom間如何連結(使用ids)。
frame
load(url("https://www.dropbox.com/s/0qpmufptv1igydh/big_mac_index.Rda?dl=1"))
df_mac %>%
ggplot()+
geom_point(
aes(y=1,x=index, color=undervalued,
text=name, # tooltips 用
frame=type, ids=name # animation 用
), size=5,
position=position_jitter(
width = 0,
height = 0.002
)
)+
geom_vline(
aes(
xintercept=0
)
) -> gg_mac
gg_complete <- bquote(gg_mac+.(big_mac_design1))
gg_mac %>%
ggplotly(
tooltip=c("text"),
width=700, height=300
) %>%
animation_opts(1000, easing = "elastic", redraw = FALSE) %>%
animation_slider(hide = T) %>%
animation_button(
x = 1, xanchor = "right", y = 0, yanchor = "bottom"
) -> ply_mac
ply_mac
9.3.1 animation_opts
frame: frames間變化完成所花時間(單位,milliseconds, 千分之一秒),包含transition時間。
transition: 由原始圖變化到新圖給予進行smooth transition的時間(單位:milliseconds)
easing: https://github.com/plotly/plotly.js/blob/master/src/plots/animation_attributes.js 下查詢easing。
- 不同easing style: https://easings.net/en
redraw: transit完是否重畫圖一次。(建議FALSE)
mode: transit未完成若使用者又按一次transition要如何處理。(immediate - 中斷未完成的先處理新transition; next - 目前transit完,下一個接新transition; afterall: 等所有前面transition請求都完成才做新transition)
9.3.2 annimation_slider
9.4 Crosstalk
9.5 Other themes
For plain html:
output:
html_document:
theme: null
highlight: null
mathjax: null
9.6 Then what?
jQuery
jQuery UI
jQuery Mobile
AJAX
D3.js