Преглед изворни кода

Completely replace the analytics strand file.
Create new backend function for getting data for the analytics page.
Not completed: displaying information in the boxes at the bottom of the page.
Not completed: submiting custom dates for the data.

Lee Morgan пре 5 година
родитељ
комит
b3d665b69d

+ 60 - 0
controllers/transactionData.js

@@ -55,6 +55,66 @@ module.exports = {
             });
     },
 
+    /*
+    GET - get transactions between two dates, sorted and group by date
+    params:
+        from: Date string
+        to: Date string
+    return:
+        [{
+            date: Date
+            transactions:[[Recipe]]
+        }]
+    */
+    getTransactionsByDate: function(req, res){
+        if(!req.session.user){
+            req.session.error = "MUST BE LOGGED IN TO DO THAT";
+            return res.redirect("/");
+        }
+
+        const from = new Date(req.params.from);
+        const to = new Date(req.params.to);
+
+        Transaction.aggregate([
+            {$match: {
+                merchant: ObjectId(req.session.user),
+                date: {
+                    $gte: from,
+                    $lt: to
+                }
+            }},
+            {$group: {
+                _id: {$function: {
+                    body: "function(year, month, date){return `${year}-${month}-${date}`;}",
+                    args: [{$year: "$date"}, {$month: "$date"}, {$dayOfMonth: "$date"}],
+                    lang: "js"
+                }},
+                transactions: {$push: {
+                    _id: "$_id",
+                    recipes: "$recipes"
+                }}
+            }},
+            {$project: {
+                _id: 0,
+                date: {$convert: {
+                    input: "$_id",
+                    to: "date"
+                }},
+                transactions: 1
+            }},
+            {$sort: {
+                date: 1
+            }}
+        ])
+            .then((transactions)=>{
+                return res.json(transactions);
+            })
+            .catch((err)=>{
+                console.log(err);
+                return res.json("ERROR: UNABLE TO RETRIEVE DATA");
+            });
+    },
+
     /*
     POST - create a new transaction
     req.body = {

+ 1 - 0
routes.js

@@ -47,6 +47,7 @@ module.exports = function(app){
 
     //Transactions
     app.post("/transaction", transactionData.getTransactions);
+    app.get("/transactions/:from/:to", transactionData.getTransactionsByDate);
     app.post("/transaction/create", transactionData.createTransaction);
     app.delete("/transaction/:id", transactionData.remove);
     app.get("/populatesometransactions", transactionData.populate);

+ 136 - 256
views/dashboardPage/bundle.js

@@ -1270,6 +1270,24 @@ class Transaction{
     get recipes(){
         return this._recipes;
     }
+
+    /*
+    Gets the quantity for a given ingredient
+    */
+    getIngredientQuantity(ingredient){
+        let quantity = 0;
+
+        for(let i = 0; i < this._recipes.length; i++){
+            const recipe = this._recipes[i].recipe;
+            for(let j = 0; j < recipe.ingredients.length; j++){
+                if(recipe.ingredients[j].ingredient === ingredient){
+                    quantity += recipe.ingredients[j].quantity;
+                }
+            }
+        }
+
+        return quantity;
+    }
 }
 
 module.exports = Transaction;
@@ -1277,7 +1295,7 @@ module.exports = Transaction;
 const home = require("./strands/home.js");
 const ingredients = require("./strands/ingredients.js");
 const recipeBook = require("./strands/recipeBook.js");
-const analytics = require("./strands/analytics.js");
+const analytics = require("./strands/analytics2.js");
 const orders = require("./strands/orders.js");
 const transactions = require("./strands/transactions.js");
 
