function showNotice() {

var notice = document.getElementById('notice');
if (notice != null) {
  notice.style.display = 'block';
}

} function hideNotice() {

var notice = document.getElementById('notice');
if (notice != null) {
  notice.style.display = 'none';
}

}

// Various formatters. // var formatNumber = d3.format(ā€œ,dā€),

formatFloat  = d3.format(".l")
formatChange = d3.format("+,d"),
formatDate = d3.time.format("%B %d, %Y"),
formatTime = d3.time.format("%I:%M %p");

// A nest operator, for grouping the flight list. // var nestByDate = d3.nest()

.key(function(d) { return d3.time.day(d.date); });

// Create the crossfilter for the relevant dimensions and groups. // var search = crossfilter(),

all = search.groupAll(),
date = search.dimension(function(d) { return d3.time.day(d.date); }),
dates = date.group(),
hour = search.dimension(function(d) { return d.date.getHours() + d.date.getMinutes() / 60; }),
hours = hour.group(),
total = search.dimension(function(d) { return d.total; }),
totals = total.group();
offset = search.dimension(function(d) { return d.offset; }),
offsets = offset.group();
allocation = search.dimension(function(d) { return d.allocations; }),
allocations = allocation.group();
duration = search.dimension(function(d) { return d.duration; }),
durations = duration.group();

var chartWidth = [0, 1000];

var totalScale = d3.scale.linear()

.domain([0, 0])
.rangeRound(chartWidth);

var allocationsScale = d3.scale.linear()

.domain([0, 0])
.rangeRound(chartWidth);

var offsetScale = d3.scale.linear()

.domain([0, 0])
.rangeRound(chartWidth);

var durationScale = d3.scale.linear()

.domain([0, 0])
.rangeRound(chartWidth);

var charts = [

// barChart()
//     .dimension(date)
//     .group(dates)
//     .round(d3.time.day.round)
//   .x(d3.time.scale()
//     .domain([new Date(2001, 0, 1), new Date(2001, 3, 1)])
//     .rangeRound([0, 10 * 90]))
//     .filter([new Date(2001, 1, 1), new Date(2001, 2, 1)]),

barChart()
    .dimension(hour)
    .group(hours)
  .x(d3.scale.linear()
    .domain([0, 24])
    .rangeRound([0, 1000])),

barChart()
    .dimension(total)
    .group(totals)
  .x(totalScale),

barChart()
    .dimension(allocation)
    .group(allocations)
  .x(allocationsScale),

barChart()
    .dimension(offset)
    .group(offsets)
  .x(offsetScale),

barChart()
    .dimension(duration)
    .group(durations)
  .x(durationScale)

];

// Renders the specified chart or list. // function render(method) {

d3.select(this).call(method);

}

// Whenever the brush moves, re-rendering everything. // function renderAll() {

// Given our array of charts, which we assume are in the same order as the
// .chart elements in the DOM, bind the charts to the DOM and render them.
// We also listen to the chart's brush events to update the display.
//
var chart = d3.selectAll(".chart")
    .data(charts)
    .each(function(chart) { chart.on("brush", renderAll).on("brushend", renderAll); });
chart.each(render);

// Render the initial lists.
//
var list = d3.selectAll(".list")
    .data([searchList]);
list.each(render);

// Render the total.
//
d3.selectAll("aside.totals .total")
    .text(formatNumber(search.size()));

d3.selectAll("aside.totals .active").text(formatNumber(all.value()));

}

// Like d3.time.format, but faster. // function parseDate(d) {

return new Date(
  d.substring(0, 4),
  d.substring(5, 7) - 1,
  d.substring(8, 10),
  d.substring(11, 13),
  d.substring(14, 16),
  d.substring(17, 19)
);

}

window.filter = function(filters) {

filters.forEach(function(d, i) { charts[i].filter(d); });
renderAll();

};

window.reset = function(i) {

charts[i].filter(null);
renderAll();

};

var intervalUpdating = false;

function updateStatistics(reloadAll, seconds) {

path = reloadAll ? 'index.json' : 'since_last.json';

if (!seconds || seconds >= 30) { showNotice(); }

d3.json(path, function(searches) {
  if (!searches || searches.length == 0) { return; }

  var totalMin = 1000000; // Highest minimum set to sane number.
  var totalMax = 0;
  var allocationsMin = 100; // Highest minimum set to sane number.
  var allocationsMax = 0;
  var offsetMin = 1000; // Highest minimum set to sane number.
  var offsetMax = 0;    
  var durationMin = 20; // Highest minimum set to sane number.
  var durationMax = 0;

  // A little coercion, since the CSV is untyped.
  //
  searches.forEach(function(d, i) {
    d.index = i;
    d.date = parseDate(d[0]);
    d.duration = Number(d[1]);
    d.text = d[2];
    d.total = Number(d[3]);
    d.offset = Number(d[4]);
    d.allocations = Number(d[5]);

    if (totalMin > d.total) { totalMin = d.total; }
    if (totalMax < d.total) { totalMax = d.total; }
    if (allocationsMin > d.allocations) { allocationsMin = d.allocations; }
    if (allocationsMax < d.allocations) { allocationsMax = d.allocations; }
    if (offsetMin > d.offset) { offsetMin = d.offset; }
    if (offsetMax < d.offset) { offsetMax = d.offset; }
    if (durationMin > d.duration) { durationMin = d.duration; }
    if (durationMax < d.duration) { durationMax = d.duration; }
  });

  // Set scales.
  //
  var totalDomain = totalScale.domain();
  totalScale.domain([d3.min([totalMin, totalDomain[0]])*0.9, d3.max([totalMax, totalDomain[1]])]);
  var allocationsDomain = allocationsScale.domain();
  allocationsScale.domain([d3.min([allocationsMin, allocationsDomain[0]])*0.9, d3.max([allocationsMax, allocationsDomain[1]])]);
  var offsetDomain = offsetScale.domain();
  offsetScale.domain([d3.min([offsetMin, offsetDomain[0]])*0.9, d3.max([offsetMax, offsetDomain[1]])]);
  var durationDomain = durationScale.domain();
  durationScale.domain([d3.min([durationMin, durationDomain[0]])*0.9, d3.max([durationMax, durationDomain[1]])]);

  search.add(searches);

  renderAll();

  if (!seconds || seconds >= 30) { hideNotice(); }
});

};

var periodicalUpdaterId;

function updateStatisticsPeriodically(seconds) {

clearInterval(periodicalUpdaterId);
periodicalUpdaterId = setInterval(function() {
     updateStatistics(false, seconds);
}, 1000*seconds);
intervalUpdating = true;

};

function stopUpdatingStatistics() {

clearInterval(periodicalUpdaterId);
intervalUpdating = false;

};