-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplot.js
106 lines (98 loc) · 3.76 KB
/
plot.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
class BoxPlot {
// fields
svg;
width;
height;
xScale;
yScale;
constructor(elementId) {
const margin = {top: 20, right: 20, bottom: 30, left: 40};
this.width = 1000 - margin.left - margin.right,
this.height = 1800 - margin.top - margin.bottom;
this.xScale = d3.scale.ordinal().rangeRoundBands([0,this.width], .1, 1);
this.yScale = d3.scale.linear().range([0,this.height]);
this.svg = d3.select(elementId).append("svg")
.attr("width", this.width + margin.left + margin.right)
.attr("height", this.height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate("+margin.left+","+margin.top+")");
}
build(url) {
d3.json(url, (error,data)=> {
this.xScale.domain( data.sort( (a,b)=>{return a.rank-b.rank;} ).map( (d)=>{return d.rank.toString();} ) );
this.yScale.domain([
0.0,
d3.max(data, (d)=>{ return d.finish_at;})
]);
this.buildAxis();
const tooltip = d3.select('span#tooltip');
this.svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", (d) => { return this.xScale(d.rank.toString()); })
.attr("width", this.xScale.rangeBand())
.attr("y", (d) => { return this.yScale(d.start_at); })
.attr("height", (d) => { return this.yScale(d.finish_at - d.start_at); })
.attr("rx", 4).attr("ry", 4)
.style("opacity", .8)
.on("mouseover", function(d) {
d3.select(this).style("opacity", 1);
let t = `task_id: ${d.task_id}, time: ${d.start_at} - ${d.finish_at}, rank: ${d.rank}, output: ${JSON.stringify(d.output)}`
if (d.input) { t += `, input: ${JSON.stringify(d.input)}`; }
tooltip.style("visibility", "visible")
.text(t);
})
.on("mousemove", function(d){
tooltip
.style("top", (d3.event.pageY-20)+"px")
.style("left", (d3.event.pageX+10)+"px");
})
.on("mouseout", function(d) {
d3.select(this).style("opacity", .8);
tooltip.style("visibility", "hidden");
});
this.updateRankRange();
});
}
buildAxis() {
const xAxis = d3.svg.axis().scale(this.xScale).orient("bottom");
const yAxis = d3.svg.axis().scale(this.yScale).orient("left");
this.svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + this.height + ")")
.call(xAxis);
this.svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Time");
}
updateRankRange() {
const domain = this.xScale.domain();
const s = `${domain[0]}-${domain[domain.length-1]}`;
d3.select('#rank_range_input')[0][0].value = s;
}
}
document.body.onload = () => {
d3.json('/filling_rate', (err, data) => {
d3.select('#input_file').text("File: " + data["file"] + " (" + data["file_info"] + ")");
d3.select('#num_runs').text("# of Runs: " + data["num_runs"]);
d3.select('#filling_rate').text("filling rate: " + data["filling_rate"] * 100.0 + " %");
d3.select('#rank_range').text("rank range: " + data["rank_range"][0] + " - " + data["rank_range"][1]);
d3.select('#num_consumer_ranks').text("# of consumer ranks: " + data["num_consumer_ranks"]);
d3.select('#max_finish_at').text("max finish at: " + data["max_finish_at"]);
});
var box = new BoxPlot('#plot');
box.build('/runs');
};
d3.select('#rank_range_update').on('click', () => {
var url = '/runs?rank=' + d3.select('#rank_range_input')[0][0].value;
d3.select('#plot').selectAll("*").remove();
var box = new BoxPlot('#plot');
box.build(url);
});