Tutorial 2 - Completed
Behavior Graph Tutorial 2 Completed
by slevin11
HTML
<html>
<head>
</head>
<body>
<div class="thermostat">
<div class="name">Tempwell</div>
<div class="display">
<div class="heat-display">
Heat: <span id="heatStatus"></span>
</div>
<div class="display-item">
<div class="display-item-title">Current</div>
<div class="display-item-text" id="currentTemperatureDisplay"></div>
</div>
<div class="display-spacer">
</div>
<div class="display-item">
<div class="display-item-title">Desired</div>
<div class="display-item-text" id="desiredTemperature"></div>
</div>
</div>
<div class="buttons">
<button id="up">Up</button>
<br />
<button id="down">Down</button>
</div>
</div>
</body>
</html>
CSS
.thermostat {
width: 400px;
height: 200px;
border: 3px solid #333;
padding: 20px;
}
.name {
font: 1.6em sans-serif;
margin-bottom: 50px;
}
.buttons {
display: inline-block;
vertical-align: top;
}
.buttons button {
width: 50px;
margin-bottom: 5px;
}
.display {
margin-right: 10px;
width: 290px;
height: 80px;
background-color: lightgray;
display: inline-block;
padding: 4px;
}
.heat-display {
font: 1em sans-serif;
margin-bottom: 4px;
}
.display-item {
display: inline-block;
vertical-align: top;
width: 100px;
text-align: center;
}
.display-item-title {
font: 0.8em sans-serif;
}
.display-item-text {
font: 1.4em sans-serif;
}
.display-spacer {
width: 50px;
display: inline-block;
vertical-align: top;
}
body {
font: 1.2em sans-serif;
}
JavaScript
import * as bg from "https://cdn.skypack.dev/behavior-graph";
class Thermostat extends bg.Extent {
constructor(graph) {
super(graph);
this.up = this.moment();
document.querySelector('#up').addEventListener('click', () => {
this.up.updateWithAction();
});
this.down = this.moment();
document.querySelector('#down').addEventListener('click', () => {
this.down.updateWithAction();
});
this.desiredTemperature = this.state(60);
this.currentTemperature = this.state(60);
this.heatOn = this.state(false);
this.behavior()
.demands(this.up, this.down, this.addedToGraph)
.supplies(this.desiredTemperature)
.runs(() => {
if (this.up.justUpdated) {
this.desiredTemperature.update(this.desiredTemperature.value + 1);
} else if (this.down.justUpdated) {
this.desiredTemperature.update(this.desiredTemperature.value - 1);
}
this.sideEffect(() => {
document.querySelector('#desiredTemperature').innerText = this.desiredTemperature.value;
});
});
this.behavior()
.demands(this.currentTemperature, this.addedToGraph)
.runs(() => {
this.sideEffect(() => {
document.querySelector('#currentTemperatureDisplay').innerText = this.currentTemperature.value;
});
});
this.behavior()
.supplies(this.heatOn)
.demands(this.currentTemperature, this.desiredTemperature, this.addedToGraph)
.runs(() => {
let heatOn = this.currentTemperature.value != null && this.desiredTemperature.value > this.currentTemperature.value;
this.heatOn.update(heatOn);
this.sideEffect(() => {
document.querySelector('#heatStatus').innerText = this.heatOn.value ? "On" : "Off"
});
});
this.behavior()
.demands(this.heatOn)
.runs(() => {
if (this.heatOn.justUpdatedTo(true)) {
this.sideEffect(() => {
this.heatingIntervalId =...