Using .blur(function() to update live calculation - javascript

I'm trying to use .blur to update a calculation function based off of a select box. It works when the user first changes the box from 0 to 1 for example, but when it's changed after that it won't reverse the previous calculation. #to_condition is the id that is displayed in text, originally 10. After I change #is_bent_num from 0 to 1, #to_condition is correctly decreasing by 0.5 to 9.5, but if I change it again, say to 3, instead of adding 0.5 back and then subtracting 1.5 (making #to_condition 8.5) it subtracts 1.5 from the 9.5, making #to_condition = 8.
var bent_num = 0.5;
var bent_orig = $("#is_bent_num").val();
$("#is_bent_num").blur(function(){
var bent_new = $("#is_bent_num").val();
updatecondition(bent_num * bent_orig * -1);
updatecondition(bent_num * bent_new);
bent_orig = bent_times;
});
function updatecondition(newcondition){
var changecondition = $("#condition_exact").val() - newcondition;
$("#condition_exact").val(changecondition);
if (changecondition < 0){
changecondition = 0;
}
changecondition = changecondition.toFixed(1);
$("#to_condition").text(changecondition);
}

James, I think you didn't paste you whole code, e.g. definition of bent_times is missing. However it clearly seems for me that the first two lines of updatecondition are the cause of your problem. You should always substract from $("#is_bent_num").val() isntead of $("#condition_exact").val()

The result put into #to_condition when the function updatecondition is called depends on both the newcondition parameter sent to the function and the #condition_exact value, and the latter is updated every time the updateconditino is called. Perhaps that update of the #condition_exact value is what is causing your problem?
$("#condition_exact").val(changecondition);

I think your problem is here:
updatecondition(bent_num * bent_orig * -1);
updatecondition(bent_num * bent_new);
You basically update the #condition_exact field twice; once with a value based on bent_num, and once with a value based on the user's input (bent_new). The second update is (of course) the one you will see. I think what you meant to do was this:
updatecondition(bent_orig - (bent_num * bent_new));
Now the field will be updated only once. The new value will be the original value, minus the user's input times bent_num.
By the way, your variable names are a bit confusing. For example, what does bent_num mean? Is it the step size? Would someone else who looks at this code know what it means? (I certainly don't.) Will you, if you look at the code again in 6 months' time? So if bent_num is the step size, why not call it step_size (or stepSize)?

Related

How to add the missing numbers with this code and only doing it when a variable is 0 in angular 7

What this functionality does is that for each priority it will rebalance the percentage (Participacion) in equal parts. The problem occurs in odd cases, for example when there are 3 priorities(Prioridad), you must divide 100 / 3, which gives a result of 33 (and 33 + 33 + 33 = 99 )
What should I add to my code, so that when the result of the division is not 100, the missing numbers are added to the last position, completing the 100.
Example problem 1 : Example gif : The idea is that the last 33 that you see in the gif is automatically transformed into a 34.Tthis is the code i have so far:
rebalance(){
this.beneficiarios = this.beneficiarios.sort((a, b) =>Number(a.Prioridad) - Number(b.Prioridad)).map((val, i, beneficiarios) => {
const priorityLenght = this.beneficiarios.filter((a) =>
Number(a.Prioridad) == Number(val.Prioridad)).map((b) =>
Number(b.Participacion)).length
const arrObj = {
...val,
Participacion : 100 / priorityLenght
}
return arrObj;
})
}
Problem 2: In the previous gif you can see that when you press the button, the rebalancing was done for all the priorities (Prioridad), I would like it to be only for those that contain a 0 in percentage (Participacion)
I'm pretty sure that both problems can be solved by adding a couple lines of code to the function I put above, but I lack experience to know what to do
Here a StackBlizz of the proyect: https://stackblitz.com/edit/create-a-basic-angular-component-v8k1hs?file=src/app/example/user.component.ts
I fixed your algorithm. Really just needed a slightly different approach. I changed it to use Math.floor() for participation and then got the diff (100 % length) needed to make the value 100% and added that to the last value. Here is the updated stackblitz.
https://stackblitz.com/edit/create-a-basic-angular-component-7vj1rr?file=src/app/example/user.component.html
PS: never make method calls in the template due to the overhead the this add each time change detection runs; instead use pure pipes or calculate their value for presentation when the data changes. There was a decimal formatting method being called that I removed.

Formula not calculating correctly in JavaScript

I'm experiencing an issue with a formula in JavaScript.
var animMoveX = $(this).attr('data-start') + (animPercentage / 100) * ($(this).attr('data-finish') - $(this).attr('data-start'));
To my eyes it's a fairly simple piece of math, but the console outputs 120-[variable no relative to animPercentage, eg. 126.49681528662421].
I've double-checked all variables, and they are correct, and if I replace one of the $(this).attr('data-start') variable in one of the positions with a fixed number, then the calculation is run just fine. Can someone shed some light on why this is, and how I could potentially work around it?
From my comment: Precedence means it will calculate a number on the right and add it to the string from data-start (i.e. using string concatenation). That needs to be converted to a number too. #Pointy's suggestion will do that as data converts strings to appropriate data types (when it can).
So basically change all the attr() calls to data() calls and "numbers" (stored in attributes) will become numbers:
var animMoveX = $(this).data('start') + (animPercentage / 100) * ($(this).data('finish') - $(this).data('start'));
As an added bonus, using data instead of attr is shorter code too :)

How to auto refresh these randomly generated colors

I've tried many solutions off my head like using setInterval in various ways but I can't seem to get it working.
Currently on every refresh, the patterns will all be random. The closest thing to what I wanted was that I made a setInterval and code but it only made 1 square continuously change its color. I deleted it by the way.
I just want after the page loads, it will continue to flip through random colors and not just be stuck on what was already generated.
var rndTile = Math.floor((Math.random() * 40) + 1);
var base = 2 / 2;
var colChoices = ["#81A594","#79BEDB","#6B78B4", "#593E1A", "#99CCCC"];
var fadeTime = Math.floor((Math.random * 6000));
Code: https://jsfiddle.net/nL56woyy/8/
Since i can't understand your fiddle properly i am presenting my own solution here. Your first problem is that the random number is only generated once on site load. Second thing: your var base is always 1 and gets reseted to 0 in the each call. Thats why your output is always the same.
Since the code is to long to put it on stackoverflow here is the fiddle: https://jsfiddle.net/0ajg01y1/1/

How do I check my condition on an if statement to see if it is working correctly?

I'm trying to make a type of circular display which cycles through a series of values as well as moving text elements within an svg file. It uses the hammer.js library and uses the drag event. The values can go in either direction. I have it working to some degree. As the last value is shown from an array, it goes back to the beginning of the array to get the first values. Or vice-versa.
var keyArray = ["C","C#","Db","D","D#","Eb","E","F","F#","Gb","G","G#","Ab","A","A#","Bb","B"];
This is my array. Here is how I wrap it past the end of the array and back to the beginning.
** As per the request of a few commenters and the suggested solution by Nina, I have modified the code below to reflect their suggestions. I have also added a few more lines for clarity of what is happening overall.**
var delta = keyArray.length - 5; // can be constant, it is always positive
for(i=0;i<5;i++){
//5 svg text element containing 5 musical keys
keys = document.getElementById("keys"+i);
//ev.deltaX is the change received from the hammer pan event
//text element moves relative to its original starting X
keys.setAttribute("x",startingSpots[i]+ev.deltaX%150);
currentX=keys.getAttribute("x");
currentEdgeIndex=keyArray.indexOf(keys.textContent);
//This if is what appears to be failing.
if (keys.getAttribute("x")>=565){
keys.setAttribute("x",currentX-150);
keys.textContent = keyArray[(currentEdgeIndex + delta) % keyArray.length];
}
}
With the suggested changes, I removed the Number() calls as well as implementing the modulus for the wrapper. The behavior is still erratic. On the example below, if you pan to the right, as the first text element reaches 565, it meets the condition for the if, is moved back to the left by 150.
What it should do next is to change the textContent to the next appropriate value in the array. However, this is where it becomes erratic, it is no longer past 565 so it does not meet the condition of the if statement, but the text changes at every increment of the pan event as if it were.
I am sure I am not seeing something simple that is causing the trouble but not sure what it is.
The array does appear to be circling correctly, though I'm still not sure "How can I check to see if the if statement is being correctly evaluated and met?"
The project can be viewed here. http://codepen.io/cmgdesignstudios/pen/zrmQaE?editors=1010
* Edit with solution *
Nina suggested the problem lie in the handling of the touch event. After further investigation, I found she was correct. I had originally been moving the object relative to its starting position and the deltaX from the touch event. I then was trying to change the current position by simply moving it back to the left rather than adjusting the starting position.
So I replaced the
keys.setAttribute("x",currentX-150);
with
startingSpots[i]-=150;
This kept the movement relative to the starting position and the deltaX of the touch event.
Please delete the Number(...) casting where it's not necessary. ...length returns always number and the result of calculation is a number too.
Your actual key feature is to move 5 entries down, and this can be achieved wit a simple addition and a modulo, to keep the value in a specific range, like
keys.textContent = keyArray[(keyArray.length + currentEdgeIndex - 5) % keyArray.length];
Further simplified can this calculation then lead to just add a positive number of
delta = keyArray.length - 5; // can be constant, it is always positive
keys.textContent = keyArray[(currentEdgeIndex + delta) % keyArray.length];
and make the modulo out of it.

Linearly scaling a number in a certain range to a new range

I've made a scaling function that takes numbers in an interval [oldMin,oldMax] and scales them linearly to the range [newMin,newMax] . It does not seem to work when using negative values.
function linearScaling(oldMin, oldMax, newMin, newMax, oldValue){
var newValue;
if(oldMin !== oldMax && newMin !== newMax){
newValue = parseFloat((((oldValue - oldMin) * (newMax - newMin)) / (oldMax - oldMin)) + newMin);
newValue = newValue.toFixed(2);
}
else{
newValue = error;
}
return newValue;
}
This function seems to work when scaling a value from 0 -> 32761 to the range range 0 -> 10. However it does not seem to give the correct output when given a new negative range i.e. -10 -> 10
I have done my best to find an answer on this site. However the person who asked the question didn't mention what he ended up doing to fix it. That question says it could have something to do with mixed up data types, but i converted everything to a float did I miss anything?
Now that you showed how you call your function, I can reproduce your problem - namely that quoted numbers that should map to the negative domain don't.
It seems to be due to the fact that Javascript is very loose about the difference between a number and a string - and if it's not sure what to do about two numbers (because one of them appears to be a string), it assumes you want concatenation rather than addition. In other words - by passing the newMin value as '-10' rather than -10 you confused JS.
As a simple example,
document.write('1' + '-2');
produces
1-2
However,
document.write(1*'1' + 1*'-2');
results in
-1
The expression you had included a "possible concatenation" where it added oldMin:
newValue = (((oldValue - oldMin) * (newMax - newMin)) / (oldMax - oldMin)) + newMin;
With newMin set to '-10', you might get newValue to look like 6-10 instead of -4, to give an example. When you then did a parseFloat, Javascript would quietly work its way through the string up to the minus sign, and return 6 instead of evaluating the expression and coming up with -4.
To clear up the confusion, multiply each parameter by 1 to make it "a genuine number":
oldMin = 1*oldMin;
oldMax = 1*oldMax;
newMin = 1*newMin;
newMax = 1*newMax;
oldValue = 1*oldValue;
When you add these lines at the start of your function declaration, everything works smoothly - regardless of how you call the function. Or just call it with the newMin value not in quotes - it is the one causing the trouble in this particular instance.
document.writeln('the new code called with parameter = 100:\n');
document.writeln(linearScaling('0', '32761', '-10', '10', 100)+'<br>');
document.writeln('the old code called with parameter = 100:\n');
document.writeln(linearScalingOld('0.0', '32761.0', '-10.0', '10.0', '100.0')+'<br>');
document.writeln('the old code called with unquoted parameters:\n');
document.writeln(linearScalingOld(0.0, 32761.0, -10.0, 10.0, 100.0)+'<br>');
results in the following:
the new code called with parameter = 100: -9.94
the old code called with parameter = 100: 0.06
the old code called with unquoted parameters: -9.94
I hope this illustrates the cause of the problem, and the solution.

Categories

Resources