// Generated by CoffeeScript 2.7.0
// iplotScanone_pxg: lod curves + phe x gen plot
// Karl W Broman
var iplotScanone_pxg;

iplotScanone_pxg = function(widgetdiv, lod_data, pxg_data, chartOpts) {
  var altrectcolor, chartdivid, chrGap, cur_chr, eff_axispos, eff_nyticks, eff_pointcolor, eff_pointcolorhilit, eff_pointsize, eff_pointstroke, eff_rotate_ylab, eff_titlepos, eff_xlab, eff_yNA, eff_ylab, eff_ylim, eff_yticks, g_lod, height, lod_axispos, lod_linecolor, lod_linewidth, lod_nyticks, lod_pointcolor, lod_pointsize, lod_pointstroke, lod_rotate_ylab, lod_title, lod_titlepos, lod_xlab, lod_ylab, lod_ylim, lod_yticks, margin, markers, mylodchart, mypxgchart, objects, plotPXG, rectcolor, ref, ref1, ref10, ref11, ref12, ref13, ref14, ref15, ref16, ref17, ref18, ref19, ref2, ref20, ref21, ref22, ref23, ref24, ref25, ref26, ref27, ref28, ref29, ref3, ref30, ref31, ref32, ref33, ref34, ref35, ref36, ref37, ref38, ref39, ref4, ref40, ref41, ref42, ref43, ref44, ref45, ref46, ref5, ref6, ref7, ref8, ref9, svg, tipdirection, widgetdivid, width, wleft, wright, x, xjitter;
  markers = (function() {
    var results;
    results = [];
    for (x in pxg_data.chrByMarkers) {
      results.push(x);
    }
    return results;
  })();
  cur_chr = "";
  // chartOpts start
  height = (ref = chartOpts != null ? chartOpts.height : void 0) != null ? ref : 450; // height of image in pixels
  width = (ref1 = chartOpts != null ? chartOpts.width : void 0) != null ? ref1 : 1200; // width of image in pixels
  wleft = (ref2 = chartOpts != null ? chartOpts.wleft : void 0) != null ? ref2 : width * 0.7; // width of left panel in pixels
  margin = (ref3 = chartOpts != null ? chartOpts.margin : void 0) != null ? ref3 : {
    left: 60,
    top: 40,
    right: 40,
    bottom: 40,
    inner: 5 // margins in pixels (left, top, right, bottom, inner)
  };
  lod_axispos = (ref4 = (ref5 = chartOpts != null ? chartOpts.lod_axispos : void 0) != null ? ref5 : chartOpts != null ? chartOpts.axispos : void 0) != null ? ref4 : {
    xtitle: 25,
    ytitle: 30,
    xlabel: 5,
    ylabel: 5 // position of axis labels in pixels (xtitle, ytitle, xlabel, ylabel) in LOD curve panel
  };
  lod_titlepos = (ref6 = (ref7 = chartOpts != null ? chartOpts.lod_titlepos : void 0) != null ? ref7 : chartOpts != null ? chartOpts.titlepos : void 0) != null ? ref6 : 20; // position of title for LOD curve panel, in pixels
  chrGap = (ref8 = chartOpts != null ? chartOpts.chrGap : void 0) != null ? ref8 : 6; // gap between chromosomes
  rectcolor = (ref9 = chartOpts != null ? chartOpts.rectcolor : void 0) != null ? ref9 : "#E6E6E6"; // color of background rectangle
  altrectcolor = (ref10 = chartOpts != null ? chartOpts.altrectcolor : void 0) != null ? ref10 : "#C8C8C8"; // color of alternate background rectangle
  lod_ylim = (ref11 = chartOpts != null ? chartOpts.lod_ylim : void 0) != null ? ref11 : null; // y-axis limits in LOD curve panel
  lod_nyticks = (ref12 = chartOpts != null ? chartOpts.lod_nyticks : void 0) != null ? ref12 : 5; // number of ticks in y-axis in LOD curve panel
  lod_yticks = (ref13 = chartOpts != null ? chartOpts.lod_yticks : void 0) != null ? ref13 : null; // vector of tick positions for y-axis in LOD curve panel
  lod_linecolor = (ref14 = chartOpts != null ? chartOpts.lod_linecolor : void 0) != null ? ref14 : "darkslateblue"; // line color for LOD curves
  lod_linewidth = (ref15 = chartOpts != null ? chartOpts.lod_linewidth : void 0) != null ? ref15 : 2; // line width for LOD curves
  lod_pointcolor = (ref16 = chartOpts != null ? chartOpts.lod_pointcolor : void 0) != null ? ref16 : "#E9CFEC"; // color for points at markers in LOD curve panel
  lod_pointsize = (ref17 = chartOpts != null ? chartOpts.lod_pointsize : void 0) != null ? ref17 : 0; // size of points at markers (default = 0 corresponding to no visible points at markers)
  lod_pointstroke = (ref18 = chartOpts != null ? chartOpts.lod_pointstroke : void 0) != null ? ref18 : "black"; // color of outer circle for points at markers in LOD curve panel
  lod_title = (ref19 = (ref20 = chartOpts != null ? chartOpts.lod_title : void 0) != null ? ref20 : chartOpts != null ? chartOpts.title : void 0) != null ? ref19 : ""; // title of LOD curve panel
  lod_xlab = (ref21 = chartOpts != null ? chartOpts.lod_xlab : void 0) != null ? ref21 : null; // x-axis label for LOD curve panel
  lod_ylab = (ref22 = chartOpts != null ? chartOpts.lod_ylab : void 0) != null ? ref22 : "LOD score"; // y-axis label for LOD curve panel
  lod_rotate_ylab = (ref23 = chartOpts != null ? chartOpts.lod_rotate_ylab : void 0) != null ? ref23 : null; // indicates whether to rotate the y-axis label 90 degrees, in LOD curve panel
  eff_pointcolor = (ref24 = (ref25 = chartOpts != null ? chartOpts.eff_pointcolor : void 0) != null ? ref25 : chartOpts != null ? chartOpts.pointcolor : void 0) != null ? ref24 : "slateblue"; // point color in phe-by-gen panel
  eff_pointcolorhilit = (ref26 = (ref27 = chartOpts != null ? chartOpts.eff_pointcolorhilit : void 0) != null ? ref27 : chartOpts != null ? chartOpts.pointcolorhilit : void 0) != null ? ref26 : "Orchid"; // point color, when highlighted, in phe-by-gen panel
  eff_pointstroke = (ref28 = (ref29 = chartOpts != null ? chartOpts.eff_pointstroke : void 0) != null ? ref29 : chartOpts != null ? chartOpts.pointstroke : void 0) != null ? ref28 : "black"; // color of outer circle for points, in phe-by-gen panel
  eff_pointsize = (ref30 = (ref31 = chartOpts != null ? chartOpts.eff_pointsize : void 0) != null ? ref31 : chartOpts != null ? chartOpts.pointsize : void 0) != null ? ref30 : 3; // point size in phe-by-gen paenl
  eff_ylim = (ref32 = chartOpts != null ? chartOpts.eff_ylim : void 0) != null ? ref32 : null; // y-axis limits in phe-by-gen panel
  eff_nyticks = (ref33 = chartOpts != null ? chartOpts.eff_nyticks : void 0) != null ? ref33 : 5; // number of ticks in y-axis in phe-by-gen panel
  eff_yticks = (ref34 = chartOpts != null ? chartOpts.eff_yticks : void 0) != null ? ref34 : null; // vector of tick positions for y-axis in phe-by-gen panel
  eff_xlab = (ref35 = chartOpts != null ? chartOpts.eff_xlab : void 0) != null ? ref35 : "Genotype"; // x-axis label in phe-by-gen panel
  eff_ylab = (ref36 = chartOpts != null ? chartOpts.eff_ylab : void 0) != null ? ref36 : "Phenotype"; // y-axis label in phe-by-gen panel
  eff_rotate_ylab = (ref37 = chartOpts != null ? chartOpts.eff_rotate_ylab : void 0) != null ? ref37 : null; // indicates whether to rotate the y-axis label 90 degrees, in phe-by-gen panel
  xjitter = (ref38 = (ref39 = chartOpts != null ? chartOpts.xjitter : void 0) != null ? ref39 : chartOpts != null ? chartOpts.eff_xjitter : void 0) != null ? ref38 : null; // amount of horizontal jittering in phe-by-gen panel
  eff_axispos = (ref40 = (ref41 = chartOpts != null ? chartOpts.eff_axispos : void 0) != null ? ref41 : chartOpts != null ? chartOpts.axispos : void 0) != null ? ref40 : {
    xtitle: 25,
    ytitle: 30,
    xlabel: 5,
    ylabel: 5 // position of axis labels in pixels (xtitle, ytitle, xlabel, ylabel) in LOD curve panel
  };
  eff_titlepos = (ref42 = (ref43 = chartOpts != null ? chartOpts.eff_titlepos : void 0) != null ? ref43 : chartOpts != null ? chartOpts.titlepos : void 0) != null ? ref42 : 20; // position of title for phe-by-gen panel, in pixels
  eff_yNA = (ref44 = chartOpts != null ? chartOpts.eff_yNA : void 0) != null ? ref44 : {
    handle: true,
    force: false,
    width: 15,
    gap: 10 // treatment of missing values in phe-by-gen panel (handle=T/F, force=T/F, width, gap)
  };
  tipdirection = (ref45 = chartOpts != null ? chartOpts.tipdirection : void 0) != null ? ref45 : null; // direction of tool tips (east/west/north/south)
  // chartOpts end
  chartdivid = (ref46 = chartOpts != null ? chartOpts.chartdivid : void 0) != null ? ref46 : 'chart';
  widgetdivid = d3.select(widgetdiv).attr('id');
  // make sure list args have all necessary bits
  margin = d3panels.check_listarg_v_default(margin, {
    left: 60,
    top: 40,
    right: 40,
    bottom: 40,
    inner: 5
  });
  lod_axispos = d3panels.check_listarg_v_default(lod_axispos, {
    xtitle: 25,
    ytitle: 30,
    xlabel: 5,
    ylabel: 5
  });
  eff_axispos = d3panels.check_listarg_v_default(eff_axispos, {
    xtitle: 25,
    ytitle: 30,
    xlabel: 5,
    ylabel: 5
  });
  eff_yNA = d3panels.check_listarg_v_default(eff_yNA, {
    handle: true,
    force: false,
    width: 15,
    gap: 10
  });
  wright = width - wleft;
  mylodchart = d3panels.lodchart({
    height: height,
    width: wleft,
    margin: margin,
    axispos: lod_axispos,
    titlepos: lod_titlepos,
    chrGap: chrGap,
    altrectcolor: altrectcolor,
    rectcolor: rectcolor,
    ylim: lod_ylim,
    nyticks: lod_nyticks,
    yticks: lod_yticks,
    linecolor: lod_linecolor,
    linewidth: lod_linewidth,
    pointcolor: lod_pointcolor,
    pointsize: lod_pointsize,
    pointstroke: lod_pointstroke,
    title: lod_title,
    xlab: lod_xlab,
    ylab: lod_ylab,
    rotate_ylab: lod_rotate_ylab,
    tipdirection: tipdirection,
    tipclass: widgetdivid
  });
  svg = d3.select(widgetdiv).select("svg");
  g_lod = svg.append("g").attr("id", "lodchart");
  mylodchart(g_lod, lod_data);
  mypxgchart = null;
  plotPXG = function(markername, markerindex) {
    var chr, chrtype, dpos, force, g, g_pxg, gabs, genonames, inferred, point_jitter, points, pos1, ref47, scaledPoints, xscale;
    g = pxg_data.geno[markerindex];
    gabs = (function() {
      var j, len, results;
      results = [];
      for (j = 0, len = g.length; j < len; j++) {
        x = g[j];
        results.push(Math.abs(x));
      }
      return results;
    })();
    inferred = (function() {
      var j, len, results;
      results = [];
      for (j = 0, len = g.length; j < len; j++) {
        x = g[j];
        results.push(x < 0);
      }
      return results;
    })();
    chr = pxg_data.chrByMarkers[markername];
    chrtype = pxg_data.chrtype[chr];
    genonames = pxg_data.genonames[chrtype];
    if (cur_chr !== chr) { // changing chromosome
      if (mypxgchart != null) {
        // remove and re-create panel
        mypxgchart.remove();
      }
      mypxgchart = d3panels.dotchart({
        height: height,
        width: wright,
        margin: margin,
        xcategories: (function() {
          var results = [];
          for (var j = 1, ref47 = genonames.length; 1 <= ref47 ? j <= ref47 : j >= ref47; 1 <= ref47 ? j++ : j--){ results.push(j); }
          return results;
        }).apply(this),
        xcatlabels: genonames,
        dataByInd: false,
        title: markername,
        axispos: eff_axispos,
        titlepos: eff_titlepos,
        xlab: eff_xlab,
        ylab: eff_ylab,
        rotate_ylab: eff_rotate_ylab,
        ylim: eff_ylim,
        nyticks: eff_nyticks,
        yticks: eff_yticks,
        pointcolor: eff_pointcolor,
        pointstroke: eff_pointstroke,
        pointsize: eff_pointsize,
        rectcolor: rectcolor,
        xjitter: xjitter,
        yNA: eff_yNA,
        tipdirection: tipdirection,
        tipclass: widgetdivid
      });
      g_pxg = svg.append("g").attr("id", "pxgchart").attr("transform", `translate(${wleft},0)`);
      mypxgchart(g_pxg, {
        x: gabs,
        y: pxg_data.pheno,
        indID: pxg_data.indID
      });
      // re-color points
      mypxgchart.points().attr("fill", function(d, i) {
        if (inferred[i]) {
          return eff_pointcolorhilit;
        }
        return eff_pointcolor; // same chromosome; animate points
      });
    } else {
      // grab scale and get info to take inverse
      xscale = mypxgchart.xscale();
      pos1 = xscale(1);
      dpos = xscale(2) - xscale(1);
      point_jitter = function(d) {
        var u;
        u = (d - pos1) / dpos;
        return u - Math.round(u);
      };
      // move points to new x-axis position
      points = mypxgchart.points().transition().duration(1000).attr("cx", function(d, i) {
        var cx, u;
        cx = d3.select(this).attr("cx");
        u = point_jitter(cx);
        return xscale(gabs[i] + u);
      }).attr("fill", function(d, i) {
        if (inferred[i]) {
          return eff_pointcolorhilit;
        }
        return eff_pointcolor;
      });
      // use force to move them apart again
      scaledPoints = [];
      points.each(function(d, i) {
        return scaledPoints.push({
          x: +d3.select(this).attr("cx"),
          y: +d3.select(this).attr("cy"),
          fy: +d3.select(this).attr("cy"),
          truex: xscale(gabs[i])
        });
      });
      force = d3.forceSimulation(scaledPoints).force("x", d3.forceX(function(d) {
        return d.truex;
      })).force("collide", d3.forceCollide(eff_pointsize * 1.1)).stop();
      (function() {
        var results = [];
        for (var j = 0; j <= 30; j++){ results.push(j); }
        return results;
      }).apply(this).map(function(d) {
        force.tick();
        return points.attr("cx", function(d, i) {
          return scaledPoints[i].x;
        });
      });
    }
    return cur_chr = chr;
  };
  // animate points at markers on click
  objects = mylodchart.markerSelect().on("click", function(event, d) {
    var i;
    i = objects.nodes().indexOf(this);
    return plotPXG(markers[i], i);
  });
  if (chartOpts.heading != null) {
    d3.select("div#htmlwidget_container").insert("h2", ":first-child").html(chartOpts.heading).style("font-family", "sans-serif");
  }
  if (chartOpts.caption != null) {
    d3.select("body").append("p").attr("class", "caption").html(chartOpts.caption);
  }
  if (chartOpts.footer != null) {
    return d3.select("body").append("div").html(chartOpts.footer).style("font-family", "sans-serif");
  }
};
