[ui/public/utils] Move items into ui/vis (#52615) (#52717)

* [ui/public/utils] Move items into ui/vis

* fix PR comments
This commit is contained in:
Alexey Antonov 2019-12-11 15:11:17 +03:00 committed by GitHub
parent e118a7d842
commit 49ee79118d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 109 additions and 146 deletions

View file

@ -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';

View file

@ -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;
}

View file

@ -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,

View file

@ -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;

View file

@ -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]);
});
});
});
});
});

View file

@ -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 function parseRange(input) {
export class NumberListRange {
constructor(
public minInclusive: boolean,
public min: number,
public max: number,
public maxInclusive: boolean
) {}
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] === ']'
const args = [match[1] === '[', parseFloat(match[2]), parseFloat(match[3]), match[4] === ']'];
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
);
}
function Range(/* minIncl, min, max, maxIncl */) {
const args = _.toArray(arguments);
if (args[1] > args[2]) args.reverse();
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;
};

View file

@ -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 = [

View file

@ -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<number | undefined>) {
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<number | undefined>): NumberRowModel[] {
function getUpdatedModels(
numberList: Array<number | undefined>,
modelList: NumberRowModel[],
numberRange: Range,
numberRange: NumberListRange,
invalidOrderModelIndex?: number
): NumberRowModel[] {
if (!numberList.length) {

View file

@ -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;

View file

@ -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],
});
});

View file

@ -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';

View file

@ -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<number, number> => {
/**
* 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, maxPrecision, maxZoom) {
calculateZoomToPrecisionMap(typeof maxZoom === 'number' ? maxZoom : 21);
return Math.min(zoomPrecisionMap[mapZoom], maxPrecision);
export function zoomToPrecision(mapZoom: number, maxPrecision: number, maxZoom: number) {
const zoomPrecisionMap = calculateZoomToPrecisionMap(typeof maxZoom === 'number' ? maxZoom : 21);
const precision = zoomPrecisionMap.get(mapZoom);
return precision ? Math.min(precision, maxPrecision) : maxPrecision;
}