/* custom d3 widgets */ // slider function makeSlider(labelName, x, y, scale, cb) { var brush = d3.svg.brush() .x(scale) .extent([0, 0]) .on("brush", brushed); var label = svg.append("text") .attr("x", x-5) .attr("y", y) .text(labelName); var brushg = svg.append("g") .attr("transform", "translate(" + x + "," + (y+10) + ")"); brushg.append("g") .attr("class", "x axis") .call(d3.svg.axis() .scale(scale) .ticks(5) .tickSize(1) .tickFormat(function(d) { return Math.floor(d*100) + "%"; }) .tickPadding(10) .orient("bottom")); var slider = brushg.append("g") .attr("class", "slider") .call(brush); var handle = slider.append("circle") .attr("r", 5) .attr("cx", 0) .attr("cy", 0) .attr("stroke", "#000") .attr("fill", "#DDD"); slider.call(brush); function brushed() { var value = brush.extent()[0]; if (d3.event.sourceEvent) { // not a programmatic event value = scale.invert(d3.mouse(this)[0]); brush.extent([value, value]); } handle.attr("cx", scale(value)); cb(value); } } /* network construction */ var Network = (function() { function Network(layout) { this.layout = layout; } Network.prototype.init = function() { this._createNodes(); this._createLinks(); }; Network.prototype.resize = function(env) { var largestLayerSize = 0; for (layer=0; layer largestLayerSize) largestLayerSize = this.layout.net[layer].size; } this.responsiveRadius = d3.min([env.width, env.height]) / d3.max([this.layout.net.layers, largestLayerSize]); this._updateNodes(env); }; Network.prototype._createNodes = function() { // create layers this.nodes = []; for (layer=0; layer layout.layers[batch][epoch].max) layout.layers[batch][epoch].max = layerMax; } } } console.log(layout); // DEBUG if (this._finished) this._finished(layout, json); }; return Loader; })(); var Animator = (function() { function Animator(layout, time, step) { this.layout = layout; this.step = step; this.batch = this.epoch = 0; this.frameDuration = time / (this.layout.data.batches * this.layout.data.epochs / this.step); console.log("frame duration:" + this.frameDuration); // DEBUG } Animator.prototype.start = function(callback) { var self = this; wrapper = function() { callback(self.batch, self.epoch, self.frameDuration); self.animate(); }; this.pid = setInterval(wrapper, this.frameDuration); }; Animator.prototype.animate = function() { this.epoch += this.step; if (this.epoch >= this.layout.data.epochs) { this.epoch = 0; if (++this.batch>= this.layout.data.batches) { this.batch = 0; clearInterval(this.pid); // suicide console.log("finished"); } } }; return Animator; })(); var Visualizer = (function() { function Visualizer(svg) { this.loader = new Loader(); this.svg = svg; } Visualizer.prototype.start = function(url, animationTime, resolution) { // animationTime in seconds per frame // resolution in epochs per frame var self = this; this.animationTime = animationTime; this.resolution = resolution; function wrapper(layout, data) { self.layout = layout; self.data = data; self._setup(); } this.loader.load("data/log.json", wrapper); }; Visualizer.prototype._setup = function() { console.log("setup"); // DEBUG var self = this; // create empty elements and determine the visualisation's size this.svg .attr("width", "100%") .attr("height", "100%"); var width = parseInt(this.svg.style("width")) || 800, height = parseInt(this.svg.style("height")) || 600; /*var slideScaler = d3.scale.linear() .domain([0, 180]) .range([0, 200]) .clamp(true); function slid(val) { console.log(val); } makeSlider("Test", 10, 20, slideScaler, slid);*/ this.network = new Network(this.layout); this.network.init(); this.network.resize({"width": width, "height": height}); this.network.updateWeights(this.data[0][0], this.layout.layers[0][0]); function resized() { width = parseInt(self.svg.style("width")) || 800; height = parseInt(self.svg.style("height")) || 600; self.network.resize({"width": width, "height": height}); node .attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }) .attr("r", function(d) { return d.r; }); link .attr("x1", function(d) { return d.source.x; }) .attr("y1", function(d) { return d.source.y; }) .attr("x2", function(d) { return d.target.x; }) .attr("y2", function(d) { return d.target.y; }); } window.addEventListener("resize", resized, true); var link = this.svg.selectAll(".link") .data(this.network.links) .enter().append("line") .attr("class", "link") .style("stroke", "grey") .style("stroke-width", function(d) { return d.weight * 10; }) .attr("x1", function(d) { return d.source.x; }) .attr("y1", function(d) { return d.source.y; }) .attr("x2", function(d) { return d.target.x; }) .attr("y2", function(d) { return d.target.y; }); var node = this.svg.selectAll(".node") .data(this.network.nodes) .enter().append("circle") .attr("class", "node") .attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }) .attr("r", function(d) { return d.r; }); this.animator = new Animator(this.layout, this.animationTime * 1000, this.resolution); this.animator.start(function(batch, epoch, duration) { self.network.updateWeights(self.data[batch][epoch], self.layout.layers[batch][epoch]); // 10% extra time per frame for the code execution duration = duration / 1.1; link .transition() .duration(duration) .style("stroke-width", function(d) { return d.weight * 10; }); }); }; return Visualizer; })(); var svg = d3.select("#visContainer").append("svg"); var visualizer = new Visualizer(svg); visualizer.start("data/log.json", 30, 10);