From 50380d5aa8029d9b510eabcc62457ea41920012f Mon Sep 17 00:00:00 2001
From: mwasiluk <m.wasiluk89@gmail.com>
Date: Thu, 16 Jun 2016 14:05:30 +0200
Subject: [PATCH] d3 scatterplot-datalet

---
 bower_components/d3-scatterplot/.bower.json                 |  34 ++++++++++++++++++++++++++++++++++
 bower_components/d3-scatterplot/LICENSE                     |  21 +++++++++++++++++++++
 bower_components/d3-scatterplot/README.md                   |   5 +++++
 bower_components/d3-scatterplot/bower.json                  |  24 ++++++++++++++++++++++++
 bower_components/d3-scatterplot/demo/demo.js                |  20 ++++++++++++++++++++
 bower_components/d3-scatterplot/demo/index.html             |  17 +++++++++++++++++
 bower_components/d3-scatterplot/dist/d3-scatterplot.css     |   8 ++++++++
 bower_components/d3-scatterplot/dist/d3-scatterplot.js      | 261 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 bower_components/d3-scatterplot/dist/d3-scatterplot.min.css |   1 +
 bower_components/d3-scatterplot/dist/d3-scatterplot.min.js  |   2 ++
 bower_components/d3-scatterplot/gulpfile.js                 |  85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 bower_components/d3-scatterplot/package.json                |  37 +++++++++++++++++++++++++++++++++++++
 bower_components/d3-scatterplot/src/d3-scatterplot-utils.js |  27 +++++++++++++++++++++++++++
 bower_components/d3-scatterplot/src/d3-scatterplot.js       | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 bower_components/d3-scatterplot/styles/d3-scatterplot.scss  |  18 ++++++++++++++++++
 datalets/scatterplot-datalet/demo/index.html                |   6 ++++--
 datalets/scatterplot-datalet/scatterplot-datalet.html       |  44 +++++++++++++++++++++++++++++++++++++++++++-
 17 files changed, 840 insertions(+), 3 deletions(-)
 create mode 100644 bower_components/d3-scatterplot/.bower.json
 create mode 100644 bower_components/d3-scatterplot/LICENSE
 create mode 100644 bower_components/d3-scatterplot/README.md
 create mode 100644 bower_components/d3-scatterplot/bower.json
 create mode 100644 bower_components/d3-scatterplot/demo/demo.js
 create mode 100644 bower_components/d3-scatterplot/demo/index.html
 create mode 100644 bower_components/d3-scatterplot/dist/d3-scatterplot.css
 create mode 100644 bower_components/d3-scatterplot/dist/d3-scatterplot.js
 create mode 100644 bower_components/d3-scatterplot/dist/d3-scatterplot.min.css
 create mode 100644 bower_components/d3-scatterplot/dist/d3-scatterplot.min.js
 create mode 100644 bower_components/d3-scatterplot/gulpfile.js
 create mode 100644 bower_components/d3-scatterplot/package.json
 create mode 100644 bower_components/d3-scatterplot/src/d3-scatterplot-utils.js
 create mode 100644 bower_components/d3-scatterplot/src/d3-scatterplot.js
 create mode 100644 bower_components/d3-scatterplot/styles/d3-scatterplot.scss

