juijs-graph
Advanced tools
Comparing version 0.3.0-es6 to 0.4.0-es6
@@ -1,231 +0,200 @@ | ||
import jui from '../src/main.js' | ||
import JUI from '../src/main.js' | ||
jui.define("chart.brush.canvas.equalizercolumn", [ "util.base" ], function(_) { | ||
var CanvasEqualizerColumnBrush = function() { | ||
let zeroY, bar_width, is_reverse; | ||
JUI.define("chart.brush.canvas.activebubble", [ "util.canvas.bubble.mortal" ], function(MortalBubble) { | ||
class ActiveBubble { | ||
constructor(renderContext, contextWidth, contextHeight) { | ||
this.renderContext = renderContext; | ||
this.contextWidth = contextWidth; | ||
this.contextHeight = contextHeight; | ||
this.getTargetSize = function() { | ||
let width = this.axis.x.rangeBand(); | ||
if(this.brush.size > 0) { | ||
return this.brush.size; | ||
} else { | ||
let size = width - this.brush.outerPadding * 2; | ||
return (size < this.brush.minSize) ? this.brush.minSize : size; | ||
} | ||
this.gravity = 0.2; | ||
this.data = []; // MortalBubble | ||
} | ||
this.getBarElement = function(dataIndex, targetIndex) { | ||
let style = this.getBarStyle(), | ||
color = this.color(targetIndex), | ||
value = this.getData(dataIndex)[this.brush.target[targetIndex]]; | ||
return { | ||
fill : color, | ||
stroke : style.borderColor, | ||
"stroke-width" : style.borderWidth, | ||
"stroke-opacity" : style.borderOpacity, | ||
hidden: value == 0 | ||
}; | ||
} | ||
this.getBarStyle = function() { | ||
return { | ||
borderColor: this.chart.theme("barBorderColor"), | ||
borderWidth: this.chart.theme("barBorderWidth"), | ||
borderOpacity: this.chart.theme("barBorderOpacity"), | ||
borderRadius: this.chart.theme("barBorderRadius"), | ||
disableOpacity: this.chart.theme("barDisableBackgroundOpacity"), | ||
circleColor: this.chart.theme("barPointBorderColor") | ||
preCheck() { | ||
for (let i = 0; i < this.data.length; i++) { | ||
const bubble = this.data[i]; | ||
if(!bubble.active) { | ||
this.data[i] = null; | ||
this.data.splice(i, 1); | ||
} | ||
} | ||
} | ||
this.drawBefore = function() { | ||
zeroY = this.axis.y(0); | ||
bar_width = this.getTargetSize(); | ||
is_reverse = this.axis.get("y").reverse; | ||
return this.data.length > 0; | ||
} | ||
this.draw = function() { | ||
const targets = this.brush.target, | ||
padding = this.brush.innerPadding, | ||
band = this.axis.y.rangeBand(), | ||
unit = band / (this.brush.unit * padding), | ||
height = unit + padding, | ||
translateY = (is_reverse) ? 0 : -unit; | ||
draw() { | ||
if(!this.preCheck()) return; | ||
this.eachData(function(data, i) { | ||
let startX = this.offset("x", i) - bar_width / 2, | ||
startY = this.axis.y(0), | ||
y = startY, | ||
value = 0, | ||
stackList = []; | ||
let collisions = [], | ||
dups = []; | ||
for(let j = 0; j < targets.length; j++) { | ||
let yValue = data[targets[j]] + value, | ||
endY = this.axis.y(yValue), | ||
targetHeight = Math.abs(startY - endY), | ||
targetY = targetHeight; | ||
for (let i = 0; i < this.data.length; i++) { | ||
// force gravity | ||
const bubble = this.data[i]; | ||
const gDirection = [1, 0]; | ||
bubble.force([ | ||
gDirection[0] * bubble.mass * this.gravity, | ||
gDirection[1] * bubble.mass * this.gravity, | ||
]); | ||
while(targetY >= height) { | ||
let r = _.extend(this.getBarElement(i, j), { | ||
x : startX, | ||
y : y + translateY, | ||
width : bar_width, | ||
height : unit | ||
}); | ||
bubble.update(); | ||
} | ||
targetY -= height; | ||
y += (is_reverse) ? height : -height; | ||
for (let i = 0; i < this.data.length; i++) { | ||
// collapse testing | ||
for (let j = 0; j < this.data.length; j++) { | ||
if (i == j) continue; | ||
const me = this.data[i]; | ||
const other = this.data[j]; | ||
const dist = me.distance(other); | ||
const radiusSum = me.radius + other.radius; | ||
if (radiusSum - dist > 1) { | ||
collisions.push([me, other]); | ||
} | ||
} | ||
} | ||
this.canvas.beginPath(); | ||
this.canvas.fillStyle = r.fill; | ||
this.canvas.strokeStyle = r.stroke; | ||
this.canvas.strokeOpacity = r["stroke-opacity"]; | ||
this.canvas.lineWidth = r["stroke-width"]; | ||
this.canvas.rect(r.x, r.y, r.width, r.height); | ||
this.canvas.fill(); | ||
stackList.push(r); | ||
for (let i = 0; i < collisions.length - 1; i++) { | ||
const me = collisions[i]; | ||
for (let j = i + 1; j < collisions.length; j++) { | ||
const other = collisions[j]; | ||
if ( | ||
(me[0] == other[0] && me[1] == other[1]) || | ||
(me[1] == other[0] && me[0] == other[1]) | ||
) { | ||
dups.push(j); | ||
} | ||
startY = endY; | ||
value = yValue; | ||
} | ||
} | ||
if(stackList.length > 0) { | ||
this.chart.setCache(`equalizer_${i}`, stackList.length == 0 ? null : stackList[stackList.length - 1]); | ||
this.chart.setCache(`raycast_area_${i}`, { | ||
x1: stackList[0].x, | ||
x2: stackList[0].x + stackList[0].width, | ||
y2: this.axis.y(this.axis.y.min()), | ||
y1: stackList[stackList.length - 1].y | ||
}); | ||
for(let i = 0; i < collisions.length; i++) { | ||
if (dups.indexOf(i) != -1) continue; | ||
const collision = collisions[i]; | ||
const me = collision[0]; | ||
const other = collision[1]; | ||
const radiusSum = me.radius + other.radius; | ||
const dist = me.distance(other); | ||
let normal = [other.pos[0] - me.pos[0], other.pos[1] - me.pos[1]]; | ||
const len = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1]); | ||
normal = [normal[0] / len, normal[1] / len]; | ||
const size = radiusSum - dist; | ||
if (other.pos[0] == me.pos[0] && other.pos[1] == me.pos[1]) { | ||
normal = [0, -1]; | ||
} | ||
}); | ||
this.drawAnimation(); | ||
} | ||
me.pos = [ | ||
-size / 2 * normal[0] + me.pos[0], | ||
-size / 2 * normal[1] + me.pos[1], | ||
]; | ||
this.drawAnimation = function() { | ||
const MAX_DISTANCE = 8; // 애니메이션 움직인 최대 반경 (0px ~ 10px) | ||
const UP_SEC_PER_MOVE = 20; // 초당 20픽셀 이동 | ||
const DOWN_SEC_PER_MOVE = 30; // 초당 30픽셀 이동 | ||
const TOP_PADDING = -3; | ||
const TOTAL_PADDING = -8; | ||
other.pos = [ | ||
size / 2 * normal[0] + other.pos[0], | ||
size / 2 * normal[1] + other.pos[1], | ||
]; | ||
this.eachData(function (data, i) { | ||
const r = this.chart.getCache(`equalizer_${i}`); | ||
let total = 0; | ||
// const c = 0.01; | ||
const meForce = [ | ||
normal[0] * me.accel[0], | ||
normal[1] * me.accel[1], | ||
]; | ||
const otherForce = [ | ||
normal[0] * other.accel[0], | ||
normal[1] * other.accel[1], | ||
]; | ||
for(let j = 0; j < this.brush.target.length; j++) { | ||
total += data[this.brush.target[j]]; | ||
if (me.pos[0] < other.pos[0]) { | ||
me.veloc = [me.veloc[0] * 0.7, me.veloc[1] * 0.99]; | ||
me.force([-otherForce[0], -otherForce[1]]); | ||
} else { | ||
other.veloc = [other.veloc[0] * 0.7, other.veloc[1] * 0.99]; | ||
other.force([-meForce[0], -meForce[1]]); | ||
} | ||
} | ||
if(r != null) { | ||
const tpf = this.chart.getCache(`tpf`, 1); | ||
const status = this.chart.getCache(`equalizer_move_${i}`, { direction: -1, distance: 0 }); | ||
const speed = status.direction == -1 ? UP_SEC_PER_MOVE : DOWN_SEC_PER_MOVE; | ||
const now = (new Date()).getTime(); | ||
for (let i = 0; i < this.data.length; i++) { | ||
const me = this.data[i]; | ||
status.distance += status.direction * speed * tpf; | ||
if (me.pos[0] > this.contextWidth - 100) { | ||
me.pos[0] = this.contextWidth - 100; | ||
} | ||
if (me.pos[1] > this.contextHeight) { | ||
me.pos[1] = this.contextHeight; | ||
} else if (me.pos[1] < 0) { | ||
me.pos[1] = 0; | ||
} | ||
// 애니메이션-바 방향 벡터 설정 | ||
if(Math.abs(status.distance) >= MAX_DISTANCE) { | ||
status.direction = 1; | ||
} else if(status.distance >= 0) { | ||
status.direction = -1; | ||
} | ||
this.data[i].draw(this.renderContext, now); | ||
} | ||
} | ||
} | ||
// 애니메이션-바 최소/최대 위치 설정 | ||
if(status.distance < -MAX_DISTANCE) { | ||
status.distance = -MAX_DISTANCE; | ||
} else if(status.distance > 0) { | ||
status.distance = 0; | ||
} | ||
const CanvasActiveBubbleBrush = function() { | ||
this.drawBefore = function() { | ||
if(this.chart.getCache('active_bubble') == null) { | ||
this.chart.setCache('active_bubble', new ActiveBubble( | ||
this.canvas, this.axis.area('width'), this.axis.area('height'))) | ||
} | ||
} | ||
const ry = r.y + status.distance + TOP_PADDING; | ||
this.draw = function() { | ||
const activeBubble = this.chart.getCache('active_bubble'); | ||
this.canvas.strokeStyle = r.fill; | ||
this.canvas.lineWidth = r.height * 0.7; | ||
this.canvas.beginPath(); | ||
this.canvas.moveTo(r.x, ry); | ||
this.canvas.lineTo(r.x + r.width, ry); | ||
this.canvas.closePath(); | ||
this.canvas.stroke(); | ||
while(this.axis.data.length > 0) { | ||
let data = this.axis.data.shift(), | ||
birthtime = this.getValue(data, "birthtime", Date.now()), | ||
age = this.getValue(data, "age", 1000); | ||
this.canvas.fillStyle = this.chart.theme("barFontColor"); | ||
this.canvas.font = this.chart.theme("barFontSize") + "px"; | ||
this.canvas.textAlign = "center"; | ||
this.canvas.textBaseline = "middle"; | ||
this.canvas.fillText(total, r.x + r.width/2, ry + TOTAL_PADDING); | ||
this.canvas.fill(); | ||
activeBubble.data.push(new MortalBubble(birthtime, age)); | ||
this.axis.start++; | ||
} | ||
this.chart.setCache(`equalizer_move_${i}`, status); | ||
} | ||
}); | ||
activeBubble.draw(); | ||
} | ||
} | ||
CanvasEqualizerColumnBrush.setup = function() { | ||
CanvasActiveBubbleBrush.setup = function() { | ||
return { | ||
/** @cfg {Number} [size=0] Set a fixed size of the bar. */ | ||
size: 0, | ||
/** @cfg {Number} [minSize=0] Sets the minimum size as it is not possible to draw a bar when the value is 0. */ | ||
minSize: 0, | ||
/** @cfg {Number} [outerPadding=15] Determines the outer margin of a stack bar. */ | ||
outerPadding: 15, | ||
/** @cfg {Number} [innerPadding=1] Determines the inner margin of a bar. */ | ||
innerPadding: 1, | ||
/** @cfg {Number} [unit=5] Determines the reference value that represents the color.*/ | ||
unit: 1 | ||
}; | ||
} | ||
return CanvasEqualizerColumnBrush; | ||
return CanvasActiveBubbleBrush; | ||
}, "chart.brush.canvas.core"); | ||
const animation = jui.include("chart.animation"); | ||
const animation = JUI.include("chart.animation"); | ||
window.c = animation("#chart", { | ||
width: 500, | ||
height: 300, | ||
axis: [{ | ||
x : { | ||
domain : [ "1 year ago", "1 month ago", "Yesterday", "Today" ], | ||
line : true | ||
}, | ||
y : { | ||
type : "range", | ||
domain : [ 0, 30 ], | ||
// domain : function(d) { | ||
// return Math.max(d.normal, d.warning, d.fatal); | ||
// }, | ||
step : 5, | ||
line : false | ||
} | ||
}], | ||
brush : [{ | ||
type : "canvas.equalizercolumn", | ||
target : [ "normal", "warning", "fatal" ], | ||
unit : 10 | ||
}], | ||
interval : 100 | ||
width: 1000, | ||
height: 70, | ||
padding: 0, | ||
axis: { | ||
data: [ | ||
{ birthtime: Date.now(), age: 5000 }, | ||
{ birthtime: Date.now() + 1000, age: 3000 }, | ||
{ birthtime: Date.now(), age: 4000 }, | ||
{ birthtime: Date.now() + 2000, age: 2000 }, | ||
{ birthtime: Date.now() + 2000, age: 2000 }, | ||
{ birthtime: Date.now() + 2000, age: 2000 }, | ||
{ birthtime: Date.now() + 2000, age: 2000 }, | ||
{ birthtime: Date.now() + 2000, age: 2000 }, | ||
{ birthtime: Date.now() + 2000, age: 2000 }, | ||
{ birthtime: Date.now() + 2000, age: 2000 }, | ||
{ birthtime: Date.now() + 2000, age: 2000 }, | ||
{ birthtime: Date.now() + 2000, age: 2000 }, | ||
{ birthtime: Date.now() + 2000, age: 2000 }, | ||
{ birthtime: Date.now() + 2000, age: 2000 }, | ||
{ birthtime: Date.now() + 2000, age: 2000 }, | ||
{ birthtime: Date.now() + 2000, age: 2000 } | ||
] | ||
}, | ||
brush : { | ||
type: "canvas.activebubble", | ||
}, | ||
interval : 0 | ||
}); | ||
c.run(function(runningTime) { | ||
if(runningTime > 10000) { | ||
c.update([ | ||
{ normal : 7, warning : 7, fatal : 7 }, | ||
{ normal : 10, warning : 8, fatal : 5 }, | ||
{ normal : 6, warning : 4, fatal : 10 }, | ||
{ normal : 5, warning : 5, fatal : 7 } | ||
]); | ||
} else { | ||
c.update([ | ||
{ normal : 5, warning : 5, fatal : 5 }, | ||
{ normal : 10, warning : 8, fatal : 5 }, | ||
{ normal : 6, warning : 4, fatal : 10 }, | ||
{ normal : 5, warning : 5, fatal : 7 } | ||
]); | ||
} | ||
}); | ||
}); |
{ | ||
"name": "juijs-graph", | ||
"version": "0.3.0-es6", | ||
"version": "0.4.0-es6", | ||
"sideEffects": false, | ||
@@ -5,0 +5,0 @@ "description": "SVG-based JUI chart that can be used in the browser and Node.js. Support many types of charts. (Dashboard, Map, Topology, Full 3D)", |
@@ -33,3 +33,4 @@ import JUI from "juijs" | ||
this.run = function(callback) { | ||
let currentTime = Date.now(); | ||
const self = this; | ||
const currentTime = Date.now(); | ||
@@ -55,9 +56,5 @@ if(startTime == 0) { | ||
if(interval > 0) { | ||
const self = this; | ||
animateSeq = requestAnimationFrame(function() { | ||
self.run(callback); | ||
}); | ||
} | ||
animateSeq = requestAnimationFrame(function() { | ||
self.run(callback); | ||
}); | ||
} | ||
@@ -89,3 +86,4 @@ | ||
canvas: true, | ||
interval: 200 | ||
interval: 200, | ||
padding: 0 | ||
}, JUIBuilder.component().setup(), true); | ||
@@ -92,0 +90,0 @@ } |
@@ -438,2 +438,8 @@ import JUI from "juijs" | ||
// Axis 기본값 설정 | ||
if(_options.axis.length == 0) { | ||
_options.axis.push({ data: [] }); | ||
} | ||
// Axis 확장 설정 | ||
@@ -440,0 +446,0 @@ for(var i = 0; i < _options.axis.length; i++) { |
@@ -5,2 +5,6 @@ import jui from 'juijs' | ||
import TransformUtil from "./util/transform.js" | ||
import CanvasUtil from "./util/canvas/base.js" | ||
import CanvasKinetic from "./util/canvas/kinetic.js" | ||
import CanvasBubble from "./util/canvas/bubble.js" | ||
import CanvasMortalBubble from "./util/canvas/bubble.mortal.js" | ||
import SvgElementUtil from "./util/svg/element.js" | ||
@@ -60,4 +64,4 @@ import SvgTransformElementUtil from "./util/svg/element.transform.js" | ||
jui.use([ | ||
TimeUtil, TransformUtil, SvgElementUtil, SvgTransformElementUtil, SvgPathElementUtil, SvgPathRectElementUtil, SvgPathSymbolElementUtil, SvgPolyElementUtil, | ||
SvgBaseUtil, SvgBase3dUtil, SvgUtil, LinearScaleUtil, CircleScaleUtil, LogScaleUtil, OrdinalScaleUtil, TimeScaleUtil, ScaleUtil, | ||
TimeUtil, TransformUtil, CanvasUtil, CanvasKinetic, CanvasBubble, CanvasMortalBubble, SvgElementUtil, SvgTransformElementUtil, SvgPathElementUtil, SvgPathRectElementUtil, SvgPathSymbolElementUtil, | ||
SvgPolyElementUtil, SvgBaseUtil, SvgBase3dUtil, SvgUtil, LinearScaleUtil, CircleScaleUtil, LogScaleUtil, OrdinalScaleUtil, TimeScaleUtil, ScaleUtil, | ||
Vector, Draw, Axis, Map, Builder, Plane, Animation, CorePolygon, GridPolygon, LinePolygon, PointPolygon, CubePolygon, | ||
@@ -64,0 +68,0 @@ Draw2dGrid, Draw3dGrid, CoreGrid, BlockGrid, DateGrid, DateBlockGrid, FullBlockGrid, RadarGrid, RangeGrid, LogGrid, RuleGrid, PanelGrid, TableGrid, OverlapGrid, Grid3dGrid, |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
784512
71
10025