Commit 752c1f5a6ed9d9528e4ed1d1a74a16d5976f7f19
1 parent
42187739
updated d3-scatterplot-matrix
Showing
8 changed files
with
571 additions
and
3 deletions
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 | ... | ... |