diff --git a/bower_components/d3-scatterplot/.bower.json b/bower_components/d3-scatterplot/.bower.json
new file mode 100644
index 0000000..975e3a1
--- /dev/null
+++ b/bower_components/d3-scatterplot/.bower.json
@@ -0,0 +1,34 @@
+{
+  "name": "d3-scatterplot",
+  "homepage": "https://github.com/mwasiluk/d3-scatterplot",
+  "authors": [
+    "Michal Wasiluk"
+  ],
+  "description": "",
+  "main": "",
+  "keywords": [
+    "scatterplot",
+    "d3"
+  ],
+  "license": "MIT",
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components",
+    "test",
+    "tests"
+  ],
+  "dependencies": {
+    "d3": "^3.5.17"
+  },
+  "version": "1.1.0",
+  "_release": "1.1.0",
+  "_resolution": {
+    "type": "version",
+    "tag": "1.1.0",
+    "commit": "9b30b60eb35b60c7c8c83cd86107a27cae0b9db9"
+  },
+  "_source": "https://github.com/mwasiluk/d3-scatterplot.git",
+  "_target": "^1.0.0",
+  "_originalSource": "d3-scatterplot"
+}
\ No newline at end of file
diff --git a/bower_components/d3-scatterplot/LICENSE b/bower_components/d3-scatterplot/LICENSE
new file mode 100644
index 0000000..102655c
--- /dev/null
+++ b/bower_components/d3-scatterplot/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Michał
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/bower_components/d3-scatterplot/README.md b/bower_components/d3-scatterplot/README.md
new file mode 100644
index 0000000..9d4d741
--- /dev/null
+++ b/bower_components/d3-scatterplot/README.md
@@ -0,0 +1,5 @@
+# d3-scatterplot
+
+<img src="http://routetopa.eu/wp-content/uploads/2015/06/eu-flag.jpg" width="22">
+This project has received funding from the European Union’s Horizon 2020 research and innovation programme under grant agreement No 645860.
+
diff --git a/bower_components/d3-scatterplot/bower.json b/bower_components/d3-scatterplot/bower.json
new file mode 100644
index 0000000..c2a06af
--- /dev/null
+++ b/bower_components/d3-scatterplot/bower.json
@@ -0,0 +1,24 @@
+{
+  "name": "d3-scatterplot",
+  "homepage": "https://github.com/mwasiluk/d3-scatterplot",
+  "authors": [
+    "Michal Wasiluk"
+  ],
+  "description": "",
+  "main": "",
+  "keywords": [
+    "scatterplot",
+    "d3"
+  ],
+  "license": "MIT",
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components",
+    "test",
+    "tests"
+  ],
+  "dependencies": {
+    "d3": "^3.5.17"
+  }
+}
diff --git a/bower_components/d3-scatterplot/demo/demo.js b/bower_components/d3-scatterplot/demo/demo.js
new file mode 100644
index 0000000..08dfb6c
--- /dev/null
+++ b/bower_components/d3-scatterplot/demo/demo.js
@@ -0,0 +1,20 @@
+var conf = {
+    // width: 500,
+    // height: 500,
+    dot:{
+        // color: 'red'
+    }
+};
+var data = [
+    [1,2],
+    [2,3],
+    [3,4],
+    [6,4],
+    [11,3],
+    [1,3.5],
+    [7,4],
+    [5,4]
+
+];
+var plot = new D3ScatterPlot("#scatterplot", data, conf);
+plot.init();
\ No newline at end of file
diff --git a/bower_components/d3-scatterplot/demo/index.html b/bower_components/d3-scatterplot/demo/index.html
new file mode 100644
index 0000000..e8bafbb
--- /dev/null
+++ b/bower_components/d3-scatterplot/demo/index.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>D3 scatterplot demo</title>
+    <link rel="stylesheet" href="../dist/d3-scatterplot.css">
+</head>
+<body>
+<h1>D3 scatterplot demo</h1>
+
+<div id="scatterplot" style="width:auto; min-height:500px;"></div>
+
+<script src="../bower_components/d3/d3.min.js" charset="utf-8"></script>
+<script src="../dist/d3-scatterplot.js" charset="utf-8"></script>
+<script src="demo.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/bower_components/d3-scatterplot/dist/d3-scatterplot.css b/bower_components/d3-scatterplot/dist/d3-scatterplot.css
new file mode 100644
index 0000000..75e7644
--- /dev/null
+++ b/bower_components/d3-scatterplot/dist/d3-scatterplot.css
@@ -0,0 +1,8 @@
+svg.mw-d3-scatterplot {
+  background-color: white;
+  font-size: 11px;
+  height: 100%; }
+  svg.mw-d3-scatterplot .mw-axis path, svg.mw-d3-scatterplot .mw-axis line {
+    fill: none;
+    stroke: #000;
+    shape-rendering: crispEdges; }
diff --git a/bower_components/d3-scatterplot/dist/d3-scatterplot.js b/bower_components/d3-scatterplot/dist/d3-scatterplot.js
new file mode 100644
index 0000000..df62d7f
--- /dev/null
+++ b/bower_components/d3-scatterplot/dist/d3-scatterplot.js
@@ -0,0 +1,261 @@
+function D3ScatterPlotUtils(){}
+
+// usage example deepExtend({}, objA, objB); => should work similar to $.extend(true, {}, objA, objB);
+D3ScatterPlotUtils.prototype.deepExtend = function(out) { //TODO consider using jquery / lo-dash / underscore / ECMA6 ; fallbacks?
+
+    var utils =this;
+    out = out || {};
+
+    for (var i = 1; i < arguments.length; i++) {
+        var obj = arguments[i];
+
+        if (!obj)
+            continue;
+
+        for (var key in obj) {
+            if (obj.hasOwnProperty(key)) {
+                if (typeof obj[key] === 'object')
+                    out[key] = utils.deepExtend(out[key], obj[key]);
+                else
+                    out[key] = obj[key];
+            }
+        }
+    }
+
+    return out;
+};
+
+
+function D3ScatterPlot(placeholderSelector, data, config){
+    this.utils = new D3ScatterPlotUtils();
+    this.placeholderSelector = placeholderSelector;
+    this.svg=null;
+    this.defaultConfig = {
+        width: 0,
+        height: 0,
+        margin:{
+            left: 50,
+            right: 30,
+            top: 30,
+            bottom: 50
+        },
+        x:{// X axis config
+            label: 'X', // axis label
+            value: function(d) { return d[0] }, // x value accessor
+            orient: "bottom"
+        },
+        y:{// Y axis config
+            label: 'Y', // axis label
+            value: function(d) { return d[1] }, // y value accessor
+            orient: "left"
+        },
+        dot:{
+            radius: 2,
+            color: function(d) { return d[0]*d[1] }, // string or function returning color's value for color scale
+            d3ColorCategory: 'category10'
+        }
+    };
+
+    if(data){
+        this.setData(data);
+    }
+
+    if(config){
+        this.setConfig(config);
+    }
+
+}
+
+D3ScatterPlot.prototype.setData = function (data){
+    this.data = data;
+    return this;
+};
+
+D3ScatterPlot.prototype.setConfig = function (config){
+    this.config = this.utils.deepExtend({}, this.defaultConfig, config);
+    return this;
+};
+D3ScatterPlot.prototype.initPlot = function (){
+    var self=this;
+    var margin = this.config.margin;
+    var conf = this.config;
+    this.plot={
+        x: {},
+        y: {},
+        dot: {
+            color: null//color scale mapping function
+        }
+    };
+
+    var width = conf.width;
+    var placeholderNode = d3.select(this.placeholderSelector).node();
+
+    if(!width){
+        width =placeholderNode.getBoundingClientRect().width;
+    }
+    var height = conf.height;
+    if(!height){
+        height =placeholderNode.getBoundingClientRect().height;
+    }
+
+    this.plot.width = width - margin.left - margin.right;
+    this.plot.height = height - margin.top - margin.bottom;
+
+    this.setupX();
+    this.setupY();
+
+    if(conf.dot.d3ColorCategory){
+        this.plot.dot.colorCategory = d3.scale[conf.dot.d3ColorCategory]();
+    }
+    var colorValue = conf.dot.color;
+    if(colorValue){
+        this.plot.dot.colorValue = colorValue;
+
+        if (typeof colorValue === 'string' || colorValue instanceof String){
+            this.plot.dot.color = colorValue;
+        }else if(this.plot.dot.colorCategory){
+            this.plot.dot.color = function(d){
+                return self.plot.dot.colorCategory(self.plot.dot.colorValue(d));
+            }
+        }
+
+
+    }
+
+    return this;
+};
+
+D3ScatterPlot.prototype.setupX = function (){
+
+    var plot = this.plot;
+    var x = plot.x;
+    var conf = this.config.x;
+
+    /*
+     * value accessor - returns the value to encode for a given data object.
+     * scale - maps value to a visual display encoding, such as a pixel position.
+     * map function - maps from data value to display value
+     * axis - sets up axis
+     */
+    x.value = conf.value;
+    x.scale = d3.scale.linear().range([0, plot.width]);
+    x.map = function(d) { return x.scale(x.value(d));};
+    x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient);
+    var data = this.data;
+    plot.x.scale.domain([d3.min(data, plot.x.value)-1, d3.max(data, plot.x.value)+1]);
+
+
+};
+
+D3ScatterPlot.prototype.setupY = function (){
+
+    var plot = this.plot;
+    var y = plot.y;
+    var conf = this.config.y;
+
+    /*
+     * value accessor - returns the value to encode for a given data object.
+     * scale - maps value to a visual display encoding, such as a pixel position.
+     * map function - maps from data value to display value
+     * axis - sets up axis
+     */
+    y.value = conf.value;
+    y.scale = d3.scale.linear().range([plot.height, 0]);
+    y.map = function(d) { return y.scale(y.value(d));};
+    y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient);
+
+
+    var data = this.data;
+    plot.y.scale.domain([d3.min(data, plot.y.value)-1, d3.max(data, plot.y.value)+1]);
+};
+
+D3ScatterPlot.prototype.drawPlot = function (){
+    this.drawAxisX();
+    this.drawAxisY();
+    this.drawDots();
+};
+D3ScatterPlot.prototype.drawAxisX = function (){
+    var self = this;
+    var plot = self.plot;
+    var axisConf = this.config.x;
+    self.svgG.append("g")
+        .attr("class", "mw-axis mw-axis-x")
+        .attr("transform", "translate(0," + plot.height + ")")
+        .call(plot.x.axis)
+        .append("text")
+        .attr("class", "mw-label")
+        .attr("transform", "translate("+ (plot.width/2) +","+ (self.config.margin.bottom) +")")  // text is drawn off the screen top left, move down and out and rotate
+        .attr("dy", "-1em")
+        .style("text-anchor", "middle")
+        .text(axisConf.label);
+};
+
+D3ScatterPlot.prototype.drawAxisY = function (){
+    var self = this;
+    var plot = self.plot;
+    var axisConf = this.config.y;
+    self.svgG.append("g")
+        .attr("class", "mw-axis mw-axis-y")
+        .call(plot.y.axis)
+        .append("text")
+        .attr("class", "mw-label")
+        .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
+        .attr("dy", "1em")
+        .style("text-anchor", "middle")
+        .text(axisConf.label);
+};
+
+
+D3ScatterPlot.prototype.drawDots = function (){
+    var self = this;
+    var plot = self.plot;
+    var data = this.data;
+    var dots = self.svgG.selectAll(".mw-dot")
+        .data(data)
+        .enter().append("circle")
+        .attr("class", "mw-dot")
+        .attr("r", self.config.dot.radius)
+        .attr("cx", plot.x.map)
+        .attr("cy", plot.y.map);
+
+    if(plot.dot.color){
+        dots.style("fill", plot.dot.color)
+    }
+
+};
+
+D3ScatterPlot.prototype.initSvg = function (){
+    var self = this;
+    var config = this.config;
+
+
+
+    var width = self.plot.width+ config.margin.left + config.margin.right;
+    var height =  self.plot.height+ config.margin.top + config.margin.bottom;
+    var aspect = width / height;
+    self.svg = d3.select(self.placeholderSelector).append("svg")
+        .attr("width", width)
+        .attr("height", height)
+        .attr("viewBox", "0 0 "+" "+width+" "+height)
+        .attr("preserveAspectRatio", "xMidYMid meet")
+        .attr("class", "mw-d3-scatterplot");
+    self.svgG = self.svg.append("g")
+        .attr("transform", "translate(" + config.margin.left + "," + config.margin.top + ")");
+
+    if(!config.width || config.height ){
+        d3.select(window)
+            .on("resize", function() {
+                //TODO add responsiveness if width/height not specified
+            });
+    }
+
+};
+
+D3ScatterPlot.prototype.init = function (){
+    var self = this;
+    self.initPlot();
+    self.initSvg();
+    self.drawPlot();
+
+};
+
diff --git a/bower_components/d3-scatterplot/dist/d3-scatterplot.min.css b/bower_components/d3-scatterplot/dist/d3-scatterplot.min.css
new file mode 100644
index 0000000..96a3abf
--- /dev/null
+++ b/bower_components/d3-scatterplot/dist/d3-scatterplot.min.css
@@ -0,0 +1 @@
+svg.mw-d3-scatterplot{background-color:#fff;font-size:11px;height:100%}svg.mw-d3-scatterplot .mw-axis line,svg.mw-d3-scatterplot .mw-axis path{fill:none;stroke:#000;shape-rendering:crispEdges}
\ No newline at end of file
diff --git a/bower_components/d3-scatterplot/dist/d3-scatterplot.min.js b/bower_components/d3-scatterplot/dist/d3-scatterplot.min.js
new file mode 100644
index 0000000..bd591cc
--- /dev/null
+++ b/bower_components/d3-scatterplot/dist/d3-scatterplot.min.js
@@ -0,0 +1,2 @@
+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};
+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()};
\ No newline at end of file
diff --git a/bower_components/d3-scatterplot/gulpfile.js b/bower_components/d3-scatterplot/gulpfile.js
new file mode 100644
index 0000000..82171a7
--- /dev/null
+++ b/bower_components/d3-scatterplot/gulpfile.js
@@ -0,0 +1,85 @@
+var gulp = require('gulp');
+var del = require('del');
+var merge = require('merge-stream');
+var plugins = require('gulp-load-plugins')();
+var browserSync = require('browser-sync').create();
+
+gulp.task('clean', function (cb) {
+    return del(['tmp', 'dist'], cb);
+});
+
+gulp.task('build-css', function () {
+    var pretty = gulp.src('./styles/*')
+        .pipe(plugins.plumber({ errorHandler: onError }))
+        .pipe(plugins.sass())
+        .pipe(plugins.minifyCss())
+        .pipe(plugins.rename({
+            extname: '.min.css'
+        }))
+        .pipe(gulp.dest('./dist'));
+    var ugly = gulp.src('./styles/*')
+        .pipe(plugins.plumber({ errorHandler: onError }))
+        .pipe(plugins.sass())
+        .pipe(plugins.rename({
+            extname: '.css'
+        }))
+        .pipe(gulp.dest('./dist'));
+    return merge(pretty, ugly);
+});
+
+gulp.task('build-js', function () {
+    var jsFileName = 'd3-scatterplot';
+   var pretty = gulp.src('./src/*.js')
+        .pipe(plugins.plumber({ errorHandler: onError }))
+        .pipe(plugins.concat(jsFileName+'.js'))
+        .pipe(gulp.dest('dist'));
+
+    var ugly = gulp.src('./src/*.js')
+        .pipe(plugins.plumber({ errorHandler: onError }))
+        .pipe(plugins.uglify())
+        .pipe(plugins.stripDebug())
+        .pipe(plugins.concat(jsFileName+'.min.js'))
+        .pipe(gulp.dest('dist'));
+
+    return merge(pretty, ugly);
+});
+
+gulp.task('build-clean', ['clean'], function () {
+    gulp.start('build');
+});
+
+gulp.task('build', ['build-css', 'build-js'], function () {
+
+});
+
+gulp.task('watch', function() {
+    return gulp.watch(['./src/**/*.html', './styles/*.*css', 'src/**/*.js'], ['default']);
+});
+
+gulp.task('default', ['build-clean'],  function() {
+
+});
+
+gulp.task('default-watch', ['default'], ()=>{ browserSync.reload() });
+gulp.task('serve', ['default'], ()=>{
+    browserSync.init({
+        server: {
+            baseDir: "demo",
+            index: "index.html",
+            routes: {
+                "/bower_components": "bower_components",
+                "/dist": "dist"
+            }
+        },
+        port: 8089,
+        open: 'local',
+        browser: "google chrome"
+    });
+    gulp.watch(['i18n/**/*.json', './src/**/*.html', './styles/*.*css', 'src/**/*.js', 'demo/*.*'], ['default-watch']);
+});
+
+// error function for plumber
+var onError = function (err) {
+    console.log(err);
+    this.emit('end');
+};
\ No newline at end of file
diff --git a/bower_components/d3-scatterplot/package.json b/bower_components/d3-scatterplot/package.json
new file mode 100644
index 0000000..4b5ed55
--- /dev/null
+++ b/bower_components/d3-scatterplot/package.json
@@ -0,0 +1,37 @@
+{
+  "name": "d3-scatterplot",
+  "version": "1.0.0",
+  "description": "d3 scatterplot",
+  "main": "gulpfile.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/mwasiluk/d3-scatterplot.git"
+  },
+  "keywords": [
+    "d3",
+    "scatterplot"
+  ],
+  "author": "Michal Wasiluk",
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/mwasiluk/d3-scatterplot/issues"
+  },
+  "homepage": "https://github.com/mwasiluk/d3-scatterplot#readme",
+  "devDependencies": {
+    "browser-sync": "^2.13.0",
+    "del": "^2.2.0",
+    "gulp": "^3.9.1",
+    "gulp-concat": "^2.6.0",
+    "gulp-load-plugins": "^1.2.4",
+    "gulp-minify-css": "^1.2.4",
+    "gulp-plumber": "^1.1.0",
+    "gulp-rename": "^1.2.2",
+    "gulp-sass": "^2.3.1",
+    "gulp-strip-debug": "^1.1.0",
+    "gulp-uglify": "^1.5.3",
+    "merge-stream": "^1.0.0"
+  }
+}
diff --git a/bower_components/d3-scatterplot/src/d3-scatterplot-utils.js b/bower_components/d3-scatterplot/src/d3-scatterplot-utils.js
new file mode 100644
index 0000000..5779dc2
--- /dev/null
+++ b/bower_components/d3-scatterplot/src/d3-scatterplot-utils.js
@@ -0,0 +1,27 @@
+function D3ScatterPlotUtils(){}
+
+// usage example deepExtend({}, objA, objB); => should work similar to $.extend(true, {}, objA, objB);
+D3ScatterPlotUtils.prototype.deepExtend = function(out) { //TODO consider using jquery / lo-dash / underscore / ECMA6 ; fallbacks?
+
+    var utils =this;
+    out = out || {};
+
+    for (var i = 1; i < arguments.length; i++) {
+        var obj = arguments[i];
+
+        if (!obj)
+            continue;
+
+        for (var key in obj) {
+            if (obj.hasOwnProperty(key)) {
+                if (typeof obj[key] === 'object')
+                    out[key] = utils.deepExtend(out[key], obj[key]);
+                else
+                    out[key] = obj[key];
+            }
+        }
+    }
+
+    return out;
+};
+
diff --git a/bower_components/d3-scatterplot/src/d3-scatterplot.js b/bower_components/d3-scatterplot/src/d3-scatterplot.js
new file mode 100644
index 0000000..ad6e77f
--- /dev/null
+++ b/bower_components/d3-scatterplot/src/d3-scatterplot.js
@@ -0,0 +1,233 @@
+function D3ScatterPlot(placeholderSelector, data, config){
+    this.utils = new D3ScatterPlotUtils();
+    this.placeholderSelector = placeholderSelector;
+    this.svg=null;
+    this.defaultConfig = {
+        width: 0,
+        height: 0,
+        margin:{
+            left: 50,
+            right: 30,
+            top: 30,
+            bottom: 50
+        },
+        x:{// X axis config
+            label: 'X', // axis label
+            value: function(d) { return d[0] }, // x value accessor
+            orient: "bottom"
+        },
+        y:{// Y axis config
+            label: 'Y', // axis label
+            value: function(d) { return d[1] }, // y value accessor
+            orient: "left"
+        },
+        dot:{
+            radius: 2,
+            color: function(d) { return d[0]*d[1] }, // string or function returning color's value for color scale
+            d3ColorCategory: 'category10'
+        }
+    };
+
+    if(data){
+        this.setData(data);
+    }
+
+    if(config){
+        this.setConfig(config);
+    }
+
+}
+
+D3ScatterPlot.prototype.setData = function (data){
+    this.data = data;
+    return this;
+};
+
+D3ScatterPlot.prototype.setConfig = function (config){
+    this.config = this.utils.deepExtend({}, this.defaultConfig, config);
+    return this;
+};
+D3ScatterPlot.prototype.initPlot = function (){
+    var self=this;
+    var margin = this.config.margin;
+    var conf = this.config;
+    this.plot={
+        x: {},
+        y: {},
+        dot: {
+            color: null//color scale mapping function
+        }
+    };
+
+    var width = conf.width;
+    var placeholderNode = d3.select(this.placeholderSelector).node();
+
+    if(!width){
+        width =placeholderNode.getBoundingClientRect().width;
+    }
+    var height = conf.height;
+    if(!height){
+        height =placeholderNode.getBoundingClientRect().height;
+    }
+
+    this.plot.width = width - margin.left - margin.right;
+    this.plot.height = height - margin.top - margin.bottom;
+
+    this.setupX();
+    this.setupY();
+
+    if(conf.dot.d3ColorCategory){
+        this.plot.dot.colorCategory = d3.scale[conf.dot.d3ColorCategory]();
+    }
+    var colorValue = conf.dot.color;
+    if(colorValue){
+        this.plot.dot.colorValue = colorValue;
+
+        if (typeof colorValue === 'string' || colorValue instanceof String){
+            this.plot.dot.color = colorValue;
+        }else if(this.plot.dot.colorCategory){
+            this.plot.dot.color = function(d){
+                return self.plot.dot.colorCategory(self.plot.dot.colorValue(d));
+            }
+        }
+
+
+    }
+
+    return this;
+};
+
+D3ScatterPlot.prototype.setupX = function (){
+
+    var plot = this.plot;
+    var x = plot.x;
+    var conf = this.config.x;
+
+    /*
+     * value accessor - returns the value to encode for a given data object.
+     * scale - maps value to a visual display encoding, such as a pixel position.
+     * map function - maps from data value to display value
+     * axis - sets up axis
+     */
+    x.value = conf.value;
+    x.scale = d3.scale.linear().range([0, plot.width]);
+    x.map = function(d) { return x.scale(x.value(d));};
+    x.axis = d3.svg.axis().scale(x.scale).orient(conf.orient);
+    var data = this.data;
+    plot.x.scale.domain([d3.min(data, plot.x.value)-1, d3.max(data, plot.x.value)+1]);
+
+
+};
+
+D3ScatterPlot.prototype.setupY = function (){
+
+    var plot = this.plot;
+    var y = plot.y;
+    var conf = this.config.y;
+
+    /*
+     * value accessor - returns the value to encode for a given data object.
+     * scale - maps value to a visual display encoding, such as a pixel position.
+     * map function - maps from data value to display value
+     * axis - sets up axis
+     */
+    y.value = conf.value;
+    y.scale = d3.scale.linear().range([plot.height, 0]);
+    y.map = function(d) { return y.scale(y.value(d));};
+    y.axis = d3.svg.axis().scale(y.scale).orient(conf.orient);
+
+
+    var data = this.data;
+    plot.y.scale.domain([d3.min(data, plot.y.value)-1, d3.max(data, plot.y.value)+1]);
+};
+
+D3ScatterPlot.prototype.drawPlot = function (){
+    this.drawAxisX();
+    this.drawAxisY();
+    this.drawDots();
+};
+D3ScatterPlot.prototype.drawAxisX = function (){
+    var self = this;
+    var plot = self.plot;
+    var axisConf = this.config.x;
+    self.svgG.append("g")
+        .attr("class", "mw-axis mw-axis-x")
+        .attr("transform", "translate(0," + plot.height + ")")
+        .call(plot.x.axis)
+        .append("text")
+        .attr("class", "mw-label")
+        .attr("transform", "translate("+ (plot.width/2) +","+ (self.config.margin.bottom) +")")  // text is drawn off the screen top left, move down and out and rotate
+        .attr("dy", "-1em")
+        .style("text-anchor", "middle")
+        .text(axisConf.label);
+};
+
+D3ScatterPlot.prototype.drawAxisY = function (){
+    var self = this;
+    var plot = self.plot;
+    var axisConf = this.config.y;
+    self.svgG.append("g")
+        .attr("class", "mw-axis mw-axis-y")
+        .call(plot.y.axis)
+        .append("text")
+        .attr("class", "mw-label")
+        .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
+        .attr("dy", "1em")
+        .style("text-anchor", "middle")
+        .text(axisConf.label);
+};
+
+
+D3ScatterPlot.prototype.drawDots = function (){
+    var self = this;
+    var plot = self.plot;
+    var data = this.data;
+    var dots = self.svgG.selectAll(".mw-dot")
+        .data(data)
+        .enter().append("circle")
+        .attr("class", "mw-dot")
+        .attr("r", self.config.dot.radius)
+        .attr("cx", plot.x.map)
+        .attr("cy", plot.y.map);
+
+    if(plot.dot.color){
+        dots.style("fill", plot.dot.color)
+    }
+
+};
+
+D3ScatterPlot.prototype.initSvg = function (){
+    var self = this;
+    var config = this.config;
+
+
+
+    var width = self.plot.width+ config.margin.left + config.margin.right;
+    var height =  self.plot.height+ config.margin.top + config.margin.bottom;
+    var aspect = width / height;
+    self.svg = d3.select(self.placeholderSelector).append("svg")
+        .attr("width", width)
+        .attr("height", height)
+        .attr("viewBox", "0 0 "+" "+width+" "+height)
+        .attr("preserveAspectRatio", "xMidYMid meet")
+        .attr("class", "mw-d3-scatterplot");
+    self.svgG = self.svg.append("g")
+        .attr("transform", "translate(" + config.margin.left + "," + config.margin.top + ")");
+
+    if(!config.width || config.height ){
+        d3.select(window)
+            .on("resize", function() {
+                //TODO add responsiveness if width/height not specified
+            });
+    }
+
+};
+
+D3ScatterPlot.prototype.init = function (){
+    var self = this;
+    self.initPlot();
+    self.initSvg();
+    self.drawPlot();
+
+};
+
diff --git a/bower_components/d3-scatterplot/styles/d3-scatterplot.scss b/bower_components/d3-scatterplot/styles/d3-scatterplot.scss
new file mode 100644
index 0000000..8de3e10
--- /dev/null
+++ b/bower_components/d3-scatterplot/styles/d3-scatterplot.scss
@@ -0,0 +1,18 @@
+svg.mw-d3-scatterplot{
+  background-color: white;
+  font-size: 11px;
+  height: 100%;
+  .mw-axis{
+
+    path, line{
+      fill: none;
+      stroke: #000;
+      shape-rendering: crispEdges;
+    }
+  }
+
+  .mw-dot {
+    //stroke: #000;
+  }
+
+}
diff --git a/datalets/scatterplot-datalet/demo/index.html b/datalets/scatterplot-datalet/demo/index.html
index 09a0bae..017c625 100644
--- a/datalets/scatterplot-datalet/demo/index.html
+++ b/datalets/scatterplot-datalet/demo/index.html
@@ -13,9 +13,11 @@
 <script src="https://code.jquery.com/jquery-2.1.4.min.js" type="text/javascript"></script>
 <link rel="import" href="../scatterplot-datalet.html" />
 
