!function() { var viz = {}; viz.sim = new viz_Sim(); function viz_Sim() {} viz_Sim.prototype.linear = function(x, N) { var randn = d3.random.normal(); var X = []; x.forEach(function(d, i) { for (var j = 0; j < N; j++) { X.push({ features: [ d.mu[0] + randn() * d.std[0], d.mu[1] + randn() * d.std[1] ], label: i }); } }); return X; }; viz_Sim.prototype.nonlinear = function(x, N) { return null; }; viz.mpld3 = {}; viz.mpld3.props = {}; viz.mpld3.scatter = viz_mpld3_scatter; function viz_mpld3_scatter() { var xlim, ylim; var color = d3.scale.category10(); var xValue = function(d) { return d.x; }; var yValue = function(d) { return d.y; }; var cValue = function(d) { return d.id; }; function chart(data) { data = data.map(function(d, i) { return [ xValue.call(data, d, i), yValue.call(data, d, i), cValue.call(data, d, i) ]; }); if (!xlim) { xlim = d3.extent(data, function(d) { return d[0]; }); } if (!ylim) { ylim = d3.extent(data, function(d) { return d[1]; }); } var props = viz_copy(default_figure); var groupByLabel = d3.nest().key(function(d) { return d[2]; }).entries(data); props.data = {}; groupByLabel.forEach(function(d, i) { props.data["data" + i] = d.values.map(function(d) { return [ d[0], d[1] ]; }); }); var props_axes = viz_copy(default_axes); props_axes.xlim = xlim; props_axes.ylim = ylim; groupByLabel.forEach(function(d, i) { var props_data = viz_copy(default_markers); props_data.data = "data" + i; props_data.facecolor = color(i); props_axes.markers.push(props_data); }); var xprops_grid = viz_copy(default_grid); xprops_grid.xy = "x"; props_axes.axes[1].grid = xprops_grid; var yprops_grid = viz_copy(default_grid); yprops_grid.xy = "y"; props_axes.axes[0].grid = yprops_grid; props.axes.push(props_axes); return props; } function X(d) { return xscale(d[0]); } function Y(d) { return yscale(d[1]); } function C(d) { return color(d[2]); } chart.x = function(_) { if (!arguments.length) return xValue; xValue = _; return chart; }; chart.y = function(_) { if (!arguments.length) return yValue; yValue = _; return chart; }; chart.c = function(_) { if (!arguments.length) return cValue; cValue = _; return chart; }; chart.xlim = function(_) { if (!arguments.length) return xlim; xlim = _; return chart; }; chart.ylim = function(_) { if (!arguments.length) return ylim; ylim = _; return chart; }; return chart; } function viz_copy(obj) { if (null == obj || "object" != typeof obj) return obj; if (obj instanceof Date) { var copy = new Date(); copy.setTime(obj.getTime()); return copy; } if (obj instanceof Array) { var copy = []; for (var i = 0, len = obj.length; i < len; i++) { copy[i] = viz_copy(obj[i]); } return copy; } if (obj instanceof Object) { var copy = {}; for (var attr in obj) { if (obj.hasOwnProperty(attr)) copy[attr] = viz_copy(obj[attr]); } return copy; } throw new Error("Unable to copy obj! Its type isn't supported."); } viz.plot = {}; function insert_css(selector, attributes) { var head = document.head || document.getElementsByTagName("head")[0]; var style = document.createElement("style"); var css = selector + " {"; for (var prop in attributes) { css += prop + ":" + attributes[prop] + "; "; } css += "}"; style.type = "text/css"; if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } head.appendChild(style); } viz.plot.figure = viz_Figure; function viz_Figure(props) { this.width = props.width; this.height = props.height; this.canvas = []; this.props = props; this.axes = []; for (var i = 0; i < props.axes.length; i++) this.axes.push(new viz_Axes(this, props.axes[i])); } viz_Figure.prototype.draw = function(figid) { this.canvas = d3.select(figid).selectAll("svg").data([ this.props ]); for (var i = 0; i < this.axes.length; i++) this.axes[i].draw(this.canvas); }; viz.plot.axes = viz_Axes; function viz_Axes(parent, props) { this.parent = parent; this.canvas = parent.canvas; this.props = props; var bbox = props.bbox; this.elements = []; this.position = [ bbox[0] * parent.width, (1 - bbox[1] - bbox[3]) * parent.height ]; this.width = bbox[2] * parent.width; this.height = bbox[3] * parent.height; this.transform = "translate(" + this.position + ")"; this.cssclass = "viz-baseaxes"; this.xscale = d3.scale.linear(); this.yscale = d3.scale.linear(); this.xscale.range([ 0, this.width ]); this.yscale.range([ this.height, 0 ]); this.xscale.domain(this.props.xlim); this.yscale.domain(this.props.ylim); var axes = this.props.axes; for (var i = 0; i < axes.length; i++) { var axis = new viz_Axis(this, props.axes[i]); this.elements.push(axis); if (this.props.gridOn || axis.props.grid.gridOn) { this.elements.push(axis.getGrid()); } } var markers = this.props.markers; for (var i = 0; i < markers.length; i++) { this.elements.push(new viz_Markers(this, markers[i])); } } viz_Axes.prototype.draw = function(canvas) { var gEnter = canvas.enter().append("svg").append("g").attr("transform", this.transform).attr("class", this.cssclass); canvas.attr("width", this.parent.width).attr("height", this.parent.height); gEnter.append("g").attr("class", "viz-background"); gEnter.append("g").attr("class", "viz-x-axis"); gEnter.append("g").attr("class", "viz-y-axis"); gEnter.append("g").attr("class", "viz-border"); gEnter.append("g").attr("class", "viz-zoom"); gEnter.append("g").attr("class", "viz-figure"); gEnter.append("defs").append("clipPath").attr("id", "clip").append("rect").attr("width", this.width).attr("height", this.height); gEnter.select("g.viz-figure").attr("clip-path", "url(#clip)"); gEnter.select("g.viz-background").append("rect").attr("width", this.width).attr("height", this.height).attr("class", "mpld3-axesbg").style("fill", this.props.axesbg).style("fill-opacity", this.props.axesbgalpha); gEnter.select("g.viz-border").append("rect").attr("width", this.width).attr("height", this.height).attr("class", "mpld3-axesborder").style("fill", "#fff").style("fill-opacity", 0).style("stroke", "#000").style("stroke-width", "2pt"); for (var i = 0; i < this.elements.length; i++) this.elements[i].draw(canvas); }; viz.plot.axis = viz_Axis; function viz_Axis(parent, props) { this.parent = parent; this.props = props; var trans = { bottom: [ 0, parent.height ], top: [ 0, 0 ], left: [ 0, 0 ], right: [ parent.width, 0 ] }; var xy = { bottom: "x", top: "x", left: "y", right: "y" }; this.transform = "translate(" + trans[this.props.position] + ")"; this.props.xy = xy[this.props.position]; this.cssclass = "viz-" + this.props.xy + "-axis"; this.scale = parent[this.props.xy + "scale"]; insert_css("." + this.cssclass + " line, " + " ." + this.cssclass + " path", { "shape-rendering": "crispEdges", stroke: this.props.axiscolor, fill: "none" }); insert_css("." + this.cssclass + " text", { "font-family": "sans-serif", "font-size": this.props.fontsize, fill: this.props.fontcolor, stroke: "none" }); } viz_Axis.prototype.draw = function(canvas) { this.axis = d3.svg.axis().scale(this.scale).orient(this.props.position).ticks(this.props.nticks).tickValues(this.props.tickvalues).tickFormat(this.props.tickformat); this.elem = canvas.select("g." + this.cssclass).attr("transform", this.transform).call(this.axis); }; viz_Axis.prototype.getGrid = function() { var gridprop = { nticks: this.props.nticks, zorder: this.props.zorder, tickvalues: this.props.tickvalues, xy: this.props.xy }; if (this.props.grid) { for (var key in this.props.grid) { gridprop[key] = this.props.grid[key]; } } return new viz_Grid(this.parent, gridprop); }; viz.plot.grid = viz_Grid; function viz_Grid(parent, props) { this.parent = parent; this.props = props; this.cssclass = "viz-" + this.props.xy + "-grid"; if (this.props.xy == "x") { this.transform = "translate(0,0)"; this.position = "bottom"; this.scale = parent.xscale; this.tickSize = -parent.height; } else if (this.props.xy == "y") { this.transform = "translate(0,0)"; this.position = "left"; this.scale = parent.yscale; this.tickSize = -parent.width; } else { throw "unrecognized grid xy specifier: should be 'x' or 'y'"; } insert_css("." + this.cssclass + " .tick", { stroke: this.props.color, "stroke-dasharray": this.props.dasharray, "stroke-opacity": this.props.alpha }); insert_css("." + this.cssclass + " path", { "stroke-width": 0 }); } viz_Grid.prototype.draw = function(canvas) { this.grid = d3.svg.axis().scale(this.scale).orient(this.position).ticks(this.props.nticks).tickValues(this.props.tickvalues).tickSize(this.tickSize, 0, 0).tickFormat(""); this.elem = canvas.select("g.viz-" + this.props.xy + "-axis").append("g").attr("class", this.cssclass).attr("transform", this.transform).call(this.grid); }; viz.plot.markers = viz_Markers; function viz_Markers(parent, props) { this.props = props; this.parent = parent; } viz_Markers.prototype.draw = function(canvas) { var gs = canvas.select("g.viz-figure"); var data = this.props.data; var parent = this.parent; var circle = gs.selectAll("circle." + data).data(function(d) { return d.data[data]; }); circle.enter().append("svg:circle").attr("class", data).style("fill", this.props.facecolor).attr("cx", function(d) { return parent.xscale(d[0]); }).attr("cy", function(d) { return parent.yscale(d[1]); }).attr("r", this.props.markersize); circle.transition().style("fill", this.props.facecolor).attr("cx", function(d) { return parent.xscale(d[0]); }).attr("cy", function(d) { return parent.yscale(d[1]); }).attr("r", this.props.markersize); circle.exit().remove(); }; if (typeof module === "object" && module.exports) { module.exports = viz; } else { this.viz = viz; } this.viz = viz; }();