processingjs——数据排序可视化

1、sort.html


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
		<title>ProcessingJS 排序动画演示</title>
		<style type="text/css">
body { overflow: hidden; }
.append-bottom label, .append-bottom input, .append-bottom span { margin-left: 40px; }
#panel { float: left; }
#code { float: left; width: 280px; margin: 0 5px 0 5px; padding: 10px 0 0 10px; background: #141414; color: #DAD085; overflow: auto; }
</style>
		<script type="text/javascript" src="./jqueyr-1.6.4.js"></script>
		<script type="text/javascript" src="./pjs.js"></script>
		<script type="text/javascript" src="sort.js"></script>
		<script type="text/javascript">
var task = null;
$(function() {
	$(window).resize(function() {
		Processing.getInstanceById("panel")
			.size($(window).width() - 320, $(window).height() - 145);
		$("#code").height($(window).height() - 155);
	});
	$("#panel").width($(window).width() - 320).height($(window).height() - 145);
	$("#code").height($(window).height() - 155)
	$("#restart").click(function() {
		task && task.stop();
		task = $.extend({
			sort: SortAlgorithm[$("#algorithm").val()]
		}, init($("#capacity").val()), controller($("#speed").val())).begin();
		$("#code").text(task.sort.toString());
	}).click();
});

function init(capacity) {
	var factor = 100 / capacity;
	var data = [];
	for(var i = 1; i <= capacity; i++)
		data.push(Math.round(i * factor * 100)/100);
	for(var i = data.length; i > 0; i--)
		data.swap(i-1, Math.round(Math.random() * i));
	var state = [];
	$.each(data, function() { state.push([this, false]); });
	return { data: data, state: state };
}

function controller(speed) {
	var interval = 2000 / speed;
	return {
		begin: function() {
			this.queue = [];
			this.compareCount = 0;
			this.swapCount = 0;
			this.insertCount = [];
			this.sort();
			var info = "比较"+this.compareCount+"次,交换"+this.swapCount+"次";
			if(this.insertCount.length > 0) {
				var count = 0;
				$.each(this.insertCount, function() { count += this; });
				info += ",插入"+this.insertCount.length+"次,平均位移为"+(count/this.insertCount.length).toFixed(2);
			}
			$("#info").text(info);
			this.next();
			return this;
		},
		stop: function() {
			this.queue = [];
			clearTimeout(this.timer);
		},
		next: function() {
			var self = this;
			this.timer = setTimeout(function() {
				self.show();
			}, interval);
		},
		show: function() {
			for(var i in this.state)
				this.state[i][1] = false;
			var task = this.queue.shift();
			if(task) {
				this.state[task[1]][1] = this.state[task[2]][1] = true;
				if(task[0] == "SWAP") {
					this.state.swap(task[1], task[2]);
				} else if(task[0] == "INSERT") {
					this.state.insertBefore(task[1], task[2]);
				} else if(task[0] == "HIGHLIGHT3") {
					this.state[task[3]][1] = true;
				}
				this.next();
			}
		},
		count: function() {
			return this.data.length;
		},
		gt: function(x, y, pivot) {
			this.queue.push(typeof(pivot) == "undefined" ? ["HIGHLIGHT2", x, y] : ["HIGHLIGHT3", x, y, pivot]);
			this.compareCount++;
			return this.data[x] > this.data[y];
		},
		lt: function(x, y, pivot) {
			this.queue.push(typeof(pivot) == "undefined" ? ["HIGHLIGHT2", x, y] : ["HIGHLIGHT3", x, y, pivot]);
			this.compareCount++;
			return this.data[x] < this.data[y];
		},
		swap: function(x, y) {
			this.queue.push(["SWAP", x, y]);
			this.swapCount++;
			this.data.swap(x, y);
		},
		insertBefore: function(from, to) {
			this.queue.push(["INSERT", from, to]);
			this.insertCount.push(this.data.insertBefore(from, to));
		}
	};
}
</script>
	</head>
	<body>
		<div class="box">ProcessingJS 排序动画演示</div>
		<div class="append-bottom">
			<label for="algorithm">算法:</label>
			<select id="algorithm">
				<option value="bubble" selected="selected">Bubble</option>
				<option value="shaker">Shaker</option>
				<option value="insertion">Insertion</option>
				<option value="selection">Selection</option>
				<option value="shell">Shell</option>
				<option value="heap">Heap</option>
				<option value="merge">Merge</option>
				<option value="quick">Quick</option>
			</select>
			<label for="capacity">数据量:</label>
			<select id="capacity">
				<option value="10">10</option>
				<option value="30" selected="selected">30</option>
				<option value="50">50</option>
				<option value="100">100</option>
				<option value="200">200</option>
			</select>
			<label for="speed">速度:</label>
			<select id="speed">
				<option value="5">5</option>
				<option value="30" selected="selected">30</option>
				<option value="50">50</option>
				<option value="100">100</option>
				<option value="200">200</option>
			</select>
			<input type="button" id="restart" value="重新开始" />
			<span id="info"></span>
		</div>
		<hr />
		<canvas id="panel" data-processing-sources="panel.pde"></canvas>
		<pre id="code"></pre>
	</body>
