block by michalskop 86228742b025940798e1e3fd0c1e4e3d

CZ: Elections 2017 - Comparison

Full Screen

index.html

<!DOCTYPE html>
<html lang="sk">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta name="author" content="Michal Škop, KohoVolit.eu">

        <link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet">
        <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
        <script src="//d3js.org/d3.v3.min.js"></script>
        <script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
        <script src="d3.tip.js"></script>
        <script src="regression.js"></script>

        <style type="text/css">
    		text {
    		  font-family: sans-serif;
    		}

    		.tick {
    		  fill-opacity: 0;
    		  stroke: #000000;
    		  stroke-width: 1;
    		}

    		.domain {
    		    fill: none;
    			fill-opacity: 0;
    			stroke: black;
    			stroke-width: 1;
    		}
    		.axis line {
    			fill: none;
    			fill-opacity: 0;
    			stroke: black;
    			stroke-width: 1;
    			shape-rendering: crispEdges;
    		}

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

    		}
    		circle {
    		  fill-opacity: .8;
    		  stroke-opacity: 0.99;
    		  stroke-width: 1;
              /*fill: #456;*/
              /*stroke: #456;*/
    		}
            circle:hover {
                stroke-opacity: 1;
                fill-opacity: 1;
            }
            path {
                fill-opacity: 0;
    			stroke: black;
    			stroke-width: 1;
                fill: none;
            }
    		.label {
    		  font-family: sans-serif;
    		  font-size: 15px;
    		}

            /* this is because of Bootstrap - very important! */
            svg:not(:root) {
                overflow: visible;
            }

            /* D3 tips */
            .d3-tip {
                line-height: 1;
                /*font-weight: bold;*/
                padding: 12px;
                background: rgba(0, 0, 0, 0.8);
                color: #fff;
                border-radius: 2px;
            }
            .d3-tip small {
                font-size: 0.5em;
            }
            /* Style northward tooltips differently */
            .d3-tip.n:after {
                margin: -1px 0 0 0;
                top: 100%;
                left: 0;
            }
            .stronger {
                color: yellow;
                font-weight: bold;
            }
            .top {
                width: 100vw;
                padding: 10px;
                color: white;
                /*font-size: 3em;*/
                /*background-color: #fed201;*/
            }
            #center-line {
                stroke:rgb(255,0,0);
                stroke-width: 1;
            }
            .info {
                padding: 10px;
                width: 100vw;
            }
        </style>

    </head>
    <body>
        <h1 class="text-center top bg-primary">
            CZECH REPUBLIC 2017<br />
            <small><span id="subtitle"></span></small>
        </h1>
        <div class="row">
            <div id="chart" class="col-md-9"></div>
            <div class="col-md-3">
                <div class="alert alert-info">
                    <i class="fa fa-info-circle"></i> Color legend:<br />
                    <img src="nuts2.png" width="200" />
                </div>
            </div>
        </div>
        <div class="alert alert-info info">
            <i class="fa fa-info-circle"></i> <br />
            Comparison between 2 parties or 2 groups of parties<br />
            Parameters:<br />
            <ul>
                <li>
                    <strong>x</strong> party on x axis (e.g., <i>x=ANO</i> or <i>x=ODS,KDU-ČSL,TOP 09,STAN</i>)
                </li>
                <li>
                    <strong>y</strong> party on y axis (e.g., <i>y=ANO</i> or <i>y=ODS,KDU-ČSL,TOP 09,STAN</i>)
                </li>
                <li>
                    <strong>level</strong> is level of detail: 1 regions, 2 sub-regions, 3 municipalities (e.g., <i>level=3</i>)
                </li>
            </ul>
            Examples:<br />
                <ul>
                    <li>
                        <a href="//bl.ocks.org/michalskop/raw/86228742b025940798e1e3fd0c1e4e3d/?x=ODS,KDU-ČSL,TOP%2009,STAN&y=ANO&level=3">ANO vs. ODS+KDU+TOP09+STAN on municipal level</a>
                    </li>
                    <li>
                        <a href="//bl.ocks.org/michalskop/raw/86228742b025940798e1e3fd0c1e4e3d/?x=Piráti&y=SPD&level=2">Pirates vs. SPD on sub-regional level</a>
                    </li>
                </ul>
        </div>


<script>

    if (getUrlParameter('level')) {
        var level = getUrlParameter('level');
    } else
        var level = "2";

    var csv = "regions_" + level + ".csv"

    if (getUrlParameter('x')) {
        var xs = getUrlParameter('x');
        xs = xs.split(',');
    } else
        var xs = ['ANO'];
    if (getUrlParameter('y')) {
        var ys = getUrlParameter('y');
        ys = ys.split(',');
    }  else
        var ys = ['ODS', 'KDU-ČSL', 'TOP 09', 'STAN'];

    if (getUrlParameter('maxrange'))
        if (isNumeric(getUrlParameter('maxrange')))
            var maxrange = getUrlParameter('maxrange');
        else
            var maxrange = 35;
    else
        var maxrange = 35

    var margin = {top: 20, right: 20, bottom: 30, left: 50},
        width = 700 - margin.left - margin.right,
        height = 550 - margin.top - margin.bottom;



