Skip to content

Commit

Permalink
Merge pull request #128 from wrench-project/addPedagogicGraphs
Browse files Browse the repository at this point in the history
Finished Host utilization graph
  • Loading branch information
rafaelfsilva authored Nov 27, 2019
2 parents 2f87d52 + aa5b080 commit 0534701
Show file tree
Hide file tree
Showing 10 changed files with 455 additions and 56 deletions.
29 changes: 29 additions & 0 deletions tools/wrench/dashboard/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,34 @@ <h6 class='title-text'>3D Visualisation</h6>
<svg width="100%" height="1000px" id='three-d-graph-svg'></svg>
</div>
</div>

<div class='element-and-title-container'>
<div class='title-container' onclick='showHideArrow("host-utilization-graph-container", "host-utilization-arrow")'>
<h6 class='title-text'>Host Utilization Graph</h6>
<div class='arrow-div'>
<span class='arrow-helper'></span>
<img id='host-utilization-arrow' class='arrow-img' src='public/expand-arrow.png'/>
</div>
</div>

<div class='hidden' id='host-utilization-graph-container' style="padding: 10px">
<div class="chart" id="host-utilization-chart">

<div class="container legend" id="host-utilization-chart-legend">
<small class="inline-block" id="host-utilization-chart-legend-compute-time">Compute Time</small>
<small class="inline-block" id="host-utilization-chart-legend-idle-time">Idle Time</small>
</div>

<div class="text-left" id="host-utilization-chart-tooltip">
<span id="host-utilization-chart-tooltip-task-id"></span><br>
<span id="host-utilization-chart-tooltip-compute-time"></span><br>
</div>

</div>
</div>

</div>

</div>
</body>
<script src="scripts/data.js" ></script>
Expand All @@ -209,5 +237,6 @@ <h6 class='title-text'>3D Visualisation</h6>
<script src="scripts/graph-sections/simulation-details.js"></script>
<script src="scripts/graph-sections/simulation-graph.js"></script>
<script src="scripts/graph-sections/workflow-summary.js"></script>
<script src="scripts/graph-sections/host-utilization.js"></script>
<script src="scripts/initialise.js"></script>
</html>
21 changes: 21 additions & 0 deletions tools/wrench/dashboard/public/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,25 @@ td {

.error-text {
color: red;
}

#host-utilization-chart-tooltip {
position: absolute;
width: auto;
padding: 10px;
background-color: #f2f2f2;
border-radius: 2px;
border: 0px solid #000;
display: none;
pointer-events: none;
font-family: sans-serif;
font-size: 12px;
}

#host-utilization-chart-legend-compute-time {
border-left: 15px solid #f7daad;
}

#host-utilization-chart-legend-idle-time {
border-left: 15px solid #ffd8f8;
}
2 changes: 1 addition & 1 deletion tools/wrench/dashboard/scripts/button-clicks.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ function toggleView() {
}
currGraphState = "hostView"
} else if (currGraphState === "hostView") {
generateGraph(data.contents, "graph-container")
generateGraph(data.contents, "graph-container", "hostView", 1000, 1000)
d3.select("#y-axis-label").text("TaskID")
populateLegend("taskView")
d3.select("#toggle-view-button").text("Switch to Host View")
Expand Down
4 changes: 2 additions & 2 deletions tools/wrench/dashboard/scripts/data.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var data={"modified":"2019-06-02T03:09:44.509Z","file":"test_data/test_data_host.json","contents":[{"compute":{"end":-1,"start":-1},"execution_host":{"hostname":"Host1"},"failed":2,"num_cores_allocated":1,"read":{"end":-1,"start":0},"task_id":"ID00000","terminated":-1,"whole_task":{"end":-1,"start":0},"write":{"end":-1,"start":-1}},{"compute":{"end":-1,"start":13},"execution_host":{"hostname":"Host2"},"failed":-1,"num_cores_allocated":1,"read":{"end":13,"start":10},"task_id":"ID00001","terminated":14,"whole_task":{"end":-1,"start":10},"write":{"end":-1,"start":-1}},{"compute":{"end":26,"start":23},"execution_host":{"hostname":"Host3"},"failed":-1,"num_cores_allocated":1,"read":{"end":23,"start":20},"task_id":"ID00002","terminated":28,"whole_task":{"end":-1,"start":20},"write":{"end":-1,"start":26}}]}
var energyData=[{"consumed_energy_trace":[{"time":0,"joules":0},{"time":2,"joules":400},{"time":4,"joules":800},{"time":6,"joules":1200}],"hostname":"host1","pstate_trace":[{"pstate":1,"time":0},{"pstate":0,"time":2}],"pstates":[{"idle":"100.0","pstate":0,"running":"200.0","speed":100000000},{"idle":" 93.0","pstate":1,"running":"170.0","speed":50000000},{"idle":" 90.0","pstate":2,"running":"150.0","speed":20000000}],"watt_off":"10"},{"consumed_energy_trace":[{"time":0,"joules":0},{"time":2,"joules":200},{"time":4,"joules":400},{"time":6,"joules":600}],"hostname":"host2","pstate_trace":[{"pstate":0,"time":0},{"pstate":1,"time":2}],"pstates":[{"idle":"100.0","pstate":0,"running":"200.0","speed":100000000},{"idle":" 93.0","pstate":1,"running":"170.0","speed":50000000},{"idle":" 90.0","pstate":2,"running":"150.0","speed":20000000}],"watt_off":"10"}]
var data={}
var energyData=[]
var currGraphState = "taskView"
var hostColours = {}
var currentlySelectedHost = {hostName: "", id: ""}
Expand Down
49 changes: 0 additions & 49 deletions tools/wrench/dashboard/scripts/graph-sections/3d-visualization.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,55 +126,6 @@ function searchOverlap(taskId, taskOverlap) {
}
}

