moodmeter/graphs.php

511 lines
12 KiB
PHP

<html>
<head>
<title>Results of analysis: The Black Box Concern</title>
<script type="text/javascript" src="lodash.core.min.js"></script>
<script type="text/javascript" src="plotly-1.31.2.min.js"></script>
<script type="text/javascript">
var d1 = <?php echo require "output/talk1.json" ?>;
var d2 = <?php echo require "output/talk2.json" ?>;
//~ var d3 = <?php echo require "output/talk3.json" ?>;
</script>
<style type="text/css">
body{
font-family: sans-serif;
width:calc(88%);
margin-left:12%;
margin-right:0;
}
#scroller{
width:100%;
overflow-x:auto;
}
#presentations{
width:200%;
}
#presentations .presentation{
width:50%;
float:left;
}
#presentations .presentation div.plot{
width:100%;
height:10em;
}
#checkboxes{
font-size: .8em;
width: 13em;
position:absolute;
left:0;
top:0;
}
label{
display:block;
}
.legendColour{
width:1em;
height:1em;
display:inline-block;
float:right;
margin-top:0.6em;
}
#checkboxes span{
color: gray;
}
#checkboxes :checked + span{
color: black;
}
#imgwrap{
}
#imgwrap div{
display:block;
color:#999;
font-size:80%;
}
#imgwrap img{
height:7em;
min-width: 3em;
background:#ccc;
margin-left:2%;
margin-top:1em;
}
h1{
margin: .1em 0;
text-transform:uppercase;
height:.9em;
}
</style>
</head>
<body>
<div id="checkboxes">
</div>
<div id="scroller">
<div id='presentations'>
<div class='presentation'>
<h1>Penousal Machado</h1>
<div class='stats' id='plot2-stats'></div>
<div class='plot' id="plot2-div"></div>
</div>
<div class='presentation'>
<h1>Orit Halpern</h1>
<div class='stats' id='plot1-stats'></div>
<div class='plot' id="plot1-div"></div>
</div>
<!--
<div class='presentation'>
<h1>Nicolas Maigret</h1>
<div class='stats' id='plot3-stats'></div>
<div class='plot' id="plot3-div"></div>
</div>
-->
</div>
</div>
<div id='imgwrap'>
</div>
<script type='text/javascript'>
facialParameters = [
"smile",
"innerBrowRaise",
"browRaise",
"browFurrow",
"noseWrinkle",
"upperLipRaise",
"lipCornerDepressor",
"chinRaise",
"lipPucker",
"lipPress",
"lipSuck",
"mouthOpen",
"smirk",
"eyeClosure",
"eyeWiden",
"cheekRaise",
"lidTighten",
"dimpler",
"lipStretch",
"jawDrop",
]
defaultFacialParameters = [
"smile",
"innerBrowRaise",
"browRaise",
"browFurrow",
"noseWrinkle",
//~ "upperLipRaise",
//~ "lipCornerDepressor",
"chinRaise",
// "lipPucker",
//~ "lipPress",
//~ "lipSuck",
//~ "mouthOpen",
//"smirk",
// "attention",
//~ "eyeClosure",
//~ "eyeWiden",
"cheekRaise", //
"lidTighten",
//~ "dimpler", //
//~ "lipStretch",
//~ "jawDrop", //
];
var paramColours = {
"smile":"#FFA500",
"innerBrowRaise":"#FF3300",
"browRaise":"#FF003D",
"browFurrow":"#FF0095",
"noseWrinkle":"#E000FF",
"upperLipRaise":"#9B00FF",
"lipCornerDepressor":"#5800FF",
"chinRaise":"#0053FF",
"lipPucker":"#00C1FF",
"lipPress":"#00FF8C",
"lipSuck":"#0BFF00",
"mouthOpen":"#8CFF00",
"smirk":"#DCFF00",
"eyeClosure":"#A3841A",
"eyeWiden":"#852D0C",
"cheekRaise":"#850C3B",
"lidTighten":"#301271",
"dimpler":"#214761",
"lipStretch":"#216156",
"jawDrop":"#326121",
}
function getCheckedParams(){
params = [];
for(var i in facialParameters){
let param = facialParameters[i];
if(document.getElementById("check_"+param).checked){
params.push(param);
}
}
return params;
}
// expresiveness = average change in value
function getExpressivenessForParams(d, params)
{
let total = 0;
let nrs = 0;
for(let i in d['windows']) {
if(i == 0) {
continue;
}
nrs++;
let sub = 0;
for(let p in params) {
let param = params[p];
sub += Math.pow(d['windows'][i-1]['params'][param] - d['windows'][i]['params'][param], 2);
}
total += Math.sqrt(sub);
}
return total/nrs;
}
function getExpressivenessPerParam(d, params)
{
let paramValues = {};
for(let p in params) {
let param = params[p];
let value = 0;
for(let i in d['windows']) {
if(i == 0) {
continue;
}
value += Math.abs(d['windows'][i-1]['params'][param] - d['windows'][i]['params'][param]);
}
paramValues[param] = value / (d['windows'].length - 1);
}
return paramValues;
}
var checkboxWrapperEl = document.getElementById("checkboxes");
var d1ParamExpressiveness = getExpressivenessPerParam(d1, facialParameters);
var d2ParamExpressiveness = getExpressivenessPerParam(d2, facialParameters);
var d3ParamExpressiveness = getExpressivenessPerParam(d3, facialParameters);
for(var i in facialParameters){
let param = facialParameters[i];
var labelEl = document.createElement('label');
var checkboxEl = document.createElement('input');
var spanEl = document.createElement('span');
checkboxEl.type = "checkbox";
checkboxEl.checked = defaultFacialParameters.indexOf(param) > -1;
checkboxEl.id = "check_"+param;
checkboxEl.addEventListener('change',function(a){drawGraphs();});
labelEl.appendChild(checkboxEl);
spanEl.innerHTML = param;
labelEl.appendChild(spanEl);
var spanColourEl = document.createElement('span');
spanColourEl.style.background = paramColours[param];
spanColourEl.innerHTML = "&nbsp;";
spanColourEl.classList.add('legendColour');
labelEl.appendChild(spanColourEl);
checkboxWrapperEl.appendChild(labelEl);
labelEl.title = "Expressiveness: " + d1ParamExpressiveness[param] + ", " + d2ParamExpressiveness[param] + ", " + d3ParamExpressiveness[param];
}
var imgwrapEl = document.getElementById("imgwrap");
var plot1Div = document.getElementById('plot1-div');
var plot2Div = document.getElementById('plot2-div');
// var plot3Div = document.getElementById('plot3-div');
var stats1Div = document.getElementById('plot1-stats');
var stats2Div = document.getElementById('plot2-stats');
// var stats3Div = document.getElementById('plot3-stats');
function drawGraphs(){
params = getCheckedParams();
drawGraph("talk1", plot1Div, d1, params, stats1Div);
drawGraph("talk2", plot2Div, d2, params, stats2Div);
//~ drawGraph("talk3", plot3Div, d3, params);
}
function drawGraph(id, targetEl, d, params, statsEl) {
statsEl.innerHTML = "Total expressiveness: " + getExpressivenessForParams(d, params);
var data = [
/* {
name: "Mean",
x: d['windows'].map(function(w){return w['start'];}),
y: d['windows'].map(function(w){return _.mean(_.filter(w['params'], function(v, param){return params.indexOf(param) > -1}));}),
//~ error_y: {
//~ type: 'data',
//~ array: d['windows'].map(function(w){return w['stddev'];}),
//~ visible: true
//~ },
type: 'scatter',
line: {
//~ color: 'rgb(55, 128, 191)',
width: 5
}
}*/
];
var avgV = {};
for(var i in params){
param = params[i];
paramValues = d['windows'].map(function(w){return w['params'][param];});
data.push({
name: param,
x: d['windows'].map(function(w){return w['start'];}),
y: paramValues,
type: 'scatter',
line: {
color: paramColours[param],
width: 1.5
}
});
avgV[param] = _.mean(paramValues);
}
var devFunction = function(w){
let dev = 0;
for(var i in params){
let param = params[i];
dev += Math.pow(avgV[param] - w['params'][param], 2);
}
return Math.sqrt(dev);
};
data.push({
name: "Deviation",
x: d['windows'].map(function(w){return w['start'];}),
y: d['windows'].map(devFunction),
//~ error_y: {
//~ type: 'data',
//~ array: d['windows'].map(function(w){return w['stddev'];}),
//~ visible: true,
//~ color: '#f00'
//~ },
type: 'scatter',
line: {
color: '#800080',
width: 5
}
});
valFun = function(w){return w['params']['smile'] - (w['params']["innerBrowRaise"]+ w['params']["browFurrow"]+ w['params']["noseWrinkle"]+ w['params']["upperLipRaise"]+ w['params']["lipCornerDepressor"]+ w['params']["chinRaise"]+ w['params']["lipPress"]+ w['params']["lipSuck"])/8;};
var posWindow = _.maxBy(d['windows'], valFun);
var negWindow = _.minBy(d['windows'], valFun);
var devWindow = _.maxBy(d['windows'], devFunction);
var avgWindow = _.minBy(d['windows'], devFunction);
var diffWindow = _.maxBy(d['windows'], function(w){return w['stddev'];});
var concensusWindow = _.minBy(d['windows'], function(w){return w['stddev'];});
var annotations = [
//~ {
//~ x: posWindow['start'],
//~ y: posWindow['params']['smile'],
//~ xref: 'x',
//~ yref: 'y',
//~ text: 'Most positive moment',
//~ font: {color: 'gray'},
//~ showarrow: true,
//~ arrowhead: 7,
//~ ax: 0,
//~ ay: -40
//~ },
//~ {
//~ x: negWindow['start'],
//~ y: _.max([negWindow['params']["innerBrowRaise"], negWindow['params']["browFurrow"], negWindow['params']["noseWrinkle"], negWindow['params']["upperLipRaise"], negWindow['params']["lipCornerDepressor"], negWindow['params']["chinRaise"], negWindow['params']["lipPress"], negWindow['params']["lipSuck"]]),
//~ xref: 'x',
//~ yref: 'y',
//~ text: 'Most negative moment',
//~ font: {color: 'gray'},
//~ showarrow: true,
//~ arrowhead: 7,
//~ ax: 0,
//~ ay: -40
//~ },
{
x: devWindow['start'],
y: devFunction(devWindow),
xref: 'x',
yref: 'y',
text: 'Most deviant moment',
font: {color: 'gray'},
showarrow: true,
arrowhead: 7,
ax: 0,
ay: -40
},
{
x: avgWindow['start'],
y: devFunction(avgWindow),
xref: 'x',
yref: 'y',
text: 'Most average moment',
font: {color: 'gray'},
showarrow: true,
arrowhead: 7,
ax: 0,
ay: -40
},
{
x: avgWindow['start'],
y: devFunction(avgWindow),
xref: 'x',
yref: 'y',
text: 'Most average moment',
font: {color: 'gray'},
showarrow: true,
arrowhead: 7,
ax: 0,
ay: -40
},
{
x: diffWindow['start'],
y: devFunction(diffWindow),
xref: 'x',
yref: 'y',
text: 'Least concensus',
font: {color: 'gray'},
showarrow: true,
arrowhead: 7,
ax: 0,
ay: -40
},
{
x: concensusWindow['start'],
y: devFunction(concensusWindow),
xref: 'x',
yref: 'y',
text: 'Most concensus',
font: {color: 'gray'},
showarrow: true,
arrowhead: 7,
ax: 0,
ay: -40
}
]
var layout = {
//~ dragmode: 'zoom',
annotations: annotations,
//~ boxmode: 'group',
margin: {
r: 10,
t: 10,
b: 18,
l: 20
},
showlegend: false,
xaxis: {
autorange: true,
//~ domain: [0, 1],
//~ range: ['2017-01-03 12:00', '2017-02-15 12:00'],
//~ rangeslider: {range: ['2017-01-03 12:00', '2017-02-15 12:00']},
//~ title: 'Date',
type: 'date'
},
yaxis: {
autorange: true,
domain: [0, 1],
//~ range: [114.609999778, 137.410004222],
type: 'linear'
}
};
Plotly.newPlot(targetEl.id, data, layout,{displayModeBar: false});
//~ targetEl.on('plotly_click', function(data){
//~ console.log(data);
//~ var pts = '';
//~ for(var i=0; i < data.points.length; i++){
//~ pts = 'x = '+data.points[i].x +'\ny = '+
//~ data.points[i].y.toPrecision(4) + '\n\n';
//~ }
//~ alert('Closest point clicked:\n\n'+pts);
//~ });
targetEl.on('plotly_hover', function (data){
let HTML = "";
var points = data.points[0],
pointNum = points.pointNumber;
console.log(d);
for(let i in d['windows'][pointNum]['frames']) {
console.log(pointNum, d['windows'][pointNum]['frames'][i], data);
//~ imgEl.src = "/images.php?i="+d['windows'][pointNum]['frames'][i]+"&params="+params.join() + "&nr=" + d['outputNr'] ;
HTML+= "<div>"+d['windows'][pointNum]['frames'][i]+"<img src=\"/images.php?i="+d['windows'][pointNum]['frames'][i]+"&params="+params.join() + "&nr=" + d['outputNr'] +"\"></div>" ;
}
imgwrapEl.innerHTML = HTML;
var audio = new Audio('output/'+d['outputNr']+'/'+d['windows'][pointNum]['startFrame']+'.wav');
audio.play();
//~ Plotly.Fx.hover('plot-div',[
//~ { curveNumber:0, pointNumber:pointNum },
//~ { curveNumber:1, pointNumber:pointNum },
//~ { curveNumber:2, pointNumber:pointNum },
//~ ]);
});
//~ plotDiv.on('plotly_hover', function (eventdata){
//~ console.log(data);
//~ });
}
drawGraphs();
</script>
</body>
</html>