UNPKG

juijs-chart

Version:

SVG-based JUI chart that can be used in the browser and Node.js. Support many types of charts. (Dashboard, Map, Topology, Full 3D)

153 lines (131 loc) 5.77 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../../dist/jui-chart.js"></script> <script> graph.redefine("chart.brush.canvas.activecircle", ["util.canvas.base", "util.color" ], function(CanvasUtil, ColorUtil) { function hexToRgba(color, opacity) { const rgb = ColorUtil.rgb(color); return `rgba(${rgb.r},${rgb.g},${rgb.b},${opacity})`; } const Circle = function(color) { this.radius = 1; // 반지름 this.position = [ 0, 0 ]; // 위치 this.velocity = [ 0, 0 ]; // 속도 this.acceleration = [ 0, 0 ]; // 가속도 this.mass = 10; // 질량 this.friction = 0.1; // 마찰 this.runtime = 0; // 운동시간 this.move = function(scale, fps, tpf) { if(tpf == 1) return; const pre_position = [ this.position[0], this.position[1] ]; // 운동시간 누적 this.runtime += 1 * tpf; // 가속도 적용 if(this.acceleration[0] != 0) this.position[0] = scale.x(this.acceleration[0] * Math.pow(this.runtime, 2)); if(this.acceleration[1] != 0) this.position[1] = scale.y(this.acceleration[1] * Math.pow(this.runtime, 2)); // 평균속도 적용 // const distX = this.velocity[0] * tpf; // const distY = this.velocity[1] * tpf; // this.position[0] += (distX == 0) ? 0 : scale.x(distX); // this.position[1] += (distY == 0) ? 0 : scale.y(distY); console.log(`런타임: ${this.runtime}, 프레임 사이의 평균 속도: ${(this.position[0]-pre_position[0]) / tpf}M/s`); } this.stop = function() { this.velocity = [ 0, 0 ]; this.acceleration = [ 0, 0 ]; } this.draw = function(context) { const util = new CanvasUtil(context); context.shadowColor = hexToRgba(color, 0.3); context.shadowBlur = 10; context.shadowOffsetX = 0; context.shadowOffsetY = 10; context.globalAlpha = 1.0; util.drawCircle(this.position[0], this.position[1], this.radius, color); } } const CanvasActiveCircleBrush = function() { this.draw = function() { const fps = this.chart.getCache("fps", 1); const tpf = this.chart.getCache("tpf", 1); const circles = this.chart.getCache("active_circle", []); const maxX = this.axis.x(this.axis.x.max()); if(circles.length == 0) { this.eachData(function (data, i) { const circle = new Circle(this.color(i)); circle.radius = data.radius || this.brush.radius; circle.position = [ this.axis.x(data.x), this.axis.y(data.y) ]; circle.velocity = [ data.vx || 0, data.vy || 0 ]; circle.acceleration = [ data.ax || 0, data.ay || 0 ]; circles.push(circle); }); } for(let i = 0; i < circles.length; i++) { const circle = circles[i]; // 차트 범위를 벗어났을 때에 대한 처리 if(circle.position[0] > maxX) { circle.stop(); } else { circle.move(this.axis, fps, tpf); } circle.draw(this.canvas); } this.chart.setCache("active_circle", circles); } } CanvasActiveCircleBrush.setup = function() { return { radius: 20 } } return CanvasActiveCircleBrush; }, "chart.brush.canvas.core"); graph.ready([ "chart.animation" ], function(animation) { var c = animation("#chart", { width: 250, height: 1000, padding: { left: 70, right: 30, top: 30, bottom: 30 }, axis: [{ x : { type : "range", domain : [ 0, 100 ], step : 2, line : false }, y : { type : "range", domain : [ 0, 1000 ], step : 10, line : false, format : function(d) { return d + "M"; } }, data: [ // { x: 50, y: 900, vx: 0, vy: 100 } { x: 50, y: 900, ax: 0, ay: -9.8 } ] }], brush: [{ type: "canvas.activecircle" }] }); c.run(); }); </script> </head> <body> <div id="chart"></div> </body> </html>