In [186]:
%%javascript

// Setup Javascript playground
window.get_element = function(el){
    if(el){ $(el).html('') }
    return (el !== undefined) ? el[0] : $('script').last().parent()[0];
};

element = undefined;

// Define external scripts
require.config({
    paths: {
        lodash: "http://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.7.0/lodash.min",
        d3: "http://d3js.org/d3.v3.min"
    }
});

// Helper functions
console.write = function(content, element){
    console.log(content);
    $(element).append($('<p>' + content + '</p>'))
}

Iteration 1

In [337]:
%%javascript

window.LineGraph = (function(){
    var LineGraph = function(target, data){
        this.target = target;
        this.data = data || [5,9,8,3,10,9,8,9,8,2,0,3,9,3,8];
        this.width = 600;
        this.height = 200;

        this.svg = d3.select(this.target)
            .append('svg')
            .attr('width', this.width)
            .attr('height', this.height)
            .style('border', '1px solid lightgray');
    }

    LineGraph.prototype = {
        line: function(){
            return d3.svg.line()
                 .x(function(d, i) { return i * 30; })
                 .y(function(d) { return 200 - d * 10; })
                 .interpolate("linear");
        },
        
        drawCircles: function(){
            this.svg.selectAll('circle')
                .data(this.data)
                .enter()
                .append('circle')
                .style('fill', 'black')
                .attr('cx', function(d, i){ return i * 30})
                .attr('cy', function(d){ return 200 - d * 10})
                .attr('r', '3px')

        },
        
        drawLine: function(){
            this.svg.append("path")
                .attr("d", this.line()(this.data))
                .attr("stroke", "skyblue")
                .attr("stroke-width", 2)
                .attr("fill", "none");
        
        },
        
        drawText: function(){
            this.svg.selectAll('text')
                .data(this.data)
                .enter()
                .append('text')
                .attr('x', function(d, i){ return i * 30 - 5})
                .attr('y', function(d){ return 200 - d * 10 - 5})
                .style('size', '8px')
                .text(function(d){ return d});
        },
        
        draw: function(){
            this.drawLine();
            this.drawCircles();
            this.drawText();
        }
    }
    
    return LineGraph;
})();
In [338]:
%%javascript

(function(){
    var target = get_element(element);
    
    var draw = function(){
        var lineGraph = new window.LineGraph(target);
        lineGraph.drawLine();
    }
    
    require(['d3'], draw);
})()
In [339]:
%%javascript

(function(){
    var target = get_element(element);
    
    var draw = function(){
        var lineGraph = new window.LineGraph(target);
        lineGraph.drawCircles();
    }
    
    require(['d3'], draw);
})()
In [340]:
%%javascript

(function(){
    var target = get_element(element);
    
    var draw = function(){
        var lineGraph = new window.LineGraph(target);
        lineGraph.drawText();
    }
    
    require(['d3'], draw);
})()
In [341]:
%%javascript

(function(){
    var target = get_element(element);
    
    var draw = function(){
        var lineGraph = new window.LineGraph(target);
        lineGraph.draw();
    }
    
    require(['d3'], draw);
})()
In [354]:
%%javascript

window.randomData = function(count, min, max){
    var array = [];

    var i = 0;
    while(i < count){
        array.push(window.random(min, max));
        i++;
    }
    
    console.log(array);
    
    return array;
};

window.random = function(min, max){
    return parseInt(Math.random() * max + min)
}
In [355]:
%%javascript

console.write(window.randomData(30, 0, 100), get_element(element))
In [344]:
%%javascript

(function(){
    var target = get_element(element);
    
    var draw = function(){
        var data = window.randomData(30, 0, 20);
        var lineGraph = new window.LineGraph(target, data);
        lineGraph.draw();
    }
    
    require(['d3'], draw);
})();

Iteration 2

In [1]:
%%javascript

