Search code examples
javascriptjqueryjqvmap

how to handle jqvmap undefined values


I am using jqvmap to show a map series (ifthq.com scroll low left). On the USA map, I have two states with values: LA and OH, both equal to 1.

The JSON used to feed jqvmap is: {"OH":1,"LA":1}.

The map shows, but does not fill correctly. My assumption is that linear normalizeFunction would result in two states at max, and the rest at min. This is not the case.

Since the US Map is over 50 elements, and the data is only two, how do I set "default" data to zero in the jqvmap? In other words, undefined states would be equal to zero?

Thanks.

UPDATE #1: Code for question: View definition. mbrmap is the result of the data pull:

@login_required
def index_view(request):
    enlisted = models.Subscription.objects.rankset("E").active().count()
    officer = models.Subscription.objects.rankset("O").active().count()
    civilian = models.Subscription.objects.rankset("C").active().count()
    lifer = models.Subscription.objects.lifer().active().count()
    subscriptions = models.Subscription.objects.all().order_by("-Modified")
    mbrcnt = models.Member.objects.values('State').annotate(c=Count('State')).exclude(State='')
    mbrcnt2 = models.Member.objects.values('Country').annotate(c=Count('Country')).exclude(Country='')
    mbrmap = dict([(type_and_count['State'], type_and_count['c']) for type_and_count in mbrcnt])
    mbrmap2 = dict([(type_and_count['Country'], type_and_count['c']) for type_and_count in mbrcnt2])
    mbrmap.update(mbrmap2)
    units = models.Unit.objects.values('Unit_name', 'Hull_type', 'Hull_number').annotate(c=Count('memberunit__Member'))
    context = {'mbrmap': mbrmap, 'enlisted': enlisted, 'officer': officer, 'civilian': civilian, 'lifer': lifer, 'units': units, 'Subscriptions': subscriptions}
    return render(request, 'index.html', context)

html:

<div class="portlet-body">
    <div id="region_statistics_loading">
        <img src="{% static "img/loading.gif" %}" alt="loading"/>
    </div>
    <div id="region_statistics_content" class="display-none">
        <div class="btn-toolbar margin-bottom-10">
            <div class="btn-group btn-group-circle" data-toggle="buttons">
                <a href="" class="btn grey-salsa btn-sm active">
                Members </a>
                <a href="" class="btn grey-salsa btn-sm">
                Units </a>
            </div>
            <div class="btn-group pull-right">
                <a href="" class="btn btn-circle grey-salsa btn-sm dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" data-close-others="true">
                Select Region <span class="fa fa-angle-down">
                </span>
                </a>
                <ul class="dropdown-menu pull-right">
                    <li>
                        <a href="javascript:;" id="regional_stat_world">
                        World </a>
                    </li>
                    <li>
                        <a href="javascript:;" id="regional_stat_usa">
                        USA </a>
                    </li>
                    {% comment %}<li>
                        <a href="javascript:;" id="regional_stat_europe">
                        Europe </a>
                    </li>
                    <li>
                        <a href="javascript:;" id="regional_stat_russia">
                        Russia </a>
                    </li>
                    <li>
                        <a href="javascript:;" id="regional_stat_germany">
                        Germany </a>
                    </li>{% endcomment %}
                </ul>
            </div>
        </div>
        <div id="vmap_world" class="vmaps display-none">
        </div>
        <div id="vmap_usa" class="vmaps display-none">
        </div>
        {% comment %}<div id="vmap_europe" class="vmaps display-none">
        </div>
        <div id="vmap_russia" class="vmaps display-none">
        </div>
        <div id="vmap_germany" class="vmaps display-none">
        </div>{% endcomment %}
    </div>
