<%
  # *******************************************************************************
  # OpenStudio(R), Copyright (c) 2008-2021, Alliance for Sustainable Energy, LLC.
  # All rights reserved.
  # Redistribution and use in source and binary forms, with or without
  # modification, are permitted provided that the following conditions are met:
  #
  # (1) Redistributions of source code must retain the above copyright notice,
  # this list of conditions and the following disclaimer.
  #
  # (2) Redistributions in binary form must reproduce the above copyright notice,
  # this list of conditions and the following disclaimer in the documentation
  # and/or other materials provided with the distribution.
  #
  # (3) Neither the name of the copyright holder nor the names of any contributors
  # may be used to endorse or promote products derived from this software without
  # specific prior written permission from the respective party.
  #
  # (4) Other than as required in clauses (1) and (2), distributions in any form
  # of modifications or other derivative works may not use the "OpenStudio"
  # trademark, "OS", "os", or any other confusingly similar designation without
  # specific prior written permission from Alliance for Sustainable Energy, LLC.
  #
  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
  # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
  # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  # *******************************************************************************
%>








<!DOCTYPE html>
<meta charset="utf-8">
<style>

svg {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.brush .extent {
  stroke: #fff;
  fill-opacity: .125;
  shape-rendering: crispEdges;
}

.xline {
  stroke-width: 1;
  fill: none;
  clip-path: url(#clip);
}

</style>
<title><%=@name%></title>
<link href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.2.0/css/bootstrap.css" rel="stylesheet">
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.3.9/d3.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<div id="timeseriesplot" class="container">
  <h1 id="plottitle">Timeseries Plot</h1>
</div>
<script>

var allSeries = <%= all_series %>;

// Set the overall plot heading
if (allSeries[0].displayname != "") $("#plottitle").text(allSeries[0].displayname);
else $("#plottitle").text(allSeries[0].type);

// Define size and margins of chart
var margin = {top: 10, right: 350, bottom: 100, left: 100},
    margin2 = {top: 430, right: 350, bottom: 20, left: 100},
    width = 1500 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom,
    height2 = 500 - margin2.top - margin2.bottom;

var parseDate = d3.time.format("%b %Y").parse;

// Determine the bounds of the chart
var x_min = new Date('January 1, 3000 00:00:00');
var x_max = new Date('January 1, 1900 00:00:00');
var y_min = Number.POSITIVE_INFINITY;
var y_max = Number.NEGATIVE_INFINITY;
$.each(allSeries, function(index, all_series) {
  var series = allSeries[index];
  
  this_x_min = d3.min(series.data.map(function(d) { return new Date(d.time); }))
  this_x_max = d3.max(series.data.map(function(d) { return new Date(d.time); }))
  this_y_min = d3.min(series.data.map(function(d) { return d.y; }))
  this_y_max = d3.max(series.data.map(function(d) { return d.y; }))
  
  if (this_x_min < x_min) x_min = this_x_min;
  if (this_x_max > x_max) x_max = this_x_max;
  if (this_y_min < y_min) y_min = this_y_min;
  if (this_y_max > y_max) y_max = this_y_max;  
  
});
// Log the bounds for debugging 
console.log("x_min = " + x_min)
console.log("x_max = " + x_max)
console.log("y_min = " + y_min)
console.log("y_max = " + y_max)  

// Increase the y max by a little for readability
y_max = y_max + ((y_max - y_min) * 0.25);
  
// Horizontal axis scale
var x_extent = [this.x_min, this.x_max];

// Vertical axis scale
var y_extent = [this.y_min, this.y_max];

// Create the x and y scales (width on page) for both chart areas    
var x = d3.time.scale().range([0, width]),
    x2 = d3.time.scale().range([0, width]),
    y = d3.scale.linear().range([height, 0]),
    y2 = d3.scale.linear().range([height2, 0]);
  
// Create the x and y domains (extent of the data) for both chart areas  
x.domain(x_extent);
y.domain(y_extent);
x2.domain(x.domain());
y2.domain(y.domain());  
  
// Create and position axes
var xAxis = d3.svg.axis().scale(x).orient("bottom"),
    xAxis2 = d3.svg.axis().scale(x2).orient("bottom"),
    yAxis = d3.svg.axis().scale(y).tickFormat(d3.format(".2e")).orient("left"),
    yAxis2 = d3.svg.axis().scale(y2).orient("left");

// Create the selector 
var brush = d3.svg.brush()
    .x(x2)
    .on("brush", brushed);

// Function to create lines in the focus area    
var line = d3.svg.line()
    .x(function(d) { return x(new Date(d.time)); })
    .y(function(d) { return y(d.y); });

// Function to create lines in the context area    
var line2 = d3.svg.line()
    .x(function(d) { return x2(new Date(d.time)); })
    .y(function(d) { return y2(d.y); });    

// Create the overall SVG    
var svg = d3.select("#timeseriesplot").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom);

svg.append("defs").append("clipPath")
    .attr("id", "clip")
  .append("rect")
    .attr("width", width)
    .attr("height", height);

// Draw the focus section (main plot)    
var focus = svg.append("g")
    .attr("class", "focus")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// Draw the focus x and y axes
focusaxis = focus.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis);
  