d3.csv(csv, function(data) {

    data.sort(function(a, b) {
        return parseFloat(b.population) - parseFloat(a.population);
    });

    // find ranges for axes:
    var maxpopulation = 0;
    var maxy = 0
    var maxx = 0
    for (var k in data){
        data[k]['xn'] = sumInRegion(data[k],xs)
        data[k]['yn'] = sumInRegion(data[k],ys)
        if (parseInt(data[k]['population']) > maxpopulation)
            maxpopulation = parseInt(data[k]['population']);
        data[k]['id'] = k;
        if (data[k]['xn']/data[k]['population'] > maxx)
            maxx = data[k]['xn']/data[k]['population'];
        if (data[k]['yn']/data[k]['population'] > maxy)
            maxy = data[k]['yn']/data[k]['population'];
    }

    if (getUrlParameter('maxdomain'))
        if (isNumeric(getUrlParameter('maxdomain')))
            var maxdomain = getUrlParameter('maxdomain');
        else
            var maxdomain = maxpopulation;
    else
        var maxdomain = maxpopulation;

    var x = d3.scale.linear()
        .range([0, width])
        .domain([0,1.1*maxx]);
    var y = d3.scale.linear()
        .range([height, 0])
        .domain([0,1.1*maxy]);
    var r = d3.scale.sqrt()
        .domain([0, maxdomain])
    	.range([1, maxrange]);

    var formatAsPercentage = d3.format("%");

    titlex = createTitle(xs)
    titley = createTitle(ys)
    $("#subtitle").html(titlex + " vs. " + titley);

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

    var svg = d3.select("#chart").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    /* Initialize tooltip */
    var tip = changetooltip();

    /* Invoke the tip in the context of your visualization */
    svg.call(tip);

    // Add tooltip div
    var div = d3.select("body").append("div")
        .attr("class", "tooltip")
        .style("opacity", 1e-6);

    svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
     .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text(titley);

    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis)
       .append("text")
        .attr("x", x(maxx))
        .attr("dy", "-1em")
        .style("text-anchor", "end")
        .text(titlex);

    svg.append("line")
        .attr("x1", x(0))
        .attr("y1", y(0))
        .attr("x2", function() { return x(Math.min(maxx, maxy))})
        .attr("y2", function() { return y(Math.min(maxx, maxy))})
        .attr("id", "center-line")
        .style("stroke-dasharray", ("3, 5"));

    nodes = data
        .map(function(d) {
            return {
                x: x(d.xn/d.population),
                y: y(d.yn/d.population),
                xn: d.xn,
                yn: d.yn,
                r: r(d.population),
                name: d.name,
                id: d.id,
                color: region2color(d.region)
            }
    });

    dats = [];
    for (i in nodes) {
        dats.push([nodes[i].x,nodes[i].y]);
    }
    dats.sort(function(a, b) {
        return parseFloat(a[0]) - parseFloat(b[0]);
    });

    var myRegression = regression('polynomial', dats, 3);


    var bubbles = svg.selectAll("svg")
        .data(nodes)
        .enter().append("svg:svg").append("svg:circle")
        	.attr("cx", function (d) {
        	       return d.x
        	})
        	.attr("cy", function (d) {return d.y})
        	.attr("r", function (d) {return d.r})
        	//.attr("stroke-width", function(d) {return d.r2})
        	.attr("title", function(d) {return d.name;})
            .attr("fill",function(d) { return d.color })
            .attr("stroke",function(d) { return d.color })
            .on("mouseover", tip.show)
            .on("mouseout", tip.hide);

    var line = d3.svg.line()
        .interpolate("basis-open")
        .tension(0.1)          // <=== THERE IT IS!
        .x(function(d) { return d[0]; })
        .y(function(d) { return d[1]; });

    svg.append("path")
        .attr("d",line(myRegression['points']));


});


//tooltip
function changetooltip() {
  tip = d3.tip().attr('class', 'd3-tip').html(function(d) {
    html = '<span class="stronger">' + d.name + "</span><br>" + titlex + ": " + d.xn + "<br>" + titley + ": " + d.yn;
    return html;
  });
  return tip;
}

function createTitle(arr) {
    ar = []
    for (k in arr) {
        ar.push(arr[k])
    }
    return ar.join(" + ");
}

function sumInRegion(items,arr) {
    var s = 0
    for (var k in items) {
        if ($.inArray(k,arr) >= 0) {
            s = s + parseInt(items[k])
        }
    }
    return s
}
//helper function for default values
function getUrlParameter(sParam) {
    var sPageURL = decodeURIComponent(window.location.search.substring(1)),
        sURLVariables = sPageURL.split('&'),
        sParameterName,
        i;

    for (i = 0; i < sURLVariables.length; i++) {
        sParameterName = sURLVariables[i].split('=');

        if (sParameterName[0] === sParam) {
            return sParameterName[1] === undefined ? true : sParameterName[1];
        }
    }
}
// helper function for coloring by region
function region2color(r){
  if (r == 'Hlavní město Praha') return '#b276b2';
  if (r == 'Středočeský kraj') return '#f17cb0';
  if ((r == 'Plzeňský kraj') || (r == 'Jihočeský kraj')) return '#5DA5DA' //'#aec7e8';
  if ((r == 'Ústecký kraj') || (r == 'Karlovarský kraj')) return '#FAA43A';
  if ((r == 'Královéhradecký kraj') || (r == 'Pardubický kraj') || (r == 'Liberecký kraj')) return '#60bd68';
  if ((r == 'Zlínský kraj') || (r == 'Olomoucký kraj')) return '#decf3f';
  if ((r == 'Jihomoravský kraj') || (r == 'Kraj Vysočina')) return '#b2912f';
  if (r == 'Moravskoslezský kraj') return '#f15854';
  return '#4d4d4d';
}

// helper function
function toObjectWithId(arr) {
  var rv = {};
  for (var i = 0; i < arr.length; ++i)
    rv[arr[i]['id']] = arr[i];
  return rv;
}
</script>
<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-8592359-13', 'ocks.org');
  ga('send', 'pageview');

</script>

</html>

d3.tip.js