function determineTaskEnd(d) {
var taskEnd
if (d.terminated !== -1) {
taskEnd = d.terminated
} else if (d.failed !== -1) {
taskEnd = d.failed
} else {
taskEnd = d.whole_task.end
}
return taskEnd
}

function determineTaskOverlap(data) {
var taskOverlap = {}
data.forEach(function(d) {
var taskStart = d.whole_task.start
var taskEnd = determineTaskEnd(d)
if (Object.keys(taskOverlap).length === 0) {
taskOverlap[0] = []
taskOverlap[0].push(d)
} else {
var i = 0
var placed = false
while (!placed) {
if (taskOverlap[i] === undefined) {
taskOverlap[i] = []
}
var overlap = false
for (var j = 0; j < taskOverlap[i].length; j++) {
var t = taskOverlap[i][j]
var currTaskStart = t.whole_task.start
var currTaskEnd = determineTaskEnd(t)
if ((taskStart >= currTaskStart && taskStart <= currTaskEnd) || (taskEnd >= currTaskStart && taskEnd <= currTaskEnd)) {
i++
overlap = true
break
}
}
if (!overlap) {
taskOverlap[i].push(d)
placed = true
}
}
}
})
return taskOverlap
}


function makeCube(h, x, z, duration, colour, taskId){
return [
{x: x , y: h, z: z + duration}, // FRONT TOP LEFT
Expand Down
203 changes: 203 additions & 0 deletions tools/wrench/dashboard/scripts/graph-sections/host-utilization.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
function determineNumCores(data) {
var numCores = 0;
var taskOverlap = determineTaskOverlap(data);
for (var i = 0; i < Object.keys(taskOverlap).length; i++) {
var currOverlap = taskOverlap[i];
var maxCores = 0;
for (var j = 0; j < currOverlap.length; j++) {
var t = currOverlap[j];
if (t.num_cores_allocated > maxCores) {
maxCores = t.num_cores_allocated;
}
}
numCores += maxCores;
}
return numCores;
}

function getComputeTime(d) {
if (d["compute"].start != -1) {
if (d["compute"].end == -1) {
if (d.terminated != -1) {
return d.terminated - d["compute"].start
} else if (d.failed != -1){
return d.failed - d["compute"].start
}
} else {
return d["compute"].end - d["compute"].start
}
}
return 0 //Box shouldn't be displayed if start is -1
}

function generateHostUtilizationGraph(data, containerId, tooltipId, tooltipTaskId, tooltipComputeTime, CONTAINER_WIDTH, CONTAINER_HEIGHT) {
var num_cores = determineNumCores(data);
var container = d3.select(`#${containerId}`);
var chart = document.getElementById(containerId);
const PADDING = 60;

var svg = d3.select("svg");

if (svg.empty()) {
svg.remove();
}

var tooltip = d3.select(`#${tooltipId}`);
var tooltip_task_id = d3.select(`#${tooltipTaskId}`);
var tooltip_compute_time = d3.select(`#${tooltipComputeTime}`)

svg = container.append("svg")
.attr("width", CONTAINER_WIDTH)
.attr("height", CONTAINER_HEIGHT);

var x_scale = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.whole_task.end;
})])
.range([PADDING, CONTAINER_WIDTH - PADDING]);

var tasks_by_hostname = d3.nest()
.key(function(d) { return d.execution_host.hostname; })
.sortKeys(d3.ascending)
.entries(data);

var y_hosts = d3.scaleBand()
.domain(tasks_by_hostname.map(function(d) {
return d.key;
}))
.range([CONTAINER_HEIGHT - PADDING, 10])
.padding(0.1);

var y_cores_per_host = d3.map();

if (num_cores === 0) {
tasks_by_hostname.forEach(function (d) {
y_cores_per_host.set(d.key,
d3.scaleLinear()
.domain([0, d.values[0].execution_host.cores])
.range([y_hosts(d.key) + y_hosts.bandwidth(), y_hosts(d.key)])
);
});
} else {
tasks_by_hostname.forEach(function (d) {
y_cores_per_host.set(d.key,
d3.scaleLinear()
.domain([0, num_cores])
.range([y_hosts(d.key) + y_hosts.bandwidth(), y_hosts(d.key)])
);
});
}

