Profiles Pictures Plotted on Trading Chart
This commit is contained in:
1 parent
8f20589147
commit
d39e76d897
7 files changed
+61
-855
No files matched your search
Binary file not shown.
@@ -26,8 +26,6 @@ function newBall() {
|
||||
fillStyle: '',
|
||||
|
||||
labelStrokeStyle: '',
|
||||
labelFirstText: '',
|
||||
labelSecondText: '',
|
||||
|
||||
radomizeCurrentPosition: radomizeCurrentPosition,
|
||||
radomizeCurrentSpeed: radomizeCurrentSpeed,
|
||||
@@ -122,17 +120,6 @@ function newBall() {
|
||||
|
||||
function drawBallBackgrond() {
|
||||
|
||||
if (thisObject.input.visible === false) { return; }
|
||||
if (thisObject.input.visible === true && thisObject.physicsEnabled === false) {
|
||||
|
||||
/* The first time that the ball becomes visible, we need to do thisObject. */
|
||||
|
||||
radomizeCurrentPosition(thisObject.input.position);
|
||||
radomizeCurrentSpeed();
|
||||
|
||||
thisObject.physicsEnabled = true;
|
||||
}
|
||||
|
||||
if (thisObject.currentRadius > 1) {
|
||||
|
||||
/* Target Line */
|
||||
@@ -165,8 +152,6 @@ function newBall() {
|
||||
|
||||
function drawBallForeground() {
|
||||
|
||||
if (thisObject.input.visible === false) { return; }
|
||||
|
||||
if (thisObject.currentRadius > 5) {
|
||||
|
||||
/* Contourn */
|
||||
@@ -206,10 +191,11 @@ function newBall() {
|
||||
|
||||
/* Image */
|
||||
|
||||
let imageSize = 50;
|
||||
|
||||
if (thisObject.input.imageId !== undefined) {
|
||||
|
||||
let image = document.getElementById(thisObject.input.imageId);
|
||||
let imageSize = 50;
|
||||
|
||||
if (image !== null) {
|
||||
|
||||
@@ -218,50 +204,30 @@ function newBall() {
|
||||
}
|
||||
}
|
||||
|
||||
/* Label First Text */
|
||||
/* Label Text */
|
||||
|
||||
if (thisObject.currentRadius > 6) {
|
||||
|
||||
browserCanvasContext.strokeStyle = thisObject.labelStrokeStyle;
|
||||
|
||||
var xOffset = 0;
|
||||
let labelPoint;
|
||||
let fontSize = 10;
|
||||
|
||||
if (thisObject.labelFirstText >= 10) {
|
||||
xOffset = thisObject.currentRadius / 10;
|
||||
}
|
||||
browserCanvasContext.font = fontSize + 'px Courier New';
|
||||
|
||||
browserCanvasContext.font = (thisObject.currentRadius / 4).toFixed(0) + 'px verdana';
|
||||
let label = thisObject.input.label;
|
||||
|
||||
try {
|
||||
browserCanvasContext.fillText(thisObject.labelFirstText.toFixed(0), thisObject.currentPosition.x - 2 - xOffset, thisObject.currentPosition.y + 2);
|
||||
} catch (err) {
|
||||
browserCanvasContext.fillText(thisObject.labelFirstText, thisObject.currentPosition.x - 2 - xOffset, thisObject.currentPosition.y + 2);
|
||||
}
|
||||
labelPoint = {
|
||||
x: thisObject.currentPosition.x - label.length / 2 * fontSize * 0.60,
|
||||
y: thisObject.currentPosition.y + imageSize / 2 + fontSize * 0.60 + 5
|
||||
};
|
||||
|
||||
}
|
||||
browserCanvasContext.font = fontSize + 'px Courier New';
|
||||
browserCanvasContext.fillStyle = thisObject.labelStrokeStyle;
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
|
||||
|
||||
/* Label Second Text */
|
||||
|
||||
if (thisObject.currentRadius > 10) {
|
||||
|
||||
browserCanvasContext.strokeStyle = thisObject.labelStrokeStyle;
|
||||
|
||||
var xOffset = 0;
|
||||
|
||||
|
||||
xOffset = thisObject.currentRadius / 2;
|
||||
|
||||
|
||||
browserCanvasContext.font = (thisObject.currentRadius / 6).toFixed(0) + 'px verdana';
|
||||
|
||||
try {
|
||||
browserCanvasContext.fillText(thisObject.labelSecondText.toFixed(8), thisObject.currentPosition.x - xOffset, thisObject.currentPosition.y + xOffset);
|
||||
} catch (err) {
|
||||
browserCanvasContext.fillText(thisObject.labelSecondText, thisObject.currentPosition.x - xOffset, thisObject.currentPosition.y + xOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -277,7 +277,7 @@ function newCanvas() {
|
||||
|
||||
if (ballDragStarted) {
|
||||
|
||||
let ball = balls[ballBeingDragged];
|
||||
let ball = thisObject.floatingSpace.balls[ballBeingDragged];
|
||||
|
||||
ball.currentPosition.x = dragVector.upX;
|
||||
ball.currentPosition.y = dragVector.upY;
|
||||
|
||||
+45
-31
@@ -6,6 +6,7 @@ This space has its own physics which helps with the animation of these objects a
|
||||
function newFloatingSpace() {
|
||||
|
||||
let thisObject = {
|
||||
balls: undefined, // This is the array of balls being displayed
|
||||
createNewBall: createNewBall,
|
||||
physicsLoop: physicsLoop,
|
||||
isInside: isInside,
|
||||
@@ -13,25 +14,23 @@ function newFloatingSpace() {
|
||||
initialize: initialize
|
||||
};
|
||||
|
||||
let balls; // This is the array of balls being displayed
|
||||
let createdBalls = [];
|
||||
|
||||
return thisObject;
|
||||
|
||||
function initialize() {
|
||||
|
||||
balls = []; // We initialize this in order to start the calculations in a clean way.
|
||||
thisObject.balls = []; // We initialize this in order to start the calculations in a clean way.
|
||||
|
||||
}
|
||||
|
||||
function physicsLoop() {
|
||||
|
||||
/* This function makes all the calculations to apply phisycs on all objects in this space. */
|
||||
/* This function makes all the calculations to apply phisycs on all balls in this space. */
|
||||
|
||||
for (let i = 0; i < balls.length; i++) {
|
||||
for (let i = 0; i < thisObject.balls.length; i++) {
|
||||
|
||||
let ball = balls[i];
|
||||
|
||||
if (ball.physicsEnabled === false) { continue;}
|
||||
let ball = thisObject.balls[i];
|
||||
|
||||
/* Change position based on speed */
|
||||
|
||||
@@ -67,13 +66,11 @@ function newFloatingSpace() {
|
||||
|
||||
/* Collision Control */
|
||||
|
||||
for (let k = i + 1; k < balls.length; k++) {
|
||||
for (let k = i + 1; k < thisObject.balls.length; k++) {
|
||||
|
||||
if (colliding(balls[i], balls[k])) {
|
||||
if (colliding(thisObject.balls[i], thisObject.balls[k])) {
|
||||
|
||||
if (balls[k].physicsEnabled === false) { continue; }
|
||||
|
||||
resolveCollision(balls[k], balls[i]);
|
||||
resolveCollision(thisObject.balls[k], thisObject.balls[i]);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -86,17 +83,37 @@ function newFloatingSpace() {
|
||||
|
||||
}
|
||||
|
||||
/* Finally we draw all the balls. */
|
||||
/* We draw all the thisObject.balls. */
|
||||
|
||||
for (let i = 0; i < balls.length; i++) {
|
||||
let ball = balls[i];
|
||||
for (let i = 0; i < thisObject.balls.length; i++) {
|
||||
let ball = thisObject.balls[i];
|
||||
ball.drawBackground();
|
||||
}
|
||||
|
||||
for (let i = 0; i < balls.length; i++) {
|
||||
let ball = balls[balls.length - i - 1];
|
||||
for (let i = 0; i < thisObject.balls.length; i++) {
|
||||
let ball = thisObject.balls[thisObject.balls.length - i - 1];
|
||||
ball.drawForeground();
|
||||
}
|
||||
|
||||
/* Finally we check if any of the created Balls where enabled to run under the Physics Engine. */
|
||||
|
||||
for (let i = 0; i < createdBalls.length; i++) {
|
||||
|
||||
let ball = createdBalls[i];
|
||||
|
||||
if (ball.input.visible === true) {
|
||||
|
||||
/* The first time that the ball becomes visible, we need to do this. */
|
||||
|
||||
ball.radomizeCurrentPosition(ball.input.position);
|
||||
ball.radomizeCurrentSpeed();
|
||||
|
||||
thisObject.balls.push(ball);
|
||||
createdBalls.splice(i, 1); // Delete item from array.
|
||||
return; // Only one at the time.
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createNewBall(pInput, pContainer) {
|
||||
@@ -112,17 +129,14 @@ function newFloatingSpace() {
|
||||
ball.friction = .995;
|
||||
|
||||
ball.initializeMass(15);
|
||||
ball.initializeRadius(3);
|
||||
ball.initializeRadius(30);
|
||||
|
||||
ball.fillStyle = 'rgba(255, 155, 155, 0.5)';
|
||||
ball.labelStrokeStyle = 'rgba(255, 0, 255, 1)';
|
||||
ball.fillStyle = 'rgba(255, 255, 255, 0.5)';
|
||||
ball.labelStrokeStyle = 'rgba(60, 60, 60, 0.50)';
|
||||
|
||||
ball.labelFirstText = pInput.name;
|
||||
ball.labelSecondText = "Soy una bola :-)";
|
||||
createdBalls.push(ball);
|
||||
|
||||
balls.push(ball);
|
||||
|
||||
ball.index = balls.length;
|
||||
ball.index = thisObject.balls.length;
|
||||
|
||||
return ball;
|
||||
}
|
||||
@@ -186,13 +200,13 @@ function newFloatingSpace() {
|
||||
|
||||
const coulomb = 2;
|
||||
|
||||
var ball1 = balls[currentBall];
|
||||
var ball1 = thisObject.balls[currentBall];
|
||||
|
||||
for (var i = 0; i < balls.length; i++) { // The force to be applied is considering all other balls...
|
||||
for (var i = 0; i < thisObject.balls.length; i++) { // The force to be applied is considering all other balls...
|
||||
|
||||
if (i !== currentBall) { // ... except for the current one.
|
||||
|
||||
var ball2 = balls[i]; // So, for each ball...
|
||||
var ball2 = thisObject.balls[i]; // So, for each ball...
|
||||
|
||||
var d = Math.sqrt(Math.pow(ball2.currentPosition.x - ball1.currentPosition.x, 2) + Math.pow(ball2.currentPosition.y - ball1.currentPosition.y, 2)); // ... we calculate the distance ...
|
||||
|
||||
@@ -267,8 +281,8 @@ function newFloatingSpace() {
|
||||
|
||||
/* This function detects weather the point x,y is inside any of the balls. */
|
||||
|
||||
for (var i = 0; i < balls.length; i++) {
|
||||
var ball = balls[i];
|
||||
for (var i = 0; i < thisObject.balls.length; i++) {
|
||||
var ball = thisObject.balls[i];
|
||||
var distance = Math.sqrt(Math.pow(ball.currentPosition.x - x, 2) + Math.pow(ball.currentPosition.y - y, 2));
|
||||
|
||||
if (distance < ball.currentRadius) {
|
||||
@@ -284,7 +298,7 @@ function newFloatingSpace() {
|
||||
/* This function detects weather the point x,y is inside one particular balls. */
|
||||
|
||||
|
||||
var ball = balls[ballIndex];
|
||||
var ball = thisObject.balls[ballIndex];
|
||||
var distance = Math.sqrt(Math.pow(ball.currentPosition.x - x, 2) + Math.pow(ball.currentPosition.y - y, 2));
|
||||
|
||||
if (distance < ball.currentRadius) {
|
||||
|
||||
@@ -104,7 +104,6 @@
|
||||
<Compile Include="ProductStorage.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="temp.js" />
|
||||
<Compile Include="TempExosystem.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
||||
+1
-1
@@ -254,7 +254,7 @@ function newTimelineChart() {
|
||||
|
||||
let imageId = pProductCard.bot.devTeam + "." + pProductCard.bot.profilePicture;
|
||||
|
||||
productPlotter.plotter.profile.text = pProductCard.bot.displayName;
|
||||
productPlotter.plotter.profile.label = pProductCard.bot.displayName;
|
||||
productPlotter.plotter.profile.imageId = imageId;
|
||||
|
||||
canvas.floatingSpace.createNewBall(productPlotter.plotter.profile, thisObject.container)
|
||||
|
||||
@@ -1,773 +0,0 @@
|
||||
|
||||
function newOrderBookChart() {
|
||||
|
||||
/*
|
||||
|
||||
This particular chart, plots information valid at a certain point in time. That menas that first it needs to get that information, and it also
|
||||
has to discard information that is not valid anymore. There is one issue: some graphics elements are displayed and animated, like balls, that
|
||||
means that every time this chart request new info, it can not destroy all the current orders it is based on, since, if they are still valid
|
||||
for the next period of time, recreating them would men producing a glinch on the visualization. So that means that every time that the time period
|
||||
changes, it needs not only to incorporate new orders, but also it needs to eliminate the ones that are out of scope.
|
||||
|
||||
*/
|
||||
|
||||
var datetime;
|
||||
|
||||
var orderBookChart = {
|
||||
setDatetime: setDatetime,
|
||||
isInitialized: false,
|
||||
container: undefined,
|
||||
timeLineCoordinateSystem: undefined,
|
||||
draw: draw,
|
||||
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
|
||||
initialize: initialize
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Here we will define the two arrays that will contain mostly the points to be plotted on the chart.
|
||||
These arrays contains an array that have the following structure:
|
||||
|
||||
0. Rate
|
||||
1. Amount A This is the SUM of Amounts A that belongs to this point in the chart.
|
||||
2. The SUM of Amount A This is the cumulative SUM of SUMs of Amounts A, begining from the smaller rate and going up.
|
||||
3. A Label Ball object
|
||||
|
||||
*/
|
||||
|
||||
var orderBookAsksChartPoints = [];
|
||||
var orderBookBidsChartPoints = [];
|
||||
|
||||
var ballsOrdersQueue = []; // This is the queue of balls waiting for the order to be added to the array to be displayed.
|
||||
var orderBallsReleaseTimer;
|
||||
|
||||
var container = newContainer();
|
||||
container.initialize();
|
||||
orderBookChart.container = container;
|
||||
|
||||
container.displacement.containerName = "Order Book Chart";
|
||||
|
||||
container.frame.containerName = "Order Book Chart";
|
||||
|
||||
var orderBookSnapShot = newOrderBookSnapShot();
|
||||
|
||||
return orderBookChart;
|
||||
|
||||
|
||||
function initialize() {
|
||||
|
||||
orderBookSnapShot.initialize();
|
||||
|
||||
orderBookSnapShot.eventHandler.listenToEvent('Order Added', onOrderAdded, undefined);
|
||||
orderBookSnapShot.eventHandler.listenToEvent('Order Removed', onOrderRemoved, undefined);
|
||||
|
||||
orderBookSnapShot.setDatetime(datetime);
|
||||
|
||||
orderBallsReleaseTimer = setInterval(onReleaseOneMoreBall, 100);
|
||||
// clearTimeout(orderBallsReleaseTimer); Use this to cancel the timer.
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getContainer(point) {
|
||||
|
||||
var container;
|
||||
|
||||
/* First we check if this point is inside this space. */
|
||||
|
||||
if (this.container.frame.isThisPointHere(point) === true) {
|
||||
|
||||
return this.container;
|
||||
|
||||
} else {
|
||||
|
||||
/* This point does not belong to this space. */
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
FUNCTIONS RELATED TO "HANDLING EVENTS"
|
||||
|
||||
*/
|
||||
|
||||
function onOrderAdded() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
function onOrderRemoved() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function onOrderBookChanged() {
|
||||
|
||||
/*
|
||||
|
||||
Fresh data about the order book has just arrived. We need to take it an put it in the right way so that
|
||||
this chart can show what it is supposed to show.
|
||||
|
||||
*/
|
||||
|
||||
/* Since the range of the data might change, we must calculate the timeLineCoordinateSystem everytime new data arrives. */
|
||||
|
||||
var timeLineCoordinateSystem = newTimeLineCoordinateSystem();
|
||||
orderBookChart.timeLineCoordinateSystem = timeLineCoordinateSystem;
|
||||
|
||||
orderBookChart.timeLineCoordinateSystem.initialize(
|
||||
orderBookChart.orderBook.server.orderBookStatistics.resultSet["row 1"].MIN_Rate,
|
||||
orderBookChart.orderBook.server.orderBookStatistics.resultSet["row 2"].MAX_Rate,
|
||||
orderBookChart.container.frame.width
|
||||
);
|
||||
|
||||
/* Balls are being created, before they enter into the floating space. */
|
||||
|
||||
transformRecivedOrdersIntoOrderBalls();
|
||||
|
||||
orderBookChart.isInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
function setDatetime(newDatetime) {
|
||||
|
||||
datetime = newDatetime;
|
||||
orderBookChart.orderBookSnapShot.setDatetime(datetime);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function onReleaseOneMoreBall() {
|
||||
|
||||
/*
|
||||
|
||||
Orders that are queued to be displayed, are released, one by one every time this function is executed.
|
||||
With released, we mean that are pushed to an array of balls that are currently rendered at the Floating Space.
|
||||
|
||||
*/
|
||||
|
||||
if (ballsOrdersQueue.length > 0) {
|
||||
|
||||
/* We take the first order in the queue and push it to the balls array. */
|
||||
|
||||
var ball = ballsOrdersQueue.shift();
|
||||
|
||||
balls.push(ball);
|
||||
|
||||
orderBookChart.addOrder(ball.linkedObject); // We add the order linked to this ball to the order book.
|
||||
|
||||
updateBallsTargets(); // This will recalculate the target for the new ball added.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
FUNCTIONS RELATED TO "PLOTTING THE CHART"
|
||||
|
||||
*/
|
||||
|
||||
function drawOrderBookChart() {
|
||||
|
||||
/*
|
||||
|
||||
This function is responsible for plotting the chart onto the browser canvas. It assumes that there exists 2 arrays, containing
|
||||
the points already calculated to be plotted. Those calculations happens when a new order is added to the chart, in this function
|
||||
we just plot whatever is already calculated.
|
||||
|
||||
*/
|
||||
|
||||
/* The first part of this function will plot BIDs, the second one will plot the ASKs. */
|
||||
|
||||
if (orderBookBidsChartPoints.length > 0) {
|
||||
|
||||
/* We calculate the first points of the chart. These are not points representing orders, but the lower part of the hill plotted. */
|
||||
|
||||
var maxBasePoint = {
|
||||
x: (orderBookBidsChartPoints[orderBookBidsChartPoints.length - 1][0] - orderBookChart.timeLineCoordinateSystem.min.x) * orderBookChart.timeLineCoordinateSystem.timeLineCoordinateSystem.x, // We take the first Order Rate on the array for this.
|
||||
y: orderBookChart.container.frame.height * 5 / 7
|
||||
};
|
||||
|
||||
var minBasePoint = {
|
||||
x: (orderBookBidsChartPoints[0][0] - orderBookChart.timeLineCoordinateSystem.min.x) * orderBookChart.timeLineCoordinateSystem.x, // We take the first Order Rate on the array for this.
|
||||
y: orderBookChart.container.frame.height * 5 / 7
|
||||
};
|
||||
|
||||
/* We make the point relative to the current frame */
|
||||
|
||||
maxBasePoint = orderBookChart.container.frame.frameThisPoint(maxBasePoint);
|
||||
minBasePoint = orderBookChart.container.frame.frameThisPoint(minBasePoint);
|
||||
|
||||
/* We add the possible displacement */
|
||||
|
||||
maxBasePoint = orderBookChart.container.displacement.displaceThisPoint(maxBasePoint);
|
||||
minBasePoint = orderBookChart.container.displacement.displaceThisPoint(minBasePoint);
|
||||
|
||||
/* Lets start the drawing. */
|
||||
|
||||
browserCanvasContext.beginPath();
|
||||
browserCanvasContext.moveTo(minBasePoint.x, minBasePoint.y);
|
||||
|
||||
var sumY = 0;
|
||||
|
||||
for (var i = 0; i < orderBookBidsChartPoints.length; i++) {
|
||||
|
||||
sumY = sumY + orderBookBidsChartPoints[i][1];
|
||||
|
||||
var point = {
|
||||
x: (orderBookBidsChartPoints[i][0] - orderBookChart.timeLineCoordinateSystem.min.x) * orderBookChart.timeLineCoordinateSystem.timeLineCoordinateSystem.x,
|
||||
y: orderBookChart.container.frame.height * 5 / 7 - sumY
|
||||
};
|
||||
|
||||
var rawPosition = {
|
||||
x: point.x,
|
||||
y: point.y
|
||||
};
|
||||
|
||||
/* Frame the point */
|
||||
|
||||
point = orderBookChart.container.frame.frameThisPoint(point);
|
||||
|
||||
/* First we apply the displacement. */
|
||||
|
||||
point = orderBookChart.container.displacement.displaceThisPoint(point);
|
||||
|
||||
browserCanvasContext.lineTo(point.x, point.y);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
browserCanvasContext.lineTo(maxBasePoint.x, maxBasePoint.y);
|
||||
browserCanvasContext.lineTo(minBasePoint.x, minBasePoint.y);
|
||||
browserCanvasContext.closePath();
|
||||
browserCanvasContext.fillStyle = 'rgba(130, 180, 30, 0.9)';
|
||||
browserCanvasContext.fill();
|
||||
browserCanvasContext.strokeStyle = 'rgba(30, 230, 30, 0.9)';
|
||||
browserCanvasContext.lineWidth = 1;
|
||||
browserCanvasContext.stroke();
|
||||
|
||||
browserCanvasContext.closePath();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Ok, Now it is the turn of the ASKs, following is the code that plots them on the chart. */
|
||||
|
||||
|
||||
if (orderBookAsksChartPoints.length > 0) {
|
||||
|
||||
/* We calculate the first point of the chart */
|
||||
|
||||
var maxBasePoint = {
|
||||
x: (orderBookAsksChartPoints[orderBookAsksChartPoints.length - 1][0] - orderBookChart.timeLineCoordinateSystem.min.x) * orderBookChart.timeLineCoordinateSystem.timeLineCoordinateSystem.x, // We take the first Order Rate on the array for this.
|
||||
y: orderBookChart.container.frame.height * 5 / 7
|
||||
};
|
||||
|
||||
var minBasePoint = {
|
||||
x: (orderBookAsksChartPoints[0][0] - orderBookChart.timeLineCoordinateSystem.min.x) * orderBookChart.timeLineCoordinateSystem.timeLineCoordinateSystem.x, // We take the first Order Rate on the array for this.
|
||||
y: orderBookChart.container.frame.height * 5 / 7
|
||||
};
|
||||
|
||||
/* We make the point relative to the current frame */
|
||||
|
||||
maxBasePoint = orderBookChart.container.frame.frameThisPoint(maxBasePoint);
|
||||
minBasePoint = orderBookChart.container.frame.frameThisPoint(minBasePoint);
|
||||
|
||||
/* We add the possible displacement */
|
||||
|
||||
maxBasePoint = orderBookChart.container.displacement.displaceThisPoint(maxBasePoint);
|
||||
minBasePoint = orderBookChart.container.displacement.displaceThisPoint(minBasePoint);
|
||||
|
||||
/* Lets start the drawing. */
|
||||
|
||||
browserCanvasContext.beginPath();
|
||||
browserCanvasContext.moveTo(minBasePoint.x, minBasePoint.y);
|
||||
|
||||
var sumY = 0;
|
||||
|
||||
for (var i = 0; i < orderBookAsksChartPoints.length; i++) {
|
||||
|
||||
sumY = sumY + orderBookAsksChartPoints[i][1];
|
||||
|
||||
var point = {
|
||||
x: (orderBookAsksChartPoints[i][0] - orderBookChart.timeLineCoordinateSystem.min.x) * orderBookChart.timeLineCoordinateSystem.timeLineCoordinateSystem.x,
|
||||
y: orderBookChart.container.frame.height * 5 / 7 - sumY
|
||||
};
|
||||
|
||||
/* Frame the point */
|
||||
|
||||
point = orderBookChart.container.frame.frameThisPoint(point);
|
||||
|
||||
/* We add the possible displacement */
|
||||
|
||||
point = orderBookChart.container.displacement.displaceThisPoint(point);
|
||||
|
||||
browserCanvasContext.lineTo(point.x, point.y);
|
||||
|
||||
}
|
||||
|
||||
browserCanvasContext.lineTo(maxBasePoint.x, maxBasePoint.y);
|
||||
browserCanvasContext.lineTo(minBasePoint.x, minBasePoint.y);
|
||||
browserCanvasContext.closePath();
|
||||
browserCanvasContext.fillStyle = 'rgba(180, 130, 30, 0.75)';
|
||||
browserCanvasContext.fill();
|
||||
browserCanvasContext.strokeStyle = 'rgba(230, 30, 30, 0.75)';
|
||||
browserCanvasContext.lineWidth = 1;
|
||||
browserCanvasContext.stroke();
|
||||
|
||||
browserCanvasContext.closePath();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function drawXAxis() {
|
||||
|
||||
var step = (orderBookChart.timeLineCoordinateSystem.max.x - orderBookChart.timeLineCoordinateSystem.min.x) / 20;
|
||||
|
||||
var decimals;
|
||||
|
||||
/* Lets identify how many decimals are needed to be displayed. To do that we will chekck when is the first time that two consecutives points in the timeLineCoordinateSystem are different. */
|
||||
|
||||
for (var j = 0; j < 10; j++) {
|
||||
|
||||
var diff = (orderBookChart.timeLineCoordinateSystem.min.x + step * 2).toFixed(j) - (orderBookChart.timeLineCoordinateSystem.min.x + step * 1).toFixed(j);
|
||||
|
||||
if (diff !== 0 && decimals === undefined) {
|
||||
decimals = j;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 1; i < 20; i++) {
|
||||
|
||||
var point = {
|
||||
x: orderBookChart.timeLineCoordinateSystem.min.x + step * i,
|
||||
y: orderBookChart.container.frame.height * 6 / 7
|
||||
};
|
||||
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(10, 103, 201, 1)';
|
||||
|
||||
var fontSize = 10;// + orderBookChart.container.zoom.level();
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px verdana';
|
||||
|
||||
/* Se the label */
|
||||
|
||||
var label = point.x.toFixed(decimals);
|
||||
|
||||
/* Now we transform x on the actual coordinate on the canvas. */
|
||||
|
||||
point.x = (point.x - orderBookChart.timeLineCoordinateSystem.min.x) * orderBookChart.timeLineCoordinateSystem.scale.x; // Now x represent a coordinate on the canvas.
|
||||
|
||||
point = orderBookChart.container.frame.frameThisPoint(point);
|
||||
point = orderBookChart.container.displacement.displaceThisPoint(point);
|
||||
|
||||
|
||||
browserCanvasContext.fillText(label, point.x, point.y);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function calculateOrdersSum(pointsArray) {
|
||||
|
||||
/* In this chart we represent the cummulative sum of all orders. That means that every time a new order arrives, we need to recalculate this. */
|
||||
|
||||
var sum = 0;
|
||||
|
||||
for (var i = 0; i < pointsArray.length; i++) {
|
||||
|
||||
sum = sum + pointsArray[i][1];
|
||||
pointsArray[i][2] = sum;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
FUNCTIONS RELATED TO "NEW ORDERS"
|
||||
|
||||
*/
|
||||
|
||||
function removeOrder(order) {
|
||||
/*
|
||||
|
||||
Here we will remove the order from the chart to be ploted. The chart has 2 parts: bids and asks, so we need to know which part to remove it from.
|
||||
|
||||
*/
|
||||
|
||||
if (order.type === 'Bid') {
|
||||
|
||||
removeOrderFromPointArray(order, orderBookBidsChartPoints);
|
||||
calculateOrdersSum(orderBookBidsChartPoints); // We sum all the amounts into the 3rd column of the array.
|
||||
|
||||
} else {
|
||||
|
||||
removeOrderFromPointArray(order, orderBookAsksChartPoints);
|
||||
calculateOrdersSum(orderBookAsksChartPoints); // We sum all the amounts into the 3rd column of the array.
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function removeOrderFromPointArray(order, pointsArray) {
|
||||
|
||||
/* To remove an order, we simply scan the array received and when we find the same order rate, we substract the amount, and thats it. */
|
||||
|
||||
for (var i = 0; i < pointsArray.length; i++) {
|
||||
|
||||
if (pointsArray[i][0] === order.rate) { // We find the item in the pointArray where the rate is the same as the orders rate.
|
||||
|
||||
pointsArray[i][1] = pointsArray[i][1] - order.amountA;
|
||||
|
||||
if (pointsArray[i][1] === 0) { // If we reach zero, then there is no reason to keep this element in the array.
|
||||
|
||||
pointsArray.splice(i, 1); // This means remove this item from the array.
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function addOrder(order) {
|
||||
|
||||
/*
|
||||
|
||||
This is the first function executed when a new order arrives. Here we still don't know if it is an ASK or BID. From here on we
|
||||
do all the things needed to incorporate this new order to the chart.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
var pointIndex;
|
||||
|
||||
if (order.type === 'Bid') {
|
||||
|
||||
pointIndex = addNewBidOrder(order); // We add the new order to the array, if necesary.
|
||||
calculateOrdersSum(orderBookBidsChartPoints); // We sum all the amounts into the 3rd column of the array.
|
||||
|
||||
//if (pointIndex >= 0) { // < 0 means that the amount of the order was summed into an existing item of the array.
|
||||
|
||||
// var ball;
|
||||
|
||||
// ball = addNewLabelBall(pointIndex, order.type, order.rate, 'rgba(30, 130, 30, 0.65)'); // We add a new ball.
|
||||
// orderBookBidsChartPoints[pointIndex][3] = ball;
|
||||
// updateLabelBallsLData(orderBookBidsChartPoints); // We update the labels of the balls we the new values, resulting of the sum calculation.
|
||||
//}
|
||||
|
||||
} else {
|
||||
|
||||
pointIndex = addNewAskOrder(order);
|
||||
calculateOrdersSum(orderBookAsksChartPoints); // We sum all the amounts into the 3rd column of the array.
|
||||
|
||||
//if (pointIndex >= 0) { // < 0 means that the amount of the order was summed into an existing item of the array.
|
||||
|
||||
// var ball;
|
||||
|
||||
// ball = addNewLabelBall(pointIndex, order.type, order.rate, 'rgba(130, 30, 30, 0.65)'); // We add a new ball.
|
||||
// orderBookAsksChartPoints[pointIndex][3] = ball;
|
||||
// updateLabelBallsLData(orderBookAsksChartPoints);
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function addNewBidOrder(order) {
|
||||
|
||||
/*
|
||||
|
||||
Everytime a new order arrives, we need to add it to the array that contains all the chart points for this type of order.
|
||||
To add it, we need to follow certain rules, that are defined by this type of chart. This is what this function does for BID orders.
|
||||
|
||||
*/
|
||||
|
||||
if (orderBookBidsChartPoints.length === 0) {
|
||||
|
||||
orderBookBidsChartPoints.push([order.rate, order.amountA, 0, undefined]); // There it goes the first element of the order book.
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
|
||||
for (var i = 0; i < orderBookBidsChartPoints.length; i++) {
|
||||
|
||||
try {
|
||||
if (order.rate < orderBookBidsChartPoints[i][0] && order.rate > orderBookBidsChartPoints[i + 1][0]) {
|
||||
|
||||
orderBookBidsChartPoints.splice(i + 1, 0, [order.rate, order.amountA, 0, undefined]);
|
||||
return i + 1;
|
||||
}
|
||||
} catch (err) {
|
||||
// It is fine if that does not work. It might be because the index i+1 does not exist.
|
||||
}
|
||||
|
||||
if (order.rate === orderBookBidsChartPoints[i][0]) {
|
||||
|
||||
/* Orders with the exact same rate that previous orders on the order book, are added to the same item of the arrray. */
|
||||
|
||||
orderBookBidsChartPoints[i][1] = orderBookBidsChartPoints[i][1] + order.rate;
|
||||
|
||||
return -1; // This means that no new item was added.
|
||||
|
||||
} else {
|
||||
|
||||
if (order.rate > orderBookBidsChartPoints[i][0] && i === 0) {
|
||||
|
||||
orderBookBidsChartPoints.splice(i, 0, [order.rate, order.amountA, 0, undefined]);
|
||||
return i;
|
||||
|
||||
} else {
|
||||
|
||||
if (order.rate < orderBookBidsChartPoints[i][0] && i === orderBookBidsChartPoints.length - 1) {
|
||||
|
||||
orderBookBidsChartPoints.push([order.rate, order.amountA, 0, undefined]);
|
||||
return orderBookBidsChartPoints.length - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function addNewAskOrder(order) {
|
||||
|
||||
/*
|
||||
|
||||
Everytime a new order arrives, we need to add it to the array that contains all the chart points for this type of order.
|
||||
To add it, we need to follow certain rules, that are defined by this type of chart. This is what this function does for ASK orders.
|
||||
|
||||
*/
|
||||
|
||||
if (orderBookAsksChartPoints.length === 0) {
|
||||
|
||||
orderBookAsksChartPoints.push([order.rate, order.amountA, 0, undefined]); // There it goes the first element of the order book.
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
|
||||
for (var i = 0; i < orderBookAsksChartPoints.length; i++) {
|
||||
|
||||
try {
|
||||
if (order.rate > orderBookAsksChartPoints[i][0] && order.rate < orderBookAsksChartPoints[i + 1][0]) {
|
||||
|
||||
orderBookAsksChartPoints.splice(i + 1, 0, [order.rate, order.amountA, 0, undefined]);
|
||||
return i + 1;
|
||||
}
|
||||
} catch (err) {
|
||||
// It is fine if that does not work. It might be because the index i+1 does not exist.
|
||||
}
|
||||
|
||||
|
||||
if (order.rate === orderBookAsksChartPoints[i][0]) {
|
||||
|
||||
/* Orders with the exact same rate that previous orders on the order book, are added to the same item of the arrray. */
|
||||
|
||||
orderBookAsksChartPoints[i][1] = orderBookAsksChartPoints[i][1] + order.rate;
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
|
||||
if (order.rate < orderBookAsksChartPoints[i][0]) {
|
||||
|
||||
orderBookAsksChartPoints.splice(i, 0, [order.rate, order.amountA, 0, undefined]);
|
||||
return i;
|
||||
|
||||
} else {
|
||||
|
||||
if (order.rate > orderBookAsksChartPoints[i][0] && i === orderBookAsksChartPoints.length - 1) {
|
||||
|
||||
orderBookAsksChartPoints.push([order.rate, order.amountA, 0, undefined]);
|
||||
return orderBookAsksChartPoints.length - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
FUNCTIONS RELATED TO "THE ANIMATION"
|
||||
|
||||
*/
|
||||
|
||||
function draw() {
|
||||
|
||||
/* This function is meant to be executed to draw the whole chart, for instance, as part of some animation loop. */
|
||||
|
||||
this.container.frame.draw();
|
||||
|
||||
if (orderBookChart.isInitialized === true) {
|
||||
|
||||
drawOrderBookChart();
|
||||
|
||||
drawXAxis();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
FUNCTIONS RELATED TO "ORDER BALLS"
|
||||
|
||||
*/
|
||||
|
||||
function transformRecivedOrdersIntoOrderBalls() {
|
||||
|
||||
/*
|
||||
|
||||
Every new order we receive, we automatically transform it into a new ball. That doesnt mean that the ball is going to be
|
||||
displayed right away, but anyway we have it ready for that.
|
||||
|
||||
*/
|
||||
|
||||
var totalRows = Object.keys(orderBookChart.orderBook.server.orderBookData.resultSet).length;
|
||||
|
||||
for (var i = 1; i <= totalRows; i++) {
|
||||
|
||||
var row = orderBookChart.orderBook.server.orderBookData.resultSet["row " + i];
|
||||
|
||||
/* We move the information from the result set to an order object, and use that from now on. */
|
||||
|
||||
var order = newOrder(undefined, row.Type, row.Rate, row.AmountA, row.AmountB, undefined, undefined);
|
||||
|
||||
/* Position of the ball without displacement or zoon. */
|
||||
|
||||
var rawPosition = {
|
||||
x: (order.rate - orderBookChart.timeLineCoordinateSystem.min.x) * orderBookChart.timeLineCoordinateSystem.scale.x,
|
||||
y: orderBookChart.container.frame.height * 5 / 7
|
||||
};
|
||||
|
||||
|
||||
var ball = newBall();
|
||||
|
||||
ball.container = orderBookChart.container;
|
||||
|
||||
|
||||
ball.radomizeCurrentSpeed();
|
||||
|
||||
ball.friction = .995;
|
||||
|
||||
ball.rawPosition = rawPosition;
|
||||
|
||||
ball.initializeMass(order.amountA * 5);
|
||||
ball.initializeRadius(order.amountA * 3);
|
||||
ball.initializeTargetPosition();
|
||||
|
||||
ball.radomizeCurrentPosition(ball.targetPosition);
|
||||
|
||||
ball.linkedObject = order;
|
||||
ball.linkedObjectType = "order";
|
||||
|
||||
if (order.type === 'Bid') {
|
||||
ball.fillStyle = 'rgba(102, 204, 0, 0.75)';
|
||||
} else {
|
||||
ball.fillStyle = 'rgba(222, 105, 42, 0.75)';
|
||||
}
|
||||
|
||||
if (order.type === 'Bid') {
|
||||
ball.labelStrokeStyle = 'rgba(255, 255, 255, 1)';
|
||||
} else {
|
||||
ball.labelStrokeStyle = 'rgba(255, 255, 255, 1)';
|
||||
}
|
||||
|
||||
ball.labelFirstText = order.amountA;
|
||||
ball.labelSecondText = order.rate;
|
||||
|
||||
|
||||
|
||||
ballsOrdersQueue.push(ball);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
FUNCTIONS RELATED TO "LABEL BALLS"
|
||||
|
||||
*/
|
||||
|
||||
function addNewLabelBall(id, type, rate, fillStyle) {
|
||||
|
||||
/* This function is used to create new balls, representing labels of each point on the chart. */
|
||||
|
||||
var rawPosition = {
|
||||
x: (rate - orderBookChart.timeLineCoordinateSystem.min.x) * orderBookChart.timeLineCoordinateSystem.scale.x,
|
||||
y: orderBookChart.container.frame.height * 5 / 7
|
||||
};
|
||||
|
||||
var ball = newBall();
|
||||
|
||||
ball.container = orderBookChart.container;
|
||||
|
||||
ball.radomizeCurrentPosition(rawPosition);
|
||||
ball.radomizeCurrentSpeed();
|
||||
|
||||
ball.friction = .995;
|
||||
|
||||
ball.rawPosition = rawPosition;
|
||||
|
||||
ball.initializeMass(15);
|
||||
ball.initializeRadius(3);
|
||||
ball.initializeTargetPosition();
|
||||
|
||||
|
||||
ball.fillStyle = fillStyle;
|
||||
ball.labelStrokeStyle = 'rgba(255, 255, 255, 1)';
|
||||
|
||||
ball.labelFirstText = 0; //.toFixed(4);
|
||||
ball.labelSecondText = rate.toFixed(8);
|
||||
|
||||
|
||||
balls.push(ball);
|
||||
|
||||
return ball;
|
||||
}
|
||||
|
||||
|
||||
function updateLabelBallsLData(pointsArray) {
|
||||
|
||||
/* When a new order arrives to the chart, all labels of balls representing points in the chart must be updated. */
|
||||
|
||||
var ball;
|
||||
var sum;
|
||||
|
||||
for (var i = 0; i < pointsArray.length; i++) {
|
||||
|
||||
/* We update the balls label. */
|
||||
|
||||
ball = pointsArray[i][3];
|
||||
sum = pointsArray[i][2];
|
||||
|
||||
ball.labelFirstText = sum.toFixed(2);
|
||||
|
||||
/* We update the balls raw position. */
|
||||
|
||||
var rawPositionY = orderBookChart.container.frame.height * 5 / 7 - sum;
|
||||
|
||||
ball.rawPosition.y = rawPositionY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user