window.LineGraph2 = (function(){
    var LineGraph = function(target, data){
        var self = this;
        
        this.target = target;
        this.data = data || [5,9,8,3,10,9,8,9,8,2,0,3,9,3,8];
        this.width = 600;
        this.height = 200;

        this.svg = d3.select(this.target)
            .append('svg')
            .attr('width', this.width)
            .attr('height', this.height)
            .style('border', '1px solid lightgray');
        
        this.refreshScale(this.data);
        
        this.svg.on('click', function(event){
            var count = window.random(20, 100);
            var max = window.random(50, 200);
            self.update(window.randomData(count, 0, max));
        });
    }

    LineGraph.prototype = {
        refreshScale: function(data){
            this.yScale = d3.scale.linear()
                .domain([d3.min(data), d3.max(data)])
                .range([0, this.height])

            this.xScale = d3.scale.linear()
                .domain([0, data.length])
                .range([0, this.width])            
        },
        
        line: function(){
            var self = this;
            return d3.svg.line()
                 .x(function(d, i) { return self.xScale(i); })
                 .y(function(d) { return self.yScale(d); })
                 .interpolate("linear");
        },
        
        drawCircles: function(){
            var self = this;
            this.svg.selectAll('circle')
                .data(this.data)
                .enter()
                .append('circle')
                .style('fill', 'gray')
                .attr('cx', function(d, i){ return self.xScale(i);})
                .attr('cy', function(d){ return self.yScale(d);})
                .attr('r', '2px')

        },
        
        drawLine: function(){
            this.svg.append("path")
                .attr("d", this.line()(this.data))
                .attr("stroke", "skyblue")
                .attr("stroke-width", 2)
                .attr("fill", "none");
        },
        
        drawText: function(){
            var self = this;
            this.svg.selectAll('text')
                .data(this.data)
                .enter()
                .append('text')
                .attr('x', function(d, i){ return self.xScale(i);} )
                .attr('y', function(d){ return self.yScale(d)})
                .style('size', '8px')
                .text(function(d){ return d});
        },
        
        draw: function(){
            this.drawLine();
            this.drawCircles();
            this.drawText();
        },

        updateCircles: function(data){
            var self = this;
            this.svg.selectAll('circle')
                .data(data)
                .transition()
                .duration(300)
                .style('fill', 'gray')
                .attr('cx', function(d, i){ return self.xScale(i);})
                .attr('cy', function(d){ return self.yScale(d);})
                .attr('r', '2px')
            
            this.svg.selectAll('circle')
                .data(data)
                .enter()
                .append('circle')
                .transition()
                .duration(300)
                .style('fill', 'gray')
                .attr('cx', function(d, i){ return self.xScale(i);})
                .attr('cy', function(d){ return self.yScale(d);})
                .attr('r', '2px')
            
            this.svg.selectAll('circle')
                .data(data)
                .exit()
                .remove()
        },
        
        updateLine: function(data){
            this.svg.selectAll('path')
                .transition()
                .duration(300)
                .attr('d', this.line()(data))
            
        },
        
        updateText: function(data){
            var self = this;
            this.svg.selectAll('text')
                .data(data)
                .transition()
                .duration(300)
                .attr('x', function(d, i){ return self.xScale(i);} )
                .attr('y', function(d){ return self.yScale(d)})
                .style('size', '8px')
                .text(function(d){ return d});
            
            this.svg.selectAll('text')
                .data(data)
                .enter()
                .append('text')
                .transition()
                .duration(300)
                .attr('x', function(d, i){ return self.xScale(i);} )
                .attr('y', function(d){ return self.yScale(d)})
                .style('size', '8px')
                .text(function(d){ return d});
            
            this.svg.selectAll('text')
                .data(data)
                .exit()
                .remove()
        },
        
        update: function(data){
            this.refreshScale(data);
            this.updateCircles(data);
            this.updateLine(data);
            this.updateText(data);
        }
    };
    
    return LineGraph;
})();
In [375]:
%%javascript

var data = [5,9,8,3,10,9,8,9,8,2,0,3,9,3,8];
var height = 200;

require(['d3'], function(){
    var yScale = d3.scale.linear()
        .domain([d3.min(data), d3.max(data)])
        .range([0, height])

    console.write(yScale(10) ,get_element(element))
});
In [376]:
%%javascript

(function(){
    var target = get_element(element);
    
    var draw = function(){
        var data = window.randomData(30, 0, 80);
        var lineGraph = new window.LineGraph2(target, data);
        lineGraph.draw();
    }
    
    require(['d3'], draw);
})();

Iteration 3

In [153]:
%%html

<style>
.axis path,
.axis line {
   fill: none;
   stroke: black;
   shape-rendering: crispEdges;
}

.axis text {
   font-family: sans-serif;
   font-size: 11px;
}

.itemValueText {
    fill: gray
}
</style>
In [194]:
%%javascript

