diff options
| author | schneefux <schneefux+commit@schneefux.xyz> | 2016-04-02 17:12:01 +0200 |
|---|---|---|
| committer | schneefux <schneefux+commit@schneefux.xyz> | 2016-04-02 17:12:01 +0200 |
| commit | cc8dda39fc4e6a875ffdbe9f7614d434375fa29b (patch) | |
| tree | 04e2d3f35e9ab3a597e04e909d08b42202bcfd6b | |
| parent | 1a7013588006e9e1efef766baf85fe528a5381a0 (diff) | |
| download | vortrag-knn-cc8dda39fc4e6a875ffdbe9f7614d434375fa29b.tar.gz vortrag-knn-cc8dda39fc4e6a875ffdbe9f7614d434375fa29b.zip | |
first impress-ions; add error vis
| -rw-r--r-- | code/errorvis.js | 126 | ||||
| -rw-r--r-- | code/weightviswrapper.js | 7 | ||||
| -rw-r--r-- | dep/impress.js | 24 | ||||
| -rw-r--r-- | index.css | 41 | ||||
| -rw-r--r-- | index.html | 91 |
5 files changed, 276 insertions, 13 deletions
diff --git a/code/errorvis.js b/code/errorvis.js new file mode 100644 index 0000000..9cd87f4 --- /dev/null +++ b/code/errorvis.js @@ -0,0 +1,126 @@ +var ErrorVis = (function() { + var margins = { + "top": 40, + "bottom": 40, + "left": 40, + "right": 40 + }; + + function ErrorVis() { + this.container = d3.select("body").append("div").remove(); + this.svgContainer = this.container.append("div"); + this.svg = this.svgContainer.append("svg"); + this.ready = false; + this.readyHooks = []; + + this.svgContainer + .style("margin-top", "1.5em") + .style("margin-bottom", "1em") + .style("height", "100%") + .style("width", "100%"); + + this.spinner = this.container.append("div") + .attr("class", "mdl-spinner mdl-js-spinner mdl-spinner--single-color is-active spinner") + .style("position", "absolute") + .style("left", "50%") + .style("top", "50%"); + componentHandler.upgradeElement(this.spinner.node()); + } + + ErrorVis.prototype.addPlaceholder = function(el) { + el.appendChild(this.spinner.node().cloneNode(true)); + }; + + ErrorVis.prototype.afterLoad = function(cb) { + if (!this.ready) { + this.readyHooks.push(cb); + } else { + cb(); + } + }; + + ErrorVis.prototype.load = function(url, callback) { + var self = this; + d3.json(url) + .get(function(e, json) { + if (e) console.log(e); + self.data = Object.keys(json).map(function(k) { return parseFloat(json[k]); }); + self.ready = true; + callback(); + self.readyHooks.forEach(function(hook) { hook(); }); + }); + }; + + ErrorVis.prototype.openIn = function(el) { + d3.select(el).select(".spinner").remove(); + el.appendChild(this.svgContainer.node()); + this.reposition(); + }; + + ErrorVis.prototype.remove = function(el) { + this.svgContainer.node().parentNode.appendChild(this.spinner.node().cloneNode(true)); + this.svgContainer.node().parentNode.removeChild(this.svgContainer.node()); + }; + + ErrorVis.prototype.reposition = function() { + var self = this; + // TODO may not need to recreate everything + this.svg.remove(); + this.svg = this.svgContainer.append("svg"); + + var width = parseInt(this.svgContainer.style("width")) || 800, + height = parseInt(this.svgContainer.style("height")) || 600; + this.svg + .style("width", width) + .style("height", height); + + this.scalerX = d3.scale.linear() + .range([margins.left, width-margins.right]) + .domain([0, this.data.length]); + this.scalerY = d3.scale.linear() + .range([height-margins.top, margins.bottom]) + .domain(d3.extent(this.data)); + + var xAxis = d3.svg.axis() + .scale(this.scalerX); + var yAxis = d3.svg.axis() + .orient("left") + .scale(this.scalerY); + + var gy = this.svg.append("g") + .attr("transform", "translate(" + margins.left + ", 0)") + .attr("class", "axis") + .call(yAxis); + var gx = this.svg.append("g") + .attr("transform", "translate(0, " + (height-margins.bottom) + ")") + .attr("class", "axis") + .call(xAxis); + + var line = d3.svg.line() + .x(function(d, i) { return self.scalerX(i); }) + .y(function(d) { return self.scalerY(d); }); + + this.svg.append("path") + .attr("d", line(this.data)) + .attr("stroke", "#673ab7") + .attr("stroke-width", 5) + .attr("fill", "none"); + + this.marker = this.svg.append("circle") + .attr("display", "none") + .attr("r", 10) + .attr("fill", "#2962ff"); + }; + + ErrorVis.prototype.showMarker = function(step) { + this.marker.style("display", "inherit"); + this.marker.attr("cx", this.scalerX(step)); + this.marker.attr("cy", this.scalerY(this.data[step])); + }; + + ErrorVis.prototype.hideMarker = function() { + this.marker.style("display", "none"); + }; + + return ErrorVis; +})(); diff --git a/code/weightviswrapper.js b/code/weightviswrapper.js index eec2a84..ad33092 100644 --- a/code/weightviswrapper.js +++ b/code/weightviswrapper.js @@ -1,3 +1,4 @@ +// TODO rename classes (weightVis etc.) var WeightVisWrapper = (function() { var attributeNames = ["CRIM", "ZN", "INDUS", "CHAS", "NOX", "RM", "AGE", "DIS", "RAD", "TAX", "PTRATIO", "B", "LSTAT"]; @@ -136,8 +137,6 @@ var WeightVisWrapper = (function() { this.svgContainer.node().parentNode.removeChild(this.controlContainer.node()); this.svgContainer.node().parentNode.appendChild(this.spinner.node().cloneNode(true)); this.svgContainer.node().parentNode.removeChild(this.svgContainer.node()); - this.container.node().appendChild(this.controlContainer.node()); - this.container.node().appendChild(this.svgContainer.node()); this.netVisualizer.stopAnimation(); this.slider.node().MaterialSlider.change(0); }; @@ -162,10 +161,10 @@ var WeightVisWrapper = (function() { /* helps with impress.js' stepenter/stepleave events */ var VisIntegrater = (function() { - function VisIntegrater(enterCb, leaveCb) { + function VisIntegrater(enterCb, leaveCb, selector) { var self = this; this.slide = document.currentScript.parentElement; - this.container = d3.select(this.slide).select(".visContainer"); + this.container = d3.select(this.slide).select(selector); this.slide.addEventListener("impress:stepenter", function() { enterCb(self.slide); }); diff --git a/dep/impress.js b/dep/impress.js index 2529e26..8115af1 100644 --- a/dep/impress.js +++ b/dep/impress.js @@ -553,15 +553,33 @@ var prev = steps.indexOf( activeStep ) - 1; prev = prev >= 0 ? steps[ prev ] : steps[ steps.length-1 ]; + // when backing through a slide, clear its inner steps + $$('.innerStep.stepped', activeStep).forEach( function (elem) { + elem.classList.remove('stepped'); + }); + return goto(prev); }; + var inner = { + next: function () { + var innerNext = activeStep.querySelector('.innerStep:not(.stepped)'); + innerNext.classList.add('stepped'); + } + }; + // `next` API function goes to next step (in document order) var next = function () { - var next = steps.indexOf( activeStep ) + 1; - next = next < steps.length ? steps[ next ] : steps[ 0 ]; + // if there are unshown inner steps, show next one instead of next slide + if(activeStep.querySelectorAll('.innerStep:not(.stepped)').length) { + inner.next(); + triggerEvent(activeStep, "impress:innerstep"); + } else { + var next = steps.indexOf( activeStep ) + 1; + next = next < steps.length ? steps[ next ] : steps[ 0 ]; - return goto(next); + return goto(next); + } }; // Adding some useful classes to step elements. @@ -23,3 +23,44 @@ time, mark, audio, video { h1, h2, h3, h4, h5, h6 { text-align: center; } + +.step { + opacity: 0; + transition: opacity 1s; +} +.step.active { + opacity: 1; +} +.innerStep { + position: absolute; + opacity: 0; + transition: opacity 0.5s; +} +.lastInnerstep { + opacity: 1; +} + +.center { + position: absolute; + left: 0; + right: 0; + margin: auto; + text-align: center; +} +p.center { + top: 50%; + bottom: 50%; +} + +.hidden { + display: none; +} + +.axis path, .axis line { + fill: none; + stroke: rgba(0, 0, 0, 0.87); + stroke-width: 3; +} +.axis text { + font-size: large; +} @@ -14,9 +14,11 @@ <script src="code/weightvis.js" type="text/javascript"></script> <script src="code/weightviswrapper.js" type="text/javascript"></script> + <script src="code/errorvis.js" type="text/javascript"></script> <script type="text/javascript"> var weightsWrapper = new WeightVisWrapper(); + var errorVis = new ErrorVis(); document.addEventListener("DOMContentLoaded", function() { impress().init(); @@ -27,6 +29,14 @@ weightsWrapper.load("data/weights.json", function() { weightsWrapper.reposition(); }); + + d3.selectAll(".errorContainer")[0].forEach(function(el) { + errorVis.addPlaceholder(el.parentNode); + }); + errorVis.load("data/error.json", function() { + //errorVis.reposition(); + }); + sizeSlides(); }, false); @@ -37,14 +47,83 @@ .style("height", parseInt(window.innerHeight) * 0.9 + "px"); }; window.addEventListener("resize", sizeSlides); + + document.addEventListener("impress:innerstep", function(e) { + d3.selectAll(".lastInnerstep")[0].forEach(function(ist) { ist.classList.remove("lastInnerstep"); }); + var stepped = d3.select(e.target).selectAll(".stepped")[0]; + stepped[stepped.length-1].classList.add("lastInnerstep"); + }); </script> <div id="impress"> - <div class="step slide" data-x="0" data-y="0"> - <div class="title mdl-layout mdl-js-layout"> - <h1 class="mdl-layout__header">Künstliche neuronale Netze</h1> - <h3>38 Gewichte in 15 Minuten</h3> + <div class="mdl-layout mdl-js-layout step slide" data-x="0" data-y="0" data-z="5000"> + <h1 class="mdl-layout__header">Künstliche neuronale Netze</h1> + <h2>38 Gewichte in 20 Minuten</h2> + </div> + + <div class="mdl-layout mdl-js-layout step slide" data-x="-1000" data-y="0" data-z="1000"> + <h1 class="mdl-layout__header">Biologie</h1> + <div class="innerStep stepped lastInnerstep center"> + <h3>Der Mensch und die Maschine.</h3> + <p style="font-size: 2500%"> + <i style="font-size: 100%;" class="material-icons">accessibility</i> + 🖥 + </p> </div> + <div class="innerStep center"> + <h3>Wahrnehmung</h3> + <p> + <i style="font-size: 800%;" class="material-icons">remove_red_eye</i> + </p> + <p> + <span style="font-size: 500%;">Rezeptor</span> + </p> + </div> + <div class="innerStep center"> + <h3>Reaktion.</h3> + <p> + <i style="font-size: 2500%;" class="material-icons">directions_walk</i> + </p> + <p> + <span style="font-size: 500%;">Effektor</span> + </p> + </div> + </div> + + <div class="mdl-layout mdl-js-layout step slide" data-x="0" data-y="0" data-z="1000"> + <h1 class="mdl-layout__header">Abstraktion eines Individuums</h1> + <p class="innerStep stepped lastInnerstep center" style="font-size: 500%;"> + Wahrnehmung ➞ + <i style="font-size: 100%;" class="material-icons">help_outline</i> + ➞ Reaktion + </p> + <p class="innerStep center" style="font-size: 500%;"> + Eingabe ➞ ✨ ➞ Ausgabe + </p> + </div> + + <!-- TODO x' besser verteilen --> + <div class="mdl-layout mdl-js-layout step slide" data-x="1000" data-y="0" data-z="1000"> + <h1 class="mdl-layout__header">Abstraktion der Ein- und Ausgabe</h1> + </div> + + <div class="step slide mdl-layout mdl-js-layout" data-x="0" data-y="1000"> + <div class="mdl-layout__header"> + <h2>Der Fehler im Verlauf</h2> + </div> + + <div class="errorContainer"></div> + + <script type="text/javascript"> + new VisIntegrater(function(c) { + errorVis.afterLoad(function() { + errorVis.openIn(c); + errorVis.showMarker(203); + }); + }, function(c) { + errorVis.remove(c); + }, ".errorContainer"); + </script> </div> <div class="step slide mdl-layout mdl-js-layout" data-x="0" data-y="1000"> @@ -62,7 +141,7 @@ }); }, function(c) { weightsWrapper.remove(c); - }); + }, ".visContainer"); </script> </div> @@ -81,7 +160,7 @@ }); }, function(c) { weightsWrapper.remove(c); - }); + }, ".visContainer"); </script> </div> </div> |