</html>

2、sort.js

var SortAlgorithm = {
bubble: function() {
  for(var i = this.count()-1; i >= 0; i--)
    for(var j = 0; j < i; j++)
      if(this.gt(j, j+1))
        this.swap(j, j+1);
},
shaker: function() {
  var left = 0, right = this.count()-1;
  while(left < right) {
    var lastRight = left;
    for(var i = left; i < right; i++) {
      if(this.gt(i, i+1, right)) {
        this.swap(i, i+1);
        lastRight = i;
      }
    }
    right = lastRight;
		
    var lastLeft = right;
    for(var i = right; i > left; i--) {
      if(this.gt(i-1, i, left)) {
        this.swap(i-1, i);
        lastLeft = i;
      }
    }
    left = lastLeft;
  }
},
insertion: function() {
  for(var i = 1; i < this.count(); i++) {
    for(var j = i; j > 0; j--) {
      if(this.gt(j-1, j))
        this.swap(j-1, j);
      else
        break;
    }
  }
},
selection: function() {
  for(var i = 0; i < this.count()-1; i++) {
    var min = i;
    for(var j = i+1; j < this.count(); j++)
      if(this.lt(j, min, i))
        min = j;
    this.swap(i, min);
  }
},
shell: function() {
  var gap = Math.floor(this.count()/2);
  while(gap > 1) {
    gap = Math.floor(gap/3)+1;
    for(var i = gap; i < this.count(); i++) {
      for(var j = i; j >= gap; j-=gap) {
        if(this.gt(j-gap, j))
          this.swap(j-gap, j);
        else
          break;
      }
    }
  }
},
heap: function() {
  for(var i = 0; i < this.count(); i++) {
    var current = i;
    while(current != 0) {
      var parent = Math.floor((current - 1) / 2);
      if(!this.gt(current, parent))
        break;
      this.swap(current, parent);
      current = parent;
    }
  }
  for(var i = this.count()-1; i > 0; i--) {
    this.swap(0, i);
    var current = 0;
    while(true) {
      var child = current * 2 + 1;
      if(child >= i) break;
      if(child+1 < i && this.lt(child, child+1)) child++;
      if(!this.lt(current, child)) break;
      this.swap(current, child);
      current = child;
    }
  }
},
merge: function() {
  (function(left, right) {
    if(left >= right)
      return;
    var mid = Math.floor((left + right) / 2);
    arguments.callee.call(this, left, mid);
    arguments.callee.call(this, mid+1, right);
    var i = left, j = mid+1;
    while(i < j && j <= right) {
      if(!this.lt(i, j))
        this.insertBefore(j++, i);
      i++;
    }
  }).call(this, 0, this.count()-1);
},
quick: function() {
  (function(left, right) {
    if(left >= right)
      return;
    this.swap(left, Math.floor((left + right) / 2));
    var pivot = left;
    for(var i = left+1; i <= right; i++)
      if(this.gt(left, i))
        this.swap(++pivot, i);
    this.swap(left, pivot);
    arguments.callee.call(this, left, pivot-1);
    arguments.callee.call(this, pivot+1, right);
  }).call(this, 0, this.count()-1);
}
};

Array.prototype.swap = function(i, j) {
  var tmp = this[i];
  this[i] = this[j];
  this[j] = tmp;
};
Array.prototype.insertBefore = function(from, to) {
  var tmp = this[from];
  if(from < to) {
    for(var i = from; i < to-1; i++)
      this[i] = this[i+1];
    this[to-1] = tmp;
    return to - from - 1;
  } else {
    for(var i = from; i > to; i--)
      this[i] = this[i-1];
    this[to] = tmp;
    return from - to;
  }
};

3、panle.pde:panle 

void setup() {
	size($(window).width() - 320, $(window).height() - 145);
	frameRate(30);
}

void draw() {
	if(!task)
		return;
	background(255);
	stroke(255);
	float cw = width / task.state.length;
	for(int i = 0; i < task.state.length; i++) {
		if(task.state[i][1])
			fill(174, 228, 150);
		else
			fill(117, 192, 238);
		float ch = map(task.state[i][0], 0, 100, 0, height);
		rect(i*cw, height-ch, cw, ch);
	}
}

其次,还需要引入jquery和processingjs库,之后将这些文件放到nginx后,访问即可。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赶路人儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值