Rxjs入门实践-各种排序算法排序过程的可视化展示

这几天学习下《算法》的排序章节,具体见对排序的总结,想着做点东西,能将各种排序算法的排序过程使用Rxjs通过可视化的方式展示出来,正好练系一下Rxjs的使用

本文不会太多介绍Rxjs的基本概念,重点介绍如何用响应式编程的思想来实现功能

在线演示地址

源码

效果图

需求

页面中包括一个随机生成300个数字的按钮和、一个选择不同排序算法的下拉列表和一个echart渲染的容器元素

点击按钮会随机生成300个随机数,同时页面渲染出300个数的柱状图,然后选择一种排序算法后,页面开始展示排序过程,在排序过程中如果我们切换成另一种排序算法,会停止当前算法的可视化展示,转而开始新的排序算法的可视化展示

思路

要展示出排序算法在排序过程中数组中数据的变化,我们要定期保存一下排序过程中当前数组的快照,然后通过echart展示当前数组的数据,重复这个过程直到排序完成,我们也就有了表示排序过程的一个动画展示

具体实现

在Rxjs中,一切皆是流,要实现这个功能,重要的是确定好数据流,以及数据流在未来一段时间内的变化过程

根据页面,可以清晰的确定几个数据流

按钮点击操作生成的数据流

const createNumber$ = Rx.Observable.fromEvent(query('.numberCreator'), 'click')

切换下拉列表生成的数据流

const select$ = Rx.Observable.fromEvent(query('.sortTypes'), 'change')

点击按钮生成随机数组并渲染echart图表很显然就用到map和do这两个operator

    createNumber$
.map(e => {
return numberCreator()
})
.do(nums => {
const option = getOption(nums)
echartInstance.setOption(option)
})

切换下拉列表时我们要得到当前选择的排序算法的一个标识

let currentType
select$
.map(e => e.target)
.map(x => x.options[x.selectedIndex].value)
.map(type => {
return {
type,
timer:1
}
})
.do(x => {
currentType = x.type
})

下面是重点

只点击按钮或者只切换下拉页面都不应该展示排序过程,只有当两个事件流都触发了,并且之后某一个再次触发的时候才会渲染排序过程的动画,所以我们需要combineLatest操作符,将两个数据流合并成一个

const combine$=Rx.Observable.combineLatest(
createNumber$,
select$
)

现在在combine$数据流中我们就有个随机数组和排序类型

[Array[300],'1']

然后就应该排序算法进行工作了,这里思考一下

  • [] 怎样来生成我们排序算法排序过程中数据的快照?
  • [] 生成的数据快照什么时候让echart来渲染?

对于第一点,我们需要将排序算法封装成一个自定义的operator,在排序过程中不断next() 数据快照,
到这里我们的数据流就变成能在未来一段时间内不断生成新Value的一个数据流


Rx.Observable.prototype.sort = function () {
const input = this
return Rx.Observable.create((observer) => {
input.subscribe((arr) => {
const nums = clone(arr[0])
const select = arr[1]
const sortMethod = sortTypes[select.type]
sortMethod(nums, function (arr) {
observer.next({
nums: JSON.parse(JSON.stringify(arr)),
select
})
}, error => {
observer.error(error)
})
}, ) })
} combine$.sort()

对于第二点,因为排序算法是非常快的,如果我们subscibe sort()操作符产生的新值就开始渲染echart,页面上是看不出动画效果的,所以,我们需要延迟echart渲染图表的过程,我们需要将sort()触发的值转变成一个异步的新事件流并打平到原数据流中

combine$
.sort()
.flatMap(obj => {
return Rx.Observable.of(obj).delay(100 * obj.select.timer++)
})

注意obj.select.timer++,对于sort()前后触发的两个值,为了展示出echart渲染的动画,我们要给它们渲染的时间依次递增

到这一步,我们的单次功能就能正常进行了,但如果在一个排序动画过程还没有结束,我们又点击了一个新的排序类型,则新旧两次的还在序列中没进行的渲染都会依次进行,干扰echart渲染的效果,所以在切换到新的类型时,我们要过滤序列中的值。

combine$
.sort()
.flatMap(obj => {
return Rx.Observable.of(obj).delay(100 * obj.select.timer++)
})
.filter(x => {
return x.select.type == currentType
})
.do(x => {
const option = getOption(x.nums)
echartInstance.setOption(option)
})
.subscribe(() => { }, null, () => {
console.log('complete')
})

整个数据流序列

   -createNumber$---------------------------------------------------------------------------------

   ---------------select$-------------------------------------------------------------------------