@@ -1564,7 +1582,7 @@ document.getElementById("ordersBtn").onclick = async ()=>{
 document.getElementById("transactionsBtn").onclick = ()=>{controller.openStrand("transactions", merchant.getTransactions())};
 
 controller.openStrand("home");
-},{"./classes/Ingredient.js":1,"./classes/Merchant.js":2,"./classes/Order.js":3,"./classes/Recipe.js":4,"./classes/Transaction.js":5,"./sidebars/editIngredient.js":7,"./sidebars/editRecipe.js":8,"./sidebars/ingredientDetails.js":9,"./sidebars/newIngredient.js":10,"./sidebars/newOrder.js":11,"./sidebars/newRecipe.js":12,"./sidebars/newTransaction.js":13,"./sidebars/orderDetails.js":14,"./sidebars/orderFilter.js":15,"./sidebars/recipeDetails.js":16,"./sidebars/transactionDetails.js":17,"./sidebars/transactionFilter.js":18,"./strands/analytics.js":19,"./strands/home.js":20,"./strands/ingredients.js":21,"./strands/orders.js":22,"./strands/recipeBook.js":23,"./strands/transactions.js":24}],7:[function(require,module,exports){
+},{"./classes/Ingredient.js":1,"./classes/Merchant.js":2,"./classes/Order.js":3,"./classes/Recipe.js":4,"./classes/Transaction.js":5,"./sidebars/editIngredient.js":7,"./sidebars/editRecipe.js":8,"./sidebars/ingredientDetails.js":9,"./sidebars/newIngredient.js":10,"./sidebars/newOrder.js":11,"./sidebars/newRecipe.js":12,"./sidebars/newTransaction.js":13,"./sidebars/orderDetails.js":14,"./sidebars/orderFilter.js":15,"./sidebars/recipeDetails.js":16,"./sidebars/transactionDetails.js":17,"./sidebars/transactionFilter.js":18,"./strands/analytics2.js":19,"./strands/home.js":20,"./strands/ingredients.js":21,"./strands/orders.js":22,"./strands/recipeBook.js":23,"./strands/transactions.js":24}],7:[function(require,module,exports){
 let editIngredient = {
     display: function(ingredient){
         let buttonList = document.getElementById("unitButtons");
@@ -2841,155 +2859,109 @@ let transactionFilter = {
 module.exports = transactionFilter;
 },{}],19:[function(require,module,exports){
 let analytics = {
-    newData: false,
-    dateChange: false,
-    transactions: [],
-    ingredient: {},
-    recipe: {},
-
-    display: function(Transaction){
-        document.getElementById("analDateBtn").onclick = ()=>{this.changeDates(Transaction)};
+    isPopulated: false,
+    recipesDisplay: false,
+    transactionsByDate: [],
 
-        if(this.transactions.length === 0 || this.newData === true){
-            let startDate = new Date();
-            startDate.setMonth(startDate.getMonth() - 1);
-            this.transactions = merchant.getTransactions(startDate);
-        }
+    display: async function(Transaction){
+        if(!this.isPopulated){
+            let to = new Date()
+            let from = new Date(to.getFullYear(), to.getMonth() - 1, to.getDate());
+            await this.getData(from, to, Transaction);
 
-        let slider = document.getElementById("analSlider");
-        slider.onchange = ()=>{this.display(Transaction)};
+            let analSlider = document.getElementById("analSlider");
+            analSlider.onclick = ()=>{this.switchDisplay()};
+            analSlider.checked = false;
+            document.getElementById("analRecipeContent").style.display = "none";
 
-        let ingredientContent = document.getElementById("analIngredientContent");
-        let recipeContent = document.getElementById("analRecipeContent");
 
-        if(slider.checked){
-            ingredientContent.style.display = "none";
-            recipeContent.style.display = "flex";
-            this.displayRecipes();
-        }else{
-            ingredientContent.style.display = "flex";
-            recipeContent.style.display = "none"
-            this.displayIngredients();
+            this.populateButtons();
+            this.displayIngredient(merchant.ingredients[0].ingredient);
+            this.displayRecipe(merchant.recipes[0]);
+            
+            this.isPopulated = true;
         }
     },
 
-    displayIngredients: function(){
-        const itemsList = document.getElementById("itemsList");
-
-        while(itemsList.children.length > 0){
-            itemsList.removeChild(itemsList.firstChild);
-        }
+    populateButtons: function(){
+        let ingredientButtons = document.getElementById("analIngredientList");
+        let recipeButtons = document.getElementById("analRecipeList");
 
         for(let i = 0; i < merchant.ingredients.length; i++){
-            let li = document.createElement("li");
-            li.classList.add("choosable");
-            li.item = merchant.ingredients[i];
-            li.innerText = merchant.ingredients[i].ingredient.name;
-            li.onclick = ()=>{
-                const itemsList = document.getElementById("itemsList");
-                for(let i = 0; i < itemsList.children.length; i++){
-                    itemsList.children[i].classList.remove("active");
-                }
-
-                li.classList.add("active");
-
-                this.ingredient = merchant.ingredients[i];
-                this.ingredientDisplay();
-            };
-            itemsList.appendChild(li);
-        }
-
-        if(this.dateChange && Object.keys(this.ingredient).length !== 0){
-            this.ingredientDisplay();
-        }
-        this.dateChange = false;
-    },
-
-    displayRecipes: function(){
-        let recipeList = document.getElementById("analRecipeList");
-        while(recipeList.children.length > 0){
-            recipeList.removeChild(recipeList.firstChild);
+            let button = document.createElement("button");
+            button.innerText = merchant.ingredients[i].ingredient.name;
+            button.classList.add("choosable");
+            button.onclick = ()=>{this.displayIngredient(merchant.ingredients[i].ingredient)};
+            ingredientButtons.appendChild(button);
         }
 
         for(let i = 0; i < merchant.recipes.length; i++){
-            let li = document.createElement("li");
-            li.classList.add("choosable");
-            li.recipe = merchant.recipes[i];
-            li.innerText = merchant.recipes[i].name;
-            li.onclick = ()=>{
-                let recipeList = document.getElementById("analRecipeList");
-                for(let i = 0; i < recipeList.children.length; i++){
-                    recipeList.children[i].classList.remove("active");
-                }
-                li.classList.add("active");
-
-                this.recipe = merchant.recipes[i];
-                this.recipeDisplay();
-            }
-
-            recipeList.appendChild(li);
-        }
-
-        if(this.dateChange  && Object.keys(this.recipe).length !== 0){
-            this.recipeDisplay();
+            let button = document.createElement("button");
+            button.innerText = merchant.recipes[i].name;
+            button.classList.add("choosable");
+            button.onclick = ()=>{this.displayRecipe(merchant.recipes[i])};
+            recipeButtons.appendChild(button);
         }
-        this.dateChange = false;
     },
 
-    ingredientDisplay: function(){
-        //Get list of recipes that contain the ingredient
-        let containingRecipes = [];
+    getData: function(from, to, Transaction){
+        let loader = document.getElementById("loaderContainer");
+        loader.style.display = "flex";
 
-        for(let i = 0; i < merchant.recipes.length; i++){
-            for(let j = 0; j < merchant.recipes[i].ingredients.length; j++){
-                if(merchant.recipes[i].ingredients[j].ingredient === this.ingredient.ingredient){
-                    containingRecipes.push({
-                        recipe: merchant.recipes[i],
-                        quantity: merchant.recipes[i].ingredients[j].quantity
-                    });
+        return fetch(`/transactions/${from.toISOString()}/${to.toISOString()}`)
+            .then(response => response.json())
+            .then((response)=>{
+                if(typeof(response) === "string"){
+                    banner.createError(response);
+                }else{
+                    this.transactionsByDate = [];
 
-                    break;
+                    for(let i = 0; i < response.length; i++){
+                        const date = new Date(response[i].date);
+                        let newDate = {
+                            date: date,
+                            transactions: []
+                        };
+
+                        for(let j = 0; j < response[i].transactions.length; j++){
+                            newDate.transactions.push(new Transaction(
+                                response[i].transactions[j]._id,
+                                date,
+                                response[i].transactions[j].recipes,
+                                merchant
+                            ));
+                        }
+
+                        this.transactionsByDate.push(newDate);
+                    }
                 }
-            }
-        }
+            })
+            .catch((err)=>{
+                banner.createError("UNABLE TO UPDATE THE PAGE");
+            })
+            .finally(()=>{
+                loader.style.display = "none";
+            });
+    },
 
-        //Create Graph
-        let quantities = [];
+    displayIngredient: function(ingredient){
+        //break down data into dates and quantities
         let dates = [];
-        let currentDate = (this.transactions.length > 0) ? this.transactions[0].date : undefined;
-        let currentQuantity = 0;
-
-        for(let i = 0; i < this.transactions.length; i++){
-            if(currentDate.getDate() !== this.transactions[i].date.getDate()){
-                quantities.push(currentQuantity);
-                dates.push(currentDate);
-                currentQuantity = 0;
-                currentDate = this.transactions[i].date;
-            }
-
-            for(let j = 0; j < this.transactions[i].recipes.length; j++){
-                for(let k = 0; k < containingRecipes.length; k++){
-                    if(this.transactions[i].recipes[j].recipe === containingRecipes[k].recipe){
-                        for(let l = 0; l < this.transactions[i].recipes[j].recipe.ingredients.length; l++){
-                            const transIngredient = this.transactions[i].recipes[j].recipe.ingredients[l];
-
-                            if(transIngredient.ingredient === this.ingredient.ingredient){
-
-                                currentQuantity += transIngredient.quantity * this.transactions[i].recipes[j].quantity;
+        let quantities = [];
 
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
+        for(let i = 0; i < this.transactionsByDate.length; i++){
+            dates.push(this.transactionsByDate[i].date);
 
-            if(i === this.transactions.length - 1){
-                quantities.push(currentQuantity);
-                dates.push(currentDate);
+            let sum = 0;
+            for(let j = 0; j < this.transactionsByDate[i].transactions.length; j++){
+                let transactions = this.transactionsByDate[i].transactions[j];
+                sum += transactions.getIngredientQuantity(ingredient);
             }
+            
+            quantities.push(sum);
         }
 
+        //create and display the graph
         let trace = {
             x: dates,
             y: quantities,
@@ -3000,168 +2972,76 @@ let analytics = {
         }
 
         const layout = {
-            title: this.ingredient.ingredient.name.toUpperCase(),
-            xaxis: {
-                title: "DATE"
-            },
-            yaxis: {
-                title: `QUANTITY (${this.ingredient.ingredient.unit.toUpperCase()})`,
-            }
+            title: ingredient.name.toUpperCase(),
+            xaxis: {title: "DATE"},
+            yaxis: {title: `QUANTITY (${ingredient.unit.toUpperCase()})`}
         }
 
         Plotly.newPlot("itemUseGraph", [trace], layout);
 
-        //Create use cards
-        let sum = 0;
-        let max = 0;
-        let min = (quantities.length > 0) ? quantities[0] : 0;
-        for(let i = 0; i < quantities.length; i++){
-            sum += quantities[i];
-            if(quantities[i] > max){
-                max = quantities[i];
-            }else if(quantities[i] < min){
-                min = quantities[i];
-            }
-        }
-        document.getElementById("analMinUse").innerText = `${min.toFixed(2)} ${this.ingredient.ingredient.unit}`;
-        document.getElementById("analAvgUse").innerText = `${(sum / quantities.length).toFixed(2)} ${this.ingredient.ingredient.unit}`;        
-        document.getElementById("analMaxUse").innerText = `${max.toFixed(2)} ${this.ingredient.ingredient.unit}`;
-
-        let dayUse = [0, 0, 0, 0, 0, 0, 0];
-        let dayCount = [0, 0, 0, 0, 0, 0, 0];
-        for(let i = 0; i < quantities.length; i++){
-            dayUse[dates[i].getDay()] += quantities[i];
-            dayCount[dates[i].getDay()]++;
-        }
-
-        document.getElementById("analDayOne").innerText = `${(dayUse[0] / dayCount[0]).toFixed(2)} ${this.ingredient.ingredient.unit}`;
-        document.getElementById("analDayTwo").innerText = `${(dayUse[1] / dayCount[1]).toFixed(2)} ${this.ingredient.ingredient.unit}`;
-        document.getElementById("analDayThree").innerText = `${(dayUse[2] / dayCount[2]).toFixed(2)} ${this.ingredient.ingredient.unit}`;
-        document.getElementById("analDayFour").innerText = `${(dayUse[3] / dayCount[3]).toFixed(2)} ${this.ingredient.ingredient.unit}`;
-        document.getElementById("analDayFive").innerText = `${(dayUse[4] / dayCount[4]).toFixed(2)} ${this.ingredient.ingredient.unit}`;
-        document.getElementById("analDaySix").innerText = `${(dayUse[5] / dayCount[5]).toFixed(2)} ${this.ingredient.ingredient.unit}`;
-        document.getElementById("analDaySeven").innerText = `${(dayUse[6] / dayCount[6]).toFixed(2)} ${this.ingredient.ingredient.unit}`;
+        //display the boxes at the bottom
+        
     },
 
-    recipeDisplay: function(){
-        let quantities = [];
+    displayRecipe: function(recipe){
+        //break down data into dates and quantities
         let dates = [];
-        let currentDate;
-        let quantity = 0;
-        if(this.transactions.length > 0){
-            currentDate = this.transactions[0].date;
-        }
+        let quantities = [];
 
-        for(let i = 0; i < this.transactions.length; i++){
-            if(currentDate.getDate() !== this.transactions[i].date.getDate()){
-                quantities.push(quantity);
-                quantity = 0;
-                dates.push(currentDate);
-                currentDate = this.transactions[i].date;
-            }
+        for(let i = 0; i < this.transactionsByDate.length; i++){
+            dates.push(this.transactionsByDate[i].date);
+            let sum = 0;
 
-            for(let j = 0; j < this.transactions[i].recipes.length; j++){
-                const recipe = this.transactions[i].recipes[j];
+            for(let j = 0; j < this.transactionsByDate[i].transactions.length; j++){
+                const transaction = this.transactionsByDate[i].transactions[j];
 
-                if(recipe.recipe === this.recipe){
-                    quantity += recipe.quantity;
+                for(let k = 0; k < transaction.recipes.length; k++){
+                    if(transaction.recipes[k].recipe === recipe){
+                        sum += transaction.recipes[k].quantity;
+                    }
                 }
             }
 
-            if(i === this.transactions.length - 1){
-                quantities.push(quantity);
-                dates.push(currentDate);
-            }
+            quantities.push(sum);
         }
-
+        
+        //create and display the graph
         const trace = {
             x: dates,
             y: quantities,
             mode: "lines+markers",
             line: {
-                color: "rgb(255, 99, 107"
+                color: "rgb(255, 99, 107)"
             }
         }
 
         const layout = {
-            title: this.recipe.name.toUpperCase(),
-            xaxis: {
-                title: "DATE"
-            },
-            yaxis: {
-                title: "Quantity"
-            }
+            title: recipe.name.toUpperCase(),
+            xaxis: {title: "DATE"},
+            yaxis: {title: "QUANTITY"}
         }
 
         Plotly.newPlot("recipeSalesGraph", [trace], layout);
 
-        let sum = 0;
-        for(let i = 0; i < quantities.length; i++){
-            sum += quantities[i];
-        }
+        //display the boxes at the bottom
 
-        document.getElementById("recipeAvgUse").innerText = (sum / quantities.length).toFixed(2);
-        document.getElementById("recipeAvgRevenue").innerText = `$${(((sum / quantities.length) * this.recipe.price) / 100).toFixed(2)}`;
     },
 
-    changeDates: function(Transaction){
-        let data = {
-            startDate: document.getElementById("analStartDate").valueAsDate,
-            endDate: document.getElementById("analEndDate").valueAsDate,
-            recipes: []
-        }
+    switchDisplay: function(){
+        const checkbox = document.getElementById("analSlider");
+        let ingredient = document.getElementById("analIngredientContent");
+        let recipe = document.getElementById("analRecipeContent");
 
-        if(data.from > data.to || data.from === "" || data.to === "" || data.to > new Date()){
-            banner.createError("INVALID DATE");
-            return;
-        }
-
-        for(let i = 0; i < merchant.recipes.length; i++){
-            data.recipes.push(merchant.recipes[i].id);
+        if(checkbox.checked === true){
+            ingredient.style.display = "none";
+            recipe.style.display = "flex";
+            if(this.recipesDisplay === false){
+                this.displayRecipe(merchant.recipes[0]);
+            }
+        }else{
+            ingredient.style.display = "flex";
+            recipe.style.display = "none";
         }
-
-        let loader = document.getElementById("loaderContainer");
-        loader.style.display = "flex";
-
-        fetch("/transaction", {
-            method: "post",
-            headers: {
-                "Content-Type": "application/json;charset=utf-8"
-            },
-            body: JSON.stringify(data)
-        })
-            .then(response => response.json())
-            .then((response)=>{
-                if(typeof(response) === "string"){
-                    banner.createError(response);
-                }else{
-                    this.transactions = [];
-
-                    for(let i = 0; i < response.length; i++){
-                        this.transactions.push(new Transaction(
-                            response[i]._id,
-                            new Date(response[i].date),
-                            response[i].recipes,
-                            merchant
-                        ));
-                    }
-
-                    let isRecipe = document.getElementById("analSlider").checked;
-                    if(isRecipe && Object.keys(this.recipe).length !== 0){
-                        this.recipeDisplay();
-                    }else if(!isRecipe && Object.keys(this.ingredient).length !== 0){
-                        this.ingredientDisplay();
-                    }
-                    
-                    this.dateChange = true;
-                }
-            })
-            .catch((err)=>{
-                banner.createError("ERROR: UNABLE TO DISPLAY THE DATA");
-            })
-            .finally(()=>{
-                loader.style.display = "none";
-            });
     }
 }
 

+ 1 - 1
views/dashboardPage/dashboard.ejs

@@ -245,7 +245,7 @@
                 </div>
 
                 <div id="analIngredientContent" class="analContent">
-                    <ul id="itemsList" class="itemsList"></ul>
+                    <div id="analIngredientList" class="itemsList"></div>
 
                     <div class="analData">
                         <div id="itemUseGraph" class="card analCard"></div>

+ 18 - 0
views/dashboardPage/js/classes/Transaction.js

@@ -64,6 +64,24 @@ class Transaction{
     get recipes(){
         return this._recipes;
     }
+
+    /*
+    Gets the quantity for a given ingredient
+    */
+    getIngredientQuantity(ingredient){
+        let quantity = 0;
+
+        for(let i = 0; i < this._recipes.length; i++){
+            const recipe = this._recipes[i].recipe;
+            for(let j = 0; j < recipe.ingredients.length; j++){
+                if(recipe.ingredients[j].ingredient === ingredient){
+                    quantity += recipe.ingredients[j].quantity;
+                }
+            }
+        }
+
+        return quantity;
+    }
 }
 
 module.exports = Transaction;

+ 1 - 1
views/dashboardPage/js/dashboard.js

@@ -1,7 +1,7 @@
 const home = require("./strands/home.js");
 const ingredients = require("./strands/ingredients.js");
 const recipeBook = require("./strands/recipeBook.js");
-const analytics = require("./strands/analytics.js");
+const analytics = require("./strands/analytics2.js");
 const orders = require("./strands/orders.js");
 const transactions = require("./strands/transactions.js");
 

+ 1 - 1
views/dashboardPage/js/strands/analytics.js

@@ -247,7 +247,7 @@ let analytics = {
                 title: "DATE"
             },
             yaxis: {
-                title: "Quantity"
+                title: "QUANTITY"
             }
         }
 

+ 188 - 0
views/dashboardPage/js/strands/analytics2.js

@@ -0,0 +1,188 @@
+let analytics = {
+    isPopulated: false,
+    recipesDisplay: false,
+    transactionsByDate: [],
+
+    display: async function(Transaction){
+        if(!this.isPopulated){
+            let to = new Date()
+            let from = new Date(to.getFullYear(), to.getMonth() - 1, to.getDate());
+            await this.getData(from, to, Transaction);
+
+            let analSlider = document.getElementById("analSlider");
+            analSlider.onclick = ()=>{this.switchDisplay()};
+            analSlider.checked = false;
+            document.getElementById("analRecipeContent").style.display = "none";
+
+
+            this.populateButtons();
+            this.displayIngredient(merchant.ingredients[0].ingredient);
+            this.displayRecipe(merchant.recipes[0]);
+            
+            this.isPopulated = true;
+        }
+    },
+
+    populateButtons: function(){
+        let ingredientButtons = document.getElementById("analIngredientList");
+        let recipeButtons = document.getElementById("analRecipeList");
+
+        for(let i = 0; i < merchant.ingredients.length; i++){
+            let button = document.createElement("button");
+            button.innerText = merchant.ingredients[i].ingredient.name;
+            button.classList.add("choosable");
+            button.onclick = ()=>{this.displayIngredient(merchant.ingredients[i].ingredient)};
+            ingredientButtons.appendChild(button);
+        }
+
+        for(let i = 0; i < merchant.recipes.length; i++){
+            let button = document.createElement("button");
+            button.innerText = merchant.recipes[i].name;
+            button.classList.add("choosable");
+            button.onclick = ()=>{this.displayRecipe(merchant.recipes[i])};
+            recipeButtons.appendChild(button);
+        }
+    },
+
+    getData: function(from, to, Transaction){
+        let loader = document.getElementById("loaderContainer");
+        loader.style.display = "flex";
+
+        return fetch(`/transactions/${from.toISOString()}/${to.toISOString()}`)
+            .then(response => response.json())
+            .then((response)=>{
+                if(typeof(response) === "string"){
+                    banner.createError(response);
+                }else{
+                    this.transactionsByDate = [];
+
+                    for(let i = 0; i < response.length; i++){
+                        const date = new Date(response[i].date);
+                        let newDate = {
+                            date: date,
+                            transactions: []
+                        };
+
+                        for(let j = 0; j < response[i].transactions.length; j++){
+                            newDate.transactions.push(new Transaction(
+                                response[i].transactions[j]._id,
+                                date,
+                                response[i].transactions[j].recipes,
+                                merchant
+                            ));
+                        }
+
+                        this.transactionsByDate.push(newDate);
+                    }
+                }
+            })
+            .catch((err)=>{
+                banner.createError("UNABLE TO UPDATE THE PAGE");
+            })
+            .finally(()=>{
+                loader.style.display = "none";
+            });
+    },
+
+    displayIngredient: function(ingredient){
+        //break down data into dates and quantities
+        let dates = [];
+        let quantities = [];
+
+        for(let i = 0; i < this.transactionsByDate.length; i++){
+            dates.push(this.transactionsByDate[i].date);
+
+            let sum = 0;
+            for(let j = 0; j < this.transactionsByDate[i].transactions.length; j++){
+                let transactions = this.transactionsByDate[i].transactions[j];
+                sum += transactions.getIngredientQuantity(ingredient);
+            }
+            
+            quantities.push(sum);
+        }
+
+        //create and display the graph
+        let trace = {
+            x: dates,
+            y: quantities,
+            mode: "lines+markers",
+            line: {
+                color: "rgb(255, 99, 107)"
+            }
+        }
+
+        const layout = {
+            title: ingredient.name.toUpperCase(),
+            xaxis: {title: "DATE"},
+            yaxis: {title: `QUANTITY (${ingredient.unit.toUpperCase()})`}
+        }
+
+        Plotly.newPlot("itemUseGraph", [trace], layout);
+
+        //display the boxes at the bottom
+        
+    },
+
+    displayRecipe: function(recipe){
+        //break down data into dates and quantities
+        let dates = [];
+        let quantities = [];
+
+        for(let i = 0; i < this.transactionsByDate.length; i++){
+            dates.push(this.transactionsByDate[i].date);
+            let sum = 0;
+
+            for(let j = 0; j < this.transactionsByDate[i].transactions.length; j++){
+                const transaction = this.transactionsByDate[i].transactions[j];
+
+                for(let k = 0; k < transaction.recipes.length; k++){
+                    if(transaction.recipes[k].recipe === recipe){
+                        sum += transaction.recipes[k].quantity;
+                    }
+                }
+            }
+
+            quantities.push(sum);
+        }
+        
+        //create and display the graph
+        const trace = {
+            x: dates,
+            y: quantities,
+            mode: "lines+markers",
+            line: {
+                color: "rgb(255, 99, 107)"
+            }
+        }
+
+        const layout = {
+            title: recipe.name.toUpperCase(),
+            xaxis: {title: "DATE"},
+            yaxis: {title: "QUANTITY"}
+        }
+
+        Plotly.newPlot("recipeSalesGraph", [trace], layout);
+
+        //display the boxes at the bottom
+
+    },
+
+    switchDisplay: function(){
+        const checkbox = document.getElementById("analSlider");
+        let ingredient = document.getElementById("analIngredientContent");
+        let recipe = document.getElementById("analRecipeContent");
+
+        if(checkbox.checked === true){
+            ingredient.style.display = "none";
+            recipe.style.display = "flex";
+            if(this.recipesDisplay === false){
+                this.displayRecipe(merchant.recipes[0]);
+            }
+        }else{
+            ingredient.style.display = "flex";
+            recipe.style.display = "none";
+        }
+    }
+}
+
+module.exports = analytics;