G2 從 4.0 開始,將全部的交互行爲使用全新的交互語法實現,而且再也不默認內置,須要用戶顯式調用chart.interaction()
接口。爲了幫助你們更好地理解、使用交互語法,咱們將會推出交互語法專題。javascript
本文介紹的是最多見的交互:框選,包括框選的形狀、框選過程當中的圖形變化以及框選後的各類操做。java
框選中,高亮圖形 | 框選後,拖拽 mask |
框選後,過濾數據 |
---|---|---|
框選後,過濾圖形 | 框選的形狀選擇 | 多視圖的框選聯動 |
G2 的交互語法,是將交互拆解成多個環節,每一個環節由觸發和反饋組成。只要你能將交互用天然語言的方式描述出來,就可使用 G2 的交互語法進行組合搭建出交互行爲。在這裏咱們再一塊兒溫習下 G2 交互語法中對於交互環節的定義,更詳細的內容能夠閱讀可視化交互語法。git
G2 將每個交互環節拆解成如下步驟:github
下面咱們就開始框選高亮圖形的交互語法組裝吧,爲了幫助你們理解,每一個交互行爲咱們都會以天然語言 + 交互語法的形式向你們闡述。咱們以柱狀圖的高亮爲例,實現交互的過程當中咱們會使用 G2 內置的 Action,Action 的定義和列表參考 G2 配置交互。markdown
registerInteraction('element-range-highlight', { showEnable: [ { trigger: 'plot:mouseenter', action: 'cursor:crosshair' }, { trigger: 'plot:mouseleave', action: 'cursor:default' }, ], start: [ { trigger: 'plot:mousedown', action: ['rect-mask:start', 'rect-mask:show'], } ], processing: [ { trigger: 'plot:mousemove', action: ['rect-mask:resize', 'element-range-highlight:highlight'], }, ], end: [ { trigger: 'plot:mouseup', action: ['rect-mask:end'] }, ], rollback: [ { trigger: 'dblclick', action: ['element-range-highlight:clear', 'rect-mask:hide'] } ], }); 複製代碼
咱們使用了三個 Action 來實現這個區域高亮功能:ssh
cursor
控制鼠標樣式的 Action,這個 Action 的方法支持全部的鼠標樣式,例如 'pointer'、'crosshair'、'move' 等。rect-mask
矩形的遮罩層,這個 Action 支持的方法有:
element-range-highlight
圖表元素的區域高亮,支持的方法有:
**
交互語法解釋:ide
showEnable
意味着交互是否能夠進行; start
表示交互開始進行; processing
表示交互持續進行; end
表示交互結束; rollback
表示交互回滾。這些過程不徹底是順序的,例如:框選結束後,不須要回滾就能夠繼續開始新的框選; showEnable
在各個環節中都生效。end
環節中的 action 增長 'rect-mask:hide' 這時候框選結束後遮罩層消失,可是框選的高亮效果還存在。框選高亮後咱們能夠開始新的框選,可是若是可以拖拽遮罩層 (mask)使得被遮罩的圖形高亮,體驗更好。
oop
這個交互的步驟以下:spa
注意這個交互同上面交互的差別,新增了 二、5 和 6 三個步驟,遮罩層的變化 3 須要增長觸發條件。code
registerInteraction('element-range-highlight', { showEnable: [ { trigger: 'plot:mouseenter', action: 'cursor:crosshair' }, { trigger: 'mask:mouseenter', action: 'cursor:move' }, { trigger: 'plot:mouseleave', action: 'cursor:default' }, { trigger: 'mask:mouseleave', action: 'cursor:crosshair' }, ], start: [ { trigger: 'plot:mousedown', isEnable(context) { // 不要點擊在 mask 上從新開始 return !context.isInShape('mask'); }, action: ['rect-mask:start', 'rect-mask:show'], }, { trigger: 'mask:dragstart', action: ['rect-mask:moveStart'] } ], processing: [ { trigger: 'plot:mousemove', action: ['rect-mask:resize'], }, { trigger: 'mask:drag',action: ['rect-mask:move'] }, { trigger: 'mask:change', action: ['element-range-highlight:highlight'] } ], end: [ { trigger: 'plot:mouseup', action: ['rect-mask:end'] }, { trigger: 'mask:dragend', action: ['rect-mask:moveEnd']}, ], rollback: [{ trigger: 'dblclick', action: ['element-range-highlight:clear', 'rect-mask:hide'] }], }); 複製代碼
咱們根據這個交互同前一個交互的差異,來逐條增長新的步驟(觸發和反饋):
showEnable
上增長鼠標移入 mask 和移出 mask 的效果。start
環節中觸發遮罩層變化的步驟中增長是否在遮罩層上觸發的斷定。start
環節中增長拖拽遮罩層,在 processing
中增長遮罩層移動、圖形根據遮罩層變化而高亮的步驟。經過這個示例,咱們能夠看到如何來擴展一個交互。框選自己不是交互的目的,框選後的操做纔是框選交互的目的,框選後能夠進行數據過濾、詳情展現、顯示隱藏等,下面咱們經過幾個交互來進行說明。
框選後對數據進行過濾時常見的操做,爲了讓用戶意識到過濾已經發生,而且顯示的告訴用戶如何恢復,咱們在框選發生過濾夠顯示了一個 reset 按鈕。
registerInteraction('brush', { showEnable: [ { trigger: 'plot:mouseenter', action: 'cursor:crosshair' }, { trigger: 'plot:mouseleave', action: 'cursor:default' }, { trigger: 'reset-button:mouseenter', action: 'cursor:pointer' }, { trigger: 'reset-button:mouseleave', action: 'cursor:crosshair' }, ], start: [ { trigger: 'plot:mousedown', action: ['brush:start', 'rect-mask:start', 'rect-mask:show'], }, ], processing: [ { trigger: 'plot:mousemove', action: ['rect-mask:resize'], }, ], end: [ { trigger: 'plot:mouseup', action: ['brush:filter', 'brush:end', 'rect-mask:end', 'rect-mask:hide', 'reset-button:show'], }, ], rollback: [ { trigger: 'reset-button:click', action: ['brush:reset', 'reset-button:hide', 'cursor:crosshair'] }], }); 複製代碼
咱們使用了四個 Action 來實現這個區域高亮功能, cursor 和 rect-mask 已經介紹過,這裏介紹其餘兩個:
brush
經過指定範圍來過濾數據,有下面幾個方法:
reset-button
恢復按鈕,僅有顯示和隱藏兩個方法:
**
幾點說明:
brush-x
僅僅過濾 x 軸範圍內的數據;brush-y
僅僅過濾 y 軸範圍內的數據。對應 rect-mask 也有兩個 Action: x-rect-mask,y-rect-mask。
框選後不進行數據過濾,而僅僅控制圖形的顯示隱藏也是常見的,交互,咱們來看一下這個交互的實現:
registerInteraction('brush-visible', { showEnable: [ { trigger: 'plot:mouseenter', action: 'cursor:crosshair' }, { trigger: 'plot:mouseleave', action: 'cursor:default' }, ], start: [ { trigger: 'plot:mousedown', action: ['rect-mask:start', 'rect-mask:show', 'element-range-highlight:start'], }, ], processing: [ { trigger: 'plot:mousemove', action: ['rect-mask:resize','element-range-highlight:highlight'], }, {trigger: 'mask:end',action: ['element-filter:filter']} ], end: [ { trigger: 'plot:mouseup', action: ['rect-mask:end', 'rect-mask:hide', 'element-range-highlight:end', 'element-range-highlight:clear'], }, ], rollback: [ { trigger: 'dblclick', action: ['element-filter:clear'] } ] }); 複製代碼
這個交互中咱們使用到了,其中 cursor
、 rect-mask
和 element-range-highlight
三個 Action 前面已經介紹到,這裏對新的 Action element-filter
進行說明:
element-filter
[8]:過濾圖表元素,有兩個方法:
從上面的幾個交互咱們能夠看到,多個交互之間會共享大量的 Action,這就解決了交互代碼複用的問題,爲提高開發交互的效率和提高質量提供了保障。
這個交互的步驟同前面的幾個交互相似,最大的差異在於:鼠標在畫布上拖拽時,根據鼠標移動的軌跡改變遮罩層的形狀。
registerInteraction('element-range-highlight', { showEnable: [ { trigger: 'plot:mouseenter', action: 'cursor:crosshair' }, { trigger: 'mask:mouseenter', action: 'cursor:move' }, { trigger: 'plot:mouseleave', action: 'cursor:default' }, { trigger: 'mask:mouseleave', action: 'cursor:crosshair' }, ], start: [ { trigger: 'plot:mousedown', isEnable(context) { // 不要點擊在 mask 上從新開始 return !context.isInShape('mask'); }, action: ['path-mask:start', 'path-mask:show'], }, { trigger: 'mask:dragstart', action: ['path-mask:moveStart'] } ], processing: [ { trigger: 'plot:mousemove', action: ['path-mask:resize'], }, { trigger: 'mask:drag',action: ['path-mask:move'] }, { trigger: 'mask:change', action: ['element-range-highlight:highlight'] }, {trigger: 'mask:end',action: ['element-filter:filter']} ], end: [ { trigger: 'plot:mouseup', action: ['path-mask:end'] }, { trigger: 'mask:dragend', action: ['path-mask:moveEnd']}, ], rollback: [ { trigger: 'dblclick', action: ['element-range-highlight:clear', 'path-mask:hide', 'element-filter:clear'] }], }); 複製代碼
這個交互同上面 「框選後的操做-拖拽」 徹底一致,除了顯示遮罩層的 Action 從 rect-mask
替換成 path-mask
以外,這個 Action 同 rect-mask
的方法徹底一致:
path-mask
矩形的遮罩層,這個 Action 支持的方法有:
除了 rect-mask
和 path-mask
以外 G2 還內置了其餘兩種 circle-mask
和 smooth-path-mask
,除了形狀不一樣外提供的方法徹底相同。
registerInteraction('highlight-view', { showEnable: [ { trigger: 'plot:mouseenter', action: 'cursor:crosshair' }, { trigger: 'mask:mouseenter', action: 'cursor:move' }, { trigger: 'plot:mouseleave', action: 'cursor:default' }, { trigger: 'mask:mouseleave', action: 'cursor:crosshair' }, ], start: [ { trigger: 'plot:mousedown',isEnable(context) { return !context.isInShape('mask'); }, action: ['rect-mask:start', 'rect-mask:show'] }, {trigger: 'mask:dragstart', action: 'rect-mask:moveStart'} ], processing: [ { trigger: 'plot:mousemove', action: 'rect-mask:resize' }, { trigger: 'mask:drag', isEnable(context) { return context.isInPlot(); }, action: 'rect-mask:move'}, { trigger: 'mask:change', action: ['element-sibling-highlight:highlight', 'element-range-highlight:highlight'] } ], end: [ { trigger: 'plot:mouseup', action: 'rect-mask:end' }, { trigger: 'mask:dragend', action: 'rect-mask:moveEnd' }, { trigger: 'document:mousedown', isEnable(context) { return !context.isInPlot(); }, action: ['element-sibling-highlight:clear', 'element-range-highlight:clear', 'rect-mask:end', 'rect-mask:hide'], once: true, }, { trigger: 'document:mouseup', isEnable(context) { return !context.isInPlot(); }, action: ['rect-mask:end'], once: true, } ], rollback: [ { trigger: 'dblclick', action: ['rect-mask:hide', 'element-sibling-highlight:clear', 'element-range-highlight:clear']} ] }); 複製代碼
這個交互同前面提到 「框選後的操做-拖拽」 幾乎如出一轍,除了在調用 Action element-range-highlight
的同時也調用了 element-sibling-highlight
的方法,其含義是「高亮圖形」 的同時 「高亮全部同級 views 的圖形」。
element-sibling-highlight
[10]:高亮當前 view 同一級的 views 的對應圖形,這個 Action 的方法有:
**
更多的解釋:
細心的讀者可能關注到這個交互中出現了幾個前面交互中沒有出現的步驟(觸發和反饋),這些都是一些異常處理的步驟,這關係到一個交互的質量:
document:mousedown
繪圖區域以外按下起鼠標(面上其餘位置 ),結束高亮而且隱藏遮罩層。document:mouseup
繪圖區域以外擡起鼠標(面上其餘位置 ),則結束 rect-mask 的變化。mask:drag
時添加約束條件,若是再也不當前 View 的繪圖區域,則再也不移動。除了多個 View 之間聯動高亮,還能夠進行聯動過濾、圖形隱藏、tooltip 聯動等操做,咱們會在後面的章節中給你們介紹。
框選高亮做爲圖表中常用的交互,在不一樣的場景下框選的過程和結果都有可能變化,傳統的固定死的交互方式並不能知足用戶的需求。當咱們有了交互語法,只要你能列出交互的步驟,就能夠將這些步驟天然地轉換成交互語法,高效並且高質,快去嘗試一下吧!
G2 官網: g2.antv.vision/zh/
github: github.com/antvis/G2