// d3.tip
// Copyright (c) 2013 Justin Palmer
//
// Tooltips for d3.js SVG visualizations

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module with d3 as a dependency.
    define(['d3'], factory)
  } else {
    // Browser global.
    root.d3.tip = factory(root.d3)
  }
}(this, function (d3) {

  // Public - contructs a new tooltip
  //
  // Returns a tip
  return function() {
    var direction = d3_tip_direction,
        offset    = d3_tip_offset,
        html      = d3_tip_html,
        node      = initNode(),
        svg       = null,
        point     = null,
        target    = null
  
    function tip(vis) {
      svg = getSVGNode(vis)
      point = svg.createSVGPoint()
      document.body.appendChild(node)
    }
  
    // Public - show the tooltip on the screen
    //
    // Returns a tip
    tip.show = function() {
      var args = Array.prototype.slice.call(arguments)
      if(args[args.length - 1] instanceof SVGElement) target = args.pop()
  
      var content = html.apply(this, args),
          poffset = offset.apply(this, args),
          dir     = direction.apply(this, args),
          nodel   = d3.select(node),
          i       = directions.length,
          coords,
          scrollTop  = document.documentElement.scrollTop || document.body.scrollTop,
          scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
  
      nodel.html(content)
        .style({ opacity: 1, 'pointer-events': 'all' })
  
      while(i--) nodel.classed(directions[i], false)
      coords = direction_callbacks.get(dir).apply(this)
      nodel.classed(dir, true).style({
        top: (coords.top +  poffset[0]) + scrollTop + 'px',
        left: (coords.left + poffset[1]) + scrollLeft + 'px'
      })
  
      return tip
    }
  
    // Public - hide the tooltip
    //
    // Returns a tip
    tip.hide = function() {
      nodel = d3.select(node)
      nodel.style({ opacity: 0, 'pointer-events': 'none' })
      return tip
    }
  
    // Public: Proxy attr calls to the d3 tip container.  Sets or gets attribute value.
    //
    // n - name of the attribute
    // v - value of the attribute
    //
    // Returns tip or attribute value
    tip.attr = function(n, v) {
      if (arguments.length < 2 && typeof n === 'string') {
        return d3.select(node).attr(n)
      } else {
        var args =  Array.prototype.slice.call(arguments)
        d3.selection.prototype.attr.apply(d3.select(node), args)
      }
  
      return tip
    }
  
    // Public: Proxy style calls to the d3 tip container.  Sets or gets a style value.
    //
    // n - name of the property
    // v - value of the property
    //
    // Returns tip or style property value
    tip.style = function(n, v) {
      if (arguments.length < 2 && typeof n === 'string') {
        return d3.select(node).style(n)
      } else {
        var args =  Array.prototype.slice.call(arguments)
        d3.selection.prototype.style.apply(d3.select(node), args)
      }
  
      return tip
    }
  
    // Public: Set or get the direction of the tooltip
    //
    // v - One of n(north), s(south), e(east), or w(west), nw(northwest),
    //     sw(southwest), ne(northeast) or se(southeast)
    //
    // Returns tip or direction
    tip.direction = function(v) {
      if (!arguments.length) return direction
      direction = v == null ? v : d3.functor(v)
  
      return tip
    }
  
    // Public: Sets or gets the offset of the tip
    //
    // v - Array of [x, y] offset
    //
    // Returns offset or
    tip.offset = function(v) {
      if (!arguments.length) return offset
      offset = v == null ? v : d3.functor(v)
  
      return tip
    }
  
    // Public: sets or gets the html value of the tooltip
    //
    // v - String value of the tip
    //
    // Returns html value or tip
    tip.html = function(v) {
      if (!arguments.length) return html
      html = v == null ? v : d3.functor(v)
  
      return tip
    }
  
    function d3_tip_direction() { return 'n' }
    function d3_tip_offset() { return [0, 0] }
    function d3_tip_html() { return ' ' }
  
    var direction_callbacks = d3.map({
      n:  direction_n,
      s:  direction_s,
      e:  direction_e,
      w:  direction_w,
      nw: direction_nw,
      ne: direction_ne,
      sw: direction_sw,
      se: direction_se
    }),
  
    directions = direction_callbacks.keys()
  
    function direction_n() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.n.y - node.offsetHeight,
        left: bbox.n.x - node.offsetWidth / 2
      }
    }
  
    function direction_s() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.s.y,
        left: bbox.s.x - node.offsetWidth / 2
      }
    }
  
    function direction_e() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.e.y - node.offsetHeight / 2,
        left: bbox.e.x
      }
    }
  
    function direction_w() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.w.y - node.offsetHeight / 2,
        left: bbox.w.x - node.offsetWidth
      }
    }
  
    function direction_nw() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.nw.y - node.offsetHeight,
        left: bbox.nw.x - node.offsetWidth
      }
    }
  
    function direction_ne() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.ne.y - node.offsetHeight,
        left: bbox.ne.x
      }
    }
  
    function direction_sw() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.sw.y,
        left: bbox.sw.x - node.offsetWidth
      }
    }
  
    function direction_se() {
      var bbox = getScreenBBox()
      return {
        top:  bbox.se.y,
        left: bbox.e.x
      }
    }
  
    function initNode() {
      var node = d3.select(document.createElement('div'))
      node.style({
        position: 'absolute',
        top: 0,
        opacity: 0,
        'pointer-events': 'none',
        'box-sizing': 'border-box'
      })
  
      return node.node()
    }
  
    function getSVGNode(el) {
      el = el.node()
      if(el.tagName.toLowerCase() == 'svg')
        return el
  
      return el.ownerSVGElement
    }
  
    // Private - gets the screen coordinates of a shape
    //
    // Given a shape on the screen, will return an SVGPoint for the directions
    // n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest),
    // sw(southwest).
    //
    //    +-+-+
    //    |   |
    //    +   +
    //    |   |
    //    +-+-+
    //
    // Returns an Object {n, s, e, w, nw, sw, ne, se}
    function getScreenBBox() {
      var targetel   = target || d3.event.target,
          bbox       = {},
          matrix     = targetel.getScreenCTM(),
          tbbox      = targetel.getBBox(),
          width      = tbbox.width,
          height     = tbbox.height,
          x          = tbbox.x,
          y          = tbbox.y
  
      point.x = x
      point.y = y
      bbox.nw = point.matrixTransform(matrix)
      point.x += width
      bbox.ne = point.matrixTransform(matrix)
      point.y += height
      bbox.se = point.matrixTransform(matrix)
      point.x -= width
      bbox.sw = point.matrixTransform(matrix)
      point.y -= height / 2
      bbox.w  = point.matrixTransform(matrix)
      point.x += width
      bbox.e = point.matrixTransform(matrix)
      point.x -= width / 2
      point.y -= height / 2
      bbox.n = point.matrixTransform(matrix)
      point.y += height
      bbox.s = point.matrixTransform(matrix)
  
      return bbox
    }
  
    return tip
  };

}));

notes.txt

The data files were obtained mainly from https://bl.ocks.org/michalskop/91a24fcaba5e2caa42d8a596f8abf4a2 and adjusted manually.

regions_1

id,name,region,region_id,population,ODS,ŘN-VU,CESTA,ČSSD,PB,RČ,STAN,KSČM,Zelení,Rozumní,SPDVPÚ,Svobodní,BPI,ODA,Piráti,Občané 2011,HAVEL,ČNF,REU,TOP 09,ANO,DV 2016,SPR-RSČ,KDU-ČSL,ČSNS,Realisté,SPS,DSSS,SPD,SPO,NáS
1100,Hlavní město Praha,Hlavní město Praha,1100,611450,99182,642,407,34079,491,221,30920,28158,14686,2600,438,12857,472,943,107590,177,93,0,423,77325,124445,358,539,29143,182,5851,1243,565,35547,1873,0
2100,Středočeský kraj,Středočeský kraj,2100,649987,84093,1348,406,43358,0,453,52602,47592,8717,5064,0,10488,677,854,77752,0,342,0,543,39100,188521,364,1196,19149,216,4155,1146,1203,59049,1599,0
3100,Jihočeský kraj,Jihočeský kraj,3100,315319,38232,557,255,23035,0,439,14435,29414,4326,2435,0,5303,270,613,33143,0,0,0,267,16713,91012,204,556,16983,243,3327,636,762,31062,1097,0
3200,Plzeňský kraj,Plzeňský kraj,3200,271510,32833,558,184,21643,0,395,13180,23502,3321,2395,0,4138,328,724,27201,182,0,0,224,13095,84114,0,603,9499,136,2009,1009,631,28686,920,0
4100,Karlovarský kraj,Karlovarský kraj,4100,122142,10796,896,0,8530,0,0,6453,9960,1549,1231,0,1544,211,280,12264,0,0,0,153,4495,43268,0,343,2885,0,799,311,428,15233,513,0
4200,Ústecký kraj,Ústecký kraj,4200,339686,32197,631,234,22464,0,0,12299,33628,5013,2920,0,4595,466,811,28004,0,0,0,321,12336,127574,292,1275,6127,113,2048,476,1527,42777,1558,0
5100,Liberecký kraj,Liberecký kraj,5100,208817,21468,327,196,11811,0,0,26780,13981,2907,1719,0,3152,192,405,23859,0,0,0,182,8825,62302,269,481,4297,135,1290,356,374,22878,631,0
5200,Královéhradecký kraj,Královéhradecký kraj,5200,278720,32242,531,297,18128,0,275,14184,19792,3650,2388,0,4310,284,322,29932,0,0,0,276,14308,88551,380,619,16294,0,2037,431,600,28038,851,0
5300,Pardubický kraj,Pardubický kraj,5300,258169,28313,509,355,19294,0,258,12855,20002,3261,2429,0,3998,186,385,27146,0,0,0,225,10864,79551,250,480,17599,0,1492,564,722,26202,1229,0
6100,Kraj Vysočina,Kraj Vysočina,6100,262764,25989,324,137,24631,0,306,11251,24829,3204,2070,0,3565,235,261,26086,0,0,0,219,10163,75247,0,600,24295,89,1562,584,556,25237,1324,0
6200,Jihomoravský kraj,Jihomoravský kraj,6200,583442,69319,768,477,49248,0,383,21222,46966,9147,3781,0,10421,448,930,53207,0,0,0,532,26356,159909,522,1222,52346,173,3849,1471,859,67973,1613,300
7100,Olomoucký kraj,Olomoucký kraj,7100,305639,27266,426,282,22760,0,307,13580,26853,3588,1942,0,3963,436,448,25955,0,0,0,213,9903,95950,248,488,25257,117,1678,766,675,41397,1141,0
7200,Zlínský kraj,Zlínský kraj,7200,294679,28752,615,195,20454,0,220,17168,20669,3685,1747,0,4812,299,393,24859,0,0,0,245,8443,84750,184,477,33631,0,2138,537,417,38020,1969,0
8100,Moravskoslezský kraj,Moravskoslezský kraj,8100,547789,40944,598,327,48417,0,592,14462,47651,6583,3790,0,5892,568,654,47332,0,0,117,450,14142,194069,650,970,35362,166,3664,1057,1083,76027,2222,0
9999,Zahraničí,Zahraničí,9999,10494,1315,5,6,483,0,3,753,97,695,14,0,189,4,7,2045,0,1,0,3,2738,800,1,7,776,3,96,6,0,431,16,0

