var keys = [
  {
    "key":"Observed",
    "clabel":"Observed",
    "slug":"observed",
    "label":"What’s Really Warming the World?",
    "sub":"Skeptics of manmade climate change offer various natural causes to explain why the Earth has warmed 1.4 degrees Fahrenheit since 1880. But can these account for the planet’s rising temperature? Scroll down to see show how much different factors, both natural and industrial, contribute to global warming, based on findings from NASA’s Goddard Institute for Space Studies.",
    "short":"Observed",
    "class":"observed"
  },
  {
    "key":"Orbital changes",
    "clabel":"Orbital Changes",
    "slug":"orbital-changes",
    "label":"Is It the Earth’s Orbit?",
    "sub":"The Earth wobbles on its axis, and its tilt and orbit change over many thousands of years, pushing the climate into and out of ice ages. Yet the influence of orbital changes on the planet’s temperature over 125 years has been negligible.",
    "short":"Orbital changes",
    "class":"natural"
  },
  {
    "key":"Solar",
    "clabel":"Solar",
    "slug":"solar",
    "label":"Is It the Sun?",
    "sub":"The sun’s temperature varies over decades and centuries. These changes have had little effect on the Earth’s overall climate.",
    "short":"Solar",
    "class":"natural"
  },
  {
    "key":"Volcanic",
    "clabel":"Volcanic",
    "slug":"volcanic",
    "label":"Is It Volcanoes?",
    "sub":"The data suggest no. Human industry emits about 100 times more CO<sub>2</sub> than volcanic activity, and eruptions release sulfate chemicals that can actually cool the atmosphere for a year or two.",
    "short":"Volcanic",
    "class":"natural"
  },
  {
    "key":"Natural",
    "clabel":"Natural Factors",
    "slug":"natural",
    "label":"Is it All Three of These Things Combined?",
    "sub":"If it were, then the response to natural factors should match the observed temperature. Adding the natural factors together just doesn’t add up.",
    "short":"Natural",
    "class":"combined"
  },
  {
    "key":"Land use",
    "clabel":"Land Use",
    "slug":"land-use",
    "label":"So If It’s Not Nature, Is It Deforestation?",
    "sub":"Humans have cut, plowed, and paved more than half the Earth’s land surface. Dark forests are yielding to lighter patches, which reflect more sunlight—and have a slight cooling effect.",
    "short":"Land Use",
    "class":"human"
  },
  {
    "key":"Ozone",
    "clabel":"Ozone",
    "slug":"ozone",
    "label":"Or Ozone Pollution?",
    "sub":"Natural ozone high in the atmosphere blocks harmful sunlight and cools things slightly. Closer to Earth, ozone is created by pollution and traps heat, making the climate a little bit hotter. What’s the overall effect? Not much.",
    "short":"Ozone",
    "class":"human"
  },
  {
    "key":"Anthropogenic tropospheric aerosol",
    "clabel":"Aerosols",
    "slug":"anthropogenic-tropospheric-aerosol",
    "label":"Or Aerosol Pollution?",
    "sub":"Some pollutants cool the atmosphere, like sulfate aerosols from coal-burning. These aerosols offset some of the warming. (Unfortunately, they also cause acid rain.)",
    "short":"Aerosols",
    "class":"human"
  },
  {
    "key":"Greenhouse gases",
    "clabel":"Greenhouse Gases",
    "slug":"greenhouse-gases",
    "label":"No, It Really Is Greenhouse Gases.",
    "sub":"Atmospheric CO<sub>2</sub> levels are 40 percent higher than they were in 1750. The green line shows the influence of greenhouse gas emissions. It's no contest.",
    "short":"Greenhouse Gases",
    "class":"human"
  },
  {
    "key":"Human",
    "clabel":"Human Factors",
    "slug":"human",
    "label":"See for Yourself",
    "sub":"Greenhouse gases warm the atmosphere. Aerosols cool it a little bit. Ozone and land-use changes add and subtract a little. Together they match the observed temperature, particularly since 1950.",
    "short":"Human",
    "class":"combined"
  },
  {
    "key":"All forcings",
    "clabel":"All Factors",
    "slug":"all-forcings",
    "label":"Compare and Contrast",
    "sub":"Putting the possible natural and human causes of climate change alongside one another makes the dominant role of greenhouse gases even more plainly visible. The only real question is: What are we going to do about it?",
    "short":"All Forcings",
    "class":"all-forcings"
  }
]


