<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Voter Sample: Real-Time Results</title>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta name="description" content="VoltDB demo dashboard" />
        <meta name="author" content="voltdb" />
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <!-- Bootstrap core CSS -->
        <link href="css/bootstrap.min.css" rel="stylesheet" />
        <!-- Bootstrap theme -->
        <link href="css/bootstrap-theme.min.css" rel="stylesheet" />
        <!-- Custom styles for this template -->
        <link href="css/demo.css" rel="stylesheet">
        <link rel="stylesheet" type="text/css" href="css/jquery.jqplot.min.css" />
        <script language="javascript" type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
        <!--[if IE]><script language="javascript" type="text/javascript" src="../../../tools/studio.web/js/jqplot/excanvas.min.js"></script><![endif]-->
        <script language="javascript" type="text/javascript" src="js/jquery.jqplot.min.js"></script>
        <script src="js/jquery.flot.js"></script>
        <script src="js/jquery.flot.time.js"></script>
        <script language="javascript" type="text/javascript" src="js/voltdb.js"></script>
        <script language="javascript" type="text/javascript" src="js/canvas-us-map.js"></script>
        <script language="javascript" type="text/javascript" src="js/jqplot.mapRenderer.js"></script>
        <script type="text/javascript" language="javascript">
        var contestants = [{label:'Edwina Burnam',color:'#f00'},{label:'Tabatha Gehling',color:'#900'},{label:'Kelly Clauss',color:'#0f0'},{label:'Jessie Alloway',color:'#090'},{label:'Alana Bregman',color:'#00f'},{label:'Jessie Eichman',color:'#009'}];
        var plot;
        var con;
        var intervalId;
        function RefreshData()
        {
            con.BeginExecute('GetStateHeatmap', [], function(response)
            {
                try
                {
                    var data = [['XX',0]];
                    var agg = [0,0,0,0,0,0];
                    var tot = 1;
                    for(var i=0;i<response.results[0].data.length;i++)
                    {
                        data.push([response.results[0].data[i][0], response.results[0].data[i][1]-1]);
                        tot += response.results[0].data[i][2];
                    }
                    for (var i=0; i < response.results[1].data.length; i++)
                    {
                        var contestant = response.results[1].data[i][0] - 1;
                        var nvotes     = response.results[1].data[i][1];
                        agg[contestant] = nvotes;
                    }
                    for(var i=0;i<agg.length;i++)
                    {
                        $('#statdata' + i).text(formatNumber(agg[i]));
                        $('#pctdata' + i).text(Math.round(100*agg[i]/tot) + "%");
                        $('#pctbar' + i).css('width', Math.round(100*agg[i]/tot) + "px");
                    }

                    plot.series[0].data = data;
                    plot.replot({clear:true, resetAxes:true});
                }
                catch(x) {}
            });
        }
        function SetRefreshInterval(interval)
        {
            if (intervalId != null)
            {
                clearInterval(intervalId);
                intervalId = null;
            }
            if(interval > 0)
                intervalId = setInterval(RefreshData, interval*1000);
                intervalId = setInterval(RefreshStats, interval*1000);
        }

function initTpsVals() {
    if (tpsVals.length == 0) {
        var now = (new Date()).getTime();
        var interval = 1000; // 1 second
        var ts = now - 60 * 1000;
        while (ts < now) {
            tpsVals.push([ts, 0]);
            ts += interval;
        }
    }
}

// this runs every second
function RefreshStats() {
    con.BeginExecute('@Statistics',
                     ['PROCEDUREPROFILE','0'],
                     function(response) {
                         DrawTPSChart(response,'#tps_chart');
                     }
                    );

}

var tpsVals = [];
var prevTsMs = null;
var tcount0 = null;
function DrawTPSChart(response, someDiv) {
    var tables = response.results;
    var table0 = tables[0];
    //var colcount = table0.schema.length;

    var cTsMs = table0.data[0][0];
    if (prevTsMs != null && cTsMs == prevTsMs) {
        // Skip cached old results
        return;
    }
    var durationMs = cTsMs - prevTsMs;
    prevTsMs = cTsMs;

    var time = table0.data[0][0]; // milliseconds
    var tcount1 = 0;
    for(var r=0;r<table0.data.length;r++){ // for each row
        //var time = table0.data[r][0]/1000;
        tcount1 += table0.data[r][3];
    }
    var tps;
    if (tcount0 == null) {
        tps = 0;
    } else {
        tps = (tcount1 - tcount0)*1000/durationMs;
    }
    tcount0 = tcount1;
    tpsVals.push([time,tps]);

    // Only keep the last minute's data to bound memory usage
    if (tpsVals[tpsVals.length - 1][0] - tpsVals[0][0] > 60000) {
        tpsVals.shift();
    }

    var tpsline = { label: "TPS", data: tpsVals };

    var options = {
        series: {
        lines: { show: true, fill: true },
        //bars: { show: true, barWidth : 60*1000, fill: true},
        points: { show: false }
        },
        xaxis: { mode: "time", timezone: "browser", minTickSize: [10, "second"], ticks: 4 },
        yaxis: { position: "right" },
        legend: { position: 'nw' }
    };

    $.plot($(someDiv), [tpsline], options);
}

        function formatNumber(num)
        {
            var cnum = ""+num;
            var parr = [], j = cnum.length, m = Math.floor(j / 3), n = cnum.length % 3 || 3;
            for (var i = 0; i < j; i += n)
            {
                if (i != 0) {n = 3;}
                parr[parr.length] = cnum.substr(i, n);
                m -= 1;
            }
            return parr.join(',');
        }

        $(document).ready(function(){
            $('#loadingModal').modal('show');
            checkConnection();
        });

