Adding up values of nested objects - javascript

I have an object which contains multiple objects. Each object has a height and a width, which I need to add together to get a total height and width. I need to update the totals on input from the user.
Object:
$scope.myObj = {
wall1: {
wFeet: 0,
wInches: 0,
hFeet: 0,
hInches: 0,
totalWidth: 0,
totalHeight: 0
},
wall2: {
wFeet: 0,
wInches: 0,
hFeet: 0,
hInches: 0,
totalWidth: 0,
totalHeight: 0
},
wall3: {
wFeet: 0,
wInches: 0,
hFeet: 0,
hInches: 0,
totalWidth: 0,
totalHeight: 0
}
};
Right Now I have a function that takes the feet and inches values, converts to decimal feet and adds them up to give the total width and height for each wall.
$scope.setTotalWidthAndHeight = function() {
angular.forEach($scope.walls, function(wall) {
//first convert inches to decimal of ft
angular.forEach(wall, function(dim, dimKey) {
if(dimKey === 'wInches') {
wall.wallWidth = wall.wFeet + (0.0833 * dim);
}
if(dimKey === 'hInches') {
wall.wallHeight = wall.hFeet + (0.0833 * dim);
}
})
});
};
What's Im having a problem with now is adding up all the totalWidth and totalHeight values from each object to get one final width and height for all walls combines. There has to be a better way to do it than below.
For example:
var allTotalWidths = $scope.myObj.wall1.totalWidth + $scope.myObj.wall2.totalWidth + $scope.myObj.wall3.totalWidth;

Your function can be optimised a little and I'm going to assume where you've currently got wall.wallWidth = and wall.wallHeight = you meant to have wall.totalWidth = and wall.totalHeight = as the previous properties don't exist in your example data and will have likely thrown an error.
var totalWidths = 0,
totalHeights = 0;
$scope.setTotalWidthAndHeight = function()
{
angular.forEach($scope.walls, function(wall)
{
wall.totalWidth = wall.wFeet + (0.0833 * wall.wInches);
wall.totalHeight = wall.hFeet + (0.0833 * wall.hInches);
totalWidths += wall.totalWidth;
totalHeights += wall.totalHeight;
});
};
I've altered your function to do all the totalling in one swoop. It will populate the totalWidth/Height properties of your initial object and also keep a running total of all widths and heights in the totalWidths and totalHeights variables.

Related

How to highlight particular region in horizontal way in dygraph and how to create dynamic graph

i need to highlight y value example 20 to -10 and -30 to -45 in y axis. permanently with some color with opacity 50%, how to do.,
in this example how to add external csv file to this following code. Pls Guide me
var orig_range;
window.onload = function(){ var r = [];
var arr = ["7/13/2015 0:15:45",45,"7/13/2015 0:30",5,"7/13/2015 0:45",100,"7/13/2015 1:00",95,"7/13/2015 1:15",88,"7/13/2015 1:30",78];
for (var i = 0; i < arr.length; i++) {
r.push([ new Date(arr[i]),arr[i+1]
]);
i++;
}
orig_range = [ r[0][0].valueOf(), r[r.length - 1][0].valueOf() ];
g2 = new Dygraph(
document.getElementById("div_g"),
r, {
rollPeriod: 7,
animatedZooms: true,
// errorBars: true,
width: 1000,
height: 500,
xlabel: 'date',
ylabel: 'Pressure',
}
);
var desired_range = null;};
function approach_range() {
if (!desired_range) return;
// go halfway there
var range = g2.xAxisRange();
if (Math.abs(desired_range[0] - range[0]) < 60 &&
Math.abs(desired_range[1] - range[1]) < 60) {
g2.updateOptions({dateWindow: desired_range});
// (do not set another timeout.)
} else {
var new_range;
new_range = [0.5 * (desired_range[0] + range[0]),
0.5 * (desired_range[1] + range[1])];
g2.updateOptions({dateWindow: new_range});
animate();
}
}
function animate() {
setTimeout(approach_range, 50);
}
function zoom(res) {
var w = g2.xAxisRange();
desired_range = [ w[0], w[0] + res * 1000 ];
animate();
}
function reset() {
desired_range = orig_range;
animate();
}
function pan(dir) {
var w = g2.xAxisRange();
var scale = w[1] - w[0];
var amount = scale * 0.25 * dir;
desired_range = [ w[0] + amount, w[1] + amount ];
animate();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/1.1.0/dygraph-combined-dev.js"></script>
<div id="div_g"></div>
<div id="output"></div>
<b>Zoom:</b>
hour
day
week
month
full
<b>Pan:</b>
left
right
i'm trying to convert graph to dynamic graph data from csv file
var data = ["te1.csv"];
g2 = new Dygraph(document.getElementById("div_g"), data,
{
drawPoints: true,
showRoller: true,
labels:['date','depth'],
});
setInterval(function() {
data.push([data]);
g2.updateOptions( { 'file': data } );
}, 1000);
i have seen example but i dont know how to link my csv file with dynamic dygraph pls guide me
This example does something extremely similar to what you want: it highlights a specific range on the x-axis. To adapt it, you'd do something like this:
new Dygraph(data, div, {
underlayCallback: function (canvas, area, g) {
var bottom = g.toDomYCoord(highlight_start);
var top = g.toDomYCoord(highlight_end);
canvas.fillStyle = "rgba(255, 255, 102, 1.0)";
canvas.fillRect(area.x, top, area.w, bottom - top);
}
})

Get x and y values from string: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3, 3, 3, 1)'

