diff --git a/bower.json b/bower.json index fe88b57..192f2bb 100755 --- a/bower.json +++ b/bower.json @@ -20,7 +20,7 @@ "iron-icon": "PolymerElements/iron-icon#~1.0.7", "iron-icons": "PolymerElements/iron-icons#~1.1.2", "paper-toast": "PolymerElements/paper-toast#~1.2.1", - "d3-scatterplot-matrix": "^0.1.0", - "d3-scatterplot": "^1.1.0" + "d3-scatterplot-matrix": "latest", + "d3-scatterplot": "latest" } } diff --git a/bower_components/d3-scatterplot-matrix/LICENSE b/bower_components/d3-scatterplot-matrix/LICENSE new file mode 100644 index 0000000..102655c --- /dev/null +++ b/bower_components/d3-scatterplot-matrix/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 MichaƂ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/bower_components/d3-scatterplot-matrix/bower.json b/bower_components/d3-scatterplot-matrix/bower.json new file mode 100644 index 0000000..013ad93 --- /dev/null +++ b/bower_components/d3-scatterplot-matrix/bower.json @@ -0,0 +1,26 @@ +{ + "name": "d3-scatterplot-matrix", + "homepage": "https://github.com/mwasiluk/d3-scatterplot-matrix", + "authors": [ + "Michal Wasiluk" + ], + "description": "", + "main": "", + "keywords": [ + "scatterplot", + "d3", + "matrix" + + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "d3": "^3.5.17" + } +} diff --git a/bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.css b/bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.css new file mode 100644 index 0000000..9b51ced --- /dev/null +++ b/bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.css @@ -0,0 +1,36 @@ +svg.mw-d3-scatterplot-matrix { + background-color: white; + font-size: 11px; + height: 100%; } + svg.mw-d3-scatterplot-matrix .mw-axis { + shape-rendering: crispEdges; } + svg.mw-d3-scatterplot-matrix .mw-axis path { + display: none; } + svg.mw-d3-scatterplot-matrix .mw-axis line { + stroke: #ddd; } + svg.mw-d3-scatterplot-matrix .mw-axis.mw-no-guides line { + display: none; } + svg.mw-d3-scatterplot-matrix .mw-frame { + shape-rendering: crispEdges; + fill: none; + stroke: #aaa; } + svg.mw-d3-scatterplot-matrix .mw-cell text { + font-weight: bold; + text-transform: capitalize; } + svg.mw-d3-scatterplot-matrix circle { + fill-opacity: .7; } + svg.mw-d3-scatterplot-matrix circle.hidden { + fill: #ccc !important; } + svg.mw-d3-scatterplot-matrix .extent { + fill: #000; + fill-opacity: .125; + stroke: #fff; } + +.mw-tooltip { + position: absolute; + pointer-events: none; + font-size: 11px; + background: #fdfdfd; + padding: 3px 5px; + border-radius: 8px; + box-shadow: 1px 3px 3px #b7b7b7; } diff --git a/bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.js b/bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.js new file mode 100644 index 0000000..e24b531 --- /dev/null +++ b/bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.js @@ -0,0 +1,483 @@ +function D3ScatterPlotMatrixUtils() { +} + +// usage example deepExtend({}, objA, objB); => should work similar to $.extend(true, {}, objA, objB); +D3ScatterPlotMatrixUtils.prototype.deepExtend = function (out) { //TODO consider using jquery / lo-dash / underscore / ECMA6 ; fallbacks? + + var utils = this; + var emptyOut = {}; + + + if (!out && arguments.length > 1 && Array.isArray(arguments[1])) { + out = []; + } + out = out || {}; + + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + if (!source) + continue; + + for (var key in source) { + if (!source.hasOwnProperty(key)) { + continue; + } + var isArray = Array.isArray(out[key]); + var isObject = utils.isObject(out[key]); + var srcObj = utils.isObject(source[key]); + + if (isObject && !isArray && srcObj) { + utils.deepExtend(out[key], source[key]); + } else { + out[key] = source[key]; + } + } + } + + return out; +}; + +D3ScatterPlotMatrixUtils.prototype.cross = function (a, b) { + var c = [], n = a.length, m = b.length, i, j; + for (i = -1; ++i < n;) for (j = -1; ++j < m;) c.push({x: a[i], i: i, y: b[j], j: j}); + return c; +}; + +D3ScatterPlotMatrixUtils.prototype.inferTraits = function (data, categoryKey, includeCategory) { + var res = []; + if (data.length) { + var d = data[0]; + if (d instanceof Array) { + res= d.map(function (v, i) { + return i; + }); + }else if (typeof d === 'object'){ + + for (var prop in d) { + if(!d.hasOwnProperty(prop)) continue; + + res.push(prop); + } + } + } + if(!includeCategory){ + var index = res.indexOf(categoryKey); + if (index > -1) { + res.splice(index, 1); + } + } + return res +}; + + +D3ScatterPlotMatrixUtils.prototype.isObject = function(a) { + return a !== null && typeof a === 'object'; +}; +D3ScatterPlotMatrixUtils.prototype.isNumber = function(a) { + return !isNaN(a) && typeof a === 'number'; +}; +D3ScatterPlotMatrixUtils.prototype.isFunction = function(a) { + return typeof a === 'function'; +}; + +D3ScatterPlotMatrixUtils.prototype.selectOrAppend = function (parent, selector, element) { + var selection = parent.select(selector); + if(selection.empty()){ + return parent.append(element || selector); + } + return selection; +}; +function D3ScatterPlotMatrix(placeholderSelector, data, config) { + this.utils = new D3ScatterPlotMatrixUtils(); + this.placeholderSelector = placeholderSelector; + this.svg = null; + this.defaultConfig = { + width: 0, + size: 200, //cell size + padding: 20, //cell padding + brush: true, + guides: true, + tooltip: true, + ticks: null, + margin: { + left: 30, + right: 30, + top: 30, + bottom: 30 + }, + x: {// X axis config + orient: "bottom", + scale: "linear" + }, + y: {// Y axis config + orient: "left", + scale: "linear" + }, + dot: { + radius: 2, + color: null, // string or function returning color's value for color scale + d3ColorCategory: 'category10' + }, + traits: { + labels: [], //optional array of trait labels + keys: [], //optional array of trait keys + categoryKey: null, + includeCategoryInPlot: false, + value: function (d, traitKey) {// trait value accessor + return d[traitKey]; + } + } + }; + + if (config) { + this.setConfig(config); + } + + if (data) { + this.setData(data); + } + + this.init(); +} + +D3ScatterPlotMatrix.prototype.setData = function (data) { + this.data = data; + + + return this; +}; + +D3ScatterPlotMatrix.prototype.setConfig = function (config) { + this.config = this.utils.deepExtend({}, this.defaultConfig, config); + return this; +}; +D3ScatterPlotMatrix.prototype.initPlot = function () { + + + var self = this; + var margin = this.config.margin; + var conf = this.config; + this.plot = { + x: {}, + y: {}, + dot: { + color: null//color scale mapping function + } + }; + + this.setupTraits(); + + this.plot.size = conf.size; + + + var width = conf.width; + var placeholderNode = d3.select(this.placeholderSelector).node(); + + if (!width) { + var maxWidth = margin.left + margin.right + this.plot.traits.length*this.plot.size; + width = Math.min(placeholderNode.getBoundingClientRect().width, maxWidth); + + } + var height = width; + if (!height) { + height = placeholderNode.getBoundingClientRect().height; + } + + this.plot.width = width - margin.left - margin.right; + this.plot.height = height - margin.top - margin.bottom; + + + + + if(conf.ticks===null){ + conf.ticks = this.plot.size / 40; + } + + this.setupX(); + this.setupY(); + + if (conf.dot.d3ColorCategory) { + this.plot.dot.colorCategory = d3.scale[conf.dot.d3ColorCategory](); + } + var colorValue = conf.dot.color; + if (colorValue) { + this.plot.dot.colorValue = colorValue; + + if (typeof colorValue === 'string' || colorValue instanceof String) { + this.plot.dot.color = colorValue; + } else if (this.plot.dot.colorCategory) { + this.plot.dot.color = function (d) { + return self.plot.dot.colorCategory(self.plot.dot.colorValue(d)); + } + } + + + }else if(conf.traits.categoryKey){ + this.plot.dot.color = function (d) { + return self.plot.dot.colorCategory(d[conf.traits.categoryKey]); + } + } + + + + return this; + +}; + +D3ScatterPlotMatrix.prototype.setupTraits = function () { + var traitsConf = this.config.traits; + + var data = this.data; + var plot = this.plot; + plot.domainByTrait = {}; + plot.traits = traitsConf.keys; + if(!plot.traits || !plot.traits.length){ + plot.traits = this.utils.inferTraits(data, traitsConf.categoryKey, traitsConf.includeCategoryInPlot); + } + + plot.labels = []; + plot.labelByTrait = {}; + plot.traits.forEach(function(traitKey, index) { + plot.domainByTrait[traitKey] = d3.extent(data, function(d) { return traitsConf.value(d, traitKey) }); + var label = traitKey; + if(traitsConf.labels && traitsConf.labels.length>index){ + + label = traitsConf.labels[index]; + } + plot.labels.push(label); + plot.labelByTrait[traitKey] = label; + }); + + console.log(plot.labelByTrait); + + plot.subplots = []; +}; + +D3ScatterPlotMatrix.prototype.setupX = function () { + + var plot = this.plot; + var x = plot.x; + var conf = this.config; + + x.value = conf.traits.value; + x.scale = d3.scale[conf.x.scale]().range([conf.padding / 2, plot.size - conf.padding / 2]); + x.map = function (d, trait) { + return x.scale(x.value(d, trait)); + }; + x.axis = d3.svg.axis().scale(x.scale).orient(conf.x.orient).ticks(conf.ticks); + x.axis.tickSize(plot.size * plot.traits.length); + +}; + +D3ScatterPlotMatrix.prototype.setupY = function () { + + var plot = this.plot; + var y = plot.y; + var conf = this.config; + + y.value = conf.traits.value; + y.scale = d3.scale[conf.y.scale]().range([ plot.size - conf.padding / 2, conf.padding / 2]); + y.map = function (d, trait) { + return y.scale(y.value(d, trait)); + }; + y.axis= d3.svg.axis().scale(y.scale).orient(conf.y.orient).ticks(conf.ticks); + y.axis.tickSize(-plot.size * plot.traits.length); +}; + + +D3ScatterPlotMatrix.prototype.drawPlot = function () { + var self =this; + var n = self.plot.traits.length; + var conf = this.config; + self.svgG.selectAll(".mw-axis-x.mw-axis") + .data(self.plot.traits) + .enter().append("g") + .attr("class", "mw-axis-x mw-axis"+(conf.guides ? '' : ' mw-no-guides')) + .attr("transform", function(d, i) { return "translate(" + (n - i - 1) * self.plot.size + ",0)"; }) + .each(function(d) { self.plot.x.scale.domain(self.plot.domainByTrait[d]); d3.select(this).call(self.plot.x.axis); }); + + self.svgG.selectAll(".mw-axis-y.mw-axis") + .data(self.plot.traits) + .enter().append("g") + .attr("class", "mw-axis-y mw-axis"+(conf.guides ? '' : ' mw-no-guides')) + .attr("transform", function(d, i) { return "translate(0," + i * self.plot.size + ")"; }) + .each(function(d) { self.plot.y.scale.domain(self.plot.domainByTrait[d]); d3.select(this).call(self.plot.y.axis); }); + + + if(conf.tooltip){ + self.plot.tooltip = this.utils.selectOrAppend(d3.select(self.placeholderSelector), 'div.mw-tooltip', 'div') + .attr("class", "mw-tooltip") + .style("opacity", 0); + } + + var cell = self.svgG.selectAll(".mw-cell") + .data(self.utils.cross(self.plot.traits, self.plot.traits)) + .enter().append("g") + .attr("class", "mw-cell") + .attr("transform", function(d) { return "translate(" + (n - d.i - 1) * self.plot.size + "," + d.j * self.plot.size + ")"; }); + + if(conf.brush){ + this.drawBrush(cell); + } + + cell.each(plotSubplot); + + + + //Labels + cell.filter(function(d) { return d.i === d.j; }).append("text") + .attr("x", conf.padding) + .attr("y", conf.padding) + .attr("dy", ".71em") + .text(function(d) { return self.plot.labelByTrait[d.x]; }); + + + + + function plotSubplot(p) { + var plot = self.plot; + plot.subplots.push(p); + var cell = d3.select(this); + + plot.x.scale.domain(plot.domainByTrait[p.x]); + plot.y.scale.domain(plot.domainByTrait[p.y]); + + cell.append("rect") + .attr("class", "mw-frame") + .attr("x", conf.padding / 2) + .attr("y", conf.padding / 2) + .attr("width", conf.size - conf.padding) + .attr("height", conf.size - conf.padding); + + + p.update = function(){ + var subplot = this; + var dots = cell.selectAll("circle") + .data(self.data); + + dots.enter().append("circle"); + + dots.attr("cx", function(d){return plot.x.map(d, subplot.x)}) + .attr("cy", function(d){return plot.y.map(d, subplot.y)}) + .attr("r", self.config.dot.radius); + + if (plot.dot.color) { + dots.style("fill", plot.dot.color) + } + + if(plot.tooltip){ + dots.on("mouseover", function(d) { + plot.tooltip.transition() + .duration(200) + .style("opacity", .9); + plot.tooltip.html("(" + plot.x.value(d, subplot.x) + + ", " +plot.y.value(d, subplot.y) + ")") + .style("left", (d3.event.pageX + 5) + "px") + .style("top", (d3.event.pageY - 28) + "px"); + }) + .on("mouseout", function(d) { + plot.tooltip.transition() + .duration(500) + .style("opacity", 0); + }); + } + + dots.exit().remove(); + }; + + p.update(); + } + + +}; + +D3ScatterPlotMatrix.prototype.update = function () { + this.plot.subplots.forEach(function(p){p.update()}); +}; + + +D3ScatterPlotMatrix.prototype.initSvg = function () { + + var self = this; + var config = this.config; + + + + var width = self.plot.width+ config.margin.left + config.margin.right; + var height = self.plot.height+ config.margin.top + config.margin.bottom; + var aspect = width / height; + + + + self.svg = d3.select(self.placeholderSelector).select("svg"); + if(!self.svg.empty()){ + self.svg.remove(); + + } + self.svg = d3.select(self.placeholderSelector).append("svg"); + + self.svg + .attr("width", width) + .attr("height", height) + .attr("viewBox", "0 0 "+" "+width+" "+height) + .attr("preserveAspectRatio", "xMidYMid meet") + .attr("class", "mw-d3-scatterplot-matrix"); + + self.svgG = self.svg.append("g") + .attr("class", "mw-container") + .attr("transform", "translate(" + config.margin.left + "," + config.margin.top + ")"); + + + if(!config.width || config.height ){ + d3.select(window) + .on("resize", function() { + //TODO add responsiveness if width/height not specified + }); + } +}; + +D3ScatterPlotMatrix.prototype.init = function () { + var self = this; + self.initPlot(); + self.initSvg(); + self.drawPlot(); +}; + +D3ScatterPlotMatrix.prototype.drawBrush = function (cell) { + var self = this; + var brush = d3.svg.brush() + .x(self.plot.x.scale) + .y(self.plot.y.scale) + .on("brushstart", brushstart) + .on("brush", brushmove) + .on("brushend", brushend); + + cell.append("g").call(brush); + + + var brushCell; + + // Clear the previously-active brush, if any. + function brushstart(p) { + if (brushCell !== this) { + d3.select(brushCell).call(brush.clear()); + self.plot.x.scale.domain(self.plot.domainByTrait[p.x]); + self.plot.y.scale.domain(self.plot.domainByTrait[p.y]); + brushCell = this; + } + } + + // Highlight the selected circles. + function brushmove(p) { + var e = brush.extent(); + self.svgG.selectAll("circle").classed("hidden", function (d) { + return e[0][0] > d[p.x] || d[p.x] > e[1][0] + || e[0][1] > d[p.y] || d[p.y] > e[1][1]; + }); + } + // If the brush is empty, select all circles. + function brushend() { + if (brush.empty()) self.svgG.selectAll(".hidden").classed("hidden", false); + } +}; + diff --git a/bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.min.css b/bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.min.css new file mode 100644 index 0000000..5aabd35 --- /dev/null +++ b/bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.min.css @@ -0,0 +1 @@ +svg.mw-d3-scatterplot-matrix .mw-axis path,svg.mw-d3-scatterplot-matrix .mw-axis.mw-no-guides line{display:none}svg.mw-d3-scatterplot-matrix{background-color:#fff;font-size:11px;height:100%}svg.mw-d3-scatterplot-matrix .mw-axis{shape-rendering:crispEdges}svg.mw-d3-scatterplot-matrix .mw-axis line{stroke:#ddd}svg.mw-d3-scatterplot-matrix .mw-frame{shape-rendering:crispEdges;fill:none;stroke:#aaa}svg.mw-d3-scatterplot-matrix .mw-cell text{font-weight:700;text-transform:capitalize}svg.mw-d3-scatterplot-matrix circle{fill-opacity:.7}svg.mw-d3-scatterplot-matrix circle.hidden{fill:#ccc!important}svg.mw-d3-scatterplot-matrix .extent{fill:#000;fill-opacity:.125;stroke:#fff}.mw-tooltip{position:absolute;pointer-events:none;font-size:11px;background:#fdfdfd;padding:3px 5px;border-radius:8px;box-shadow:1px 3px 3px #b7b7b7} \ No newline at end of file diff --git a/bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.min.js b/bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.min.js new file mode 100644 index 0000000..0a5e8e2 --- /dev/null +++ b/bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.min.js @@ -0,0 +1,2 @@ +function D3ScatterPlotMatrixUtils(){}D3ScatterPlotMatrixUtils.prototype.deepExtend=function(t){var r=this;!t&&arguments.length>1&&Array.isArray(arguments[1])&&(t=[]),t=t||{};for(var e=1;e-1&&i.splice(a,1)}return i},D3ScatterPlotMatrixUtils.prototype.isObject=function(t){return null!==t&&"object"==typeof t},D3ScatterPlotMatrixUtils.prototype.isNumber=function(t){return!isNaN(t)&&"number"==typeof t},D3ScatterPlotMatrixUtils.prototype.isFunction=function(t){return"function"==typeof t},D3ScatterPlotMatrixUtils.prototype.selectOrAppend=function(t,r,e){var i=t.select(r);return i.empty()?t.append(e||r):i}; +function D3ScatterPlotMatrix(t,i,e){this.utils=new D3ScatterPlotMatrixUtils,this.placeholderSelector=t,this.svg=null,this.defaultConfig={width:0,size:200,padding:20,brush:!0,guides:!0,tooltip:!0,ticks:null,margin:{left:30,right:30,top:30,bottom:30},x:{orient:"bottom",scale:"linear"},y:{orient:"left",scale:"linear"},dot:{radius:2,color:null,d3ColorCategory:"category10"},traits:{labels:[],keys:[],categoryKey:null,includeCategoryInPlot:!1,value:function(t,i){return t[i]}}},e&&this.setConfig(e),i&&this.setData(i),this.init()}D3ScatterPlotMatrix.prototype.setData=function(t){return this.data=t,this},D3ScatterPlotMatrix.prototype.setConfig=function(t){return this.config=this.utils.deepExtend({},this.defaultConfig,t),this},D3ScatterPlotMatrix.prototype.initPlot=function(){var t=this,i=this.config.margin,e=this.config;this.plot={x:{},y:{},dot:{color:null}},this.setupTraits(),this.plot.size=e.size;var a=e.width,o=d3.select(this.placeholderSelector).node();if(!a){var l=i.left+i.right+this.plot.traits.length*this.plot.size;a=Math.min(o.getBoundingClientRect().width,l)}var r=a;r||(r=o.getBoundingClientRect().height),this.plot.width=a-i.left-i.right,this.plot.height=r-i.top-i.bottom,null===e.ticks&&(e.ticks=this.plot.size/40),this.setupX(),this.setupY(),e.dot.d3ColorCategory&&(this.plot.dot.colorCategory=d3.scale[e.dot.d3ColorCategory]());var s=e.dot.color;return s?(this.plot.dot.colorValue=s,"string"==typeof s||s instanceof String?this.plot.dot.color=s:this.plot.dot.colorCategory&&(this.plot.dot.color=function(i){return t.plot.dot.colorCategory(t.plot.dot.colorValue(i))})):e.traits.categoryKey&&(this.plot.dot.color=function(i){return t.plot.dot.colorCategory(i[e.traits.categoryKey])}),this},D3ScatterPlotMatrix.prototype.setupTraits=function(){var t=this.config.traits,i=this.data,e=this.plot;e.domainByTrait={},e.traits=t.keys,e.traits&&e.traits.length||(e.traits=this.utils.inferTraits(i,t.categoryKey,t.includeCategoryInPlot)),e.labels=[],e.labelByTrait={},e.traits.forEach(function(a,o){e.domainByTrait[a]=d3.extent(i,function(i){return t.value(i,a)});var l=a;t.labels&&t.labels.length>o&&(l=t.labels[o]),e.labels.push(l),e.labelByTrait[a]=l}),void 0,e.subplots=[]},D3ScatterPlotMatrix.prototype.setupX=function(){var t=this.plot,i=t.x,e=this.config;i.value=e.traits.value,i.scale=d3.scale[e.x.scale]().range([e.padding/2,t.size-e.padding/2]),i.map=function(t,e){return i.scale(i.value(t,e))},i.axis=d3.svg.axis().scale(i.scale).orient(e.x.orient).ticks(e.ticks),i.axis.tickSize(t.size*t.traits.length)},D3ScatterPlotMatrix.prototype.setupY=function(){var t=this.plot,i=t.y,e=this.config;i.value=e.traits.value,i.scale=d3.scale[e.y.scale]().range([t.size-e.padding/2,e.padding/2]),i.map=function(t,e){return i.scale(i.value(t,e))},i.axis=d3.svg.axis().scale(i.scale).orient(e.y.orient).ticks(e.ticks),i.axis.tickSize(-t.size*t.traits.length)},D3ScatterPlotMatrix.prototype.drawPlot=function(){function t(t){var e=i.plot;e.subplots.push(t);var o=d3.select(this);e.x.scale.domain(e.domainByTrait[t.x]),e.y.scale.domain(e.domainByTrait[t.y]),o.append("rect").attr("class","mw-frame").attr("x",a.padding/2).attr("y",a.padding/2).attr("width",a.size-a.padding).attr("height",a.size-a.padding),t.update=function(){var t=this,a=o.selectAll("circle").data(i.data);a.enter().append("circle"),a.attr("cx",function(i){return e.x.map(i,t.x)}).attr("cy",function(i){return e.y.map(i,t.y)}).attr("r",i.config.dot.radius),e.dot.color&&a.style("fill",e.dot.color),e.tooltip&&a.on("mouseover",function(i){e.tooltip.transition().duration(200).style("opacity",.9),e.tooltip.html("("+e.x.value(i,t.x)+", "+e.y.value(i,t.y)+")").style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px")}).on("mouseout",function(t){e.tooltip.transition().duration(500).style("opacity",0)}),a.exit().remove()},t.update()}var i=this,e=i.plot.traits.length,a=this.config;i.svgG.selectAll(".mw-axis-x.mw-axis").data(i.plot.traits).enter().append("g").attr("class","mw-axis-x mw-axis"+(a.guides?"":" mw-no-guides")).attr("transform",function(t,a){return"translate("+(e-a-1)*i.plot.size+",0)"}).each(function(t){i.plot.x.scale.domain(i.plot.domainByTrait[t]),d3.select(this).call(i.plot.x.axis)}),i.svgG.selectAll(".mw-axis-y.mw-axis").data(i.plot.traits).enter().append("g").attr("class","mw-axis-y mw-axis"+(a.guides?"":" mw-no-guides")).attr("transform",function(t,e){return"translate(0,"+e*i.plot.size+")"}).each(function(t){i.plot.y.scale.domain(i.plot.domainByTrait[t]),d3.select(this).call(i.plot.y.axis)}),a.tooltip&&(i.plot.tooltip=this.utils.selectOrAppend(d3.select(i.placeholderSelector),"div.mw-tooltip","div").attr("class","mw-tooltip").style("opacity",0));var o=i.svgG.selectAll(".mw-cell").data(i.utils.cross(i.plot.traits,i.plot.traits)).enter().append("g").attr("class","mw-cell").attr("transform",function(t){return"translate("+(e-t.i-1)*i.plot.size+","+t.j*i.plot.size+")"});a.brush&&this.drawBrush(o),o.each(t),o.filter(function(t){return t.i===t.j}).append("text").attr("x",a.padding).attr("y",a.padding).attr("dy",".71em").text(function(t){return i.plot.labelByTrait[t.x]})},D3ScatterPlotMatrix.prototype.update=function(){this.plot.subplots.forEach(function(t){t.update()})},D3ScatterPlotMatrix.prototype.initSvg=function(){var t=this,i=this.config,e=t.plot.width+i.margin.left+i.margin.right,a=t.plot.height+i.margin.top+i.margin.bottom;t.svg=d3.select(t.placeholderSelector).select("svg"),t.svg.empty()||t.svg.remove(),t.svg=d3.select(t.placeholderSelector).append("svg"),t.svg.attr("width",e).attr("height",a).attr("viewBox","0 0 "+e+" "+a).attr("preserveAspectRatio","xMidYMid meet").attr("class","mw-d3-scatterplot-matrix"),t.svgG=t.svg.append("g").attr("class","mw-container").attr("transform","translate("+i.margin.left+","+i.margin.top+")"),i.width&&!i.height||d3.select(window).on("resize",function(){})},D3ScatterPlotMatrix.prototype.init=function(){var t=this;t.initPlot(),t.initSvg(),t.drawPlot()},D3ScatterPlotMatrix.prototype.drawBrush=function(t){function i(t){r!==this&&(d3.select(r).call(l.clear()),o.plot.x.scale.domain(o.plot.domainByTrait[t.x]),o.plot.y.scale.domain(o.plot.domainByTrait[t.y]),r=this)}function e(t){var i=l.extent();o.svgG.selectAll("circle").classed("hidden",function(e){return i[0][0]>e[t.x]||e[t.x]>i[1][0]||i[0][1]>e[t.y]||e[t.y]>i[1][1]})}function a(){l.empty()&&o.svgG.selectAll(".hidden").classed("hidden",!1)}var o=this,l=d3.svg.brush().x(o.plot.x.scale).y(o.plot.y.scale).on("brushstart",i).on("brush",e).on("brushend",a);t.append("g").call(l);var r}; \ No newline at end of file diff --git a/datalets/scatterplot-datalet/scatterplot-datalet.html b/datalets/scatterplot-datalet/scatterplot-datalet.html index 35b2a1d..99a92b3 100644 --- a/datalets/scatterplot-datalet/scatterplot-datalet.html +++ b/datalets/scatterplot-datalet/scatterplot-datalet.html @@ -47,7 +47,6 @@ }; var plot = new D3ScatterPlot("#scatterplot-placeholder", data, conf); - plot.init(); } };