D3.js可视化冒泡排序(递归)

一、初始的柱状图的上升效果

  1. D3中可用于实现图形过渡的方法有四种:

1.transition()

该 API 的功能为启动过渡效果。其前后是图形变化前后的状态,可用于形状,位置,颜色的变化。

2.duration()

该 API 的功能为指定过渡的持续时间,单位为毫秒。例如duration(1000),即1秒。

3.ease()

该API可以指定过渡的变化方式,常用的如下:

①linear:普通的线性变化;

②circle:慢慢地到达变换的最终状态;

③elastic:带有弹跳的到达最终状态;

④bounce:在最终状态处弹跳几次;

4.delay()

用于指定延迟的时间,表示一定时间后才开始转变,单位为毫秒。

  1. 开始的动画效果代码如下:使用.transition(),前后y的位置由svgHeight -到 svgHeight - scale(d),使用了delay(),使其按照x位置的顺序延迟矩形的动态变化。
 .attr("y",function(d){  
            return svgHeight;
          })
          .attr("height", function(d){
           return 0;
          })
           //产生上升效果
          .transition()
          //顺序上升
          .delay(function(d,i){
            return i * 200;
          })
          //上升速度调节
          .duration(500)
          //上升到指定高度
          .attr('y', (d) => svgHeight - scale(d))
  1. 效果如下:

二、冒泡排序

  1. 递归实现冒泡排序的方法为:

      function bullsort(arr,size){
        if(size<2){return;}    //递归结束条件
          for(var i=0;i<size;i++){
            if(arr[i-1]>arr[i]){  //比较大小,交换
              var temp=arr[i];
              arr[i]=arr[i-1];
              arr[i-1]=temp;
            }
          }
        bullsort(arr,size-1);   //递归调用
      }
  1. 因为需要有动画效果和时序的问题,加入时间控制修改为:
   function bullsort(arr,size){
        if(size<2){d3.timeout(()=>complete(1),200);return;}//递归结束条件,排序结束
        var i=0; 
        const timer = d3.interval(() => 
        {  
          d3.timeout(()=>complete(size),200);//将已经排好的矩形变为橘色
          if  (i<size-1)
          {  
            i=i+1;
            compare(i-1, i);   //交换动画
          }
          if(i>=size-1)
          {  
             timer.stop();
             bullsort(arr,size-1); //递归调用原函数
          }
      },1000);

使用d3.interval(function ,time)循环定时器,会在参数二指定的时间到达时持续运行。体现为影响冒泡是两两比较交换后,进行下一个比较之间暂停的时间。

调用时:使用bullsort(data,data.length);

每递归一遍,则排好一个数,在控制台打印信息如下所示:已经排好最大的数,可以在控制台看到数组变化的情况。

三、排序的动画

compare函数的实现:

compare函数传进去两个参数key1,key2。通过选择id的方法,选择比较的数的矩形,例如:

 svg
      .select(`#rect${key1}`)
      .transition()
      .duration(100)
      .style('fill', 'green');

将两两比较的矩形从初始的skyblue的颜色变为green。

比较数值的大小,若前面的数大于后面的数,则前一个矩形右移,后一个矩形左移:

 if (data[key1] > data[key2]) {
            // 交换值
            [data[key1], data[key2]] = [data[key2], data[key1]];
            move_left(key2);
            move_right(key1);
            min = key2;
          }

记录小值min,小值恢复初始的颜色skyblue:

 svg.select(`#rect${min}`).style('fill', 'skyblue');

矩形左移或者右移时,改变的是x的位置和它对应的id,需要加入.transition()产生动画效果。

对于左移的矩形,改变如下(key+1):

  .transition()
  .duration(600)
  .attr('x', (key + 1) * (rectWidth + rectGap))
  .attr('id', `rect${key + 1}`);

对于右移的矩形,改变如下(key-1):

  .transition()
  .duration(600)
  .attr('x', (key - 1) * (rectWidth + rectGap))
  .attr('id', `rect${key -1 }`);

动画效果如下所示:65>34,已经比较出结果,65的矩形将要往后移,34的矩形将要往前移。34的矩形正由绿色转为蓝色。

 主要函数调用为:先对画布初始化,产生矩形效果等。再间隔一定时间后进行冒泡排序。

        init();                                  
        d3.timeout(()=>bullsort(data,data.length),2500);

四、排一遍将排好的矩形变为橘色。

编写compete函数,传入id,改变其颜色:

  svg.select(`#rect${key}`).style('fill', 'orange');

因为需要在每一遍结束后将排好的矩形标记,所以在比较交换之前加入d3.timeout(()=>complete(size),200);,将上一个排好的矩形改变其颜色,并产生视觉上的时序效果。

排序结束后效果如下:

如有完整代码需求,私信发邮箱号哈

猜你喜欢

转载自blog.csdn.net/cangzhexingxing/article/details/124810445