Commit 50380d5aa8029d9b510eabcc62457ea41920012f
1 parent
36f11711
d3 scatterplot-datalet
Showing
17 changed files
with
840 additions
and
3 deletions
bower_components/d3-scatterplot/.bower.json
0 → 100644
1 | +{ | ||
2 | + "name": "d3-scatterplot", | ||
3 | + "homepage": "https://github.com/mwasiluk/d3-scatterplot", | ||
4 | + "authors": [ | ||
5 | + "Michal Wasiluk" | ||
6 | + ], | ||
7 | + "description": "", | ||
8 | + "main": "", | ||
9 | + "keywords": [ | ||
10 | + "scatterplot", | ||
11 | + "d3" | ||
12 | + ], | ||
13 | + "license": "MIT", | ||
14 | + "ignore": [ | ||
15 | + "**/.*", | ||
16 | + "node_modules", | ||
17 | + "bower_components", | ||
18 | + "test", | ||
19 | + "tests" | ||
20 | + ], | ||
21 | + "dependencies": { | ||
22 | + "d3": "^3.5.17" | ||
23 | + }, | ||
24 | + "version": "1.1.0", | ||
25 | + "_release": "1.1.0", | ||
26 | + "_resolution": { | ||
27 | + "type": "version", | ||
28 | + "tag": "1.1.0", | ||
29 | + "commit": "9b30b60eb35b60c7c8c83cd86107a27cae0b9db9" | ||
30 | + }, | ||
31 | + "_source": "https://github.com/mwasiluk/d3-scatterplot.git", | ||
32 | + "_target": "^1.0.0", | ||
33 | + "_originalSource": "d3-scatterplot" | ||
34 | +} | ||
0 | \ No newline at end of file | 35 | \ No newline at end of file |
bower_components/d3-scatterplot/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/README.md
0 → 100644
bower_components/d3-scatterplot/bower.json
0 → 100644
1 | +{ | ||
2 | + "name": "d3-scatterplot", | ||
3 | + "homepage": "https://github.com/mwasiluk/d3-scatterplot", | ||
4 | + "authors": [ | ||
5 | + "Michal Wasiluk" | ||
6 | + ], | ||
7 | + "description": "", | ||
8 | + "main": "", | ||
9 | + "keywords": [ | ||
10 | + "scatterplot", | ||
11 | + "d3" | ||
12 | + ], | ||
13 | + "license": "MIT", | ||
14 | + "ignore": [ | ||
15 | + "**/.*", | ||
16 | + "node_modules", | ||
17 | + "bower_components", | ||
18 | + "test", | ||
19 | + "tests" | ||
20 | + ], | ||
21 | + "dependencies": { | ||
22 | + "d3": "^3.5.17" | ||
23 | + } | ||
24 | +} |
bower_components/d3-scatterplot/demo/demo.js
0 → 100644
1 | +var conf = { | ||
2 | + // width: 500, | ||
3 | + // height: 500, | ||
4 | + dot:{ | ||
5 | + // color: 'red' | ||
6 | + } | ||
7 | +}; | ||
8 | +var data = [ | ||
9 | + [1,2], | ||
10 | + [2,3], | ||
11 | + [3,4], | ||
12 | + [6,4], | ||
13 | + [11,3], | ||
14 | + [1,3.5], | ||
15 | + [7,4], | ||
16 | + [5,4] | ||
17 | + | ||
18 | +]; | ||
19 | +var plot = new D3ScatterPlot("#scatterplot", data, conf); | ||
20 | +plot.init(); | ||
0 | \ No newline at end of file | 21 | \ No newline at end of file |
bower_components/d3-scatterplot/demo/index.html
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html lang="en"> | ||
3 | +<head> | ||
4 | + <meta charset="UTF-8"> | ||
5 | + <title>D3 scatterplot demo</title> | ||
6 | + <link rel="stylesheet" href="../dist/d3-scatterplot.css"> | ||
7 | +</head> | ||
8 | +<body> | ||
9 | +<h1>D3 scatterplot demo</h1> | ||
10 | + | ||
11 | +<div id="scatterplot" style="width:auto; min-height:500px;"></div> | ||
12 | + | ||
13 | +<script src="../bower_components/d3/d3.min.js" charset="utf-8"></script> | ||
14 | +<script src="../dist/d3-scatterplot.js" charset="utf-8"></script> | ||
15 | +<script src="demo.js"></script> | ||
16 | +</body> | ||
17 | +</html> | ||
0 | \ No newline at end of file | 18 | \ No newline at end of file |
bower_components/d3-scatterplot/dist/d3-scatterplot.css
0 → 100644
bower_components/d3-scatterplot/dist/d3-scatterplot.js
0 → 100644
1 | +function D3ScatterPlotUtils(){} | ||
2 | + | ||
3 | +// usage example deepExtend({}, objA, objB); => should work similar to $.extend(true, {}, objA, objB); | ||
4 | +D3ScatterPlotUtils.prototype.deepExtend = function(out) { //TODO consider using jquery / lo-dash / underscore / ECMA6 ; fallbacks? | ||
5 | + | ||
6 | + var utils =this; | ||
7 | + out = out || {}; | ||
8 | + | ||
9 | + for (var i = 1; i < arguments.length; i++) { | ||
10 | + var obj = arguments[i]; | ||
11 | + | ||
12 | + if (!obj) | ||
13 | + continue; | ||
14 | + | ||
15 | + for (var key in obj) { | ||
16 | + if (obj.hasOwnProperty(key)) { | ||
17 | + if (typeof obj[key] === 'object') | ||
18 | + out[key] = utils.deepExtend(out[key], obj[key]); | ||
19 | + else | ||
20 | + out[key] = obj[key]; | ||
21 | + } | ||
22 | + } | ||
23 | + } | ||
24 | + | ||
25 | + return out; | ||
26 | +}; | ||
27 | + | ||
28 | + | ||
29 | +function D3ScatterPlot(placeholderSelector, data, config){ | ||
30 | + this.utils = new D3ScatterPlotUtils(); | ||
31 | + this.placeholderSelector = placeholderSelector; | ||
32 | + this.svg=null; | ||
33 | + this.defaultConfig = { | ||
34 | + width: 0, | ||
35 | + height: 0, | ||
36 | + margin:{ | ||
37 | + left: 50, | ||
38 | + right: 30, | ||
39 | + top: 30, | ||
40 | + bottom: 50 | ||
41 | + }, | ||
42 | + x:{// X axis config | ||
43 | + label: 'X', // axis label | ||
44 | + value: function(d) { return d[0] }, // x value accessor | ||
45 | + orient: "bottom" | ||
46 | + }, | ||
47 | + y:{// Y axis config | ||
48 | + label: 'Y', // axis label | ||
49 | + value: function(d) { return d[1] }, // y value accessor | ||
50 | + orient: "left" | ||
51 | + }, | ||
52 | + dot:{ | ||
53 | + radius: 2, | ||
54 | + color: function(d) { return d[0]*d[1] }, // string or function returning color's value for color scale | ||
55 | + d3ColorCategory: 'category10' | ||
56 | + } | ||
57 | + }; | ||
58 | + | ||
59 | + if(data){ | ||
60 | + this.setData(data); | ||
61 | + } | ||
62 | + | ||
63 | + if(config){ | ||
64 | + this.setConfig(config); | ||
65 | + } | ||
66 | + | ||
67 | +} | ||
68 | + | ||
69 | +D3ScatterPlot.prototype.setData = function (data){ | ||
70 | + this.data = data; | ||
71 | + return this; | ||
72 | +}; | ||
73 | + | ||
74 | +D3ScatterPlot.prototype.setConfig = function (config){ | ||
75 | + this.config = this.utils.deepExtend({}, this.defaultConfig, config); | ||
76 | + return this; | ||
77 | +}; | ||
78 | +D3ScatterPlot.prototype.initPlot = function (){ | ||
79 | + var self=this; | ||
80 | + var margin = this.config.margin; | ||
81 | + var conf = this.config; | ||
82 | + this.plot={ | ||
83 | + x: {}, | ||
84 | + y: {}, | ||
85 | + dot: { | ||
86 | + color: null//color scale mapping function | ||
87 | + } | ||
88 | + }; | ||
89 | + | ||
90 | + var width = conf.width; | ||
91 | + var placeholderNode = d3.select(this.placeholderSelector).node(); | ||
92 | + | ||
93 | + if(!width){ | ||
94 | + width =placeholderNode.getBoundingClientRect().width; | ||
95 | + } | ||
96 | + var height = conf.height; | ||
97 | + if(!height){ | ||
98 | + height =placeholderNode.getBoundingClientRect().height; | ||
99 | + } | ||
100 | + | ||
101 | + this.plot.width = width - margin.left - margin.right; | ||
102 | + this.plot.height = height - margin.top - margin.bottom; | ||
103 | + | ||
104 | + this.setupX(); | ||
105 | + this.setupY(); | ||
106 | + | ||
107 | + if(conf.dot.d3ColorCategory){ | ||
108 | + this.plot.dot.colorCategory = d3.scale[conf.dot.d3ColorCategory](); | ||
109 | + } | ||
110 | + var colorValue = conf.dot.color; | ||
111 | + if(colorValue){ | ||
112 | + this.plot.dot.colorValue = colorValue; | ||
113 | + | ||
114 | + if (typeof colorValue === 'string' || colorValue instanceof String){ | ||
115 | + this.plot.dot.color = colorValue; | ||
116 | + }else if(this.plot.dot.colorCategory){ | ||
117 | + this.plot.dot.color = function(d){ | ||
118 | + return self.plot.dot.colorCategory(self.plot.dot.colorValue(d)); | ||
119 | + } | ||
120 | + } | ||
121 | + | ||
122 | + | ||
123 | + } | ||
124 | + | ||
125 | + return this; | ||
126 | +}; | ||
127 | + | ||
128 | +D3ScatterPlot.prototype.setupX = function (){ | ||
129 | + | ||
130 | + var plot = this.plot; | ||
131 | + var x = plot.x; | ||
132 | + var conf = this.config.x; | ||
133 | + | ||
134 | + /* | ||
135 | + * value accessor - returns the value to encode for a given data object. | ||
136 | + * scale - maps value to a visual display encoding, such as a pixel position. | ||
137 | + * map function - maps from data value to display value | ||
138 | + * axis - sets up axis | ||
139 | + */ | ||
140 | + x.value = conf.value; | ||
141 | + x.scale = d3.scale.linear().range([0, plot.width]); | ||
142 | + x.map = function(d) { return x.scale(x.value(d));}; | ||
143 | + x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient); | ||
144 | + var data = this.data; | ||
145 | + plot.x.scale.domain([d3.min(data, plot.x.value)-1, d3.max(data, plot.x.value)+1]); | ||
146 | + | ||
147 | + | ||
148 | +}; | ||
149 | + | ||
150 | +D3ScatterPlot.prototype.setupY = function (){ | ||
151 | + | ||
152 | + var plot = this.plot; | ||
153 | + var y = plot.y; | ||
154 | + var conf = this.config.y; | ||
155 | + | ||
156 | + /* | ||
157 | + * value accessor - returns the value to encode for a given data object. | ||
158 | + * scale - maps value to a visual display encoding, such as a pixel position. | ||
159 | + * map function - maps from data value to display value | ||
160 | + * axis - sets up axis | ||
161 | + */ | ||
162 | + y.value = conf.value; | ||
163 | + y.scale = d3.scale.linear().range([plot.height, 0]); | ||
164 | + y.map = function(d) { return y.scale(y.value(d));}; | ||
165 | + y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient); | ||
166 | + | ||
167 | + | ||
168 | + var data = this.data; | ||
169 | + plot.y.scale.domain([d3.min(data, plot.y.value)-1, d3.max(data, plot.y.value)+1]); | ||
170 | +}; | ||
171 | + | ||
172 | +D3ScatterPlot.prototype.drawPlot = function (){ | ||
173 | + this.drawAxisX(); | ||
174 | + this.drawAxisY(); | ||
175 | + this.drawDots(); | ||
176 | +}; | ||
177 | +D3ScatterPlot.prototype.drawAxisX = function (){ | ||
178 | + var self = this; | ||
179 | + var plot = self.plot; | ||
180 | + var axisConf = this.config.x; | ||
181 | + self.svgG.append("g") | ||
182 | + .attr("class", "mw-axis mw-axis-x") | ||
183 | + .attr("transform", "translate(0," + plot.height + ")") | ||
184 | + .call(plot.x.axis) | ||
185 | + .append("text") | ||
186 | + .attr("class", "mw-label") | ||
187 | + .attr("transform", "translate("+ (plot.width/2) +","+ (self.config.margin.bottom) +")") // text is drawn off the screen top left, move down and out and rotate | ||
188 | + .attr("dy", "-1em") | ||
189 | + .style("text-anchor", "middle") | ||
190 | + .text(axisConf.label); | ||
191 | +}; | ||
192 | + | ||
193 | +D3ScatterPlot.prototype.drawAxisY = function (){ | ||
194 | + var self = this; | ||
195 | + var plot = self.plot; | ||
196 | + var axisConf = this.config.y; | ||
197 | + self.svgG.append("g") | ||
198 | + .attr("class", "mw-axis mw-axis-y") | ||
199 | + .call(plot.y.axis) | ||
200 | + .append("text") | ||
201 | + .attr("class", "mw-label") | ||
202 | + .attr("transform", "translate("+ -self.config.margin.left +","+(plot.height/2)+")rotate(-90)") // text is drawn off the screen top left, move down and out and rotate | ||
203 | + .attr("dy", "1em") | ||
204 | + .style("text-anchor", "middle") | ||
205 | + .text(axisConf.label); | ||
206 | +}; | ||
207 | + | ||
208 | + | ||
209 | +D3ScatterPlot.prototype.drawDots = function (){ | ||
210 | + var self = this; | ||
211 | + var plot = self.plot; | ||
212 | + var data = this.data; | ||
213 | + var dots = self.svgG.selectAll(".mw-dot") | ||
214 | + .data(data) | ||
215 | + .enter().append("circle") | ||
216 | + .attr("class", "mw-dot") | ||
217 | + .attr("r", self.config.dot.radius) | ||
218 | + .attr("cx", plot.x.map) | ||
219 | + .attr("cy", plot.y.map); | ||
220 | + | ||
221 | + if(plot.dot.color){ | ||
222 | + dots.style("fill", plot.dot.color) | ||
223 | + } | ||
224 | + | ||
225 | +}; | ||
226 | + | ||
227 | +D3ScatterPlot.prototype.initSvg = function (){ | ||
228 | + var self = this; | ||
229 | + var config = this.config; | ||
230 | + | ||
231 | + | ||
232 | + | ||
233 | + var width = self.plot.width+ config.margin.left + config.margin.right; | ||
234 | + var height = self.plot.height+ config.margin.top + config.margin.bottom; | ||
235 | + var aspect = width / height; | ||
236 | + self.svg = d3.select(self.placeholderSelector).append("svg") | ||
237 | + .attr("width", width) | ||
238 | + .attr("height", height) | ||
239 | + .attr("viewBox", "0 0 "+" "+width+" "+height) | ||
240 | + .attr("preserveAspectRatio", "xMidYMid meet") | ||
241 | + .attr("class", "mw-d3-scatterplot"); | ||
242 | + self.svgG = self.svg.append("g") | ||
243 | + .attr("transform", "translate(" + config.margin.left + "," + config.margin.top + ")"); | ||
244 | + | ||
245 | + if(!config.width || config.height ){ | ||
246 | + d3.select(window) | ||
247 | + .on("resize", function() { | ||
248 | + //TODO add responsiveness if width/height not specified | ||
249 | + }); | ||
250 | + } | ||
251 | + | ||
252 | +}; | ||
253 | + | ||
254 | +D3ScatterPlot.prototype.init = function (){ | ||
255 | + var self = this; | ||
256 | + self.initPlot(); | ||
257 | + self.initSvg(); | ||
258 | + self.drawPlot(); | ||
259 | + | ||
260 | +}; | ||
261 | + |
bower_components/d3-scatterplot/dist/d3-scatterplot.min.css
0 → 100644
bower_components/d3-scatterplot/dist/d3-scatterplot.min.js
0 → 100644
1 | +function D3ScatterPlotUtils(){}D3ScatterPlotUtils.prototype.deepExtend=function(t){var e=this;t=t||{};for(var r=1;r<arguments.length;r++){var o=arguments[r];if(o)for(var n in o)o.hasOwnProperty(n)&&("object"==typeof o[n]?t[n]=e.deepExtend(t[n],o[n]):t[n]=o[n])}return t}; | ||
2 | +function D3ScatterPlot(t,o,e){this.utils=new D3ScatterPlotUtils,this.placeholderSelector=t,this.svg=null,this.defaultConfig={width:0,height:0,margin:{left:50,right:30,top:30,bottom:50},x:{label:"X",value:function(t){return t[0]},orient:"bottom"},y:{label:"Y",value:function(t){return t[1]},orient:"left"},dot:{radius:2,color:function(t){return t[0]*t[1]},d3ColorCategory:"category10"}},o&&this.setData(o),e&&this.setConfig(e)}D3ScatterPlot.prototype.setData=function(t){return this.data=t,this},D3ScatterPlot.prototype.setConfig=function(t){return this.config=this.utils.deepExtend({},this.defaultConfig,t),this},D3ScatterPlot.prototype.initPlot=function(){var t=this,o=this.config.margin,e=this.config;this.plot={x:{},y:{},dot:{color:null}};var a=e.width,i=d3.select(this.placeholderSelector).node();a||(a=i.getBoundingClientRect().width);var r=e.height;r||(r=i.getBoundingClientRect().height),this.plot.width=a-o.left-o.right,this.plot.height=r-o.top-o.bottom,this.setupX(),this.setupY(),e.dot.d3ColorCategory&&(this.plot.dot.colorCategory=d3.scale[e.dot.d3ColorCategory]());var l=e.dot.color;return l&&(this.plot.dot.colorValue=l,"string"==typeof l||l instanceof String?this.plot.dot.color=l:this.plot.dot.colorCategory&&(this.plot.dot.color=function(o){return t.plot.dot.colorCategory(t.plot.dot.colorValue(o))})),this},D3ScatterPlot.prototype.setupX=function(){var t=this.plot,o=t.x,e=this.config.x;o.value=e.value,o.scale=d3.scale.linear().range([0,t.width]),o.map=function(t){return o.scale(o.value(t))},o.axis=d3.svg.axis().scale(o.scale).orient(e.orient);var a=this.data;t.x.scale.domain([d3.min(a,t.x.value)-1,d3.max(a,t.x.value)+1])},D3ScatterPlot.prototype.setupY=function(){var t=this.plot,o=t.y,e=this.config.y;o.value=e.value,o.scale=d3.scale.linear().range([t.height,0]),o.map=function(t){return o.scale(o.value(t))},o.axis=d3.svg.axis().scale(o.scale).orient(e.orient);var a=this.data;t.y.scale.domain([d3.min(a,t.y.value)-1,d3.max(a,t.y.value)+1])},D3ScatterPlot.prototype.drawPlot=function(){this.drawAxisX(),this.drawAxisY(),this.drawDots()},D3ScatterPlot.prototype.drawAxisX=function(){var t=this,o=t.plot,e=this.config.x;t.svgG.append("g").attr("class","mw-axis mw-axis-x").attr("transform","translate(0,"+o.height+")").call(o.x.axis).append("text").attr("class","mw-label").attr("transform","translate("+o.width/2+","+t.config.margin.bottom+")").attr("dy","-1em").style("text-anchor","middle").text(e.label)},D3ScatterPlot.prototype.drawAxisY=function(){var t=this,o=t.plot,e=this.config.y;t.svgG.append("g").attr("class","mw-axis mw-axis-y").call(o.y.axis).append("text").attr("class","mw-label").attr("transform","translate("+-t.config.margin.left+","+o.height/2+")rotate(-90)").attr("dy","1em").style("text-anchor","middle").text(e.label)},D3ScatterPlot.prototype.drawDots=function(){var t=this,o=t.plot,e=this.data,a=t.svgG.selectAll(".mw-dot").data(e).enter().append("circle").attr("class","mw-dot").attr("r",t.config.dot.radius).attr("cx",o.x.map).attr("cy",o.y.map);o.dot.color&&a.style("fill",o.dot.color)},D3ScatterPlot.prototype.initSvg=function(){var t=this,o=this.config,e=t.plot.width+o.margin.left+o.margin.right,a=t.plot.height+o.margin.top+o.margin.bottom;t.svg=d3.select(t.placeholderSelector).append("svg").attr("width",e).attr("height",a).attr("viewBox","0 0 "+e+" "+a).attr("preserveAspectRatio","xMidYMid meet").attr("class","mw-d3-scatterplot"),t.svgG=t.svg.append("g").attr("transform","translate("+o.margin.left+","+o.margin.top+")"),o.width&&!o.height||d3.select(window).on("resize",function(){})},D3ScatterPlot.prototype.init=function(){var t=this;t.initPlot(),t.initSvg(),t.drawPlot()}; | ||
0 | \ No newline at end of file | 3 | \ No newline at end of file |
bower_components/d3-scatterplot/gulpfile.js
0 → 100644
1 | +var gulp = require('gulp'); | ||
2 | +var del = require('del'); | ||
3 | +var merge = require('merge-stream'); | ||
4 | +var plugins = require('gulp-load-plugins')(); | ||
5 | +var browserSync = require('browser-sync').create(); | ||
6 | + | ||
7 | +gulp.task('clean', function (cb) { | ||
8 | + return del(['tmp', 'dist'], cb); | ||
9 | +}); | ||
10 | + | ||
11 | +gulp.task('build-css', function () { | ||
12 | + var pretty = gulp.src('./styles/*') | ||
13 | + .pipe(plugins.plumber({ errorHandler: onError })) | ||
14 | + .pipe(plugins.sass()) | ||
15 | + .pipe(plugins.minifyCss()) | ||
16 | + .pipe(plugins.rename({ | ||
17 | + extname: '.min.css' | ||
18 | + })) | ||
19 | + .pipe(gulp.dest('./dist')); | ||
20 | + var ugly = gulp.src('./styles/*') | ||
21 | + .pipe(plugins.plumber({ errorHandler: onError })) | ||
22 | + .pipe(plugins.sass()) | ||
23 | + .pipe(plugins.rename({ | ||
24 | + extname: '.css' | ||
25 | + })) | ||
26 | + .pipe(gulp.dest('./dist')); | ||
27 | + return merge(pretty, ugly); | ||
28 | +}); | ||
29 | + | ||
30 | +gulp.task('build-js', function () { | ||
31 | + var jsFileName = 'd3-scatterplot'; | ||
32 | + var pretty = gulp.src('./src/*.js') | ||
33 | + .pipe(plugins.plumber({ errorHandler: onError })) | ||
34 | + .pipe(plugins.concat(jsFileName+'.js')) | ||
35 | + .pipe(gulp.dest('dist')); | ||
36 | + | ||
37 | + var ugly = gulp.src('./src/*.js') | ||
38 | + .pipe(plugins.plumber({ errorHandler: onError })) | ||
39 | + .pipe(plugins.uglify()) | ||
40 | + .pipe(plugins.stripDebug()) | ||
41 | + .pipe(plugins.concat(jsFileName+'.min.js')) | ||
42 | + .pipe(gulp.dest('dist')); | ||
43 | + | ||
44 | + return merge(pretty, ugly); | ||
45 | +}); | ||
46 | + | ||
47 | +gulp.task('build-clean', ['clean'], function () { | ||
48 | + gulp.start('build'); | ||
49 | +}); | ||
50 | + | ||
51 | +gulp.task('build', ['build-css', 'build-js'], function () { | ||
52 | + | ||
53 | +}); | ||
54 | + | ||
55 | +gulp.task('watch', function() { | ||
56 | + return gulp.watch(['./src/**/*.html', './styles/*.*css', 'src/**/*.js'], ['default']); | ||
57 | +}); | ||
58 | + | ||
59 | +gulp.task('default', ['build-clean'], function() { | ||
60 | + | ||
61 | +}); | ||
62 | + | ||
63 | +gulp.task('default-watch', ['default'], ()=>{ browserSync.reload() }); | ||
64 | +gulp.task('serve', ['default'], ()=>{ | ||
65 | + browserSync.init({ | ||
66 | + server: { | ||
67 | + baseDir: "demo", | ||
68 | + index: "index.html", | ||
69 | + routes: { | ||
70 | + "/bower_components": "bower_components", | ||
71 | + "/dist": "dist" | ||
72 | + } | ||
73 | + }, | ||
74 | + port: 8089, | ||
75 | + open: 'local', | ||
76 | + browser: "google chrome" | ||
77 | + }); | ||
78 | + gulp.watch(['i18n/**/*.json', './src/**/*.html', './styles/*.*css', 'src/**/*.js', 'demo/*.*'], ['default-watch']); | ||
79 | +}); | ||
80 | + | ||
81 | +// error function for plumber | ||
82 | +var onError = function (err) { | ||
83 | + console.log(err); | ||
84 | + this.emit('end'); | ||
85 | +}; | ||
0 | \ No newline at end of file | 86 | \ No newline at end of file |
bower_components/d3-scatterplot/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "d3-scatterplot", | ||
3 | + "version": "1.0.0", | ||
4 | + "description": "d3 scatterplot", | ||
5 | + "main": "gulpfile.js", | ||
6 | + "scripts": { | ||
7 | + "test": "echo \"Error: no test specified\" && exit 1" | ||
8 | + }, | ||
9 | + "repository": { | ||
10 | + "type": "git", | ||
11 | + "url": "git+https://github.com/mwasiluk/d3-scatterplot.git" | ||
12 | + }, | ||
13 | + "keywords": [ | ||
14 | + "d3", | ||
15 | + "scatterplot" | ||
16 | + ], | ||
17 | + "author": "Michal Wasiluk", | ||
18 | + "license": "MIT", | ||
19 | + "bugs": { | ||
20 | + "url": "https://github.com/mwasiluk/d3-scatterplot/issues" | ||
21 | + }, | ||
22 | + "homepage": "https://github.com/mwasiluk/d3-scatterplot#readme", | ||
23 | + "devDependencies": { | ||
24 | + "browser-sync": "^2.13.0", | ||
25 | + "del": "^2.2.0", | ||
26 | + "gulp": "^3.9.1", | ||
27 | + "gulp-concat": "^2.6.0", | ||
28 | + "gulp-load-plugins": "^1.2.4", | ||
29 | + "gulp-minify-css": "^1.2.4", | ||
30 | + "gulp-plumber": "^1.1.0", | ||
31 | + "gulp-rename": "^1.2.2", | ||
32 | + "gulp-sass": "^2.3.1", | ||
33 | + "gulp-strip-debug": "^1.1.0", | ||
34 | + "gulp-uglify": "^1.5.3", | ||
35 | + "merge-stream": "^1.0.0" | ||
36 | + } | ||
37 | +} |
bower_components/d3-scatterplot/src/d3-scatterplot-utils.js
0 → 100644
1 | +function D3ScatterPlotUtils(){} | ||
2 | + | ||
3 | +// usage example deepExtend({}, objA, objB); => should work similar to $.extend(true, {}, objA, objB); | ||
4 | +D3ScatterPlotUtils.prototype.deepExtend = function(out) { //TODO consider using jquery / lo-dash / underscore / ECMA6 ; fallbacks? | ||
5 | + | ||
6 | + var utils =this; | ||
7 | + out = out || {}; | ||
8 | + | ||
9 | + for (var i = 1; i < arguments.length; i++) { | ||
10 | + var obj = arguments[i]; | ||
11 | + | ||
12 | + if (!obj) | ||
13 | + continue; | ||
14 | + | ||
15 | + for (var key in obj) { | ||
16 | + if (obj.hasOwnProperty(key)) { | ||
17 | + if (typeof obj[key] === 'object') | ||
18 | + out[key] = utils.deepExtend(out[key], obj[key]); | ||
19 | + else | ||
20 | + out[key] = obj[key]; | ||
21 | + } | ||
22 | + } | ||
23 | + } | ||
24 | + | ||
25 | + return out; | ||
26 | +}; | ||
27 | + |
bower_components/d3-scatterplot/src/d3-scatterplot.js
0 → 100644
1 | +function D3ScatterPlot(placeholderSelector, data, config){ | ||
2 | + this.utils = new D3ScatterPlotUtils(); | ||
3 | + this.placeholderSelector = placeholderSelector; | ||
4 | + this.svg=null; | ||
5 | + this.defaultConfig = { | ||
6 | + width: 0, | ||
7 | + height: 0, | ||
8 | + margin:{ | ||
9 | + left: 50, | ||
10 | + right: 30, | ||
11 | + top: 30, | ||
12 | + bottom: 50 | ||
13 | + }, | ||
14 | + x:{// X axis config | ||
15 | + label: 'X', // axis label | ||
16 | + value: function(d) { return d[0] }, // x value accessor | ||
17 | + orient: "bottom" | ||
18 | + }, | ||
19 | + y:{// Y axis config | ||
20 | + label: 'Y', // axis label | ||
21 | + value: function(d) { return d[1] }, // y value accessor | ||
22 | + orient: "left" | ||
23 | + }, | ||
24 | + dot:{ | ||
25 | + radius: 2, | ||
26 | + color: function(d) { return d[0]*d[1] }, // string or function returning color's value for color scale | ||
27 | + d3ColorCategory: 'category10' | ||
28 | + } | ||
29 | + }; | ||
30 | + | ||
31 | + if(data){ | ||
32 | + this.setData(data); | ||
33 | + } | ||
34 | + | ||
35 | + if(config){ | ||
36 | + this.setConfig(config); | ||
37 | + } | ||
38 | + | ||
39 | +} | ||
40 | + | ||
41 | +D3ScatterPlot.prototype.setData = function (data){ | ||
42 | + this.data = data; | ||
43 | + return this; | ||
44 | +}; | ||
45 | + | ||
46 | +D3ScatterPlot.prototype.setConfig = function (config){ | ||
47 | + this.config = this.utils.deepExtend({}, this.defaultConfig, config); | ||
48 | + return this; | ||
49 | +}; | ||
50 | +D3ScatterPlot.prototype.initPlot = function (){ | ||
51 | + var self=this; | ||
52 | + var margin = this.config.margin; | ||
53 | + var conf = this.config; | ||
54 | + this.plot={ | ||
55 | + x: {}, | ||
56 | + y: {}, | ||
57 | + dot: { | ||
58 | + color: null//color scale mapping function | ||
59 | + } | ||
60 | + }; | ||
61 | + | ||
62 | + var width = conf.width; | ||
63 | + var placeholderNode = d3.select(this.placeholderSelector).node(); | ||
64 | + | ||
65 | + if(!width){ | ||
66 | + width =placeholderNode.getBoundingClientRect().width; | ||
67 | + } | ||
68 | + var height = conf.height; | ||
69 | + if(!height){ | ||
70 | + height =placeholderNode.getBoundingClientRect().height; | ||
71 | + } | ||
72 | + | ||
73 | + this.plot.width = width - margin.left - margin.right; | ||
74 | + this.plot.height = height - margin.top - margin.bottom; | ||
75 | + | ||
76 | + this.setupX(); | ||
77 | + this.setupY(); | ||
78 | + | ||
79 | + if(conf.dot.d3ColorCategory){ | ||
80 | + this.plot.dot.colorCategory = d3.scale[conf.dot.d3ColorCategory](); | ||
81 | + } | ||
82 | + var colorValue = conf.dot.color; | ||
83 | + if(colorValue){ | ||
84 | + this.plot.dot.colorValue = colorValue; | ||
85 | + | ||
86 | + if (typeof colorValue === 'string' || colorValue instanceof String){ | ||
87 | + this.plot.dot.color = colorValue; | ||
88 | + }else if(this.plot.dot.colorCategory){ | ||
89 | + this.plot.dot.color = function(d){ | ||
90 | + return self.plot.dot.colorCategory(self.plot.dot.colorValue(d)); | ||
91 | + } | ||
92 | + } | ||
93 | + | ||
94 | + | ||
95 | + } | ||
96 | + | ||
97 | + return this; | ||
98 | +}; | ||
99 | + | ||
100 | +D3ScatterPlot.prototype.setupX = function (){ | ||
101 | + | ||
102 | + var plot = this.plot; | ||
103 | + var x = plot.x; | ||
104 | + var conf = this.config.x; | ||
105 | + | ||
106 | + /* | ||
107 | + * value accessor - returns the value to encode for a given data object. | ||
108 | + * scale - maps value to a visual display encoding, such as a pixel position. | ||
109 | + * map function - maps from data value to display value | ||
110 | + * axis - sets up axis | ||
111 | + */ | ||
112 | + x.value = conf.value; | ||
113 | + x.scale = d3.scale.linear().range([0, plot.width]); | ||
114 | + x.map = function(d) { return x.scale(x.value(d));}; | ||
115 | + x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient); | ||
116 | + var data = this.data; | ||
117 | + plot.x.scale.domain([d3.min(data, plot.x.value)-1, d3.max(data, plot.x.value)+1]); | ||
118 | + | ||
119 | + | ||
120 | +}; | ||
121 | + | ||
122 | +D3ScatterPlot.prototype.setupY = function (){ | ||
123 | + | ||
124 | + var plot = this.plot; | ||
125 | + var y = plot.y; | ||
126 | + var conf = this.config.y; | ||
127 | + | ||
128 | + /* | ||
129 | + * value accessor - returns the value to encode for a given data object. | ||
130 | + * scale - maps value to a visual display encoding, such as a pixel position. | ||
131 | + * map function - maps from data value to display value | ||
132 | + * axis - sets up axis | ||
133 | + */ | ||
134 | + y.value = conf.value; | ||
135 | + y.scale = d3.scale.linear().range([plot.height, 0]); | ||
136 | + y.map = function(d) { return y.scale(y.value(d));}; | ||
137 | + y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient); | ||
138 | + | ||
139 | + | ||
140 | + var data = this.data; | ||
141 | + plot.y.scale.domain([d3.min(data, plot.y.value)-1, d3.max(data, plot.y.value)+1]); | ||
142 | +}; | ||
143 | + | ||
144 | +D3ScatterPlot.prototype.drawPlot = function (){ | ||
145 | + this.drawAxisX(); | ||
146 | + this.drawAxisY(); | ||
147 | + this.drawDots(); | ||
148 | +}; | ||
149 | +D3ScatterPlot.prototype.drawAxisX = function (){ | ||
150 | + var self = this; | ||
151 | + var plot = self.plot; | ||
152 | + var axisConf = this.config.x; | ||
153 | + self.svgG.append("g") | ||
154 | + .attr("class", "mw-axis mw-axis-x") | ||
155 | + .attr("transform", "translate(0," + plot.height + ")") | ||
156 | + .call(plot.x.axis) | ||
157 | + .append("text") | ||
158 | + .attr("class", "mw-label") | ||
159 | + .attr("transform", "translate("+ (plot.width/2) +","+ (self.config.margin.bottom) +")") // text is drawn off the screen top left, move down and out and rotate | ||
160 | + .attr("dy", "-1em") | ||
161 | + .style("text-anchor", "middle") | ||
162 | + .text(axisConf.label); | ||
163 | +}; | ||
164 | + | ||
165 | +D3ScatterPlot.prototype.drawAxisY = function (){ | ||
166 | + var self = this; | ||
167 | + var plot = self.plot; | ||
168 | + var axisConf = this.config.y; | ||
169 | + self.svgG.append("g") | ||
170 | + .attr("class", "mw-axis mw-axis-y") | ||
171 | + .call(plot.y.axis) | ||
172 | + .append("text") | ||
173 | + .attr("class", "mw-label") | ||
174 | + .attr("transform", "translate("+ -self.config.margin.left +","+(plot.height/2)+")rotate(-90)") // text is drawn off the screen top left, move down and out and rotate | ||
175 | + .attr("dy", "1em") | ||
176 | + .style("text-anchor", "middle") | ||
177 | + .text(axisConf.label); | ||
178 | +}; | ||
179 | + | ||
180 | + | ||
181 | +D3ScatterPlot.prototype.drawDots = function (){ | ||
182 | + var self = this; | ||
183 | + var plot = self.plot; | ||
184 | + var data = this.data; | ||
185 | + var dots = self.svgG.selectAll(".mw-dot") | ||
186 | + .data(data) | ||
187 | + .enter().append("circle") | ||
188 | + .attr("class", "mw-dot") | ||
189 | + .attr("r", self.config.dot.radius) | ||
190 | + .attr("cx", plot.x.map) | ||
191 | + .attr("cy", plot.y.map); | ||
192 | + | ||
193 | + if(plot.dot.color){ | ||
194 | + dots.style("fill", plot.dot.color) | ||
195 | + } | ||
196 | + | ||
197 | +}; | ||
198 | + | ||
199 | +D3ScatterPlot.prototype.initSvg = function (){ | ||
200 | + var self = this; | ||
201 | + var config = this.config; | ||
202 | + | ||
203 | + | ||
204 | + | ||
205 | + var width = self.plot.width+ config.margin.left + config.margin.right; | ||
206 | + var height = self.plot.height+ config.margin.top + config.margin.bottom; | ||
207 | + var aspect = width / height; | ||
208 | + self.svg = d3.select(self.placeholderSelector).append("svg") | ||
209 | + .attr("width", width) | ||
210 | + .attr("height", height) | ||
211 | + .attr("viewBox", "0 0 "+" "+width+" "+height) | ||
212 | + .attr("preserveAspectRatio", "xMidYMid meet") | ||
213 | + .attr("class", "mw-d3-scatterplot"); | ||
214 | + self.svgG = self.svg.append("g") | ||
215 | + .attr("transform", "translate(" + config.margin.left + "," + config.margin.top + ")"); | ||
216 | + | ||
217 | + if(!config.width || config.height ){ | ||
218 | + d3.select(window) | ||
219 | + .on("resize", function() { | ||
220 | + //TODO add responsiveness if width/height not specified | ||
221 | + }); | ||
222 | + } | ||
223 | + | ||
224 | +}; | ||
225 | + | ||
226 | +D3ScatterPlot.prototype.init = function (){ | ||
227 | + var self = this; | ||
228 | + self.initPlot(); | ||
229 | + self.initSvg(); | ||
230 | + self.drawPlot(); | ||
231 | + | ||
232 | +}; | ||
233 | + |
bower_components/d3-scatterplot/styles/d3-scatterplot.scss
0 → 100644
datalets/scatterplot-datalet/demo/index.html
@@ -13,9 +13,11 @@ | @@ -13,9 +13,11 @@ | ||
13 | <script src="https://code.jquery.com/jquery-2.1.4.min.js" type="text/javascript"></script> | 13 | <script src="https://code.jquery.com/jquery-2.1.4.min.js" type="text/javascript"></script> |
14 | <link rel="import" href="../scatterplot-datalet.html" /> | 14 | <link rel="import" href="../scatterplot-datalet.html" /> |
15 | 15 | ||
16 | +<div style="height: 600px"> | ||
17 | + <scatterplot-datalet data-url="http://ckan.ancitel.it/api/action/datastore_search?resource_id=29d9700a-fb2c-45fe-9cea-da856d5afd6c&limit=500" | ||
18 | + fields='["result,records,pop_residente","result,records,superficie_kmq"]'></scatterplot-datalet> | ||
19 | +</div> | ||
16 | 20 | ||
17 | -<scatterplot-datalet data-url="http://ckan.ancitel.it/api/action/datastore_search?resource_id=29d9700a-fb2c-45fe-9cea-da856d5afd6c&limit=500" | ||
18 | - fields='["result,records,area_geo","result,records,pop_residente","result,records,superficie_kmq"]'></scatterplot-datalet> | ||
19 | 21 | ||
20 | </body> | 22 | </body> |
21 | </html> | 23 | </html> |
22 | \ No newline at end of file | 24 | \ No newline at end of file |
datalets/scatterplot-datalet/scatterplot-datalet.html
@@ -4,15 +4,57 @@ | @@ -4,15 +4,57 @@ | ||
4 | 4 | ||
5 | <dom-module id="scatterplot-datalet"> | 5 | <dom-module id="scatterplot-datalet"> |
6 | <template> | 6 | <template> |
7 | + <link rel="stylesheet" href="../../bower_components/d3-scatterplot/dist/d3-scatterplot.min.css"> | ||
8 | + <style is="custom-style"> | ||
9 | + :host ::content #scatterplot-placeholder { | ||
10 | + width: 100%; | ||
11 | + height: 70%; | ||
12 | + background: #ffffff; | ||
13 | + position: relative; | ||
14 | + } | ||
15 | + </style> | ||
7 | <div id="scatterplot-placeholder"></div> | 16 | <div id="scatterplot-placeholder"></div> |
8 | <base-ajax-json-alasql-datalet data-url="{{dataUrl}}" fields="{{fields}}" data="{{data}}" title="{{title}}" description="{{description}}" export_menu="{{export_menu}}"></base-ajax-json-alasql-datalet> | 17 | <base-ajax-json-alasql-datalet data-url="{{dataUrl}}" fields="{{fields}}" data="{{data}}" title="{{title}}" description="{{description}}" export_menu="{{export_menu}}"></base-ajax-json-alasql-datalet> |
9 | </template> | 18 | </template> |
10 | - | ||
11 | <script src="../shared_js/d3.js"></script> | 19 | <script src="../shared_js/d3.js"></script> |
20 | + <script type="text/javascript" src="../../bower_components/d3-scatterplot/dist/d3-scatterplot.js"></script> | ||
12 | <script> | 21 | <script> |
13 | 22 | ||
14 | var ScatterplotBehavior = { | 23 | var ScatterplotBehavior = { |
24 | + presentData: function () { | ||
25 | + | ||
26 | + var self =this; | ||
27 | + var scatterSeries = []; | ||
28 | + var series = []; | ||
29 | + var point = []; | ||
30 | + | ||
31 | + for (var j = 0; j < this.data[0]["data"].length; j++) { | ||
32 | + point = [this.data[0].data[j], this.data[1].data[j]]; | ||
33 | + series.push(point); | ||
34 | + } | ||
15 | 35 | ||
36 | + scatterSeries.push({data: series}); | ||
37 | + | ||
38 | + this.properties.series = scatterSeries; | ||
39 | + this._component.legend = false; | ||
40 | + | ||
41 | + var conf = { | ||
42 | +// width: 500, | ||
43 | +// height: 500, | ||
44 | + x:{ | ||
45 | + label: self._component.yAxisLabel | ||
46 | + }, | ||
47 | + y:{ | ||
48 | + label: self._component.yAxisLabel | ||
49 | + }, | ||
50 | + dot: { | ||
51 | + // color: 'red' | ||
52 | + } | ||
53 | + }; | ||
54 | + | ||
55 | + var plot = new D3ScatterPlot("#scatterplot-placeholder", this.properties.series[0].data, conf); | ||
56 | + plot.init(); | ||
57 | + } | ||
16 | }; | 58 | }; |
17 | 59 | ||
18 | ScatterplotDatalet = Polymer({ | 60 | ScatterplotDatalet = Polymer({ |