regions_1.csv

id,name,region,region_id,population,ODS,ŘN-VU,CESTA,ČSSD,PB,RČ,STAN,KSČM,Zelení,Rozumní,SPDVPÚ,Svobodní,BPI,ODA,Piráti,Občané 2011,HAVEL,ČNF,REU,TOP 09,ANO,DV 2016,SPR-RSČ,KDU-ČSL,ČSNS,Realisté,SPS,DSSS,SPD,SPO,NáS
1100,Hlavní město Praha,Hlavní město Praha,1100,611450,99182,642,407,34079,491,221,30920,28158,14686,2600,438,12857,472,943,107590,177,93,0,423,77325,124445,358,539,29143,182,5851,1243,565,35547,1873,0
2100,Středočeský kraj,Středočeský kraj,2100,649987,84093,1348,406,43358,0,453,52602,47592,8717,5064,0,10488,677,854,77752,0,342,0,543,39100,188521,364,1196,19149,216,4155,1146,1203,59049,1599,0
3100,Jihočeský kraj,Jihočeský kraj,3100,315319,38232,557,255,23035,0,439,14435,29414,4326,2435,0,5303,270,613,33143,0,0,0,267,16713,91012,204,556,16983,243,3327,636,762,31062,1097,0
3200,Plzeňský kraj,Plzeňský kraj,3200,271510,32833,558,184,21643,0,395,13180,23502,3321,2395,0,4138,328,724,27201,182,0,0,224,13095,84114,0,603,9499,136,2009,1009,631,28686,920,0
4100,Karlovarský kraj,Karlovarský kraj,4100,122142,10796,896,0,8530,0,0,6453,9960,1549,1231,0,1544,211,280,12264,0,0,0,153,4495,43268,0,343,2885,0,799,311,428,15233,513,0
4200,Ústecký kraj,Ústecký kraj,4200,339686,32197,631,234,22464,0,0,12299,33628,5013,2920,0,4595,466,811,28004,0,0,0,321,12336,127574,292,1275,6127,113,2048,476,1527,42777,1558,0
5100,Liberecký kraj,Liberecký kraj,5100,208817,21468,327,196,11811,0,0,26780,13981,2907,1719,0,3152,192,405,23859,0,0,0,182,8825,62302,269,481,4297,135,1290,356,374,22878,631,0
5200,Královéhradecký kraj,Královéhradecký kraj,5200,278720,32242,531,297,18128,0,275,14184,19792,3650,2388,0,4310,284,322,29932,0,0,0,276,14308,88551,380,619,16294,0,2037,431,600,28038,851,0
5300,Pardubický kraj,Pardubický kraj,5300,258169,28313,509,355,19294,0,258,12855,20002,3261,2429,0,3998,186,385,27146,0,0,0,225,10864,79551,250,480,17599,0,1492,564,722,26202,1229,0
6100,Kraj Vysočina,Kraj Vysočina,6100,262764,25989,324,137,24631,0,306,11251,24829,3204,2070,0,3565,235,261,26086,0,0,0,219,10163,75247,0,600,24295,89,1562,584,556,25237,1324,0
6200,Jihomoravský kraj,Jihomoravský kraj,6200,583442,69319,768,477,49248,0,383,21222,46966,9147,3781,0,10421,448,930,53207,0,0,0,532,26356,159909,522,1222,52346,173,3849,1471,859,67973,1613,300
7100,Olomoucký kraj,Olomoucký kraj,7100,305639,27266,426,282,22760,0,307,13580,26853,3588,1942,0,3963,436,448,25955,0,0,0,213,9903,95950,248,488,25257,117,1678,766,675,41397,1141,0
7200,Zlínský kraj,Zlínský kraj,7200,294679,28752,615,195,20454,0,220,17168,20669,3685,1747,0,4812,299,393,24859,0,0,0,245,8443,84750,184,477,33631,0,2138,537,417,38020,1969,0
8100,Moravskoslezský kraj,Moravskoslezský kraj,8100,547789,40944,598,327,48417,0,592,14462,47651,6583,3790,0,5892,568,654,47332,0,0,117,450,14142,194069,650,970,35362,166,3664,1057,1083,76027,2222,0
9999,Zahraničí,Zahraničí,9999,10494,1315,5,6,483,0,3,753,97,695,14,0,189,4,7,2045,0,1,0,3,2738,800,1,7,776,3,96,6,0,431,16,0

regions_2.csv

