about summary refs log tree commit diff
path: root/wqflask/wqflask/static/new/javascript/scatterplot.coffee
diff options
context:
space:
mode:
Diffstat (limited to 'wqflask/wqflask/static/new/javascript/scatterplot.coffee')
-rw-r--r--wqflask/wqflask/static/new/javascript/scatterplot.coffee426
1 files changed, 426 insertions, 0 deletions
diff --git a/wqflask/wqflask/static/new/javascript/scatterplot.coffee b/wqflask/wqflask/static/new/javascript/scatterplot.coffee
new file mode 100644
index 00000000..2d809071
--- /dev/null
+++ b/wqflask/wqflask/static/new/javascript/scatterplot.coffee
@@ -0,0 +1,426 @@
+root = exports ? this

+

+scatterplot = () ->

+    width = 800

+    height = 600

+    margin = {left:60, top:40, right:40, bottom: 40, inner:5}

+    axispos = {xtitle:25, ytitle:45, xlabel:5, ylabel:5}

+    titlepos = 20

+    xNA = {handle:true, force:false, width:15, gap:10}

+    yNA = {handle:true, force:false, width:15, gap:10}

+    xlim = null

+    ylim = null

+    nxticks = 5

+    xticks = null

+    nyticks = 5

+    yticks = null

+    rectcolor = d3.rgb(230, 230, 230)

+    pointcolor = null

+    pointstroke = "black"

+    pointsize = 3 # default = no visible points at markers

+    title = "Correlation Scatterplot"

+    xlab = "X"

+    ylab = "Y"

+    rotate_ylab = null

+    yscale = d3.scale.linear()

+    xscale = d3.scale.linear()

+    xvar = 0

+    yvar = 1

+    pointsSelect = null

+    dataByInd = false

+  

+    ## the main function

+    chart = (selection) ->

+      selection.each (data) ->

+  

+        if dataByInd

+          x = data.data.map (d) -> d[xvar]

+          y = data.data.map (d) -> d[yvar]

+        else # reorganize data

+          x = data.data[xvar]

+          y = data.data[yvar]

+  

+        console.log("x:", x)

+        console.log("y:", y)

+  

+        # grab indID if it's there

+        # if no indID, create a vector of them

+        indID = data?.indID ? null

+        indID = indID ? [1..x.length]

+  

+        console.log("indID:", indID)

+  

+        # groups of colors

+        group = data?.group ? (1 for i in x)

+        ngroup = d3.max(group)

+        group = (g-1 for g in group) # changed from (1,2,3,...) to (0,1,2,...)

+  

+        # colors of the points in the different groups

+        pointcolor = pointcolor ? selectGroupColors(ngroup, "dark")

+        pointcolor = expand2vector(pointcolor, ngroup)

+  

+        # if all (x,y) not null

+        xNA.handle = false if x.every (v) -> (v?) and !xNA.force

+        yNA.handle = false if y.every (v) -> (v?) and !yNA.force

+        if xNA.handle

+          paneloffset = xNA.width + xNA.gap

+          panelwidth = width - paneloffset

+        else

+          paneloffset = 0

+          panelwidth = width

+        if yNA.handle

+          panelheight = height - (yNA.width + yNA.gap)

+        else

+          panelheight = height

+  

+        xlim = xlim ? d3.extent(x)

+        ylim = ylim ? d3.extent(y)

+  

+        # I'll replace missing values something smaller than what's observed

+        na_value = d3.min(x.concat y) - 100

+  

+        # Select the svg element, if it exists.

+        svg = d3.select(this).selectAll("svg").data([data])

+  

+        # Otherwise, create the skeletal chart.

+        gEnter = svg.enter().append("svg").append("g")

+  

+        # Update the outer dimensions.

+        svg.attr("width", width+margin.left+margin.right)

+           .attr("height", height+margin.top+margin.bottom)

+  

+        g = svg.select("g")

+  

+        # box

+        g.append("rect")

+         .attr("x", paneloffset+margin.left)

+         .attr("y", margin.top)

+         .attr("height", panelheight)

+         .attr("width", panelwidth)

+         .attr("fill", rectcolor)

+         .attr("stroke", "none")

+        if xNA.handle

+          g.append("rect")

+           .attr("x", margin.left)

+           .attr("y", margin.top)

+           .attr("height", panelheight)

+           .attr("width", xNA.width)

+           .attr("fill", rectcolor)

+           .attr("stroke", "none")

+        if xNA.handle and yNA.handle

+          g.append("rect")

+           .attr("x", margin.left)

+           .attr("y", margin.top+height - yNA.width)

+           .attr("height", yNA.width)

+           .attr("width", xNA.width)

+           .attr("fill", rectcolor)

+           .attr("stroke", "none")

+        if yNA.handle

+          g.append("rect")

+           .attr("x", margin.left+paneloffset)

+           .attr("y", margin.top+height-yNA.width)

+           .attr("height", yNA.width)