combineLatest()
---------------------------combine$------------------------------------------------------------
sort()
---------------------------v1 v2 v3 v4 .......v11 v22 v33----------
flatMap()
---------------------------delay1 delay2 delay3 delay4 ....delay11 delay22 delay33--------
filter(currentType==type)
---------------------------delay1 delay2 delay11 delay22 delay33--------------------------

Rxjs入门实践-各种排序算法排序过程的可视化展示的更多相关文章

  1. Python的函数式编程-传入函数、排序算法、函数作为返回值、匿名函数、偏函数、装饰器

    函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计的基本单元. ...

  2. javascript数据结构与算法--基本排序算法(冒泡、选择、排序)及效率比较

    javascript数据结构与算法--基本排序算法(冒泡.选择.排序)及效率比较 一.数组测试平台. javascript数据结构与算法--基本排序(封装基本数组的操作),封装常规数组操作的函数,比如 ...

  3. 易普优APS混流排序算法助力汽车整车厂的均衡生产

    一.汽车整车厂生产排序的难点 “ 冲压-焊接-涂装-总装”是汽车整车生产的四大工艺类型,它们存在上下游关联关系,每个车间都有自己的优化排序目标,汽车混流生产模式使得生产过程更加复杂,从而生产管控的难度 ...

  4. python 经典排序算法

    python 经典排序算法 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.常见的内部排序算 ...

  5. 基于Qt5的排序算法简单可视化

    之前写了几个排序算法,然后看到别人将排序算法的过程可视化出来,所以就想尝试一下,然后就用Qt简单写了个界面,用QImage和QPainter来画图显示,代码比较简单. 我的想法是画图的时候,图像的X轴 ...

  6. 11.经典O(n²)比较型排序算法

    关注公号「码哥字节」修炼技术内功心法,完整代码可跳转 GitHub:https://github.com/UniqueDong/algorithms.git 摘要:排序算法提多了,很多甚至连名字你都没 ...

  7. Python实现一些常用排序算法

    一些常用的排序 #系统内置排序算法#list.sort()#heapq模块 def sys_heap_sort(list): import heapq heap = [] for i in range ...

  8. C++进阶 STL(3) 第三天 函数对象适配器、常用遍历算法、常用排序算法、常用算数生成算法、常用集合算法、 distance_逆序遍历_修改容器元素

    01昨天课程回顾 02函数对象适配器 函数适配器是用来让一个函数对象表现出另外一种类型的函数对象的特征.因为,许多情况下,我们所持有的函数对象或普通函数的参数个数或是返回值类型并不是我们想要的,这时候 ...

  9. 【高级排序算法】2、归并排序法的实现-Merge Sort

    简单记录 - bobo老师的玩转算法系列–玩转算法 -高级排序算法 Merge Sort 归并排序 Java实现归并排序 SortTestHelper 排序测试辅助类 package algo; im ...

随机推荐

  1. 1)PHP,数据库操作类网址

    (1)脚本之家 http://www.jb51.net/article/94347.htm (2)一个博客 http://www.cnblogs.com/lvchenfeng/p/5003629.ht ...

  2. git基本操作-长期维护

    ###############    初识git    ############## """ git初识: 1,git是什么?git是一个帮助用户版本控制的软件, 2,g ...

  3. 用@font-face应用自定义字体

    @font-face格式 @font-face { font-family: <YourWebFontName>; src: <source> [<format>] ...

  4. Python练习五-函数

    1.简述普通参数.指定参数.默认参数.动态参数的区别1)普通参数中,有形参和实参,其中形参是定义函数时写的参数,实参是调用函数时传给函数的参数:2)默认参数是在定义函数时,参数设定一个默认值:3)指定 ...

  5. VLC查看日志的方法

    最近使用VLC去播放rtsp网络串流总是失败,显示要查看日志,查看的方法: 进入VLC的GUI,点击视图,添加界面,添加调试窗口: 添加调试窗口,会弹出界面: 上面会有报错的提示. 大佬如果有其他的办 ...

  6. Invert Binary Tree(easy)

    1.直接把递归把左右子树翻转即可 AC代码: /** * Definition for a binary tree node. * struct TreeNode { * int val; * Tre ...

  7. python中安装surprise中出现error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools":

    pip安装 安装之前要先进行numpy的安装 pip install numpy pip install surprise 安装出错: 安装surprise需要Microsoft visual c++ ...

  8. 次小生成树题(k) poj1679The Unique MST

    http://poj.org/problem?id=1679 #include<iostream> #include<vector> #include<cstdio> ...

  9. LeetCode No.82,83,84

    No.82 DeleteDuplicates 删除排序链表中的重复元素 II 题目 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字. 示例 输入: 1->2 ...

  10. Python||NameError: name 'reload' is not defined

    多半是运行如下代码时报错: import sysreload(sys)sys.setdefaultencoding("utf-8")123这段代码是为了解决Python中中文输出出 ...