Lemonade Laboratory
Measure the concentration of lemonade in a sample.
by Wouter Vos
HTML
<!--script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"-->
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<body class="container">
<div>
<h1>Calibration Line - iVention Development Case</h1>
<p>Calibration Formula: y = ax + b</p>
<p>a = unknown</p>
<p>b = unknown</p>
<p>Results lemonade testing</p>
<table>
<thead>
<tr class="tableHeader">
<td class="col-sm-3">X Concentration</td>
<td class="col-sm-3">Y (theoretical)</td>
<td class="col-sm-3">Y (measured)</td>
<td>Include</td>
</tr>
</thead>
<tbody data-bind="foreach: calibrations">
<tr>
<td><input type="number" step="any" class="col-sm-3" data-bind="numeric, value: x" /></td>
<td><input type="number" step="any" class="col-sm-3" data-bind="numeric, value: yT" /></td>
<td><input type="number" step="any" class="col-sm-3" data-bind="numeric, value: yM" /></td>
<td><input type="checkbox" data-bind="checked: included" /></td>
<td><button class="col-sm-2" data-bind="click: $parent.remove">Remove</button></td>
</tr>
</tbody>
</table>
<p><button data-bind="click: add">Add Calibration</button></p>
<p>
<label for="sample">Measured value in sample:</label>
<input id="sample" type="number" step="any" class="col-sm-4" data-bind='value: sampleValue' />
</p>
<p>
<button click="calculate">Calculate values</button><br />
<label for="addition" class="col-sm-4">Unknown a (Addition):</label>
<input readonly id="addition" type="number" step="any" class="col-sm-4" data-bind='value: addition' />
<label for="factor" class="col-sm-4">Unknown b (Factor):</label>
<input readonly id="factor" type="number" step="any" class="col-sm-4" data-bind='value: factor' />
<label for="concentration" class="col-sm-4">Concentration:</label>
<input readonly id="concentration" type="number" step="any" class="col-sm-4"...
CSS
@import url('https://cdnjs.cloudflare.com/ajax/libs/jquery-ui-bootstrap/0.5pre/assets/css/bootstrap.min.css');
@import url('https://cdnjs.cloudflare.com/ajax/libs/jquery-ui-bootstrap/0.5pre/assets/css/font-awesome.min.css');
body { font-family: Verdana; font-size: 14px; }
.container {
margin-top: 10px;
margin-left: 10px;
}
.tableHeader {
font-weight: bold;
}
JavaScript
debugger;// Here's my data model
var ViewModel = function() {
var self = this;
self.concentration = ko.observable();
self.calibrations = ko.observableArray();
self.inclusions = ko.observableArray();
self.sampleValue = ko.observable();
self.addition = ko.observable();
self.factor = ko.observable();
self.sampleValue.subscribe(function(newValue) {
self.calculate();
});
self.add = function() {
self.calibrations.push({
// Data-binding expects the object to have these properties.
x: undefined,
yT: undefined,
yM: undefined,
included: true
});
};
self.remove = function(item) {
self.calibrations.remove(item);
};
// Find the concentration of the measured sample.
self.calculate = function() {
self.calibrations().forEach(function(cal) {
// User input is in string type, convert to number.
cal.x = Number(cal.x);
cal.yT = Number(cal.yT);
cal.yM = Number(cal.yM);
if(cal.included) {
self.inclusions.push(cal);
})
var xsum = 0, x2sum = 0, ysum = 0, xysum = 0;
self.inclusions().forEach(function(cal) {
xsum += cal.x;
ysum += cal.yM;
x2sum += cal.x * cal.x;
xysum += cal.x * cal.yM;
}
});
var n = self.inclusions().length; // number of measurements
self.factor((n * xysum - xsum * ysum) / (n * x2sum - xsum * xsum));
self.addition((x2sum * ysum - xsum * xysum) / (x2sum * n - xsum * xsum));
self.concentration((self.sampleValue() - self.addition()) / self.factor());
self.drawChart();
};
self.drawChart = function() {
var lastx = 0;
var data = {
theoretical: [],
measured: []
};
self.inclusions().forEach(function(cal) {
data.theoretical.push({ x: cal.x, y: cal.yT });
data.measured.push({ x: cal.x, y: cal.yM });
lastx = cal.x;
});
// Line that on average is closest to all measured points
var calibrationLine = [
[0, self.addition()],
[lastx, self.addition() + self.factor() *...