Commit 752c1f5a6ed9d9528e4ed1d1a74a16d5976f7f19

Authored by mwasiluk
1 parent 42187739

updated d3-scatterplot-matrix

bower.json
... ... @@ -20,7 +20,7 @@
20 20 "iron-icon": "PolymerElements/iron-icon#~1.0.7",
21 21 "iron-icons": "PolymerElements/iron-icons#~1.1.2",
22 22 "paper-toast": "PolymerElements/paper-toast#~1.2.1",
23   - "d3-scatterplot-matrix": "^0.1.0",
24   - "d3-scatterplot": "^1.1.0"
  23 + "d3-scatterplot-matrix": "latest",
  24 + "d3-scatterplot": "latest"
25 25 }
26 26 }
... ...
bower_components/d3-scatterplot-matrix/LICENSE 0 → 100644
  1 +The MIT License (MIT)
  2 +
  3 +Copyright (c) 2016 Michał
  4 +
  5 +Permission is hereby granted, free of charge, to any person obtaining a copy
  6 +of this software and associated documentation files (the "Software"), to deal
  7 +in the Software without restriction, including without limitation the rights
  8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9 +copies of the Software, and to permit persons to whom the Software is
  10 +furnished to do so, subject to the following conditions:
  11 +
  12 +The above copyright notice and this permission notice shall be included in all
  13 +copies or substantial portions of the Software.
  14 +
  15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21 +SOFTWARE.
... ...
bower_components/d3-scatterplot-matrix/bower.json 0 → 100644
  1 +{
  2 + "name": "d3-scatterplot-matrix",
  3 + "homepage": "https://github.com/mwasiluk/d3-scatterplot-matrix",
  4 + "authors": [
  5 + "Michal Wasiluk"
  6 + ],
  7 + "description": "",
  8 + "main": "",
  9 + "keywords": [
  10 + "scatterplot",
  11 + "d3",
  12 + "matrix"
  13 +
  14 + ],
  15 + "license": "MIT",
  16 + "ignore": [
  17 + "**/.*",
  18 + "node_modules",
  19 + "bower_components",
  20 + "test",
  21 + "tests"
  22 + ],
  23 + "dependencies": {
  24 + "d3": "^3.5.17"
  25 + }
  26 +}