window.LineGraph3 = (function(){
    var LineGraph = function(target, data){
        var self = this;
        
        this.target = target;
        this.data = data || [5,9,8,3,10,9,8,9,8,2,0,3,9,3,8];
        this.width = 900;
        this.height = 250;
        this.padding = 40;

        this.svg = d3.select(this.target)
            .append('svg')
            .attr('width', this.width)
            .attr('height', this.height)
            .style('border', '1px solid lightgray');
        
        this.refreshScale(this.data);
        
        this.svg.on('click', function(event){
            var count = window.random(20, 100);
            var max = window.random(50, 200);
            self.update(window.randomData(count, 0, max));
        });
    }

    LineGraph.prototype = {
        refreshScale: function(data){
            this.yScale = d3.scale.linear()
                .domain([d3.max(data), d3.min(data)])
                .range([0 + this.padding, this.height - this.padding])

            this.xScale = d3.scale.linear()
                .domain([0, data.length])
                .range([0 + this.padding, this.width - this.padding])
            
            this.xAxis = d3.svg.axis()
                .scale(this.xScale)
                .orient("bottom");
            
            this.yAxis = d3.svg.axis()
                .scale(this.yScale)
                .orient("left")
        },
        
        line: function(){
            var self = this;
            return d3.svg.line()
                 .x(function(d, i) { return self.xScale(i); })
                 .y(function(d) { return self.yScale(d); })
                 .interpolate("linear");
        },
        
        drawCircles: function(){
            var self = this;
            this.svg.selectAll('circle')
                .data(this.data)
                .enter()
                .append('circle')
                .style('fill', 'gray')
                .attr('cx', function(d, i){ return self.xScale(i);})
                .attr('cy', function(d){ return self.yScale(d);})
                .attr('r', '2px')

        },
        
        drawLine: function(){
            this.svg.append("path")
                .attr('class', 'itemLine')
                .attr("d", this.line()(this.data))
                .attr("stroke", "skyblue")
                .attr("stroke-width", 2)
                .attr("fill", "none");
        },
        
        drawText: function(){
            var self = this;
            this.svg.selectAll('text')
                .data(this.data)
                .enter()
                .append('text')
                .attr('class', 'itemValueText')
                .attr('x', function(d, i){ return self.xScale(i);} )
                .attr('y', function(d){ return self.yScale(d)})
                .style('size', '8px')
                .text(function(d){ return d});
        },
        
        drawAxis: function(){
            this.svg.append("g")
                .attr("class", "xAxis axis")
                .attr("transform", "translate(0," + (this.height - this.padding) + ")")
                .call(this.xAxis);

            this.svg.append("g")
                .attr("class", "yAxis axis")
                .attr("transform", "translate(" + this.padding + ",0)")
                .call(this.yAxis)  
        },
        
        
        draw: function(){
            this.drawLine();
            this.drawCircles();
            this.drawText();
            this.drawAxis();
        },

        updateCircles: function(data){
            var self = this;
            this.svg.selectAll('circle')
                .data(data)
                .transition()
                .duration(300)
                .style('fill', 'gray')
                .attr('cx', function(d, i){ return self.xScale(i);})
                .attr('cy', function(d){ return self.yScale(d);})
                .attr('r', '2px')
            
            this.svg.selectAll('circle')
                .data(data)
                .enter()
                .append('circle')
                .transition()
                .duration(300)
                .style('fill', 'gray')
                .attr('cx', function(d, i){ return self.xScale(i);})
                .attr('cy', function(d){ return self.yScale(d);})
                .attr('r', '2px')
            
            this.svg.selectAll('circle')
                .data(data)
                .exit()
                .remove()
        },
        
        updateLine: function(data){
            this.svg.selectAll('path.itemLine')
                .transition()
                .duration(300)
                .attr('d', this.line()(data))
            
        },
        
        updateText: function(data){
            var self = this;
            this.svg.selectAll('text.itemValueText')
                .data(data)
                .transition()
                .duration(300)
                .attr('x', function(d, i){ return self.xScale(i);} )
                .attr('y', function(d){ return self.yScale(d)})
                .style('size', '8px')
                .text(function(d){ return d});
            
            this.svg.selectAll('text.itemValueText')
                .data(data)
                .enter()
                .append('text')
                .transition()
                .duration(300)
                .attr('class', 'itemValueText')
                .attr('x', function(d, i){ return self.xScale(i);} )
                .attr('y', function(d){ return self.yScale(d)})
                .style('size', '8px')
                .text(function(d){ return d});
            
            this.svg.selectAll('text.itemValueText')
                .data(data)
                .exit()
                .remove()
        },
        
        updateAxis: function(){
            this.svg.select('.xAxis')
                .attr("transform", "translate(0," + (this.height - this.padding) + ")")
                .call(this.xAxis)
            
            this.svg.select('.yAxis')
                .attr("transform", "translate(" + this.padding + ",0)")
                .call(this.yAxis)
            
            console.log(this.svg.select('.yAxis'));
        },
        
        update: function(data){
            this.refreshScale(data);
            this.updateCircles(data);
            this.updateLine(data);
            this.updateText(data);
            this.updateAxis();
        }
    };
    
    return LineGraph;
})();
In [195]:
%%javascript

(function(){
    var target = get_element(element);
    
    var draw = function(){
        var data = window.randomData(30, 0, 80);
        var lineGraph = new window.LineGraph3(target, data);
        lineGraph.draw();
    }
    
    require(['d3'], draw);
})();
In [191]:
%%javascript

(function(){
    require(['lodash'], function(){
        console.log('abc')
       console.log(_);
    });
})();