forked from hazrmard/QLearning
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdemo.html
151 lines (140 loc) · 6.48 KB
/
demo.html
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<!DOCTYPE html>
<!--This is a HTML template rendered by demo.py-->
<html style="height: 100%; width: 100%">
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<style> /* set the CSS */
.line {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
</style>
</head>
<body style="padding: 0px; margin: 0px; height: 100%; width: 100%">
<svg style="height: 90%; width: 100%"></svg>
<div class="control-panel" style="width: 100%; text-align: center">
<button autofocus type="button" id="btnStart">Start</button>
<button type="button" id="btnStop">Stop</button>
</div>
<script>
// Template variables
{% autoescape false %}
var N = {{ N }}; // number of levels per tank/ max tank capacity+1
var T = {{ T }}; // number of tanks
var L = {{ L }}; // Tank labels
var O = {{ O }}; // Tank order
{% endautoescape %}
var W = d3.select("svg")._groups[0][0].clientWidth | document.getElementsByTagName("svg")[0].getBoundingClientRect().width;
var H = d3.select("svg")._groups[0][0].clientHeight | document.getElementsByTagName("svg")[0].getBoundingClientRect().height;
var timeout = 1000;
var width = W / (2*T); // width of each tank
var height = H / 3; // height of tank, graph
var gapx = (W - (T * width)) / (T+1);
var gapy = height / 3; // arbitrary vertical spacing
var levelScale = d3.scaleLinear().domain([0, N-1]).range([0, height]).clamp(true);
var colourScale = d3.scaleLinear().domain([0, N-1]).range(["red", "blue"]).clamp(true);
// header text
var text = d3.select("svg").append("text")
.attr("x", W / 2)
.attr("y", gapy/2)
.attr("text-anchor", "middle")
.attr("font-size", "25px");
// container for all tanks
var tanks = d3.select("svg").append("g")
// container for graph
var graph = d3.select("svg").append("g")
.attr("transform", "translate(" + gapx + "," + (gapy + height + gapy) + ")");
// draw tanks and labels
for (var n=0; n<T; n++) {
var i = O[n]; // get tank labels' order. Label n is at ith pos
// tank outlines
tanks.append("rect")
.attr("x", gapx*(i+1) + width*i)
.attr("y", gapy)
.attr("width", width)
.attr("height", height)
.style("stroke", "black")
.style("stroke-width", "3px")
.style("fill", "none");
// tank labels
tanks.append("text")
.attr("x", gapx*(i+1) + width*(i+0.5))
.attr("y", gapy + height + 25)
.attr("font-size", "25px")
.attr("text-anchor", "middle")
.text(L[n]);
// tank fills
tanks.append("rect")
.attr("class", "tank")
.attr("x", gapx*(i+1) + width*i)
.attr("y", gapy)
.attr("width", width)
.attr("height", height)
.style("fill", "blue");
}
// draw the graph
var yScale = d3.scaleLinear().domain([0, -1]).range([0, height]).clamp(true);
var xScale = d3.scaleLinear().domain([0, 1]).range([0, W-2*gapx]).clamp(true);
var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale);
var line = d3.line()
.x(function(d, i) {return xScale(i)})
.y(function(d, i) {return yScale(d)});
graph.append("g")
.attr("class", "xaxis")
.attr("transform", "translate(" + 0 + "," + height + ")")
.call(xAxis);
graph.append("g")
.attr("class", "yaxis")
.call(yAxis);
var linePath = graph.append("path")
.attr("class", "line");
// define regular update function
var stopFlag = true; // indicates update is paused
var count = 0; // timesteps passed
var imbalances = []; // record of imbalances
var update = function() {
d3.json('/status', function(data) {
count++;
console.log(data.imbalance)
imbalances.push(data.imbalance);
// update tank level displays
d3.selectAll(".tank")
.data(data.levels)
.transition()
.duration(timeout / 2)
.attr("y", function(d) {return gapy + height - levelScale(d)})
.attr("height", levelScale)
.style("fill", colourScale);
text.text(data.action.length == 0 ? "" : data.action);
// modify graph
xScale.domain([0, count]);
yScale.domain([0, d3.min([yScale.domain()[1], data.imbalance])]);
graph.select(".xaxis")
.transition().duration(timeout)
.call(xAxis);
graph.select(".yaxis")
.transition().duration(timeout)
.call(yAxis);
linePath.data([imbalances])
.transition()
.duration(timeout)
.attr("d", line);
if (!stopFlag) {
setTimeout(update, timeout);
}
});
}
// add functionality to start button
document.getElementById("btnStart").addEventListener("click", function() {
stopFlag = false;
update();
})
// add functionality to stop button
document.getElementById("btnStop").addEventListener("click", function() {
stopFlag = true;
})
</script>
</body>
</html>