KKostya
7/17/2013 - 10:29 PM

Z^2 + brush

Z^2 + brush

<!DOCTYPE html>
<meta charset="utf-8">
<style>
svg { font: 10px sans-serif; }
.brsh .extent { fill: steelblue; stroke: grey; stroke-width: 0.5px; fill-opacity: .125;}
.brsh .back   { fill: none; stroke: black; stroke-width: 1px;}
.mapd .line   { fill: none; stroke: black; stroke-width: 1px; }
.axis         { fill: none; stroke: black; }
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
    function Complex(re, im) { this.re  =   re; this.im  =   im; };
    Complex.prototype.clone = function(){ return new Complex(this.re,this.im); };
    Complex.prototype.add = function(z) { this.re += z.re; this.im += z.im; return this; };
    Complex.prototype.sub = function(z) { this.re -= z.re; this.im -= z.im; return this; };
    Complex.prototype.mul = function(z) 
    { 
        var tmp = this.re;
        this.re = this.re*z.re - this.im*z.im; 
        this.im =     tmp*z.im + this.im*z.re; 
        return this;
    };
                                                     
    Complex.prototype.div = function(z) 
    { 
        var tmp =  this.re, 
              n =     z.re*z.re +    z.im*z.im;
        this.re = (this.re*z.re + this.im*z.im)/n; 
        this.im = (   -tmp*z.im + this.im*z.re)/n; 
        return this;
    };
                                                     
 
 
    var width = 960, height = 500;
 
    var svg = d3.select("body")
                .append("svg")
                .attr("width",   width)
                .attr("height", height);

    var mapd = svg.append("g").attr("class","mapd");

    var brsh = svg.append("g").attr("class","brsh")
                              .attr("transform","translate("+width/2+")");
 
    var x = d3.scale.linear()
                    .range( [ 0, width/2])
                    .domain([    -1, 1]);
 
    var y = d3.scale.linear()
                    .range( [height, 0])
                    .domain([    -1, 1]);

    var xAxis = d3.svg.axis().scale(x).orient("bottom"),
        yAxis = d3.svg.axis().scale(y).orient("left");

    [mapd,brsh].map(function(g){
           g.append("g").attr("class","axis")
            .attr("transform","translate(0,"+height/2+")")
            .call(xAxis);

           g.append("g").attr("class","axis")
            .attr("transform","translate("+width/4+")")
            .call(yAxis); });
     
    var line = d3.svg.line()
                     .x(function(d) { return x(d.re); })
                     .y(function(d) { return y(d.im); });

    var brush = d3.svg.brush()
                      .x(x).y(y).on("brush", plot);    

    brsh.append("rect").attr("class","back")
                       .attr("width",width/2)
                       .attr("height",height);

    brsh.call(brush);


    function plot()
    { 
        if(brush.empty()) return;
        ext = brush.extent();

        var data = d3.range(ext[0][0],ext[1][0],(ext[1][0]-ext[0][0])/50.1).map(function(r){
            return d3.range(ext[0][1],ext[1][1],(ext[1][1]-ext[0][1])/50.1).map(function(i){
            return new Complex(r,i);})})

        data.forEach(function(d){d.forEach(function(z) {z.mul(z.clone())})});

        data = data.concat(d3.transpose(data));

        var paths = mapd.selectAll('.line').data(data);
        paths.enter().append('path').attr('class','line');
        paths.attr('d',line);
        paths.exit().remove();
    }

</script>
</body>