svg.append('g').selectAll('rect')
.data(y_cores_per_host.keys())
.enter()
.append("rect")
.attr("x", PADDING)
.attr("y", function(d) {
return y_hosts(d);
})
.attr("width", CONTAINER_WIDTH - PADDING - PADDING)
.attr("height", y_hosts.bandwidth())
.attr("opacity", 0.3)
.attr("fill", "#ffd8f8");


svg.append('g').selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x", function(d) {
return x_scale(d.compute.start);
})
.attr("y", function(d) {
var y_scale = y_cores_per_host.get(d.execution_host.hostname);
return y_scale(d.vertical_position + d.num_cores_allocated);
})
.attr("width", function(d) {
return x_scale(d.compute.end) - x_scale(d.compute.start);
})
.attr("height", function(d) {
var y_scale = y_cores_per_host.get(d.execution_host.hostname);
return y_scale(0) - y_scale(d.num_cores_allocated);
})
.attr("fill", "#f7daad")
.attr("stroke", "gray")
.on('mouseover', function() {
tooltip.style('display', 'inline');

d3.select(this)
.attr('fill', '#ffdd7f');
})
.on('mousemove', function(d) {
var offset = getOffset(chart, d3.mouse(this));
var x = window.scrollX + offset.left + 20
var y = window.scrollY + offset.top - 30 // 20 se

tooltip.style('left', x + 'px')
.style('top', y + 'px');

tooltip_task_id.text('TaskID: ' + d.task_id);
tooltip_compute_time.text('Compute Time: ' + getComputeTime(d) + 's');
})
.on('mouseout', function(d) {
tooltip.style('display', 'none');

d3.select(this)
.attr('fill', '#f7daad')
});


var x_axis = d3.axisBottom(x_scale)
.ticks(d3.max(data, function(d) {
return d.end;
}));

svg.append("g")
.attr("class", "x-axis")
.attr("transform",
"translate(0," + (CONTAINER_HEIGHT - PADDING) + ")")
.call(x_axis);

var y_axis = d3.axisLeft(y_hosts).tickSize(0);

svg.append("g")
.attr("class", "y-axis")
.attr("stroke-width", "0px")
.attr("transform",
"translate(20, 0)")
.call(y_axis)
.selectAll("text")
.attr("transform", "rotate(-90)")
.attr("text-anchor", "middle");

y_cores_per_host.entries().forEach(function(entry) {
var axis = d3.axisLeft(entry.value)
.tickValues(d3.range(0, entry.value.domain()[1] + 1, 1))
.tickFormat(d3.format(""));;

svg.append("g")
.attr("class", "y-axis2")
.attr("transform",
"translate(" + PADDING + ",0)")
.call(axis);
});

svg.append("text")
.attr("transform",
"translate(" + (CONTAINER_WIDTH / 2) + " ," + (CONTAINER_HEIGHT - 10) + ")")
.style("text-anchor", "middle")
.attr('font-size', 12+'px')
.attr('fill', 'gray')
.text("Time (seconds)");

svg.append("text")
.attr("transform",
"rotate(-90)")
.attr("y", -3)
.attr("x", 0 - (CONTAINER_HEIGHT / 2))
.attr("dy", "1em")
.attr("text-anchor", "middle")
.attr('font-size', 12+'px')
.attr('fill', 'gray')
.text("Host");
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function getOffset(el, position) {
containerId: id of <div> container of graph
currGraphState: pass in "hostView" to see the host view and "taskView" to see the task view
*/
function generateGraph(data, containerId, currGraphState) {
function generateGraph(data, containerId, currGraphState, CONTAINER_WIDTH, CONTAINER_HEIGHT) {
document.getElementById(containerId).innerHTML = //reset graph
`<div class="text-left" id="tooltip-container">
<span id="tooltip-task-id"></span><br>
Expand All @@ -59,8 +59,6 @@ function generateGraph(data, containerId, currGraphState) {
var compute_color = '#f7daad'
var write_color = '#abdcf4'
var container = d3.select(`#${containerId}`)
const CONTAINER_WIDTH = 1000
const CONTAINER_HEIGHT = 1000
const PADDING = 60
var svg = container
.append("svg")
Expand Down
3 changes: 2 additions & 1 deletion tools/wrench/dashboard/scripts/initialise.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ function initialise() {
} else {
noFileDiv.style.display = "none"
mainBodyDiv.style.display = "block"
generateGraph(data.contents, "graph-container", currGraphState)
generateGraph(data.contents, "graph-container", currGraphState, 1000, 1000)
populateLegend("taskView")
populateWorkflowTaskDataTable(data.contents, "task-details-table", "task-details-table-body", "task-details-table-td")
getOverallWorkflowMetrics(data.contents, "overall-metrics-table", "task-details-table-td")
generate3dGraph(data.contents, true, "three-d-graph-svg", "origin-x", "origin-y", "time-interval", "scale-input")
generateHostUtilizationGraph(data.contents, "host-utilization-chart", "host-utilization-chart-tooltip", "host-utilization-chart-tooltip-task-id", "host-utilization-chart-tooltip-compute-time", 1000, 1000)
}
}

Expand Down
Loading

0 comments on commit 0534701

Please sign in to comment.