diff --git a/node/PublicResources/js/cytoStylesheet.js b/node/PublicResources/js/cytoStylesheet.js index 077b4de..ff34840 100644 --- a/node/PublicResources/js/cytoStylesheet.js +++ b/node/PublicResources/js/cytoStylesheet.js @@ -6,6 +6,7 @@ export { CytoStyle, TestCytoStyle }; * Applies the stylesheet to the cytoscape graph * @param {string} containerId The id of the given graph * @param {string} graphSize The size of the graph, either "small" or "large", that the stylesheet is to be applied to + * @param {boolean} headless Whether the graph should be rendered or not * @returns The finished graph object */ function CytoStyle(containerId, graphSize, headless) { diff --git a/node/PublicResources/js/darkMode.js b/node/PublicResources/js/darkMode.js deleted file mode 100644 index 166e3f8..0000000 --- a/node/PublicResources/js/darkMode.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Adds a button to switch between light and dark mode on the simulation pages - * @param {Array} graphArr The array of all active graphs - */ -function addDarkBtn(graphArr) { - let graphClasses = document.querySelectorAll(".cy"), - darkBtn = document.createElement("input"), - documentTheme = "Dark mode"; - darkBtn.type = "button"; - darkBtn.value = "Light mode"; - darkBtn.id = "darkBtn"; - - darkBtn.addEventListener("mousedown", function () { - //If the theme is light switch every attribute to dark - if (documentTheme == "Light mode") { - documentTheme = "Dark mode"; - darkBtn.value = "Light mode"; - document.body.style.backgroundColor = "rgb(30,30,30)"; - document.body.style.color = "white"; - - //Background color for the visualized graphs - graphClasses.forEach( - (graphClass) => (graphClass.style.backgroundColor = "rgb(30,30,30)") - ); - - //Changes color of edges on every graph - graphArr.forEach((cyGraph) => { - cyGraph.graph.style().selector("edge").style("line-color", "white"); - cyGraph.graph - .style() - .selector("edge") - .style("target-arrow-color", "white"); - cyGraph.graph - .style() - .selector("edge") - .style("color", "lightgreen") - .update(); - }); - //Changes colors on the headless simulation page - document.getElementById("statistics-div").style.color = "white"; - document.getElementById("order-textarea").style.backgroundColor = "rgba(0,0,0,0.1)"; - document.getElementById("order-textarea").style.color = "white"; - } else { //If the theme is dark switch every attribute to light - documentTheme = "Light mode"; - darkBtn.value = "Dark mode"; - document.body.style.backgroundColor = "white"; - document.body.style.color = "black"; - - //Background color for the visualized graphs - graphClasses.forEach( - (graphClass) => (graphClass.style.backgroundColor = "white") - ); - - //Changes color of edges on every graph - graphArr.forEach((cyGraph) => { - cyGraph.graph.style().selector("edge").style("line-color", "black"); - cyGraph.graph - .style() - .selector("edge") - .style("target-arrow-color", "black"); - cyGraph.graph - .style() - .selector("edge") - .style("color", "darkgreen") - .update(); - }); - - //Changes colors on the headless simulation page - document.getElementById("statistics-div").style.color = "black"; - document.getElementById("order-textarea").style.backgroundColor = "lightgrey"; - document.getElementById("order-textarea").style.color = "black"; - } - }); - document.getElementById("cy0").before(darkBtn); - document.getElementById(darkBtn.id).after(document.createElement("br")); -} - -export { addDarkBtn }; \ No newline at end of file diff --git a/node/PublicResources/js/dijkstra.js b/node/PublicResources/js/dijkstra.js index d3a5564..36b520d 100644 --- a/node/PublicResources/js/dijkstra.js +++ b/node/PublicResources/js/dijkstra.js @@ -3,7 +3,7 @@ import { initializeSingleSource, relax } from "../js/pathModules.js"; /** * Dijkstra's algorithm will find the shortest path between all nodes in a weighted graph. - * @param {Object} cyGraph The graph nodes will be updated with new distances + * @param {Class} cyGraph The graph nodes will be updated with new distances * and parents in terms of the new starting point. * @param {Object} startNode The starting point node. Also called source. */ diff --git a/node/PublicResources/js/dynamicPageGeneration.js b/node/PublicResources/js/dynamicPageGeneration.js index 3a20327..08e7054 100644 --- a/node/PublicResources/js/dynamicPageGeneration.js +++ b/node/PublicResources/js/dynamicPageGeneration.js @@ -33,7 +33,6 @@ const generateVisualizationHTML = (graphs) => { Graph legend reference - `; @@ -366,7 +365,6 @@ const generateHeadlessHTML = (graph, infoDiv) => { ${infoDiv} - `; diff --git a/node/PublicResources/js/graphCore.js b/node/PublicResources/js/graphCore.js index 5defa75..2e34ecb 100644 --- a/node/PublicResources/js/graphCore.js +++ b/node/PublicResources/js/graphCore.js @@ -2,24 +2,24 @@ import { CyGraph } from "./graphHelper.js"; import { CytoStyle } from "./cytoStylesheet.js"; import { dijkstra } from "./dijkstra.js"; import { aStar } from "./aStar.js"; -import { addDarkBtn } from "./darkMode.js"; import { greedyBestFirstSearch } from "./greedyBestFirstSearch.js"; import { startSimulation } from "./orderGeneration.js"; -import * as tests from "./tests.js"; +import { runAllTests } from "./tests.js"; export { SetupGraph, simulationTest, getAlgorithm, startSim }; /** * Performs setup and initialization of the input Cytoscape graph - * @param {CyGraph} cyGraph The CyGraph class to set up + * @param {Class} cyGraph The CyGraph class to set up * @param {File} presetFile The graph preset file to load * @param {Function} startSimulationCallback Callback function which starts the simulation + * @param {Number} tickDuration the desired miliseconds per simulation tick */ function SetupGraph( cyGraph, presetFile = null, startSimulationCallback, - tickSpeed + tickDuration ) { if (presetFile === null) { startSimulation(cyGraph); @@ -35,16 +35,18 @@ function SetupGraph( cyGraph.initializeNodes(); cyGraph.graph.fit(cyGraph.graph.elements()); // then call the given start simulation function for this graph - startSimulationCallback(cyGraph, tickSpeed); + startSimulationCallback(cyGraph, tickDuration); }); } /** * Callback function which starts the simulation once the graph is initialized - * @param {CyGraph} cyGraph The graph to perform the simulation on + * @param {Class} cyGraph The graph to perform the simulation on + * @param {Number} tickDuration the desired miliseconds per simulation tick */ -function simulationTest(cyGraph, tickSpeed) { - startSimulation(cyGraph, tickSpeed); +function simulationTest(cyGraph, tickDuration) { + startSimulation(cyGraph, tickDuration); + runAllTests(); console.log(`[${cyGraph.name}] Started simulation`); } @@ -87,7 +89,7 @@ async function startSim() { : graphSettings["graph-size"] === "large" ? BIG_GRAPH_PRESET_FILE : AALBORG_GRAPH; - let tickSpeed = 1000 / graphSettings["ticks-per-second"]; + let tickDuration = 1000 / graphSettings["ticks-per-second"]; for (let i = 0; i < graphSettings["number-of-graphs"]; i++) { let cytoStyle = new CytoStyle( @@ -105,11 +107,11 @@ async function startSim() { graphSettings["idle-zones"], // use idle zones graphDivs[i].classList.contains("headless"), // headless traversal graphSettings["courier-frequency"], // max number of couriers - tickSpeed, // ms per tick + tickDuration, // ms per tick graphSettings["obstruction-level"] ); graphArray.push(cyGraph); - SetupGraph(cyGraph, graphSize, simulationTest, tickSpeed); + SetupGraph(cyGraph, graphSize, simulationTest, tickDuration); } } @@ -122,5 +124,3 @@ const DISTANCE_PER_TICK = 300; // 300 units per tick -> meters per minute -> 18 let graphArray = []; startSim(); - -addDarkBtn(graphArray); diff --git a/node/PublicResources/js/graphHelper.js b/node/PublicResources/js/graphHelper.js index b2e0e92..8eb5220 100644 --- a/node/PublicResources/js/graphHelper.js +++ b/node/PublicResources/js/graphHelper.js @@ -4,7 +4,7 @@ import { SimStats } from "./stats.js"; import { formatTime } from "./orderGeneration.js"; export { eleType, CyGraph }; -const simStartTime = 479; +const simStartTime = 479; //The desired start time for the simulation in raw minutes, default 479 (7:59 AM). let eleType = { default: "default", @@ -30,13 +30,13 @@ class CyGraph { idleZoneAmount, headless, courierFreq, - tickSpeed, + tickDuration, obstructionLevel ) { this.name = name; this.graph = graph; this.pathFunc = pathFunc; - this.tickSpeed = tickSpeed; + this.tickDuration = tickDuration; this.courierCount = 0; this.simulationStats = new SimStats(); this.distancePerTick = distancePerTick; @@ -57,35 +57,6 @@ class CyGraph { idleZones = new Array(); obstructions = new Array(); - /** - * Adds a node at specified location with potential weight - * @param {String} nodeId An ID for the node - * @param {String} type The type of the node, customer or restaurant (defaults to regular node) - * @param {Number} xCoord The x coordinate - * @param {Number} yCoord The y coordinate - * @param {Number} nodeWeight The specified weight (defaults to 1) - */ - addNode(nodeId, type = eleType.default, xCoord, yCoord, nodeWeight = 1) { - let node = this.graph.add({ - group: "nodes", - data: { - weight: nodeWeight, - id: nodeId, - _parent: null, - distanceOrigin: 0, - }, - position: { - x: xCoord, - y: yCoord, - }, - }); - - // add the node to the corresponding type-array of the CyGraph - if (type !== eleType.default) { - this[type + "s"].push(node); - } - } - /** * Removes a node and returns it * @param {String} nodeId The node ID to remove @@ -97,6 +68,7 @@ class CyGraph { /** * Adds a courier to the map on rootNode + * @param {Object} rootNode the node to place the courier at, null causes random position through if-statement. */ addCourier(rootNode = null) { let nodes = this.graph.nodes().filter((n) => this.couriers.indexOf(n)); @@ -124,8 +96,10 @@ class CyGraph { /** * Adds an edge between two nodes in the network - * @param {String} sourceNode The source node of the edge - * @param {String} targetNode The target node of the edge + * @param {String} _id the desired ID of the edge + * @param {String} _source The source node of the edge + * @param {String} _target The target node of the edge + * @param {Number} _obstructions The desired obstruction level of the edge */ addEdge(_id, _source, _target, _obstructions) { this.graph.add({ @@ -162,7 +136,7 @@ class CyGraph { } } - /** Initializes the type of every nodes */ + /** Initializes the type of all nodes */ initializeNodes() { let nodes = this.graph.nodes(), n = nodes.length; @@ -222,7 +196,7 @@ class CyGraph { /** * Gets the length of an edge between two nodes. * @param {String} sourceNode The source node - * @param {String} targetNode + * @param {String} targetNode The target node * @returns The length of the edge between the specified nodes */ getLength(sourceNode, targetNode) { @@ -231,10 +205,10 @@ class CyGraph { } /** - * Returns the ID of the edge connecting the two nodes. (Lexicographically) + * Returns the ID of the edge connecting the two nodes. * @param {String} node1Id The ID of the first node * @param {String} node2Id The ID of the second node - * @returns A concatenated string of the two nodes sorted lexicographically + * @returns A concatenated string of the two nodes, the ID of the edge. */ getEdgeId(node1Id, node2Id) { return node1Id + node2Id; @@ -274,7 +248,7 @@ class CyGraph { if (order) { order.status = "transit"; } - if (this.headless || this.tickSpeed < 100) { + if (this.headless || this.tickDuration < 100) { this.moveCourierHeadless(courier, path); } else { // Edge/route highlighting @@ -290,7 +264,7 @@ class CyGraph { /** * Moves the designated courier along the input path and performs an action based on the destination. * @param {Object} courier The courier node to move. - * @param {String[]} path The path generated by the traceback algorithm. + * @param {Array} path The path generated by the traceback algorithm. * @param {Number} i The index of the current node in the path array. */ moveCourierHeadless(courier, path, i = 0) { @@ -314,7 +288,7 @@ class CyGraph { let distance = this.graph .$id(this.getEdgeId(curNode.id(), nextNode.id())) .data("weight"), - timeout = (distance / this.distancePerTick) * this.tickSpeed; + timeout = (distance / this.distancePerTick) * this.tickDuration; setTimeout(() => this.moveCourierHeadless(courier, path, i + 1), timeout); } // The current node is the destination @@ -351,7 +325,7 @@ class CyGraph { if (dist < lowestDistance) { lowestDistance = dist; bestZone = zone; - } + } // The best zone has been found, being the closest } if (bestZone) { this.traversePath(courier.id(), bestZone.id()); @@ -361,11 +335,12 @@ class CyGraph { /** * Animates the movement of a courier from point A to B, highlighting the route. * @param {Array} path The array of nodes produced by a pathfinding algorithm - * @param {String} courierId The ID of the courier to animate + * @param {String} courier The courier object to animate * @param {Number} index The index to start from (default: 0) */ animateCourier(path, courier, edges, index = 0) { if (path.length === 1) { + // The courier is already at the destination let order = courier.data("currentOrder"); if (order && courier.data("currentNode") === order.restaurant) { return this.traversePath(courier.id(), order.customer.id()); @@ -376,21 +351,25 @@ class CyGraph { } } + // Preparing all necessary variables let nextPos = this.getPos(path[index + 1]), currentPos = this.getPos(path[index]), diff1 = nextPos.x - currentPos.x, diff2 = nextPos.y - currentPos.y, steps = ~~(this.getLength(path[index], path[index + 1]) / 10), i = 0, - perTick = ~~(this.tickSpeed / 30); + perTick = ~~(this.tickDuration / 30); let anim = setInterval(() => { + // Interval based animation by small steps of movement on edges courier.shift({ x: diff1 / steps, y: diff2 / steps }); i++; if (i >= steps) { + // When done stepping clearInterval(anim); courier.data("currentNode", this.graph.$id(path[index + 1])); if (courier.data("pendingOrder")) { + // If heading to idle zone, and received an order courier.data("pendingOrder", false); courier.data("moving", false); for (const edge of edges) { @@ -407,9 +386,10 @@ class CyGraph { courier.data("currentOrder").restaurant.id() ); } else if (index < path.length - 2) { - // on traversing a node + // Upon arrival to non final node return this.animateCourier(path, courier, edges, index + 1); } else { + // Upon arrival to final node for (const edge of edges) { let courierIndex = edge.inRoute.indexOf(courier.id()); edge.inRoute.splice(courierIndex, 1); @@ -419,7 +399,6 @@ class CyGraph { edge.addClass(eleType.inroute); } } - // on arrival let order = courier.data("currentOrder"); if (courier.data("moving")) { courier.data("moving", false); @@ -488,25 +467,6 @@ class CyGraph { return edges; } - /** Prints the nodes of the network as well as their connected edges */ - listNetwork() { - let nodes = this.graph.nodes(), - n = nodes.length, - netStr = ""; - - for (let i = 0; i < n; i++) { - netStr += `Node: ${nodes[i].id()}\n`; - let conEdges = nodes[i].connectedEdges(), - m = conEdges.length; - if (conEdges) { - for (let j = 0; j < m; j++) { - netStr += `Connected edge: ${conEdges[j].id()}\n`; - } - } - } - console.log(netStr); - } - /** * Moves a node to a new point in the network * @param {String} nodeID The ID of node to be moved diff --git a/node/PublicResources/js/heatGeneration.js b/node/PublicResources/js/heatGeneration.js index 335beaf..39c8995 100644 --- a/node/PublicResources/js/heatGeneration.js +++ b/node/PublicResources/js/heatGeneration.js @@ -5,7 +5,7 @@ export { generateHeatmap, generateObstructions }; /** * Gets the graph 'radius', which is the average edge weight of the graph - * @param {Object} cyGraph The graph the simulation is contained within. + * @param {Class} cyGraph The graph the simulation is contained within. * @returns The graph radius */ function getGraphRadius(cyGraph) { @@ -23,7 +23,7 @@ function getGraphRadius(cyGraph) { /** * Generates a heat map based on restaurant order activity, and finds/assigns appropriate idle-zones - * @param {Object} cyGraph The graph the simulation is contained within. + * @param {Class} cyGraph The graph the simulation is contained within. */ function generateHeatmap(cyGraph) { resetHeat(cyGraph); @@ -44,18 +44,9 @@ function generateHeatmap(cyGraph) { updateColors(cyGraph); } -/** - * Calculates a number of idle zones based on the number of restaurants and couriers - * @param {Object} cyGraph The graph the simulation is contained within. - * @returns The amount of idle zones to assign (based on restaurants pr courier). - */ -function getZoneCount(cyGraph) { - return Math.ceil(cyGraph.restaurants.length / 2); -} - /** * Sets the heat of all nodes in the graph to 0 - * @param {Object} cyGraph The graph the simulation is contained within. + * @param {Class} cyGraph The graph the simulation is contained within. */ function resetHeat(cyGraph) { for (let node of cyGraph.graph.nodes()) { @@ -65,7 +56,7 @@ function resetHeat(cyGraph) { /** * Calculates a heat property for all nodes in a specific radius of each restaurant - * @param {Object} cyGraph The graph the simulation is contained within. + * @param {Class} cyGraph The graph the simulation is contained within. */ function assignHeat(cyGraph) { let radius = 3 * getGraphRadius(cyGraph); @@ -85,7 +76,7 @@ function assignHeat(cyGraph) { /** * Finds the current best idle zone in the graph - * @param {Object} cyGraph + * @param {Class} cyGraph * @returns The 'warmest' node (read: best idle zone) */ function findIdleZone(cyGraph) { @@ -108,7 +99,7 @@ function findIdleZone(cyGraph) { /** * Reduces heat of nodes in a radius around the input idle zone node - * @param {Object} cyGraph The graph the simulation is contained within. + * @param {Class} cyGraph The graph the simulation is contained within. * @param {Object} zone The node around which heat should be updated. */ function updateHeat(cyGraph, zone) { @@ -121,7 +112,7 @@ function updateHeat(cyGraph, zone) { /** * Colors the graph based on heat values. - * @param {Object} cyGraph The graph the simulation is contained within. + * @param {Class} cyGraph The graph the simulation is contained within. */ function updateColors(cyGraph) { let warmNodes = cyGraph.graph @@ -156,7 +147,7 @@ function updateColors(cyGraph) { /** * Determines whether a given node is currently an idle-zone * @param {Object} node the node to check - * @param {Object} cyGraph the graph the node is present on + * @param {Class} cyGraph the graph the node is present on * @returns True if the node in question is an idle-zone, false if not */ function isIdleZone(node, cyGraph) { @@ -175,7 +166,7 @@ function isRegNode(n) { /** * Finds all nodes in a radius around the given startNode. - * @param {Object} cyGraph The graph the simulation is contained within. + * @param {Class} cyGraph The graph the simulation is contained within. * @param {Object} startNode The center of the selection circle * @param {Number} radius The radius of the circle. * @returns An array of nodes in circle centered on 'startNode' with the radius 'radius'. @@ -194,7 +185,7 @@ function findNodesInRadius(cyGraph, startNode, radius) { /** * Creates obstructions on random edges in the graph. - * @param {Object} cyGraph The graph the simulation is contained within. + * @param {Class} cyGraph The graph the simulation is contained within. */ function generateObstructions(cyGraph) { for (let obstructionEdge of cyGraph.obstructions) { diff --git a/node/PublicResources/js/orderGeneration.js b/node/PublicResources/js/orderGeneration.js index 6c58a4b..f5a2622 100644 --- a/node/PublicResources/js/orderGeneration.js +++ b/node/PublicResources/js/orderGeneration.js @@ -15,11 +15,11 @@ const isHeadless = document.querySelector("div.headless"); /** * Starts the order generation simulation - * @param {Object} cyGraph The graph the simulation is contained within. - * @param {integer} tickSpeed the time (in ms) per tick. + * @param {Class} cyGraph The graph the simulation is contained within. + * @param {Number} tickDuration the time (in ms) per tick. * @returns The update interval. */ -function startSimulation(cyGraph, tickSpeed) { +function startSimulation(cyGraph, tickDuration) { let n = cyGraph.restaurants.length; for (let i = 0; i < n; i++) { if (i < Math.ceil(n / 2)) { @@ -32,12 +32,12 @@ function startSimulation(cyGraph, tickSpeed) { cyGraph.restaurants[i].addClass(eleType.dinner); } } - return setInterval(() => perTick(cyGraph), tickSpeed); + return setInterval(() => perTick(cyGraph), tickDuration); } /** - * Assigns the time throughout the simulation. - * @param {Object} cyGraph The graph the simulation is contained within. + * Handles the simulation time, and all actions that should be performed at specific times or intervals. + * @param {Class} cyGraph The graph the simulation is contained within. */ function perTick(cyGraph) { cyGraph.timeMinutes++; @@ -116,7 +116,7 @@ function perTick(cyGraph) { /** * Ensures that the number of couriers is set according to expected values for each hour - * @param {Object} cyGraph The graph the simulation is contained within. + * @param {Class} cyGraph The graph the simulation is contained within. */ function maintainCouriers(cyGraph) { // The expectedCourierMultiplier array denotes the courier multiplier of each hour of the day (starting at 00:00) @@ -208,12 +208,18 @@ function formatTime(timeMinutes) { /** * Determines the intensity in the amount of orders generated every hour. * @param {Number} x The current minutes to the hour as a float. + * @param {Function} func The function to provide return value of input x for. * @returns The order intensity based on predefined restaurant rush-hour spikes (piecewise equations). */ function orderIntensity(x, func) { return func(x); } +/** + * Determines current intensity (business) of restaurants for order generation + * @param {Number} x The current minutes to the hour as a float. + * @returns The order intensity + */ function lunchRate(x) { if (x >= 8 && x < 15) { return (Math.sin(0.86 * x - 2.3) + 1) / 2; @@ -224,6 +230,11 @@ function lunchRate(x) { } } +/** + * Determines current intensity (business) of restaurants for order generation + * @param {Number} x The current minutes to the hour as a float. + * @returns The order intensity + */ function dinnerRate(x) { if (x >= 8 && x < 15) { return Math.sin(0.43 * x + 2.9) / 2; @@ -236,7 +247,7 @@ function dinnerRate(x) { /** * Generates an order from a random restaurant to a random customer in the network based on the current intensity and some randomness. - * @param {Object} cyGraph The graph the simulation is contained within. + * @param {Class} cyGraph The graph the simulation is contained within. * @returns The new order. */ function generateOrders(cyGraph) { @@ -281,7 +292,7 @@ function Order(id, origin, destination, startTime) { /** * Assigns and dispatches a courier to the given order. - * @param {CyGraph} cyGraph The cyGraph to perform the assignment on. + * @param {Class} cyGraph The cyGraph to perform the assignment on. * @param {Object} order The order to be assigned. * @param {Number} index The index of the order in the CyGraph's order array. */ @@ -303,7 +314,7 @@ function assignCourier(cyGraph, order, index) { /** * Searches the given graph for a courier that is closest to the origin of a given order. - * @param {CyGraph} cyGraph The cyGraph to perform the search on. + * @param {Class} cyGraph The cyGraph to perform the search on. * @param {Object} order The order to find a courier for. * @returns The best courier of all candidates, or null no none are found. */ diff --git a/node/PublicResources/js/pathModules.js b/node/PublicResources/js/pathModules.js index a52528b..bff3513 100644 --- a/node/PublicResources/js/pathModules.js +++ b/node/PublicResources/js/pathModules.js @@ -42,6 +42,7 @@ function relax(currentNode, adjacentNode, weight) { /** * Approximates the direct distance from the current node being observed + * @param {Class} cyGraph The container for the graph * @param {Object} currentNodeId The current node we are evaluating in respect to the end goal. * @param {Object} endNodeId The end goal node. * @returns The Pythagorean distance between the currentNodeId and the endNodeId. @@ -60,6 +61,7 @@ function heuristicApprox(cyGraph, currentNodeId, endNodeId) { * and walks fra the endNode and backwards toward the starting point. * @param {Object} graph The graph which contains distances and parents, * which we will use for navigation. + * @param {Object} startNode The node to pathfind from * @param {Object} endNode The end goal for which we want to find the shortest path. */ function traceback(graph, startNode, endNode) { diff --git a/node/PublicResources/js/stats.js b/node/PublicResources/js/stats.js index 05c0747..c5ad91a 100644 --- a/node/PublicResources/js/stats.js +++ b/node/PublicResources/js/stats.js @@ -35,7 +35,7 @@ class SimStats { this.failedOrders = 0; // The number of failed orders this.averageDeliveryTime = 0; // The average delivery time of orders on the graph this.totalDeliveryTime = 0; // Total delivery time - this.ordersPrinted = 0; + this.ordersPrinted = 0; // The amount of printed orders } /** @@ -81,7 +81,7 @@ function updateStats(simStatObject) { ).toFixed(2) + "%"; } - // The textarea containing the entire log of orders in the simulation + // The textarea containing the previous 200 orders in the simulation if (simStatObject.totalOrdersArr !== null) { let data = ""; for ( diff --git a/node/PublicResources/js/tests.js b/node/PublicResources/js/tests.js index 47bb5b8..2d1b264 100644 --- a/node/PublicResources/js/tests.js +++ b/node/PublicResources/js/tests.js @@ -6,17 +6,18 @@ import * as pathModules from "./pathModules.js"; import { dijkstra } from "./dijkstra.js"; import { aStar } from "./aStar.js"; import { greedyBestFirstSearch } from "./greedyBestFirstSearch.js"; +//Exports +export { runAllTests }; /* Since certain functions modify the values of nodes/edges in the graph, * the immutable test graph 'TEMPLATE' is used to reset the graph after - * each test is executed. */ + * each test is executed. + */ const TEMPLATE = new TestCytoStyle(); const UNREACHABLE = "Unreachable end node", START_NO_ADJ = "Start node with no adjacent nodes", VIABLE = "Viable path"; -runAllTests(); - /** Runs all application tests sequentially. */ function runAllTests() { let testGraph = TEMPLATE,