id,name,region,region_id,population,ODS,ŘN-VU,CESTA,ČSSD,PB,RČ,STAN,KSČM,Zelení,Rozumní,SPDVPÚ,Svobodní,BPI,ODA,Piráti,Občané 2011,HAVEL,ČNF,REU,TOP 09,ANO,DV 2016,SPR-RSČ,KDU-ČSL,ČSNS,Realisté,SPS,DSSS,SPD,SPO,NáS
1100,Hlavní město Praha,Hlavní město Praha,1100,611450,99182,642,407,34079,491,221,30920,28158,14686,2600,438,12857,472,943,107590,177,93,0,423,77325,124445,358,539,29143,182,5851,1243,565,35547,1873,0
2101,Benešov,Středočeský kraj,2100,50386,5279,70,23,3748,0,24,4371,3805,567,341,0,658,47,54,5334,0,32,0,48,2289,16251,23,101,2267,18,300,106,116,4413,101,0
2102,Beroun,Středočeský kraj,2100,44601,6675,90,39,3105,0,26,2155,3845,636,358,0,842,39,72,5535,0,26,0,30,2568,12652,25,93,1245,13,255,74,93,4002,108,0
2103,Kladno,Středočeský kraj,2100,74107,8797,111,40,5068,0,93,4151,6767,1014,591,0,1416,75,84,8682,0,35,0,66,3760,22227,52,177,1562,27,508,114,172,8319,199,0
2104,Kolín,Středočeský kraj,2100,48207,4604,150,23,3223,0,32,8841,4057,431,300,0,653,49,53,4173,0,25,0,22,1827,13707,16,89,1056,12,289,69,80,4280,146,0
2105,Kutná Hora,Středočeský kraj,2100,36827,3443,131,27,3552,0,21,3674,3240,296,289,0,380,46,38,3461,0,18,0,23,1302,11689,16,82,1263,8,165,69,55,3448,91,0
2106,Mělník,Středočeský kraj,2100,49063,6343,115,28,3107,0,24,3349,3822,672,439,0,910,65,53,5718,0,24,0,69,2342,14820,31,105,1098,14,303,95,120,5253,144,0
2107,Mladá Boleslav,Středočeský kraj,2100,58562,6990,115,37,4213,0,40,4080,4033,809,630,0,841,68,71,5812,0,33,0,44,2559,19991,35,129,1314,21,353,157,95,5953,139,0
2108,Nymburk,Středočeský kraj,2100,47177,5626,93,23,3527,0,36,3573,3288,627,418,0,641,46,71,5305,0,35,0,55,2670,14730,24,101,1425,23,248,100,95,4295,102,0
2109,Praha-východ,Středočeský kraj,2100,85497,15295,269,62,4049,0,49,6721,3891,1252,573,0,1564,85,138,12917,0,42,0,68,7457,20818,41,120,2676,33,668,113,124,6272,200,0
2110,Praha-západ,Středočeský kraj,2100,70884,12048,91,65,3120,0,45,5925,3079,1340,431,0,1348,70,118,11210,0,37,0,69,8243,15662,57,67,2334,14,572,91,93,4594,161,0
2111,Příbram,Středočeský kraj,2100,58185,6438,80,29,4299,0,41,4082,4965,785,506,0,860,62,77,6853,0,24,0,25,2896,17588,32,87,2382,14,331,103,113,5381,132,0
2112,Rakovník,Středočeský kraj,2100,26491,2555,33,10,2347,0,22,1680,2800,288,188,0,375,25,25,2752,0,11,0,24,1187,8386,12,45,527,19,163,55,47,2839,76,0
3101,České Budějovice,Jihočeský kraj,3100,97068,12861,112,74,6163,0,116,5123,8126,1499,616,0,1985,82,205,10175,0,0,0,71,5689,27065,83,151,5023,95,1519,236,200,9483,316,0
3102,Český Krumlov,Jihočeský kraj,3100,27586,3370,50,30,1760,0,63,1015,2760,393,264,0,425,25,61,2562,0,0,0,27,1342,8274,33,41,1447,36,297,42,151,3042,76,0
3103,Jindřichův Hradec,Jihočeský kraj,3100,45365,5009,75,42,3917,0,57,1589,4814,634,355,0,774,44,91,4668,0,0,0,28,1877,13011,20,106,2995,34,283,72,84,4637,149,0
3104,Písek,Jihočeský kraj,3100,34981,4174,125,22,2756,0,44,1167,3487,402,253,0,538,39,69,4011,0,0,0,32,1990,9866,19,55,1939,14,245,63,72,3437,162,0
3105,Prachatice,Jihočeský kraj,3100,23730,3270,66,18,1724,0,33,1184,2403,329,172,0,334,16,38,2179,0,0,0,14,1057,6588,12,47,1409,11,182,50,68,2416,110,0
3106,Strakonice,Jihočeský kraj,3100,34379,3660,71,26,2565,0,54,1451,3163,384,299,0,424,27,60,3651,0,0,0,47,1538,10599,20,74,1980,21,344,95,100,3598,128,0
3107,Tábor,Jihočeský kraj,3100,52210,5888,58,43,4150,0,72,2906,4661,685,476,0,823,37,89,5897,0,0,0,48,3220,15609,17,82,2190,32,457,78,87,4449,156,0
3201,Domažlice,Plzeňský kraj,3200,27834,3084,43,15,2492,0,42,1630,2756,245,364,0,258,31,58,2217,12,0,0,15,756,8570,0,65,1442,13,185,68,55,3337,81,0
3202,Klatovy,Plzeňský kraj,3200,42977,4874,112,27,3500,0,81,2306,3688,413,436,0,490,41,69,4303,23,0,0,34,1691,13792,0,89,2071,24,213,130,109,4333,128,0
3203,Plzeň-město,Plzeňský kraj,3200,88649,12744,170,79,6694,0,101,3605,5649,1341,513,0,1790,101,336,10228,59,0,0,72,6279,25430,0,177,3299,31,832,338,170,8334,277,0
3204,Plzeň-jih,Plzeňský kraj,3200,29576,3249,72,26,2506,0,56,1601,2940,373,253,0,430,47,78,2575,38,0,0,21,1268,9355,0,60,725,14,198,136,90,3359,106,0
3205,Plzeň-sever,Plzeňský kraj,3200,37720,4511,62,22,2966,0,59,2131,3428,405,366,0,608,64,101,3573,22,0,0,38,1605,11775,0,114,967,41,301,200,96,4128,137,0
3206,Rokycany,Plzeňský kraj,3200,23189,2762,62,6,1772,0,29,967,2350,285,222,0,340,28,56,2271,14,0,0,22,891,7510,0,61,543,5,186,76,53,2564,114,0
3207,Tachov,Plzeňský kraj,3200,21565,1609,37,9,1713,0,27,940,2691,259,241,0,222,16,26,2034,14,0,0,22,605,7682,0,37,452,8,94,61,58,2631,77,0
4101,Cheb,Karlovarský kraj,4100,36295,3084,174,0,2495,0,0,1889,3348,549,306,0,381,76,100,4075,0,0,0,42,1212,12804,0,104,979,0,180,58,89,4242,108,0
4102,Karlovy Vary,Karlovarský kraj,4100,50455,5049,265,0,3366,0,0,3062,3635,624,544,0,592,70,130,5323,0,0,0,67,2265,17039,0,115,1295,0,383,165,172,6077,217,0
4103,Sokolov,Karlovarský kraj,4100,35392,2663,457,0,2669,0,0,1502,2977,376,381,0,571,65,50,2866,0,0,0,44,1018,13425,0,124,611,0,236,88,167,4914,188,0
4201,Děčín,Ústecký kraj,4200,54782,4510,84,48,3607,0,0,2480,4602,650,513,0,756,99,120,4523,0,0,0,47,1904,21405,41,217,1082,27,309,62,258,7095,343,0
4202,Chomutov,Ústecký kraj,4200,48315,4292,114,22,3225,0,0,1612,4920,644,473,0,682,60,121,3792,0,0,0,40,1328,18894,33,174,690,19,320,62,142,6471,185,0
4203,Litoměřice,Ústecký kraj,4200,55822,6457,131,42,3507,0,0,2220,6030,876,535,0,915,84,97,5279,0,0,0,47,2344,18770,54,181,1393,20,325,98,215,6010,192,0
4204,Louny,Ústecký kraj,4200,37739,3526,57,17,2676,0,0,992,4418,461,324,0,397,56,47,2715,0,0,0,33,1394,14295,24,147,771,14,211,54,164,4798,148,0
4205,Most,Ústecký kraj,4200,42560,3594,114,26,2980,0,0,1503,4536,788,293,0,540,36,68,3023,0,0,0,56,1241,16740,17,175,448,13,244,42,250,5614,219,0
4206,Teplice,Ústecký kraj,4200,51109,5137,65,27,3444,0,0,1492,4697,733,463,0,585,71,112,4143,0,0,0,54,1970,19476,34,213,871,13,252,90,269,6693,205,0
4207,Ústí nad Labem,Ústecký kraj,4200,49359,4681,66,52,3025,0,0,2000,4425,861,319,0,720,60,246,4529,0,0,0,44,2155,17994,89,168,872,7,387,68,229,6096,266,0
5101,Česká Lípa,Liberecký kraj,5100,44257,3703,49,27,2709,0,0,5261,3905,613,373,0,613,55,71,4288,0,0,0,34,1386,14264,59,121,624,41,231,72,120,5471,167,0
5102,Jablonec nad Nisou,Liberecký kraj,5100,43345,5390,38,37,2319,0,0,4150,2627,532,413,0,677,44,58,6137,0,0,0,79,2039,12468,38,83,695,26,335,72,79,4857,152,0
5103,Liberec,Liberecký kraj,5100,81516,7735,138,75,4580,0,0,11494,4909,1303,542,0,1222,62,221,8883,0,0,0,40,3654,25335,89,196,1360,40,519,144,111,8647,217,0
5104,Semily,Liberecký kraj,5100,39699,4640,102,57,2203,0,0,5875,2540,459,391,0,640,31,55,4551,0,0,0,29,1746,10235,83,81,1618,28,205,68,64,3903,95,0
5201,Hradec Králové,Královéhradecký kraj,5200,85218,9888,155,122,5241,0,74,3589,5968,1233,624,0,1506,76,135,9743,0,0,0,66,5676,26916,149,116,4550,0,895,152,131,7954,259,0
5202,Jičín,Královéhradecký kraj,5200,40060,4017,104,61,2674,0,41,3374,3003,483,416,0,530,41,40,4478,0,0,0,28,1636,13202,56,111,1730,0,294,64,89,3455,133,0
5203,Náchod,Královéhradecký kraj,5200,54949,6059,98,34,4259,0,69,2359,3391,717,427,0,742,45,49,5391,0,0,0,62,2577,17194,74,118,4875,0,297,74,127,5767,144,0
5204,Rychnov nad Kněžnou,Královéhradecký kraj,5200,39550,4184,80,35,2599,0,30,1711,3219,479,396,0,642,46,41,3789,0,0,0,43,1685,12682,54,138,2849,0,215,49,93,4336,155,0
5205,Trutnov,Královéhradecký kraj,5200,58943,8094,94,45,3355,0,61,3151,4211,738,525,0,890,76,57,6531,0,0,0,77,2734,18557,47,136,2290,0,336,92,160,6526,160,0
5301,Chrudim,Pardubický kraj,5300,52753,5178,75,78,4124,0,50,2620,4702,532,460,0,812,34,62,5191,0,0,0,43,1752,17187,36,105,3743,0,309,88,111,5103,358,0
5302,Pardubice,Pardubický kraj,5300,84478,10524,128,138,6044,0,64,4132,6064,1168,603,0,1444,66,167,9291,0,0,0,66,4262,26804,124,167,3908,0,632,167,182,8044,289,0
5303,Svitavy,Pardubický kraj,5300,51441,5388,126,41,4319,0,57,2489,4613,572,687,0,697,39,50,4900,0,0,0,48,1791,14932,41,92,4681,0,221,138,173,5201,145,0
5304,Ústí nad Orlicí,Pardubický kraj,5300,69497,7223,180,98,4807,0,87,3614,4623,989,679,0,1045,47,106,7764,0,0,0,68,3059,20628,49,116,5267,0,330,171,256,7854,437,0
6101,Havlíčkův Brod,Kraj Vysočina,6100,49372,5482,91,20,4162,0,55,2244,4808,689,414,0,561,31,62,5106,0,0,0,37,1771,15388,0,91,3504,14,316,101,108,4181,136,0
6102,Jihlava,Kraj Vysočina,6100,56391,5920,66,40,4468,0,57,2040,4856,906,452,0,919,55,59,5924,0,0,0,52,2441,15552,0,138,4982,20,432,151,133,6458,270,0
6103,Pelhřimov,Kraj Vysočina,6100,37285,4002,61,16,4421,0,40,2195,3470,433,252,0,552,22,35,3900,0,0,0,23,1557,10202,0,98,2526,9,180,73,73,3061,84,0
6104,Třebíč,Kraj Vysočina,6100,58131,4956,46,18,5010,0,72,2540,6245,558,500,0,777,51,56,5406,0,0,0,50,1859,17126,0,159,5408,24,304,134,113,6491,228,0
6105,Žďár nad Sázavou,Kraj Vysočina,6100,61585,5629,60,43,6570,0,82,2232,5450,618,452,0,756,76,49,5750,0,0,0,57,2535,16979,0,114,7875,22,330,125,129,5046,606,0
6201,Blansko,Jihomoravský kraj,6200,55661,5480,50,44,5406,0,30,1862,5561,739,428,0,885,41,92,4955,0,0,0,52,1631,15327,42,138,5866,23,309,136,92,6287,164,21
6202,Brno-město,Jihomoravský kraj,6200,185636,28601,127,192,14396,0,109,6661,10269,4467,774,0,3716,131,308,20718,0,0,0,190,12924,45592,162,334,14273,57,1754,528,201,18674,398,80
6203,Brno-venkov,Jihomoravský kraj,6200,111932,13611,105,92,8301,0,96,5044,8558,1561,731,0,2105,90,183,9778,0,0,0,140,5288,30941,85,230,10313,32,713,355,161,13079,271,69
6204,Břeclav,Jihomoravský kraj,6200,56358,6474,78,44,4223,0,30,2371,5315,616,489,0,943,42,84,4693,0,0,0,32,1884,16676,112,102,4532,13,254,103,82,7007,125,34
6205,Hodonín,Jihomoravský kraj,6200,75389,6897,273,56,6690,0,44,2502,6812,791,518,0,1311,56,117,5982,0,0,0,50,1911,21326,49,175,9380,24,360,143,138,9543,202,39
6206,Vyškov,Jihomoravský kraj,6200,44518,4015,70,25,5452,0,35,1276,4822,516,390,0,724,37,64,3580,0,0,0,41,1131,11530,31,138,4053,4,224,115,98,5892,225,30
6207,Znojmo,Jihomoravský kraj,6200,53948,4241,65,24,4780,0,39,1506,5629,457,451,0,737,51,82,3501,0,0,0,27,1587,18517,41,105,3929,20,235,91,87,7491,228,27
7101,Jeseník,Olomoucký kraj,7100,17911,1237,18,13,1353,0,19,1099,1781,162,111,0,183,24,15,1293,0,0,0,16,722,5949,19,46,785,8,90,32,39,2859,38,0
7102,Olomouc,Olomoucký kraj,7100,112995,11288,143,99,8563,0,116,4572,8664,1675,709,0,1642,184,196,11212,0,0,0,66,4803,34125,90,164,8935,32,763,392,209,13917,436,0
7103,Prostějov,Olomoucký kraj,7100,52738,4552,50,65,4558,0,45,1609,5238,645,357,0,578,63,72,4250,0,0,0,37,1398,15516,31,78,4733,30,223,107,223,8111,169,0
7104,Přerov,Olomoucký kraj,7100,63279,5533,114,36,4296,0,69,2191,5855,514,359,0,835,65,109,4501,0,0,0,44,1462,21108,68,105,6257,24,360,134,97,8827,316,0
7105,Šumperk,Olomoucký kraj,7100,58716,4656,101,69,3990,0,58,4109,5315,592,406,0,725,100,56,4699,0,0,0,50,1518,19252,40,95,4547,23,242,101,107,7683,182,0
7201,Kroměříž,Zlínský kraj,7200,52781,4389,115,31,3840,0,51,2140,5083,684,308,0,739,59,120,3984,0,0,0,53,1338,16004,36,96,4632,0,315,103,112,8250,299,0
7202,Uherské Hradiště,Zlínský kraj,7200,73007,7715,82,32,5173,0,41,4783,6038,840,360,0,1060,67,72,5894,0,0,0,65,1991,18781,35,101,9798,0,542,95,96,8751,595,0
7203,Vsetín,Zlínský kraj,7200,70320,7120,93,46,4894,0,61,3505,4089,973,526,0,1276,76,91,6239,0,0,0,49,1951,20528,48,128,8492,0,423,181,117,9089,325,0
7204,Zlín,Zlínský kraj,7200,98571,9528,325,86,6547,0,67,6740,5459,1188,553,0,1737,97,110,8742,0,0,0,78,3163,29437,65,152,10709,0,858,158,92,11930,750,0
8101,Bruntál,Moravskoslezský kraj,8100,40575,2763,47,18,3462,0,36,1327,4862,440,385,0,432,65,57,2940,0,0,5,52,794,14852,28,67,1314,5,240,65,93,6123,103,0
8102,Frýdek-Místek,Moravskoslezský kraj,8100,101439,7530,107,56,9301,0,155,3116,7694,1101,559,0,1116,87,90,8860,0,0,11,64,2253,34686,227,140,9769,32,748,179,145,13038,375,0
8103,Karviná,Moravskoslezský kraj,8100,106196,5839,170,48,10602,0,103,2277,11334,1041,763,0,851,88,120,7699,0,0,14,92,1696,40004,106,246,5193,42,476,142,188,16575,487,0
8104,Nový Jičín,Moravskoslezský kraj,8100,72390,6213,69,61,6003,0,84,1611,5785,1231,574,0,920,76,148,6986,0,0,13,58,1770,24248,88,112,5666,16,401,179,138,9729,211,0
8105,Opava,Moravskoslezský kraj,8100,85906,6782,75,59,7117,0,69,2490,5909,1012,590,0,872,89,76,7761,0,0,9,67,3667,30226,62,156,6902,31,585,149,170,10664,317,0
8106,Ostrava-město,Moravskoslezský kraj,8100,141283,11817,130,85,11932,0,145,3641,12067,1758,919,0,1701,163,163,13086,0,0,65,117,3962,50053,139,249,6518,40,1214,343,349,19898,729,0
9999,Zahraničí,Zahraničí,9999,10494,1315,5,6,483,0,3,753,97,695,14,0,189,4,7,2045,0,1,0,3,2738,800,1,7,776,3,96,6,0,431,16,0