var dispatch = d3.dispatch(
  'init',
  'voronoi',
  'tooltip',
  'lineover',
  'lineout',
  'mouseoverArea',
  'mouseoutArea',
  'scrubbing'
)

var byline = 'By Eric Roston '
    byline += '<a target="_blank" href="https://twitter.com/eroston" alt="@eroston"><img width="15" class="twitimg terminal" src="graphics/assets/img/twitter-byline.png"></a>'
    byline += 'and Blacki Migliozzi '
    byline += '<a target="_blank" href="https://twitter.com/blackili" alt="@blackili"><img width="15" class="twitimg terminal" src="graphics/assets/img/twitter-byline.png"></a>'
    byline += ' | June 24, 2015'


var graphic = d3.select("#graphic")
var sections = graphic.selectAll('.section')
  .data(keys).enter()
  .append('div.section.chart-label')
  .style('opacity',1)


var annotations

sections.append('div.label').html(ƒ('label'))
graphic.select('.section:first-child').append('div.timestamp').html(byline)
sections.append('div.sub-label').html(ƒ('sub'))


var mGraphic = d3.select("#mobile")
var mSections = mGraphic.selectAll('.section')
  .data(keys).enter()
  .append('div.section.chart-label')

mSections.append('div.label').html(ƒ('label'))
mGraphic.select('.section:first-child').append('div.timestamp').html(byline)
mSections.append('div.sub-label').html(ƒ('sub'))
mSections.append('img.mobile-img').attr('src',function(d) {return 'img/'+d.slug+'.png'})

graphic.append('div#chart').append('div.steps')

var body = d3.select("body")
var ttBottom = body.append('div.tooltip')
var ttTop = body.append('div.tooltip')
d3.select('.tooltip').html('')

var tooltip = body.append('div')
  .attr('class', 'tooltip ')

var param = getJsonFromUrl()

if(param.terminal){
  d3.selectAll('.t-link').attr('href','').attr('target','')
}

function getChartSize() {
  var w,h
  if(window.innerWidth>1280){
    w = 1*parseInt(graphic.style('width'))
    h = .7*parseInt(w*7/9)
  }else if(window.innerWidth<1281){
    w = .95*parseInt(graphic.style('width'))
    h = .7*parseInt(w*6/9)
  }else{
    w = 1*parseInt(graphic.style('width'))
    h = .7*parseInt(w*7/9)
  }
  return  [w,h]
}

d3.select("#show-voronoi")
  .property("disabled", false)
  .on("change",function(d) {
    dispatch.voronoi(this.checked)
  })

var chartWidth = getChartSize()[0]
var chartHeight = getChartSize()[1]


var mobile = window.innerWidth < 768 ? true:false
var chart
var y
var x
var gs
var nasaData = []
var currentData = []
var currentIndex = 0
var lastIndex = 0
var opacD = .2
var opacF = .7
var areaOpacity = .3
var ignoreScroll = false
var pils
var forceTypes
var bottomRatio = window.innerWidth>1200?1.2:1.4
var introDuration = 1500

var area = d3.svg.area()
    .x(function(d) { return chart.x()(d.key); })
    .y0(function(d) { return chart.y()(d.minus); })
    .y1(function(d) {
      return chart.y()(d.plus);
    });

var svg = d3.select("#map svg").html('')

queue()
    .defer(function(done) {
      d3.csv("data/forcings.csv", function(error, data) {
        data.forEach(function(d){
          Object.keys(d).forEach(function(k){
            d[k] = (k=='Year')?parseInt(d[k]):parseFloat(d[k])
          })
        })
        done(error, data)
      })
    })
    .defer(function(done) {
      d3.csv("data/observed.csv", function(error, data) {
        data.forEach(function(d){
          Object.keys(d).forEach(function(k){
            d[k] = (k=='Year')?parseInt(d[k]):parseFloat(d[k])
          })
        })
        done(error, data)
      })
    })
    .await(ready);

