Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
Added D3 Histogram
  • Loading branch information
dtraviglia committed May 25, 2016
1 parent 11940b4 commit 142d78fdf77b03db14631f70219d69f89a5e9630
Showing 7 changed files with 328 additions and 36 deletions.
@@ -322,22 +322,22 @@ <h1 id="expStatusHeader">Experiment Status</h1>
</div>
<div id="metrics" class="expTraySection">
<div id="metricsNav">
<div id="{{ experimentName }}LoadBtn" class="metricsNavBtn active">Load</div>
<div id="{{ experimentName }}DifficultyBtn" class="metricsNavBtn">Difficulty</div>
<div id="{{ experimentName }}PerformanceBtn" class="metricsNavBtn">Performance</div>
<div id="{{ experimentName }}ConfidenceBtn" class="metricsNavBtn">Confidence</div>
<div id="{{ experimentName }}LoadBtn" class="metricsNavBtn active" data-category="Load">Load</div>
<div id="{{ experimentName }}DifficultyBtn" class="metricsNavBtn" data-category="Difficulty">Difficulty</div>
<div id="{{ experimentName }}PerformanceBtn" class="metricsNavBtn" data-category="Performance">Performance</div>
<div id="{{ experimentName }}ConfidenceBtn" class="metricsNavBtn" data-category="Confidence">Confidence</div>
<!-- <div id="{{ experimentName }}ActivityBtn" class="metricsNavBtn">Activity</div> -->
<div id="{{ experimentName }}TimeBtn" class="metricsNavBtn">Time</div>
<div id="{{ experimentName }}TimeBtn" class="metricsNavBtn" data-category="Time">Time</div>
</div>
<div class="metricsBody">
<div class="metricsDropdowns">
<div class="selectTitle">Tool</div>
<select name="tools" id="toolsSelect">
<!-- <option value="all">All</option> -->
<option value="all">All</option>
{% for expObjKey, expObjVal in experimentVal.items %}
{% if 'products' in expObjKey %}
{% for product in expObjVal %}
<!-- <option value="{{ product.name }}">{{ product.name }}</option> -->
<option value="{{ product.name }}">{{ product.name }}</option>
{% endfor %}
{% endif %}
{% endfor %}
@@ -354,24 +354,7 @@ <h1 id="expStatusHeader">Experiment Status</h1>
{% endfor %}
</select>
</div>
<div id="{{ experimentName }}Load" class="metricsSection active">
<svg id="{{ experimentName }}LoadChart" class="chart"></svg>
</div>
<div id="{{ experimentName }}Difficulty" class="metricsSection">
<svg id="{{ experimentName }}DifficultyChart" class="chart"></svg>
</div>
<div id="{{ experimentName }}Performance" class="metricsSection">
<svg id="{{ experimentName }}PerformanceChart" class="chart"></svg>
</div>
<div id="{{ experimentName }}Confidence" class="metricsSection">
<svg id="{{ experimentName }}ConfidenceChart" class="chart"></svg>
</div>
<!-- <div id="activity" class="metricsSection">
<svg id="{{ experimentName }}ActivityChart" class="chart"></svg>
</div> -->
<div id="{{ experimentName }}Time" class="metricsSection">
<svg id="{{ experimentName }}TimeChart" class="chart"></svg>
</div>
<div id="canvasD3" class="metricsSection active" data-experiment="{{ experimentName }}"></div>
</div>
</div>
</div>
@@ -6,6 +6,7 @@
urlpatterns= patterns('',
url(r'^$', views.home_page, name='home'),
url(r'^all_status$', views.view_status, name='view_status'),
url(r'^metrics_data$', views.metrics_data, name='metrics_data'),
url(r'^experiments/manage$', views.manage_exps, name='manage_exps'),
url(r'^experiments/details/(?P<exppk>.*)$', views.view_exp_details, name='view_exp_details'),
url(r'^experiment/edit/(?P<exppk>.*)$', views.edit_exp, name='edit_exp'),
@@ -1,6 +1,10 @@
import json
import os.path

from django.shortcuts import render, redirect
from op_tasks.models import UserProfile, Product, Dataset, OpTask, TaskListItem, Experiment
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_protect
from django.http import JsonResponse
from users import *
from products import *
@@ -18,6 +22,46 @@ def home_page(request):
if user_authorized(request):
return render(request, 'experimenthome.html')

@csrf_protect
@login_required(login_url='/tasking/login')
def metrics_data(request):
rparams = json.loads(request.body)
if request.method == 'POST':
experiment = rparams['experiment']
category = rparams['category']
tool = rparams['tool']
task = rparams['task']
# load experiment data from file
histDataFile = "/home/ubuntu/SCOtCH/"+experiment+".json"
histDataAll = []
if os.path.isfile(histDataFile):
with open(histDataFile) as data_file:
histDataAll = json.load(data_file)
# filter experiment data
histData = []
for row in histDataAll:
if (tool!="all" and tool!=row['SYS.FIL.APP.']) or (task!="all" and task!=row['SYS.FIL.TSK.']):
continue
if category=="Load":
if row['PST.EXP.CLD.'] != "NA" and row['PST.EXP.CLD.'] != "NaN":
histData.append(row['PST.EXP.CLD.'])
elif category=="Difficulty":
if row['PST.EXP.BED.'] != "NA" and row['PST.EXP.BED.'] != "NaN":
histData.append(row['PST.EXP.BED.'])
elif category=="Performance":
if row['TSK.PRB.ANS.'] != "NA" and row['TSK.PRB.ANS.'] != "NaN":
histData.append(row['TSK.PRB.ANS.'])
elif category=="Confidence":
if row['TSK.CON.'] != "NA" and row['TSK.CON.'] != "NaN":
histData.append(row['TSK.CON.'])
elif category=="Time":
if row['TSK.TIME.DIFF.'] != "NA" and row['TSK.TIME.DIFF.'] != "NaN" and row['TSK.TIME.DIFF.'] > 0 and row['TSK.TIME.DIFF.'] < 3000:
histData.append(row['TSK.TIME.DIFF.'])

return JsonResponse({"data":json.dumps(histData)})
else:
return JsonResponse({"request": "Not Supported"})

@login_required(login_url='/tasking/login')
def view_status(request):
if user_authorized(request):
@@ -196,4 +240,4 @@ def view_experiment_products(request):
experimentList["percentageComplete"] = percentageComplete
masterList[name] = experimentList
response = JsonResponse({'experimentInfo': str(masterList)})
return response
return response
@@ -1000,6 +1000,21 @@ div.product-instructions .glyphicon{
text-anchor: end;
}

.bar rect {
fill: steelblue;
shape-rendering: crispEdges;
}

.bar text {
fill: #fff;
}

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

.emailRow {
float: left;
margin-bottom: 20px;
@@ -1,3 +1,18 @@
var csrftoken = $.cookie('csrftoken');

function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});

