// Generated by CoffeeScript 2.0.0
(function() {
  // layout setting
  var H, W, all_items, draw, enter_items, flag, height, items, legend, margin, stack, svg, vis, width, x, y, y_axis;

  width = document.body.getBoundingClientRect().width;

  height = document.body.getBoundingClientRect().height;

  margin = 30;

  W = width - margin * 3;

  H = height - margin * 3;

  svg = d3.select('svg');

  vis = svg.append('g').attrs({
    width: width - margin,
    height: height - margin,
    transform: `translate(${margin}, ${margin})`
  });

  // button switch
  flag = true;

  d3.select('.switch').on('click', function() {
    if (flag) {
      draw('data_2.json');
    } else {
      draw('data_1.json');
    }
    return flag = !flag;
  });

  // scales
  x = d3.scaleLinear().domain([0, 24]).range([0, W]);

  y = d3.scaleLinear().rangeRound([H, 0]);

  // x-axis
  vis.append('g').attrs({
    transform: `translate(0, ${H})`
  }).call(d3.axisBottom(x).ticks(24)).append('text').attrs({
    fill: '#000',
    transform: `translate(${W}, 30)`,
    'text-anchor': 'middle'
  }).text("Hours");

  // y-axis
  y_axis = vis.append('g');

  y_axis.append('text').attrs({
    fill: '#000',
    x: 10,
    y: -5,
    dy: '0.71em',
    'text-anchor': 'start'
  }).text("Bike Slots status");

  // stack layout
  stack = d3.stack().keys(["free_bikes", "empty_slots", "unavailable_slots"]);

  // legend
  legend = vis.append('g').attrs({
    class: 'legend',
    transform: `translate(0, ${height - 60})`
  });

  items = legend.selectAll('.item').data([
    {
      "label": "free bikes",
      "color": "#ccebc5"
    },
    {
      "label": "empty slots",
      "color": "#f2f2f2"
    },
    {
      "label": "unavailable slots",
      "color": "#fbb4ae"
    }
  ]);

  enter_items = items.enter().append('g').attrs({
    class: 'item'
  });

  all_items = enter_items.merge(items);

  all_items.append('rect').attrs({
    x: function(d, i) {
      return i * 100;
    },
    width: 10,
    height: 20,
    fill: function(d) {
      return d.color;
    }
  });

  all_items.append('text').attrs({
    x: function(d, i) {
      return 15 + i * 100;
    },
    y: 10,
    dy: '0.35em'
  }).text(function(d) {
    return d.label;
  });

  items.exit().remove();

  // MAIN visualization function
  draw = function(filename) {
    // data loading
    return d3.json(filename, function(data) {
      var all_bars, all_groups, bars, enter_bars, enter_groups, groups, stacked, t_data;
      /* data transformation
      */
      t_data = data.map(function(datum) {
        var empty_slots, free_bikes, unavailable_slots;
        free_bikes = datum.bin.map(function(doc) {
          return doc.doc.free_bikes * doc.duration;
        }).reduce(function(acc, cur) {
          return acc + cur;
        });
        empty_slots = datum.bin.map(function(doc) {
          return doc.doc.empty_slots * doc.duration;
        }).reduce(function(acc, cur) {
          return acc + cur;
        });
        unavailable_slots = datum.bin.map(function(doc) {
          return doc.doc.unavailable_slots * doc.duration;
        }).reduce(function(acc, cur) {
          return acc + cur;
        });
        return {
          hour: datum.hour,
          free_bikes: free_bikes / 3600,
          empty_slots: empty_slots / 3600,
          unavailable_slots: unavailable_slots / 3600
        };
      });
      /* y-axis setting
      */

      // update y scale domain according to data
      y.domain([
        0,
        d3.max(t_data,
        function(d) {
          return d.free_bikes + d.empty_slots + d.unavailable_slots;
        }) + 1
      ]);
      y_axis.call(d3.axisLeft(y).ticks(y.domain()[1]));
      /* stacked bar chart
      */
      stacked = stack(t_data);
      // groups
      groups = vis.selectAll('.group').data(stacked);
      enter_groups = groups.enter().append('g').attrs({
        class: function(d) {
          return `group ${d.key}`;
        }
      });
      all_groups = enter_groups.merge(groups);
      groups.exit().remove();
      // bars
      bars = all_groups.selectAll('.bar').data(function(d) {
        return d;
      });
      bars.transition().duration(750).attrs({
        x: function(d) {
          return x(d.data.hour) + W / 24 / 20;
        },
        y: function(d) {
          return y(d[1]);
        },
        width: W / 24 - W / 24 / 10,
        height: function(d) {
          return H - y(d[1] - d[0]);
        }
      });
      enter_bars = bars.enter().append('rect').attrs({
        class: 'bar',
        x: function(d) {
          return x(d.data.hour) + W / 24 / 20;
        },
        y: function(d) {
          return y(d[1]);
        },
        width: W / 24 - W / 24 / 10,
        height: function(d) {
          return H - y(d[1] - d[0]);
        }
      });
      all_bars = enter_bars.merge(bars);
      return bars.exit().remove();
    });
  };

  draw('data_1.json');

}).call(this);