function checkConnection() {
    VoltDB.TestConnection(location.hostname, 8080, false, null, null, false,
                          function(connected){
                              if (connected) {
                                  $('#loadingModal').modal('hide');
                                  connectToDatabase();
                              } else {
                                  checkConnection();
                              }
                          });
}

        function connectToDatabase() {
            initTpsVals();

            var states = ['AL','AK','AZ','AR','CA','CO','CT','DE','FL','GA','ID','IL','IN','IA','HI','KS','KY','LA','ME','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','OH','OK','OR','PA','RI','SC','SD','TN','TX','UT','VT','VA','WA','WV','WI','WY'];
            var data = [[['XX',0]],[],[],[],[],[]];
            var colors = [];
            for(var i=0;i<contestants.length;i++)
                colors.push(contestants[i].color);

            var chartParams = {
                    legend:{ show: true, yoffset:110, xoffset: -80 },
                    seriesDefaults:{
                            renderer: $.jqplot.MapRenderer,
                            rendererOptions: { mapVarName: 'usMapData' }
                    },
                    axesDefaults: {
                            tickOptions: {
                                    showMark: false,
                                    showLabel: false
                            }
                    },
                    grid: {
                            drawGridlines: false,
                            shadow: false,
                            borderWidth: 0.01,
                            background: '#fff'
                    },
                    series: contestants,
                    seriesColors: colors
            };
            plot = $.jqplot('chartUSMap1', data, chartParams);

            con = VoltDB.AddConnection(location.hostname, 8080, false, null, null, false, (function(connection, success)
            {}));
            SetRefreshInterval(1);
        }
        </script>
    </head>
<body>

    <!-- Fixed navbar -->
    <div class="navbar navbar-default navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <a class="navbar-brand" href="http://voltdb.com"><img alt="" src="img/logo.png" /></a>
          <span class="navbar-brand">Voter Demo</span>
        </div>
        <div class="navbar-collapse collapse">
          <ul class="nav navbar-nav navbar-right">
            <li><a href="javascript:window.location='http://'+window.location.hostname+':8080'">VoltDB Management Center</a></li>
          </ul>
        </div>
      </div>
    </div>

    <div class="container">
      <div class="row">
        <div class="col-md-8">
          <h4>Voter Sample: Real-Time Results</h4>
          <p>Watch the voting results live - the heat map indicates which
          contestant is winning in a given state, while the table next to the
          map lists the total number of votes each contestant has received,
          nationwide.</p>
          <div class="jqPlot" id="chartUSMap1" style="width:550px;"></div>
        </div>
        <div class="col-md-4">
          <div id="time" class="pull-right"></div>
<table class="table table-striped">
<thead><tr><th width="200">Contestant</th><th width="150">%</th><th>Votes</th></tr></thead><tbody>
<script type="text/javascript" language="javascript">
for(var i=0;i<contestants.length;i++)
    document.write('<tr><td>' + contestants[i].label +
    '</td><td><div id="pctdata' + i + '" style="float:left;width:30px;text-align:right;">0%</div><div id="pctbar' + i + '" style="float:left;margin-left:10px;margin-right:10px;width:0px;background-color:#ccc">&nbsp;</div></td><td id="statdata' + i + '" class="text-right">0</td></tr>');
</script>
</table>

          <h4>Performance</h4>
          <div id="tps_chart" style="height:200px;"></div>
        </div>
      </div>
    </div>

    <!-- Loading Modal -->
    <div class="modal fade" id="loadingModal" tabindex="-1" role="dialog"
         aria-labelledby="myModalLabel" aria-hidden="true"
         data-backdrop="static"
         data-keyboard="false">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-body center-block">
            <h4 class="modal-title" id="myModalLabel">Starting database, this may take 30 seconds...</h4>
          </div>
        </div><!-- /.modal-content -->
      </div><!-- /.modal-dialog -->
    </div><!-- /.modal -->

    <!-- Placed at the end of the document so the pages load faster -->
    <script src="js/bootstrap.min.js"></script>
</body></html>