function ready(error,f,observed) {
  f=f.filter(function(y){return y.Year>=1880})

  oBaseline = d3.mean(observed.filter(function(y){return parseInt(y.Year)>=1880 && parseInt(y.Year)<= 1910}).map(ƒ('Annual_Mean')))
  mBaseline = kToC(d3.mean(f.filter(function(y){return parseInt(y.Year)>=1880 && parseInt(y.Year)<= 1910}).map(ƒ('All forcings'))))

  var humanKeys = keys.filter(function(d){return d.class=='human'}).map(ƒ('key'))
  var naturalKeys = keys.filter(function(d){return d.class=='natural'}).map(ƒ('key'))

  // 2 standard deviations in Celsius
  var env = 1.96*.14

  _.each(keys,function(l,i){
    var d
    if(l.key=='Observed'){
      var line = observed.map(function(d){return {key: time.parse(''+d.Year), value: cToF((d.Annual_Mean)-oBaseline)}})
      d = _.extend(l,{values:line,color:'#000'})
    }else{
      var line = f.map(function(d){return {
        key: time.parse(''+d.Year),
        value: cToF(kToC(d[l.key])-mBaseline),
        plus: cToF(env+kToC(d[l.key])-mBaseline),
        minus: cToF(-env+kToC(d[l.key])-mBaseline)
      }})
      d = _.extend(l,{values:line,color:color(i)})
    }
    nasaData.push(d)
  })

  chart = new Multiline('#chart','force-chart',nasaData, chartWidth,chartHeight)
  var diff = chart.el().select('.diff')
  var diffExtent = collectionRangeExtent(nasaData)
  var diffScale = d3.scale.quantize().domain([0,diffExtent[1]-diffExtent[0]]).range([.3,.6,.8,.95])
  annotations =chart.el().select('.annotations')

  diff.append('line')
    .attr({
      x1:0,
      y1:chartHeight,
      x2:0,
      y2:0,
    })

  chart.animate(0,0)
  d3.selectAll('#chart').style({
    'height':chartHeight+'px'
  })

  pathSpeed = 3500
  var top = .5

  var circles = d3.select('.steps').selectAll('.step').data(d3.range(sections.size())).enter()
    .append('div')
    .classed('step bg g4 op',true)
    .style('top', function(i) {
      return i*20 +'px'
    })

  d3.selectAll('.foot').style('opacity',0)
    .on('mouseover',function() {
      d3.select(this).style('opacity',.5)
    })
    .on('mouseout',function() {
      d3.select(this).style('opacity',1)
    })
    .on('click',function() {
      gs.scrollTo(currentIndex+1)
    })
  d3.select('.section:nth-child('+(sections.size())+')')
    .style('padding-bottom',bottomRatio*chartHeight+'px')


  var combineTimer, afterTimer, scrollTimer
  var steps = [
    function(k) {
      clearTimeout(combineTimer)
      clearTimeout(afterTimer)
      var currentkeys = ['Observed'].concat(keys.filter(function(d){return d.key==k}).map(ƒ('key')))
      currentData = nasaData.filter(function(d){return currentkeys.indexOf(d.key)>-1})
      chart.data(currentData)
      reset()

      d3.selectAll('.'+toSlug(k)+' .color-line').style({
        'stroke-opacity':.7
      })
      .each(function(d){
        chart.animate(0,0,'.lineG.'+toSlug(d.key))
        if(currentIndex!=0) chart.animate(135,0,'.lineG.'+toSlug('Observed'))
      })

      var els = d3.selectAll('.'+toSlug(k)+'')
      els
        .each(function(d,i){
          setTimeout(function() {
            if(currentIndex!=0) {
              d3.selectAll('.moving.text')
                .style('top',function(d) {
                  return chart.y()(0)+35+'px'
                })
                .style('left',function(d) {
                  return chart.x()(d.values[0].key)+60+'px'
                })
              d3.selectAll('.moving.observed.text')
                .style('opacity',1)
                .style('top',function(d) {
                  return chart.y()(d.values[d.values.length-1].value)+35+'px'
                })
                .style('left',function(d) {
                  return chart.x()(d.values[d.values.length-1].key)+60+'px'
                })

              chart.animate(135,pathSpeed,'.lineG.'+toSlug(d.key))
              d3.selectAll('.moving.'+toSlug(d.key)+' text').style('opacity',1)
            }else{
              setTimeout(function() {
                chart.animate(135,pathSpeed,'.lineG.'+toSlug(d.key))
                d3.selectAll('.moving.'+toSlug(d.key)+' text').style('opacity',1)
              },introDuration*1.5)
            }

            d3.selectAll('path.plus').style('opacity',0)
            if(currentIndex!=0){
              d3.select('path.plus-'+d.slug).style('opacity',areaOpacity)
            }
            chart.el().classed('hoverable',true)
          }, i * pathSpeed/8)
        })
      if(k=='All forcings'){
        combineTimer = setTimeout(function(){
          attachPils()
          d3.selectAll('.pils').classed('col-2',true)
          showPils(k)
        },pathSpeed)
      }
    },
    function(k) {
      clearTimeout(combineTimer)
      clearTimeout(afterTimer)

      var currentkeys = ['Observed'].concat(keys.filter(function(d){return d.class==k}).map(ƒ('key')))
      currentData = nasaData.filter(function(d){return currentkeys.indexOf(d.key)>-1})
      chart.data(currentData)
      reset()
      chart.el().classed('hoverable',false)

      d3.selectAll('.'+toSlug(k)+' .color-line').style({
        'stroke-opacity':.4
      })
      .each(function(d){
        if(d.slug != 'observed') chart.animate(0,0,'.lineG.'+toSlug(d.key))
        if(currentIndex!=0) {
          d3.selectAll('.moving.'+toSlug(d.key)+' text').style('opacity',1)
          chart.animate(135,0,'.lineG.'+toSlug('Observed'))
        }
      })

      var els = d3.selectAll('.'+toSlug(k)+'')
      els
        .each(function(d,i){
          setTimeout(function() {
            chart.animate(135,pathSpeed,'.lineG.'+toSlug(d.key))
            d3.selectAll('.moving.'+toSlug(d.key)+' text').style('opacity',1)

          }, i * pathSpeed/8)
        })


      var newData = nasaData.filter(function(d){return d.slug==k})[0]
      chart.addPatterns([newData])

      combineTimer = setTimeout(function(){
        els
          .selectAll('path')
          .data(d3.range(els.size()).map(function(){return newData}))
          .transition().duration(500)
          .ease('linear')
          .attr("d", function(d,i) {
              d.line = this;
              var line = chart.line()
              d.short = d.class
              return line(d.values)
          })
          .each('end',function(d,i){
            chart.updateVoronoi([nasaData[0]].concat(_.clone(newData)))
          })
          .call(function() {
            afterTimer = setTimeout(function() {
              currentkeys = ['Observed',newData.key]
              currentData = nasaData.filter(function(d){return currentkeys.indexOf(d.key)>-1})
              chart.data(currentData)

              currentData.forEach(function(d) {
                var years = d.slug=='observed' ? 135 : 125
                chart.animate(years,0,'.lineG.'+toSlug(d.key))
              })

              d3.selectAll('.moving.text').style('opacity',1)
                .style('top',function(d) {
                  var y = d.slug=='observed'?d.values[d.values.length-1].value:newData.values[newData.values.length-1].value
                  return chart.y()(y)+35+'px'
                })
                .style('left',function(d) {
                  // debugger
                  var x = d.slug=='observed'?d.values[d.values.length-1].key:newData.values[newData.values.length-1].key
                  return chart.x()(x)+60+'px'
                })

              uncertaintyBands(newData.slug)
              d3.selectAll('path.plus-'+newData.slug).transition().duration(500).style('opacity',areaOpacity)
              chart.el().select('.chart-container .year-label').text('1880-2005')
              chart.el().classed('hoverable',true)
              chart.isAnimating(false)
              d3.selectAll('.diff').style('opacity',0)
              d3.selectAll('.key .uncertainty').style('opacity',1)

              attachPils()
              d3.selectAll('.pils').classed('col-2',false)
              showPils(k)
            },800)
          })

          d3.selectAll('.moving.text')
            .style('opacity',function(d) {return d.slug=='observed'?1:0})
            .transition().duration(500)
            .ease('linear')
            .style('top',function(d) {
              var y = d.slug=='observed'?d.values[d.values.length-1].value:newData.values[newData.values.length-1].value
              return chart.y()(y)+35+'px'
            })
            .each('end',function(d,i){
              if(d.slug=='observed'){
                d3.select(this).style('opacity',1)
              }else{
                d3.select('.moving.'+newData.slug+'.text').style('opacity',1)
                  .text(newData.clabel)
              }
            })
            .call(function() {
              uncertaintyBands(newData.slug)
              d3.selectAll('path.plus-'+newData.slug).transition().duration(500).style('opacity',areaOpacity)
            })

        d3.selectAll('.plus')
          .data(d3.range(els.size()).map(function(){return newData}))
          .transition().duration(500)
          .ease('linear')
          .attr('d', function(d,i){
            return area(newData.values)
          })


      },pathSpeed+1400)
    },
  ];

  function attachPils() {
    d3.select('.pils').remove()

    pils = d3.select('.chart-container')
      .append('div.pils')

    forceTypes = pils.selectAll('div.type')
      .data(['natural','human']).enter()
      .append('div')
      .attr('class',function(d) {return d + ' type'})

    forceTypes.append('p.text.pil-label.cl.g2')
      .text(function(d) {return d=='natural'?'Natural factors':'Human factors'})

    var forcePils = forceTypes.selectAll('div')
      .data(function(k) {return nasaData.filter(function(d) {return d.class == k})}).enter()
      .append('div')
      .attr('class',function(d){return d.slug + ' text pil'})
      .classed('opM',true)
      .style('background',ƒ('color'))
      .append('p').text(ƒ('clabel'))
        .classed('c w',true)

    forcePils.on('mouseover',function(d) {
      d3.selectAll('.type .pil').style('opacity',function(p) {return (p.slug==d.slug)?1:.4})
      if(chart.data().map(ƒ('slug')).indexOf(d.slug)<0){
        chart.el().select('g.line').append('g.lineG.hover-path.'+d.slug).append('path.color-line')
          .attr('d',chart.line()(d.values))
          .attr('stroke',d.color)
          .datum(d)
        // debugger
        d3.select('.labels').append('div.text.moving.opM.hover-path.'+d.slug)
          .style({
            'background':d.color,
            'left':parseInt(chart.x()(d.values[d.values.length-1].key))+60+'px',
            'top':chart.y()(d.values[d.values.length-1].value)+35+'px',
            'opacity':1
          })
          .append('p').text(d.clabel)
            .classed('c w',true)

        uncertaintyBands(d.slug)
        chart.el().select('.plus.plus-'+d.slug).style('opacity',1)
        chart.el().select('.plus.plus-'+d.slug).node().parentElement.classList.add('hover-path')
      }

    })
    .on('mouseout', function(d) {
      d3.selectAll('.type .pil').style('opacity',1)
      d3.selectAll('.hover-path').transition().duration(200).style('opacity',0)
        .call(function() {d3.select(this).remove()})
    })

  }
  function showPils (k) {
    d3.select('.type.'+k).style('display','block')

    d3.select('.pils')
      .style({
        opacity:0
      })
      .transition()
      .duration(200)
      .ease('linear')
      .style({
        opacity:1
      })

    d3.selectAll('.pil')
      .style({
        opacity:0
      })
      .transition()
      .delay(function(d,i){return i*50})
      .duration(200)
      .ease('linear')
      .style({
        opacity:1
      })
  }

  function reset(){

    var section = d3.select('.section:nth-child('+(currentIndex+1)+')')
    if(currentIndex!=0){
      d3.selectAll('.label').style('opacity',0)
      d3.selectAll('.sub-label').style('opacity',((param.text)?.05:0))
      d3.selectAll('.foot').style('opacity',currentIndex>=9?0:1)
      if(!ignoreScroll && !mobile) {
        gs.scrollTo(currentIndex)
      }

    }else{
      if(lastIndex !=0){
        d3.selectAll('.label').style('opacity',0)
        d3.selectAll('.sub-label').style('opacity',((param.text)?.05:0))
        d3.selectAll('.foot').style('opacity',1)
      }

      if(!ignoreScroll && !mobile){
        d3.select(document.documentElement)
          .transition()
            .duration(500)
            .tween("scroll", function() {
              var i = d3.interpolateNumber(pageYOffset, -100)
              return function(t) { scrollTo(0, i(t)) }
            })
      }
    }
    chart.el().style('opacity',1)
    d3.selectAll('.method').style('opacity',1)
    d3.selectAll('path.plus').style('opacity',0)
    d3.selectAll('.moving').style('opacity',0)
    d3.selectAll('.diff').style('opacity',0)
    d3.selectAll('.year').style('opacity',0)
    d3.selectAll('.swoop').style('opacity',0)


    if(currentIndex==0){
      intro()
    }else{
      main()
    }

    function intro() {
      d3.select('.section').select('.label').transition().duration(500).style('opacity',1)

      setTimeout(function(){
        d3.select('.section').select('.timestamp').transition().duration(1000).style('opacity',1)
      },introDuration/3)

      setTimeout(function(){
        d3.select('.section').select('.sub-label').transition().duration(1000).style('opacity',1)
        d3.selectAll('.foot').transition().duration(1000).style('opacity',1)
      },introDuration/2)

      setTimeout(main,introDuration)
    }

    function main() {
      if(currentIndex!=0){
        section.select('.sub-label').style('opacity',1)
        section.select('.label').style('opacity',1)
      }
      d3.selectAll('.lineG .color-line').style({
        'stroke-opacity':0
      })
      d3.selectAll('.lineG.'+toSlug('Observed')+' .color-line').style({
        stroke:'#000',
        'stroke-opacity':opacF
      })
      var els = d3.selectAll('.lineG')
        .each(function(d){
          chart.animate(0,0,'.lineG.'+toSlug(d.key))

          d3.select(this).selectAll('path')
            .attr("d", function() {
                d.line = this;
                var line =chart.line()
                return line(d.values)
            })

          var key = toSlug(d.key)
          if(key!='observed'){
            uncertaintyBands(key)
          }
        })

      chart.el().classed('hoverable',false)
    }
  }

  function uncertaintyBands(key){
    var defs =chart.el().select('defs')

    var line = d3.selectAll('.'+key+' .color-line')
    var data = line.data()

    var showPlus = true
    var plus = d3.selectAll('path.plus-'+key)

    if(plus.size()==0){

      plus = d3.select('.area').append('g')
        .selectAll('path')
        .data(data).enter()
        .append('path.plus.plus-'+key)
        .attr('clip-path', function(d,i){return "url(#line-clip-path-"+toSlug(key)+")"})

      defs.selectAll('pattern')
        .data(data).enter()
        .append('pattern').attr({
          x:1,
          y:1,
          width:4,
          height:4,
          patternUnits:'userSpaceOnUse'
        })
        .attr('id',function(d){return 'pattern-'+toSlug(key)})
        .append('circle').attr({
          cx:1,
          cy:1,
          r:1
        })
        .style('fill',function(d,i){return d.color})
    }

    plus.attr('d', function(d,i){
        return area(d.values)
      })
      .attr('fill',function(d){
        return 'url(#pattern-'+toSlug(d.key)+')'
      })
      .transition().duration(50)
      .style('opacity',0)
  }

  gs = graphScroll()
    .container(d3.select('#graphic'))
    .graph(d3.selectAll('#chart'))
    .sections(sections)
    .on('active', function(i){
      circles.attr('class',function(d){
        return (i==d)?'step bg g4 opF focused' : 'step bg g4 opL'
      })
      lastIndex = currentIndex
      currentIndex = i
      if(!mobile) showStep(i)
      d3.select('.steps').classed('below',false)
    })
    .on('below',function(){
      d3.select('.steps').classed('below',true)
    })

  circles.on('click',function(i){
    ignoreScroll = !ignoreScroll
    if(!mobile) gs.scrollTo(i)
    scrollTimer = setTimeout(function() {
      ignoreScroll = !ignoreScroll
    },500)
  })

  dispatch.on('lineover.index',function(d) {

   var key = d.id.split('-').slice(0,-1).join('-')
   var index = parseInt(d.id.split('-').slice(-1))
   if(chart.el().classed('hoverable') && !chart.isAnimating()){

    var pos = d3.mouse(d3.select('body').node())
    var offset = d3.select('body').node().getBoundingClientRect()
    pos[1] = pos[1]+document.body.getBoundingClientRect().top;

    var offset = chart.el().node().getBoundingClientRect()
    var tt = tooltip.node().getBoundingClientRect()

    var dd = nasaData.filter(function(d){ return chart.data().map(ƒ('slug')).indexOf(d.slug)>-1})
    var diff = chart.el().select('.diff')
    var year = (d.key.getFullYear() < 2006)?d.key:new Date('1/1/2005')

    if(index<126 && chart.data().length>1){
      var extent =collectionRangeExtent(chart.data())
      var observed = dd[0].values[index]
      var other = dd[1].values[index]

      if(other && observed){
        diff.attr('transform', 'translate('+chart.x()(year)+',0)')

        diff.select('line.tt-axis')
          .attr({
            y1:chart.y()(d3.min([observed.value,other.value])-.8),
            y2:chart.y()(d3.max([observed.value,other.value])+.8),
          })
      }

        diff.style('opacity',1)

        tooltip.html('')
        ttBottom.html('')

        ttBottom.append('div').classed('tt-year', true)
          .text(d.key.getFullYear())
          .style({ color: '#767676' })

        ttBottom.style({
            opacity: 1,
            display: 'block',
            left: chart.margin().left/2+ chart.x()(d.key)+offset.left+ 15 - tt.width/2 + 'px',
            top: chart.y()(0)+offset.top+tt.height+40 + 'px',
          })
      }

    }


   if(param.hover){
    if(key!='observed'){
      uncertaintyBands(key)
      d3.selectAll('path.plus-'+key).transition().duration(100).style('opacity',areaOpacity)
    }

    if(!chart.isAnimating()){
      var el = d3.select('.'+key+' .color-line')
      el.style({
       'stroke-opacity':opacF
      })
    }
   }

  })

  dispatch.on('lineout.index',function(d) {
    var key = d.id.split('-').slice(0,-1).join('-')
    var diff = chart.el().select('.diff').style('opacity',0)
    d3.selectAll('.tooltip').style('opacity',0)

    if(param.hover){
      d3.selectAll('path.plus-'+key).transition().duration(100).style('opacity',0)
      d3.selectAll('.color-line').style({
        'stroke-opacity':opacF
      })
    }
  })

  dispatch.on('tooltip.index',function(d) {
  })
  function showStep (i) {
    if(i==4 || i==9){
        steps[1](keys[i].slug)
    }else{
      steps[0](keys[i].key)
    }
  }

  var docheight = d3.select("body").node().getBoundingClientRect().height,
      winheight = window.innerHeight
  var progress = {}
  progress.el = d3.select('#bg-progress')
  progress.scale = d3.scale.linear().domain([0,docheight-winheight]).range([0, 100]).clamp(true)

  window.onscroll =function() {
    // progress.el.style("width", progress.scale(pageYOffset)+"%")
    d3.selectAll('.diff').style('opacity',0)
  }

  d3.select(window)
    .on('resize.index', function(){
      mobile = window.innerWidth < 768 ? true:false

      chartWidth = getChartSize()[0]
      chartHeight = getChartSize()[1]

      chart.resize(chartWidth,chartHeight)

      d3.select('.section:nth-child('+(sections.size())+')')
        .style('padding-bottom',bottomRatio*chartHeight+'px')

      d3.selectAll('#chart').style({
        'height':chartHeight+'px'
      })


      if(!mobile) showStep(currentIndex)
    })

}
