Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increased code-coverage for choropleth #676

Merged
merged 3 commits into from
Mar 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 43 additions & 8 deletions src/choroplethFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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},
Expand All @@ -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;
}
Expand All @@ -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}
*/
////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -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}
*/
////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -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}
*/
////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -235,7 +270,7 @@ var choroplethFeature = function (arg) {
};

////////////////////////////////////////////////////////////////////////////
/**sr
/**
* Generate scale for choropleth.data(), make polygons from features.
* @returns: [ [geo.feature.polygon, ...] , ... ]
*/
Expand All @@ -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
Expand Down
139 changes: 139 additions & 0 deletions tests/cases/choroplethFeature.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// 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 = $('<div id="map"/>').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('direct creation', function () {
mockVGLRenderer();
var map, layer, choropleth;
map = create_map();
layer = map.createLayer('feature', {renderer: 'vgl'});
choropleth = geo.choroplethFeature({layer: layer});
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();
});
});
});