d3.js+react实现算法可视化:排序篇
来源:互联网 发布:万网域名指向 编辑:程序博客网 时间:2024/06/06 05:18
前言:
知道d3.js已经很长时间了,直到去年才好好看了一些教程写了一些demo,当时还是3.x版。最近这几天在看react、react-router之类的,想自己写些东西出来,刚好想到该复习下d3.js,自己就做了这个算法可视化的demo,目前只做了排序,包括冒泡排序、插入排序、选择排序、归并排序、快速排序,之后有时间的话会继续做其他的数据结构与算法的可视化。
目前有很多算法可视化的网站,比如新加坡的National University of Singapore就有个visualgo:点击打开链接
visualgo的算法已经很齐全了,而且界面、交互都很不错,比起我的demo那就强太多了
我的demo演示地址:点击打开链接(起了个山寨味很浓的名字,VisualCompute)
使用npm+jspm搭建工程,使用react-router + d3.js 操作svg图像,顺便使用了Materialize当UI(关于select控件有个坑,onChange事件获取不到)。
基本思路:
由于react建议不直接操作dom,所以d3的选择器也就用不上了,svg都是由react进行render,react的方便之处在于每次更新state后会重新render一下dom,所以在排序的时候,每当数据发生变化,就更新state。d3的优势就在于可以进行比例变换,根据数据的大小,把svg的高度变换的一个指定的范围,这样免得图形过大或过小。而且d3还能生成动画,不过我这里暂时没用上。
所以比较关键的地方就在于,如何更新state?
对于一个排序算法,比如冒泡排序,每次数据发生变化时怎么样通知外界呢?通过回调函数?但是在算法可视化过程中要有能力暂停算法,然后更新dom,之后再继续运行算法(比如要支持用户手动点击“下一步”),所以我觉得纯粹使用callback似乎有些麻烦。刚开始想的是保存每一步中间结果,这样不仅可以让算法“下一步”,还能“上一步”观察结果,不过后来突然想到es6的generator,generator可以生成迭代器啊!而且还把控制权限交给了外界!有外界决定这个generator是否要运行下一步,感觉很适合。由于之前一直没有用过generator,想想还是趁此机会用下吧。
ES6 Generator
这里先把阮一峰老师的博客搬过来:Generator 函数的含义与用法
基本语法
- 使用function*(){}定义,返回的是一个迭代器,函数内部使用yield产出数据,每次迭代器调用next会获得下一个yield产出的数据
function* Generator(){ yield 1; let v = yield 2; yield v;}var iterator = Generator();console.log(iterator);//输出{},只有调用next后才有数据console.log(iterator.next());//{ value: 1, done: false }console.log(iterator.next());//{ value: 2, done: false }console.log(iterator.next());//{ value: undefined, done: false }, yield并不能把值传给v,yield*+generator可以console.log(iterator.next());//{ value: undefined, done: true }
- 使用yield*可以产出迭代器
function* Generator1(){ yield 1; let v = yield* Generator2();//这里使用的是yield*,会把Generator2的控制器接入,如果使用yield,则还需要调用next一次后才能得到迭代器 yield v;}function* Generator2(){ yield 2; return 3;//这里的return会传给Generator1中的v}var iterator = Generator1();console.log(iterator.next());//{ value: 1, done: false }console.log(iterator.next());//{ value: 1, done: false }console.log(iterator.next());//{ value: 3, done: false }console.log(iterator.next());//{ value: undefined, done: true }下面就以冒泡排序来说明下demo中的实现
Generator+冒泡排序
- 冒泡排序JS实现:
var data = [ {v:5,color:"blue"}, {v:6,color:"blue"}, {v:2,color:"blue"}, {v:0,color:"blue"}, {v:7,color:"blue"}, {v:3,color:"blue"}, {v:9,color:"blue"}];//这里定义一些svg柱状图的参数,包括高度和颜色两种属性function bubbleSort(data){ var length = data.length; for(var i=0;i<length;i++){ for(var j=0;j<length-1;j++){ if(data[j].v>data[j+1].v){ //交换 let t = data[j].v; data[j].v = data[j+1].v; data[j+1].v = t; } } }}bubbleSort(data);console.log(data.map(v=>v.v));//[ 0, 2, 3, 5, 6, 7, 9 ]
- generator+冒泡
function* bubbleSort(data){ var length = data.length; for(var i=0;i<length;i++){ for(var j=0;j<length-1;j++){ data[j].color = colorYellow;//把当前这步的数据标黄 yield data;//产出数据 if(data[j].v>data[j+1].v){ //交换 data[j].color = data[j+1].color = colorRed;//把要交换的数据标红 yield data;//产出数据 let t = data[j].v; data[j].v = data[j+1].v; data[j+1].v = t; yield data;//产出交换位置后的数据 } resetColor(data);//重置数据color颜色属性 } }}
这个generator版的冒泡排序可以有外界调用next方法进行下一步运算,而且会把data返回出来,由于data中的一些数据发生变化,这时候通过react的setstate方法可以实现dom的更新,调用示例如下:
/**********处理各种算法************/ var iter = bubbleSort(data); var go = function() { let currentData = iter.next(); if(!currentData.done){//更新state this.setState( (prevState) => {return {"data":currentData.value}}); setTimeout(go,500); } }.bind(this); setTimeout(go,0);
其他排序都是差不多的思路,只不过在快速排序和归并排序中用到了yield* 。
源码
demo的源码可以在本文开头提到的连接上复制下来,也可以在这里找到:https://git.oschina.net/liuyaqi/VisualCompute
要使用npm install和jspm install
demo演示地址:点击打开链接
- d3.js+react实现算法可视化:排序篇
- d3.js+react实现算法可视化:排序篇
- 可视化库 D3.js
- 基于D3.js的数据可视化前端实现方案
- 数据可视化与D3.js
- 一.d3.js 数据可视化
- 了解D3.js-数据可视化
- JS:如何实现可视化排序
- 【D3.js数据可视化系列教程】(二十)--交互图表之条形图排序
- 【D3.js数据可视化系列教程】(二十一)--交互图表之条形图排序切换
- D3.js 数据可视化学习笔记——Hello D3!
- 数据处理可视化技术D3.JS--JavaScript常识
- 使用D3.js进行数据可视化
- Python学习6-D3.js可视化库
- 数据可视化 D3.js实现力导向图之二(node带文字说明和提示)
- D3可视化
- 排序算法JS实现
- Js实现排序算法
- 75.[Docker]容器间的网络通信
- 腾讯云主机搭建Nginx的https出错
- Lua 字符串替换函数 string.gsub(s, pat, repl [, n])
- UILabel的文字顶部对齐
- 区块链技术现在及未来应用
- d3.js+react实现算法可视化:排序篇
- 函数的参数传递
- 解析xml
- Android 在引用Xstream 解析xml 编译报错问题解决办法
- AAR文件在Android开发中的集成
- 树的定义、分类及存储
- 【数据结构作业 链表 + BFS + DFS】
- iOS 拨打系统电话弹窗延迟问题
- Shell特殊变量:Shell $0, $#, $*, $@, $?, $$和命令行参数