Saturday, December 28, 2024
Google search engine
HomeLanguagesJavascriptSliding Window Visualizer using HTML CSS and JavaScript

Sliding Window Visualizer using HTML CSS and JavaScript

Window sliding technique is used extensively in array problems and used a lot in subarray-related problems like subarray sum etc. In this article, we will understand how Sliding Window Visualizer works along with knowing the basic implementation of the visualizer.

Window sliding technique is an efficient way to calculate and solve problems with contiguous elements in an array with fixed-sized windows. Window sliding techniques are used in subarray problems and problems where we need to focus on the particular window of the problem statement. Understanding this algorithm is very important because it deals with major problem statements out there. 

Pre-requisite knowledge: HTML, CSS, Javascript

We can use the window-sliding technique when we need to work with a set of elements, which can be an array, string, or any other structure and we need to get an output with a fixed-size window inside a particular structure like an array, string, etc. 

For example with arrays:

/* K is the size of the window and we need 
to find the maximum sum in that window */
Input  : arr[] = {100, 200, 300, 400}, k = 2
Output : 700

Input  : arr[] = {1, 4, 2, 10, 23, 3, 1, 0, 20}, k = 4 
Output : 39
/* We get maximum sum by adding subarray 
{4, 2, 10, 23} of size 4 */

Input  : arr[] = {2, 3}, k = 3
Output : Invalid
/* There is no subarray of size 3 as 
size of whole array is 2 */

For example with strings:

/* Find the sum 299 in ASCII values
in contiguous form fixed sized */
window of 3 inside a string

string s : abadfg
sum : 299;
Output : Found

The basic idea of the window sliding technique is to remove elements that should be not there in the new window and add new elements to the window to make the new window.

Stepwise implementation for Visualizer:  To make the visualizer, we will follow the below steps:

Step 1: We need to now understand the HTML part of how we made the containers in HTML in order to divide we made a container that holds all of our elements like a displayer which holds elements that are to be displayed on the screen and then we have pattern and pattern text a message div where pattern displays the array and pattern text holds the message like maximum sum current sum, we have start button which at the end begins the algorithm visualization when clicked.

  • Index.html

HTML




<!DOCTYPE html>
<html lang="en">
  
<head>
    <meta name="viewport" content=
        "width=device-width, initial-scale=1.0">
    <link href=
"https://fonts.googleapis.com/css2?family=Open+Sans:wght@300&display=swap" 
          rel="stylesheet" />
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
    <title>Document</title>
</head>
  
<body>
    <h1>
        <span class="1">S</span>liding 
        <span class="2">W</span>indow 
        <span class="3">T</span>echnique
        <span>Visualizer</span>
    </h1>
    <div id="message">
        We will find the maximum sum in array using 
        sliding window technique in certain sized 
        window when window size is 4
    </div>
    <div id="container">
        <div id="displayer">
            <div id="pattern"></div>
            <div id="pattern_text"></div>
        </div>
          
        <div id="start">Begin</div>
    </div>
</body>
  
</html>


 

Step 2: We will have a black background, so we gave the text color white to every element so that it will be visible, and then for the span, we have to make it glow, so we give a text-shadow that we set our HTML background color and font family. Now, for the body, we make sure everything remains centered and set flex-direction as a center and for the container. Also, we give it some position same goes for the container we give it a letter spacing so that it looks neat. We make a tile, and make sure every element displayed is with tile for symmetric. We set it on hover and change color to cyan and then we style every element for its positions. When we iterate over the array elements we make sure that the color of the array element iterator is shown with different color which is red and when the element is added to the window then we highlight it with green color and when highlighting the element that is to be removed with red color, Window is shown with white color.

  • style.css

CSS




* {
    color: white;
    font-family: "Open sans", sans-serif;
}
  
html {
    background-color: black;
}
  
body {
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 100vmin;
}
  
h1 span {
    font-size: 6vmin;
    font-weight: normal;
    text-shadow: 0 0 20px cyan,
        0 0 40px cyan,
        0 0 80px cyan;
}
  
#container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 80%;
    width: 80%;
}
  
#displayer {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
    height: 90%;
}
  
#pattern,
#message {
    width: 100%;
    height: 7vmin;
    margin: 3vmin;
    font-size: 5vmin;
    display: flex;
    align-items: center;
    justify-content: center;
}
  
#message {
    color: cyan;
    font-size: 2vmin;
}
  
#pattern_text {
    width: 100%;
    height: 5vmin;
    margin: 3vmin;
    font-size: 5vmin;
    display: flex;
    align-items: center;
    justify-content: center;
    color: g;
}
  
#pattern_text {
    width: 100%;
    height: 5vmin;
    margin: 3vmin;
    font-size: 5vmin;
    display: flex;
    align-items: center;
    justify-content: center;
    color: g;
}
  
.tile {
    width: 6vmin;
    height: 6vmin;
    margin: 10px;
    text-align: center;
    height: fit-content;
    border: 2px pink;
}
  
#start {
    align-self: center;
    background-color: black;
    font-size: 3vmin;
    box-sizing: border-box;
    padding: 1vmin;
    color: white;
    cursor: pointer;
    border: none;
    margin-top: 2vmin;
    transition: 0.5s ease-in-out;
    font-weight: bold;
    letter-spacing: 4px;
}
  
#start:hover {
    transform: scale(1.5);
    text-shadow: 0 0 10px cyan,
        0 0 20px cyan,
        0 0 40px cyan;
}
  
h1 {
    margin-top: 0;
    text-align: center;
    padding: 1vmin;
    margin-bottom: 1vmin;
    width: 100%;
    font-size: 5vmin;
    font-weight: normal;
    letter-spacing: 2px;
    border-bottom: 1px solid white;
}


 

