编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

svg演示kafka的broker和zookeeper动态交互

wxchong 2024-07-19 05:41:12 开源技术 13 ℃ 0 评论

根据《开发动画演示系统-计划和架构》中我第一步需要实现一个web前端来动态演示分布式系统。今天已经可以展示简单的动画了。哈哈



该动画还很初级,只是演示了kafka的broker在启动的时候,先要想zookeeper注册一个id。kafka用zookeeper来管理kafka集群的所有broker。后面我将继续完善和丰富这个动画。还要加上交互效果。本文分享一下这个动画的制作过程。

准备环境

需要启动一个http server。用nodejs非常方便。

用npm安装一个简单的http server:

npm install -g http-server

准备一个项目目录, 并启动http-server

mkdir kafka
cd kafka
http-server 

现在这个kafka目录就是web站点的根目录了。可以打开:

http://localhost:8080/

准备项目结构


安装js库

npm install @svgdotjs/svg.js @svgdotjs/svg.draggable.js jquery

svgjs 就是我用来绘制svg动画的,draggable是它的一个插件,可以实现拖拽。运行之后就会把js类库安装在node_modules下面了。就可以在html里面引用了。jquery大家都知道,不可或缺。

开始写页面

一开始先画出效果再说,后面在慢慢重构。先引入js,可以从node_modules直接引入,很方便。

<script src="node_modules/jquery/dist/jquery.js"></script>
<script src="node_modules/@svgdotjs/svg.js/dist/svg.js"></script>
<script src="node_modules/@svgdotjs/svg.draggable.js/dist/svg.draggable.js"></script>

写js入口函数

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

这里调用了一个函数createNode,后面讲。我把节点的数据信息放到json文件里面,然后用数据驱动的方式画图。这样做的好处是:我可以用python在后端用算法生成svg的动画数据,一来我喜欢用python,二来这样比较高效。第一步我先mock一下,等数据模型差不多稳定了我再写后台生成算法。

数据模型设计

下面是broker节点的定义:

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

我按照svg的结构来定义数据节点,方便编程和理解,这也是基于领域模型驱动的设计(domain driven design)的一个重要思想。

绘制节点函数

    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(); // 支持拖拽
    }

绘制连线

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

箭头的绘制花了我很多时间,最后还是找到了方法。这里svg有个神奇的地方是箭头的方向可以根据线的方向自动调整。就是"orient": "auto"。

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

绘制动画

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

svg画动画真的很简单,一句话就可以搞定,哈哈。

总结

svg很强大也很方便,值得学习。利用svgjs的attr()函数,我可以直接把节点数据json里面的内容灌入svg节点,方便我做数据驱动的编程。

文字不太容易表达得很细致,我后面会录一期视频详细讲解一下。全部的代码可以在我的github里面下载:

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

感兴趣的小伙伴,可以评论和转发,也欢迎给我的github提pr和建议。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表