I'm trying to make a function that returns x or y translate position of an element based on what pos was specified 'x' or 'y' like this
function getTranslate(el, pos) {
var translate = '',
position = 0;
if(el.css('transform')) {
translate = el.css('transform');
}
else if(el.css('-webkit-transform')) {
translate = el.css('-webkit-transform');
} else {
translate = 'translate3d(0, 0, 0)';
}
if(pos == 'x') {
position = /* Get x position here */ ;
}
else if(pos == 'y') {
position = /* Get y position here */ ;
}
}
When we grab transform property a string like 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3, 3, 3, 1)' (more info here) is returned for translate3d(3px, 3px, 0). this gets stored in translate variable that I need to parse in order to get position variable to just store number value of either x or y position based on what was given to the function. I'm having trouble figuring out how to parse that string
you can parse the translate string with regular expressions:
var regex = /translate3d\(\s*([^ ,]+)\s*,\s*([^ ,]+)\s*,\s*([^ )]+)\s*\)/;
var test = "translate3d( 10px,20px , 30px)"
var result = test.split(regex);
alert('x is '+result[1]+", and y is "+result[2]);
You can get the position of an element with .offset() or .position().
They are different one get position relative to the document and second relative to the offset parent.
position = element.offset();
position = element.position();
http://api.jquery.com/offset/
https://api.jquery.com/position/

calculated histogram doesn't look as expected

I'm trying to implement histogram RGB but my algorithm doesn't produce similarly look like surface as in graphics programs. For example image on this site:
OpenCV histogram
My version looks like:
As I understood it correctly, RGB Histogram just measuring how often each value occured in specific channel. So I implement it in such way:
public Process(layerManager: dl.LayerManager) {
var surface = layerManager.GetCurrent();
var components = new Uint8Array(1024);
surface.ForEachPixel((arr: number[], i: number): void => {
components[arr[i]] += 1;
components[arr[i + 1] + 256] += 1;
components[arr[i + 2] + 512] += 1;
components[arr[i + 3] + 768] += 1;
});
var histogram = layerManager.GetHistogram();
histogram.Clear();
var viewPort = layerManager.GetHistogramViewPort();
viewPort.Clear();
this.DrawColor(histogram, components, 0, new ut.Color(255, 0, 0, 255));
//histogram.SetBlendMode(ds.BlendMode.Overlay);
//this.DrawColor(histogram, components, 256, new ut.Color(0, 255, 0, 255));
//this.DrawColor(histogram, components, 512, new ut.Color(0, 0, 255, 255));
}
private DrawColor(surface: ds.ICanvas, components: Uint8Array, i: number, fillStyle: ut.Color) {
var point = new ut.Point(0, 255);
surface.BeginPath();
surface.FillStyle(fillStyle.R, fillStyle.G, fillStyle.B, fillStyle.A);
surface.RGBAStrokeStyle(fillStyle.R, fillStyle.G, fillStyle.B, fillStyle.A);
surface.LineWidth(1);
surface.MoveTo(point);
for (var j = i + 256; i < j; ++i) {
point = new ut.Point(point.X + 1, 255 - components[i]);
surface.ContinueLine(point);
}
surface.ClosePathAndStroke();
var viewPort = layerManager.GetHistogramViewPort();
viewPort.DrawImage(surface.Self<HTMLElement>(), 0, 0, 255, 255, 0, 0, viewPort.Width(), viewPort.Height());
}
Am I missing something?
You have a Uint8Array array to hold the results, but the most common RGB values are occurring more than 255 times. This causes an overflow and you end up seeing a histogram of the values modulo 256, which is effectively random for high values. That's why the left and middle parts of the graph (where values are less than 255) are correct, but the higher-valued areas are all over the place.
Use a larger data type to store the results, and normalize to the size of your output canvas before drawing.