Step 3: In JavaScript, when we load the window for the first time, we see the begin button to start the visualization. After that, we have an array as max_sum and current_sum, and the window size is shown with white color and the iterator is shown with red color. The max_sum, & the current_sum are calculated and shown below in the array. We used async await to show the actual visualization smoothly by creating a delay. At first, we compare the 1st window calculate the sum and then keep the max_sum as the current_sum. Now, for the 2nd window, we find the current_sum of the second window and compare it to max_sum, if the 2nd window’s current_sum is bigger than the max_sum, we give max_sum the value of 2nd window’s current_sum, and so on, it goes at the end of the complete iteration. We get the max_sum of the fixed-size window i.e 4 in this case.

  • script.js:

Javascript




function id(id) {
    return document.getElementById(id);
}
var count = 0;
var pattern, text, Psize, Tsize;
var idcountrater = 0;
var conti = 0;
const slidingWindowTech = async (pattern, Psize, sum, k) => {
    console.log("hola")
    var max_sum = 0;
    let maxi = document.createElement('div');
    maxi.id = "message";
    maxi.classList.add("message");
    maxi.innerText = `MaximumSum is ${max_sum}`
    console.log(maxi)
    id("pattern_text").appendChild(maxi);
    let current_sum = 0;
    let current = document.createElement('div');
    current.id = "message";
    current.classList.add("message");
    current.innerText = `CurrentSum is ${current_sum}`
    id("pattern_text").appendChild(current);
    for (let i = 0; i < Psize - k + 1; i++) {
        await new Promise((resolve) =>
            setTimeout(() => {
                resolve();
            }, 1000)
        )
        console.log(i + " " + (i + k - 1));
        id(i).style.borderLeft = "2px solid white"
        id(i).style.borderTop = "2px solid white"
        id(i).style.borderBottom = "2px solid white"
        id(i + 1).style.borderBottom = "2px solid white"
        id(i + 1).style.borderTop = "2px solid white"
        id(i + 2).style.borderTop = "2px solid white"
        id(i + 2).style.borderBottom = "2px solid white"
        id((i + k - 1)).style.borderRight = "2px solid white";
        id(i + k - 1).style.borderTop = "2px solid white"
        id(i + k - 1).style.borderBottom = "2px solid white"
        if (i != 0) {
            // current_sum=current_sum-pattern[i-1]
            id(i - 1).style.color = "Red"
            await new Promise((resolve) =>
                setTimeout(() => {
                    resolve();
                }, 1000)
            )
            current_sum = current_sum - pattern[i - 1]
            current.innerText =
                `CurrentSum after subtracting ${i - 1}th ` +
                `element from ${i} window is ${current_sum}`
            id(i - 1).style.color = "white"
            await new Promise((resolve) =>
                setTimeout(() => {
                    resolve();
                }, 1000)
            )
            id(i + k - 1).style.color = "green"
            await new Promise((resolve) =>
                setTimeout(() => {
                    resolve();
                }, 1000)
            )
            current_sum = current_sum + pattern[i + k - 1]
            current.innerText =
`CurrentSum after adding ${i + k - 1}th in ${i} window is ${current_sum}`
            id(i + k - 1).style.color = "white"
            await new Promise((resolve) =>
                setTimeout(() => {
                    resolve();
                }, 1000)
            )
        }
        else {
            for (let j = 0; j < k; j++) {
                console.log("hola 1 " + current_sum)
                id((i + j)).style.color = "Red"
                await new Promise((resolve) =>
                    setTimeout(() => {
                        resolve();
                    }, 1000)
                )
                current_sum = current_sum + pattern[i + j];
                current.innerText =
                    `CurrentSum is for ${i}th window ${current_sum}`
                await new Promise((resolve) =>
                    setTimeout(() => {
                        resolve();
                    }, 1000)
                )
                id((i + j)).style.color = "white"
            }
        }
        id(i).style.borderLeft = "none"
        id(i).style.borderTop = "none"
        id(i).style.borderBottom = "none"
        id(i + 1).style.borderBottom = "none"
        id(i + 1).style.borderTop = "none"
        id(i + 2).style.borderTop = "none"
        id(i + 2).style.borderBottom = "none"
        id((i + k - 1)).style.borderRight = "none";
        id(i + k - 1).style.borderTop = "none"
        id(i + k - 1).style.borderBottom = "none"
        console.log(current_sum)
  
        // Update result if required.
        // max_sum = max(current_sum, max_sum);
        if (current_sum > max_sum) max_sum = current_sum;
        maxi.innerText = `MaximumSum is ${max_sum}`
    }
    current.style.display = "none"
}
let idcount = 0;
window.onload = async () => {
    id("displayer").style.display = "none";
    id("start").addEventListener('click', () => {
        id("start").style.display = "none"
        id("displayer").style.display = "flex";
        pattern = [1, 4, 2, 10, 2, 3, 1, 0, 20]
        Psize = 9
        sum = 24
        let idcount1 = 0;
        for (let i = 0; i < Psize; i++) {
            let tile = document.createElement('span');
            tile.id = idcount;
            tile.classList.add("tile");
            tile.innerText = pattern[i];
            id("pattern").appendChild(tile);
            idcount++;
        }
        slidingWindowTech(pattern, Psize, sum, 4)
    })
}


Output:

Sliding window visualization

Whether you’re preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape, neveropen Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we’ve already empowered, and we’re here to do the same for you. Don’t miss out – check it out now!

RELATED ARTICLES

Most Popular

Recent Comments