UNPKG

j6

Version:

Javascript scientific library (like R, NumPy, Matlab)

365 lines (327 loc) 9.52 kB
G = glab = { tgMap:{}, // (dimension+graph) Map canvas:{width:800,height:600}, } G.show = function(chartName, tg) { var g = tg.graph; if (tg.type === 'Canvas') { G.showCanvas(chartName, g); } else if (tg.type === '2D') { g.bindto=chartName; c3.generate(g); } else { var box=document.getElementById(chartName.replace('#','')); new vis.Graph3d(box, g.dataSet, g.options); } } // 2D chart by C3.js G.new2D=function() { return { // c3 graph data: { xs: {}, columns: [], type: "line", types : {} }, axis: { x: { label: 'X', tick: { fit: false, format:d3.format(".2f") } }, y: { label: 'Y', tick : { format: d3.format(".2f") } } }, bar: { width: { ratio: 0.9 } }, } } G.chart2D = function(chartName, f) { var g = G.new2D(); f(g); var tg = {type:'2D', graph:g}; G.tgMap[chartName] = tg; return G.show(chartName, tg); } // type : line, spline, step, area, area-spline, area-step, bar, scatter, pie, donut, gauge G.draw = function(g, name, x, y, type) { g.data.types[name] = type; g.data.xs[name] = name+"x"; g.data.columns.push([name+"x"].concat(x)); g.data.columns.push([name].concat(y)); } G.curve = function(g, name, f, from=-10, to=10, step=0.1) { var rg = j6.curve(f, from, to, step); console.log('curve:rg = ', rg) G.draw(g, name, rg.x, rg.y, 'line'); } G.hist = function(g, name, x, type, from, to, step=1) { var rh = j6.hist(x, from, to, step); G.draw(g, name, rh.xc, rh.bins, type || 'bar'); } G.ihist=function(g, name, x, type) { // console.log("x.min()=%d x.max()=%d", x.min(), x.max()); G.hist(g, name, x, type, x.min()-0.5, x.max()+0.5, 1); } G.plot =(g, name, x, y)=>G.draw(g, name, x, y, 'scatter'); G.pie =function(g, countMap) { g.data.type = 'pie'; for (var name in countMap) { var count = countMap[name]; g.data.columns.push([name, count]); } } G.timeSeries =function(g, columns) { g.data.x = 'x'; g.axis.x = { type:'timeseries', tick:{format:'%Y-%m-%d'}}; g.data.columns = columns; } // 3D chart by Vis.js G.new3D = function() { return { dataSet:new vis.DataSet(), options:{ width: '95%', height: '95%', style: 'surface', showPerspective: true, showGrid: true, showShadow: false, keepAspectRatio: true, verticalRatio: 0.5 } } } // style : surface, grid, bar, bar-color, bar-size, dot, dot-line, dot-color, dot-size, line G.chart3D = function(chartName, style, f) { var g = G.new3D(); // create some nice looking data with sin/cos var counter = 0; var steps = 50; // number of datapoints will be steps*steps var axisMax = 314; var axisStep = axisMax / steps; for (var x = 0; x < axisMax; x+=axisStep) { for (var y = 0; y < axisMax; y+=axisStep) { var value = f(x,y); g.dataSet.add({id:counter++,x:x,y:y,z:value,style:value}); } } g.options.style=style; G.tgMap[chartName] = {type:'3D',graph:g}; var box=document.getElementById(chartName.replace('#','')); new vis.Graph3d(box, g.dataSet, g.options); } /* G.cloneCanvas=function(oldCanvas) { assert(typeof oldCanvas !== 'undefined'); var newCanvas = document.createElement('canvas'); var context = newCanvas.getContext('2d'); newCanvas.width = oldCanvas.width; newCanvas.height = oldCanvas.height; context.drawImage(oldCanvas, 0, 0); // 這行OK, drawImage 的第一個參數可以是 canvas, 不一定要是 image。 return newCanvas; } */ G.loadImage = function(url, callback) { var image = new Image(); image.addEventListener("load", function() { callback(image); }, false); image.src = url; } function assert(condition, message) { if (!condition) { message = message || "Assertion failed"; if (typeof Error !== "undefined") { throw new Error(message); } throw message; // Fallback } } G.cloneCanvas = function(width, height, oldCanvas) { var newCanvas = document.createElement('canvas'); var context = newCanvas.getContext('2d'); newCanvas.width = width; newCanvas.height = height; context.fillStyle = "black"; context.fillRect(0,0,newCanvas.width, newCanvas.height); context.drawImage(oldCanvas, 0, 0); // 這行OK, drawImage return newCanvas; } G.showCanvas = function(chartName, g) { var box=document.getElementById(chartName.replace('#','')); var rect = box.getBoundingClientRect(); var canvas = G.cloneCanvas(rect.width, rect.height, g.canvas); box.innerHTML = ''; box.appendChild(canvas); } G.getImageData = function(canvas, x, y, width, height) { x=x||0; y=y||0; width=width||canvas.width; height=height||canvas.height; return canvas.getContext('2d').getImageData(x,y,width,height); } G.gray=function(idata) { var d = idata.data; for (var i=0; i<d.length; i+=4) { var r = d[i]; var g = d[i+1]; var b = d[i+2]; // CIE luminance for the RGB var v = 0.2126*r + 0.7152*g + 0.0722*b; d[i] = d[i+1] = d[i+2] = v; } } G.bright = function(idata, adjustment) { var d = idata.data; for (var i=0; i<d.length; i+=4) { d[i] += adjustment; d[i+1] += adjustment; d[i+2] += adjustment; } } G.threshold = function(idata, threshold) { var d = idata.data; for (var i=0; i<d.length; i+=4) { var r = d[i]; var g = d[i+1]; var b = d[i+2]; var v = (0.2126*r + 0.7152*g + 0.0722*b >= threshold) ? 255 : 0; d[i] = d[i+1] = d[i+2] = v } } var tmpCanvas = document.createElement('canvas'); var tmpCtx = tmpCanvas.getContext('2d'); G.createImageData = function(w,h) { return tmpCtx.createImageData(w,h); } G.convolute = function(idata, weights, opaque) { var side = Math.round(Math.sqrt(weights.length)); var halfSide = Math.floor(side/2); var src = idata.data; var sw = idata.width; var sh = idata.height; // pad output by the convolution matrix var w = sw; var h = sh; var output = G.createImageData(w, h); var dst = output.data; // go through the destination image pixels var alphaFac = opaque ? 1 : 0; for (var y=0; y<h; y++) { for (var x=0; x<w; x++) { var sy = y; var sx = x; var dstOff = (y*w+x)*4; // calculate the weighed sum of the source image pixels that // fall under the convolution matrix var r=0, g=0, b=0, a=0; for (var cy=0; cy<side; cy++) { for (var cx=0; cx<side; cx++) { var scy = sy + cy - halfSide; var scx = sx + cx - halfSide; if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { var srcOff = (scy*sw+scx)*4; var wt = weights[cy*side+cx]; r += src[srcOff] * wt; g += src[srcOff+1] * wt; b += src[srcOff+2] * wt; a += src[srcOff+3] * wt; } } } dst[dstOff] = r; dst[dstOff+1] = g; dst[dstOff+2] = b; dst[dstOff+3] = a + alphaFac*(255-a); } } return output; } if (!window.Float32Array) Float32Array = Array; G.convoluteFloat32 = function(pixels, weights, opaque) { var side = Math.round(Math.sqrt(weights.length)); var halfSide = Math.floor(side/2); var src = pixels.data; var sw = pixels.width; var sh = pixels.height; var w = sw; var h = sh; var output = { width: w, height: h, data: new Float32Array(w*h*4) }; var dst = output.data; var alphaFac = opaque ? 1 : 0; for (var y=0; y<h; y++) { for (var x=0; x<w; x++) { var sy = y; var sx = x; var dstOff = (y*w+x)*4; var r=0, g=0, b=0, a=0; for (var cy=0; cy<side; cy++) { for (var cx=0; cx<side; cx++) { var scy = Math.min(sh-1, Math.max(0, sy + cy - halfSide)); var scx = Math.min(sw-1, Math.max(0, sx + cx - halfSide)); var srcOff = (scy*sw+scx)*4; var wt = weights[cy*side+cx]; r += src[srcOff] * wt; g += src[srcOff+1] * wt; b += src[srcOff+2] * wt; a += src[srcOff+3] * wt; } } dst[dstOff] = r; dst[dstOff+1] = g; dst[dstOff+2] = b; dst[dstOff+3] = a + alphaFac*(255-a); } } return output; } G.sharpen=function(idata) { var weights = [ 0, -1, 0, -1, 5, -1, 0, -1, 0 ]; return G.convolute(idata, weights); } G.blurC = function(idata) { var weights = [ 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9 ]; return G.convolute(idata, weights); } G.sobel = function(px) { G.gray(px); var vertical = G.convoluteFloat32(px, [-1,-2,-1, 0, 0, 0, 1, 2, 1]); var horizontal = G.convoluteFloat32(px, [-1,0,1, -2,0,2, -1,0,1]); var id = G.createImageData(vertical.width, vertical.height); for (var i=0; i<id.data.length; i+=4) { var v = Math.abs(vertical.data[i]); id.data[i] = v; var h = Math.abs(horizontal.data[i]); id.data[i+1] = h id.data[i+2] = (v+h)/4; id.data[i+3] = 255; } return id; } // 2D canvas by HTML5 G.newCanvas = function() { var canvas = document.createElement('canvas'); canvas.width = G.canvas.width; canvas.height=G.canvas.height; var g = { canvas:canvas }; return g; } G.drawCanvas = function(chartName, f) { var g = G.newCanvas(); f(g.canvas.getContext('2d'), g.canvas); var tg = {type:'Canvas', graph:g}; G.tgMap[chartName] = tg; return G.show(chartName, tg); }