var graphs, variables, currentEditor, maxSquareCount, minSquareCount, padding, paddingFactor, tickFactor, textHeight, paddingDivider, scrollFactor, squareCount, axisDispo, axisDispoPI, origin, distance, valid, editing; function setup(){ frameRate(0); assignGlobalVariables(); restoreSettings(); //restoreStandard(); prepareVisibilites(); updateAll(); updateScroll(); } function assignGlobalVariables(){ graphs = [], variables = [], currentEditor = null, maxSquareCount = {x: 20, y: 15}, minSquareCount = {x: 15, y: 10}, squareCount = {x: 0, y: 0}, padding = {x: 50, y: 50}, paddingFactor = {x: 1, y: 1}, paddingDivider = {x: 0, y: 0}, axisDispoPI = {x: false, y: false}, axisDispo = 2, tickFactor = 1, origin = {x: 0, y: 0}, distance = {x: 0, y: 0}, textHeight = 15; } function addGraph(){ var newGraph = new Graph($("#input").val()); var same = false; if (newGraph.getName().length == 0) return; graphs.forEach(function(g){ if (g.getName() == newGraph.getName()){ newGraph.setColor(g.getColor()); newGraph.setThickness(g.getThickness()); graphs[graphs.indexOf(g)] = newGraph; same = true; } }); if (!same){ graphs.push(newGraph); $("#input").val(newGraph.getFullDescription()); } updateAll(); } function updateAll(){ updateInterface(); updateDisplay(); safeSettings(); } function updateDisplay(){ prepareGridValues(); drawGrid(); drawGraphs(); } function updateInterface(){ $("#functions").html(""); graphs.forEach(function(g){ var bc = g.getColor(); var c = g.visible ? g.getColor() : "none"; $("#functions").append("
"); }); } function prepareGridValues(){ squareCount.x = width / padding.x; squareCount.y = height / padding.y; while (squareCount.x > maxSquareCount.x){ squareCount.x = round(squareCount.x / axisDispo); paddingFactor.x *= axisDispo; padding.x *= axisDispo; } while (squareCount.y > maxSquareCount.y){ squareCount.y = round(squareCount.y / axisDispo); paddingFactor.y *= axisDispo; padding.y *= axisDispo; } while (squareCount.x < minSquareCount.x){ squareCount.x *= axisDispo; paddingFactor.x /= axisDispo; padding.x = round(padding.x / axisDispo); } while (squareCount.y < minSquareCount.y){ squareCount.y *= axisDispo; paddingFactor.y /= axisDispo; padding.y = round(padding.y / axisDispo); } squareCount.x = round(squareCount.x); squareCount.y = round(squareCount.y); paddingDivider.x = padding.x / paddingFactor.x; paddingDivider.y = padding.y / paddingFactor.y; } function drawGrid(){ clear(); stroke("#000"); strokeWeight(2); line(0, origin.y, width, origin.y); line(origin.x, height, origin.x, 0); strokeWeight(0.25); var centerX = (origin.x - width / 2) % padding.x + width / 2; var centerY = (origin.y - height / 2) % padding.y + height / 2; var x, y, numX, numY, textWidthX, textWidthY, i; for (i = 0; i < squareCount.x * 2; i++){ x = centerX - squareCount.x * padding.x + padding.x * i; if (axisDispoPI.x) numX = round((x - origin.x) / padding.x * paddingFactor.x / PI * 100) / 100 + "π"; if (!axisDispoPI.x) numX = round((x - origin.x) / padding.x) * paddingFactor.x; if (numX == 0 || numX == "0π") numX = ""; line(x, 0, x, height); textWidthX = textWidth(str(numX)); text(numX, x - textWidthX / 2, origin.y + textHeight / 2, textWidthX, textHeight); } for (i = 0; i < squareCount.y * 2; i++){ y = centerY - squareCount.y * padding.y + padding.y * i; if (axisDispoPI.y) numY = -round((y - origin.y) / padding.y * paddingFactor.y / PI * 100) / 100 + "π"; if (!axisDispoPI.y) numY = -round((y - origin.y) / padding.y) * paddingFactor.y; if (numY == 0 || numY == "0π") numY = ""; line(0, y, width, y); textWidthY = textWidth(str(numY)); text(numY, origin.x - textWidthY - textHeight / 2, y - textHeight / 2, textWidthY, textHeight); } } function drawGraphs(){ graphs.forEach(function(g){ if (!g.visible) return; var rdyFunc = g.getExecuteFunction(); var r = g.getReference(); function f(value){ var y; var execFunc = rdyFunc.replace(new RegExp(r, "g"), value); try{y = eval(execFunc);} catch(e){y = null;} return y; } var pointsRange = [], x, y; for (var px = 0; px <= width; px += tickFactor){ x = (px - origin.x) / paddingDivider.x; y = f(x); pointsRange[px / tickFactor] = {x: x, y: y}; } g.setPoints(pointsRange); }); graphs.forEach(function(g){ if (!g.visible) return; var t = g.getThickness(), x, y; stroke(g.getColor()); strokeWeight(t); g.getPoints().forEach(function(p){ x = origin.x + p.x * paddingDivider.x; y = origin.y - p.y * paddingDivider.y; if (x != null && y != null) line(x, y, x + t / 4, y); }); //Straight lines instead of points: /*for (var i = 0; i < g.getPoints().length; i++){ p = g.getPoints()[i]; x1 = origin.x + p.x * paddingDivider.x; y1 = origin.y - p.y * paddingDivider.y; try{ x2 = origin.x + g.getPoints()[i + 1].x * paddingDivider.x; y2 = origin.y - g.getPoints()[i + 1].y * paddingDivider.y; line(x1, y1, x2, y2); }catch(e){} }*/ }); } function editGraph(obj){ var i = $(obj).parent().parent().index(); obj.blur(); currentEditor = new Editor(obj, i); } function deleteGraph(obj){ var i = $(obj).parent().parent().index(); obj.blur(); graphs.splice(i, 1); updateAll(); } function toggleGraph(obj){ var i = $(obj).parent().parent().index(); obj.blur(); graphs[i].visible = !graphs[i].visible; updateAll(); } function mouseWheel(event){ if (mouseX > 0 && mouseY < height && !editing){ var oldPaddingX = padding.x; var oldPaddingY = padding.y; var oldPaddingFactorX = paddingFactor.x; var oldPaddingFactorY = paddingFactor.y; padding.x *= (scrollFactor - (event.delta > 0 ? 3 : -3)) / scrollFactor; padding.y *= (scrollFactor - (event.delta > 0 ? 3 : -3)) / scrollFactor; padding.x = round(padding.x); padding.y = round(padding.y); prepareGridValues(); origin.x = -(mouseX - origin.x) / (oldPaddingX / oldPaddingFactorX) * (padding.x / paddingFactor.x) + mouseX; origin.y = -(mouseY - origin.y) / (oldPaddingY / oldPaddingFactorY) * (padding.y / paddingFactor.y) + mouseY; updateDisplay(); } } function updateScroll(){ scrollFactor = round((500 - $("#scroll_input").val() * 0.95) / 5); } function updateDisposition(obj, xAxis){ obj.blur(); var dispo = $(obj).val(); if (xAxis){ if (dispo == "PI" && !axisDispoPI.x){ paddingFactor.x *= PI; padding.x *= PI; axisDispoPI.x = true; } if (dispo == "1" && axisDispoPI.x){ paddingFactor.x /= PI; padding.x /= PI; axisDispoPI.x = false; } } if (!xAxis){ if (dispo == "PI" && !axisDispoPI.y){ paddingFactor.y *= PI; padding.y *= PI; axisDispoPI.y = true; } if (dispo == "1" && axisDispoPI.y){ paddingFactor.y /= PI; padding.y /= PI; axisDispoPI.y = false; } } updateAll(); } function mouseDragged(){ if (editing){currentEditor.colorPicker.mouseDragged();} else if (valid){ origin.x = round(mouseX - distance.x); origin.y = round(mouseY - distance.y); updateDisplay(); } } function mousePressed(){ if (editing){currentEditor.colorPicker.mousePressed();} else if (mouseX > 0 && mouseY < height){ valid = true; distance.x = mouseX - origin.x; distance.y = mouseY - origin.y; $("#defaultCanvas0").css("cursor", "all-scroll"); } else {valid = false;} } function mouseReleased(){ if (editing){currentEditor.colorPicker.mouseReleased();} $("#defaultCanvas0").css("cursor", "auto"); } function prepareVisibilites(){ if (!editing) $("#graph_editor_wrapper").hide(); $("#canvas_holder").css("height", windowHeight - $("#input_holder").outerHeight() + "px"); var canvas = createCanvas(windowWidth - $("#displayer").outerWidth(), windowHeight - $("#input_holder").outerHeight()); canvas.parent("canvas_holder"); $(".holder:not(#settings_holder)").css("height", windowHeight * 0.7 * 0.5 + "px"); $("#settings_holder").css("height", $("#displayer").outerHeight() - $("#function_holder").outerHeight() - $("#variable_holder").outerHeight() - 80 + "px"); origin.x = width / 2; origin.y = height / 2; textFont("Arial", textHeight); $("body").css("background-color", "#FFF"); }