text: // Global vars
  var pymChild = null;
  var isMobile = false;
  
  /*
   * Initialize the graphic.
   */
  var onWindowLoaded = function() {
      if (Modernizr.svg) {
          formatData();
  
          pymChild = new pym.Child({
              renderCallback: render
          });
      } else {
          pymChild = new pym.Child({});
      }
  }
  
  /*
   * Format data for D3.
   */
  var formatData = function() {
      DATA.forEach(function(d) {
          d['amt'] = +d['amt'];
      });
  }
  
  /*
   * Render the graphic(s). Called by pym with the container width.
   */
  var render = function(containerWidth) {
      if (!containerWidth) {
          containerWidth = DEFAULT_WIDTH;
      }
  
      if (containerWidth <= MOBILE_THRESHOLD) {
          isMobile = true;
      } else {
          isMobile = false;
      }
  
      var containerElement = d3.select('#bar-chart');
      containerElement.html('');
      containerElement.append('h3')
          .attr('class', 'initial-h3')
          .text('Share of mosquitoes attracted...');
  
      var dataValues = ['initial', '240'];
      for (var i=0; i < dataValues.length; i++) {
          var value = dataValues[i];
          var chartContainer = containerElement.append('div')
              .attr('class', 'chart-wrapper')
              .attr('id', 'chart-' + value);
  
          // Render the chart!
          renderBarChart({
              container: '#chart-' + value,
              overallWidth: containerWidth,
              width: isMobile ? containerWidth : containerWidth / 2,
              data: DATA,
              key: 'value_' + value
          });
      }
  
      // Update iframe
      if (pymChild) {
          pymChild.sendHeight();
      }
  }
  
  /*
   * Render a bar chart.
   */
  var renderBarChart = function(config) {
      /*
       * Setup
       */
      var labelColumn = 'label';
      var valueColumn = config['key'];
  
      var barHeight = 30;
      var barGap = 9;
      var labelColumnWidth = 140;
      var labelWidth = !isMobile && config['key'] == 'value_initial' ? labelColumnWidth + 5 : isMobile ? 120 : 5;
      var labelMargin = 6;
      var valueGap = 6;
  
      var margins = {
          top: 0,
          right: 15,
          bottom: 20,
          left: (labelWidth + labelMargin)
      };
  
      var ticksX = 4;
      var roundTicksFactor = 20;
  
      var actualWidth = isMobile ? config['width'] : (config['overallWidth'] - labelColumnWidth)/2;
      // Calculate actual chart dimensions
      var chartWidth = !isMobile && config['key'] == 'value_initial' ? actualWidth + 140 - margins['left'] - margins['right'] : actualWidth  - margins['left'] - margins['right'];
      var chartHeight = ((barHeight + barGap) * config['data'].length);
  
      // Clear existing graphic (for redraw)
      var containerElement = d3.select(config['container']);
      containerElement.html('');
  
      var chartLabel = config['key'] == 'value_initial' ? 'upon application' : 'After four hours';
      containerElement.append('h3')
          .text(chartLabel);
  
      /*
       * Create the root SVG element.
       */
      var chartWrapper = containerElement.append('div')
          .attr('class', 'graphic-wrapper');
  
      var chartElement = chartWrapper.append('svg')
          .attr('width', chartWidth + margins['left'] + margins['right'])
          .attr('height', chartHeight + margins['top'] + margins['bottom'])
          .append('g')
          .attr('transform', 'translate(' + margins['left'] + ',' + margins['top'] + ')');
  
      /*
       * Create D3 scale objects.
       */
      var min = d3.min(config['data'], function(d) {
          return Math.floor(d[valueColumn] / roundTicksFactor) * roundTicksFactor;
      });
  
      if (min > 0) {
          min = 0;
      }
  
      var max = d3.max(config['data'], function(d) {
          return Math.ceil(d[valueColumn] / roundTicksFactor) * roundTicksFactor;
      })
  
      var xScale = d3.scale.linear()
          .domain([min, max])
          .range([0, chartWidth]);
  
      /*
       * Create D3 axes.
       */
      var xAxis = d3.svg.axis()
          .scale(xScale)
          .orient('bottom')
          .ticks(ticksX)
          .tickFormat(function(d) {
              return d.toFixed(0) + '%';
          });
  
      /*
       * Render axes to chart.
       */
      chartElement.append('g')
          .attr('class', 'x axis')
          .attr('transform', makeTranslate(0, chartHeight))
          .call(xAxis);
  
      /*
       * Render grid to chart.
       */
      var xAxisGrid = function() {
          return xAxis;
      };
  
      chartElement.append('g')
          .attr('class', 'x grid')
          .attr('transform', makeTranslate(0, chartHeight))
          .call(xAxisGrid()
              .tickSize(-chartHeight, 0, 0)
              .tickFormat('')
          );
  
      /*
       * Render bars to chart.
       */
      chartElement.append('g')
          .attr('class', 'bars')
          .selectAll('rect')
          .data(config['data'])
          .enter()
          .append('rect')
              .attr('x', function(d) {
                  if (d[valueColumn] >= 0) {
                      return xScale(0);
                  }
  
                  return xScale(d[valueColumn]);
              })
              .attr('width', function(d) {
                  return Math.abs(xScale(0) - xScale(d[valueColumn]));
              })
              .attr('y', function(d, i) {
                  return i * (barHeight + barGap);
              })
              .attr('height', barHeight)
              .attr('class', function(d, i) {
                  var addClass = d['has_deet'] === 'deet' ? ' has-deet ' : ' ';
                  return 'bar-' + i + addClass + classify(d[labelColumn]);
              });
  
      /*
       * Render 0-line.
       */
      if (min < 0) {
          chartElement.append('line')
              .attr('class', 'zero-line')
              .attr('x1', xScale(0))
              .attr('x2', xScale(0))
              .attr('y1', 0)
              .attr('y2', chartHeight);
      }
  
      /*
       * Render bar labels.
       */
      if (isMobile || config['key'] === 'value_initial') {
          chartWrapper.append('ul')
              .attr('class', 'labels')
              .attr('style', formatStyle({
                  'width': labelWidth + 'px',
                  'top': margins['top'] + 'px',
                  'left': '0'
              }))
              .selectAll('li')
              .data(config['data'])
              .enter()
              .append('li')
                  .attr('style', function(d, i) {
                      return formatStyle({
                          'width': labelWidth + 'px',
                          'height': barHeight + 'px',
                          'left': '0px',
                          'top': (i * (barHeight + barGap)) + 'px;'
                      });
                  })
                  .attr('class', function(d) {
                      return classify(d[labelColumn]);
                  })
                  .append('span')
                      .text(function(d) {
                          return d[labelColumn];
                      });
      }
  
      /*
       * Render bar values.
       */
      chartElement.append('g')
          .attr('class', 'value')
          .selectAll('text')
          .data(config['data'])
          .enter()
          .append('text')
              .text(function(d) {
                  return parseInt(d[valueColumn]) + '%';
              })
              .attr('x', function(d) {
                  return xScale(d[valueColumn]);
              })
              .attr('y', function(d, i) {
                  return i * (barHeight + barGap);
              })
              .attr('dx', function(d) {
                  var xStart = xScale(d[valueColumn]);
                  var textWidth = this.getComputedTextLength()
  
                  // Negative case
                  if (d[valueColumn] < 0) {
                      var outsideOffset = -(valueGap + textWidth);
  
                      if (xStart + outsideOffset < 0) {
                          d3.select(this).classed('in', true)
                          return valueGap;
                      } else {
                          d3.select(this).classed('out', true)
                          return outsideOffset;
                      }
                  // Positive case
                  } else {
                      if (xStart + valueGap + textWidth > chartWidth) {
                          d3.select(this).classed('in', true)
                          return -(valueGap + textWidth);
                      } else {
                          d3.select(this).classed('out', true)
                          return valueGap;
                      }
                  }
              })
              .attr('dy', (barHeight / 2) + 3)
  }
  
  /*
   * Initially load the graphic
   * (NB: Use window.load to ensure all images have loaded)
   */
  window.onload = onWindowLoaded;
  