D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
EE2dev
Full window
Github gist
Math exercise for kids - division
<!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="https://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>
Modified
http://d3js.org/d3.v3.js
to a secure url
https://d3js.org/d3.v3.js