knockout.google.maps.clusterer example

HTML

<script src="http://maps.googleapis.com/maps/api/js?sensor=false&amp;extension=.js"></script>
<script src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/markerclusterer.js"></script>
<script src="https://rawgit.com/manuel-guilbault/knockout.google.maps/master/dist/knockout.google.maps-0.2.0.debug.js"></script>
<script src="https://rawgit.com/manuel-guilbault/knockout.google.maps.clusterer/master/dist/knockout.google.maps.clusterer-0.2.0.debug.js"></script>
<div>
    <fieldset>
        <legend>Clusters</legend>
        <select size="1" data-bind="options: availableStyles, optionsText: function(style) { return style.name; }, value: selectedStyles"></select>
    </fieldset>
    <fieldset>
        <legend>Locations</legend>
        <button data-bind="click: newPin">New random location</button>
        <select size="1" data-bind="options: pins, optionsText: function(pin) { return '[' + pin.position().lat().toFixed(2) + ', ' + pin.position().lng().toFixed(2) + '] ' + pin.title(); }, value: selectedPin"></select>
        <div data-bind="with: selectedPin">
            <input type="text" data-bind="value: title, valueUpdate: 'afterkeydown'" />
            <button data-bind="click: function() { $parent.removePin($data); }">Remove</button>
        </div>
    </fieldset>
</div>
<div data-bind="map: $data" style="width:500px;height:300px;">
    <div data-bind="marker: currentLocation"></div>
    <div data-bind="clusterer: { styles: styles }">
        <div data-bind="mapItems: pins">
            <div data-bind="marker: $data">
                <div data-bind="infoWindow: { anchor: $marker, visible: hintVisible }">
                    <p data-bind="text: title"></p>
                </div>
            </div>
        </div>
    </div>
</div>
<div>
    <span>
        Center: [<span data-bind="text: center().lat().toFixed(4)"></span>, <span data-bind="text: center().lng().toFixed(4)"></span>]
    </span>
    <span>
        Zoom: <span...

CSS

.gm-style-iw p {
    margin:0;
}

JavaScript

function randomLatitude() {
    return Math.floor(Math.random() * 180) - 90;
}

function randomLongitude() {
    return Math.floor(Math.random() * 360) - 180;
}

function Pin(owner) {
    this.latitude = ko.observable(randomLatitude());
    this.longitude = ko.observable(randomLongitude());
    
    this.title = ko.observable('');
    this.animation = ko.observable(google.maps.Animation.DROP);
    this.clickable = ko.observable(true);
    this.cursor = ko.observable(null);
    this.icon = ko.observable(null);
    this.raiseOnDrag = ko.observable(true);
    this.shadow = ko.observable(null);
    this.draggable = ko.observable(true);
    this.flat = ko.observable(false);
    this.visible = ko.observable(true);
    
    this.position = ko.computed({
        read: function () {
            return new google.maps.LatLng(this.latitude(), this.longitude());
        },
        write: function (value) {
            this.latitude(value.lat());
            this.longitude(value.lng());
        },
        owner: this
    });
    
    this.hintVisible = ko.observable(true);
    this.click = function () {
        owner.selectedPin(this);
    }
}

var styles = [
    {
        name: 'People',
        styles: [{
            url: 'http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/people35.png',
            height: 35,
            width: 35,
            anchor: [16, 0],
            textColor: '#ff00ff',
            textSize: 10
        }, {
            url: 'http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/people45.png',
            height: 45,
            width: 45,
            anchor: [24, 0],
            textColor: '#ff0000',
            textSize: 11
        }, {
            url: 'http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/people55.png',
            height: 55,
            width: 55,
            anchor: [32, 0],
            textColor: '#ffffff',
           ...