Example Enumeration Card
Demonstration of an enumeration card
by IPWright83
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<script src="https://dl.dropboxusercontent.com/u/41796243/JSFiddle/knockout.merge.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/js/bootstrap.js"></script>
<div class="card"> <span class="title" data-bind="text: name">Name</span>
<div class="content">
<div class="states" data-bind="foreach: allValues">
<div class="state container">
<div class="col-xs-1">
<div class="circle" data-bind="style: { background: color }"></div>
</div>
<span class="name col-xs-5" data-bind="text: text"></span>
<span class="count col-xs-3" data-bind="text: count"></span>
<span class="percentage col-xs-3"><span data-bind="text: percentage().toFixed(1)"></span>%</span>
</div>
</div>
<div class="graph" data-bind="foreach: allValues">
<div class="bar" data-bind="style: { background: color, width: percentage() + '%' }"/>
</div>
</div>
</div>
CSS
body {
background: rgb(40, 40, 40);
}
.spacer {
height: 230px;
}
.cards {
float: right;
}
/* Small Card */
.card {
margin-bottom: 3px;
background: white;
border-radius: 3px;
width:396px;
float: right;
clear: both;
min-height: 100px;
padding: 10px 5px 15px 5px;
font-family:'Open Sans', Arial, sans-serif;
}
.title {
color: rgb(105, 161, 36);
font-size: 16px;
}
.states {
padding-top: 10px;
}
.state {
font-size: 12px;
color: rgb(67, 88, 98);
padding: 0px 5px 2px 5px;
clear: both;
}
.circle {
width: 10px;
height: 10px;
border-radius: 50%;
float: left;
margin: 1px 5px 5px 0px;
}
.value {
float: right;
}
.graph {
padding: 10px 5px 0px 5px;
}
.bar {
float: left;
height: 10px;
-webkit-transition: width 10s;
transition: width 10s;
}
JavaScript
var vm = (function generateModel() {
var data = {
name: "Sign-off",
id: "XX",
values: [{ text: "Signed-off", count: 150, color: "#5fb5cc" },
{ text: "Submitted", count: 90, color: "#75d181" },
{ text: "Not Submitted", count: 75, color: "#f8a25b" }
],
aggregates: {
count: 650
}
};
// Create a view model directly from the data which we will update
var vm = ko.mapping.fromJS(data);
// Add a computed value to calculate percentage
vm.values().forEach(function (d) {
d.percentage = ko.computed(function () {
return d.count() / vm.aggregates.count() * 100;
});
});
// Create a new object for 'other' values
vm.other = {
text: ko.observable("Other"),
count: ko.computed(function() {
var total = vm.aggregates.count();
var count = 0;
vm.values().forEach(function(d) { count += d.count(); });
return total - count;
}),
percentage: ko.computed(function(d, b) {
var total = vm.aggregates.count();
var count = 0;
vm.values().forEach(function(d) { count += d.count(); });
return (total - count) / total * 100;
}),
color: ko.observable("#ff0000")
};
// Create a
vm.allValues = ko.computed(function() {
var values = [];
// Add each of these results into those that will be returned
vm.values().forEach(function(d) { values.push(d); });
values.push(vm.other);
return values;
});
return vm;
})();
ko.applyBindings(vm);
setTimeout(function() {
vm.values()[0].count(90);
vm.values()[1].count(40);
vm.values()[2].count(35);
vm.aggregates.count(9550);
}, 5000);