canvas实现DBSCAN聚类算法可视化过程代码
代码语言:html
所属分类:其他
代码描述:canvas实现DBSCAN聚类算法可视化过程代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!doctype html> <html lang="en-us"> <head> <meta charset="utf-8"> </head> <body> <div class="center"> <article> <div class="social"> </div> <h1 class="title">DBSCAN</h1> <div class="content"><div> <p>A visualization of a <a href="http://en.wikipedia.org/wiki/DBSCAN">DBSCAN algorithm</a>.</p> <style> .post { max-width: none; width: 640px; padding: 0; } </style> <header> <nav id="menu"></nav> <div class="clear"></div> </header> <p><canvas id="canvas" ></canvas></p> <script> Math.TAU = Math.PI*2; function $P(x,y){ return new Point(x,y);} function Point(x,y){ this.x = x; this.y = y; } Point.prototype = { toString : function(){ return "<" + this.x.toFixed(2) + ";" + this.y.toFixed(2) + ">"; } }; function $R(left, top, right, bottom){ return new Rect(left, top, right, bottom); } function Rect(left, top, right, bottom){ this.left = left; this.top = top; this.right = right; this.bottom = bottom; } Rect.prototype = { get width(){ return Math.abs(this.right - this.left); }, get height(){ return Math.abs(this.bottom - this.top); }, get dx(){ return this.right - this.left; }, get dy(){ return this.bottom - this.top; }, get topLeft(){ return new Point(this.left, this.top); }, get bottomRight(){ return new Point(this.right, this.bottom); }, intersect : function(rect){ var left = this.left > other.left ? this.left : other.left, top = this.top > other.top ? this.top : other.top, right = this.right < other.right ? this.right : other.right, bottom = this.bottom < other.bottom ? this.bottom : other.bottom; return new Rect(left, top, right, bottom); } }; function sortRange(zero, from, to, delta){ if (from < to) { return {from:from, to:to, delta:Math.abs(delta)}; } else { return {from:to, to:from, delta:Math.abs(delta)}; } } </script> <script > function clone(obj){ if(typeof(obj) != "object") return obj; var result = {}; for(var i in obj) result[i] = clone(obj[i]); return result; } function foreach(obj, f){ if(obj instanceof Array){ for(var i = 0; i < obj.length; i += 1){ f(obj[i], i, obj); }; } else { for(var name in obj){ if(!obj.hasOwnProperty(name)) continue; f(obj[name], name, obj); }; } } </script> <script > function $(id){ return document.getElementById(id); } main = { canvas : $("canvas"), draw : null, nav : $("menu"), size : {x: 480, y:480}, updateTimer: 0, drawTimer: 0, history: [], tick : 0, updateRate: 1000, drawRate : 33, running : false, state : null, updates : function(state){}, render : function(draw, size, state){}, runRendering: function(){ this.drawTimer = window.setInterval($render, this.drawRate); }, stopRendering: function(){ window.clearInterval(this.drawTimer); }, run : function(){ this.stop(); this.running = true; this.updateTimer = window.setInterval($update, this.updateRate); }, stop : function(){ this.running = false; window.clearInterval(this.updateTimer); }, reset : function(){ this.stop(); this.tick = 0; this.history = []; this.state = {}; this.resetState(this.draw, this.size, this.state); this.render(this.draw, this.size, this.state); }, log : function(data){ this.history.unshift(data); }, update : function(){ this.tick += 1; this.updates(this.state); }, updateDisplay : function(){ this.render(this.draw, this.size, this.state); }, setSize : function(w,h){ this.size = {x:w, y:h}; this.canvas.width = this.size.x; this.canvas.height = this.size.y; }, mouse : $P(0,0) }; $update = function(){main.update()}; $run = function(){main.run()}; $stop = function(){main.stop()}; $reset = function(){main.reset()}; $render = function(){main.updateDisplay()}; main.draw = main.canvas.getContext("2d"); function button(caption, func){ var elem = document.createElement("button"); elem.innerHTML = caption; elem.addEventListener("click", func); main.nav.appendChild(elem); return elem; } function input(id, value){ var elem = document.createElement("input"); elem.id = id; elem.value = value; main.nav.appendChild(elem); return elem; } main.canvas.addEventListener("mousemove", function(e){ main.mouse.x = e.pageX - main.canvas.offsetLeft; main.mouse.y = e.pageY - main.canvas.offsetTop; }); </script> <script > inputData = { A : {x : 2, y : 4 }, B : {x : 7, y : 3 }, C : {x : 3, y : 5 }, D : {x : 5, y : 3 }, E : {x : 7, y : 4 }, F : {x : 6, y : 8 }, G : {x : 6, y : 5 }, H : {x : 8, y : 4 }, I : {x : 2, y : 5 }, J : {x : 3, y : 7 } }; </script> <script > function Grid(rect, range){ this._rect = rect; this._range = range; this.tick = $P(1.0,1.0); this.scale = $P(1.0,1.0); this.recalc(); } Grid.prototype = { get range(){ return this._range; }, set range(range){ this._range = range; this.recalc(); }, get rect(){ return this._rect; }, set rect(rect){ this._rect = rect; this.recalc(); }, recalc : function(){ this.scale.x = this.rect.dx / this.range.dx; this.scale.y = this.rect.dy / this.range.dy; }, render : function(draw){ var zero = this.toScreen($P(0.0,0.0)), one = this.toScreen(this.tick), dx = one.x - zero.x, dy = one.y - zero.y, topLeft = this.toScreen(this.range.topLeft), bottomRight = this.toScreen(this.range.bottomRight); draw.beginPath(); var r = sortRange(zero.x, topLeft.x, bottomRight.x, dx), gx = this.range.left; for(var x = r.from; x <= r.to; x += r.delta){ draw.moveTo(x, topLeft.y); draw.lineTo(x, bottomRight.y); draw.fillText(gx.toFixed(1), x+2, zero.y-2); gx += this.tick.x; } var r = sortRange(zero.y, topLeft.y, bottomRight.y, dy), gy = this.range.top; for(var y = r.from; y <= r.to; y += r.delta){ draw.moveTo(topLeft.x, y); draw.lineTo(bottomRight.x, y); draw.fillText(gy.toFixed(1), zero.x+2, y-2); gy -= this.tick.y; } draw.stroke(); }, toScreen : function(p, r){ r = r || new Point(0,0); r.x = (p.x - this._range.left) * this.scale.x + this._rect.left, r.y = (p.y - this._range.top) * this.scale.y + this._rect.top; return r; }, fromScreen : function(p, r){ r = r || new Point(0,0); r.x = (p.x - this._rect.left) / this.scale.x + this._range.left, r.y = (p.y - this._rect.top) / this.scale.y + this._range.top; return r; } }; </script> <script> function loaded(){ main.setSize(640, 640); button("Step", $update); button("Run", $run); button("Stop", $stop); button("Reset", $reset); input("eps", 2); input("minPts", 2); main.reset(); main.runRendering(); } var conf = { main : { background : "#222", foreground : "#ddd", }, data : { background : "#fff", foreground : "#222", radius : 15, }, algorithm : { marking : 18, } }; main.resetState = function(draw, size, state){ state.data = clone(inputData); state.n.........完整代码请登录后点击上方下载按钮下载查看
网友评论0