CSS matrix calculation

Been trying to sort this out for a few days and I am not sure if the CSS matrix is different from standard graphics matrices, or if I have something wrong (likely I have something wrong).
I am primarily trying to figure out how to rotate on the X and Y axis. When I use "transform: rotateX(2deg) rotateY(2deg) translate3d(0px, -100px, 0px);" and I use javascript to grab the matrix style, this is what I am able to output.
0.9993908270190958, -0.001217974870087876, -0.03487823687206265, 0,
0, 0.9993908270190958, -0.03489949670250097, 0,
0.03489949670250097, 0.03487823687206265, 0.9987820251299122, 0,
0, -99.93908270190957, 3.489949670250097, 1
But if I try to calculate the matrix using javascript (with 2 degrees on both X and Y) I get
0.9993908270190958, 0, -0.03489949670250097, 0,
-0.001217974870087876, 0.9993908270190958, -0.03487823687206265, 0,
0.03487823687206265, 0.03489949670250097, 0.9987820251299122, 0,
0.1217974870087876, -99.93908270190957, 3.487823687206265, 1
Now while several numbers are different in the second one, I believe one number is causing the problem. Note the numbers in row 1/column 2 and in row 2/column 1, for both matrices. The "-0.001217974870087876" looks to be switched. And if I understand how everything is calculated that is likely throwing off all the other numbers.
Here's the code I am using to create the second matrix
var basematrix = [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, -100, 0, 1]
];
function RotateWorld(y, x)
{
var halfrot = Math.PI / 180;
var xcos = Math.cos(x * halfrot);
var xsin = Math.sin(x * halfrot);
var ycos = Math.cos(y * halfrot);
var ysin = Math.sin(y * halfrot);
var ymatrix = [
[ycos, 0, -ysin, 0],
[0, 1, 0, 0],
[ysin, 0, ycos, 0],
[0, 0, 0, 1]
];
var xmatrix = [
[1, 0, 0, 0],
[0, xcos, xsin, 0],
[0, -xsin, xcos, 0],
[0, 0, 0, 1]
];
var calcmatrix = MatrixMultiply(ymatrix, basematrix);
calcmatrix = MatrixMultiply(xmatrix, calcmatrix);
calcmatrix = TransMultiply(calcmatrix);
for (var i = 0; i < 4; i++)
{
for (var j = 0; j < 4; j++)
{
document.getElementById('info').innerHTML += calcmatrix[i][j] + ', ';
}
}
}
function MatrixMultiply(matrixa, matrixb)
{
var newmatrix = [];
for (var i = 0; i < 4; ++i)
{
newmatrix[i] = [];
for (var j = 0; j < 4; ++j)
{
newmatrix[i][j] = matrixa[i][0] * matrixb[0][j]
+ matrixa[i][1] * matrixb[1][j]
+ matrixa[i][2] * matrixb[2][j]
+ matrixa[i][3] * matrixb[3][j];
}
}
return newmatrix;
}
function TransMultiply(matrix)
{
var newmatrix = matrix;
var x = matrix[3][0];
var y = matrix[3][1];
var z = matrix[3][2];
var w = matrix[3][3];
newmatrix[3][0] = x * matrix[0][0] + y * matrix[1][0] + z * matrix[2][0];
newmatrix[3][1] = x * matrix[0][1] + y * matrix[1][1] + z * matrix[2][1];
newmatrix[3][2] = x * matrix[0][2] + y * matrix[1][2] + z * matrix[2][2];
newmatrix[3][3] = x * matrix[0][3] + y * matrix[1][3] + z * matrix[2][3] + newmatrix[3][3];
if (newmatrix[3][3] != 1 && newmatrix[3][3] != 0)
{
newmatrix[3][0] = x / w;
newmatrix[3][1] = y / w;
newmatrix[3][2] = z / w;
}
return newmatrix;
}
My code is a bit verbose as I am just trying to learn how to work with the CSS matrix. But hopefully someone can help me get that one number into the right place.
Edit
I hate to bump a post but I am running out of places to ask, so I am hoping a few more people will see it with a chance of getting an answer. I have tried every possible search to figure this out (unique questions don't get ranked very high in Google). I have probably read over 20 articles on working with matrices and they are yielding nothing. If I need to add more information please let me know. Also if there is a better place to ask let me know that as well. I would assume by now several people have looked at the code and the code must be ok, maybe my assumption that CSS is the culprit is a possibility, if so how does one track that down?
Take a look at this page, it explains how css 3dmatrix work. Also here you have an implementation in JS of CSSMatrix object, very similar to WebKitCSSMatrix which is already included in your (webkit) browser for your use.
You have a bug in your implementation of function TransMultiply(matrix) { .. }
var newmatrix = matrix;
That isn't cloning your matrix, that's setting newmatrix to refer to your original matrix! Anything using this method is going to have the original matrix and new matrix messed up. You might want to use a method that creates new 4x4 matricies, like:
function new4x4matrix(){
return [[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]];
}
and then wherever you need a new matrix, do:
var newmatrix = new4x4matrix();
Edit: err, but you may actually need a clone method: fine.
function cloneMatrix(matrixa)
{
var newmatrix = [];
for (var i = 0; i < 4; ++i)
{
newmatrix[i] = [];
for (var j = 0; j < 4; ++j)
{
newmatrix[i][j] = matrixa[i][j];
}
}
return newmatrix;
}
and instead, for TransMultiply do:
var newmatrix = cloneMatrix(matrix);

animation path problems

How would I make my object reach the end of the animation paths? I am making a basic pong game, but the ball stops early if it misses the paddle, It should reach the end of the path. Here is my code:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf8">
<title> Rapahel test </title>
<script type="text/javascript" src="raphael.js">
</script>
</head>
<body>
<script type="text/javascript">
//create the canvas, which all the shapes are on
var paper = Raphael(0,0,500,500);
ballpath = '';
ballNum = 0;
//the paths the ball will follow, one at a time, starting from 0. which is the first in an array.
paths = ["M480, 180L35, 180", "M35, 180L480, 325", "M480, 325L35, 110", "M35, 110L480, 50", "M480, 50L35, 340", "M35, 340L480, 340", "M480, 340L35, 200", "M35, 200L35, 200"];
Raphael(function () {
ballpath = paper.path(paths[ballNum]).attr({stroke: "#0000ff", opacity: .3, "stroke-width": 1});
var ball = paper.circle(0, 0, 5).attr("fill", "rgba(255, 0, 0, 1)");
//the length variable (and arribute)
var len = ballpath.getTotalLength();
ball.onAnimation(function () {
var t = this.attr("transform");
});
paper.customAttributes.along = function (v) {
var point = ballpath.getPointAtLength(v * len);
return {
transform: "t" + [point.x, point.y] + "r" + point.alpha
};
};
ball.attr({along: 0});
//the variable rotateAlongThePath is true
var rotateAlongThePath = true;
//th function that actually makes the ball move
function run() {
//the path which the wall will follow
wallpath = paper.path("M480, 180L480, 380, M480, 380L480, 60, M480, 60L480, 340").attr({stroke: "#0000ff", opacity: .3, "stroke-width": 1});
//create a rectangle
var wall2 = paper.rect(0 - 50, 0 - 9, 100, 20).attr("fill", "rgba(0, 0, 255, 1)");
//the length variable (and arribute)
var wallLen = wallpath.getTotalLength();
//not sure aout these commands, they are to do with animation paths
wall2.onAnimation(function () {
var t = this.attr("transform");
});
paper.customAttributes.along2 = function (v2) {
var point2 = wallpath.getPointAtLength(v2 * wallLen);
return {
transform: "t" + [point2.x, point2.y] + "r" + point2.alpha
};
};
//set the wall's movemnt to 0
wall2.attr({along2: 0});
var collision = function(){
//find the paddle's height and width, the ball's center point, and AI Paddle's x position
var paddleheight = Math.round(paddle.getBBox().y + paddle.getBBox().height / 2);
var paddleWidth = Math.round(paddle.getBBox().x + paddle.getBBox().width / 2);
var ballcenterpoint = Math.round(ball.getBBox().y + ball.getBBox().height / 2);
var AIpaddle = Math.round(wall2.getBBox().x + wall2.getBBox().width / 2);
//the height from the center point of the paddle to the edge (heigh variance), finding the height of the top edge of the boundingbox (where the ball will colide with) by adding the centerpoint and height variance. finding the bottom edge by subtracting the centerpoint from the bounding box.
var heightvariance = pHeight;
var heightPlusboundingbox = paddleheight + heightvariance;
var heightMinusboundingbox = paddleheight - heightvariance;
//if the edge of the box is less than or equal to the center of the ball.
var balledge = Math.round(ball.getBBox().x + (ball.getBBox().width / 2) + 22);
//continue ballbounce is used for the if below; it equals: if the ball center is largerthan or equal to the height of the paddle minus its bounding box AND the center point is equal to or less than the height of the paddle plus the bounding box AND the center is equal to or greater than the width (extending the detected edge ofthe box by a few pixels so as to fix some collision problems) the if below will work.
console.log('Ball X: ', balledge);
console.log('AI X: ', AIpaddle);
console.log(balledge);
console.log(AIpaddle);
//the if
if(ballcenterpoint >= heightMinusboundingbox && ballcenterpoint <= heightPlusboundingbox || balledge >= AIpaddle){
//if the ball number is less than or equal to 6 it will increase theball number by one an change the ballpath to one in the array called paths[ballNum], the ball will then begin at the beginning of that path and be animated along it
if(ballNum <= 6){
ballNum++
ballpath = paper.path(paths[ballNum]).attr({stroke: "#0000ff", opacity: .3, "stroke-width": 1});
ball.attr({along: 0});
ball.animate({along: 1}, 2500, onanimationdone);
}
//if the ballNum is greater than 6 it will remove the ball (fixin the error of an infinite loop of theball just sitting the corner acting all boring and doing nothing)
}
else {
// ball.remove(); //- YOU LOSE
};
};
//animates the wall
wall2.animate({along2: 1}, 16200, function () {
});
//loops through all the ball paths
var onanimationdone = function () {
collision();
};
ball.animate({along: 1}, 2500, onanimationdone);
ball.attr({along: 0});
};
//create a rectangles
var pHeight = 100;
var pWidth = 20;
var paddle = paper.rect(10, 130, pWidth, pHeight);
paddle.attr("fill", "rgba(0, 0, 255, 1)");
var start = function () {
// storing original coordinates
this.originalY = this.attr("y");
this.attr({opacity: 0.9});
},
move = function (dx, dy) {
// moves the object up and down, when clicked and dragged
this.attr({y: this.originalY + dy});
},
up = function () {
// restoring state
this.attr({opacity: 1.0});
};
//runs the functions
paddle.drag(move, start, up);
run();
});
</script>
</body
</html>
I am new to JavaScript, I apologise if my code is a little hard to understand (this is my fourth day doing JavaScript).
Using raphael is valid for rendering your graphics, but I would suggest using the paths array for the ball's motion is not. If you are in fact trying to make a game you are best off having the ball store it's current position and velocity, and update these per frame via some some of timer.

Categories