From a72da03aa3b1766f6e1d56fd9fb9ae22c62d93f3 Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Fri, 10 Mar 2017 04:45:16 -0500 Subject: [PATCH] Increased code-coverage for choropleth Also fixed documentation and style issues. --- src/choroplethFeature.js | 51 ++++++++++-- tests/cases/choroplethFeature.js | 129 +++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+), 8 deletions(-) create mode 100644 tests/cases/choroplethFeature.js diff --git a/src/choroplethFeature.js b/src/choroplethFeature.js index 7fd7262e2f..dee0efb875 100644 --- a/src/choroplethFeature.js +++ b/src/choroplethFeature.js @@ -6,9 +6,26 @@ var feature = require('./feature'); * Create a new instance of class choroplethFeature * * @class geo.choroplethFeature + * @param {Object} arg Options object * @extends geo.feature + * @param {Array} [colorRange] Color lookup table for + * choroplethFeature. Default is 9-step color table. + * @param {Function} [scale] A scale converts a input domain into the + * the colorRange. Default is d3.scale.quantize. + * @param {Object} [accessor] A accessor defines three functions; Retrieve + * geoId from geometry feature and scalarId and scalarValue from scalarData. By + * default geoId uses GEO_ID key in the geometry feature property, + * scalarId uses id key and scalarValue uses value from a object within + * the scalar array. + * @param {Object|Function} [scalar] A scalar is a array of objects with keys id + * that maps scalar value to the geometry and value of the scalar. + * Multiple values mapped to the same id are aggregated by the aggregator. + * @param {Object|Function} [choropleth] Defines accessor for choropleth. It + * provides an API to replace or add attributes to the choropleth. + * @param {Object|Function} [choropleth.get] A uniform getter that + * always returns a function even for constant values. + * If undefined input, return all the choropleth values as an object. * @returns {geo.choroplethFeature} - * */ ////////////////////////////////////////////////////////////////////////////// var choroplethFeature = function (arg) { @@ -32,7 +49,6 @@ var choroplethFeature = function (arg) { s_init = this._init, m_choropleth = $.extend({}, { - /* 9-step based on paraview bwr colortable */ colorRange: [ {r: 0.07514311, g: 0.468049805, b: 1}, {r: 0.468487184, g: 0.588057293, b: 1}, @@ -46,15 +62,15 @@ var choroplethFeature = function (arg) { ], scale: d3.scale.quantize(), accessors: { - //accessor for ID on geodata feature + //accessor for ID on geodata feature geoId: function (geoFeature) { return geoFeature.properties.GEO_ID; }, - //accessor for ID on scalar element + //accessor for ID on scalar element scalarId: function (scalarElement) { return scalarElement.id; }, - //accessor for value on scalar element + //accessor for value on scalar element scalarValue: function (scalarElement) { return scalarElement.value; } @@ -66,6 +82,13 @@ var choroplethFeature = function (arg) { /** * Get/Set choropleth scalar data * + * @memberof geo.choroplethFeature + * @param {Array} [data] Scalar data is an array of objects in which each + * object provides an id and a value for that id. The id uniquely identifies + * the geometry this scalar is associated with. + * @param {Function} [aggregator] The aggregator aggregates the scalar in case + * there are multiple values are found with the same id. The default + * is d3.mean. * @returns {geo.feature.choropleth} */ //////////////////////////////////////////////////////////////////////////// @@ -105,6 +128,14 @@ var choroplethFeature = function (arg) { /** * Get/Set choropleth accessor * + * @memberof geo.choroplethFeature + * @param {Object|String} [arg1] The first argument is the key for a + * attributes of the choropleth. If the argument is a string and the second + * argument is undefined, the value of the key is returned. If the arg1 is + * an object and the second argument is undefined, choropleth attributes + * are extended by that object. If arg1 is an object and arg2 is defined, + * a new key-value pair is then added to the choropleth as an attribute. + * @param {Object|String} [arg2] arg2 defines the value of the key (arg1). * @returns {geo.feature.choropleth} */ //////////////////////////////////////////////////////////////////////////// @@ -133,10 +164,14 @@ var choroplethFeature = function (arg) { //////////////////////////////////////////////////////////////////////////// /** + * Get/Set choropleth getter + * + * @memberof geo.choroplethFeature * A uniform getter that always returns a function even for constant values. * If undefined input, return all the choropleth values as an object. * - * @param {string|undefined} key + * @param {string|undefined} key defines one of the attributes of a + * choropleth. * @return {function} */ //////////////////////////////////////////////////////////////////////////// @@ -235,7 +270,7 @@ var choroplethFeature = function (arg) { }; //////////////////////////////////////////////////////////////////////////// - /**sr + /** * Generate scale for choropleth.data(), make polygons from features. * @returns: [ [geo.feature.polygon, ...] , ... ] */ @@ -255,7 +290,7 @@ var choroplethFeature = function (arg) { var valueArray = scalars._dictionary[id]; var accumulatedScalarValue = choropleth().scalarAggregator(valueArray); // take average of this array of values - // which allows for non-bijective correspondance + // which allows for non-bijective correspondence // between geo data and scalar data var fillColor = m_this diff --git a/tests/cases/choroplethFeature.js b/tests/cases/choroplethFeature.js new file mode 100644 index 0000000000..2cb4261917 --- /dev/null +++ b/tests/cases/choroplethFeature.js @@ -0,0 +1,129 @@ +// Test geo.choroplethFeature and geo.gl.choroplethFeature + +var geo = require('../test-utils').geo; +var $ = require('jquery'); +var mockVGLRenderer = require('../test-utils').mockVGLRenderer; +var restoreVGLRenderer = require('../test-utils').restoreVGLRenderer; + +describe('geo.choroplethFeature', function () { + 'use strict'; + + function create_map(opts) { + var node = $('
').css({width: '640px', height: '360px'}); + $('#map').remove(); + $('body').append(node); + opts = $.extend({}, opts); + opts.node = node; + return geo.map(opts); + } + + var mpdata = [{ + 'type': 'Feature', + 'geometry': { + 'type': 'MultiPolygon', + 'coordinates': [ + [ + [ + [ -123.123779, 48.227039 ], + [ -123.318787, 49.000042 ], + [ -121.742592, 49.000267 ], + [ -95.157394, 49.000493 ], + [ -95.157394, 49.390418 ], + [ -94.795532, 49.357334 ], + [ -94.482422, 48.857487 ], + [ -88.36853, 48.314255 ], + [ -84.126389, 46.531937 ], + [ -81.331787, 45.344424 ], + [ -83.034668, 41.910453 ], + [ -79.013672, 42.867912 ], + [ -79.299316, 43.590338 ], + [ -77.305298, 43.761176 ], + [ -74.849854, 45.058001 ], + [ -71.586914, 45.1123 ], + [ -69.213867, 47.480088 ], + [ -67.758179, 47.271775 ], + [ -67.719727, 45.813486 ], + [ -66.780396, 44.785734 ], + [ -80.628662, 24.417142 ], + [ -97.058716, 25.730633 ], + [ -99.283447, 26.382028 ], + [ -101.480713, 29.678508 ], + [ -102.612305, 29.716681 ], + [ -103.117676, 28.88316 ], + [ -104.699707, 29.649869 ], + [ -106.44104, 31.737511 ], + [ -108.187866, 31.760867 ], + [ -108.193359, 31.325487 ], + [ -111.08551, 31.325487 ], + [ -114.930725, 32.521342 ], + [ -114.724731, 32.711044 ], + [ -124.892578, 31.952453 ], + [ -129.067383, 49.047486 ], + [ -123.123779, 48.227039 ] + ] + ], + [ + [ + [ -163.916016, 71.992578 ], + [ -140.888672, 70.641769 ], + [ -140.976562, 60.326948 ], + [ -135.175781, 60.326948 ], + [ -129.550781, 55.553495 ], + [ -131.286621, 54.239551 ], + [ -179.736328, 51.069017 ], + [ -172.089844, 63.626745 ], + [ -163.916016, 71.992578 ] + ] + ], + [ + [ + [ -161.323242, 22.512557 ], + [ -152.446289, 22.065278 ], + [ -156.09375, 17.811456 ], + [ -161.323242, 22.512557 ] + ] + ] + ] + }, + 'properties': { + 'GEO_ID': 0 + } + }]; + + describe('create', function () { + it('create function', function () { + mockVGLRenderer(); + var map, layer, choropleth; + map = create_map(); + layer = map.createLayer('feature', {renderer: 'vgl'}); + choropleth = layer.createFeature('choropleth'); + expect(choropleth instanceof geo.choroplethFeature).toBe(true); + restoreVGLRenderer(); + }); + + it('multipolygon', function () { + mockVGLRenderer(); + var map, layer, choropleth, scalarData = [ + {'id': 0, 'value': 10} + ]; + + map = create_map(); + layer = map.createLayer('feature', {renderer: 'vgl'}); + + choropleth = layer.createFeature('choropleth') + .data(mpdata) + .scalar(scalarData); + choropleth.choropleth('name', 'multipolygon'); + expect(choropleth instanceof geo.choroplethFeature).toBe(true); + expect(choropleth.choropleth('name')).toBe('multipolygon'); + expect(choropleth.choropleth.get('accessors')() + .scalarValue(scalarData[0])).toBe(10); + expect(choropleth.choropleth.get('accessors')() + .geoId(mpdata[0])).toBe(0); + expect(Object.keys(choropleth.choropleth.get())).toEqual( + ['colorRange', 'scale', 'accessors', 'scalar', + 'scalarAggregator', 'name']); + restoreVGLRenderer(); + }); + }); +});