(function($){var data;

$(function() {


  function submit_download_form(output_format, svg, name)
  {
    // Get the d3js SVG element
    // var tmp = document.getElementById("ex1");
    // var svg = tmp.getElementsByTagName("svg")[0];
    // Extract the data as SVG text string
    // d3.select(svg).selectAll("style").remove();
    d3.select(svg).attr("xmlns", "http://www.w3.org/2000/svg")
    .attr("version", "1.1")
    // .insert("text", ":first-child").text(name)
      // .attr("y", "1em").attr("x", "1.5em").attr("class", "svg-header");
    
    var svg_xml = (new XMLSerializer).serializeToString(svg);
    // d3.select(svg).select(".svg-header").remove();
    // Submit the <FORM> to the server.
    // The result will be an attachment file to download.
    var form = document.getElementById("svgform");
    form['output_format'].value = output_format;
    form['data'].value = svg_xml;
    form['name'].value = name;
    form.submit();
    // $.post('/svg2other/index.php', $('#svgform').serialize())
    //  .done(function(){
    //    console.log(arguments);
    //    window.location = arguments[0];
    //  })
  }


  "use strict";

  d3.json("/bitrix/templates/sberbank/js/int-an/rus-data.json", function(json) {
    data = json;
    // console.log(data);
    build();
  });

  var width = 660;

  $(".an-controls a").on("click", function(e) {
    e.preventDefault();
    $(".an-controls a").removeClass("an-cur");
    $(this).addClass("an-cur");
    switch ($(this).attr("id")) {
      case "an-table":
        $(".an-chart-container").removeClass().addClass("an-chart-container an-chart-table");
        // d3.select(".vis").attr("class", "vis an-chart an-chart-table");
        break;
      case "an-line":
        $(".an-chart-container").removeClass().addClass("an-chart-container an-chart-line");
        // d3.select(".vis").attr("class", "vis an-chart an-chart-line");
        break;
      case "an-hist":
        $(".an-chart-container").removeClass().addClass("an-chart-container an-chart-hist");
        // d3.select(".vis").attr("class", "vis an-chart an-chart-hist");
        break;
    }
  });

  $(".convert-btn").on("click", function(){
    var format = $(this).data("format")
    var svg = $(".an-chart-container").hasClass("an-chart-hist") ? $("svg")[1] : $("svg")[0]
    submit_download_form(format, svg, "interactive-analysis");
  })


  var colors = ["#ff8752", "#ff9829", "#ffc82a", "#ffe451", "#c7e747", "#c9ba14", "#a1a224", "#308336", "#39b54a", "#9dd29c", "#3ed5a5", "#249ba3", "#91dadf", "#c2dcff", "#72aeff", "#717bdb", "#9577af", "#cbade4", "#d876ab", "#ffbfa9", "#bbc2c8", "#78858d"];

  $(".an-chart").empty(); // clear container
  // functions


  function selectData(num, rs, cs) {
    var res = [];
    for (var i = 0; i < rs.length; i++) {
      res[i] = num[rs[i]];
    }
    return res;
  }

  function findMax(newData) {
    var max = newData[0][2],
      umax = newData[0][1];
    newData.forEach(function(el, i) {
      var newMax = d3.max(el.slice(2));
      return (newMax > max) ? (max = newMax, umax = el[1]) : 0;
    })
    return [max, umax];
  }

  function findMin(newData) {
    var min = newData[0][2],
      umin = newData[0][1];
    newData.forEach(function(el, i) {
      var newMin = d3.min(el.slice(2));
      return (newMin < min) ? (min = newMin, umin = el[1]) : 0;
    })
    return [min, umin];
  }

  function showWarning(msg, el, before, x, y) {
    d3.select(el).insert("span", before).style("opacity", 0).html(msg).transition().duration(400).attr("class", "warn-msg").style("opacity", 1).transition().delay(2000).transition().duration(400).style("opacity", 0).remove().each("end", function() {
      d3.select(this).remove()
    });
  }

  function cmp2(el1, el2, table) {
    return table[el1][el2];
  }

  function prop(pr) {
    return function(d) {
      return d[pr]
    };
  }

  function getDates(data) {
    return d3.set(d3.merge(data.map(function(d) {
      return d3.keys(d["FACTS"]).map(function(d) {
        return d.split("/").map(function(d) {
          return (new Date(parseInt(d, 10) * 1000)).getFullYear();
        })[0];
      });
    }))).values().sort(d3.ascending);
  }


  function fillData(data, dates, fillWithNulls) {
    return data.map(function(d) {
      var f = d["FACTS"];

      var newf = {};
      d3.entries(f).forEach(function(o) {
        var year = o.key.split("/").map(function(d) {
          return (new Date(parseInt(d, 10) * 1000)).getFullYear();
        })[0];
        if (dates.some(function(date) {
          return date == year
        })) newf[year] = o.value;
      })
      if (fillWithNulls) {
        dates.forEach(function(date) {
          if (date in newf) return;
          newf[date] = {
            value: null
          };
        })
      }
      return {
        "FACTS": newf,
        "ID": d["ID"],
        "NAME": d["NAME"]
      };
    })
  }

  function filterData(data, rows, cols) {
    var res = {
      dates: data.dates,
      rows: [],
      units: []
    }
    if (cols) {
      res.dates = cols.map(function(d){
        return data.dates[d];
      })
    }
    res.rows = rows.map(function(d,i){
      return data.rows[d].filter(function(r,j){
        return (!cols || j==0) ? true : cols.has(j-1);
      });
    })
    res.units = rows.map(function(d,i){
      return data.units[d];
    })
    return res;
  }

  function formPost(xbrlData, rows, category) {
    // console.log(arguments)
    var cat = xbrlData.filter(function(d) {
      // console.log(d["NAME"], category)
      return d["NAME"] == category;
    })[0];

    cat["EVENTS"] = cat["EVENTS"].filter(function(d) {
      return rows.some(function(r) {
        return r == d["ID"];
      })
    })

    // console.log(cat);
    return cat;
  }

  function LineChart(container, data, dates) {
    this.numbers = data.rows.map(function(d) {
      return d.slice(1);
    })
    this.valFormat = "s";
    this.container = container;
    this.data = data;
    this.dates = dates;
    this.width = width;
    this.height = 510;
    this.margin = 60;
    this.textHeight = 30;
    this.titles = data.rows.map(function(d){
      return d[0];
    })

    this.colors = ["#ff8752", "#ff9829", "#ffc82a", "#ffe451", "#c7e747", "#c9ba14", "#a1a224", "#308336", "#39b54a", "#9dd29c", "#3ed5a5", "#249ba3", "#91dadf", "#c2dcff", "#72aeff", "#717bdb", "#9577af", "#cbade4", "#d876ab", "#ffbfa9", "#bbc2c8", "#78858d"];


    // this.build();
  }

  LineChart.prototype.getColor = function(title) {
    return this.colors[(this.titles.indexOf(title)) % this.colors.length];
  }


  LineChart.prototype.showTooltip = function(d, i, j, self, title) {
    var top = self.vis.property("offsetTop");
    var that = self.data.rows[j];
    var padding = 5;
    var graphicArea = d3.select(".graphic-area");
    var cx = self.x(self.data.dates[i]);
    d3.select(self.container).selectAll(".dot-tooltip").remove();
    var gw = d3.select(self.container).select(".field").node().getBBox().width;
    var key = title == undefined ? that[0] : title;
    // console.log(key, d, title)
    self.vis.selectAll(".line-graph").filter(function(ld) {
      return ld[0] == key;
    }).select(".dot:nth-of-type(" + (i + 1) + ")").attr("r",8)//.style("stroke", self.getColor(key)).style("stroke-width", 4);

    var tt = d3.select(self.container).insert("div").attr("class", "dot-tooltip").style("left", (cx + 100 + self.margin) + "px").style("top", top + self.y(d) + 8 + "px")
    tt.insert("div").attr("class", "dot-tooltip-par").html(key + ", " + self.data.dates[i]);
    tt.insert("div").attr("class", "dot-tooltip-val").html((function(d) {
      return d3.format(",f")(d)
    })(d) + " " + self.data.units[j])

  }



  LineChart.prototype.hideTooltip = function(d, i, j, self) {

    d3.select(self.container).selectAll(".dot-tooltip").transition().duration(300).style("opacity", 0).remove();

    self.vis.selectAll(".dot").attr("r", 4);
  }



  LineChart.prototype.update = function(data) {
    var self = this;
    this.data = data;
    var dates = this.dates = data.dates;
    this.numbers = data.rows.map(function(d) {
      return d.slice(1);
    })
    this.max = d3.max(d3.merge(this.numbers));
    this.min = d3.min(d3.merge(this.numbers));
    var max = this.max + (this.max - this.min) * .1;
    var min = this.min - (this.max - this.min) * .1;
    if (max - min < 0.1) {
      max = max + Math.abs(max) * .1;
      min = max - Math.abs(max) * .1;
    }
    this.x.domain(dates);
    this.y.domain([min, max]);
    var x = this.x;
    var y = this.y;
    var height = this.height;
    var width = this.width;
    var margin = this.margin;
    this.vis.select(".y-axis").call(this.yAxis);
    this.vis.select(".x-axis").call(this.xAxis);
    this.vis.select(".y-text").text(data.units[0])
    var line = this.line;
    var lineGraphs = this.vis.select(".graphic-area").attr("transform", "translate("+(x.rangeBand()*.5)+", " + -height + ")").selectAll(".line-graph").datum([]).data(data.rows, function(d) {
      return d[0];
    }).attr("fill", function(d, i, j) {
        return self.getColor.call(self, d[0]);
      })
      .attr("stroke", function(d, i, j) {
        return self.getColor.call(self, d[0]);
      });
    lineGraphs.selectAll(".line")
      .attr("fill", "none").attr("d", function(d, i) {
       line.x(function(d, i) {
        return x(parseInt(dates[i]));
      });
      return line.y(function(d) {
        return y(parseFloat(d));
      })(d.slice(1));
    });
    
    lineGraphs.exit().remove();

    var lineGraph = lineGraphs.enter().append("g").attr("class", "line-graph").attr("clip-path", "url(#big-clip)")
      .attr("fill", function(d, i, j) {
        return self.getColor.call(self, d[0]);
      })
      .attr("stroke", function(d, i, j) {
        return self.getColor.call(self, d[0]);
      });
    lineGraph.append("path").attr("class", "line").attr("stroke-width", 2).attr("fill", "none").attr("d", function(d, i) {
       line.x(function(d, i) {
        return x(parseInt(dates[i]));
      });
      return line.y(function(d) {
        return y(parseFloat(d));
      })(d.slice(1));
    })

    this.updateLegend();

    var dotGroup = lineGraphs.selectAll(".dot").data(function(d) {
      return d.slice(1);
    });
    lineGraphs.selectAll(".dot").attr("transform", function(d, i) {

      return "translate(" + x(dates[i]) + "," + y(parseFloat(d)) + ")"
    })
    dotGroup.enter().append("circle").attr("filter", "url(#svg-shadow)").attr("r", 4).attr("class", "dot")
      .attr("transform", function(d, i) {
      return "translate(" + x(dates[i]) + "," + y(parseFloat(d)) + ")"
    });
    dotGroup.exit().remove();


    var anchorsGroup = this.vis.select(".anchors-area").attr("transform", "translate("+x.rangeBand()*.5+", " + -height + ")").selectAll("g.anchors").data(data.rows, function(d) {
      return d[0];
    });
    anchorsGroup.exit().remove();
    var anchors = anchorsGroup.enter().append("g").attr("class", "anchors");
    anchors.datum(function(d) {
      return d.slice(1);
    })
    anchors.selectAll("circle").data(function(d) {
      return d;
    }).enter().append("circle").attr("transform", function(d, i, j) {
      return "translate(" + x(dates[i]) + "," + y(parseFloat(d)) + ")"
    }).attr("opacity", 0).attr("r", 20).attr("class", "dot-anchor")
      .on("mouseover", function(d, i, j) {
      self.showTooltip(d, i, j, self)
    })
      .on("mouseout", function(d, i, j) {
      self.hideTooltip(d, i, j, self)
    });
    this.vis.selectAll(".tick line").attr("stroke", "#d3dade").attr("stroke-width", 1);
  }



  LineChart.prototype.build = function() {
    var self = this;
    var data = this.data;
    var dates = this.data.dates;
    var numbers = this.numbers;
    var valFormat = this.valFormat;
    var width = this.width;
    var height = this.height;
    var margin = this.margin;
    this.max = d3.max(d3.merge(numbers));
    this.min = d3.min(d3.merge(numbers));
    var max = this.max + (this.max - this.min) * .1;
    var min = this.min - (this.max - this.min) * .1;
    if (max - min < 0.1) {
      max = max + Math.abs(max) * .1;
      min = max - Math.abs(max) * .1;
    }

    this.y = d3.scale.linear().domain([min, max]).range([height - margin, 0 + margin]);
    var y = this.y;
    
    this.x = d3.scale.ordinal().domain(dates).rangeBands([width, 0], 0, .6);
    var x = this.x;
    this.xAxis = d3.svg.axis().scale(x).ticks(dates.length - 1).tickFormat(d3.format("g")).tickSize(-height + margin * 2).tickPadding(10);
    var xAxis = this.xAxis;
    this.yAxis = d3.svg.axis().scale(y).ticks(6).tickFormat(function(d) {
      return d3.format(",f")((d))
    }).orient("left").tickSize(-width + margin * 2).tickSubdivide(true).tickPadding(10);
    var yAxis = this.yAxis;

    var container = this.container;

    var vis = this.vis = d3.select(container).append("svg:svg").attr("width", width).attr("height", height).attr("class", "vis an-chart line-chart").style("font-family", "Arial, sans-serif");
    
     // filters go in defs element
    var defs = vis.append("defs");

    // create filter with id #drop-shadow
    // height=130% so that the shadow is not clipped
    var filter = defs.append("filter")
        .attr("id", "svg-shadow")
        .attr("height", "200%")
        .attr("width", "200%")
        .attr("x", "-.5")
        .attr("y", "-.5")


    // translate output of Gaussian blur to the right and downwards with 2px
    // store result in offsetBlur
    filter.append("feOffset")
        .attr("in", "SourceAlpha")
        .attr("dx", 1)
        .attr("dy", 0)
        .attr("result", "offOut");

    // SourceAlpha refers to opacity of graphic that this filter will be applied to
    // convolve that with a Gaussian with standard deviation 3 and store result
    // in blur
    filter.append("feGaussianBlur")
        .attr("in", "offOut")
        .attr("stdDeviation", 1)
        .attr("result", "blurOut");

    filter.append("feBlend")
        .attr("in", "SourceGraphic")
        .attr("in2", "blurOut")
        .attr("mode", "normal")

    filter.append("feComponentTransfer").append("feFuncA").attr("type", "linear").attr("slope", .6);

    // overlay original SourceGraphic over translated blurred opacity by using
    // feMerge filter. Order of specifying inputs is important!
    var feMerge = filter.append("feMerge");

    feMerge.append("feMergeNode")
        // .attr("in", "offsetBlur")
    feMerge.append("feMergeNode")
        .attr("in", "SourceGraphic");


    vis.append("rect").attr("fill", "none").attr("stroke", "#d3dade").attr("stroke-width",1).attr("width", width-margin*2).attr("height", height-margin*2).attr("transform", "translate("+margin+","+margin+")");


    var g = this.field = vis.append("svg:g").attr("class", "field").attr("transform", "translate(" + 0 + ", " + height + ")");

    g.append("svg:g").attr("class", "y-axis").attr("transform", "translate(" + margin + "," + (-height) + ")").call(yAxis).append("text").attr("transform", "rotate(0),translate(-" + margin * 1 + "," + margin * .8 + ")").attr("class", "y-text").text(this.data.units[0]);

    // x axis
    g.append("svg:g").attr("class", "x-axis").attr("transform", "translate(0," + -margin + ")").call(xAxis)
      // .append("text").attr("transform", "translate(" + (width * 0.5 - margin * .2) + "," + margin * 0.8 + ")").attr("class", "x-text").text("Period");


    var graphicArea = g.append("svg:g").attr("transform", "translate("+(x.rangeBand()*.5)+", " + -height + ")").attr("class", "graphic-area");
    vis.append("clipPath").attr("id", "big-clip").append("rect").attr("height", height - margin * 2).attr("transform", "translate(" + (margin-x.rangeBand()*.5) + "," + margin + ")").attr("width", 0).transition().duration(1000).attr("width", width - margin);

    vis.selectAll("path.domain").attr("fill", "none");

    // add legend
    var legend = this.legend = this.vis.append("g").attr("class", "legend").attr("transform", "translate(0, " + (this.height + this.margin * .5) + ")");

    this.updateLegend();

    // line generator
    var line = this.line = d3.svg.line().interpolate("cardinal");

    var lineGraphs = this.lineGraphs = graphicArea.selectAll("g.line-graph").data(data.rows, function(d) {
      return d[0];
    });
    var lineGraph = lineGraphs.enter().append("g").attr("class", "line-graph").attr("clip-path", "url(#big-clip)");
    lineGraphs.exit().remove();
    lineGraph.append("path").attr("class", "line").attr("stroke", function(d, i) {
      return colors[i % colors.length];
    }).attr("fill", "none").attr("stroke-width", 2).transition().attr("d", function(d, i) {
      
      line.x(function(d, i) {
        return x(parseInt(dates[i]));
      });
      return line.y(function(d) {
        return y(parseFloat(d));
      })(d.slice(1));
    })

    // adding dots
    var dotGroup = this.dotGroup = lineGraphs.selectAll(".dot").data(function(d) {
      return d.slice(1);
    });
    dotGroup.enter().append("circle").style("fill", function(d, i, j) {
      return colors[j % colors.length];
    }).attr("r", 4).attr("class", "dot")
      .attr("transform", function(d, i) {
      return "translate(" + x(dates[i]) + "," + y(parseFloat(d)) + ")"
    }).attr("filter", "url(#svg-shadow)");

    // adding anchors
    var anchorsArea = g.append("g").attr("class", "anchors-area").attr("clip-path", "url(#big-clip)").attr("transform", "translate("+x.rangeBand()*.5+", " + -height + ")");
    var anchorsGroup = this.anchorsGroup = anchorsArea.selectAll("g.anchors").data(data.rows, function(d) {
      return d[0];
    });
    anchorsGroup.exit().remove();
    var anchors = anchorsGroup.enter().append("g").attr("class", "anchors");
    anchors.datum(function(d) {
      return d.slice(1);
    })
    anchors.selectAll("circle").data(function(d) {
      return d;
    }).enter().append("circle").attr("transform", function(d, i, j) {
      return "translate(" + x(dates[i]) + "," + y(parseFloat(d)) + ")"
    }).attr("opacity", 0).attr("r", 20).attr("class", "dot-anchor")
      .on("mouseover", function(d, i, j) {
      self.showTooltip(d, i, j, self)
    })
      .on("mouseout", function(d, i, j) {
      self.hideTooltip(d, i, j, self)
    });
      vis.selectAll(".tick line").attr("stroke", "#d3dade").attr("stroke-width", 1);

  }



  LineChart.prototype.updateLegend = function() {
    var self = this;

    var legend = this.legend;
    var legendList = legend.selectAll("g.legend-item").data(this.data.rows, function(d) {
      return d[0];
    });
    legendList.exit()
      .remove()
    //.classed("lowlight", true);
    legendList.attr("transform", function(d, i) {
      return "translate(0, " + (i * self.textHeight) + ")";
    }).classed("lowlight", false).on("click", function(d,i){
      // toggle class
      d3.select(this).classed("lowlight", function(){
        if (d3.select(this).classed("lowlight"))
            return false;
        return true;
      });
      // select data
      var titles = [];
      // console.log(legendList)
      legendList.each(function(l,j){
        if (!d3.select(this).classed("lowlight")) 
          titles.push(l[0]);
      })
      // console.log(titles)
      self.showOnly(titles);
    });;
    var legendItem = legendList.enter().append("g").classed("legend-item", true).classed("lowlight", false).attr("transform", function(d, i) {
      return "translate(0, " + (i * self.textHeight) + ")";
    });
    legendItem.on("mouseover", function(d, i) {
      self.field.selectAll(".line-graph").classed("current", function(dd, ii) {
        return d[0] == dd[0];
      })
    }).on("mouseout", function() {
      self.field.selectAll(".line-graph").classed("current", false);
    }).on("click", function(d,i){
      // toggle class
      d3.select(this).classed("lowlight", function(){
        if (d3.select(this).classed("lowlight"))
            return false;
        return true;
      });
      // select data
      var titles = [];
      // console.log(legendList)
      legendList.each(function(l,j){
        if (!d3.select(this).classed("lowlight")) 
          titles.push(l[0]);
      })
      // console.log(titles)
      self.showOnly(titles);
    });
    legendItem.append("rect").attr("class", "legend-mark").attr("fill", function(d, i, j) {
      return self.getColor.call(self, d[0]);
    }).attr("width", 10).attr("height", 10);
    legendItem.append("text").attr("class", "legend-text").attr("x", 20).attr("y", 10).text(function(d) {
      return d[0];
    }).attr("fill", "#78858d");


    self.vis.attr("height", self.height + self.margin * .5 + self.textHeight * legend.selectAll(".legend-item")[0].length);

  }

  LineChart.prototype.showOnly = function(titles) {
    var self = this;
    var data = this.data;
    var dates = this.dates = data.dates;
    var rowIndexes = [];
    var rows = data.rows.filter(function(d, i){
      var hasTitle = titles.has(d[0]);
      if (hasTitle) rowIndexes.push(i)
      return hasTitle;
    })
    var numbers = rows.map(function(d) {
      return d.slice(1);
    })
    var units = data.units.filter(function(d, i){
      return rowIndexes.has(i);
    })
    this.max = d3.max(d3.merge(numbers));
    this.min = d3.min(d3.merge(numbers));
    var max = this.max + (this.max - this.min) * .1;
    var min = this.min - (this.max - this.min) * .1;
    if (max - min < 0.1) {
      max = max + Math.abs(max) * .1;
      min = max - Math.abs(max) * .1;
    }
    this.x.domain(dates);
    this.y.domain([min, max]);
    var x = this.x;
    var y = this.y;
    var height = this.height;
    var width = this.width;
    var margin = this.margin;
    this.vis.select(".y-axis").transition().call(this.yAxis);
    this.vis.select(".x-axis").call(this.xAxis);
    this.vis.select(".y-text").text(units[0])
    var line = this.line;
    var lineGraphs = this.vis.select(".graphic-area").selectAll(".line-graph").data(rows, function(d) {
      return d[0];
    })
    
    
    lineGraphs.exit().transition().attr("opacity", 0);

    var lineGraph = lineGraphs.transition().attr("opacity", 1).selectAll(".line").attr("d", function(d, i) {
       line.x(function(d, i) {
        return x(parseInt(dates[i]));
      });
      return line.y(function(d) {
        return y(parseFloat(d));
      })(d.slice(1));
    })

    var dotGroup = lineGraphs.selectAll(".dot").data(function(d) {
      return d.slice(1);
    });
    lineGraphs.selectAll(".dot").transition().attr("transform", function(d, i) {

      return "translate(" + x(dates[i]) + "," + y(parseFloat(d)) + ")"
    })

    var anchorsGroup = this.vis.select(".anchors-area").selectAll("g.anchors").data(rows, function(d) {
      return d[0];
    });
    anchorsGroup.exit().remove();
    anchorsGroup.selectAll("circle").attr("transform", function(d, i, j) {
      return "translate(" + x(dates[i]) + "," + y(parseFloat(d)) + ")"
    });
    var anchors = anchorsGroup.enter().append("g").attr("class", "anchors");
    anchors.datum(function(d) {
      return d.slice(1);
    })
    anchors.selectAll("circle").data(function(d) {
      return d;
    }).enter().append("circle").attr("transform", function(d, i, j) {
      return "translate(" + x(dates[i]) + "," + y(parseFloat(d)) + ")"
    }).attr("opacity", 0).attr("r", 20).attr("class", "dot-anchor")
      .on("mouseover", function(d, i, j) {
      // console.log(arguments, rows)
      self.showTooltip(d, i, j, self, rows[j][0])
    })
      .on("mouseout", function(d, i, j) {
      self.hideTooltip(d, i, j, self, rows[j][0])
    });
    this.vis.selectAll(".tick line").attr("stroke", "#d3dade").attr("stroke-width", 1);
  }

  function BarChart(container, data, dates) {
    this.numbers = data.rows.map(function(d) {
      return d.slice(1);
    })
    this.valFormat = "s";
    this.container = container;
    this.data = data;
    this.dates = dates;
    this.width = width;
    this.height = 510;
    this.margin = 60;
    this.textHeight = 30;
    this.titles = data.rows.map(function(d){
      return d[0];
    })

    this.colors = ["#ff8752", "#ff9829", "#ffc82a", "#ffe451", "#c7e747", "#c9ba14", "#a1a224", "#308336", "#39b54a", "#9dd29c", "#3ed5a5", "#249ba3", "#91dadf", "#c2dcff", "#72aeff", "#717bdb", "#9577af", "#cbade4", "#d876ab", "#ffbfa9", "#bbc2c8", "#78858d"];


    // this.build();
  }

  BarChart.prototype.showOnly = function(titles) {
    var self = this;
    var data = this.data;
    var dates = this.dates = data.dates;
    var rowIndexes = [];
    var rows = data.rows.filter(function(d, i){
      var hasTitle = titles.has(d[0]);
      if (hasTitle) rowIndexes.push(i)
      return hasTitle;
    })
    var numbers = rows.map(function(d) {
      return d.slice(1);
    })
    var units = data.units.filter(function(d, i){
      return rowIndexes.has(i);
    })
    this.max = d3.max(d3.merge(numbers));
    this.min = d3.min(d3.merge(numbers));
    var bottom = this.min < 0 ? -Math.max(Math.abs(this.min), Math.abs(this.max)) : 0;
    var top = this.max > 0 ? Math.max(Math.abs(this.min), Math.abs(this.max)) : 0;
    var max = this.max + (this.max - this.min) * .1;
    var min = this.min - (this.max - this.min) * .1;
    if (max - min < 0.1) {
      max = max + Math.abs(max) * .1;
      min = max - Math.abs(max) * .1;
    } 
    this.yBars.domain([bottom*1.1, top*1.1]);
    // console.log(this.yBars.domain())
    this.x.domain(dates);
    var yBars = this.yBars;

    var vis = this.vis;
    var g = this.field;
    this.vis.select(".y-bars-axis").transition().call(this.barsAxis);
    this.vis.select(".x-axis").call(this.xAxis);
    this.vis.select(".y-text").text(units[0])
    var graphicArea = g.select(".graphic-area");

    var barsData = dates.map(function(d,i) {
      var yearData = rows.map(function(yd) {
        return {
          "title": yd[0],
          "value": yd[i+1]
        }
      })
      return {
        key: d,
        value: yearData
      };
    })
    var barGroupsWidth = this.x.rangeBand();
    var barWidth = barGroupsWidth / rows.length;
    var barGroup = graphicArea.selectAll("g.bar-group").data(barsData, function(d) {
      return d.key;
    });
    barGroup.exit().attr("opacity", 0).attr("pointer-events", "none")
    barGroup.transition().attr("transform", function(d, i) {
      return "translate(" + (self.x(dates[i])) + "," + 0 + ")";
    });
    // var barsEnter = barGroup.enter().append("g").attr("class", "bar-group")
    //   .attr("transform", function(d, i) {

    //   return "translate(" + ((self.x(dates[i]))) + "," + 0 + ")";
    // });
    var bars = barGroup.selectAll("rect")
      .data(function(d) {
        return d.value;
      }, function(d){
        return d.title;
      }).attr("filter", "url(#svg-shadow)")
    bars.exit().attr("opacity", 0).attr("pointer-events", "none");
    bars.transition().attr("opacity", 1).attr("pointer-events", "visiblePainted").attr("height", function(d) {
      var val = d.value;
      return parseInt(Math.abs(yBars(val) - yBars(0)));
    })
      .attr("width", barWidth * .99)
      .attr("x", function(d, i) {
        return i * barWidth;
      })
      .attr("y", function(d) {
      var val = d.value;
      return val > 0 ? yBars(val) : yBars(0);
    })
    //   .style("fill", function(d, i) {
    //   return colors[i % colors.length];
    // });

    

    bars.on("mouseover", function(d, i, j) {
      self.showTooltip(d, i, j, self, d.title)
    })
      .on("mouseout", function(d, i, j) {
      self.hideTooltip(d, i, j, self)
    })
    this.vis.selectAll(".tick line").attr("stroke", "#d3dade").attr("stroke-width", 1);
  }


  BarChart.prototype.updateLegend = function() {
    var self = this;

    var legend = this.legend;
    var legendList = legend.selectAll("g.legend-item").data(this.data.rows, function(d) {
      return d[0];
    });
    legendList.exit()
      .remove()
    //.classed("lowlight", true);
    legendList.attr("transform", function(d, i) {
      return "translate(0, " + (i * self.textHeight) + ")";
    }).classed("lowlight", false).on("mouseover", function(d, i) {
      var titles = [];
      legendList.each(function(l,j){
        if (!d3.select(this).classed("lowlight")) 
          titles.push(l[0]);
      })

      self.field.selectAll(".bar-group rect").filter(function(ld) {
        return ld.title != d[0] && titles.has(ld.title);
      }).attr("opacity", .1);

    }).on("mouseout", function(d) {
       var titles = [];
      legendList.each(function(l,j){
        if (!d3.select(this).classed("lowlight")) 
          titles.push(l[0]);
      })
      self.field.selectAll(".bar-group rect").filter(function(ld) {
        // console.log(ld.title,titles)
        return titles.has(ld.title);
      })
      .attr("opacity", 1);
    }).on("click", function(d,i){
      // toggle class
      d3.select(this).classed("lowlight", function(){
        if (d3.select(this).classed("lowlight"))
            return false;
        return true;
      });
      // select data
      var titles = [];
      legendList.each(function(l,j){
        if (!d3.select(this).classed("lowlight")) 
          titles.push(l[0]);
      })
      self.showOnly(titles);
    });
    var legendItem = legendList.enter().append("g").classed("legend-item", true).classed("lowlight", false).attr("transform", function(d, i) {
      return "translate(0, " + (i * self.textHeight) + ")";
    });
    legendItem.on("mouseover", function(d, i) {
      var titles = [];
      legendList.each(function(l,j){
        if (!d3.select(this).classed("lowlight")) 
          titles.push(l[0]);
      })

      self.field.selectAll(".bar-group rect").filter(function(ld) {
        return ld.title != d[0] && titles.has(ld.title);
      }).attr("opacity", .1);

    }).on("mouseout", function(d) {
       var titles = [];
      legendList.each(function(l,j){
        if (!d3.select(this).classed("lowlight")) 
          titles.push(l[0]);
      })
      self.field.selectAll(".bar-group rect").filter(function(ld) {
        // console.log(ld.title,titles)
        return titles.has(ld.title);
      })
      .attr("opacity", 1);
    }).on("click", function(d,i){
      // toggle class
      d3.select(this).classed("lowlight", function(){
        if (d3.select(this).classed("lowlight"))
            return false;
        return true;
      });
      // select data
      var titles = [];
      legendList.each(function(l,j){
        if (!d3.select(this).classed("lowlight")) 
          titles.push(l[0]);
      })
      self.showOnly(titles);
    });
    legendItem.append("rect").attr("class", "legend-mark").attr("fill", function(d, i, j) {
      return self.getColor.call(self, d[0]);
    }).attr("width", 10).attr("height", 10);
    legendItem.append("text").attr("class", "legend-text").attr("x", 20).attr("y", 10).text(function(d) {
      return d[0];
    }).attr("fill", "#78858d");


    self.vis.attr("height", self.height + self.margin * .5 + self.textHeight * legend.selectAll(".legend-item")[0].length);

  }

  BarChart.prototype.getColor = function(title) {
    return this.colors[(this.titles.indexOf(title)) % this.colors.length];
  }

  BarChart.prototype.update = function(data, dates) {
    this.data = data;
    var dates = this.dates = data.dates;
    var self = this;
    var numbers = this.numbers = data.rows.map(function(d) {
      return d.slice(1);
    })
    var valFormat = this.valFormat;
    var width = this.width;
    var height = this.height;
    var margin = this.margin;
    this.max = d3.max(d3.merge(numbers));
    this.min = d3.min(d3.merge(numbers));
    var bottom = this.min < 0 ? -Math.max(Math.abs(this.min), Math.abs(this.max)) : 0;
    var top = this.max > 0 ? Math.max(Math.abs(this.min), Math.abs(this.max)) : 0;
    var max = this.max + (this.max - this.min) * .1;
    var min = this.min - (this.max - this.min) * .1;
    if (max - min < 0.1) {
      max = max + Math.abs(max) * .1;
      min = max - Math.abs(max) * .1;
    } 
    this.yBars.domain([bottom*1.1, top*1.1]);
    this.x.domain(dates);
    var yBars = self.yBars;

    var vis = this.vis;
    var g = this.field;
    this.vis.select(".y-bars-axis").transition().call(this.barsAxis);
    this.vis.select(".x-axis").call(this.xAxis);
    this.vis.select(".y-text").text(data.units[0])
    var graphicArea = g.select(".graphic-area");

    var barsData = dates.map(function(d,i) {
      var yearData = data.rows.map(function(yd) {
        return {
          "title": yd[0],
          "value": yd[i+1]
        }
      })
      return {
        key: d,
        value: yearData
      };
    })
    // console.log(barsData)
    this.updateLegend();
    var barGroupsWidth = this.x.rangeBand();
    var barWidth = barGroupsWidth / data.rows.length;
    var barGroup = graphicArea.selectAll("g.bar-group").data(barsData, function(d) {
      return d.key;
    });
    barGroup.exit().remove();
    barGroup.transition().attr("transform", function(d, i) {
      return "translate(" + (self.x(dates[i])) + "," + 0 + ")";
    });
    var barsEnter = barGroup.enter().append("g").attr("class", "bar-group")
      .attr("transform", function(d, i) {

      return "translate(" + ((self.x(dates[i]))) + "," + 0 + ")";
    });
    var bars = barGroup.selectAll("rect")
      .data(function(d) {
        return d.value;
      }, function(d){
        return d.title;
      }).attr("filter", "url(#svg-shadow)").attr("opacity", 1)
    bars.exit().remove();
    bars.transition().attr("height", function(d) {
      var val = d.value;
      return parseInt(Math.abs(yBars(val) - yBars(0)));
    })
      .attr("width", barWidth * .99)
      .attr("x", function(d, i) {
        return i * barWidth;
      })
      .attr("y", function(d) {
      var val = d.value;
      return val > 0 ? yBars(val) : yBars(0);
    })
    //   .style("fill", function(d, i) {
    //   return colors[i % colors.length];
    // });

    bars.enter().append("rect")
    .attr("filter", "url(#svg-shadow)")
      .attr("height", function(d) {
      var val = d.value;
      return parseInt(Math.abs(yBars(val) - yBars(0)));
    })
      .attr("width", barWidth * .99)
      .attr("x", function(d, i) {
      return i * barWidth;
    })
      .attr("y", function(d) {
      var val = d.value;
      return val > 0 ? yBars(val) : yBars(0);
    })
     .attr("fill", function(d, i) {
      return self.getColor.call(self, d.title);
    })

    bars.on("mouseover", function(d, i, j) {
      // console.log(arguments, self.titles,d)
      self.showTooltip(d, i, j, self, d.title)
    })
      .on("mouseout", function(d, i, j) {
      self.hideTooltip(d, i, j, self)
    })
    this.vis.selectAll(".tick line").attr("stroke", "#d3dade").attr("stroke-width", 1);
  }

  BarChart.prototype.showTooltip = function(d, i, j, self, title) {
    var top = self.vis.property("offsetTop");
    var that = self.data.rows[i];
    var padding = 5;
    var graphicArea = d3.select(".graphic-area");
    var cx = self.x(self.data.dates[j]);
    d3.select(self.container).selectAll(".dot-tooltip").remove();
    var gw = d3.select(self.container).select(".field").node().getBBox().width;
    var key = title == undefined ? that[0] : title;

    
    var tt = d3.select(self.container).insert("div").attr("class", "dot-tooltip").style("left", (cx + 100 + self.margin) + "px").style("top", top + self.yBars(d.value) + 8 + "px")
    tt.insert("div").attr("class", "dot-tooltip-par").html(key + ", " + self.data.dates[j]);
    tt.insert("div").attr("class", "dot-tooltip-val").html((function(d) {
      return d3.format(",f")(d.value)
    })(d) + " " + self.data.units[i])
    var tw = tt.property("clientHeight");
    if (d.value > 0) {
      tt.style("margin-top", (-tw-16) + "px");
    }
  }



  BarChart.prototype.hideTooltip = function(d, i, j, self) {
    d3.select(self.container).selectAll(".dot-tooltip").transition().duration(300).style("opacity", 0).remove();
    // self.vis.selectAll(".bar-group rect").attr("opacity", 1);
  }

  BarChart.prototype.build = function() {
    var self = this;
    var data = this.data;
    var dates = this.data.dates;
    var numbers = this.numbers;
    var valFormat = this.valFormat;
    var width = this.width;
    var height = this.height;
    var margin = this.margin;
    this.max = d3.max(d3.merge(numbers));
    this.min = d3.min(d3.merge(numbers));
    var max = this.max + (this.max - this.min) * .1;
    var min = this.min - (this.max - this.min) * .1;
    if (max - min < 0.1) {
      max = max + Math.abs(max) * .1;
      min = max - Math.abs(max) * .1;
    }
    this.yBars = d3.scale.linear().domain([min, max]).range([height - margin, 0 + margin]);
    var yBars = this.yBars;
    this.x = d3.scale.ordinal().domain(dates).rangeBands([width - margin, 0 + margin], 0.2, 0.2);
    var x = this.x;
    this.xAxis = d3.svg.axis().scale(x).ticks(dates.length - 1).tickFormat(d3.format("g")).tickSize(0).tickPadding(10);
    var xAxis = this.xAxis;
    this.barsAxis = d3.svg.axis().scale(yBars).ticks(6).tickFormat((function(d) {
      return d3.format(",f")((d))
    })).orient("left").tickSize(-width + margin * 2).tickSubdivide(true).tickPadding(10);
    var barsAxis = this.barsAxis;
    var container = this.container;


    var vis = this.vis = d3.select(container).append("svg:svg").attr("width", width).attr("height", height).attr("class", "vis an-chart bar-chart").style("font-family", "Arial, sans-serif");

    // filters go in defs element
    var defs = vis.append("defs");

    // create filter with id #drop-shadow
    // height=130% so that the shadow is not clipped
    var filter = defs.append("filter")
        .attr("id", "svg-shadow")
        .attr("height", "130%");

    // SourceAlpha refers to opacity of graphic that this filter will be applied to
    // convolve that with a Gaussian with standard deviation 3 and store result
    // in blur
    filter.append("feGaussianBlur")
        .attr("in", "SourceAlpha")
        .attr("stdDeviation", 3)
        .attr("result", "blur");

    // translate output of Gaussian blur to the right and downwards with 2px
    // store result in offsetBlur
    filter.append("feOffset")
        .attr("in", "blur")
        .attr("dx", 2)
        .attr("dy", 0)
        .attr("result", "offsetBlur");

    filter.append("feComponentTransfer").append("feFuncA").attr("type", "linear").attr("slope", .2);

    // overlay original SourceGraphic over translated blurred opacity by using
    // feMerge filter. Order of specifying inputs is important!
    var feMerge = filter.append("feMerge");

    feMerge.append("feMergeNode")
        // .attr("in", "offsetBlur")
    feMerge.append("feMergeNode")
        .attr("in", "SourceGraphic");

    var g = this.field = vis.append("svg:g").attr("class", "field").attr("transform", "translate(" + 0 + ", " + height + ")");

    g.append("svg:g").attr("class", "y-bars-axis").attr("transform", "translate(" + margin + "," + (-height) + ")").call(barsAxis).append("text").attr("transform", "rotate(0),translate(-" + margin * 1 + "," + margin * .8 + ")").attr("class", "y-text").text(data.units[0]);

    // x axis
    g.append("svg:g").attr("class", "x-axis").attr("transform", "translate(0," + -margin + ")").call(xAxis)
    // .append("text").attr("transform", "translate(" + (width * 0.5 - margin * .2) + "," + margin * 0.8 + ")").attr("class", "x-text").text("Period");


    var graphicArea = g.append("svg:g").attr("transform", "translate(0, " + -height + ")").attr("class", "graphic-area");
    graphicArea.append("clipPath").attr("id", "big-clip").append("rect").attr("height", height - margin * 2).attr("transform", "translate(" + margin + "," + margin + ")").attr("width", 0).transition().duration(1000).attr("width", width - margin * 2);

    vis.selectAll("path.domain").attr("fill", "none");
    // vis.select(".x-axis .domain").attr("stroke", "#d3dade").attr("stroke-width", 1);
    // add legend

    vis.append("rect").attr("fill", "none").attr("stroke", "#d3dade").attr("stroke-width",1).attr("width", width-margin*2).attr("height", height-margin*2).attr("transform", "translate("+margin+","+margin+")");

    var legend = this.legend = this.vis.append("g").attr("class", "legend").attr("transform", "translate(0, " + (this.height + this.margin * .5) + ")");

    this.updateLegend();

    yBars.domain([-Math.max(Math.abs(min), Math.abs(max)), Math.max(Math.abs(min), Math.abs(max))]);
    barsAxis.scale(yBars);
    g.transition().select(".y-bars-axis").call(barsAxis);


    var barsData = dates.map(function(d,i) {
      var yearData = data.rows.map(function(yd) {
        return {
          "title": yd[0],
          "value": yd[i+1]
        }
      })
      return {
        key: d,
        value: yearData
      };
    })

    var barPadding = this.barPadding = 10;
    var barGroupsWidth = x.rangeBand();
    var barWidth = barGroupsWidth / data.rows.length;
    var barGroup = graphicArea.selectAll("g.bar-group").data(barsData, function(d) {
      return d.key;
    });
    barGroup.exit().remove();

    var barsEnter = barGroup.enter().append("g").attr("class", "bar-group")
      .attr("transform", function(d, i) {

      return "translate(" + (x(dates[i])) + "," + 0 + ")";
    });
    var bars = barsEnter.selectAll("rect")
      .data(function(d) {
      return d.value;
    }).attr("filter", "url(#svg-shadow)")
      .enter().append("rect")
      .attr("height", function(d) {
        var val = d.value;
        return parseInt(Math.abs(yBars(val) - yBars(0)));
      })
      .attr("width", barWidth * .99)
    // .attr("transform", "translate(0," + 0 + ")")
    .attr("x", function(d, i) {
      return i * barWidth;
    })
      .attr("y", function(d) {
        var val = d.value;
        return val > 0 ? yBars(val) : yBars(0); // parseInt((difUnits.length > 0 && d[1] == difUnits[0][1]) ? y2(d[2]) : yBars(d[2]));
      })
    .attr("fill", function(d, i) {
      return self.getColor.call(self, d.title);
    })
    bars.on("mouseover", function(d, i, j) {
      self.showTooltip(d, i, j, self)
    })
      .on("mouseout", function(d, i, j) {
      self.hideTooltip(d, i, j, self)
    })

  
  }


  function diffData(data) {
    // console.log(data);

  }

  function bracesFormat(number) {
    return number >= 0 ? number : "(" + (-number) + ")";
  }

  Array.prototype.has = function(el) {
    return this.some(function(d){return el === d});
  }

  function buildTable(data, table, lineChart, barChart) {
    var dates = data.dates;

    var thead = table.select("thead");
    thead.append("tr").classed("cat-hdr", true).classed("level-2", true).selectAll("th").data([data.rows[0][0]].concat(dates))
      .enter()
      .append("th").html(function(d,i){
      if (i !== 0) return d;
      var s = d.toString().toLowerCase();
      s = s[0].toUpperCase().concat(s.slice(1));
      return s;
    }).classed("data-col", function(d,i){return i != 0});
    var tbody = table.select("tbody");
    var tr = tbody.selectAll("tr.data-row").data(data.rows.slice(1), function(d) {
      return d[0];
    });
    var selecting = true;
    tr.exit().remove();
    var te = tr.enter().append("tr")
      .attr("class", function(d,i){
        var level = 0;
        data.levels.forEach(function(l,j){
          level = l.has(i+1) ? 2-j : level;
        })
        return "level-" + level + (i==0 ? " ui-selected" : "");
      })
      .classed("data-row", function(d){
        // console.log(d);
        return d.length > 1;
      }).classed("cat-hdr", function(d){
        // console.log(d);
        return d.length == 1;
      })
      .on("mousedown", function(d, i) {
      selecting = !$(".data-table tbody tr.data-row").eq(i).hasClass("ui-selected");
    });
    var th = te.append("th");
    th.append("span").html(function(d){
      var s = d[0].toString().toLowerCase();
      s = s[0].toUpperCase().concat(s.slice(1));
      return s;
    });
    var td = te.selectAll("td").data(function(d, i) {
      return d.slice(1);
    });
    td.enter().append("td").attr("class", function(d, i) {
      return "col-" + i;
    }).text(bracesFormat);
    var th0 = te.select("th:first-child");
    th0.filter(function(d){
      return d.length > 1;
    }).insert("span", "span").attr("class", "legend-mark").style("background-color", function(d,i){
      return colors[i % colors.length]
    })
    th0.append("span").attr("class", "notes-block");
    th0.filter(function(d,i){
      return d.length == 1 && i > 0;
    }).attr("colspan", data.dates.length+1)
    // var hdrData = dates.map(String);
    // // = (["Facts"]).concat(dates);
    var hdr = tbody.select("tr.cat-hdr:first-child").selectAll("td").data(dates);
    hdr.enter().append("td").text(function(d){
      var s = d.toString().toLowerCase();
      s[0] = s[0].toUpperCase();
      return s;
    }).classed("data-col", function(d) {
      return !isNaN(parseInt(d));
    })
    $(".data-table tbody,.data-table thead").on("mousedown mouseup", function(e) {
      e.metaKey = true;
    });
    var rows = [0];
    var cols;
    var filteredData;


    var dataRows = [], 
        units = [];

    data.rows.forEach(function(d,i){
      if (d.length > 1) {
        dataRows.push(d);
        units.push(data.units[i]);
      }
    })
    
    var chartsData = {
      dates: data.dates,
      units: units,
      rows: dataRows
    }


    $(".data-table tbody").selectable({
      filter: ".data-row",
      selecting: function(e, ui) {
        rows = $("tr.ui-selected, tr.ui-selecting").map(function(ind, el) {
          return $(el).index(".data-row");
        }).get();
        
        // if (!selecting) {
        //   $(ui.selecting).removeClass("click-selected").removeClass("ui-selecting").addClass("ui-unselecting");
        // } else {
          $(ui.selecting).addClass("click-selected").addClass("ui-selecting").removeClass("ui-unselecting");
        // }
      },
      selected: function(e, ui) {
        // legend.selectAll(".legend-item").data([]).exit().remove();
        $(ui.selected).removeClass("ui-unselecting");
        filteredData = filterData(chartsData, rows, cols);
        lineChart.update(filteredData);
        barChart.update(filteredData)
      },
      unselected: function(e, ui) {
        rows = $("tr.ui-selected, tr.ui-selecting").map(function(ind, el) {
          return $(el).index(".data-row");
        }).get();

        $(ui.unselected).removeClass("click-selected").removeClass("ui-unselecting");
        // legend.selectAll(".legend-item").data([]).exit().remove();
        filteredData = filterData(chartsData, rows, cols);
        lineChart.update(filteredData);
        barChart.update(filteredData)
        $(ui.unselected).removeClass("ui-unselecting").removeClass("click-selected");
      }

    });


    $(".data-table thead").selectable({
      distance: 0,
      filter: "th.data-col",
      selecting: function(e, ui) {
        e.metaKey = true;
        // e.preventDefault();
        var i = ui.selecting.cellIndex;
        cols = $(".data-col.ui-selected, .data-col.ui-selecting").map(function(i, el) {
          return $(el).index() - 1;
        }).get();

        // table.selectAll("t.col-" + (i - 1) + ",th.col-" + (i - 1)).classed("ui-selected-column", true);
        table.selectAll(".data-row").selectAll("td").classed("ui-selected-column", function(d, j){
          return cols.has(j);
        })
      },
      unselecting: function(e, ui) {
        cols = $(".data-col.ui-selected, .data-col.ui-selecting").map(function(i, el) {
          return $(el).index() - 1;
        }).get();
        var newDates = cols.map(function(d) {
          return dates[d];
        })
        table.selectAll(".data-row").selectAll("td").classed("ui-selected-column", function(d, j){
          return cols.has(j);
        })
        // $(ui.unselected).removeClass("click-selected").removeClass("ui-unselecting");
        var filteredData = filterData(chartsData, rows, cols);
        lineChart.update(filteredData);
        barChart.update(filteredData)
      },
      selected: function() {
        var newDates = cols.map(function(d) {
          return dates[d];
        })
        var filteredData = filterData(chartsData, rows, cols);
        lineChart.update(filteredData);
        barChart.update(filteredData)
      },
      unselected: function(e, ui) {
        cols = $(".data-col.ui-selected, .data-col.ui-selecting").map(function(i, el) {
          return $(el).index() - 1;
        }).get();
        var newDates = cols.map(function(d) {
          return dates[d];
        })
        table.selectAll(".data-row").selectAll("td").classed("ui-selected-column", function(d, j){
          return cols.has(j);
        })
        // $(ui.unselected).removeClass("click-selected").removeClass("ui-unselecting");
        var filteredData = filterData(chartsData, rows, cols);
        lineChart.update(filteredData);
        barChart.update(filteredData)
      }
    });



  }

  // /functions

  function build() {


    var names = [];
    var rowHeaders;
    var numberData = [];
    var mergedData = {};

    

    // build filter buttons
    var table = d3.select(".an-chart-container").append("table").attr("class", "data-table").attr("cellspacing", 0);
    table.append("thead");
    table.append("tbody");

    $(".postData").on("click", function() {
      var rows = $("tr.ui-selected, tr.ui-selecting").map(function(ind, el) {
        // console.log(d3.select(el).datum())
        return d3.select(el).datum()["ID"];
      }).get();
      var cat = $(".filters-list").val();
      // console.log(formPost(xbrl, rows, cat))
      var json = JSON.stringify(formPost(xbrl, rows, cat));
      // console.log(json);

      $.post("./xbrl/for_array.php", {
        "json": json
      }, function(e) {
        // console.log(arguments);
        window.location = arguments[0];
      });

    })


    var dates = data.dates;

    var rows = [], 
        units = [];

    data.rows.forEach(function(d,i){
      if (d.length > 1) {
        rows.push(d);
        units.push(data.units[i]);
      }
    })
    var chartsData = {
      dates: data.dates,
      units: units,
      rows: rows
    }
    var lineChart = new LineChart(".an-chart-container", chartsData);
    var barChart = new BarChart(".an-chart-container", chartsData);

    buildTable(data, table, lineChart, barChart);
    lineChart.build();
    barChart.build();
    // lineChart.update(filterData(chartsData, [])); // dirty trick, TODO
    lineChart.update(filterData(chartsData, [0]));
    barChart.update(filterData(chartsData, [0]));


  }


})

function formSVG(selector) {

  // Инициализируем таблицу перевода
  var trans = [];
  for (var i = 0x410; i <= 0x44F; i++)
  trans[i] = i - 0x350; // А-Яа-я
  trans[0x401] = 0xA8; // Ё
  trans[0x451] = 0xB8; // ё

  // Сохраняем стандартную функцию escape()
  var escapeOrig = window.escape;

  // Переопределяем функцию escape()
  var escape = function(str) {
    var ret = [];
    // Составляем массив кодов символов, попутно переводим кириллицу
    for (var i = 0; i < str.length; i++) {
      var n = str.charCodeAt(i);
      if (typeof trans[n] != 'undefined') n = trans[n];
      if (n <= 0xFF) ret.push(n);
    }
    return escapeOrig(String.fromCharCode.apply(null, ret));
  }

  var svgcopy = $(selector).addClass("an-chart").clone().attr("title", "test2")
    .attr("version", 1.1)
    .attr("encoding", "utf-8")
    .attr("xmlns", "http://www.w3.org/2000/svg");
  svgcopy.find("text").text(function(i, s) {
    // $(this).text(escape(s));
  });
  $.when($.get("styles/main.css"))
    .done(function(response) {
    svgcopy.prepend("<style>" + response + "</style>");
    var svg = svgcopy[0];
    // var html = svgcopy.html();
    // console.log(svg);

    // d3.select(svg).classed("an-chart", true);
    // console.log(svg);
    // Extract the data as SVG text string
    var svg_xml = (new XMLSerializer).serializeToString(svg);
    // console.log((svg_xml))

    d3.select("body").append("div")
      .attr("id", "download")
      .append("img")
      .attr("src", "data:image/svg+xml;base64," + btoa(svg_xml));


  })
  // var svg = d3.select(selector)
  // .attr("title", "svg-image")
  // .attr("version", 1.1)
  // .attr("xmlns", "http://www.w3.org/2000/svg").node();


  // console.log((svg_xml));

}})(jQuery);