regression.js

/**
* @license
*
* Regression.JS - Regression functions for javascript
* http://tom-alexander.github.com/regression-js/
*
* copyright(c) 2013 Tom Alexander
* Licensed under the MIT license.
*
**/

;(function() {
    'use strict';

    var gaussianElimination = function(a, o) {
           var i = 0, j = 0, k = 0, maxrow = 0, tmp = 0, n = a.length - 1, x = new Array(o);
           for (i = 0; i < n; i++) {
              maxrow = i;
              for (j = i + 1; j < n; j++) {
                 if (Math.abs(a[i][j]) > Math.abs(a[i][maxrow]))
                    maxrow = j;
              }
              for (k = i; k < n + 1; k++) {
                 tmp = a[k][i];
                 a[k][i] = a[k][maxrow];
                 a[k][maxrow] = tmp;
              }
              for (j = i + 1; j < n; j++) {
                 for (k = n; k >= i; k--) {
                    a[k][j] -= a[k][i] * a[i][j] / a[i][i];
                 }
              }
           }
           for (j = n - 1; j >= 0; j--) {
              tmp = 0;
              for (k = j + 1; k < n; k++)
                 tmp += a[k][j] * x[k];
              x[j] = (a[n][j] - tmp) / a[j][j];
           }
           return (x);
    };

        var methods = {
            linear: function(data) {
                var sum = [0, 0, 0, 0, 0], n = 0, results = [];

                for (; n < data.length; n++) {
                  if (data[n][1] != null) {
                    sum[0] += data[n][0];
                    sum[1] += data[n][1];
                    sum[2] += data[n][0] * data[n][0];
                    sum[3] += data[n][0] * data[n][1];
                    sum[4] += data[n][1] * data[n][1];
                  }
                }

                var gradient = (n * sum[3] - sum[0] * sum[1]) / (n * sum[2] - sum[0] * sum[0]);
                var intercept = (sum[1] / n) - (gradient * sum[0]) / n;
              //  var correlation = (n * sum[3] - sum[0] * sum[1]) / Math.sqrt((n * sum[2] - sum[0] * sum[0]) * (n * sum[4] - sum[1] * sum[1]));

                for (var i = 0, len = data.length; i < len; i++) {
                    var coordinate = [data[i][0], data[i][0] * gradient + intercept];
                    results.push(coordinate);
                }

                var string = 'y = ' + Math.round(gradient*100) / 100 + 'x + ' + Math.round(intercept*100) / 100;

                return {equation: [gradient, intercept], points: results, string: string};
            },

            linearThroughOrigin: function(data) {
                var sum = [0, 0], n = 0, results = [];

                for (; n < data.length; n++) {
                    if (data[n][1] != null) {
                        sum[0] += data[n][0] * data[n][0]; //sumSqX
                        sum[1] += data[n][0] * data[n][1]; //sumXY
                    }
                }

                var gradient = sum[1] / sum[0];

                for (var i = 0, len = data.length; i < len; i++) {
                    var coordinate = [data[i][0], data[i][0] * gradient];
                    results.push(coordinate);
                }

                var string = 'y = ' + Math.round(gradient*100) / 100 + 'x';

                return {equation: [gradient], points: results, string: string};
            },

            exponential: function(data) {
                var sum = [0, 0, 0, 0, 0, 0], n = 0, results = [];

                for (len = data.length; n < len; n++) {
                  if (data[n][1] != null) {
                    sum[0] += data[n][0];
                    sum[1] += data[n][1];
                    sum[2] += data[n][0] * data[n][0] * data[n][1];
                    sum[3] += data[n][1] * Math.log(data[n][1]);
                    sum[4] += data[n][0] * data[n][1] * Math.log(data[n][1]);
                    sum[5] += data[n][0] * data[n][1];
                  }
                }

                var denominator = (sum[1] * sum[2] - sum[5] * sum[5]);
                var A = Math.pow(Math.E, (sum[2] * sum[3] - sum[5] * sum[4]) / denominator);
                var B = (sum[1] * sum[4] - sum[5] * sum[3]) / denominator;

                for (var i = 0, len = data.length; i < len; i++) {
                    var coordinate = [data[i][0], A * Math.pow(Math.E, B * data[i][0])];
                    results.push(coordinate);
                }

                var string = 'y = ' + Math.round(A*100) / 100 + 'e^(' + Math.round(B*100) / 100 + 'x)';

                return {equation: [A, B], points: results, string: string};
            },

            logarithmic: function(data) {
                var sum = [0, 0, 0, 0], n = 0, results = [];

                for (len = data.length; n < len; n++) {
                  if (data[n][1] != null) {
                    sum[0] += Math.log(data[n][0]);
                    sum[1] += data[n][1] * Math.log(data[n][0]);
                    sum[2] += data[n][1];
                    sum[3] += Math.pow(Math.log(data[n][0]), 2);
                  }
                }

                var B = (n * sum[1] - sum[2] * sum[0]) / (n * sum[3] - sum[0] * sum[0]);
                var A = (sum[2] - B * sum[0]) / n;

                for (var i = 0, len = data.length; i < len; i++) {
                    var coordinate = [data[i][0], A + B * Math.log(data[i][0])];
                    results.push(coordinate);
                }

                var string = 'y = ' + Math.round(A*100) / 100 + ' + ' + Math.round(B*100) / 100 + ' ln(x)';

                return {equation: [A, B], points: results, string: string};
            },

            power: function(data) {
                var sum = [0, 0, 0, 0], n = 0, results = [];

                for (len = data.length; n < len; n++) {
                  if (data[n][1] != null) {
                    sum[0] += Math.log(data[n][0]);
                    sum[1] += Math.log(data[n][1]) * Math.log(data[n][0]);
                    sum[2] += Math.log(data[n][1]);
                    sum[3] += Math.pow(Math.log(data[n][0]), 2);
                  }
                }

                var B = (n * sum[1] - sum[2] * sum[0]) / (n * sum[3] - sum[0] * sum[0]);
                var A = Math.pow(Math.E, (sum[2] - B * sum[0]) / n);

                for (var i = 0, len = data.length; i < len; i++) {
                    var coordinate = [data[i][0], A * Math.pow(data[i][0] , B)];
                    results.push(coordinate);
                }

                 var string = 'y = ' + Math.round(A*100) / 100 + 'x^' + Math.round(B*100) / 100;

                return {equation: [A, B], points: results, string: string};
            },

            polynomial: function(data, order) {
                if(typeof order == 'undefined'){
                    order = 2;
                }
                 var lhs = [], rhs = [], results = [], a = 0, b = 0, i = 0, k = order + 1;

                        for (; i < k; i++) {
                           for (var l = 0, len = data.length; l < len; l++) {
                              if (data[l][1] != null) {
                               a += Math.pow(data[l][0], i) * data[l][1];
                              }
                            }
                            lhs.push(a), a = 0;
                            var c = [];
                            for (var j = 0; j < k; j++) {
                               for (var l = 0, len = data.length; l < len; l++) {
                                  if (data[l][1] != null) {
                                   b += Math.pow(data[l][0], i + j);
                                  }
                                }
                                c.push(b), b = 0;
                            }
                            rhs.push(c);
                        }
                rhs.push(lhs);

               var equation = gaussianElimination(rhs, k);

                    for (var i = 0, len = data.length; i < len; i++) {
                        var answer = 0;
                        for (var w = 0; w < equation.length; w++) {
                            answer += equation[w] * Math.pow(data[i][0], w);
                        }
                        results.push([data[i][0], answer]);
                    }

                    var string = 'y = ';

                    for(var i = equation.length-1; i >= 0; i--){
                      if(i > 1) string += Math.round(equation[i] * Math.pow(10, i)) / Math.pow(10, i)  + 'x^' + i + ' + ';
                      else if (i == 1) string += Math.round(equation[i]*100) / 100 + 'x' + ' + ';
                      else string += Math.round(equation[i]*100) / 100;
                    }

                return {equation: equation, points: results, string: string};
            },

            lastvalue: function(data) {
              var results = [];
              var lastvalue = null;
              for (var i = 0; i < data.length; i++) {
                if (data[i][1]) {
                  lastvalue = data[i][1];
                  results.push([data[i][0], data[i][1]]);
                }
                else {
                  results.push([data[i][0], lastvalue]);
                }
              }

              return {equation: [lastvalue], points: results, string: "" + lastvalue};
            }
        };

var regression = (function(method, data, order) {

       if (typeof method == 'string') {
           return methods[method](data, order);
       }
    });

if (typeof exports !== 'undefined') {
    module.exports = regression;
} else {
    window.regression = regression;
}

}());