Skip to content

Commit 1adf878

Browse files
committed
Add a visible() function to layers.
Note that, much like feature level visibility, you might need to call layer.draw() after making the layer visible to ensure an update. For feature layers, visibility cascades down to individual features (which disables their interaction).
1 parent 8501fb8 commit 1adf878

File tree

11 files changed

+174
-28
lines changed

11 files changed

+174
-28
lines changed

src/feature.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -413,24 +413,37 @@ var feature = function (arg) {
413413
////////////////////////////////////////////////////////////////////////////
414414
/**
415415
* Get/Set visibility of the feature
416+
*
417+
* @param {boolean|undefined} val: undefined to return the visibility, a
418+
* boolean to change the visibility.
419+
* @param {boolean} direct: if true, when getting the visibility, disregard
420+
* the visibility of the parent layer, and when setting, refresh the state
421+
* regardless of whether it has changed or not.
422+
* @return {boolean|object} either the visibility (if getting) or the feature
423+
* (if setting).
416424
*/
417425
////////////////////////////////////////////////////////////////////////////
418-
this.visible = function (val) {
426+
this.visible = function (val, direct) {
419427
if (val === undefined) {
428+
if (!direct && m_layer && m_layer.visible && !m_layer.visible()) {
429+
return false;
430+
}
420431
return m_visible;
421432
}
422-
if (m_visible !== val) {
433+
if (m_visible !== val || direct) {
423434
m_visible = val;
424435
m_this.modified();
425-
436+
if (m_layer && m_layer.visible && !m_layer.visible()) {
437+
val = false;
438+
}
426439
// bind or unbind mouse handlers on visibility change
427-
if (m_visible) {
440+
if (val) {
428441
m_this._bindMouseHandlers();
429442
} else {
430443
m_this._unbindMouseHandlers();
431444
}
432445
for (var i = 0; i < m_dependentFeatures.length; i += 1) {
433-
m_dependentFeatures[i].visible(val);
446+
m_dependentFeatures[i].visible(m_visible, direct);
434447
}
435448
}
436449
return m_this;

src/featureLayer.js

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ var featureLayer = function (arg) {
3030
s_init = this._init,
3131
s_exit = this._exit,
3232
s_update = this._update,
33+
s_visible = this.visible,
3334
s_draw = this.draw;
3435

3536
////////////////////////////////////////////////////////////////////////////
@@ -231,13 +232,45 @@ var featureLayer = function (arg) {
231232
*/
232233
////////////////////////////////////////////////////////////////////////////
233234
this.draw = function () {
234-
// Call sceneObject.draw, which calls draw on all child objects.
235-
s_draw();
235+
if (m_this.visible()) {
236+
// Call sceneObject.draw, which calls draw on all child objects.
237+
s_draw();
236238

237-
// Now call render on the renderer. In certain cases it may not do
238-
// anything if the if the child objects are drawn on the screen already.
239-
if (m_this.renderer()) {
240-
m_this.renderer()._render();
239+
// Now call render on the renderer. In certain cases it may not do
240+
// anything if the child objects are drawn on the screen already.
241+
if (m_this.renderer()) {
242+
m_this.renderer()._render();
243+
}
244+
}
245+
return m_this;
246+
};
247+
248+
////////////////////////////////////////////////////////////////////////////
249+
/**
250+
* Get/Set visibility of the layer
251+
*
252+
* @param {boolean|undefined} val: undefined to return the visibility, a
253+
* boolean to change the visibility.
254+
* @return {boolean|object} either the visibility (if getting) or the layer
255+
* (if setting).
256+
*/
257+
////////////////////////////////////////////////////////////////////////////
258+
this.visible = function (val) {
259+
if (val === undefined) {
260+
return s_visible();
261+
}
262+
if (m_this.visible() !== val) {
263+
s_visible(val);
264+
265+
// take a copy of the features; changing visible could mutate them.
266+
var features = m_features.slice(), i;
267+
268+
for (i = 0; i < features.length; i += 1) {
269+
features[i].visible(features[i].visible(undefined, true), true);
270+
}
271+
if (val) {
272+
m_this.draw();
273+
}
241274
}
242275
return m_this;
243276
};

src/gl/quadFeature.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,11 +373,11 @@ var gl_quadFeature = function (arg) {
373373
m_this._build();
374374
}
375375
if (m_actor_color) {
376-
m_actor_color.setVisible(m_this.visible());
376+
m_actor_color.setVisible(m_this.visible(undefined, true));
377377
m_actor_color.material().setBinNumber(m_this.bin());
378378
}
379379
if (m_actor_image) {
380-
m_actor_image.setVisible(m_this.visible());
380+
m_actor_image.setVisible(m_this.visible(undefined, true));
381381
m_actor_image.material().setBinNumber(m_this.bin());
382382
}
383383
m_this.updateTime().modified();

src/layer.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ var layer = function (arg) {
5555
m_active = arg.active === undefined ? true : arg.active,
5656
m_opacity = arg.opacity === undefined ? 1 : arg.opacity,
5757
m_attribution = arg.attribution || null,
58+
m_visible = arg.visible === undefined ? true : arg.visible,
5859
m_zIndex;
5960

6061
m_rendererName = checkRenderer(m_rendererName);
@@ -352,6 +353,28 @@ var layer = function (arg) {
352353
return m_attribution;
353354
};
354355

356+
////////////////////////////////////////////////////////////////////////////
357+
/**
358+
* Get/Set visibility of the layer
359+
*
360+
* @param {boolean|undefined} val: undefined to return the visibility, a
361+
* boolean to change the visibility.
362+
* @return {boolean|object} either the visibility (if getting) or the layer
363+
* (if setting).
364+
*/
365+
////////////////////////////////////////////////////////////////////////////
366+
this.visible = function (val) {
367+
if (val === undefined) {
368+
return m_visible;
369+
}
370+
if (m_visible !== val) {
371+
m_visible = val;
372+
m_node.css('display', m_visible ? '' : 'none');
373+
m_this.modified();
374+
}
375+
return m_this;
376+
};
377+
355378
////////////////////////////////////////////////////////////////////////////
356379
/**
357380
* Init layer

src/pixelmapFeature.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -339,13 +339,14 @@ var pixelmapFeature = function (arg) {
339339
m_quadFeature = m_this.layer().createFeature('quad', {
340340
selectionAPI: false,
341341
gcs: m_this.gcs(),
342-
visible: m_this.visible()
342+
visible: m_this.visible(undefined, true)
343343
});
344344
m_this.dependentFeatures([m_quadFeature]);
345-
m_quadFeature.style({image: m_info.canvas,
346-
position: m_this.style.get('position')})
347-
.data([{}])
348-
.draw();
345+
m_quadFeature.style({
346+
image: m_info.canvas,
347+
position: m_this.style.get('position')})
348+
.data([{}])
349+
.draw();
349350
}
350351
/* If we prepared the pixelmap and rendered it, send a prepared event */
351352
if (prepared) {

src/pointFeature.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,6 @@ var pointFeature = function (arg) {
224224
strokeWidth = m_this.style.get('strokeWidth'),
225225
radius = m_this.style.get('radius');
226226

227-
if (!m_this.selectionAPI()) {
228-
return [];
229-
}
230-
231227
data = m_this.data();
232228
if (!data || !data.length) {
233229
return {

src/polygonFeature.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ var polygonFeature = function (arg) {
271271
m_lineFeature = m_this.layer().createFeature('line', {
272272
selectionAPI: false,
273273
gcs: m_this.gcs(),
274-
visible: m_this.visible()
274+
visible: m_this.visible(undefined, true)
275275
});
276276
m_this.dependentFeatures([m_lineFeature]);
277277
}

src/tileLayer.js

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ module.exports = (function () {
138138
*/
139139
//////////////////////////////////////////////////////////////////////////////
140140
var tileLayer = function (options) {
141+
'use strict';
142+
if (!(this instanceof tileLayer)) {
143+
return new tileLayer(options);
144+
}
145+
featureLayer.call(this, options);
141146

142147
var $ = require('jquery');
143148
var geo_event = require('./event');
@@ -147,11 +152,6 @@ module.exports = (function () {
147152
var adjustLayerForRenderer = require('./registry').adjustLayerForRenderer;
148153
var Tile = require('./tile');
149154

150-
if (!(this instanceof tileLayer)) {
151-
return new tileLayer(options);
152-
}
153-
featureLayer.call(this, options);
154-
155155
options = $.extend(true, {}, this.constructor.defaults, options || {});
156156
if (!options.cacheSize) {
157157
// this size should be sufficient for a 4k display
@@ -177,6 +177,7 @@ module.exports = (function () {
177177

178178
var s_init = this._init,
179179
s_exit = this._exit,
180+
s_visible = this.visible,
180181
m_lastTileSet = [],
181182
m_maxBounds = [],
182183
m_exited;
@@ -1063,6 +1064,9 @@ module.exports = (function () {
10631064
evt.event.event === geo_event.rotate)) {
10641065
return;
10651066
}
1067+
if (!this.visible()) {
1068+
return;
1069+
}
10661070
var map = this.map(),
10671071
bounds = map.bounds(undefined, null),
10681072
mapZoom = map.zoom(),
@@ -1430,6 +1434,30 @@ module.exports = (function () {
14301434
return m_tileOffsetValues[level];
14311435
};
14321436

1437+
////////////////////////////////////////////////////////////////////////////
1438+
/**
1439+
* Get/Set visibility of the layer
1440+
*
1441+
* @param {boolean|undefined} val: undefined to return the visibility, a
1442+
* boolean to change the visibility.
1443+
* @return {boolean|object} either the visibility (if getting) or the layer
1444+
* (if setting).
1445+
*/
1446+
////////////////////////////////////////////////////////////////////////////
1447+
this.visible = function (val) {
1448+
if (val === undefined) {
1449+
return s_visible();
1450+
}
1451+
if (this.visible() !== val) {
1452+
s_visible(val);
1453+
1454+
if (val) {
1455+
this._update();
1456+
}
1457+
}
1458+
return this;
1459+
};
1460+
14331461
/**
14341462
* Initialize after the layer is added to the map.
14351463
*/

tests/cases/feature.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,20 @@ describe('geo.feature', function () {
198198
feat.dependentFeatures([]);
199199
expect(feat.visible(true)).toBe(feat);
200200
expect(depFeat.visible()).toBe(false);
201+
202+
// the layer can control the visibility
203+
expect(feat.visible()).toBe(true);
204+
expect(feat.visible(undefined, true)).toBe(true);
205+
layer.visible(false);
206+
expect(feat.visible()).toBe(false);
207+
expect(feat.visible(undefined, true)).toBe(true);
208+
expect(feat.visible(false, true)).toBe(feat);
209+
expect(feat.visible()).toBe(false);
210+
expect(feat.visible(undefined, true)).toBe(false);
211+
layer.visible(true);
212+
expect(feat.visible()).toBe(false);
213+
expect(feat.visible(true, true)).toBe(feat);
214+
expect(feat.visible()).toBe(true);
201215
});
202216
});
203217
describe('Check class accessors', function () {

tests/cases/featureLayer.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,19 @@ describe('geo.featureLayer', function () {
127127
expect(layer.features().length).toBe(2);
128128
expect(layer.features()).toEqual([feat2, feat1]);
129129
});
130+
it('visible', function () {
131+
expect(layer.visible()).toBe(true);
132+
expect(feat1.visible()).toBe(true);
133+
expect(feat1.visible(undefined, true)).toBe(true);
134+
expect(layer.visible(false)).toBe(layer);
135+
expect(layer.visible()).toBe(false);
136+
expect(feat1.visible()).toBe(false);
137+
expect(feat1.visible(undefined, true)).toBe(true);
138+
expect(layer.visible(true)).toBe(layer);
139+
expect(layer.visible()).toBe(true);
140+
expect(feat1.visible()).toBe(true);
141+
expect(feat1.visible(undefined, true)).toBe(true);
142+
});
130143
it('draw', function () {
131144
sinon.stub(feat1, 'draw', function () {});
132145
expect(layer.draw()).toBe(layer);

0 commit comments

Comments
 (0)