focusaxis.append("text")
      .text(allSeries[0].type + " [" + allSeries[0].units + "]")
      .attr("transform", "rotate (-90, 0, 0) translate(" + (height / 5) + "," + (-1*(margin.left / 2 + 20)) + ")"); // TODO dynamically account for width of axis label to center

focus.append("g")
  .attr("class", "y axis")
  .call(yAxis);   
       
// Draw the context section (selector)
var context = svg.append("g")
  .attr("class", "context")
  .attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");

// Draw the context x axis 
context.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height2 + ")")
  .call(xAxis2); 
  
// Draw the brush selector for the context  
context.append("g")
    .attr("class", "x brush")
    .call(brush)
  .selectAll("rect")
    .attr("y", -6)
    .attr("height", height2 + 7);

// set default extent for brush selected (custom code for FRP)
brush.extent([new Date("January 15 2009 00:00:00"), new Date("January 16 2009 24:00:00")])
context.select('.brush').call(brush);
brushed();

// Setup the spacing for the legends
var legendSpacing = 25;
    
// Create a legend for the data series
var primlegend = focus.append("g")
  .attr("class", "w axis")
  .attr("transform", "translate(" + (width + 10) + ",0)");

// TODO make series toggle-able
primlegend.append("text").text("Series Names")
  //.style("cursor", " pointer")
  .attr("y", legendSpacing * 1)
  .attr("class", "noselect");
    
// Define the color scale
var c20 = d3.scale.category20();
c20.domain([1, allSeries.length]);   
    
// Plot each series
var i = 1;
$.each(allSeries, function(index, all_series) {
  var series = allSeries[index];
  
  // Generate a color
  var lineColor = series.color  
  
  // Plot on the focus
  focus.append("path")
  .datum(series.data)
  .attr("class", "xline")
  .attr("d", line)
  .style("stroke", lineColor);
  
  // Plot on the context
  // Note that line2 uses the x2 and y2 scales
  context.append("path")
  .datum(series.data)
  .attr("class", "xline")
  .attr("d", line2)
  .style("stroke", lineColor);
  
  // Add the series name to the legend
  primlegend.append("text").text(series.name + " [" + series.units + "]")
    .style("cursor", " pointer")
    .attr("y", legendSpacing * (i + 1))
    .attr("class", "noselect")
    .style("fill", lineColor);    
  
  i += 1;
  
});

  // Add the series cvrmse to the legend
  primlegend.append("text").text("CVRMSE:" + allSeries[0].cvrmse)
    .attr("y", legendSpacing * (i + 1))
    .attr("class", "noselect");  
i += 1;

  // Add the series nmbe to the legend
  primlegend.append("text").text("NMBE:" + allSeries[0].nmbe)
    .attr("y", legendSpacing * (i + 1))
    .attr("class", "noselect"); 
i += 1;

// Define what to do when the selector is moved around
function brushed() {
  console.log("Brushed")
  x.domain(brush.empty() ? x2.domain() : brush.extent());
  focus.selectAll(".xline").attr("d", line);
  focus.selectAll(".x.axis").call(xAxis);
}

</script>