</div>
<!-- PAGE LEVEL SPELLS -->
{% block PageSpells %}
    <!-- PLUGINS -->
    <script src="{% static "plugins/jqvmap/jqvmap/jquery.vmap.js" %}" type="text/javascript"></script>
    <script src="{% static "plugins/jqvmap/jqvmap/maps/jquery.vmap.russia.js" %}" type="text/javascript"></script>
    <script src="{% static "plugins/jqvmap/jqvmap/maps/jquery.vmap.world.js" %}" type="text/javascript"></script>
    <script src="{% static "plugins/jqvmap/jqvmap/maps/jquery.vmap.europe.js" %}" type="text/javascript"></script>
    <script src="{% static "plugins/jqvmap/jqvmap/maps/jquery.vmap.germany.js" %}" type="text/javascript"></script>
    <script src="{% static "plugins/jqvmap/jqvmap/maps/jquery.vmap.usa.js" %}" type="text/javascript"></script>
    <script src="{% static "plugins/jqvmap/jqvmap/data/jquery.vmap.sampledata.js" %}" type="text/javascript"></script>

    <!-- SPELLS -->
    <script src="{% static "js/index.js" %}" type="text/javascript"></script>
    <script src="{% static "plugins/uniform/jquery.uniform.min.js" %}" type="text/javascript"></script>
{% endblock %}

<!-- PAGE JQUERY -->
{% block Jquery %}
    var mapdata = {{ mbrmap|safe }};
    Index.init();
    Index.initCmdSelect();
    Index.initJQVMAP(mapdata); // init index page's custom scripts
{% endblock %}

javascript code:

initJQVMAP: function (mapdata) {
    if (!jQuery().vectorMap) {
        return;
    }

    var showMap = function (name) {
        jQuery('.vmaps').hide();
        jQuery('#vmap_' + name).show();
    }

    var setMap = function (name) {
        var data = {
            map: 'world_en',
            backgroundColor: null,
            borderColor: '#333333',
            borderOpacity: 0.5,
            borderWidth: 1,
            color: '#c6c6c6',
            enableZoom: true,
            hoverColor: '#c9dfaf',
            hoverOpacity: null,
            values: mapdata,
            normalizeFunction: 'linear',
            scaleColors: ['#C8EEFF', '#0071A4'],
            selectedColor: '#c9dfaf',
            selectedRegion: null,
            showTooltip: true,
            onLabelShow: function (event, label, code) {

            },
            onRegionOver: function (event, code) {
                if (code == 'ca') {
                    event.preventDefault();
                }
            },
            onRegionClick: function (element, code, region) {
                if (typeof mapdata[code.toUpperCase()] === 'undefined') {
                    var sval = 0;
                } else {
                    var sval = mapdata[code.toUpperCase()]
                }
                var message = 'You clicked "' + region + '" which has the code: ' + code.toUpperCase() + ' and value:  ' + sval;
                alert(message);
            }
        };

        data.map = name + '_en';
        var map = jQuery('#vmap_' + name);
        if (!map) {
            return;
        }
        map.width(map.parent().parent().width());
        map.show();
        map.vectorMap(data);
        map.hide();
    }

    setMap("world");
    setMap("usa");
    //setMap("europe");
    //setMap("russia");
    //setMap("germany");
    showMap("world");

    jQuery('#regional_stat_world').click(function () {
        showMap("world");
    });

    jQuery('#regional_stat_usa').click(function () {
        showMap("usa");
    });

    jQuery('#regional_stat_europe').click(function () {
        showMap("europe");
    });
    jQuery('#regional_stat_russia').click(function () {
        showMap("russia");
    });
    jQuery('#regional_stat_germany').click(function () {
        showMap("germany");
    });

    $('#region_statistics_loading').hide();
    $('#region_statistics_content').show();
},

Of note, the initJQVMAP function is a method in the index object:

var Index = function() {....

It is initialized by the Index.initJQVMAP(mapdata); function call. Thanks.


Solution

  • You could try changing the colors after creating the map:

    var newData = {};
    for (var key in mapdata)
        newData[key.toLowerCase()] = '#0071A4';
    map.vectorMap('set', 'colors', newData);
    

    Here there is a working sample.

    Edit

    I've also found this different solution:

    var arrStates = [];
    for (var key in mapdata)
        arrStates.push(key);
    map.vectorMap('set', 'colors', arrStates, '#0071A4');