svg演示kafka的broker和zookeeper動態交互

根據《 》中我第一步需要實現一個web前端來動態演示分佈式系統。今天已經可以展示簡單的動畫了。哈哈


svg演示kafka的broker和zookeeper動態交互


該動畫還很初級,只是演示了kafka的broker在啟動的時候,先要想zookeeper註冊一個id。kafka用zookeeper來管理kafka集群的所有broker。後面我將繼續完善和豐富這個動畫。還要加上交互效果。本文分享一下這個動畫的製作過程。

準備環境

需要啟動一個http server。用nodejs非常方便。

用npm安裝一個簡單的http server:

<code>npm install -g http-server/<code>

準備一個項目目錄, 並啟動http-server

<code>mkdir kafka
cd kafka
http-server /<code>

現在這個kafka目錄就是web站點的根目錄了。可以打開:

<code>http://localhost:8080//<code>

準備項目結構


svg演示kafka的broker和zookeeper動態交互

安裝js庫

<code>npm install @svgdotjs/svg.js @svgdotjs/svg.draggable.js jquery/<code>

svgjs 就是我用來繪製svg動畫的,draggable是它的一個插件,可以實現拖拽。運行之後就會把js類庫安裝在node_modules下面了。就可以在html裡面引用了。jquery大家都知道,不可或缺。

開始寫頁面

一開始先畫出效果再說,後面在慢慢重構。先引入js,可以從node_modules直接引入,很方便。

<code>

/<code>

寫js入口函數

<code> SVG.on(document, 'DOMContentLoaded', function () {
// 定義svg對象, 在body裡面添加一個svg
let svg = SVG().addTo('body').attr({width: 1000, height: 800});
$.getJSON("data/brokers.json?"+version, function (data) {
data.forEach(node => createNode(svg, node))
});
}/<code>

這裡調用了一個函數createNode,後面講。我把節點的數據信息放到json文件裡面,然後用數據驅動的方式畫圖。這樣做的好處是:我可以用python在後端用算法生成svg的動畫數據,一來我喜歡用python,二來這樣比較高效。第一步我先mock一下,等數據模型差不多穩定了我再寫後臺生成算法。

數據模型設計

下面是broker節點的定義:

<code>[
{
"group": {
"id": "broker1",
"transform": {
"translateX": 100,
"translateY": 200
}
},
"shape": {
"type": "rect",
"attributes": {
"x": 10,
"y": 10
}
},
"label": {
"text": "broker1",
"attributes": {
"x": 24,
"y": 8
}
}
},
...
]/<code>

我按照svg的結構來定義數據節點,方便編程和理解,這也是基於領域模型驅動的設計(domain driven design)的一個重要思想。

繪製節點函數

<code>    function createNode(container, data) {
// 用一個group把節點邊框和文本放在一起,這樣可以利用group的transform來定義
// 整個group裡面所有節點的座標位置
let group = container.group()

.transform({translateX: data.group.transform.translateX, translateY: data.group.transform.translateY})
.id(data.group.id);
// TODO style 的信息暫時hardcode, 後面會用程序控制動態變化的效果。
let style = {fill: 'none', stroke: 'blue'};
let attributes = {...style, ...data.shape.attributes};
// 動態的調用函數,可以支持繪製各種圖形,比如:rect, ellipse
let rect = container[data.shape.type](data.group.id.length * 11, 28).attr(attributes);
group.add(rect);

let label = container.text(data.label.text);
label.attr(data.label.attributes);
group.add(label);

return group.draggable(); // 支持拖拽
}/<code>

繪製連線

<code>    let marker = svg.marker(13, 13, function (add) {
add.path('M2,2 L2,11 L10,6 L2,2').fill('blue').stroke({width: 1, color: 'blue'})
}).attr({"refX": "2", "refY": "6", "orient": "auto"});
function createPath(container, data, marker) {
container.path(data.data).id(data.id)
.fill('blue')
.stroke({width: 1, color: 'blue'})
.marker('end', marker);
}/<code>

箭頭的繪製花了我很多時間,最後還是找到了方法。這裡svg有個神奇的地方是箭頭的方向可以根據線的方向自動調整。就是"orient": "auto"。

<code>\t\tlet marker = svg.marker(13, 13, function (add) {
add.path('M2,2 L2,11 L10,6 L2,2').fill('blue').stroke({width: 1, color: 'blue'})
}).attr({"refX": "2", "refY": "6", "orient": "auto"});/<code>

繪製動畫

<code>let circle1 = svg.circle(20).attr({cx: 200, cy:230}).fill('green').animate(2000, 100, 'now').move(380, 300);/<code>

svg畫動畫真的很簡單,一句話就可以搞定,哈哈。

總結

svg很強大也很方便,值得學習。利用svgjs的attr()函數,我可以直接把節點數據json裡面的內容灌入svg節點,方便我做數據驅動的編程。

文字不太容易表達得很細緻,我後面會錄一期視頻詳細講解一下。全部的代碼可以在我的github裡面下載:

<code>https://github.com/jacky-calm/visualize-the-idea/<code>

感興趣的小夥伴,可以評論和轉發,也歡迎給我的github提pr和建議。


分享到:


相關文章: