第 9 章 htmlwidgets (II): integrate with flexdashboard

9.1 Flexdashboard流程

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裡):

隱藏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:

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.

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);   

9.2.3.2 Plotly events

Plotly提供了幾個自己的events,它們不只可以使圖形DOMObject對傳統html events有反應,而且DOMObject會自動釋放出JSON資料,可讓Handler有更多有趣的變化。

要查詢每個plotly events會使plotly DOMObject釋放出什麼資料,可以利用以下程式範例:

另一個加上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。

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.3 Animation

動態效果可以想成靜態的plot畫很多張(稱為frame),不同張圖的geom間如何連結(使用ids)。

frame

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

  • redraw: transit完是否重畫圖一次。(建議FALSE)

  • mode: transit未完成若使用者又按一次transition要如何處理。(immediate - 中斷未完成的先處理新transition; next - 目前transit完,下一個接新transition; afterall: 等所有前面transition請求都完成才做新transition)

9.3.3 annimation_button

9.3.3.1 Controls

  • 增加button, dropdown menu等去更動:data > . > {trace設定}

先做好變化前後的plotly objects

比較JSON差異

  • data > 0 > mode: 由lines變成markers

將前後有差異部份拿出來設定

設定updatemenus

使用layout套上變化前plotly object

9.3.3.2 animation

9.3.3.2.1 animate trace

first plot the trace you wish to animate.

frame.duration must be set at least as long as transition.duration.

Currently, only scatter traces may be smoothly transitioned from one state to the next. Other traces are compatible with frames and animations but will be updated instantaneously.

9.3.3.2.2 animate layout

A present limitation of the animate API is that only one of either data or layout may be smoothly transitioned at a time. If both are provided, the data will be updated instantaneously after the layout is transitioned.

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