Put delay on adding Class - javascript

I'm working on the next simple racing game.
I animate the cars using some JQuery code, adding the values that comes from the carspeed array. I have manage to make it work, but i have a problem with the addClass function: once the game started the task is already done, so it is not syncing to the animate function which has 200 duration.
I tried the answers from here but still don't work, I also tried to separate the addClass function inside a setTimeout but didn't work.
Check the next snippet example, Hope you help me.
Thanks.
var cars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var winningCars = shuffle(cars);
var carSpeeds = [
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20,
19, 18, 17, 16, 15, 16, 18, 20, 22, 24, 26, 27, 28, 29, 30, 32,
34, 35, 36, 38, 40, 38, 37, 36, 35, 34, 36, 38, 40, 42, 44, 46,
48, 50, 50, 50, 49, 48, 47, 91.5],
[1, 2, 3, 4, 5, 5, 5, 5, 5, 7, 9, 11, 13, 15, 16, 17, 17, 17, 17,
19, 19, 19, 19, 20, 22, 22, 22, 22, 24, 24, 24, 26, 28, 30, 32,
34, 35, 35, 35, 35, 37, 39, 41, 43, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54, 53, 53, 52, 51, 50, 91.5],
[2, 4, 6, 8, 10, 11, 12, 13, 14, 16, 18, 20, 19, 18, 17, 16, 15,
15, 15, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 27, 29,
31, 33, 35, 37, 39, 41, 42, 43, 44, 91.5],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 21, 22, 23,
24, 25, 23, 21, 19, 17, 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 32, 34, 36, 38, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 50, 50, 50, 52, 54, 56, 91.5],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 10, 12, 14, 16, 18, 20,
22, 24, 23, 22, 21, 20, 19, 18, 19, 20, 21, 22, 23, 24, 26, 28, 28,
28, 28, 29, 30, 31, 32, 33, 34, 35, 37, 39, 41, 43, 45, 46, 47, 48,
49, 49, 49, 49, 48, 47, 46, 45, 44, 91.5],
[1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 8, 10, 12, 14, 14, 14, 16, 17, 17, 17,
17, 16, 15, 14, 16, 18, 20, 22, 24, 26, 28, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 39, 38, 37, 38, 39, 40, 41, 42, 43, 44, 44, 44,
44, 46, 48, 50, 48, 47, 46, 48, 50, 91.5],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 22, 24, 23, 23,
22, 22, 20, 19, 18, 16, 18, 20, 22, 24, 26, 28, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 39, 39, 38, 38, 37, 38, 39, 39, 39, 38, 38,
38, 38, 38, 38, 38, 40, 42, 44, 46, 48, 50, 91.5],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 16, 16,
16, 16, 17, 18, 19, 20, 22, 24, 26, 28, 30, 32, 34, 36, 35, 34, 33,
32, 31, 30, 29, 28, 27, 26, 27, 28, 28, 28, 28, 27, 28, 29, 30, 31,
32, 33, 34, 35, 34, 33, 32, 31, 30, 32, 34, 36, 91.5],
[1, 2, 3, 4, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 18, 18, 18, 19, 20, 21, 22, 23, 24, 23, 22, 21, 20, 19, 18, 17,
16, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31, 33, 35,
37, 39, 40, 40, 40, 40, 41, 41, 41, 43, 45, 47, 91.5],
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 22, 24, 26, 28, 30,
32, 34, 36, 38, 40, 41, 41, 41, 41, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 50, 50, 50, 50, 50, 51, 51, 51, 52, 52, 52, 52, 52, 91.5]
];
function burst(current, prev)
{
const speed = current - prev;
if (speed <= 2)
{
return 'burst';
}
else if (speed > 2)
{
return 'mega-burst';
}
}
for (let i = 0; i < winningCars.length; i++)
{
for (let x = 0; x < carSpeeds[i].length; x++)
{
$('.track .lane:nth-child(' + winningCars[i] + ') .cars')
.removeClass('mega-burst burst')
.addClass(burst(carSpeeds[i][x], carSpeeds[i][x - 1]))
.animate({right: carSpeeds[i][x] + '%'}, 200);
}
}
function shuffle(array)
{
var currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex)
{
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
.track {
position: relative;
width: 588px;
height: 490px;
background-image: url(https://i.postimg.cc/fTP5Q9Bb/road2.png);
background-position: 0px 0px;
background-repeat: repeat-x;
}
.track.start {
animation: animatedBackground 1s linear infinite;
}
#keyframes animatedBackground {
from {
background-position: 0 0;
}
to {
background-position: -100% 0;
}
}
.road {
position: absolute;
width: 100%;
top: 42px;
}
.road .lane {
height: 17.5px;
width: 100%;
margin-bottom: 1px;
padding-top: 3px;
position: relative;
}
.road .cars {
width: 30px;
height: 15px;
position: absolute;
right: 10px;
}
.road .car1 {
background-color: blue;
}
.road .car2 {
background-color: red;
}
.road .car3 {
background-color: yellow;
}
.road .car4 {
background-color: orange;
}
.road .car5 {
background-color: purple;
}
.road .car6 {
background-color: black;
}
.road .car7 {
background-color: green;
}
.road .car8 {
background-color: violet;
}
.road .car9 {
background-color: lime;
}
.road .car10 {
background-color: gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="track start">
<div class="road">
<div class="road-lanes">
<div class="lane">
<div class="cars car1"></div>
</div>
<div class="lane">
<div class="cars car2"></div>
</div>
<div class="lane">
<div class="cars car3"></div>
</div>
<div class="lane">
<div class="cars car4"></div>
</div>
<div class="lane">
<div class="cars car5"></div>
</div>
<div class="lane">
<div class="cars car6"></div>
</div>
<div class="lane">
<div class="cars car7"></div>
</div>
<div class="lane">
<div class="cars car8"></div>
</div>
<div class="lane">
<div class="cars car9"></div>
</div>
<div class="lane">
<div class="cars car10"></div>
</div>
</div>
</div>
</div>

As you are iterating classes in for loop, all the manipulations will happen within a loop hence you wont be able to see it happening.
Use setTimeout with proper timeout duration.
var cars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var winningCars = shuffle(cars);
var carSpeeds = [
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20,
19, 18, 17, 16, 15,
16, 18, 20, 22, 24, 26, 27, 28, 29, 30, 32, 34, 35, 36, 38, 40,
38, 37, 36, 35, 34,
36, 38, 40, 42, 44, 46, 48, 50, 50, 50, 49,
48, 47,
91.5
]
}
function burst(current, prev) {
const speed = current - prev;
if (speed <= 2) {
return 'burst';
} else if (speed > 2) {
return 'mega-burst';
}
}
let count = 0;
const timeout = 2000;
for (let i = 0; i < winningCars.length; i++) {
for (let x = 0; x < carSpeeds[i].length; x++) {
setTimeout(() => {
$('.racing-animation-modal .track .lane:nth-child(' + winningCars[i] + ') .cars').removeClass('mega-burst burst').addClass(burst(carSpeeds[i][x], carSpeeds[i][x - 1])).animate({
right: carSpeeds[i][x] + '%'
}, 200);
}, count++ * timeout);
}
}

Here is my approach, using the features of the complete callback method of the JQuery animate function, and a recursive approach. To check how this is done proggresively in time, just uncomment the console.log() inside the moveCar() function. Here is a preview of the main code that manage animations proggresively:
for (let i = 0; i < winningCars.length; i++)
{
// Start moving the cars.
setTimeout(function(){moveCar(i, 0);}, 100);
}
function moveCar(carIdx, iteration)
{
//console.log("Entering iteration: " + iteration + " for car: " + carIdx);
// Check the stop condition.
if (iteration >= carSpeeds[carIdx].length)
return;
// Get the burst class.
var burstClass;
if (iteration > 0)
burstClass = burst(carSpeeds[carIdx][iteration], carSpeeds[carIdx][iteration - 1]);
else
burstClass = burst(carSpeeds[carIdx][iteration], 0);
// Make an iteration of movement on the car.
$('.track .lane:nth-child(' + winningCars[carIdx] + ') .cars')
.removeClass('mega-burst burst')
.addClass(burstClass)
.animate({right: carSpeeds[carIdx][iteration] + '%'}, 200, function()
{
// On amination complete, call recursively next iteration.
moveCar(carIdx, iteration + 1);
});
}
And here you can see the working snippet:
var cars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var winningCars = shuffle(cars);
var carSpeeds = [
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20,
19, 18, 17, 16, 15, 16, 18, 20, 22, 24, 26, 27, 28, 29, 30, 32,
34, 35, 36, 38, 40, 38, 37, 36, 35, 34, 36, 38, 40, 42, 44, 46,
48, 50, 50, 50, 49, 48, 47, 91.5],
[1, 2, 3, 4, 5, 5, 5, 5, 5, 7, 9, 11, 13, 15, 16, 17, 17, 17, 17,
19, 19, 19, 19, 20, 22, 22, 22, 22, 24, 24, 24, 26, 28, 30, 32,
34, 35, 35, 35, 35, 37, 39, 41, 43, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54, 53, 53, 52, 51, 50, 91.5],
[2, 4, 6, 8, 10, 11, 12, 13, 14, 16, 18, 20, 19, 18, 17, 16, 15,
15, 15, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 27, 29,
31, 33, 35, 37, 39, 41, 42, 43, 44, 91.5],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 21, 22, 23,
24, 25, 23, 21, 19, 17, 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 32, 34, 36, 38, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 50, 50, 50, 52, 54, 56, 91.5],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 10, 12, 14, 16, 18, 20,
22, 24, 23, 22, 21, 20, 19, 18, 19, 20, 21, 22, 23, 24, 26, 28, 28,
28, 28, 29, 30, 31, 32, 33, 34, 35, 37, 39, 41, 43, 45, 46, 47, 48,
49, 49, 49, 49, 48, 47, 46, 45, 44, 91.5],
[1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 8, 10, 12, 14, 14, 14, 16, 17, 17, 17,
17, 16, 15, 14, 16, 18, 20, 22, 24, 26, 28, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 39, 38, 37, 38, 39, 40, 41, 42, 43, 44, 44, 44,
44, 46, 48, 50, 48, 47, 46, 48, 50, 91.5],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 22, 24, 23, 23,
22, 22, 20, 19, 18, 16, 18, 20, 22, 24, 26, 28, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 39, 39, 38, 38, 37, 38, 39, 39, 39, 38, 38,
38, 38, 38, 38, 38, 40, 42, 44, 46, 48, 50, 91.5],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 16, 16,
16, 16, 17, 18, 19, 20, 22, 24, 26, 28, 30, 32, 34, 36, 35, 34, 33,
32, 31, 30, 29, 28, 27, 26, 27, 28, 28, 28, 28, 27, 28, 29, 30, 31,
32, 33, 34, 35, 34, 33, 32, 31, 30, 32, 34, 36, 91.5],
[1, 2, 3, 4, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 18, 18, 18, 19, 20, 21, 22, 23, 24, 23, 22, 21, 20, 19, 18, 17,
16, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31, 33, 35,
37, 39, 40, 40, 40, 40, 41, 41, 41, 43, 45, 47, 91.5],
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 22, 24, 26, 28, 30,
32, 34, 36, 38, 40, 41, 41, 41, 41, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 50, 50, 50, 50, 50, 51, 51, 51, 52, 52, 52, 52, 52, 91.5]
];
function burst(current, prev)
{
const speed = current - prev;
if (speed <= 2)
{
return 'burst';
}
else if (speed > 2)
{
return 'mega-burst';
}
}
for (let i = 0; i < winningCars.length; i++)
{
// Start moving the cars.
setTimeout(function(){moveCar(i, 0);}, 100);
}
function moveCar(carIdx, iteration)
{
//console.log("Entering iteration: " + iteration + " for car: " + carIdx);
// Check the stop condition.
if (iteration >= carSpeeds[carIdx].length)
return;
// Get the burst class.
var burstClass;
if (iteration > 0)
burstClass = burst(carSpeeds[carIdx][iteration], carSpeeds[carIdx][iteration - 1]);
else
burstClass = burst(carSpeeds[carIdx][iteration], 0);
// Make an iteration of movement on the car.
$('.track .lane:nth-child(' + winningCars[carIdx] + ') .cars')
.removeClass('mega-burst burst')
.addClass(burstClass)
.animate({right: carSpeeds[carIdx][iteration] + '%'}, 200, function()
{
// On amination complete, call recursively next iteration.
moveCar(carIdx, iteration + 1);
});
}
function shuffle(array)
{
var currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex)
{
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
.track {
position: relative;
width: 588px;
height: 490px;
background-image: url(https://i.postimg.cc/fTP5Q9Bb/road2.png);
background-position: 0px 0px;
background-repeat: repeat-x;
}
.track.start {
animation: animatedBackground 1s linear infinite;
}
#keyframes animatedBackground {
from {
background-position: 0 0;
}
to {
background-position: -100% 0;
}
}
.road {
position: absolute;
width: 100%;
top: 42px;
}
.road .lane {
height: 17.5px;
width: 100%;
margin-bottom: 1px;
padding-top: 3px;
position: relative;
}
.road .cars {
width: 30px;
height: 15px;
position: absolute;
right: 10px;
}
.road .car1 {
background-color: blue;
}
.road .car2 {
background-color: red;
}
.road .car3 {
background-color: yellow;
}
.road .car4 {
background-color: orange;
}
.road .car5 {
background-color: purple;
}
.road .car6 {
background-color: black;
}
.road .car7 {
background-color: green;
}
.road .car8 {
background-color: violet;
}
.road .car9 {
background-color: lime;
}
.road .car10 {
background-color: gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="track start">
<div class="road">
<div class="road-lanes">
<div class="lane">
<div class="cars car1"></div>
</div>
<div class="lane">
<div class="cars car2"></div>
</div>
<div class="lane">
<div class="cars car3"></div>
</div>
<div class="lane">
<div class="cars car4"></div>
</div>
<div class="lane">
<div class="cars car5"></div>
</div>
<div class="lane">
<div class="cars car6"></div>
</div>
<div class="lane">
<div class="cars car7"></div>
</div>
<div class="lane">
<div class="cars car8"></div>
</div>
<div class="lane">
<div class="cars car9"></div>
</div>
<div class="lane">
<div class="cars car10"></div>
</div>
</div>
</div>
</div>

Related

ApexChart column resize on zoom

I would like to resize the columns width when the user zoom on my chart. Could you suggest any method or option? I searched through the documentation but I didn't find any solution. Until now I tried by changing the bar width percentage, the responsive option and the stroke width. The stroke has the side effect of overlapping the bars but I need them separate
Before Zoom
After Zoom actual behaviour
After Zoom desired behaviour
Code used until now
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Bar with Custom DataLabels</title>
<link href="../../assets/styles.css" rel="stylesheet" />
<style>
#chart {
max-width: 650px;
margin: 35px auto;
}
</style>
<script>
window.Promise ||
document.write(
'<script src="https://cdn.jsdelivr.net/npm/promise-polyfill#8/dist/polyfill.min.js"><\/script>'
);
window.Promise ||
document.write(
'<script src="https://cdn.jsdelivr.net/npm/eligrey-classlist-js-polyfill#1.2.20171210/classList.min.js"><\/script>'
);
window.Promise ||
document.write(
'<script src="https://cdn.jsdelivr.net/npm/findindex_polyfill_mdn"><\/script>'
);
</script>
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<script>
// Replace Math.random() with a pseudo-random number generator to get reproducible results in e2e tests
// Based on https://gist.github.com/blixt/f17b47c62508be59987b
var _seed = 42;
Math.random = function () {
_seed = (_seed * 16807) % 2147483647;
return (_seed - 1) / 2147483646;
};
</script>
</head>
<body>
<div id="chart"></div>
<script>
var options = {
series: [
{
name: 'Net Profit',
data: [
95, 4, 48, 95, 71, 16, 44, 98, 75, 94, 28, 61, 76, 1, 54, 90, 19,
5, 37, 57, 88, 31, 41, 59, 27, 96, 20, 65, 84, 49, 67, 73, 78, 22,
75, 82, 67, 16, 4, 95, 84, 100, 76, 88, 66, 65, 14, 15, 46, 23,
48, 91, 23, 18, 32, 15, 71, 73, 28, 2, 61, 21, 63, 30, 35, 62, 29,
11, 71, 95, 43, 9, 59, 20, 85, 46, 59, 82, 4, 54, 60, 11, 15, 51,
34, 12, 19, 45, 2, 89, 3, 6, 60, 17, 57, 16, 90, 13, 46, 8,
],
},
{
name: 'Revenue',
data: [
97, 46, 49, 16, 11, 41, 36, 38, 16, 89, 71, 42, 68, 79, 52, 64,
40, 38, 29, 32, 50, 74, 88, 76, 65, 50, 66, 56, 42, 45, 46, 39,
29, 57, 68, 75, 34, 5, 100, 47, 79, 76, 53, 78, 39, 46, 13, 80,
22, 61, 67, 61, 17, 86, 65, 76, 82, 63, 27, 58, 64, 6, 100, 39,
25, 39, 14, 79, 12, 44, 9, 72, 63, 96, 27, 77, 70, 36, 100, 96, 5,
36, 89, 25, 67, 53, 61, 86, 64, 46, 52, 41, 56, 1, 93, 45, 49, 23,
35, 11,
],
},
{
name: 'Free Cash Flow',
data: [
20, 32, 92, 20, 36, 25, 4, 61, 77, 49, 11, 74, 15, 21, 49, 52, 11,
12, 12, 21, 78, 47, 95, 6, 68, 51, 66, 29, 67, 22, 100, 66, 42,
48, 8, 94, 87, 74, 43, 72, 90, 34, 66, 23, 82, 79, 64, 79, 89, 53,
25, 70, 25, 48, 43, 11, 17, 63, 30, 100, 79, 29, 41, 3, 99, 78,
93, 53, 12, 99, 30, 76, 30, 18, 5, 11, 16, 38, 49, 87, 21, 67, 41,
28, 13, 82, 1, 88, 79, 53, 3, 63, 61, 4, 5, 75, 83, 62, 17, 43,
],
},
],
annotations: {
points: [
{
x: 'Bananas',
seriesIndex: 0,
label: {
borderColor: '#775DD0',
offsetY: 0,
style: {
color: '#fff',
background: '#775DD0',
},
text: 'Bananas are good',
},
},
],
},
chart: {
height: 350,
type: 'bar',
},
plotOptions: {
bar: {
columnWidth: '100%',
},
},
dataLabels: {
enabled: false,
},
stroke: {
width: 2,
},
grid: {
row: {
colors: ['#fff', '#f2f2f2'],
},
},
xaxis: {
labels: {
rotate: -45,
},
categories: [
31, 48, 33, 88, 5, 91, 76,
],
tickPlacement: 'on',
},
yaxis: {
title: {
text: 'Servings',
},
},
fill: {
type: 'gradient',
gradient: {
shade: 'light',
type: 'horizontal',
shadeIntensity: 0.25,
gradientToColors: undefined,
inverseColors: true,
opacityFrom: 0.85,
opacityTo: 0.85,
stops: [50, 0, 100],
},
}
};
var chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
</script>
</body>
this is not a complete answer but wanted to share my findings.
IMO the functionality the OP requests should be the default behavior.
regardless, I found that by using the zoomed event, we can find the x-axis range of the zoom.
then remove the data points from the series that are outside of that range and re-draw the chart.
which results in exactly the desired behavior.
however, this kills the ability to zoom out to original series.
to make this work, I think you would need to implement custom zoom buttons,
to allow keeping track of which action occurred, zoom in or out.
this would allow you to know which data points to include when the chart is re-drawn.
you can use the zoomX method to manually set the zoom level.
see following working snippet for zoom-in only functionality.
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Bar with Custom DataLabels</title>
<link href="../../assets/styles.css" rel="stylesheet" />
<style>
#chart {
max-width: 650px;
margin: 35px auto;
}
</style>
<script>
window.Promise ||
document.write(
'<script src="https://cdn.jsdelivr.net/npm/promise-polyfill#8/dist/polyfill.min.js"><\/script>'
);
window.Promise ||
document.write(
'<script src="https://cdn.jsdelivr.net/npm/eligrey-classlist-js-polyfill#1.2.20171210/classList.min.js"><\/script>'
);
window.Promise ||
document.write(
'<script src="https://cdn.jsdelivr.net/npm/findindex_polyfill_mdn"><\/script>'
);
</script>
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<script>
// Replace Math.random() with a pseudo-random number generator to get reproducible results in e2e tests
// Based on https://gist.github.com/blixt/f17b47c62508be59987b
var _seed = 42;
Math.random = function () {
_seed = (_seed * 16807) % 2147483647;
return (_seed - 1) / 2147483646;
};
</script>
</head>
<body>
<div id="chart"></div>
<script>
var data = [
{
name: 'Net Profit',
data: [
95, 4, 48, 95, 71, 16, 44, 98, 75, 94, 28, 61, 76, 1, 54, 90, 19,
5, 37, 57, 88, 31, 41, 59, 27, 96, 20, 65, 84, 49, 67, 73, 78, 22,
75, 82, 67, 16, 4, 95, 84, 100, 76, 88, 66, 65, 14, 15, 46, 23,
48, 91, 23, 18, 32, 15, 71, 73, 28, 2, 61, 21, 63, 30, 35, 62, 29,
11, 71, 95, 43, 9, 59, 20, 85, 46, 59, 82, 4, 54, 60, 11, 15, 51,
34, 12, 19, 45, 2, 89, 3, 6, 60, 17, 57, 16, 90, 13, 46, 8,
],
},
{
name: 'Revenue',
data: [
97, 46, 49, 16, 11, 41, 36, 38, 16, 89, 71, 42, 68, 79, 52, 64,
40, 38, 29, 32, 50, 74, 88, 76, 65, 50, 66, 56, 42, 45, 46, 39,
29, 57, 68, 75, 34, 5, 100, 47, 79, 76, 53, 78, 39, 46, 13, 80,
22, 61, 67, 61, 17, 86, 65, 76, 82, 63, 27, 58, 64, 6, 100, 39,
25, 39, 14, 79, 12, 44, 9, 72, 63, 96, 27, 77, 70, 36, 100, 96, 5,
36, 89, 25, 67, 53, 61, 86, 64, 46, 52, 41, 56, 1, 93, 45, 49, 23,
35, 11,
],
},
{
name: 'Free Cash Flow',
data: [
20, 32, 92, 20, 36, 25, 4, 61, 77, 49, 11, 74, 15, 21, 49, 52, 11,
12, 12, 21, 78, 47, 95, 6, 68, 51, 66, 29, 67, 22, 100, 66, 42,
48, 8, 94, 87, 74, 43, 72, 90, 34, 66, 23, 82, 79, 64, 79, 89, 53,
25, 70, 25, 48, 43, 11, 17, 63, 30, 100, 79, 29, 41, 3, 99, 78,
93, 53, 12, 99, 30, 76, 30, 18, 5, 11, 16, 38, 49, 87, 21, 67, 41,
28, 13, 82, 1, 88, 79, 53, 3, 63, 61, 4, 5, 75, 83, 62, 17, 43,
],
},
];
var options = {
series: data,
annotations: {
points: [
{
x: 'Bananas',
seriesIndex: 0,
label: {
borderColor: '#775DD0',
offsetY: 0,
style: {
color: '#fff',
background: '#775DD0',
},
text: 'Bananas are good',
},
},
],
},
chart: {
height: 350,
id: 'thisChart',
type: 'bar',
events: {
zoomed: function(chartContext, {xaxis, yaxis}) {
console.log('zoom', xaxis);
var newSeries = data.map(function (series) {
var newData = [];
series.data.forEach(function (row, index) {
if ((index >= xaxis.min) && (index <= xaxis.max)) {
newData.push(row);
}
});
return {
name: series.name,
data: newData
};
});
ApexCharts.exec('thisChart', 'updateSeries', newSeries, true);
}
}
},
plotOptions: {
bar: {
columnWidth: '100%',
},
},
dataLabels: {
enabled: false,
},
stroke: {
width: 2,
},
grid: {
row: {
colors: ['#fff', '#f2f2f2'],
},
},
xaxis: {
labels: {
rotate: -45,
},
categories: [
31, 48, 33, 88, 5, 91, 76,
],
tickPlacement: 'on',
},
yaxis: {
title: {
text: 'Servings',
},
},
fill: {
type: 'gradient',
gradient: {
shade: 'light',
type: 'horizontal',
shadeIntensity: 0.25,
gradientToColors: undefined,
inverseColors: true,
opacityFrom: 0.85,
opacityTo: 0.85,
stops: [50, 0, 100],
},
}
};
var chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
</script>
</body>