... ...
bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.css 0 → 100644
  1 +svg.mw-d3-scatterplot-matrix {
  2 + background-color: white;
  3 + font-size: 11px;
  4 + height: 100%; }
  5 + svg.mw-d3-scatterplot-matrix .mw-axis {
  6 + shape-rendering: crispEdges; }
  7 + svg.mw-d3-scatterplot-matrix .mw-axis path {
  8 + display: none; }
  9 + svg.mw-d3-scatterplot-matrix .mw-axis line {
  10 + stroke: #ddd; }
  11 + svg.mw-d3-scatterplot-matrix .mw-axis.mw-no-guides line {
  12 + display: none; }
  13 + svg.mw-d3-scatterplot-matrix .mw-frame {
  14 + shape-rendering: crispEdges;
  15 + fill: none;
  16 + stroke: #aaa; }
  17 + svg.mw-d3-scatterplot-matrix .mw-cell text {
  18 + font-weight: bold;
  19 + text-transform: capitalize; }
  20 + svg.mw-d3-scatterplot-matrix circle {
  21 + fill-opacity: .7; }
  22 + svg.mw-d3-scatterplot-matrix circle.hidden {
  23 + fill: #ccc !important; }
  24 + svg.mw-d3-scatterplot-matrix .extent {
  25 + fill: #000;
  26 + fill-opacity: .125;
  27 + stroke: #fff; }
  28 +
  29 +.mw-tooltip {
  30 + position: absolute;
  31 + pointer-events: none;
  32 + font-size: 11px;
  33 + background: #fdfdfd;
  34 + padding: 3px 5px;
  35 + border-radius: 8px;
  36 + box-shadow: 1px 3px 3px #b7b7b7; }
... ...
bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.js 0 → 100644
  1 +function D3ScatterPlotMatrixUtils() {
  2 +}
  3 +
  4 +// usage example deepExtend({}, objA, objB); => should work similar to $.extend(true, {}, objA, objB);
  5 +D3ScatterPlotMatrixUtils.prototype.deepExtend = function (out) { //TODO consider using jquery / lo-dash / underscore / ECMA6 ; fallbacks?
  6 +
  7 + var utils = this;
  8 + var emptyOut = {};
  9 +
  10 +
  11 + if (!out && arguments.length > 1 && Array.isArray(arguments[1])) {
  12 + out = [];
  13 + }
  14 + out = out || {};
  15 +
  16 + for (var i = 1; i < arguments.length; i++) {
  17 + var source = arguments[i];
  18 + if (!source)
  19 + continue;
  20 +
  21 + for (var key in source) {
  22 + if (!source.hasOwnProperty(key)) {
  23 + continue;
  24 + }
  25 + var isArray = Array.isArray(out[key]);
  26 + var isObject = utils.isObject(out[key]);
  27 + var srcObj = utils.isObject(source[key]);
  28 +
  29 + if (isObject && !isArray && srcObj) {
  30 + utils.deepExtend(out[key], source[key]);
  31 + } else {
  32 + out[key] = source[key];
  33 + }
  34 + }
  35 + }
  36 +
  37 + return out;
  38 +};
  39 +
  40 +D3ScatterPlotMatrixUtils.prototype.cross = function (a, b) {
  41 + var c = [], n = a.length, m = b.length, i, j;
  42 + for (i = -1; ++i < n;) for (j = -1; ++j < m;) c.push({x: a[i], i: i, y: b[j], j: j});
  43 + return c;
  44 +};
  45 +
  46 +D3ScatterPlotMatrixUtils.prototype.inferTraits = function (data, categoryKey, includeCategory) {
  47 + var res = [];
  48 + if (data.length) {
  49 + var d = data[0];
  50 + if (d instanceof Array) {
  51 + res= d.map(function (v, i) {
  52 + return i;
  53 + });
  54 + }else if (typeof d === 'object'){
  55 +
  56 + for (var prop in d) {
  57 + if(!d.hasOwnProperty(prop)) continue;
  58 +
  59 + res.push(prop);
  60 + }
  61 + }
  62 + }
  63 + if(!includeCategory){
  64 + var index = res.indexOf(categoryKey);
  65 + if (index > -1) {
  66 + res.splice(index, 1);
  67 + }
  68 + }
  69 + return res
  70 +};
  71 +
  72 +
  73 +D3ScatterPlotMatrixUtils.prototype.isObject = function(a) {
  74 + return a !== null && typeof a === 'object';
  75 +};
  76 +D3ScatterPlotMatrixUtils.prototype.isNumber = function(a) {
  77 + return !isNaN(a) && typeof a === 'number';
  78 +};
  79 +D3ScatterPlotMatrixUtils.prototype.isFunction = function(a) {
  80 + return typeof a === 'function';
  81 +};
  82 +
  83 +D3ScatterPlotMatrixUtils.prototype.selectOrAppend = function (parent, selector, element) {
  84 + var selection = parent.select(selector);
  85 + if(selection.empty()){
  86 + return parent.append(element || selector);
  87 + }
  88 + return selection;
  89 +};
  90 +function D3ScatterPlotMatrix(placeholderSelector, data, config) {
  91 + this.utils = new D3ScatterPlotMatrixUtils();
  92 + this.placeholderSelector = placeholderSelector;
  93 + this.svg = null;
  94 + this.defaultConfig = {
  95 + width: 0,
  96 + size: 200, //cell size
  97 + padding: 20, //cell padding
  98 + brush: true,
  99 + guides: true,
  100 + tooltip: true,
  101 + ticks: null,
  102 + margin: {
  103 + left: 30,
  104 + right: 30,
  105 + top: 30,
  106 + bottom: 30
  107 + },
  108 + x: {// X axis config
  109 + orient: "bottom",
  110 + scale: "linear"
  111 + },
  112 + y: {// Y axis config
  113 + orient: "left",
  114 + scale: "linear"
  115 + },
  116 + dot: {
  117 + radius: 2,
  118 + color: null, // string or function returning color's value for color scale
  119 + d3ColorCategory: 'category10'
  120 + },
  121 + traits: {
  122 + labels: [], //optional array of trait labels
  123 + keys: [], //optional array of trait keys
  124 + categoryKey: null,
  125 + includeCategoryInPlot: false,
  126 + value: function (d, traitKey) {// trait value accessor
  127 + return d[traitKey];
  128 + }
  129 + }
  130 + };
  131 +
  132 + if (config) {
  133 + this.setConfig(config);
  134 + }
  135 +
  136 + if (data) {
  137 + this.setData(data);
  138 + }
  139 +
  140 + this.init();
  141 +}
  142 +
  143 +D3ScatterPlotMatrix.prototype.setData = function (data) {
  144 + this.data = data;
  145 +
  146 +
  147 + return this;
  148 +};
  149 +
  150 +D3ScatterPlotMatrix.prototype.setConfig = function (config) {
  151 + this.config = this.utils.deepExtend({}, this.defaultConfig, config);
  152 + return this;
  153 +};
  154 +D3ScatterPlotMatrix.prototype.initPlot = function () {
  155 +
  156 +
  157 + var self = this;
  158 + var margin = this.config.margin;
  159 + var conf = this.config;
  160 + this.plot = {
  161 + x: {},
  162 + y: {},
  163 + dot: {
  164 + color: null//color scale mapping function
  165 + }
  166 + };
  167 +
  168 + this.setupTraits();
  169 +
  170 + this.plot.size = conf.size;
  171 +
  172 +
  173 + var width = conf.width;
  174 + var placeholderNode = d3.select(this.placeholderSelector).node();
  175 +
  176 + if (!width) {
  177 + var maxWidth = margin.left + margin.right + this.plot.traits.length*this.plot.size;
  178 + width = Math.min(placeholderNode.getBoundingClientRect().width, maxWidth);
  179 +
  180 + }
  181 + var height = width;
  182 + if (!height) {
  183 + height = placeholderNode.getBoundingClientRect().height;
  184 + }
  185 +
  186 + this.plot.width = width - margin.left - margin.right;
  187 + this.plot.height = height - margin.top - margin.bottom;
  188 +
  189 +
  190 +
  191 +
  192 + if(conf.ticks===null){
  193 + conf.ticks = this.plot.size / 40;
  194 + }
  195 +
  196 + this.setupX();
  197 + this.setupY();
  198 +
  199 + if (conf.dot.d3ColorCategory) {
  200 + this.plot.dot.colorCategory = d3.scale[conf.dot.d3ColorCategory]();
  201 + }
  202 + var colorValue = conf.dot.color;
  203 + if (colorValue) {
  204 + this.plot.dot.colorValue = colorValue;
  205 +
  206 + if (typeof colorValue === 'string' || colorValue instanceof String) {
  207 + this.plot.dot.color = colorValue;
  208 + } else if (this.plot.dot.colorCategory) {
  209 + this.plot.dot.color = function (d) {
  210 + return self.plot.dot.colorCategory(self.plot.dot.colorValue(d));
  211 + }
  212 + }
  213 +
  214 +
  215 + }else if(conf.traits.categoryKey){
  216 + this.plot.dot.color = function (d) {
  217 + return self.plot.dot.colorCategory(d[conf.traits.categoryKey]);
  218 + }
  219 + }
  220 +
  221 +
  222 +
  223 + return this;
  224 +
  225 +};
  226 +
  227 +D3ScatterPlotMatrix.prototype.setupTraits = function () {
  228 + var traitsConf = this.config.traits;
  229 +
  230 + var data = this.data;
  231 + var plot = this.plot;
  232 + plot.domainByTrait = {};
  233 + plot.traits = traitsConf.keys;
  234 + if(!plot.traits || !plot.traits.length){
  235 + plot.traits = this.utils.inferTraits(data, traitsConf.categoryKey, traitsConf.includeCategoryInPlot);
  236 + }
  237 +
  238 + plot.labels = [];
  239 + plot.labelByTrait = {};
  240 + plot.traits.forEach(function(traitKey, index) {
  241 + plot.domainByTrait[traitKey] = d3.extent(data, function(d) { return traitsConf.value(d, traitKey) });
  242 + var label = traitKey;
  243 + if(traitsConf.labels && traitsConf.labels.length>index){
  244 +
  245 + label = traitsConf.labels[index];
  246 + }
  247 + plot.labels.push(label);
  248 + plot.labelByTrait[traitKey] = label;
  249 + });
  250 +
  251 + console.log(plot.labelByTrait);
  252 +
  253 + plot.subplots = [];
  254 +};
  255 +
  256 +D3ScatterPlotMatrix.prototype.setupX = function () {
  257 +
  258 + var plot = this.plot;
  259 + var x = plot.x;
  260 + var conf = this.config;
  261 +
  262 + x.value = conf.traits.value;
  263 + x.scale = d3.scale[conf.x.scale]().range([conf.padding / 2, plot.size - conf.padding / 2]);
  264 + x.map = function (d, trait) {
  265 + return x.scale(x.value(d, trait));
  266 + };
  267 + x.axis = d3.svg.axis().scale(x.scale).orient(conf.x.orient).ticks(conf.ticks);
  268 + x.axis.tickSize(plot.size * plot.traits.length);
  269 +
  270 +};
  271 +
  272 +D3ScatterPlotMatrix.prototype.setupY = function () {
  273 +
  274 + var plot = this.plot;
  275 + var y = plot.y;
  276 + var conf = this.config;
  277 +
  278 + y.value = conf.traits.value;
  279 + y.scale = d3.scale[conf.y.scale]().range([ plot.size - conf.padding / 2, conf.padding / 2]);
  280 + y.map = function (d, trait) {
  281 + return y.scale(y.value(d, trait));
  282 + };
  283 + y.axis= d3.svg.axis().scale(y.scale).orient(conf.y.orient).ticks(conf.ticks);
  284 + y.axis.tickSize(-plot.size * plot.traits.length);
  285 +};
  286 +
  287 +
  288 +D3ScatterPlotMatrix.prototype.drawPlot = function () {
  289 + var self =this;
  290 + var n = self.plot.traits.length;
  291 + var conf = this.config;
  292 + self.svgG.selectAll(".mw-axis-x.mw-axis")
  293 + .data(self.plot.traits)
  294 + .enter().append("g")
  295 + .attr("class", "mw-axis-x mw-axis"+(conf.guides ? '' : ' mw-no-guides'))
  296 + .attr("transform", function(d, i) { return "translate(" + (n - i - 1) * self.plot.size + ",0)"; })
  297 + .each(function(d) { self.plot.x.scale.domain(self.plot.domainByTrait[d]); d3.select(this).call(self.plot.x.axis); });
  298 +
  299 + self.svgG.selectAll(".mw-axis-y.mw-axis")
  300 + .data(self.plot.traits)
  301 + .enter().append("g")
  302 + .attr("class", "mw-axis-y mw-axis"+(conf.guides ? '' : ' mw-no-guides'))
  303 + .attr("transform", function(d, i) { return "translate(0," + i * self.plot.size + ")"; })
  304 + .each(function(d) { self.plot.y.scale.domain(self.plot.domainByTrait[d]); d3.select(this).call(self.plot.y.axis); });
  305 +
  306 +
  307 + if(conf.tooltip){
  308 + self.plot.tooltip = this.utils.selectOrAppend(d3.select(self.placeholderSelector), 'div.mw-tooltip', 'div')
  309 + .attr("class", "mw-tooltip")
  310 + .style("opacity", 0);
  311 + }
  312 +
  313 + var cell = self.svgG.selectAll(".mw-cell")
  314 + .data(self.utils.cross(self.plot.traits, self.plot.traits))
  315 + .enter().append("g")
  316 + .attr("class", "mw-cell")
  317 + .attr("transform", function(d) { return "translate(" + (n - d.i - 1) * self.plot.size + "," + d.j * self.plot.size + ")"; });
  318 +
  319 + if(conf.brush){
  320 + this.drawBrush(cell);
  321 + }
  322 +
  323 + cell.each(plotSubplot);
  324 +
  325 +
  326 +
  327 + //Labels
  328 + cell.filter(function(d) { return d.i === d.j; }).append("text")
  329 + .attr("x", conf.padding)
  330 + .attr("y", conf.padding)
  331 + .attr("dy", ".71em")
  332 + .text(function(d) { return self.plot.labelByTrait[d.x]; });
  333 +
  334 +
  335 +
  336 +
  337 + function plotSubplot(p) {
  338 + var plot = self.plot;
  339 + plot.subplots.push(p);
  340 + var cell = d3.select(this);
  341 +
  342 + plot.x.scale.domain(plot.domainByTrait[p.x]);
  343 + plot.y.scale.domain(plot.domainByTrait[p.y]);
  344 +
  345 + cell.append("rect")
  346 + .attr("class", "mw-frame")
  347 + .attr("x", conf.padding / 2)
  348 + .attr("y", conf.padding / 2)
  349 + .attr("width", conf.size - conf.padding)
  350 + .attr("height", conf.size - conf.padding);
  351 +
  352 +
  353 + p.update = function(){
  354 + var subplot = this;
  355 + var dots = cell.selectAll("circle")
  356 + .data(self.data);
  357 +
  358 + dots.enter().append("circle");
  359 +
  360 + dots.attr("cx", function(d){return plot.x.map(d, subplot.x)})
  361 + .attr("cy", function(d){return plot.y.map(d, subplot.y)})
  362 + .attr("r", self.config.dot.radius);
  363 +
  364 + if (plot.dot.color) {
  365 + dots.style("fill", plot.dot.color)
  366 + }
  367 +
  368 + if(plot.tooltip){
  369 + dots.on("mouseover", function(d) {
  370 + plot.tooltip.transition()
  371 + .duration(200)
  372 + .style("opacity", .9);
  373 + plot.tooltip.html("(" + plot.x.value(d, subplot.x)
  374 + + ", " +plot.y.value(d, subplot.y) + ")")
  375 + .style("left", (d3.event.pageX + 5) + "px")
  376 + .style("top", (d3.event.pageY - 28) + "px");
  377 + })
  378 + .on("mouseout", function(d) {
  379 + plot.tooltip.transition()
  380 + .duration(500)
  381 + .style("opacity", 0);
  382 + });
  383 + }
  384 +
  385 + dots.exit().remove();
  386 + };
  387 +
  388 + p.update();
  389 + }
  390 +
  391 +
  392 +};
  393 +
  394 +D3ScatterPlotMatrix.prototype.update = function () {
  395 + this.plot.subplots.forEach(function(p){p.update()});
  396 +};
  397 +
  398 +
  399 +D3ScatterPlotMatrix.prototype.initSvg = function () {
  400 +
  401 + var self = this;
  402 + var config = this.config;
  403 +
  404 +
  405 +
  406 + var width = self.plot.width+ config.margin.left + config.margin.right;
  407 + var height = self.plot.height+ config.margin.top + config.margin.bottom;
  408 + var aspect = width / height;
  409 +
  410 +
  411 +
  412 + self.svg = d3.select(self.placeholderSelector).select("svg");
  413 + if(!self.svg.empty()){
  414 + self.svg.remove();
  415 +
  416 + }
  417 + self.svg = d3.select(self.placeholderSelector).append("svg");
  418 +
  419 + self.svg
  420 + .attr("width", width)
  421 + .attr("height", height)
  422 + .attr("viewBox", "0 0 "+" "+width+" "+height)
  423 + .attr("preserveAspectRatio", "xMidYMid meet")
  424 + .attr("class", "mw-d3-scatterplot-matrix");
  425 +
  426 + self.svgG = self.svg.append("g")
  427 + .attr("class", "mw-container")
  428 + .attr("transform", "translate(" + config.margin.left + "," + config.margin.top + ")");
  429 +
  430 +
  431 + if(!config.width || config.height ){
  432 + d3.select(window)
  433 + .on("resize", function() {
  434 + //TODO add responsiveness if width/height not specified
  435 + });
  436 + }
  437 +};
  438 +
  439 +D3ScatterPlotMatrix.prototype.init = function () {
  440 + var self = this;
  441 + self.initPlot();
  442 + self.initSvg();
  443 + self.drawPlot();
  444 +};
  445 +
  446 +D3ScatterPlotMatrix.prototype.drawBrush = function (cell) {
  447 + var self = this;
  448 + var brush = d3.svg.brush()
  449 + .x(self.plot.x.scale)
  450 + .y(self.plot.y.scale)
  451 + .on("brushstart", brushstart)
  452 + .on("brush", brushmove)
  453 + .on("brushend", brushend);
  454 +
  455 + cell.append("g").call(brush);
  456 +
  457 +
  458 + var brushCell;
  459 +
  460 + // Clear the previously-active brush, if any.
  461 + function brushstart(p) {
  462 + if (brushCell !== this) {
  463 + d3.select(brushCell).call(brush.clear());
  464 + self.plot.x.scale.domain(self.plot.domainByTrait[p.x]);
  465 + self.plot.y.scale.domain(self.plot.domainByTrait[p.y]);
  466 + brushCell = this;
  467 + }
  468 + }
  469 +
  470 + // Highlight the selected circles.
  471 + function brushmove(p) {
  472 + var e = brush.extent();
  473 + self.svgG.selectAll("circle").classed("hidden", function (d) {
  474 + return e[0][0] > d[p.x] || d[p.x] > e[1][0]
  475 + || e[0][1] > d[p.y] || d[p.y] > e[1][1];
  476 + });
  477 + }
  478 + // If the brush is empty, select all circles.
  479 + function brushend() {
  480 + if (brush.empty()) self.svgG.selectAll(".hidden").classed("hidden", false);
  481 + }
  482 +};
  483 +
... ...
bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.min.css 0 → 100644
  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}
0 2 \ No newline at end of file
... ...
bower_components/d3-scatterplot-matrix/dist/d3-scatterplot-matrix.min.js 0 → 100644
  1 +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<arguments.length;e++){var i=arguments[e];if(i)for(var n in i)if(i.hasOwnProperty(n)){var o=Array.isArray(t[n]),a=r.isObject(t[n]),p=r.isObject(i[n]);a&&!o&&p?r.deepExtend(t[n],i[n]):t[n]=i[n]}}return t},D3ScatterPlotMatrixUtils.prototype.cross=function(t,r){var e,i,n=[],o=t.length,a=r.length;for(e=-1;++e<o;)for(i=-1;++i<a;)n.push({x:t[e],i:e,y:r[i],j:i});return n},D3ScatterPlotMatrixUtils.prototype.inferTraits=function(t,r,e){var i=[];if(t.length){var n=t[0];if(n instanceof Array)i=n.map(function(t,r){return r});else if("object"==typeof n)for(var o in n)n.hasOwnProperty(o)&&i.push(o)}if(!e){var a=i.indexOf(r);a>-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};
  2 +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};
0 3 \ No newline at end of file
... ...
datalets/scatterplot-datalet/scatterplot-datalet.html
... ... @@ -47,7 +47,6 @@
47 47 };
48 48  
49 49 var plot = new D3ScatterPlot("#scatterplot-placeholder", data, conf);
50   - plot.init();
51 50 }
52 51 };
53 52  
... ...