From fd1bc5867d8f664de9373377fed710e912dab91f Mon Sep 17 00:00:00 2001 From: ppisljar Date: Tue, 13 Dec 2016 13:40:08 +0100 Subject: [PATCH 1/3] moving colors and tooltips out of vislib to vis --- .../kibana/public/visualize/editor/nesting_indicator.js | 2 +- src/core_plugins/tagcloud/public/tag_cloud.js | 2 +- .../public/{vislib => vis}/__tests__/components/color.js | 8 ++++---- src/ui/public/{vislib => vis}/components/color/color.js | 0 .../{vislib => vis}/components/color/color_palette.js | 0 .../{vislib => vis}/components/color/mapped_colors.js | 0 .../{vislib => vis}/components/color/seed_colors.js | 0 src/ui/public/vis/components/index.js | 9 +++++++++ .../components/tooltip/__tests__/positioning.js | 0 .../components/tooltip/position_tooltip.js | 0 .../public/{vislib => vis}/components/tooltip/tooltip.js | 0 src/ui/public/vis/vis_type.js | 2 +- src/ui/public/vislib/lib/chart_title.js | 3 ++- src/ui/public/vislib/lib/data.js | 2 +- src/ui/public/vislib/visualizations/_chart.js | 5 ++--- src/ui/public/vislib/visualizations/point_series.js | 2 +- src/ui/public/visualize/visualize_legend.js | 2 +- 17 files changed, 23 insertions(+), 14 deletions(-) rename src/ui/public/{vislib => vis}/__tests__/components/color.js (96%) rename src/ui/public/{vislib => vis}/components/color/color.js (100%) rename src/ui/public/{vislib => vis}/components/color/color_palette.js (100%) rename src/ui/public/{vislib => vis}/components/color/mapped_colors.js (100%) rename src/ui/public/{vislib => vis}/components/color/seed_colors.js (100%) create mode 100644 src/ui/public/vis/components/index.js rename src/ui/public/{vislib => vis}/components/tooltip/__tests__/positioning.js (100%) rename src/ui/public/{vislib => vis}/components/tooltip/position_tooltip.js (100%) rename src/ui/public/{vislib => vis}/components/tooltip/tooltip.js (100%) diff --git a/src/core_plugins/kibana/public/visualize/editor/nesting_indicator.js b/src/core_plugins/kibana/public/visualize/editor/nesting_indicator.js index 6187760f8265b..8daa5d277213c 100644 --- a/src/core_plugins/kibana/public/visualize/editor/nesting_indicator.js +++ b/src/core_plugins/kibana/public/visualize/editor/nesting_indicator.js @@ -1,6 +1,6 @@ import _ from 'lodash'; import $ from 'jquery'; -import VislibComponentsColorColorPaletteProvider from 'ui/vislib/components/color/color_palette'; +import VislibComponentsColorColorPaletteProvider from 'ui/vis/components/color/color_palette'; import uiModules from 'ui/modules'; uiModules .get('kibana') diff --git a/src/core_plugins/tagcloud/public/tag_cloud.js b/src/core_plugins/tagcloud/public/tag_cloud.js index c5038bb49627e..dfb9507d6ae84 100644 --- a/src/core_plugins/tagcloud/public/tag_cloud.js +++ b/src/core_plugins/tagcloud/public/tag_cloud.js @@ -1,6 +1,6 @@ import d3 from 'd3'; import d3TagCloud from 'd3-cloud'; -import vislibComponentsSeedColorsProvider from 'ui/vislib/components/color/seed_colors'; +import vislibComponentsSeedColorsProvider from 'ui/vis/components/color/seed_colors'; import { EventEmitter } from 'events'; diff --git a/src/ui/public/vislib/__tests__/components/color.js b/src/ui/public/vis/__tests__/components/color.js similarity index 96% rename from src/ui/public/vislib/__tests__/components/color.js rename to src/ui/public/vis/__tests__/components/color.js index 7362f8c98d54f..95a3b0be8a85c 100644 --- a/src/ui/public/vislib/__tests__/components/color.js +++ b/src/ui/public/vis/__tests__/components/color.js @@ -3,10 +3,10 @@ import expect from 'expect.js'; import ngMock from 'ng_mock'; import _ from 'lodash'; import d3 from 'd3'; -import VislibComponentsColorSeedColorsProvider from 'ui/vislib/components/color/seed_colors'; -import VislibComponentsColorColorProvider from 'ui/vislib/components/color/color'; -import VislibComponentsColorMappedColorsProvider from 'ui/vislib/components/color/mapped_colors'; -import VislibComponentsColorColorPaletteProvider from 'ui/vislib/components/color/color_palette'; +import VislibComponentsColorSeedColorsProvider from 'ui/vis/components/color/seed_colors'; +import VislibComponentsColorColorProvider from 'ui/vis/components/color/color'; +import VislibComponentsColorMappedColorsProvider from 'ui/vis/components/color/mapped_colors'; +import VislibComponentsColorColorPaletteProvider from 'ui/vis/components/color/color_palette'; describe('Vislib Color Module Test Suite', function () { let seedColors; diff --git a/src/ui/public/vislib/components/color/color.js b/src/ui/public/vis/components/color/color.js similarity index 100% rename from src/ui/public/vislib/components/color/color.js rename to src/ui/public/vis/components/color/color.js diff --git a/src/ui/public/vislib/components/color/color_palette.js b/src/ui/public/vis/components/color/color_palette.js similarity index 100% rename from src/ui/public/vislib/components/color/color_palette.js rename to src/ui/public/vis/components/color/color_palette.js diff --git a/src/ui/public/vislib/components/color/mapped_colors.js b/src/ui/public/vis/components/color/mapped_colors.js similarity index 100% rename from src/ui/public/vislib/components/color/mapped_colors.js rename to src/ui/public/vis/components/color/mapped_colors.js diff --git a/src/ui/public/vislib/components/color/seed_colors.js b/src/ui/public/vis/components/color/seed_colors.js similarity index 100% rename from src/ui/public/vislib/components/color/seed_colors.js rename to src/ui/public/vis/components/color/seed_colors.js diff --git a/src/ui/public/vis/components/index.js b/src/ui/public/vis/components/index.js new file mode 100644 index 0000000000000..cf438b9bf492f --- /dev/null +++ b/src/ui/public/vis/components/index.js @@ -0,0 +1,9 @@ +import TooltipProvider from './tooltip'; +import ColorProvider from './color'; + +export default function ComponentsProvider(Private) { + return { + tooltip: Private(TooltipProvider), + colors: Private(ColorProvider) + }; +} diff --git a/src/ui/public/vislib/components/tooltip/__tests__/positioning.js b/src/ui/public/vis/components/tooltip/__tests__/positioning.js similarity index 100% rename from src/ui/public/vislib/components/tooltip/__tests__/positioning.js rename to src/ui/public/vis/components/tooltip/__tests__/positioning.js diff --git a/src/ui/public/vislib/components/tooltip/position_tooltip.js b/src/ui/public/vis/components/tooltip/position_tooltip.js similarity index 100% rename from src/ui/public/vislib/components/tooltip/position_tooltip.js rename to src/ui/public/vis/components/tooltip/position_tooltip.js diff --git a/src/ui/public/vislib/components/tooltip/tooltip.js b/src/ui/public/vis/components/tooltip/tooltip.js similarity index 100% rename from src/ui/public/vislib/components/tooltip/tooltip.js rename to src/ui/public/vis/components/tooltip/tooltip.js diff --git a/src/ui/public/vis/vis_type.js b/src/ui/public/vis/vis_type.js index 7540ec5a6c964..39c3de6ecaf79 100644 --- a/src/ui/public/vis/vis_type.js +++ b/src/ui/public/vis/vis_type.js @@ -1,4 +1,4 @@ -import VisSchemasProvider from 'ui/vis/schemas'; +import VisSchemasProvider from './schemas'; export default function VisTypeFactory(Private) { const VisTypeSchemas = Private(VisSchemasProvider); diff --git a/src/ui/public/vislib/lib/chart_title.js b/src/ui/public/vislib/lib/chart_title.js index 0d290922e6781..62ea4fea2bdb0 100644 --- a/src/ui/public/vislib/lib/chart_title.js +++ b/src/ui/public/vislib/lib/chart_title.js @@ -1,7 +1,8 @@ import d3 from 'd3'; import _ from 'lodash'; import ErrorHandlerProvider from './_error_handler'; -import TooltipProvider from '../components/tooltip'; +import TooltipProvider from 'ui/vis/components/tooltip'; + export default function ChartTitleFactory(Private) { const ErrorHandler = Private(ErrorHandlerProvider); const Tooltip = Private(TooltipProvider); diff --git a/src/ui/public/vislib/lib/data.js b/src/ui/public/vislib/lib/data.js index 269d9bf525a6f..92d5ede91a821 100644 --- a/src/ui/public/vislib/lib/data.js +++ b/src/ui/public/vislib/lib/data.js @@ -3,7 +3,7 @@ import _ from 'lodash'; import VislibComponentsZeroInjectionInjectZerosProvider from '../components/zero_injection/inject_zeros'; import VislibComponentsZeroInjectionOrderedXKeysProvider from '../components/zero_injection/ordered_x_keys'; import VislibComponentsLabelsLabelsProvider from '../components/labels/labels'; -import VislibComponentsColorColorProvider from '../components/color/color'; +import VislibComponentsColorColorProvider from 'ui/vis/components/color/color'; export default function DataFactory(Private) { const injectZeros = Private(VislibComponentsZeroInjectionInjectZerosProvider); diff --git a/src/ui/public/vislib/visualizations/_chart.js b/src/ui/public/vislib/visualizations/_chart.js index 51ec979b2bc3b..74cb56d06a80c 100644 --- a/src/ui/public/vislib/visualizations/_chart.js +++ b/src/ui/public/vislib/visualizations/_chart.js @@ -2,12 +2,11 @@ import d3 from 'd3'; import _ from 'lodash'; import dataLabel from 'ui/vislib/lib/_data_label'; import VislibLibDispatchProvider from '../lib/dispatch'; -import VislibComponentsTooltipProvider from '../components/tooltip'; +import TooltipProvider from 'ui/vis/components/tooltip'; export default function ChartBaseClass(Private) { const Dispatch = Private(VislibLibDispatchProvider); - const Tooltip = Private(VislibComponentsTooltipProvider); - + const Tooltip = Private(TooltipProvider); /** * The Base Class for all visualizations. * diff --git a/src/ui/public/vislib/visualizations/point_series.js b/src/ui/public/vislib/visualizations/point_series.js index a41a132998d02..1847df56875cd 100644 --- a/src/ui/public/vislib/visualizations/point_series.js +++ b/src/ui/public/vislib/visualizations/point_series.js @@ -2,7 +2,7 @@ import d3 from 'd3'; import _ from 'lodash'; import $ from 'jquery'; import errors from 'ui/errors'; -import TooltipProvider from '../components/tooltip'; +import TooltipProvider from 'ui/vis/components/tooltip'; import VislibVisualizationsChartProvider from './_chart'; import VislibVisualizationsTimeMarkerProvider from './time_marker'; import VislibVisualizationsSeriTypesProvider from './point_series/series_types'; diff --git a/src/ui/public/visualize/visualize_legend.js b/src/ui/public/visualize/visualize_legend.js index dd8874fe2ca5a..7384c5f112733 100644 --- a/src/ui/public/visualize/visualize_legend.js +++ b/src/ui/public/visualize/visualize_legend.js @@ -1,7 +1,7 @@ import _ from 'lodash'; import html from 'ui/visualize/visualize_legend.html'; import VislibLibDataProvider from 'ui/vislib/lib/data'; -import VislibComponentsColorColorProvider from 'ui/vislib/components/color/color'; +import VislibComponentsColorColorProvider from 'ui/vis/components/color/color'; import FilterBarFilterBarClickHandlerProvider from 'ui/filter_bar/filter_bar_click_handler'; import uiModules from 'ui/modules'; From 126f1de6c3092cc2b35b9690044ffb5c89ef10ff Mon Sep 17 00:00:00 2001 From: ppisljar Date: Tue, 13 Dec 2016 13:40:49 +0100 Subject: [PATCH 2/3] moving tile map vis out of vislib --- .../kbn_vislib_vis_types/public/tile_map.js | 6 +- .../__tests__}/tile_maps/map.js | 2 +- .../__tests__}/tile_maps/markers.js | 8 +- .../__tests__}/tile_maps/tile_map.js | 15 +- src/ui/public/vis_maps/lib/data.js | 201 +++++++++++ src/ui/public/vis_maps/lib/dispatch.js | 315 ++++++++++++++++++ src/ui/public/vis_maps/lib/layout.js | 50 +++ src/ui/public/vis_maps/lib/maps_config.js | 38 +++ .../lib/splits}/map_split.js | 0 src/ui/public/vis_maps/maps.js | 106 ++++++ src/ui/public/vis_maps/maps_renderbot.js | 77 +++++ src/ui/public/vis_maps/maps_vis_type.js | 22 ++ .../{vislib => vis_maps}/styles/_tilemap.less | 0 .../public/vis_maps/visualizations/_chart.js | 60 ++++ .../visualizations/_map.js | 8 +- .../marker_types/base_marker.js | 0 .../marker_types/geohash_grid.js | 0 .../visualizations/marker_types/heatmap.js | 0 .../marker_types/scaled_circles.js | 0 .../marker_types/shaded_circles.js | 0 .../visualizations/tile_map.js | 11 +- .../public/vislib/lib/layout/layout_types.js | 2 - .../vislib/lib/layout/types/map_layout.js | 49 --- src/ui/public/vislib/lib/types/index.js | 2 - src/ui/public/vislib/lib/types/tile_map.js | 19 -- src/ui/public/vislib/styles/main.less | 1 - src/ui/public/vislib/vislib.js | 2 - .../public/vislib/visualizations/vis_types.js | 2 - 28 files changed, 892 insertions(+), 104 deletions(-) rename src/ui/public/{vislib/__tests__/visualizations => vis_maps/__tests__}/tile_maps/map.js (98%) rename src/ui/public/{vislib/__tests__/visualizations => vis_maps/__tests__}/tile_maps/markers.js (98%) rename src/ui/public/{vislib/__tests__/visualizations => vis_maps/__tests__}/tile_maps/tile_map.js (91%) create mode 100644 src/ui/public/vis_maps/lib/data.js create mode 100644 src/ui/public/vis_maps/lib/dispatch.js create mode 100644 src/ui/public/vis_maps/lib/layout.js create mode 100644 src/ui/public/vis_maps/lib/maps_config.js rename src/ui/public/{vislib/lib/layout/splits/tile_map => vis_maps/lib/splits}/map_split.js (100%) create mode 100644 src/ui/public/vis_maps/maps.js create mode 100644 src/ui/public/vis_maps/maps_renderbot.js create mode 100644 src/ui/public/vis_maps/maps_vis_type.js rename src/ui/public/{vislib => vis_maps}/styles/_tilemap.less (100%) create mode 100644 src/ui/public/vis_maps/visualizations/_chart.js rename src/ui/public/{vislib => vis_maps}/visualizations/_map.js (97%) rename src/ui/public/{vislib => vis_maps}/visualizations/marker_types/base_marker.js (100%) rename src/ui/public/{vislib => vis_maps}/visualizations/marker_types/geohash_grid.js (100%) rename src/ui/public/{vislib => vis_maps}/visualizations/marker_types/heatmap.js (100%) rename src/ui/public/{vislib => vis_maps}/visualizations/marker_types/scaled_circles.js (100%) rename src/ui/public/{vislib => vis_maps}/visualizations/marker_types/shaded_circles.js (100%) rename src/ui/public/{vislib => vis_maps}/visualizations/tile_map.js (93%) delete mode 100644 src/ui/public/vislib/lib/types/tile_map.js diff --git a/src/core_plugins/kbn_vislib_vis_types/public/tile_map.js b/src/core_plugins/kbn_vislib_vis_types/public/tile_map.js index a2c2cc4de455e..6605479c0798c 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/tile_map.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/tile_map.js @@ -1,17 +1,17 @@ import _ from 'lodash'; import supports from 'ui/utils/supports'; -import VislibVisTypeVislibVisTypeProvider from 'ui/vislib_vis_type/vislib_vis_type'; +import MapsVisTypeVislibVisTypeProvider from 'ui/vis_maps/maps_vis_type'; import VisSchemasProvider from 'ui/vis/schemas'; import AggResponseGeoJsonGeoJsonProvider from 'ui/agg_response/geo_json/geo_json'; import FilterBarPushFilterProvider from 'ui/filter_bar/push_filter'; import tileMapTemplate from 'plugins/kbn_vislib_vis_types/editors/tile_map.html'; export default function TileMapVisType(Private, getAppState, courier, config) { - const VislibVisType = Private(VislibVisTypeVislibVisTypeProvider); + const MapsVisType = Private(MapsVisTypeVislibVisTypeProvider); const Schemas = Private(VisSchemasProvider); const geoJsonConverter = Private(AggResponseGeoJsonGeoJsonProvider); - return new VislibVisType({ + return new MapsVisType({ name: 'tile_map', title: 'Tile map', icon: 'fa-map-marker', diff --git a/src/ui/public/vislib/__tests__/visualizations/tile_maps/map.js b/src/ui/public/vis_maps/__tests__/tile_maps/map.js similarity index 98% rename from src/ui/public/vislib/__tests__/visualizations/tile_maps/map.js rename to src/ui/public/vis_maps/__tests__/tile_maps/map.js index 2e9e1d1c69ef0..d03814db7d8d3 100644 --- a/src/ui/public/vislib/__tests__/visualizations/tile_maps/map.js +++ b/src/ui/public/vis_maps/__tests__/tile_maps/map.js @@ -7,7 +7,7 @@ import L from 'leaflet'; import sinon from 'auto-release-sinon'; import geoJsonData from 'fixtures/vislib/mock_data/geohash/_geo_json'; import $ from 'jquery'; -import VislibVisualizationsMapProvider from 'ui/vislib/visualizations/_map'; +import VislibVisualizationsMapProvider from 'ui/vis_maps/visualizations/_map'; // // Data // const dataArray = [ diff --git a/src/ui/public/vislib/__tests__/visualizations/tile_maps/markers.js b/src/ui/public/vis_maps/__tests__/tile_maps/markers.js similarity index 98% rename from src/ui/public/vislib/__tests__/visualizations/tile_maps/markers.js rename to src/ui/public/vis_maps/__tests__/tile_maps/markers.js index 8d06738695399..bd9d59016dcc1 100644 --- a/src/ui/public/vislib/__tests__/visualizations/tile_maps/markers.js +++ b/src/ui/public/vis_maps/__tests__/tile_maps/markers.js @@ -7,10 +7,10 @@ import L from 'leaflet'; import sinon from 'auto-release-sinon'; import geoJsonData from 'fixtures/vislib/mock_data/geohash/_geo_json'; import $ from 'jquery'; -import VislibVisualizationsMarkerTypesBaseMarkerProvider from 'ui/vislib/visualizations/marker_types/base_marker'; -import VislibVisualizationsMarkerTypesShadedCirclesProvider from 'ui/vislib/visualizations/marker_types/shaded_circles'; -import VislibVisualizationsMarkerTypesScaledCirclesProvider from 'ui/vislib/visualizations/marker_types/scaled_circles'; -import VislibVisualizationsMarkerTypesHeatmapProvider from 'ui/vislib/visualizations/marker_types/heatmap'; +import VislibVisualizationsMarkerTypesBaseMarkerProvider from 'ui/vis_maps/visualizations/marker_types/base_marker'; +import VislibVisualizationsMarkerTypesShadedCirclesProvider from 'ui/vis_maps/visualizations/marker_types/shaded_circles'; +import VislibVisualizationsMarkerTypesScaledCirclesProvider from 'ui/vis_maps/visualizations/marker_types/scaled_circles'; +import VislibVisualizationsMarkerTypesHeatmapProvider from 'ui/vis_maps/visualizations/marker_types/heatmap'; // defaults to roughly the lower 48 US states const defaultSWCoords = [13.496, -143.789]; const defaultNECoords = [55.526, -57.919]; diff --git a/src/ui/public/vislib/__tests__/visualizations/tile_maps/tile_map.js b/src/ui/public/vis_maps/__tests__/tile_maps/tile_map.js similarity index 91% rename from src/ui/public/vislib/__tests__/visualizations/tile_maps/tile_map.js rename to src/ui/public/vis_maps/__tests__/tile_maps/tile_map.js index 8500ca9cd790f..4ca355f57904c 100644 --- a/src/ui/public/vislib/__tests__/visualizations/tile_maps/tile_map.js +++ b/src/ui/public/vis_maps/__tests__/tile_maps/tile_map.js @@ -6,7 +6,7 @@ import sinon from 'auto-release-sinon'; import geoJsonData from 'fixtures/vislib/mock_data/geohash/_geo_json'; import MockMap from 'fixtures/tilemap_map'; import $ from 'jquery'; -import VislibVisualizationsTileMapProvider from 'ui/vislib/visualizations/tile_map'; +import VislibVisualizationsTileMapProvider from 'ui/vis_maps/visualizations/tile_map'; const mockChartEl = $('
'); let TileMap; @@ -18,6 +18,11 @@ function createTileMap(handler, chartEl, chartData) { get: function () { return ''; } + }, + uiState: { + get: function () { + return ''; + } } }; chartEl = chartEl || mockChartEl; @@ -32,7 +37,7 @@ describe('TileMap Tests', function () { beforeEach(ngMock.module('kibana')); beforeEach(ngMock.inject(function (Private) { - Private.stub(require('ui/vislib/visualizations/_map'), MockMap); + Private.stub(require('ui/vis_maps/visualizations/_map'), MockMap); TileMap = Private(VislibVisualizationsTileMapProvider); extentsStub = sinon.stub(TileMap.prototype, '_appendGeoExtents', _.noop); })); @@ -55,12 +60,6 @@ describe('TileMap Tests', function () { it('should return a function', function () { expect(tilemap.draw()).to.be.a('function'); }); - - it('should call destroy for clean state', function () { - const destroySpy = sinon.spy(tilemap, 'destroy'); - tilemap.draw(); - expect(destroySpy.callCount).to.equal(1); - }); }); describe('appendMap', function () { diff --git a/src/ui/public/vis_maps/lib/data.js b/src/ui/public/vis_maps/lib/data.js new file mode 100644 index 0000000000000..2c84b801355a4 --- /dev/null +++ b/src/ui/public/vis_maps/lib/data.js @@ -0,0 +1,201 @@ +import d3 from 'd3'; +import _ from 'lodash'; +export default function DataFactory(Private) { + /** + * Provides an API for pulling values off the data + * and calculating values using the data + * + * @class Data + * @constructor + * @param data {Object} Elasticsearch query results + * @param attr {Object|*} Visualization options + */ + class Data { + constructor(data, uiState) { + this.uiState = uiState; + this.data = this.copyDataObj(data); + this._normalizeOrdered(); + } + + copyDataObj(data) { + const copyChart = data => { + const newData = {}; + Object.keys(data).forEach(key => { + if (key !== 'series') { + newData[key] = data[key]; + } else { + newData[key] = data[key].map(seri => { + return { + label: seri.label, + values: seri.values.map(val => { + const newVal = _.clone(val); + newVal.aggConfig = val.aggConfig; + newVal.aggConfigResult = val.aggConfigResult; + newVal.extraMetrics = val.extraMetrics; + return newVal; + }) + }; + }); + } + }); + return newData; + }; + + if (!data.series) { + const newData = {}; + Object.keys(data).forEach(key => { + if (!['rows', 'columns'].includes(key)) { + newData[key] = data[key]; + } + else { + newData[key] = data[key].map(chart => { + return copyChart(chart); + }); + } + }); + return newData; + } + return copyChart(data); + } + + /** + * Returns an array of the actual x and y data value objects + * from data with series keys + * + * @method chartData + * @returns {*} Array of data objects + */ + chartData() { + if (!this.data.series) { + const arr = this.data.rows ? this.data.rows : this.data.columns; + return _.toArray(arr); + } + return [this.data]; + }; + + /** + * Returns an array of chart data objects + * + * @method getVisData + * @returns {*} Array of chart data objects + */ + getVisData() { + let visData; + + if (this.data.rows) { + visData = this.data.rows; + } else if (this.data.columns) { + visData = this.data.columns; + } else { + visData = [this.data]; + } + + return visData; + }; + + /** + * get min and max for all cols, rows of data + * + * @method getMaxMin + * @return {Object} + */ + getGeoExtents() { + const visData = this.getVisData(); + + return _.reduce(_.pluck(visData, 'geoJson.properties'), function (minMax, props) { + return { + min: Math.min(props.min, minMax.min), + max: Math.max(props.max, minMax.max) + }; + }, {min: Infinity, max: -Infinity}); + }; + + /** + * Get attributes off the data, e.g. `tooltipFormatter` or `xAxisFormatter` + * pulls the value off the first item in the array + * these values are typically the same between data objects of the same chart + * TODO: May need to verify this or refactor + * + * @method get + * @param thing {String} Data object key + * @returns {*} Data object value + */ + get(thing, def) { + const source = (this.data.rows || this.data.columns || [this.data])[0]; + return _.get(source, thing, def); + }; + + /** + * Return an array of all value objects + * Pluck the data.series array from each data object + * Create an array of all the value objects from the series array + * + * @method flatten + * @returns {Array} Value objects + */ + flatten() { + return _(this.chartData()) + .pluck('series') + .flattenDeep() + .pluck('values') + .flattenDeep() + .value(); + }; + + /** + * ensure that the datas ordered property has a min and max + * if the data represents an ordered date range. + * + * @return {undefined} + */ + _normalizeOrdered() { + const data = this.getVisData(); + const self = this; + + data.forEach(function (d) { + if (!d.ordered || !d.ordered.date) return; + + const missingMin = d.ordered.min == null; + const missingMax = d.ordered.max == null; + + if (missingMax || missingMin) { + const extent = d3.extent(self.xValues()); + if (missingMin) d.ordered.min = extent[0]; + if (missingMax) d.ordered.max = extent[1]; + } + }); + }; + + /** + * Calculates min and max values for all map data + * series.rows is an array of arrays + * each row is an array of values + * last value in row array is bucket count + * + * @method mapDataExtents + * @param series {Array} Array of data objects + * @returns {Array} min and max values + */ + mapDataExtents(series) { + let values; + values = _.map(series.rows, function (row) { + return row[row.length - 1]; + }); + return [_.min(values), _.max(values)]; + }; + + /** + * Get the maximum number of series, considering each chart + * individually. + * + * @return {number} - the largest number of series from all charts + */ + maxNumberOfSeries() { + return this.chartData().reduce(function (max, chart) { + return Math.max(max, chart.series.length); + }, 0); + }; + } + + return Data; +}; diff --git a/src/ui/public/vis_maps/lib/dispatch.js b/src/ui/public/vis_maps/lib/dispatch.js new file mode 100644 index 0000000000000..114b7e2a6a2af --- /dev/null +++ b/src/ui/public/vis_maps/lib/dispatch.js @@ -0,0 +1,315 @@ +import d3 from 'd3'; +import _ from 'lodash'; +import $ from 'jquery'; +import SimpleEmitter from 'ui/utils/simple_emitter'; + +export default function DispatchClass(Private, config) { + + /** + * Handles event responses + * + * @class Dispatch + * @constructor + * @param handler {Object} Reference to Handler Class Object + */ + + class Dispatch extends SimpleEmitter { + constructor(handler) { + super(); + this.handler = handler; + this._listeners = {}; + } + + /** + * Response to click and hover events + * + * @param d {Object} Data point + * @param i {Number} Index number of data point + * @returns {{value: *, point: *, label: *, color: *, pointIndex: *, + * series: *, config: *, data: (Object|*), + * e: (d3.event|*), handler: (Object|*)}} Event response object + */ + eventResponse(d, i) { + const datum = d._input || d; + const data = d3.event.target.nearestViewportElement ? + d3.event.target.nearestViewportElement.__data__ : d3.event.target.__data__; + const label = d.label ? d.label : (d.series || 'Count'); + const isSeries = !!(data && data.series); + const isSlices = !!(data && data.slices); + const series = isSeries ? data.series : undefined; + const slices = isSlices ? data.slices : undefined; + const handler = this.handler; + const color = _.get(handler, 'data.color'); + const isPercentage = (handler && handler.visConfig.get('mode', 'normal') === 'percentage'); + + const eventData = { + value: d.y, + point: datum, + datum: datum, + label: label, + color: color ? color(label) : undefined, + pointIndex: i, + series: series, + slices: slices, + config: handler && handler.visConfig, + data: data, + e: d3.event, + handler: handler + }; + + if (isSeries) { + // Find object with the actual d value and add it to the point object + const object = _.find(series, {'label': label}); + if (object) { + eventData.value = +object.values[i].y; + + if (isPercentage) { + // Add the formatted percentage to the point object + eventData.percent = (100 * d.y).toFixed(1) + '%'; + } + } + } + + return eventData; + }; + + /** + * Returns a function that adds events and listeners to a D3 selection + * + * @method addEvent + * @param event {String} + * @param callback {Function} + * @returns {Function} + */ + addEvent(event, callback) { + return function (selection) { + selection.each(function () { + const element = d3.select(this); + + if (typeof callback === 'function') { + return element.on(event, callback); + } + }); + }; + }; + + /** + * + * @method addHoverEvent + * @returns {Function} + */ + addHoverEvent() { + const self = this; + const isClickable = this.listenerCount('click') > 0; + const addEvent = this.addEvent; + const $el = this.handler.el; + if (!this.handler.highlight) { + this.handler.highlight = self.highlight; + } + + function hover(d, i) { + // Add pointer if item is clickable + if (isClickable) { + self.addMousePointer.call(this, arguments); + } + + self.handler.highlight.call(this, $el); + self.emit('hover', self.eventResponse(d, i)); + } + + return addEvent('mouseover', hover); + }; + + /** + * + * @method addMouseoutEvent + * @returns {Function} + */ + addMouseoutEvent() { + const self = this; + const addEvent = this.addEvent; + const $el = this.handler.el; + if (!this.handler.unHighlight) { + this.handler.unHighlight = self.unHighlight; + } + + function mouseout() { + self.handler.unHighlight.call(this, $el); + } + + return addEvent('mouseout', mouseout); + }; + + /** + * + * @method addClickEvent + * @returns {Function} + */ + addClickEvent() { + const self = this; + const addEvent = this.addEvent; + + function click(d, i) { + self.emit('click', self.eventResponse(d, i)); + } + + return addEvent('click', click); + }; + + /** + * Determine if we will allow brushing + * + * @method allowBrushing + * @returns {Boolean} + */ + allowBrushing() { + const xAxis = this.handler.categoryAxes[0]; + + //Allow brushing for ordered axis - date histogram and histogram + return Boolean(xAxis.ordered); + }; + + /** + * Determine if brushing is currently enabled + * + * @method isBrushable + * @returns {Boolean} + */ + isBrushable() { + return this.allowBrushing() && this.listenerCount('brush') > 0; + }; + + /** + * Mouseover Behavior + * + * @method addMousePointer + * @returns {d3.Selection} + */ + addMousePointer() { + return d3.select(this).style('cursor', 'pointer'); + }; + + /** + * Highlight the element that is under the cursor + * by reducing the opacity of all the elements on the graph. + * @param element {d3.Selection} + * @method highlight + */ + highlight(element) { + const label = this.getAttribute('data-label'); + if (!label) return; + + const dimming = config.get('visualization:dimmingOpacity'); + $(element).parent().find('[data-label]') + .css('opacity', 1)//Opacity 1 is needed to avoid the css application + .not((els, el) => String($(el).data('label')) === label) + .css('opacity', justifyOpacity(dimming)); + } + + /** + * Mouseout Behavior + * + * @param element {d3.Selection} + * @method unHighlight + */ + unHighlight(element) { + $('[data-label]', element.parentNode).css('opacity', 1); + }; + + /** + * Adds D3 brush to SVG and returns the brush function + * + * @param xScale {Function} D3 xScale function + * @param svg {HTMLElement} Reference to SVG + * @returns {*} Returns a D3 brush function and a SVG with a brush group attached + */ + createBrush(xScale, svg) { + const self = this; + const visConfig = self.handler.visConfig; + const {width, height} = svg.node().getBBox(); + const isHorizontal = self.handler.categoryAxes[0].axisConfig.isHorizontal(); + + // Brush scale + const brush = d3.svg.brush(); + if (isHorizontal) { + brush.x(xScale); + } else { + brush.y(xScale); + } + + brush.on('brushend', function brushEnd() { + + // Assumes data is selected at the chart level + // In this case, the number of data objects should always be 1 + const data = d3.select(this).data()[0]; + const isTimeSeries = (data.ordered && data.ordered.date); + + // Allows for brushing on d3.scale.ordinal() + const selected = xScale.domain().filter(function (d) { + return (brush.extent()[0] <= xScale(d)) && (xScale(d) <= brush.extent()[1]); + }); + const range = isTimeSeries ? brush.extent() : selected; + + return self.emit('brush', { + range: range, + config: visConfig, + e: d3.event, + data: data + }); + }); + + // if `addBrushing` is true, add brush canvas + if (self.listenerCount('brush')) { + const rect = svg.insert('g', 'g') + .attr('class', 'brush') + .call(brush) + .call(function (brushG) { + // hijack the brush start event to filter out right/middle clicks + const brushHandler = brushG.on('mousedown.brush'); + if (!brushHandler) return; // touch events in use + brushG.on('mousedown.brush', function () { + if (validBrushClick(d3.event)) brushHandler.apply(this, arguments); + }); + }) + .selectAll('rect'); + + if (isHorizontal) { + rect.attr('height', height); + } else { + rect.attr('width', width); + } + + return brush; + } + }; + } + + /** + * Determine if d3.Scale is quantitative + * + * @param element {d3.Scale} + * @method isQuantitativeScale + * @returns {boolean} + */ + function isQuantitativeScale(scale) { + //Invert is a method that only exists on quantitative scales + if (scale.invert) { + return true; + } else { + return false; + } + } + + function validBrushClick(event) { + return event.button === 0; + } + + + function justifyOpacity(opacity) { + const decimalNumber = parseFloat(opacity, 10); + const fallbackOpacity = 0.5; + return (0 <= decimalNumber && decimalNumber <= 1) ? decimalNumber : fallbackOpacity; + } + + return Dispatch; +}; diff --git a/src/ui/public/vis_maps/lib/layout.js b/src/ui/public/vis_maps/lib/layout.js new file mode 100644 index 0000000000000..a33d182b624f2 --- /dev/null +++ b/src/ui/public/vis_maps/lib/layout.js @@ -0,0 +1,50 @@ +import d3 from 'd3'; +import MapSplitProvider from './splits/map_split'; + +export default function LayoutFactory(Private) { + const mapSplit = Private(MapSplitProvider); + class Layout { + constructor(el, config, data) { + this.el = el; + this.config = config; + this.data = data; + } + + render() { + this.removeAll(); + this.createLayout(); + }; + + createLayout() { + const wrapper = this.appendElem(this.el, 'div', 'vis-wrapper'); + wrapper.datum(this.data.data); + const colWrapper = this.appendElem(wrapper.node(), 'div', 'vis-col-wrapper'); + const chartWrapper = this.appendElem(colWrapper.node(), 'div', 'chart-wrapper'); + chartWrapper.call(mapSplit, colWrapper.node(), this.config); + }; + + appendElem(el, type, className) { + if (!el || !type || !className) { + throw new Error('Function requires that an el, type, and class be provided'); + } + + if (typeof el === 'string') { + // Create a DOM reference with a d3 selection + // Need to make sure that the `el` is bound to this object + // to prevent it from being appended to another Layout + el = d3.select(this.el) + .select(el)[0][0]; + } + + return d3.select(el) + .append(type) + .attr('class', className); + }; + + removeAll() { + return d3.select(this.el).selectAll('*').remove(); + }; + } + + return Layout; +}; diff --git a/src/ui/public/vis_maps/lib/maps_config.js b/src/ui/public/vis_maps/lib/maps_config.js new file mode 100644 index 0000000000000..57c67a0c04808 --- /dev/null +++ b/src/ui/public/vis_maps/lib/maps_config.js @@ -0,0 +1,38 @@ +/** + * Provides vislib configuration, throws error if invalid property is accessed without providing defaults + */ +import _ from 'lodash'; + +export default function MapsConfigFactory(Private) { + + const DEFAULT_VIS_CONFIG = { + style: { + margin : { top: 10, right: 3, bottom: 5, left: 3 } + }, + alerts: {}, + categoryAxes: [], + valueAxes: [] + }; + + + class MapsConfig { + constructor(mapsConfigArgs) { + this._values = _.defaultsDeep({}, mapsConfigArgs, DEFAULT_VIS_CONFIG); + }; + + get(property, defaults) { + if (_.has(this._values, property) || typeof defaults !== 'undefined') { + return _.get(this._values, property, defaults); + } else { + throw new Error(`Accessing invalid config property: ${property}`); + return defaults; + } + }; + + set(property, value) { + return _.set(this._values, property, value); + }; + } + + return MapsConfig; +} diff --git a/src/ui/public/vislib/lib/layout/splits/tile_map/map_split.js b/src/ui/public/vis_maps/lib/splits/map_split.js similarity index 100% rename from src/ui/public/vislib/lib/layout/splits/tile_map/map_split.js rename to src/ui/public/vis_maps/lib/splits/map_split.js diff --git a/src/ui/public/vis_maps/maps.js b/src/ui/public/vis_maps/maps.js new file mode 100644 index 0000000000000..f3a8c12841b19 --- /dev/null +++ b/src/ui/public/vis_maps/maps.js @@ -0,0 +1,106 @@ +import _ from 'lodash'; +import d3 from 'd3'; +import MapsConfigProvider from './lib/maps_config'; +import TileMapChartProvider from './visualizations/tile_map'; +import EventsProvider from 'ui/events'; +import MapsDataProvider from './lib/data'; +import LayoutProvider from './lib/layout'; +import './styles/_tilemap.less'; + +export default function MapsFactory(Private) { + const Events = Private(EventsProvider); + const MapsConfig = Private(MapsConfigProvider); + const TileMapChart = Private(TileMapChartProvider); + const Data = Private(MapsDataProvider); + const Layout = Private(LayoutProvider); + + class Maps extends Events { + constructor($el, vis, mapsConfigArgs) { + super(arguments); + this.el = $el.get ? $el.get(0) : $el; + this.vis = vis; + this.mapsConfigArgs = mapsConfigArgs; + + // memoize so that the same function is returned every time, + // allowing us to remove/re-add the same function + this.getProxyHandler = _.memoize(function (event) { + const self = this; + return function (e) { + self.emit(event, e); + }; + }); + + this.enable = this.chartEventProxyToggle('on'); + this.disable = this.chartEventProxyToggle('off'); + } + + chartEventProxyToggle(method) { + return function (event, chart) { + const proxyHandler = this.getProxyHandler(event); + + _.each(chart ? [chart] : this.charts, function (chart) { + chart.events[method](event, proxyHandler); + }); + }; + } + + on(event, listener) { + const first = this.listenerCount(event) === 0; + const ret = Events.prototype.on.call(this, event, listener); + const added = this.listenerCount(event) > 0; + + // if this is the first listener added for the event + // enable the event in the handler + if (first && added && this.handler) this.handler.enable(event); + + return ret; + }; + + off(event, listener) { + const last = this.listenerCount(event) === 1; + const ret = Events.prototype.off.call(this, event, listener); + const removed = this.listenerCount(event) === 0; + + // Once all listeners are removed, disable the events in the handler + if (last && removed && this.handler) this.handler.disable(event); + return ret; + }; + + render(data, uiState) { + if (!data) { + throw new Error('No valid data!'); + } + + this.uiState = uiState; + this.data = new Data(data, this.uiState); + this.visConfig = new MapsConfig(this.mapsConfigArgs, this.data, this.uiState); + this.layout = new Layout(this.el, this.visConfig, this.data); + this.draw(); + }; + + destroy() { + this.charts.forEach(chart => chart.destroy()); + d3.select(this.el).selectAll('*').remove(); + }; + + draw() { + this.layout.render(); + // todo: title + const self = this; + this.charts = []; + d3.select(this.el).selectAll('.chart').each(function (chartData) { + const chart = new TileMapChart(self, this, chartData); + + self.activeEvents().forEach(function (event) { + self.enable(event, chart); + }); + + self.charts.push(chart); + chart.render(); + }); + } + + } + + return Maps; +}; diff --git a/src/ui/public/vis_maps/maps_renderbot.js b/src/ui/public/vis_maps/maps_renderbot.js new file mode 100644 index 0000000000000..94aae9f230b6d --- /dev/null +++ b/src/ui/public/vis_maps/maps_renderbot.js @@ -0,0 +1,77 @@ +import _ from 'lodash'; +import MapsProvider from 'ui/vis_maps/maps'; +import VisRenderbotProvider from 'ui/vis/renderbot'; +import MapsVisTypeBuildChartDataProvider from 'ui/vislib_vis_type/build_chart_data'; +module.exports = function MapsRenderbotFactory(Private, $injector) { + const AngularPromise = $injector.get('Promise'); + let Maps = Private(MapsProvider); + let Renderbot = Private(VisRenderbotProvider); + let buildChartData = Private(MapsVisTypeBuildChartDataProvider); + + _.class(MapsRenderbot).inherits(Renderbot); + function MapsRenderbot(vis, $el, uiState) { + MapsRenderbot.Super.call(this, vis, $el, uiState); + this._createVis(); + } + + MapsRenderbot.prototype._createVis = function () { + if (this.mapsVis) this.destroy(); + this.mapsParams = this._getMapsParams(); + this.mapsVis = new Maps(this.$el[0], this.vis, this.mapsParams); + + _.each(this.vis.listeners, (listener, event) => { + this.mapsVis.on(event, listener); + }); + + if (this.mapsData) { + this.mapsVis.render(this.mapsData, this.uiState); + } + }; + + MapsRenderbot.prototype._getMapsParams = function () { + let self = this; + + return _.assign( + {}, + self.vis.type.params.defaults, + { + type: self.vis.type.name, + // Add attribute which determines whether an index is time based or not. + hasTimeField: self.vis.indexPattern && self.vis.indexPattern.hasTimeField() + }, + self.vis.params + ); + }; + + MapsRenderbot.prototype.buildChartData = buildChartData; + MapsRenderbot.prototype.render = function (esResponse) { + this.mapsData = this.buildChartData(esResponse); + return AngularPromise.delay(1).then(() => { + this.mapsVis.render(this.mapsData, this.uiState); + }); + }; + + MapsRenderbot.prototype.destroy = function () { + let self = this; + + let mapsVis = self.mapsVis; + + _.forOwn(self.vis.listeners, function (listener, event) { + mapsVis.off(event, listener); + }); + + mapsVis.destroy(); + }; + + MapsRenderbot.prototype.updateParams = function () { + let self = this; + + // get full maps params object + let newParams = self._getMapsParams(); + + // if there's been a change, replace the vis + if (!_.isEqual(newParams, self.mapsParams)) self._createVis(); + }; + + return MapsRenderbot; +}; diff --git a/src/ui/public/vis_maps/maps_vis_type.js b/src/ui/public/vis_maps/maps_vis_type.js new file mode 100644 index 0000000000000..1f730bdcf45a7 --- /dev/null +++ b/src/ui/public/vis_maps/maps_vis_type.js @@ -0,0 +1,22 @@ +import _ from 'lodash'; +import 'ui/vislib'; +import 'plugins/kbn_vislib_vis_types/controls/vislib_basic_options'; +import VisVisTypeProvider from 'ui/vis/vis_type'; +import MapsVisTypeMapsRenderbotProvider from 'ui/vis_maps/maps_renderbot'; +export default function MapsVisTypeFactory(Private) { + let VisType = Private(VisVisTypeProvider); + let MapsRenderbot = Private(MapsVisTypeMapsRenderbotProvider); + + + _.class(MapsVisType).inherits(VisType); + function MapsVisType(opts = {}) { + MapsVisType.Super.call(this, opts); + this.listeners = opts.listeners || {}; + } + + MapsVisType.prototype.createRenderbot = function (vis, $el, uiState) { + return new MapsRenderbot(vis, $el, uiState); + }; + + return MapsVisType; +}; diff --git a/src/ui/public/vislib/styles/_tilemap.less b/src/ui/public/vis_maps/styles/_tilemap.less similarity index 100% rename from src/ui/public/vislib/styles/_tilemap.less rename to src/ui/public/vis_maps/styles/_tilemap.less diff --git a/src/ui/public/vis_maps/visualizations/_chart.js b/src/ui/public/vis_maps/visualizations/_chart.js new file mode 100644 index 0000000000000..23f890dd50880 --- /dev/null +++ b/src/ui/public/vis_maps/visualizations/_chart.js @@ -0,0 +1,60 @@ +import d3 from 'd3'; +import _ from 'lodash'; +import VislibLibDispatchProvider from '../lib/dispatch'; +import TooltipProvider from 'ui/vis/components/tooltip'; +export default function ChartBaseClass(Private) { + + const Dispatch = Private(VislibLibDispatchProvider); + const Tooltip = Private(TooltipProvider); + /** + * The Base Class for all visualizations. + * + * @class Chart + * @constructor + * @param handler {Object} Reference to the Handler Class Constructor + * @param el {HTMLElement} HTML element to which the chart will be appended + * @param chartData {Object} Elasticsearch query results for this specific chart + */ + class Chart { + constructor(handler, el, chartData) { + this.handler = handler; + this.chartEl = el; + this.chartData = chartData; + this.tooltips = []; + + const events = this.events = new Dispatch(handler); + + if (this.handler.visConfig && this.handler.visConfig.get('addTooltip', false)) { + const $el = this.handler.el; + const formatter = this.handler.data.get('tooltipFormatter'); + + // Add tooltip + this.tooltip = new Tooltip('chart', $el, formatter, events); + this.tooltips.push(this.tooltip); + } + } + + render() { + const selection = d3.select(this.chartEl); + selection.selectAll('*').remove(); + selection.call(this.draw()); + }; + + + /** + * Removes all DOM elements from the root element + * + * @method destroy + */ + destroy() { + const selection = d3.select(this.chartEl); + this.events.removeAllListeners(); + this.tooltips.forEach(function (tooltip) { + tooltip.destroy(); + }); + selection.remove(); + }; + } + + return Chart; +}; diff --git a/src/ui/public/vislib/visualizations/_map.js b/src/ui/public/vis_maps/visualizations/_map.js similarity index 97% rename from src/ui/public/vislib/visualizations/_map.js rename to src/ui/public/vis_maps/visualizations/_map.js index a0b5c66fab71f..9fa887560e711 100644 --- a/src/ui/public/vislib/visualizations/_map.js +++ b/src/ui/public/vis_maps/visualizations/_map.js @@ -7,10 +7,10 @@ marked.setOptions({ sanitize: true // Sanitize HTML tags }); -import VislibVisualizationsMarkerTypesScaledCirclesProvider from 'ui/vislib/visualizations/marker_types/scaled_circles'; -import VislibVisualizationsMarkerTypesShadedCirclesProvider from 'ui/vislib/visualizations/marker_types/shaded_circles'; -import VislibVisualizationsMarkerTypesGeohashGridProvider from 'ui/vislib/visualizations/marker_types/geohash_grid'; -import VislibVisualizationsMarkerTypesHeatmapProvider from 'ui/vislib/visualizations/marker_types/heatmap'; +import VislibVisualizationsMarkerTypesScaledCirclesProvider from './marker_types/scaled_circles'; +import VislibVisualizationsMarkerTypesShadedCirclesProvider from './marker_types/shaded_circles'; +import VislibVisualizationsMarkerTypesGeohashGridProvider from './marker_types/geohash_grid'; +import VislibVisualizationsMarkerTypesHeatmapProvider from './marker_types/heatmap'; export default function MapFactory(Private, tilemap, $sanitize) { const defaultMapZoom = 2; diff --git a/src/ui/public/vislib/visualizations/marker_types/base_marker.js b/src/ui/public/vis_maps/visualizations/marker_types/base_marker.js similarity index 100% rename from src/ui/public/vislib/visualizations/marker_types/base_marker.js rename to src/ui/public/vis_maps/visualizations/marker_types/base_marker.js diff --git a/src/ui/public/vislib/visualizations/marker_types/geohash_grid.js b/src/ui/public/vis_maps/visualizations/marker_types/geohash_grid.js similarity index 100% rename from src/ui/public/vislib/visualizations/marker_types/geohash_grid.js rename to src/ui/public/vis_maps/visualizations/marker_types/geohash_grid.js diff --git a/src/ui/public/vislib/visualizations/marker_types/heatmap.js b/src/ui/public/vis_maps/visualizations/marker_types/heatmap.js similarity index 100% rename from src/ui/public/vislib/visualizations/marker_types/heatmap.js rename to src/ui/public/vis_maps/visualizations/marker_types/heatmap.js diff --git a/src/ui/public/vislib/visualizations/marker_types/scaled_circles.js b/src/ui/public/vis_maps/visualizations/marker_types/scaled_circles.js similarity index 100% rename from src/ui/public/vislib/visualizations/marker_types/scaled_circles.js rename to src/ui/public/vis_maps/visualizations/marker_types/scaled_circles.js diff --git a/src/ui/public/vislib/visualizations/marker_types/shaded_circles.js b/src/ui/public/vis_maps/visualizations/marker_types/shaded_circles.js similarity index 100% rename from src/ui/public/vislib/visualizations/marker_types/shaded_circles.js rename to src/ui/public/vis_maps/visualizations/marker_types/shaded_circles.js diff --git a/src/ui/public/vislib/visualizations/tile_map.js b/src/ui/public/vis_maps/visualizations/tile_map.js similarity index 93% rename from src/ui/public/vislib/visualizations/tile_map.js rename to src/ui/public/vis_maps/visualizations/tile_map.js index 467d3d9f0f664..53484f851de1d 100644 --- a/src/ui/public/vislib/visualizations/tile_map.js +++ b/src/ui/public/vis_maps/visualizations/tile_map.js @@ -39,9 +39,6 @@ export default function TileMapFactory(Private) { draw() { const self = this; - // clean up old maps - self.destroy(); - return function (selection) { selection.each(function () { self._appendMap(this); @@ -95,10 +92,10 @@ export default function TileMapFactory(Private) { */ _appendMap(selection) { const container = $(selection).addClass('tilemap'); - const uiStateParams = this.handler.vis ? { - mapCenter: this.handler.vis.uiState.get('mapCenter'), - mapZoom: this.handler.vis.uiState.get('mapZoom') - } : {}; + const uiStateParams = { + mapCenter: this.handler.uiState.get('mapCenter'), + mapZoom: this.handler.uiState.get('mapZoom') + }; const params = _.assign({}, _.get(this._chartData, 'geoAgg.vis.params'), uiStateParams); diff --git a/src/ui/public/vislib/lib/layout/layout_types.js b/src/ui/public/vislib/lib/layout/layout_types.js index 2be3b007b9edd..c9680ee0985f0 100644 --- a/src/ui/public/vislib/lib/layout/layout_types.js +++ b/src/ui/public/vislib/lib/layout/layout_types.js @@ -1,6 +1,5 @@ import VislibLibLayoutTypesColumnLayoutProvider from './types/column_layout'; import VislibLibLayoutTypesPieLayoutProvider from './types/pie_layout'; -import VislibLibLayoutTypesMapLayoutProvider from './types/map_layout'; export default function LayoutTypeFactory(Private) { @@ -14,7 +13,6 @@ export default function LayoutTypeFactory(Private) { */ return { pie: Private(VislibLibLayoutTypesPieLayoutProvider), - tile_map: Private(VislibLibLayoutTypesMapLayoutProvider), point_series: Private(VislibLibLayoutTypesColumnLayoutProvider) }; } diff --git a/src/ui/public/vislib/lib/layout/types/map_layout.js b/src/ui/public/vislib/lib/layout/types/map_layout.js index 06aeada0ae514..e69de29bb2d1d 100644 --- a/src/ui/public/vislib/lib/layout/types/map_layout.js +++ b/src/ui/public/vislib/lib/layout/types/map_layout.js @@ -1,49 +0,0 @@ -import VislibLibLayoutSplitsTileMapMapSplitProvider from '../splits/tile_map/map_split'; -export default function ColumnLayoutFactory(Private) { - const mapSplit = Private(VislibLibLayoutSplitsTileMapMapSplitProvider); - - /* - * Specifies the visualization layout for tile maps. - * - * This is done using an array of objects. The first object has - * a `parent` DOM element, a DOM `type` (e.g. div, svg, etc), - * and a `class` (required). Each child can omit the parent object, - * but must include a type and class. - * - * Optionally, you can specify `datum` to be bound to the DOM - * element, a `splits` function that divides the selected element - * into more DOM elements based on a callback function provided, or - * a children array which nests other layout objects. - * - * Objects in children arrays are children of the current object and return - * DOM elements which are children of their respective parent element. - */ - - return function (el, data) { - if (!el || !data) { - throw new Error('Both an el and data need to be specified'); - } - - return [ - { - parent: el, - type: 'div', - class: 'vis-wrapper', - datum: data, - children: [ - { - type: 'div', - class: 'vis-col-wrapper', - children: [ - { - type: 'div', - class: 'chart-wrapper', - splits: mapSplit - } - ] - } - ] - } - ]; - }; -} diff --git a/src/ui/public/vislib/lib/types/index.js b/src/ui/public/vislib/lib/types/index.js index 140db3425a0fe..eddc7947992f3 100644 --- a/src/ui/public/vislib/lib/types/index.js +++ b/src/ui/public/vislib/lib/types/index.js @@ -1,6 +1,5 @@ import VislibLibTypesPointSeriesProvider from './point_series'; import VislibLibTypesPieProvider from './pie'; -import VislibLibTypesTileMapProvider from './tile_map'; export default function TypeFactory(Private) { const pointSeries = Private(VislibLibTypesPointSeriesProvider); @@ -15,7 +14,6 @@ export default function TypeFactory(Private) { line: pointSeries.line, pie: Private(VislibLibTypesPieProvider), area: pointSeries.area, - tile_map: Private(VislibLibTypesTileMapProvider), point_series: pointSeries.line }; } diff --git a/src/ui/public/vislib/lib/types/tile_map.js b/src/ui/public/vislib/lib/types/tile_map.js deleted file mode 100644 index d69f119375096..0000000000000 --- a/src/ui/public/vislib/lib/types/tile_map.js +++ /dev/null @@ -1,19 +0,0 @@ -import _ from 'lodash'; -export default function MapHandlerProvider(Private) { - return function (config) { - if (!config.chart) { - config.chart = _.defaults({}, config, { - type: 'tile_map' - }); - } - - config.resize = function () { - this.charts.forEach(function (chart) { - chart.resizeArea(); - }); - }; - - return config; - }; -} - diff --git a/src/ui/public/vislib/styles/main.less b/src/ui/public/vislib/styles/main.less index f44fe6823d33c..3c1c25ab908fe 100644 --- a/src/ui/public/vislib/styles/main.less +++ b/src/ui/public/vislib/styles/main.less @@ -5,5 +5,4 @@ @import "./_legend"; @import "./_svg"; @import "./_tooltip"; -@import "./_tilemap"; @import "./_alerts"; diff --git a/src/ui/public/vislib/vislib.js b/src/ui/public/vislib/vislib.js index 0c0a91164f1c4..147ec3563d7f3 100644 --- a/src/ui/public/vislib/vislib.js +++ b/src/ui/public/vislib/vislib.js @@ -1,10 +1,8 @@ import './lib/types/pie'; import './lib/types/point_series'; -import './lib/types/tile_map'; import './lib/types'; import './lib/layout/layout_types'; import './lib/data'; -import './visualizations/_map.js'; import './visualizations/vis_types'; import './styles/main.less'; import VislibVisProvider from './vis'; diff --git a/src/ui/public/vislib/visualizations/vis_types.js b/src/ui/public/vislib/visualizations/vis_types.js index c27fe6ad6d9e2..268ba8c849b6d 100644 --- a/src/ui/public/vislib/visualizations/vis_types.js +++ b/src/ui/public/vislib/visualizations/vis_types.js @@ -1,6 +1,5 @@ import VislibVisualizationsPointSeriesProvider from './point_series'; import VislibVisualizationsPieChartProvider from './pie_chart'; -import VislibVisualizationsTileMapProvider from './tile_map'; export default function VisTypeFactory(Private) { @@ -14,7 +13,6 @@ export default function VisTypeFactory(Private) { */ return { pie: Private(VislibVisualizationsPieChartProvider), - tile_map: Private(VislibVisualizationsTileMapProvider), point_series: Private(VislibVisualizationsPointSeriesProvider) }; } From c665d4c0d383edfd1c359eb9d804fff3f27b848f Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 14 Dec 2016 10:51:18 +0100 Subject: [PATCH 3/3] rebasing on master and fixing linting --- src/ui/public/vis_maps/lib/data.js | 23 ++++++++-------- src/ui/public/vis_maps/lib/dispatch.js | 26 +++++++++---------- src/ui/public/vis_maps/lib/layout.js | 10 +++---- src/ui/public/vis_maps/lib/maps_config.js | 6 ++--- src/ui/public/vis_maps/maps.js | 10 +++---- src/ui/public/vis_maps/maps_renderbot.js | 16 ++++++------ src/ui/public/vis_maps/maps_vis_type.js | 6 ++--- .../public/vis_maps/visualizations/_chart.js | 6 ++--- 8 files changed, 51 insertions(+), 52 deletions(-) diff --git a/src/ui/public/vis_maps/lib/data.js b/src/ui/public/vis_maps/lib/data.js index 2c84b801355a4..93dc77f90a2db 100644 --- a/src/ui/public/vis_maps/lib/data.js +++ b/src/ui/public/vis_maps/lib/data.js @@ -71,7 +71,7 @@ export default function DataFactory(Private) { return _.toArray(arr); } return [this.data]; - }; + } /** * Returns an array of chart data objects @@ -91,7 +91,7 @@ export default function DataFactory(Private) { } return visData; - }; + } /** * get min and max for all cols, rows of data @@ -107,8 +107,8 @@ export default function DataFactory(Private) { min: Math.min(props.min, minMax.min), max: Math.max(props.max, minMax.max) }; - }, {min: Infinity, max: -Infinity}); - }; + }, { min: Infinity, max: -Infinity }); + } /** * Get attributes off the data, e.g. `tooltipFormatter` or `xAxisFormatter` @@ -123,7 +123,7 @@ export default function DataFactory(Private) { get(thing, def) { const source = (this.data.rows || this.data.columns || [this.data])[0]; return _.get(source, thing, def); - }; + } /** * Return an array of all value objects @@ -140,7 +140,7 @@ export default function DataFactory(Private) { .pluck('values') .flattenDeep() .value(); - }; + } /** * ensure that the datas ordered property has a min and max @@ -164,7 +164,7 @@ export default function DataFactory(Private) { if (missingMax) d.ordered.max = extent[1]; } }); - }; + } /** * Calculates min and max values for all map data @@ -177,12 +177,11 @@ export default function DataFactory(Private) { * @returns {Array} min and max values */ mapDataExtents(series) { - let values; - values = _.map(series.rows, function (row) { + const values = _.map(series.rows, function (row) { return row[row.length - 1]; }); return [_.min(values), _.max(values)]; - }; + } /** * Get the maximum number of series, considering each chart @@ -194,8 +193,8 @@ export default function DataFactory(Private) { return this.chartData().reduce(function (max, chart) { return Math.max(max, chart.series.length); }, 0); - }; + } } return Data; -}; +} diff --git a/src/ui/public/vis_maps/lib/dispatch.js b/src/ui/public/vis_maps/lib/dispatch.js index 114b7e2a6a2af..99217313348b2 100644 --- a/src/ui/public/vis_maps/lib/dispatch.js +++ b/src/ui/public/vis_maps/lib/dispatch.js @@ -59,7 +59,7 @@ export default function DispatchClass(Private, config) { if (isSeries) { // Find object with the actual d value and add it to the point object - const object = _.find(series, {'label': label}); + const object = _.find(series, { 'label': label }); if (object) { eventData.value = +object.values[i].y; @@ -71,7 +71,7 @@ export default function DispatchClass(Private, config) { } return eventData; - }; + } /** * Returns a function that adds events and listeners to a D3 selection @@ -91,7 +91,7 @@ export default function DispatchClass(Private, config) { } }); }; - }; + } /** * @@ -118,7 +118,7 @@ export default function DispatchClass(Private, config) { } return addEvent('mouseover', hover); - }; + } /** * @@ -138,7 +138,7 @@ export default function DispatchClass(Private, config) { } return addEvent('mouseout', mouseout); - }; + } /** * @@ -154,7 +154,7 @@ export default function DispatchClass(Private, config) { } return addEvent('click', click); - }; + } /** * Determine if we will allow brushing @@ -167,7 +167,7 @@ export default function DispatchClass(Private, config) { //Allow brushing for ordered axis - date histogram and histogram return Boolean(xAxis.ordered); - }; + } /** * Determine if brushing is currently enabled @@ -177,7 +177,7 @@ export default function DispatchClass(Private, config) { */ isBrushable() { return this.allowBrushing() && this.listenerCount('brush') > 0; - }; + } /** * Mouseover Behavior @@ -187,7 +187,7 @@ export default function DispatchClass(Private, config) { */ addMousePointer() { return d3.select(this).style('cursor', 'pointer'); - }; + } /** * Highlight the element that is under the cursor @@ -214,7 +214,7 @@ export default function DispatchClass(Private, config) { */ unHighlight(element) { $('[data-label]', element.parentNode).css('opacity', 1); - }; + } /** * Adds D3 brush to SVG and returns the brush function @@ -226,7 +226,7 @@ export default function DispatchClass(Private, config) { createBrush(xScale, svg) { const self = this; const visConfig = self.handler.visConfig; - const {width, height} = svg.node().getBBox(); + const { width, height } = svg.node().getBBox(); const isHorizontal = self.handler.categoryAxes[0].axisConfig.isHorizontal(); // Brush scale @@ -281,7 +281,7 @@ export default function DispatchClass(Private, config) { return brush; } - }; + } } /** @@ -312,4 +312,4 @@ export default function DispatchClass(Private, config) { } return Dispatch; -}; +} diff --git a/src/ui/public/vis_maps/lib/layout.js b/src/ui/public/vis_maps/lib/layout.js index a33d182b624f2..24402f960c136 100644 --- a/src/ui/public/vis_maps/lib/layout.js +++ b/src/ui/public/vis_maps/lib/layout.js @@ -13,7 +13,7 @@ export default function LayoutFactory(Private) { render() { this.removeAll(); this.createLayout(); - }; + } createLayout() { const wrapper = this.appendElem(this.el, 'div', 'vis-wrapper'); @@ -21,7 +21,7 @@ export default function LayoutFactory(Private) { const colWrapper = this.appendElem(wrapper.node(), 'div', 'vis-col-wrapper'); const chartWrapper = this.appendElem(colWrapper.node(), 'div', 'chart-wrapper'); chartWrapper.call(mapSplit, colWrapper.node(), this.config); - }; + } appendElem(el, type, className) { if (!el || !type || !className) { @@ -39,12 +39,12 @@ export default function LayoutFactory(Private) { return d3.select(el) .append(type) .attr('class', className); - }; + } removeAll() { return d3.select(this.el).selectAll('*').remove(); - }; + } } return Layout; -}; +} diff --git a/src/ui/public/vis_maps/lib/maps_config.js b/src/ui/public/vis_maps/lib/maps_config.js index 57c67a0c04808..2032f25c28e6e 100644 --- a/src/ui/public/vis_maps/lib/maps_config.js +++ b/src/ui/public/vis_maps/lib/maps_config.js @@ -18,7 +18,7 @@ export default function MapsConfigFactory(Private) { class MapsConfig { constructor(mapsConfigArgs) { this._values = _.defaultsDeep({}, mapsConfigArgs, DEFAULT_VIS_CONFIG); - }; + } get(property, defaults) { if (_.has(this._values, property) || typeof defaults !== 'undefined') { @@ -27,11 +27,11 @@ export default function MapsConfigFactory(Private) { throw new Error(`Accessing invalid config property: ${property}`); return defaults; } - }; + } set(property, value) { return _.set(this._values, property, value); - }; + } } return MapsConfig; diff --git a/src/ui/public/vis_maps/maps.js b/src/ui/public/vis_maps/maps.js index f3a8c12841b19..a508eecc6855c 100644 --- a/src/ui/public/vis_maps/maps.js +++ b/src/ui/public/vis_maps/maps.js @@ -54,7 +54,7 @@ export default function MapsFactory(Private) { if (first && added && this.handler) this.handler.enable(event); return ret; - }; + } off(event, listener) { const last = this.listenerCount(event) === 1; @@ -64,7 +64,7 @@ export default function MapsFactory(Private) { // Once all listeners are removed, disable the events in the handler if (last && removed && this.handler) this.handler.disable(event); return ret; - }; + } render(data, uiState) { if (!data) { @@ -76,12 +76,12 @@ export default function MapsFactory(Private) { this.visConfig = new MapsConfig(this.mapsConfigArgs, this.data, this.uiState); this.layout = new Layout(this.el, this.visConfig, this.data); this.draw(); - }; + } destroy() { this.charts.forEach(chart => chart.destroy()); d3.select(this.el).selectAll('*').remove(); - }; + } draw() { this.layout.render(); @@ -103,4 +103,4 @@ export default function MapsFactory(Private) { } return Maps; -}; +} diff --git a/src/ui/public/vis_maps/maps_renderbot.js b/src/ui/public/vis_maps/maps_renderbot.js index 94aae9f230b6d..119b2389c5c5a 100644 --- a/src/ui/public/vis_maps/maps_renderbot.js +++ b/src/ui/public/vis_maps/maps_renderbot.js @@ -4,9 +4,9 @@ import VisRenderbotProvider from 'ui/vis/renderbot'; import MapsVisTypeBuildChartDataProvider from 'ui/vislib_vis_type/build_chart_data'; module.exports = function MapsRenderbotFactory(Private, $injector) { const AngularPromise = $injector.get('Promise'); - let Maps = Private(MapsProvider); - let Renderbot = Private(VisRenderbotProvider); - let buildChartData = Private(MapsVisTypeBuildChartDataProvider); + const Maps = Private(MapsProvider); + const Renderbot = Private(VisRenderbotProvider); + const buildChartData = Private(MapsVisTypeBuildChartDataProvider); _.class(MapsRenderbot).inherits(Renderbot); function MapsRenderbot(vis, $el, uiState) { @@ -29,7 +29,7 @@ module.exports = function MapsRenderbotFactory(Private, $injector) { }; MapsRenderbot.prototype._getMapsParams = function () { - let self = this; + const self = this; return _.assign( {}, @@ -52,9 +52,9 @@ module.exports = function MapsRenderbotFactory(Private, $injector) { }; MapsRenderbot.prototype.destroy = function () { - let self = this; + const self = this; - let mapsVis = self.mapsVis; + const mapsVis = self.mapsVis; _.forOwn(self.vis.listeners, function (listener, event) { mapsVis.off(event, listener); @@ -64,10 +64,10 @@ module.exports = function MapsRenderbotFactory(Private, $injector) { }; MapsRenderbot.prototype.updateParams = function () { - let self = this; + const self = this; // get full maps params object - let newParams = self._getMapsParams(); + const newParams = self._getMapsParams(); // if there's been a change, replace the vis if (!_.isEqual(newParams, self.mapsParams)) self._createVis(); diff --git a/src/ui/public/vis_maps/maps_vis_type.js b/src/ui/public/vis_maps/maps_vis_type.js index 1f730bdcf45a7..999397dc2d92e 100644 --- a/src/ui/public/vis_maps/maps_vis_type.js +++ b/src/ui/public/vis_maps/maps_vis_type.js @@ -4,8 +4,8 @@ import 'plugins/kbn_vislib_vis_types/controls/vislib_basic_options'; import VisVisTypeProvider from 'ui/vis/vis_type'; import MapsVisTypeMapsRenderbotProvider from 'ui/vis_maps/maps_renderbot'; export default function MapsVisTypeFactory(Private) { - let VisType = Private(VisVisTypeProvider); - let MapsRenderbot = Private(MapsVisTypeMapsRenderbotProvider); + const VisType = Private(VisVisTypeProvider); + const MapsRenderbot = Private(MapsVisTypeMapsRenderbotProvider); _.class(MapsVisType).inherits(VisType); @@ -19,4 +19,4 @@ export default function MapsVisTypeFactory(Private) { }; return MapsVisType; -}; +} diff --git a/src/ui/public/vis_maps/visualizations/_chart.js b/src/ui/public/vis_maps/visualizations/_chart.js index 23f890dd50880..a18682e36e81e 100644 --- a/src/ui/public/vis_maps/visualizations/_chart.js +++ b/src/ui/public/vis_maps/visualizations/_chart.js @@ -38,7 +38,7 @@ export default function ChartBaseClass(Private) { const selection = d3.select(this.chartEl); selection.selectAll('*').remove(); selection.call(this.draw()); - }; + } /** @@ -53,8 +53,8 @@ export default function ChartBaseClass(Private) { tooltip.destroy(); }); selection.remove(); - }; + } } return Chart; -}; +}