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 | 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 | 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 | 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 | 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 | 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 | 13 | <script src="https://code.jquery.com/jquery-2.1.4.min.js" type="text/javascript"></script> |
14 | 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 | 22 | </body> |
21 | 23 | </html> |
22 | 24 | \ No newline at end of file |
... | ... |
datalets/scatterplot-datalet/scatterplot-datalet.html
... | ... | @@ -4,15 +4,57 @@ |
4 | 4 | |
5 | 5 | <dom-module id="scatterplot-datalet"> |
6 | 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 | 16 | <div id="scatterplot-placeholder"></div> |
8 | 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 | 18 | </template> |
10 | - | |
11 | 19 | <script src="../shared_js/d3.js"></script> |
20 | + <script type="text/javascript" src="../../bower_components/d3-scatterplot/dist/d3-scatterplot.js"></script> | |
12 | 21 | <script> |
13 | 22 | |
14 | 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 | 60 | ScatterplotDatalet = Polymer({ |
... | ... |