+<div style="height: 600px">
+    <scatterplot-datalet data-url="http://ckan.ancitel.it/api/action/datastore_search?resource_id=29d9700a-fb2c-45fe-9cea-da856d5afd6c&limit=500"
+                         fields='["result,records,pop_residente","result,records,superficie_kmq"]'></scatterplot-datalet>
+</div>
 
-<scatterplot-datalet data-url="http://ckan.ancitel.it/api/action/datastore_search?resource_id=29d9700a-fb2c-45fe-9cea-da856d5afd6c&limit=500"
-                     fields='["result,records,area_geo","result,records,pop_residente","result,records,superficie_kmq"]'></scatterplot-datalet>
 
 </body>
 </html>
\ No newline at end of file
diff --git a/datalets/scatterplot-datalet/scatterplot-datalet.html b/datalets/scatterplot-datalet/scatterplot-datalet.html
index 6179fc8..532d7f0 100644
--- a/datalets/scatterplot-datalet/scatterplot-datalet.html
+++ b/datalets/scatterplot-datalet/scatterplot-datalet.html
@@ -4,15 +4,57 @@
 
 <dom-module id="scatterplot-datalet">
     <template>
+        <link rel="stylesheet" href="../../bower_components/d3-scatterplot/dist/d3-scatterplot.min.css">
+        <style is="custom-style">
+            :host ::content #scatterplot-placeholder {
+                width: 100%;
+                height: 70%;
+                background: #ffffff;
+                position: relative;
+            }
+        </style>
         <div id="scatterplot-placeholder"></div>
         <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>
     </template>
-
     <script src="../shared_js/d3.js"></script>
+    <script type="text/javascript" src="../../bower_components/d3-scatterplot/dist/d3-scatterplot.js"></script>
     <script>
 
         var ScatterplotBehavior = {
+            presentData: function () {
+
+                var self =this;
+                var scatterSeries = [];
+                var series = [];
+                var point = [];
+
+                for (var j = 0; j < this.data[0]["data"].length; j++) {
+                    point = [this.data[0].data[j], this.data[1].data[j]];
+                    series.push(point);
+                }
 
+                scatterSeries.push({data: series});
+
+                this.properties.series = scatterSeries;
+                this._component.legend = false;
+
+                var conf = {
+//                    width: 500,
+//                    height: 500,
+                    x:{
+                        label: self._component.yAxisLabel
+                    },
+                    y:{
+                        label: self._component.yAxisLabel
+                    },
+                    dot: {
+                        // color: 'red'
+                    }
+                };
+
+                var plot = new D3ScatterPlot("#scatterplot-placeholder", this.properties.series[0].data, conf);
+                plot.init();
+            }
         };
 
         ScatterplotDatalet = Polymer({
--
libgit2 0.21.4