Example Enumeration Card

Demonstration of an enumeration summary card to be used on the Landscape Explorer

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 2s;
    transition: width 2s;
}

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);
}, 2500);