diff --git a/src/legacy/ui/public/agg_types/buckets/geo_hash.ts b/src/legacy/ui/public/agg_types/buckets/geo_hash.ts index 700f5a048fce2..0acbaf4aa02a2 100644 --- a/src/legacy/ui/public/agg_types/buckets/geo_hash.ts +++ b/src/legacy/ui/public/agg_types/buckets/geo_hash.ts @@ -18,13 +18,13 @@ */ import { i18n } from '@kbn/i18n'; +import { geohashColumns } from 'ui/vis/map/decode_geo_hash'; import chrome from '../../chrome'; import { BucketAggType, IBucketAggConfig } from './_bucket_agg_type'; import { AutoPrecisionParamEditor } from '../../vis/editors/default/controls/auto_precision'; import { UseGeocentroidParamEditor } from '../../vis/editors/default/controls/use_geocentroid'; import { IsFilteredByCollarParamEditor } from '../../vis/editors/default/controls/is_filtered_by_collar'; import { PrecisionParamEditor } from '../../vis/editors/default/controls/precision'; -import { geohashColumns } from '../../utils/decode_geo_hash'; import { AggGroupNames } from '../../vis/editors/default/agg_groups'; import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; diff --git a/src/legacy/ui/public/utils/range.d.ts b/src/legacy/ui/public/utils/range.d.ts deleted file mode 100644 index c484c6f43eebb..0000000000000 --- a/src/legacy/ui/public/utils/range.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export function parseRange(input: string): Range; - -export interface Range { - min: number; - max: number; - minInclusive: boolean; - maxInclusive: boolean; - within(n: number): boolean; -} diff --git a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/__snapshots__/number_list.test.tsx.snap b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/__snapshots__/number_list.test.tsx.snap index ab192e6fd3cbb..4004f8627a898 100644 --- a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/__snapshots__/number_list.test.tsx.snap +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/__snapshots__/number_list.test.tsx.snap @@ -18,7 +18,7 @@ exports[`NumberList should be rendered with default set of props 1`] = ` onChange={[Function]} onDelete={[Function]} range={ - Range { + NumberListRange { "max": 10, "maxInclusive": true, "min": 1, @@ -45,7 +45,7 @@ exports[`NumberList should be rendered with default set of props 1`] = ` onChange={[Function]} onDelete={[Function]} range={ - Range { + NumberListRange { "max": 10, "maxInclusive": true, "min": 1, diff --git a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_row.tsx b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_row.tsx index 23e671180e980..777b0a94f0f3d 100644 --- a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_row.tsx +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_row.tsx @@ -21,7 +21,7 @@ import React, { useCallback } from 'react'; import { EuiFieldNumber, EuiFlexGroup, EuiFlexItem, EuiButtonIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { Range } from '../../../../../../utils/range'; +import { NumberListRange } from './range'; export interface NumberRowProps { autoFocus: boolean; @@ -29,7 +29,7 @@ export interface NumberRowProps { isInvalid: boolean; labelledbyId: string; model: NumberRowModel; - range: Range; + range: NumberListRange; onBlur(): void; onChange({ id, value }: { id: string; value: string }): void; onDelete(index: string): void; diff --git a/src/legacy/ui/public/utils/__tests__/range.js b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/range.test.ts similarity index 66% rename from src/legacy/ui/public/utils/__tests__/range.js rename to src/legacy/ui/public/vis/editors/default/controls/components/number_list/range.test.ts index e7947894d3e22..e9090e5b38ef7 100644 --- a/src/legacy/ui/public/utils/__tests__/range.js +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/range.test.ts @@ -17,32 +17,30 @@ * under the License. */ -import _ from 'lodash'; -import expect from '@kbn/expect'; -import { parseRange } from '../range'; +import { forOwn } from 'lodash'; +import { parseRange } from './range'; -describe('Range parsing utility', function () { - - it('throws an error for inputs that are not formatted properly', function () { - expect(function () { +describe('Range parsing utility', () => { + test('throws an error for inputs that are not formatted properly', () => { + expect(() => { parseRange(''); - }).to.throwException(TypeError); + }).toThrowError(TypeError); - expect(function () { + expect(function() { parseRange('p10202'); - }).to.throwException(TypeError); + }).toThrowError(TypeError); - expect(function () { + expect(function() { parseRange('{0,100}'); - }).to.throwException(TypeError); + }).toThrowError(TypeError); - expect(function () { + expect(function() { parseRange('[0,100'); - }).to.throwException(TypeError); + }).toThrowError(TypeError); - expect(function () { + expect(function() { parseRange(')0,100('); - }).to.throwException(TypeError); + }).toThrowError(TypeError); }); const tests = { @@ -51,52 +49,52 @@ describe('Range parsing utility', function () { min: 0, max: 100, minInclusive: true, - maxInclusive: true + maxInclusive: true, }, within: [ [0, true], [0.0000001, true], [1, true], [99.99999, true], - [100, true] - ] + [100, true], + ], }, '(26.3 , 42]': { props: { min: 26.3, max: 42, minInclusive: false, - maxInclusive: true + maxInclusive: true, }, within: [ [26.2999999, false], [26.3000001, true], [30, true], [41, true], - [42, true] - ] + [42, true], + ], }, '(-50,50)': { props: { min: -50, max: 50, minInclusive: false, - maxInclusive: false + maxInclusive: false, }, within: [ [-50, false], [-49.99999, true], [0, true], [49.99999, true], - [50, false] - ] + [50, false], + ], }, '(Infinity, -Infinity)': { props: { min: -Infinity, max: Infinity, minInclusive: false, - maxInclusive: false + maxInclusive: false, }, within: [ [0, true], @@ -105,25 +103,24 @@ describe('Range parsing utility', function () { [-10000000000, true], [-Infinity, false], [Infinity, false], - ] - } + ], + }, }; - _.forOwn(tests, function (spec, str) { - - describe(str, function () { + forOwn(tests, (spec, str: any) => { + // eslint-disable-next-line jest/valid-describe + describe(str, () => { const range = parseRange(str); - it('creation', function () { - expect(range).to.eql(spec.props); + it('creation', () => { + expect(range).toEqual(spec.props); }); - spec.within.forEach(function (tup) { - it('#within(' + tup[0] + ')', function () { - expect(range.within(tup[0])).to.be(tup[1]); + spec.within.forEach((tup: any[]) => { + it('#within(' + tup[0] + ')', () => { + expect(range.within(tup[0])).toBe(tup[1]); }); }); }); - }); }); diff --git a/src/legacy/ui/public/utils/range.js b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/range.ts similarity index 59% rename from src/legacy/ui/public/utils/range.js rename to src/legacy/ui/public/vis/editors/default/controls/components/number_list/range.ts index 54bd1b1903346..da3b7a61aea9d 100644 --- a/src/legacy/ui/public/utils/range.js +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/range.ts @@ -17,8 +17,6 @@ * under the License. */ -import _ from 'lodash'; - /** * Regexp portion that matches our number * @@ -44,41 +42,44 @@ const _RE_NUMBER = '(\\-?(?:\\d+(?:\\.\\d+)?|Infinity))'; * * @type {RegExp} */ -const RANGE_RE = new RegExp('^\\s*([\\[|\\(])\\s*' + _RE_NUMBER + '\\s*,\\s*' + _RE_NUMBER + '\\s*([\\]|\\)])\\s*$'); +const RANGE_RE = new RegExp( + '^\\s*([\\[|\\(])\\s*' + _RE_NUMBER + '\\s*,\\s*' + _RE_NUMBER + '\\s*([\\]|\\)])\\s*$' +); + +export class NumberListRange { + constructor( + public minInclusive: boolean, + public min: number, + public max: number, + public maxInclusive: boolean + ) {} -export function parseRange(input) { + within(n: number): boolean { + if ((this.min === n && !this.minInclusive) || this.min > n) return false; + if ((this.max === n && !this.maxInclusive) || this.max < n) return false; + + return true; + } +} +export function parseRange(input: string): NumberListRange { const match = String(input).match(RANGE_RE); if (!match) { throw new TypeError('expected input to be in interval notation e.g., (100, 200]'); } - return new Range( - match[1] === '[', - parseFloat(match[2]), - parseFloat(match[3]), - match[4] === ']' - ); -} - -function Range(/* minIncl, min, max, maxIncl */) { - const args = _.toArray(arguments); - if (args[1] > args[2]) args.reverse(); + const args = [match[1] === '[', parseFloat(match[2]), parseFloat(match[3]), match[4] === ']']; - this.minInclusive = args[0]; - this.min = args[1]; - this.max = args[2]; - this.maxInclusive = args[3]; -} - -Range.prototype.within = function (n) { - if (this.min === n && !this.minInclusive) return false; - if (this.min > n) return false; - - if (this.max === n && !this.maxInclusive) return false; - if (this.max < n) return false; - - return true; -}; + if (args[1] > args[2]) { + args.reverse(); + } + const [minInclusive, min, max, maxInclusive] = args; + return new NumberListRange( + minInclusive as boolean, + min as number, + max as number, + maxInclusive as boolean + ); +} diff --git a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts index c6772cc108762..89fb5738db379 100644 --- a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts @@ -27,12 +27,12 @@ import { getNextModel, getRange, } from './utils'; -import { Range } from '../../../../../../utils/range'; +import { NumberListRange } from './range'; import { NumberRowModel } from './number_row'; describe('NumberList utils', () => { let modelList: NumberRowModel[]; - let range: Range; + let range: NumberListRange; beforeEach(() => { modelList = [ diff --git a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.ts b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.ts index 563e8f0a6a9b7..399253f27445c 100644 --- a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.ts +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.ts @@ -21,7 +21,7 @@ import { last } from 'lodash'; import { i18n } from '@kbn/i18n'; import { htmlIdGenerator } from '@elastic/eui'; -import { parseRange, Range } from '../../../../../../utils/range'; +import { parseRange, NumberListRange } from './range'; import { NumberRowModel } from './number_row'; const EMPTY_STRING = ''; @@ -34,7 +34,7 @@ function parse(value: string) { return isNaN(parsedValue) ? EMPTY_STRING : parsedValue; } -function getRange(range?: string): Range { +function getRange(range?: string): NumberListRange { try { return range ? parseRange(range) : defaultRange; } catch (e) { @@ -42,7 +42,7 @@ function getRange(range?: string): Range { } } -function validateValue(value: number | '', numberRange: Range) { +function validateValue(value: number | '', numberRange: NumberListRange) { const result: { isInvalid: boolean; error?: string } = { isInvalid: false, }; @@ -76,7 +76,7 @@ function validateOrder(list: Array) { return result; } -function getNextModel(list: NumberRowModel[], range: Range): NumberRowModel { +function getNextModel(list: NumberRowModel[], range: NumberListRange): NumberRowModel { const lastValue = last(list).value; let next = Number(lastValue) ? Number(lastValue) + 1 : 1; @@ -104,7 +104,7 @@ function getInitModelList(list: Array): NumberRowModel[] { function getUpdatedModels( numberList: Array, modelList: NumberRowModel[], - numberRange: Range, + numberRange: NumberListRange, invalidOrderModelIndex?: number ): NumberRowModel[] { if (!numberList.length) { diff --git a/src/legacy/ui/public/vis/map/convert_to_geojson.js b/src/legacy/ui/public/vis/map/convert_to_geojson.js index 77896490678ff..14c282b58beda 100644 --- a/src/legacy/ui/public/vis/map/convert_to_geojson.js +++ b/src/legacy/ui/public/vis/map/convert_to_geojson.js @@ -17,10 +17,9 @@ * under the License. */ -import { decodeGeoHash } from 'ui/utils/decode_geo_hash'; +import { decodeGeoHash } from './decode_geo_hash'; import { gridDimensions } from './grid_dimensions'; - export function convertToGeoJson(tabifiedResponse, { geohash, geocentroid, metric }) { let features; diff --git a/src/legacy/ui/public/utils/__tests__/decode_geo_hash.test.js b/src/legacy/ui/public/vis/map/decode_geo_hash.test.ts similarity index 75% rename from src/legacy/ui/public/utils/__tests__/decode_geo_hash.test.js rename to src/legacy/ui/public/vis/map/decode_geo_hash.test.ts index 1ffe9ca7b4df2..c1ca7e4c80383 100644 --- a/src/legacy/ui/public/utils/__tests__/decode_geo_hash.test.js +++ b/src/legacy/ui/public/vis/map/decode_geo_hash.test.ts @@ -17,27 +17,18 @@ * under the License. */ -import { geohashColumns, decodeGeoHash } from '../decode_geo_hash'; +import { geohashColumns, decodeGeoHash } from './decode_geo_hash'; -test('geohashColumns', function () { +test('geohashColumns', () => { expect(geohashColumns(1)).toBe(8); expect(geohashColumns(2)).toBe(8 * 4); expect(geohashColumns(3)).toBe(8 * 4 * 8); expect(geohashColumns(4)).toBe(8 * 4 * 8 * 4); }); -test('decodeGeoHash', function () { +test('decodeGeoHash', () => { expect(decodeGeoHash('drm3btev3e86')).toEqual({ - latitude: [ - 41.119999922811985, - 41.12000009045005, - 41.12000000663102, - ], - longitude: [ - -71.34000029414892, - -71.3399999588728, - -71.34000012651086, - ], + latitude: [41.119999922811985, 41.12000009045005, 41.12000000663102], + longitude: [-71.34000029414892, -71.3399999588728, -71.34000012651086], }); }); - diff --git a/src/legacy/ui/public/utils/decode_geo_hash.ts b/src/legacy/ui/public/vis/map/decode_geo_hash.ts similarity index 100% rename from src/legacy/ui/public/utils/decode_geo_hash.ts rename to src/legacy/ui/public/vis/map/decode_geo_hash.ts diff --git a/src/legacy/ui/public/vis/map/kibana_map.js b/src/legacy/ui/public/vis/map/kibana_map.js index dc57809b6570f..cb618444af7ce 100644 --- a/src/legacy/ui/public/vis/map/kibana_map.js +++ b/src/legacy/ui/public/vis/map/kibana_map.js @@ -22,7 +22,7 @@ import { createZoomWarningMsg } from './map_messages'; import L from 'leaflet'; import $ from 'jquery'; import _ from 'lodash'; -import { zoomToPrecision } from '../../utils/zoom_to_precision'; +import { zoomToPrecision } from './zoom_to_precision'; import { i18n } from '@kbn/i18n'; import { ORIGIN } from '../../../../core_plugins/tile_map/common/origin'; diff --git a/src/legacy/ui/public/utils/zoom_to_precision.js b/src/legacy/ui/public/vis/map/zoom_to_precision.ts similarity index 52% rename from src/legacy/ui/public/utils/zoom_to_precision.js rename to src/legacy/ui/public/vis/map/zoom_to_precision.ts index f5c16b640d127..552c509590286 100644 --- a/src/legacy/ui/public/utils/zoom_to_precision.js +++ b/src/legacy/ui/public/vis/map/zoom_to_precision.ts @@ -19,39 +19,42 @@ import { geohashColumns } from './decode_geo_hash'; -const maxPrecision = 12; -/** - * Map Leaflet zoom levels to geohash precision levels. - * The size of a geohash column-width on the map should be at least `minGeohashPixels` pixels wide. - */ - - +const defaultMaxPrecision = 12; +const minGeoHashPixels = 16; - -const zoomPrecisionMap = {}; -const minGeohashPixels = 16; - -function calculateZoomToPrecisionMap(maxZoom) { +const calculateZoomToPrecisionMap = (maxZoom: number): Map => { + /** + * Map Leaflet zoom levels to geohash precision levels. + * The size of a geohash column-width on the map should be at least `minGeohashPixels` pixels wide. + */ + const zoomPrecisionMap = new Map(); for (let zoom = 0; zoom <= maxZoom; zoom += 1) { - if (typeof zoomPrecisionMap[zoom] === 'number') { + if (typeof zoomPrecisionMap.get(zoom) === 'number') { continue; } + const worldPixels = 256 * Math.pow(2, zoom); - zoomPrecisionMap[zoom] = 1; - for (let precision = 2; precision <= maxPrecision; precision += 1) { + + zoomPrecisionMap.set(zoom, 1); + + for (let precision = 2; precision <= defaultMaxPrecision; precision += 1) { const columns = geohashColumns(precision); - if ((worldPixels / columns) >= minGeohashPixels) { - zoomPrecisionMap[zoom] = precision; + + if (worldPixels / columns >= minGeoHashPixels) { + zoomPrecisionMap.set(zoom, precision); } else { break; } } } -} + return zoomPrecisionMap; +}; + +export function zoomToPrecision(mapZoom: number, maxPrecision: number, maxZoom: number) { + const zoomPrecisionMap = calculateZoomToPrecisionMap(typeof maxZoom === 'number' ? maxZoom : 21); + const precision = zoomPrecisionMap.get(mapZoom); -export function zoomToPrecision(mapZoom, maxPrecision, maxZoom) { - calculateZoomToPrecisionMap(typeof maxZoom === 'number' ? maxZoom : 21); - return Math.min(zoomPrecisionMap[mapZoom], maxPrecision); + return precision ? Math.min(precision, maxPrecision) : maxPrecision; }