$("#contacts li").click(function(){
var emailAddress = $(this).html();
$("#email-to").val(emailAddress);
@@ -44,16 +59,30 @@ $(".expTrayNavBtn").on("click", function(){
var divId = id.slice(0, -3);
$this.find(".expTraySection").removeClass("active");
$this.find("#" + divId).addClass("active");

if(divId=="metrics") {
var experiment = $(this).parents(".experimentStatusRow").attr("id");
var category = $this.find(".metricsNavBtn.active").attr("data-category");
var mparams = {"experiment":experiment,"tool":$this.find("#toolsSelect").val(),"task":$this.find("#tasksSelect").val(),"category":category};
getHistData(experiment, category, JSON.stringify(mparams));
}
})

$(".metricsNavBtn").click(function(){
$(this).parent().find(".metricsNavBtn").removeClass("active");
$(this).addClass("active");
var rowId = $(this).parents(".experimentStatusRow").attr("id");
$("#" + rowId + " .metricsSection").removeClass("active");
var id = $(this).attr("id");
id = id.slice(0, -3);
$("#" + id).addClass("active");
//var rowId = $(this).parents(".experimentStatusRow").attr("id");
//$("#" + rowId + " .metricsSection").removeClass("active");
//var id = $(this).attr("id");
//id = id.slice(0, -3);
//$("#" + id).addClass("active");

var $this = $(this).parents(".expTray");
var experiment = $(this).parents(".experimentStatusRow").attr("id");
var category = $(this).attr("data-category");
var mparams = {"experiment":experiment,"tool":$this.find("#toolsSelect").val(),"task":$this.find("#tasksSelect").val(),"category":category};
//console.log(".metricsNavBtn experiment = ", mparams);
getHistData(experiment, category, JSON.stringify(mparams));
})

$(".expShelf").click(function(){
@@ -75,15 +104,24 @@ var start = true;
loopCharts(start);

$("#toolsSelect, #tasksSelect").change(function(){
start = false;
var id = $(this).parents(".experimentStatusRow").attr("id");
$(".chart").empty();
loopCharts(start, id);
// start = false;
// var id = $(this).parents(".experimentStatusRow").attr("id");
// $(".chart").empty();
// loopCharts(start, id);

var $this = $(this).parents(".expTray");
var experiment = $(this).parents(".experimentStatusRow").attr("id");
var category = $this.find(".metricsNavBtn.active").attr("data-category");
var mparams = {"experiment":experiment,"tool":$this.find("#toolsSelect").val(),"task":$this.find("#tasksSelect").val(),"category":category};
//console.log(".metricsNavBtn experiment = ", mparams);
getHistData(experiment, category, JSON.stringify(mparams));

});

function loopCharts(start, id) {
if (start==true) {
startChartBuildwithToolLists();
//startChartBuildwithToolLists();
buildCharts();
} else if (start==false) {
buildCharts();
}
@@ -239,3 +277,96 @@ function buildD3Chart(dataPath, chartId, tool) {
}
}

function getHistData(experimentName, categoryName, params) {
var xtick = 1;
if(categoryName=="Load") {
xtick = 2;
} else if(categoryName=="Time") {
xtick = 0.01;
}
$.ajax({
'type': 'POST',
'url': 'metrics_data',
'contentType': 'application/json',
'data': params,
'dataType': 'json',
'complete': function(xhrObj, msg){
//console.log(xhrObj);
var values = JSON.parse(xhrObj.responseJSON.data);
//console.log(values);
if(values.length>0) {
buildD3Histogram('#canvasD3[data-experiment="'+experimentName+'"]', xtick, values);
} else {
$('#canvasD3[data-experiment="'+experimentName+'"]').text("Data unavailable.")
}
}
});

}

function buildD3Histogram(canvasSelector, tickScale, histValues) {
$(canvasSelector).empty();

// Generate a Bates distribution of 10 random variables.
//var values = d3.range(1000).map(d3.random.bates(10));
var values = histValues;

var minVal = Math.floor(Math.min.apply(Math, values));
var maxVal = Math.ceil(Math.max.apply(Math, values));

// A formatter for counts.
var formatCount = d3.format(",.0f");

var margin = {top: 10, right: 30, bottom: 30, left: 30},
//width = 960 - margin.left - margin.right,
width = $(canvasSelector).width(),
//height = 500 - margin.top - margin.bottom;
height = 320;

var x = d3.scale.linear()
.domain([0, maxVal+minVal])
.range([0, width]);

// Generate a histogram using twenty uniformly-spaced bins.
var data = d3.layout.histogram()
.bins(x.ticks((maxVal+minVal)*tickScale))
(values);

var y = d3.scale.linear()
.domain([0, d3.max(data, function(d) { return d.y; })])
.range([height, 0]);

var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");

var svg = d3.select(canvasSelector).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var bar = svg.selectAll(".bar")
.data(data)
.enter().append("g")
.attr("class", "bar")
.attr("transform", function(d) { return "translate(" + x(d.x) + "," + y(d.y) + ")"; });

bar.append("rect")
.attr("x", 1)
.attr("width", x(data[0].dx) - 1)
.attr("height", function(d) { return height - y(d.y); });

bar.filter(function(d) { return d.y>0; })
.append("text")
.attr("dy", ".75em")
.attr("y", 6)
.attr("x", x(data[0].dx) / 2)
.attr("text-anchor", "middle")
.text(function(d) { return formatCount(d.y); });

svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
}

0 comments on commit 142d78f

Please sign in to comment.