TranscriptionLanes
by Barry Carter
HTML
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<div class='liveExample'>
<div data-bind="with: rec">
<span data-bind='text: totalLength'> </span>
<div class="RecWrapper" data-bind="foreach: parties">
<div class="party row">
<div class="col-sm-1" data-bind="text: $root.getPartyName($data)">
</div>
<div class="col-sm-11">
<div class="partyWrapper" data-bind="foreach: $root.getInstants($data.partyType), css: 'partyWrapper-' + $index()">
<span class="instant" data-bind="css: 'instantType-' + $parent.partyType">
<p data-bind="style: { width: $root.elementWidth($data), left: $root.elementStart($data) }"></p>
</span>
</div>
</div>
</div>
</div>
</div>
<div data-bind="with: rec">
<div data-bind="foreach: instants">
<div>
<div data-bind="text: $root.formatTime($data.position())">
</div>
<span data-bind="text: text"></span>
</div>
</div>
</div>
</div>
CSS
body { font-family: arial; font-size: 14px; }
.liveExample { padding: 1em; background-color: white; border: 1px solid #CCC; width:100%; max-width: 100%; position: relative; }
.instant p {
position: absolute;
height:14px;
background-color: #9ddcff;
top: 2px;
display:block;
padding:0px;
margin:0px;
}
.partyWrapper {
height:20px;
position: relative;
margin-bottom: 15px;
}
.partyWrapper-0 {
border-bottom: 1px solid #e8e8e8;
}
.partyWrapper-1 {
border-top: 1px solid #e8e8e8;
}
.instantType-1 p {
background-color: #a6e1bf;
}
JavaScript
//data
var PartyModel = function(id, partyType, name) {
this.id = id;
this.name = name;
this.partyType = partyType; // 0 = agent, 1=customer, 2=coach, 3=other
}
var RecordingModel = function() {
this.totalLength = 30000;
this.instants = ko.observableArray([]);
this.parties = ko.observableArray([new PartyModel(1, 0, "Agent Smith"), new PartyModel(1, 1, "Customer Jane")]);
}
//data
var InstantModel = function(id, party, start, len, text) {
this.instantId = id;
this.party = party;
this.position = ko.observable(start);
this.totalInstantLength = ko.observable(len);
this.text = text;
}
var recs = new RecordingModel();
recs.instants([
new InstantModel(1, 0, 1000, 2000, "Hello, I am calling from your bank"),
new InstantModel(2, 1, 4000, 3000, "Oh Hi Bank"),
new InstantModel(2, 0, 8000, 1000, "Yeah it would seem that blah"),
new InstantModel(2, 1, 9000, 1000, "Oh Noes!"),
new InstantModel(2, 0, 12000, 1000, "Indeed. If you would just hand over your card details, that would be greeeaaat"),
new InstantModel(2, 1, 14000, 1000, "Sure, theey are four five..."),
new InstantModel(2, 0, 16000, 1000, "Thanks"),
]);
// Here's my data model
var ViewModel = function(recordingModel) {
var self = this;
this.rec = ko.observable(recordingModel);
this.getInstants = function(partyId) {
return ko.pureComputed(function() {
if (typeof(self.rec()) == 'undefined')
return;
console.log(self.rec());
return ko.utils.arrayFilter(self.rec().instants(), function(item) {
return item.party == partyId;
});
});
}
this.getPartyName = function(data) {
if (data.partyType == 0)
return "Agent";
else if (data.partyType == 1)
return "Customer";
else
return "Other";
}
this.formatTime = function(ms) {
var milliseconds = parseInt((ms % 1000) / 100),
seconds = Math.floor((ms / 1000) % 60),
minutes = Math.floor((ms / (1000 * 60)) % 60),
hours =...