Difference between revisions of "Template:Genspace"

Line 144: Line 144:
 
     <script>
 
     <script>
 
      
 
      
 +
    (function() {
 +
           
 +
        function jetpack(d3) {
 +
            d3.selection.prototype.translate = function(xy) {
 +
                return this.attr('transform', function(d,i) {
 +
                    return 'translate('+[typeof xy == 'function' ? xy(d,i) : xy]+')';
 +
                });
 +
            };
 +
 +
            d3.transition.prototype.translate = function(xy) {
 +
                return this.attr('transform', function(d,i) {
 +
                    return 'translate('+[typeof xy == 'function' ? xy(d,i) : xy]+')';
 +
                });
 +
            };
 +
 +
            d3.selection.prototype.tspans = function(lines, lh) {
 +
                return this.selectAll('tspan')
 +
                    .data(lines)
 +
                    .enter()
 +
                    .append('tspan')
 +
                    .text(function(d) { return d; })
 +
                    .attr('x', 0)
 +
                    .attr('dy', function(d,i) { return i ? lh || 15 : 0; });
 +
            };
 +
 +
            d3.selection.prototype.append =
 +
            d3.selection.enter.prototype.append = function(name) {
 +
                var n = d3_parse_attributes(name), s;
 +
                //console.log(name, n);
 +
                name = n.attr ? n.tag : name;
 +
                name = d3_selection_creator(name);
 +
                s = this.select(function() {
 +
                    return this.appendChild(name.apply(this, arguments));
 +
                });
 +
                return n.attr ? s.attr(n.attr) : s;
 +
            };
 +
 +
            d3.selection.prototype.insert =
 +
            d3.selection.enter.prototype.insert = function(name, before) {
 +
                var n = d3_parse_attributes(name), s;
 +
                name = n.attr ? n.tag : name;
 +
                name = d3_selection_creator(name);
 +
                before = d3_selection_selector(before);
 +
                s = this.select(function() {
 +
                    return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null);
 +
                });
 +
                return n.attr ? s.attr(n.attr) : s;
 +
            };
 +
 +
            var d3_parse_attributes_regex = /([\.#])/g;
 +
 +
            function d3_parse_attributes(name) {
 +
                if (typeof name === "string") {
 +
                    var attr = {},
 +
                        parts = name.split(d3_parse_attributes_regex), p;
 +
                        name = parts.shift();
 +
                    while ((p = parts.shift())) {
 +
                        if (p == '.') attr['class'] = attr['class'] ? attr['class'] + ' ' + parts.shift() : parts.shift();
 +
                        else if (p == '#') attr.id = parts.shift();
 +
                    }
 +
                    return attr.id || attr['class'] ? { tag: name, attr: attr } : name;
 +
                }
 +
                return name;
 +
            }
 +
 +
            function d3_selection_creator(name) {
 +
                return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? function() {
 +
                    return this.ownerDocument.createElementNS(name.space, name.local);
 +
                } : function() {
 +
                    return this.ownerDocument.createElementNS(this.namespaceURI, name);
 +
                };
 +
            }
 +
 +
            function d3_selection_selector(selector) {
 +
                return typeof selector === "function" ? selector : function() {
 +
                    return this.querySelector(selector);
 +
                };
 +
            }
 +
 +
            d3.wordwrap = function(line, maxCharactersPerLine) {
 +
                var w = line.split(' '),
 +
                    lines = [],
 +
                    words = [],
 +
                    maxChars = maxCharactersPerLine || 40,
 +
                    l = 0;
 +
                w.forEach(function(d) {
 +
                    if (l+d.length > maxChars) {
 +
                        lines.push(words.join(' '));
 +
                        words.length = 0;
 +
                        l = 0;
 +
                    }
 +
                    l += d.length;
 +
                    words.push(d);
 +
                });
 +
                if (words.length) {
 +
                    lines.push(words.join(' '));
 +
                }
 +
                return lines;
 +
            };
 +
           
 +
            d3.ascendingKey = function(key) {
 +
                return typeof key == 'function' ? function (a, b) {
 +
                      return key(a) < key(b) ? -1 : key(a) > key(b) ? 1 : key(a) >= key(b) ? 0 : NaN;
 +
                } : function (a, b) {
 +
                      return a[key] < b[key] ? -1 : a[key] > b[key] ? 1 : a[key] >= b[key] ? 0 : NaN;
 +
                };
 +
            };
 +
 +
            d3.descendingKey = function(key) {
 +
                return typeof key == 'function' ? function (a, b) {
 +
                    return key(b) < key(a) ? -1 : key(b) > key(a) ? 1 : key(b) >= key(a) ? 0 : NaN;
 +
                } : function (a, b) {
 +
                    return b[key] < a[key] ? -1 : b[key] > a[key] ? 1 : b[key] >= a[key] ? 0 : NaN;
 +
                };
 +
            };
 +
           
 +
            d3.f = function(){
 +
                var functions = arguments;
 +
                //convert all string arguments into field accessors
 +
                var i = 0, l = functions.length;
 +
                while (i < l) {
 +
                    if (typeof(functions[i]) === 'string' || typeof(functions[i]) === 'number'){
 +
                        functions[i] = (function(str){ return function(d){ return d[str] }; })(functions[i])
 +
                    }
 +
                    i++;
 +
                }
 +
                //return composition of functions
 +
                return function(d) {
 +
                    var i=0, l = functions.length;
 +
                    while (i++ < l) d = functions[i-1].call(this, d);
 +
                    return d;
 +
                };
 +
            };
 +
            // store d3.f as convenient unicode character function (alt-f on macs)
 +
            if (!window.hasOwnProperty('ƒ')) window.ƒ = d3.f;
 +
           
 +
            // this tweak allows setting a listener for multiple events, jquery style
 +
            var d3_selection_on = d3.selection.prototype.on;
 +
            d3.selection.prototype.on = function(type, listener, capture) {
 +
                if (typeof type == 'string' && type.indexOf(' ') > -1) {
 +
                    type = type.split(' ');
 +
                    for (var i = 0; i<type.length; i++) {
 +
                        d3_selection_on.apply(this, [type[i], listener, capture]);
 +
                    }
 +
                } else {
 +
                    d3_selection_on.apply(this, [type, listener, capture]);
 +
                }
 +
                return this;
 +
            };
 +
           
 +
            // for heaven's sake, let's add prop as alias for property
 +
            d3.selection.prototype.prop = d3.selection.prototype.property;
 +
        }
 +
 +
        if (typeof d3 === 'object' && d3.version) jetpack(d3);
 +
        else if (typeof define === 'function' && define.amd) {
 +
            define(['d3'], jetpack);
 +
        }
 +
 +
    })();
 +
 +
    function graphScroll() {
 +
      var windowHeight,
 +
          dispatch = d3.dispatch("scroll", "active", "fixed", "above", "below"),
 +
          sections = d3.select('null'),
 +
          i = -1,
 +
          sectionPos = [],
 +
          n,
 +
          graph = d3.select('null'),
 +
          isFixed = null,
 +
          isBelow = null,
 +
          isAbove = null,
 +
          container = d3.select('body'),
 +
          containerStart = 0,
 +
          belowStart,
 +
          eventId = Math.random(),
 +
          stickyTop
 +
 +
      function reposition(){
 +
        var i1 = 0
 +
        sectionPos.forEach(function(d, i){
 +
          if (d < pageYOffset - containerStart + 180) i1 = i
 +
        })
 +
        i1 = Math.min(n - 1, i1)
 +
        if (i != i1){
 +
          sections.classed('graph-scroll-active', function(d, i){ return i === i1 })
 +
 +
          dispatch.active(i1, i)
 +
 +
          i = i1
 +
        }
 +
 +
        var isAbove1 = pageYOffset < containerStart
 +
        if (isAbove != isAbove1){
 +
          isAbove = isAbove1
 +
          graph.classed('graph-scroll-above', isAbove)
 +
          if(isAbove) dispatch.above(i1)
 +
        }
 +
        var isBelow1 = pageYOffset > belowStart
 +
        if (isBelow != isBelow1){
 +
          isBelow = isBelow1
 +
          graph.classed('graph-scroll-below', isBelow)
 +
          if(isBelow) dispatch.below(i1)
 +
        }
 +
        var isFixed1 = !isBelow && pageYOffset > containerStart+stickyTop
 +
        if (isFixed != isFixed1){
 +
          isFixed = isFixed1
 +
          graph.classed('graph-scroll-fixed', isFixed)
 +
          if(isFixed) dispatch.fixed(i1)
 +
        }
 +
 +
        if (stickyTop){
 +
          graph.style('padding-top', (isBelow || isFixed ? stickyTop : 0)+ 'px')
 +
        }
 +
      }
 +
 +
      function resize(){
 +
        sectionPos = []
 +
        var startPos
 +
        sections.each(function(d, i){
 +
          if (!i) startPos = this.getBoundingClientRect().top
 +
          sectionPos.push(this.getBoundingClientRect().top -  startPos) })
 +
 +
        var containerBB = container.node().getBoundingClientRect()
 +
        var graphBB = graph.node().getBoundingClientRect()
 +
 +
        containerStart = containerBB.top + pageYOffset
 +
        belowStart = containerBB.bottom - graphBB.height  + pageYOffset
 +
      }
 +
 +
      function keydown() {
 +
        if (!isFixed) return
 +
        var delta
 +
        switch (d3.event.keyCode) {
 +
          case 39: // right arrow
 +
          if (d3.event.metaKey) return
 +
          case 40: // down arrow
 +
          case 34: // page down
 +
          delta = d3.event.metaKey ? Infinity : 1 ;break
 +
          case 37: // left arrow
 +
          if (d3.event.metaKey) return
 +
          case 38: // up arrow
 +
          case 33: // page up
 +
          delta = d3.event.metaKey ? -Infinity : -1 ;break
 +
          case 32: // space
 +
          delta = d3.event.shiftKey ? -1 : 1
 +
          ;break
 +
          default: return
 +
        }
 +
 +
        var i1 = Math.max(0, Math.min(i + delta, n - 1))
 +
        rv.scrollTo(i1)
 +
 +
        d3.event.preventDefault()
 +
      }
 +
 +
 +
      var rv ={}
 +
 +
      rv.scrollTo = function(_x){
 +
        if (isNaN(_x)) return rv
 +
 +
        d3.select(document.documentElement)
 +
            .interrupt()
 +
          .transition()
 +
            .duration(500)
 +
            .tween("scroll", function() {
 +
              var i = d3.interpolateNumber(pageYOffset, sectionPos[_x] + containerStart+(stickyTop?-stickyTop:0))
 +
              return function(t) { scrollTo(0, i(t)) }
 +
            })
 +
        return rv
 +
      }
 +
 +
 +
      rv.container = function(_x){
 +
        if (!_x) return container
 +
 +
        container = _x
 +
        return rv
 +
      }
 +
 +
      rv.graph = function(_x){
 +
        if (!_x) return graph
 +
 +
        graph = _x
 +
        return rv
 +
      }
 +
 +
      rv.eventId = function(_x){
 +
        if (!_x) return eventId
 +
 +
        eventId = _x
 +
        return rv
 +
      }
 +
 +
      rv.stickyTop = function(_x){
 +
        if (!_x) return stickyTop
 +
 +
        stickyTop = _x
 +
        return rv
 +
      }
 +
 +
      rv.sections = function (_x){
 +
        if (!_x) return sections
 +
 +
        sections = _x
 +
        n = sections.size()
 +
 +
        d3.select(window)
 +
            .on('scroll.gscroll'  + eventId, reposition)
 +
            .on('resize.gscroll'  + eventId, resize)
 +
            .on('keydown.gscroll' + eventId, keydown)
 +
 +
        resize()
 +
        d3.timer(function() {
 +
          reposition()
 +
          return true
 +
        })
 +
 +
        return rv
 +
      }
 +
 +
      d3.rebind(rv, dispatch, "on")
 +
 +
      return rv
 +
    }
 +
 +
    d3.selectAll('.dropdown')
 +
      .on('mouseover',function(){ this.classList.add('expand') })
 +
      .on('mouseout',function(){ this.classList.remove('expand') })
 +
 +
    var map = d3.select('#map')
 +
    var img = d3.select('#mapimg')
 +
    var content = d3.select('#content')
 +
    size()
 +
    function size () {
 +
      img.style({
 +
        width:window.innerWidth+'px',
 +
      })
 +
      // content.style({
 +
      //  height:img.node().getBoundingClientRect().height,
 +
      // })
 +
    }
 +
 +
    d3.select(window).on('resize.index',size)
 +
 +
    d3.selectAll('video')
 +
      .on('click',function(){
 +
        console.log(this)
 +
          this.play()
 +
      })
 
     </script>
 
     </script>
 
      
 
      

Revision as of 15:37, 18 September 2015

<!DOCTYPE html> Gowanus SuperFUNd - Genspace iGEM 2015

The Gowanus Canal is a heavily polluted waterway that runs through Brooklyn NY. A designated superfund site, it is slated for cleanup but nearby residents are concerned about the results. Our team is developing a biosensor for waste pollution, giving the community real time access to data on the health of the canal. Additionally we have mined the canal for extremophiles with interesting properties.

Place sticky footer content here.