A little help on this code, please

Hi everyone, I am trying to generate 20 squares with random x and y values between 0 and 100. However, this code does nothing. @Grasshopper_Ben, you wouldn’t have the time to see what is wrong with that code, would you?

var h = 300;
var w = 600;

var svg = d3.select('body').append('svg').attr('width', h).attr('height', h);
var x = [];
var y = [];

function createRect () {
for (var i = 0; i < 101; i++) {
x.push(i);
y.push(i);
}
randomControl();
var counter = 1
function randomControl () {
if (counter < 21) {
counter ++
random();
randomControl();
}
}
}

function random () {
let randomX = Math.floor(Math.random() * x.length);
let randomY = Math.floor(Math.random() * y.length);
var rectangle = svg.append('rect').attr('height', 10).attr('width', 10).attr('fill', 'blue').attr('x', randomX).attr('y', randomY)
}

createRect()

Hey there, looks cool! What might help is to walk through the code bit by bit:. Let’s look at the createRect() function:

First, this for loop pushes the numbers 0 to 100 to the x and y arrays:

for (var i = 0; i < 101; i++) {
  x.push(i);
  y.push(i);
}

Then, the randomControl() function is called:

randomControl()

The function then runs its code. This function first checks if counter is less than 21:

if (counter < 21) {
  counter++
  random();
  randomControl();
}

This is false, because counter is undefined when the function is called. So the if statement will not run its code.

Next, counter is declared:

var counter = 1

The function then exits, as there is no more code to run.

This type of walk-through debugging is called “rubber ducking”. It’s a good way to figure out what your code is doing.

Hope this helps!
Ben

3 Likes

Thank you for this reply, I’ll look into it, right now.

It worked, thank you. :smile:

I may need your help on that code again because I am still working on it. :sweat_smile:

No problem! Feel free to post the code again.

Hello, When I click the button I want a new combination of squares to be displayed, however, something else happened and I do not know why. See by yourself, here is the code(It’s the same code I’ve just changed the name of the functions because their last names didn’t really reflect what each function does):

var h = 600;
var w = 600;

var svg = d3.select('body').append('svg').attr('width', h).attr('height', h);
var backGround
var x = [];
var y = [];
var color = ['red', 'blue', 'violet', 'DarkMagenta', 'aquamarine', 'salmon'];
function initiateRectsCreation () {
for (var i = 0; i < 101; i++) {
x.push(i);
y.push(i);
}
var counter = 1;
numberOfRects();

function numberOfRects () {
if (counter < 21) {
counter ++;
rectsCreation();
numberOfRects();
}
}
}

function rectsCreation () {
let randomX = Math.floor(Math.random() * x.length);
let randomY = Math.floor(Math.random() * y.length);
let randomColorIndex = Math.floor(Math.random() * color.length);
var rectangle = svg.append('rect').attr('height', 10).attr('width', 10).attr('fill', color[randomColorIndex]).attr('x', randomX * 3).attr('y', randomY * 3);
}

initiateRectsCreation();

var number = 0;
let button = document.createElement('button');
button.textContent = 'Reload';
document.body.appendChild(button);
button.addEventListener('click', () => {
if (button.textContent === 'Reload') {
    number ++;
button.textContent = 'Reload: ' + number + ' time';
}else{
number ++;
button.textContent = 'Reload: ' + number + ' times';
}

var rectangles = d3.selectAll('rect');
rectangles.remove();
initiateRectsCreation();
});

Take a look at the code in ‘‘Gallery’’.

Very cool!

It looks like it’s working, but the rectangles are just offscreen and need to be scrolled to. This is because of the svg variable declaration. There’s already an svg element added to the webview by the app, so the svg you’ve create in the code is being added below that.

I deleted that line, and the background variable declaration. I also added a little CSS to the button to make it appear a bit higher on the webview.

Here’s a link to the snippet!

Nice work!
Ben

1 Like

Thank you, I’ll look at the code

Oh, now I understand why the rectangles were down there.:partying_face:

However, when I click on the button I created, instead of getting a new combination of the rectangles, they tend to disappear:thinking:. Try the button a few times you’ll see what I mean.

What I want is for the “reload button” to act (in a way) as the “Run Code” button.

Ps: Thanks for moving the button, I was wondering how to do that directly in JS.

I think the issue might be that the rectangles are being drawn somewhere outside the screen of the webview (the phone screen where you see the code output). Try playing around with the code that determines the x and y coordinates of the rectangles.

To help you figure out the max values, try adding the following code:

console.log(window.innerWidth)
console.log(window.innerHeight)

Any x coordinate that is greater than window.innerWidth will appear offscreen to the right.
Any y coordinate that is greater than window.innerHeight will appear below the screen.

Try adjusting the math to make sure the coordinates stay within these bounds.

Good luck!

2 Likes

I’ll do that, thanks.

Looks like the x and y attributes keep getting higher and higher everytime the button is clicked.

Whenever you click the button, the initiateRectsCreation() function runs. This function adds 100 elements to both the x and y arrays. So each time you click the button, the arrays grow by 100 elements each. This means the x.length and y.length you’re using to calculate the coordinates are growing as well, making the rectangles gradually appear offscreen.

Try moving the arrays into the function, before the for loop. This means that they’ll be created and then destroyed every time you press Reload, and won’t exceed 100 elements.

Moving these declarations into the initiateRectsCreation() function will break your other functions that rely on seeing the x and y arrays, so you’ll have to do some minor refactoring there to get things working again. Try passing the values in as parameters.

Hope this helps!

3 Likes

At last the code is how I want it to be. Thanks a lot for your help, I really appreciate it.:partying_face::partying_face::grin:

3 Likes

Try setting ur var equals to 0…