+           .attr("width", panelwidth)

+           .attr("fill", rectcolor)

+           .attr("stroke", "none")

+  

+        # simple scales (ignore NA business)

+        xrange = [margin.left+paneloffset+margin.inner, margin.left+paneloffset+panelwidth-margin.inner]

+        yrange = [margin.top+panelheight-margin.inner, margin.top+margin.inner]

+        xscale.domain(xlim).range(xrange)

+        yscale.domain(ylim).range(yrange)

+        xs = d3.scale.linear().domain(xlim).range(xrange)

+        ys = d3.scale.linear().domain(ylim).range(yrange)

+  

+        # "polylinear" scales to handle missing values

+        if xNA.handle

+          xscale.domain([na_value].concat xlim) 

+                .range([margin.left + xNA.width/2].concat xrange)

+          x = x.map (e) -> if e? then e else na_value

+        if yNA.handle

+          yscale.domain([na_value].concat ylim)

+                .range([height+margin.top-yNA.width/2].concat yrange)

+          y = y.map (e) -> if e? then e else na_value

+  

+        # if yticks not provided, use nyticks to choose pretty ones

+        yticks = yticks ? ys.ticks(nyticks)

+        xticks = xticks ? xs.ticks(nxticks)

+  

+        # title

+        titlegrp = g.append("g").attr("class", "title")

+         .append("text")

+         .attr("x", margin.left + width/2)

+         .attr("y", margin.top - titlepos)

+         .text(title)

+  

+        # x-axis

+        xaxis = g.append("g").attr("class", "x axis")

+        xaxis.selectAll("empty")

+             .data(xticks)

+             .enter()

+             .append("line")

+             .attr("x1", (d) -> xscale(d))

+             .attr("x2", (d) -> xscale(d))

+             .attr("y1", margin.top)

+             .attr("y2", margin.top+height)

+             .attr("fill", "none")

+             .attr("stroke", "white")

+             .attr("stroke-width", 1)

+             .style("pointer-events", "none")

+        xaxis.selectAll("empty")

+             .data(xticks)

+             .enter()

+             .append("text")

+             .attr("x", (d) -> xscale(d))

+             .attr("y", margin.top+height+axispos.xlabel)

+             .text((d) -> formatAxis(xticks)(d))

+        xaxis.append("text").attr("class", "title")

+             .attr("x", margin.left+width/2)

+             .attr("y", margin.top+height+axispos.xtitle)

+             .text(xlab)

+        if xNA.handle

+          xaxis.append("text")

+              .attr("x", margin.left+xNA.width/2)

+              .attr("y", margin.top+height+axispos.xlabel)

+              .text("N/A")

+  

+        # y-axis

+        rotate_ylab = rotate_ylab ? (ylab.length > 1)

+        yaxis = g.append("g").attr("class", "y axis")

+        yaxis.selectAll("empty")

+             .data(yticks)

+             .enter()

+             .append("line")

+             .attr("y1", (d) -> yscale(d))

+             .attr("y2", (d) -> yscale(d))

+             .attr("x1", margin.left)

+             .attr("x2", margin.left+width)

+             .attr("fill", "none")

+             .attr("stroke", "white")

+             .attr("stroke-width", 1)

+             .style("pointer-events", "none")

+        yaxis.selectAll("empty")

+             .data(yticks)

+             .enter()

+             .append("text")

+             .attr("y", (d) -> yscale(d))

+             .attr("x", margin.left-axispos.ylabel)

+             .text((d) -> formatAxis(yticks)(d))

+        yaxis.append("text").attr("class", "title")

+             .attr("y", margin.top+height/2)

+             .attr("x", margin.left-axispos.ytitle)

+             .text(ylab)

+             .attr("transform", if rotate_ylab then "rotate(270,#{margin.left-axispos.ytitle},#{margin.top+height/2})" else "")

+        if yNA.handle

+          yaxis.append("text")

+              .attr("x", margin.left-axispos.ylabel)

+              .attr("y", margin.top+height-yNA.width/2)

+              .text("N/A")

+  

+        indtip = d3.tip()

+                   .attr('class', 'd3-tip')

+                   .html((d,i) -> indID[i])

+                   .direction('e')

+                   .offset([0,10])

+        svg.call(indtip)

+  

+        #g.append("line")

+        #        .attr("x1")

+        #

+        #g.append("line")

+        #  .attr("x1", xscale(minx))

+        #  .attr("x2", xscale(maxx*0.995))

+        #  .attr("y2", yscale(slope*maxx*0.995+intercept))

+        #  .style("stroke", "black")

+        #  .style("stroke-width", 2);

+  

+        points = g.append("g").attr("id", "points")

+        pointsSelect =

+          points.selectAll("empty")

+                .data(d3.range(x.length))

+                .enter()

+                .append("circle")

+                .attr("cx", (d,i) -> xscale(x[i]))

+                .attr("cy", (d,i) -> yscale(y[i]))

