| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <style> | |
| circle { | |
| stroke: #000; | |
| fill: #ddd; | |
| fill-opacity: .8; | |
| } | |
| text { | |
| font-size: 32px; | |
| } | |
| div.top { | |
| position: relative; | |
| } | |
| div#answer { | |
| position: absolute; | |
| left: 0px; | |
| } | |
| div.info { | |
| margin-left: 650px; | |
| } | |
| </style> | |
| <script src="http://d3js.org/d3.v3.js"></script> | |
| </head> | |
| <body> | |
| <div class="top"> | |
| <div id="answer"></div> | |
| <div class="info"> | |
| <select id ="sp" name="Sprache" onchange="setLanguage(this.value, true);"> | |
| <option value="german" selected>Deutsch</option> | |
| <option value="english">English</option> | |
| </select> | |
| <select id ="ro" name="Rechnenoperationen" onchange="newQuestion(this.value); displayAnswers();"> | |
| <option value="+" selected>Addition</option> | |
| <option value="-">Subtraktion</option> | |
| <option value="*">Multiplikation</option> | |
| <option value=":">Division</option> | |
| </select> | |
| <label><input type="checkbox" id="cbox1" value="first_checkbox" onchange="checkTime()">Zeitmessung (10 Fragen)</label> | |
| <div id="feedback"><h1></h1></div> | |
| <div id="result"></div> | |
| <div class="count"></div> | |
| </div> | |
| </div> | |
| <script> | |
| var width = 700; | |
| var fontSize = 32; | |
| var radius = 25, cx = 30, cy = 150; | |
| var totalCorrect = 0; | |
| var totalQuestions = 0; | |
| var colorIterations = 0; | |
| var data; | |
| var value1, value2, result; | |
| var positiveComment, negativeComment, infoComment, resultComment; | |
| var counter = 0; | |
| var myTimer; | |
| var answerSVG = d3.select("#answer") | |
| .append("svg") | |
| .attr("width", width) | |
| .attr("height", 750); | |
| reset(); | |
| function reset() { | |
| newQuestion(d3.select("select#ro").node().value); | |
| displayAnswers(); | |
| setLanguage(d3.select("select#sp").node().value); | |
| checkTime(); | |
| } | |
| function countNow() { | |
| counter += 0.01; | |
| d3.select("div.count").html(counter.toFixed(2)); | |
| } | |
| function checkTime() { | |
| if (document.getElementById("cbox1").checked===false) { | |
| clearInterval(myTimer) | |
| } else { | |
| counter = 0; | |
| myTimer = setInterval(countNow, 10); | |
| } | |
| } | |
| function displayAnswers() { | |
| var answerG = answerSVG.selectAll("g.circle") | |
| .data(data); | |
| answerG.enter() | |
| .append("g") | |
| .attr("class", "circle") | |
| .attr("transform", translateOriginalCircles); | |
| answerG.exit().remove(); | |
| d3.selectAll("g") | |
| .on("mouseover", reactUponMouseOver) | |
| .on("mouseout", reactUponMouseOut) | |
| .on("click", evaluate); | |
| answerG.append("circle") | |
| .attr("cx", cx) | |
| .attr("cy", cy) | |
| .attr("r", radius); | |
| answerG.append("text") | |
| .attr("class", "number") | |
| .attr("x", function(d) { if (d > 9) { return cx - fontSize/2; } else {return cx - fontSize*0.25;}}) | |
| .attr("y", cy - fontSize*0.7/2) | |
| .attr("dy", ".71em") | |
| .text(function(d) {return d;}); | |
| } | |
| function translateOriginalCircles(d) { | |
| var digits = d.toString(); | |
| if (digits.length == 1) { digits = "0" + digits;} | |
| console.log("d: " +d + " d[1]: " + digits[1] + " d[0]: " + digits[0]); | |
| var x = digits[1]*(2*radius+5); | |
| var y = digits[0] * (2*radius+5) | |
| return "translate(" + x + ", " + y + ")"; | |
| } | |
| function newQuestion(questionType) { | |
| if (!questionType) { questionType = d3.select("#ro").node().value;} | |
| switch (questionType) { | |
| case "+": | |
| data = d3.range(0, 100, 1); | |
| result = getRandomInteger(data[0],data[data.length-1]); | |
| value2 = getRandomInteger(data[0], result); | |
| value1 = result - value2; | |
| break; | |
| case "-": | |
| data = d3.range(0, 100, 1); | |
| value1 = getRandomInteger(data[0],data[data.length-1]); | |
| value2 = getRandomInteger(data[0], value1); | |
| result = value1 - value2; | |
| break; | |
| case "*": | |
| data = d3.range(0, 11, 1); | |
| value1 = getRandomInteger(data[0],data[data.length-1]); | |
| value2 = getRandomInteger(data[0],data[data.length-1]); | |
| result = value1 * value2; | |
| data = d3.range(0, 100, 1); | |
| break; | |
| case ":": | |
| data = d3.range(0, 11, 1); | |
| result = getRandomInteger(data[0],data[data.length-1]); | |
| value2 = getRandomInteger(data[1],data[data.length-1]); | |
| value1 = value2 * result; | |
| break; | |
| } | |
| colorIterations = 0; | |
| // d3.select("#feedback").select("h1").html("Bitte klicke auf die richtige Antwort!"); | |
| d3.selectAll("circle").style("fill", "lightgrey"); | |
| d3.select("#answer svg").select(".questionbox").remove(); | |
| var question = d3.select("#answer").select("svg") | |
| .append("g") | |
| .attr("class", "questionbox"); | |
| question.append("rect") | |
| .attr("class", "highlight") | |
| .attr("x", 120) | |
| .attr("y", 15) | |
| .attr("width", 320) | |
| .attr("height", 50) | |
| .style("fill", "lightgreen") | |
| .style("opacity", 0); | |
| question.append("text") | |
| .attr("class", "question") | |
| .attr("x", width/2) | |
| .attr("y", 30) | |
| .attr("dy", ".71em") | |
| .text(value1 + " " + questionType + " " + value2 + " = ") | |
| .style("text-anchor", "end"); | |
| } | |
| function setLanguage(language, updateResult) { | |
| // to do: update values for rechenops, name for zeitmessung | |
| switch (language) { | |
| case "german": | |
| positiveComment = ["Bravo!", "Sehr gut!", "Prima!", "Na also, es geht doch!", "Ausgezeichnet!"]; | |
| negativeComment = ["Nicht so schnell ... Versuch es noch einmal!", | |
| "Du Schlafmütze ... Mach das bitte nochmal!", | |
| "Leider falsch ...noch ein Versuch!", | |
| "Bist Du sicher? Schau nochmal genau hin!", | |
| "War ein Versuch wert... aber leider falsch ... bitte jetzt aber richtig!"]; | |
| infoComment = "Bitte klicke auf die richtige Antwort!"; | |
| resultComment = "Ergebnis"; | |
| break; | |
| case "english": | |
| positiveComment = ["Great!", "Very good!", "Excellent!", "I told you, you can do it!", "Terrific!"]; | |
| negativeComment = ["Not so fast ... Try it again!", | |
| "Hey, wake up ... Try it again, please!", | |
| "Unfortunately wrong ... one more try!", | |
| "Are you sure? think twice!", | |
| "It was worth a try... but wrong ... please do it right next time!"]; | |
| infoComment = "Please click on the correct answer!"; | |
| resultComment = "Result"; | |
| break; | |
| } | |
| d3.select("#feedback").select("h1").html(infoComment); | |
| if (updateResult){ | |
| var newResultComment = d3.select("div#result").html().split(":"); | |
| d3.select("div#result").html(resultComment + ":" + newResultComment[1]); | |
| } | |
| } | |
| function reactUponMouseOver(d, i) { | |
| var sel = d3.selectAll("text.number").filter( function (da) { return da === d;}); | |
| var translationXY = d3.transform(d3.select(this).attr("transform")); | |
| sel.transition() | |
| .duration(750) | |
| .attr("x", width/2 + 5 - translationXY.translate[0]) | |
| .attr("y", 30 - translationXY.translate[1]) | |
| .style("text-anchor", "start"); | |
| } | |
| function reactUponMouseOut(d, i) { | |
| var sel = d3.selectAll("text.number").filter( function (da) { return da === d;}); | |
| sel.transition() | |
| .duration(750) | |
| .ease("bounce") | |
| .attr("x", function(d) { if (d > 9) { return cx - fontSize/2; } else {return cx - fontSize*0.25;}}) | |
| .attr("y", cy - fontSize*0.7/2); | |
| } | |
| function evaluate(d, i) { | |
| var guess; | |
| totalQuestions++; | |
| if (totalQuestions === 10) { | |
| clearInterval(myTimer); | |
| } | |
| var sel = d3.selectAll("text.number").filter( function (da) { return da === d;}); | |
| sel.each(function (d) {guess = d;}); | |
| var feedback = d3.select("#feedback") | |
| feedback.select("h1").remove(); | |
| if (guess === result) { | |
| totalCorrect++; | |
| d3.select("rect.highlight") | |
| .style("opacity", 0.5); | |
| feedback.append("h1") | |
| .attr("class", "feedback") | |
| .html(function() { return positiveComment[getRandomInteger(0, positiveComment.length-1)]}) | |
| .transition() | |
| .duration(2000) | |
| .each("end", newQuestion); | |
| d3.select("div#result").html(resultComment + ": " + totalCorrect + "/" + totalQuestions); | |
| } | |
| else { | |
| var feedback = d3.select("#feedback") | |
| feedback.append("h1") | |
| .html(function() { return negativeComment[getRandomInteger(0, negativeComment.length-1)]}); | |
| d3.selectAll("circle") | |
| .filter( function (da) { return da === d;}) | |
| .style("fill", "red"); | |
| reactUponMouseOut(d, i); | |
| d3.select("div#result").html(resultComment + ": " + totalCorrect + "/" + totalQuestions); | |
| } | |
| } | |
| function getRandomInteger(lower, upper) { | |
| if (arguments.length === 1) { | |
| upper = lower; | |
| lower = 0; | |
| } | |
| return Math.floor(Math.random() * (upper - lower)) + lower; | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment