From 2a67e8e457bcf07d9f07ab56ddf232d057c4c838 Mon Sep 17 00:00:00 2001 From: Kim Truong <47833996+khtruong@users.noreply.github.com> Date: Tue, 9 Apr 2019 15:46:47 -0700 Subject: [PATCH] fix: Handle rendering a single point (#7256) * fix: Handle rendering a single point * fix: typo --- .../deckgl/layers/common_spec.jsx | 63 ++++++++++++++++++- .../visualizations/deckgl/layers/common.jsx | 42 ++++++++++++- 2 files changed, 102 insertions(+), 3 deletions(-) diff --git a/superset/assets/spec/javascripts/visualizations/deckgl/layers/common_spec.jsx b/superset/assets/spec/javascripts/visualizations/deckgl/layers/common_spec.jsx index a2a6ef3f5..c82eeeea4 100644 --- a/superset/assets/spec/javascripts/visualizations/deckgl/layers/common_spec.jsx +++ b/superset/assets/spec/javascripts/visualizations/deckgl/layers/common_spec.jsx @@ -17,7 +17,7 @@ * under the License. */ import { max } from 'd3-array'; -import { getAggFunc } from '../../../../../src/visualizations/deckgl/layers/common'; +import { getAggFunc, getBounds } from '../../../../../src/visualizations/deckgl/layers/common'; describe('deckgl layers common', () => { it('getAggFunc', () => { @@ -46,4 +46,65 @@ describe('deckgl layers common', () => { expect(getAggFunc('p95', accessor)(arr)).toEqual(2.9); expect(getAggFunc('p99', accessor)(arr)).toEqual(2.98); }); + + describe('getBounds', () => { + it('should return valid bounds for multiple points', () => { + const points = [ + [0, 20], + [5, 25], + [10, 15], + ]; + expect(getBounds(points)).toEqual([ + [0, 15], + [10, 25], + ]); + }); + it('should return valid bounds for single latitude point', () => { + const points = [ + [0, 0], + [5, 0], + ]; + expect(getBounds(points)).toEqual([ + [0, -0.25], + [5, 0.25], + ]); + }); + it('should return valid bounds for single longitude point', () => { + const points = [ + [0, 0], + [0, 5], + ]; + expect(getBounds(points)).toEqual([ + [-0.25, 0], + [0.25, 5], + ]); + }); + it('should return valid bounds for single point', () => { + const points = [ + [0, 0], + ]; + expect(getBounds(points)).toEqual([ + [-0.25, -0.25], + [0.25, 0.25], + ]); + }); + it('should return valid bounds for point 90, 180', () => { + const points = [ + [180, 90], + ]; + expect(getBounds(points)).toEqual([ + [179.75, 89.75], + [180, 90], + ]); + }); + it('should return valid bounds for point -90, -180', () => { + const points = [ + [-180, -90], + ]; + expect(getBounds(points)).toEqual([ + [-180, -90], + [-179.75, -89.75], + ]); + }); + }); }); diff --git a/superset/assets/src/visualizations/deckgl/layers/common.jsx b/superset/assets/src/visualizations/deckgl/layers/common.jsx index 7adf3b789..aaee55361 100644 --- a/superset/assets/src/visualizations/deckgl/layers/common.jsx +++ b/superset/assets/src/visualizations/deckgl/layers/common.jsx @@ -20,12 +20,50 @@ import { fitBounds } from 'viewport-mercator-project'; import * as d3array from 'd3-array'; import sandboxedEval from '../../../modules/sandbox'; +const PADDING = 0.25; +const GEO_BOUNDS = { + LAT_MIN: -90, + LAT_MAX: 90, + LNG_MIN: -180, + LNG_MAX: 180, +}; + +/** + * Get the latitude bounds if latitude is a single coordinate + * @param latExt Latitude range + */ +function getLatBoundsForSingleCoordinate(latExt) { + const latMin = latExt[0] - PADDING < GEO_BOUNDS.LAT_MIN + ? GEO_BOUNDS.LAT_MIN + : latExt[0] - PADDING; + const latMax = latExt[1] + PADDING > GEO_BOUNDS.LAT_MAX + ? GEO_BOUNDS.LAT_MAX + : latExt[1] + PADDING; + return [latMin, latMax]; +} + +/** + * Get the longitude bounds if longitude is a single coordinate + * @param lngExt Longitude range + */ +function getLngBoundsForSingleCoordinate(lngExt) { + const lngMin = lngExt[0] - PADDING < GEO_BOUNDS.LNG_MIN + ? GEO_BOUNDS.LNG_MIN + : lngExt[0] - PADDING; + const lngMax = lngExt[1] + PADDING > GEO_BOUNDS.LNG_MAX + ? GEO_BOUNDS.LNG_MAX + : lngExt[1] + PADDING; + return [lngMin, lngMax]; +} + export function getBounds(points) { const latExt = d3array.extent(points, d => d[1]); const lngExt = d3array.extent(points, d => d[0]); + const latBounds = latExt[0] === latExt[1] ? getLatBoundsForSingleCoordinate(latExt) : latExt; + const lngBounds = lngExt[0] === lngExt[1] ? getLngBoundsForSingleCoordinate(lngExt) : lngExt; return [ - [lngExt[0], latExt[0]], - [lngExt[1], latExt[1]], + [lngBounds[0], latBounds[0]], + [lngBounds[1], latBounds[1]], ]; }