Do you know why executing the following expressions take more time than the same within a function call in javascript?

I'm trying to compare the difference in terms of execution time in JS between running some expressions sequentially versus running the same expressions within a function call.
Given the following code:
const t1 = Date.now();
console.log(Array.from(Array(500)).map((i, idx) => idx));
const t2 = Date.now();
console.log('t=', t2 - t1, 'ms', t2, t1);
function traverseArrAndPrint() {
console.log(Array.from(Array(500)).map((i, idx) => idx));
}
const t3 = Date.now();
traverseArrAndPrint();
const t4 = Date.now();
console.log('t=', t4 - t3, 'ms', t4, t3);
Now look at the output:
node a.js
[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99,
... 400 more items
]
t= 8 ms 1620926365937 1620926365929
[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99,
... 400 more items
]
t= 1 ms 1620926365938 1620926365937
Why would a function call take less time to execute than the sequential expressions before it?

Nested Arrays inside an object, searching with For loop, giving undefined result

I have editted to upload the complete code to run in any browser. All I'm getting is blanks here, but I am looking for every combination of numbers in groups of 3 from 1-80 (of which there are 82,160 combinations) and I want it to output an array of all of those results. However currently, the array is blank, but if I use my original code which includes a jQuery, it only gives me the last value, 78,79,and 80, over and over again 82160 times. It's giving me the right NUMBER of values, but it isn't filling those values correctly.
<!doctype html>
<html>
<head>
<title>Keno Tracker v2</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
div {
margin: 0em auto;
padding: 00px;
background-color: #fff;
border-radius: 0em;
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
#media (max-width: 700px) {
body {
background-color: #fff;
}
div {
width: auto;
margin: 0 auto;
border-radius: 0;
padding: 0em;
}
}
</style>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>
<body>
<div class="mypanel" style="" id="Heading">Last Draw Result</div>
<div class="mypanel" style="all: unset" id="draw"></div><br>
<div class="mypanel" style="all: unset" id="numbs"></div><br>
<div class="mypanel" style="all: unset" id="bon"></div><br>
<div class="mypanel" style="" id="MostDue">Most Overdue Pairs</div>
<div class="mypanel" style="all: unset" id="mosdu"></div><br>
<div class="mypanel" style="" id="MostFreq">Most Frequent Pairs</div>
<div class="mypanel" style="all: unset" id="mosfq"></div><br>
<div class="mypanel" style="display:none" id="test"></div><br>
<div class="mypanel" style="display:none" id="test2"></div><br>
<script type=text/javascript>
var results = new Object();
results.Num = [12354, 12353, 12352, 12351, 12350, 12349, 12348, 12347, 12346, 12345]
results.Picks = [[1, 2, 4, 6, 8, 9, 13, 15, 38, 39, 22, 25, 65, 44, 66, 75, 80, 34, 12, 77], [5, 2, 4, 38, 39, 7, 8, 9, 18, 14, 23, 25, 65, 44, 66, 75, 80, 34, 12, 77], [1, 2, 3, 7, 9, 10, 14, 15, 26, 21, 63, 41, 67, 71, 38, 39, 79, 32, 17, 72], [11, 12, 14, 16, 18, 19, 13, 15, 26, 27, 61, 43, 62, 72, 79, 38, 39, 37, 10, 74], [1, 2, 4, 6, 8, 9, 13, 15, 22, 25, 65, 44, 66, 75, 80, 38, 39, 34, 12, 77], [2, 3, 5, 7, 9, 10, 14, 16, 23, 26, 67, 45, 66, 76, 1, 38, 39, 35, 13, 78], [10, 22, 19, 1, 8, 9, 37, 4, 11, 5, 20, 14, 3, 35, 38, 39, 41, 74, 57, 61], [1, 2, 4, 6, 8, 9, 13, 15, 22, 25, 65, 44, 66, 75, 80, 38, 39, 34, 12, 77], [1, 2, 4, 6, 8, 9, 13, 15, 22, 25, 65, 44, 66, 75, 80, 38, 39, 34, 12, 77], [1, 2, 4, 6, 8, 9, 13, 15, 22, 25, 65, 44, 66, 75, 80, 38, 39, 34, 12, 77]]
results.Bonus = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
var Totals = new Array();
var temp = new Object();
var drawsdone = 0
var Totsdone = 0
var displayd = 0
function getdraws() {
var results = new Object()
results.Num = [12354, 12353, 12352, 12351, 12350, 12349, 12348, 12347, 12346, 12345]
results.Picks = [[1, 2, 4, 6, 8, 9, 13, 15, 38, 39, 22, 25, 65, 44, 66, 75, 80, 34, 12, 77], [5, 2, 4, 38, 39, 7, 8, 9, 18, 14, 23, 25, 65, 44, 66, 75, 80, 34, 12, 77], [1, 2, 3, 7, 9, 10, 14, 15, 26, 21, 63, 41, 67, 71, 38, 39, 79, 32, 17, 72], [11, 12, 14, 16, 18, 19, 13, 15, 26, 27, 61, 43, 62, 72, 79, 38, 39, 37, 10, 74], [1, 2, 4, 6, 8, 9, 13, 15, 22, 25, 65, 44, 66, 75, 80, 38, 39, 34, 12, 77], [2, 3, 5, 7, 9, 10, 14, 16, 23, 26, 67, 45, 66, 76, 1, 38, 39, 35, 13, 78], [10, 22, 19, 1, 8, 9, 37, 4, 11, 5, 20, 14, 3, 35, 38, 39, 41, 74, 57, 61], [1, 2, 4, 6, 8, 9, 13, 15, 22, 25, 65, 44, 66, 75, 80, 38, 39, 34, 12, 77], [1, 2, 4, 6, 8, 9, 13, 15, 22, 25, 65, 44, 66, 75, 80, 38, 39, 34, 12, 77], [1, 2, 4, 6, 8, 9, 13, 15, 22, 25, 65, 44, 66, 75, 80, 38, 39, 34, 12, 77]]
results.Bonus = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
window.drawsdone = 1
}
function getTotals() {
if (Totsdone == 0){
for (a=1;a<81;a++){
for (b=1;b<81;b++){
if (a<b){
for (c=1;c<81;c++){
if (b<c){
temp.n1 = 0
temp.n2 = 0
temp.n3 = 0
temp.fq123 = 0
temp.sin123 = 0
temp.fq12 = 0
temp.sin12 = 0
temp.fq13 = 0
temp.sin13 = 0
temp.fq23 = 0
temp.sin23 = 0
temp.fq1 = 0
temp.sin1 = 0
temp.fq2 = 0
temp.sin2 = 0
temp.fq3 = 0
temp.sin3 = 0
for (i in results.Picks){
if (results.Picks[i].includes(a)){
if (results.Picks[i].includes(b)){
if (results.Picks[i].includes(c)){
if (temp.sin123 == 0){
temp.sin123 = results.Num[0]-results.Num[i]
}
temp.fq123++
temp.n1=a
temp.n2=b
temp.n3=c
}
}
}
}
Totals.push(temp)
}
}
}
}
}
window.Totsdone = 1
}
}
function display(){
if (displayd == 0){
console.log(Totals)
Totals = new Array()
window.displayd = 1
}
}
getdraws();
setInterval(function(){
getTotals()},2000)
setInterval(function(){
display()},3000)
</script>
</body>
</html>
Because your for-loop has a hardcoded second condition of i<20 and your Picks array only has 10 items, e.g. from the 11th item onwards you'll get undefined...
EDIT: Updated answer based on the updated question.
Still not sure about the entire logic of your code, but regarding
I am looking for every combination of numbers in groups of 3 from 1-80 (of which there are 82,160 combinations) and I want it to output an array of all of those results.
I think this might be a more elegant solution:
function* generateDraws(pool, size) {
if (size < 1) {
yield [];
} else {
for (let i = size; i <= pool; i++) {
for (let tail of generateDraws(i - 1, size - 1)) {
tail.push(i);
yield tail;
}
}
}
}
let draws = [];
for (let draw of generateDraws(80, 3)) {
draws.push(draw);
}
console.log(draws.length);
//console.log(draws); // will not work in stackoverflow snippet runner, does in the browser though!
When dealing with large iterations like that (as you say, it's 82160 combinations, e.g. 80!/(3!(80-3)!) things have a potential get quite slow, so using a generator function seems to be most appropriate as it will run with constant memory usage.
also be aware that generator functions are modern JS, so if you actually need to run this code client side and your users use old browser you need to transpile it with babel or typescript first OR generate the draws server-side and fetch them in your app from the server.
hope it helps at least a bit!

Javascript declare multiple variables with the same values

Maybe I should use some kind of loop or something. But I don't have any idea how to declare this, excluding do it manually.
Is there any solution that will have only a few lines for all of this. Because, there should be 100 variable, despite I only presented 5, I didn't want to type all night.
a1=1; a2=1; a3=1; a4=1; a5=1;
function myfn1() {
a1++;
//unique function code
}
function myfn2() {
a2++;
//unique function code
}
function myfn3() {
a3++;
//unique function code
}
function myfn4() {
a4++;
//unique function code
}
function myfn5() {
a5++;
//unique function code
}
Although this isn't answering your question, I think this approach will help you more in the long run (and probably in the short run too). Check out using an array, which is just a collection of data. Check out the following code.
var arr = [];
for(var i =0; i <= 100; i++){
arr[i] = i;
}
this gives you a collection like this [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100] that you can then manipulate, etc etc.
*edit or if you want them all to have the same value, then
var arr = [];
for(var i =0; i <= 100; i++){
arr[i] = 1;
}

How to do statistical classification on an array in javascript?

I've got a bunch of numbers in an array and I need to do some statistics on them. I need to know how many of each number there are in the array.
Here's the array:
myArray =
[2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 27, 27, 28, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 34, 34, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 40, 40, 40, 41, 41, 42, 42, 42, 42, 42, 42, 43, 43, 43, 44, 44, 44, 44, 44, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 55, 55, 55, 55, 55, 56, 57, 57, 57, 57, 57, 57, 57, 58, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 61, 61, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 68, 69, 69, 69, 69, 69, 69, 70, 70, 71, 71, 71, 71, 71, 71, 71, 72, 73, 73, 73, 73, 74, 74, 74, 75, 75, 75, 76, 77, 78, 78, 79, 79, 80, 80, 81, 81, 81, 81, 81, 82, 82, 82, 82, 83, 83, 83, 83, 84, 84, 84, 85, 85, 85, 85, 85, 86, 86, 86, 86, 86, 86, 87, 87, 87, 88, 88, 89, 89, 90, 90, 91, 91, 91, 92, 93, 94, 95, 95, 95, 95, 95, 96, 96, 96, 96, 97, 97, 99, 99, 99, 99, 99, 101, 101, 102, 102, 103, 103, 105, 105, 105, 106, 107, 107, 108, 108, 109, 109, 109, 109, 110, 112, 112, 113, 113, 113, 114, 114, 115, 116, 116, 117, 118, 120, 121, 121, 121, 122, 122, 123, 123, 123, 124, 124, 124, 124, 125, 126, 127, 128, 129, 130, 130, 131, 131, 131, 131, 132, 133, 133, 134, 134, 134, 136, 136, 136, 136, 137, 137, 137, 138, 138, 138, 139, 139, 139, 140, 141, 141, 142, 142, 143, 144, 144, 144, 144, 145, 150, 150, 153, 155, 159, 160, 160, 161, 162, 164, 164, 166, 176, 180, 180, 180, 181, 181, 187, 191, 192, 193, 194, 197, 200, 203, 211, 216, 224, 251, 280, 333]
Here's what I'm using to parse through it currently (which is not working very well):
for (var key in myArray){
var obj = myArray[key];
var count = 0;
while(obj < 30){
myArrayStats[0] = count;
obj++;
}
while(obj > 30 && obj < 40){
myArrayStats[1] = count;
obj++;
}
//etc....
}
Creating a new array using object literals would be much nicer and easier to use, but I'm not sure how to do it.
This just works whether your array is sorted or not, but it shouldn't be much slower than any algorithm that takes advantage of the fact that it is sorted anyways:
var myArrayStats = [];
for(var i = myArray.length; i--;)
myArrayStats[myArray[i]] = (myArrayStats[myArray[i]] || 0) + 1;
console.log(myArrayStats[6]); // Outputs 7
console.log(myArrayStats[10]); // Outputs 5
console.log(myArrayStats[20]); // Outputs 5
If you want to do this for only a portion of the original array than use slice() to get the portion of the array you want and then do the same thing as above on that array:
var mySubArray = myArray.slice(0,30);
var myArrayStats = [];
for(var i = mySubArray.length; i--;)
myArrayStats[mySubArray[i]] = (myArrayStats[mySubArray[i]] || 0) + 1;
console.log(myArrayStats[6]); // Outputs 7
console.log(myArrayStats[9]); // Outputs 7
console.log(myArrayStats[10]); // Outputs undefined
It sounds like you have equally spaced bins and want to count how many values fall in each. Since this question was tagged with jQuery, let's use a utility function from that to avoid an explicit loop to show another way to do things. (I guess PaulPRO's approach is superior though.)
function hist(values, min, max, numBins) {
var bins = [];
var range = max - min;
jQuery.each(values, function(i, value) {
var bin = Math.floor(numBins * (value - min) / range);
bin = Math.min(Math.max(bin, -1), numBins) + 1;
bins[bin] = (bins[bin] || 0) + 1;
});
return bins;
}
We can exercise the above code with the following:
function consoleHist(values, min, max, numBins) {
var bins = hist(values, min, max, numBins);
var step = (max - min) / numBins;
jQuery.each(bins, function(i, count) {
var lower = (i - 1) * step + min;
var upper = lower + step;
if (lower < min) {
lower = -Infinity;
}
if (upper > max) {
upper = Infinity;
}
console.log('[' + lower + ', ' + upper + '): ' + (count || 0));
});
}
consoleHist([-10, 0, 11, 29, 30, 59, 60, 1000], 0, 60, 2);
Produces the following output on the console:
[-Infinity, 0): 1
[0, 30): 3
[30, 60): 2
[60, Infinity): 2
myArray = [2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8,
8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11,
11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 14, 14]
for (var a = myArray, b = {}, i = 0; i < myArray.length; i++) b[a[i]] ? b[a[i]]++ : b[a[i]] = 1;
console.log(JSON.stringify(Object.keys(b)
.map(function(c) {
return [c, b[c]]
})));

Categories

Resources