+                .attr("class", (d,i) -> "pt#{i}")

+                .attr("r", pointsize)

+                .attr("fill", (d,i) -> pointcolor[group[i]])

+                .attr("stroke", pointstroke)

+                .attr("stroke-width", "1")

+                .attr("opacity", (d,i) ->

+                     return 1 if (x[i]? or xNA.handle) and (y[i]? or yNA.handle)

+                     return 0)

+                .on("mouseover.paneltip", indtip.show)

+                .on("mouseout.paneltip", indtip.hide)

+  

+        # box

+        g.append("rect")

+               .attr("x", margin.left+paneloffset)

+               .attr("y", margin.top)

+               .attr("height", panelheight)

+               .attr("width", panelwidth)

+               .attr("fill", "none")

+               .attr("stroke", "black")

+               .attr("stroke-width", "none")

+        if xNA.handle

+          g.append("rect")

+           .attr("x", margin.left)

+           .attr("y", margin.top)

+           .attr("height", panelheight)

+           .attr("width", xNA.width)

+           .attr("fill", "none")

+           .attr("stroke", "black")

+           .attr("stroke-width", "none")

+        if xNA.handle and yNA.handle

+          g.append("rect")

+           .attr("x", margin.left)

+           .attr("y", margin.top+height - yNA.width)

+           .attr("height", yNA.width)

+           .attr("width", xNA.width)

+           .attr("fill", "none")

+           .attr("stroke", "black")

+           .attr("stroke-width", "none")

+        if yNA.handle

+          g.append("rect")

+           .attr("x", margin.left+paneloffset)

+           .attr("y", margin.top+height-yNA.width)

+           .attr("height", yNA.width)

+           .attr("width", panelwidth)

+           .attr("fill", "none")

+           .attr("stroke", "black")

+           .attr("stroke-width", "none")

+  

+    ## configuration parameters

+    chart.width = (value) ->

+      return width if !arguments.length

+      width = value

+      chart

+  

+    chart.height = (value) ->

+      return height if !arguments.length

+      height = value

+      chart

+  

+    chart.margin = (value) ->

+      return margin if !arguments.length

+      margin = value

+      chart

+  

+    chart.axispos = (value) ->

+      return axispos if !arguments.length

+      axispos = value

+      chart

+  

+    chart.titlepos = (value) ->

+      return titlepos if !arguments.length

+      titlepos

+      chart

+  

+    chart.xlim = (value) ->

+      return xlim if !arguments.length

+      xlim = value

+      chart

+  

+    chart.nxticks = (value) ->

+      return nxticks if !arguments.length

+      nxticks = value

+      chart

+  

+    chart.xticks = (value) ->

+      return xticks if !arguments.length

+      xticks = value

+      chart

+  

+    chart.ylim = (value) ->

+      return ylim if !arguments.length

+      ylim = value

+      chart

+  

+    chart.nyticks = (value) ->

+      return nyticks if !arguments.length

+      nyticks = value

+      chart

+  

+    chart.yticks = (value) ->

+      return yticks if !arguments.length

+      yticks = value

+      chart

+  

+    chart.rectcolor = (value) ->

+      return rectcolor if !arguments.length

+      rectcolor = value

+      chart

+  

+    chart.pointcolor = (value) ->

+      return pointcolor if !arguments.length

+      pointcolor = value

+      chart

+  

+    chart.pointsize = (value) ->

+      return pointsize if !arguments.length

+      pointsize = value

+      chart

+  

+    chart.pointstroke = (value) ->

+      return pointstroke if !arguments.length

+      pointstroke = value

+      chart

+  

+    chart.dataByInd = (value) ->

+      return dataByInd if !arguments.length

+      dataByInd = value

+      chart

+  

+    chart.title = (value) ->

+      return title if !arguments.length

+      title = value

+      chart

+  

+    chart.xlab = (value) ->

+      return xlab if !arguments.length

+      xlab = value

+      chart

+  

+    chart.ylab = (value) ->

+      return ylab if !arguments.length

+      ylab = value

+      chart

+  

+    chart.rotate_ylab = (value) ->

+      return rotate_ylab if !arguments.length

+      rotate_ylab = value

+      chart

+  

+    chart.xvar = (value) ->

+      return xvar if !arguments.length

+      xvar = value

+      chart

+  

+    chart.yvar = (value) ->

+      return yvar if !arguments.length

+      yvar = value

+      chart

+  

+    chart.xNA = (value) ->

+      return xNA if !arguments.length

+      xNA = value

+      chart

+  

+    chart.yNA = (value) ->

+      return yNA if !arguments.length

+      yNA = value

+      chart

+  

+    chart.yscale = () ->

+      return yscale

+  

+    chart.xscale = () ->

+      return xscale

+  

+    chart.pointsSelect = () ->

+      return pointsSelect

+  

+    # return the chart function

+    chart

+    

+root.scatterplot = scatterplot
\ No newline at end of file