diff --git a/src/legacy/core_plugins/kibana/public/discover/_index.scss b/src/legacy/core_plugins/kibana/public/discover/_index.scss index 0fcb79474ae7fdb..435d600e67a5152 100644 --- a/src/legacy/core_plugins/kibana/public/discover/_index.scss +++ b/src/legacy/core_plugins/kibana/public/discover/_index.scss @@ -9,6 +9,7 @@ @import 'components/fetch_error/index'; @import 'components/field_chooser/index'; +@import 'components/histogram/index'; @import 'directives/index'; @import 'doc_table/index'; diff --git a/src/legacy/core_plugins/kibana/public/discover/components/histogram/_index.scss b/src/legacy/core_plugins/kibana/public/discover/components/histogram/_index.scss new file mode 100644 index 000000000000000..f055d69e593e161 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/discover/components/histogram/_index.scss @@ -0,0 +1,3 @@ +.dscHistogram__header--partial { + font-weight: $euiFontWeightRegular; +} \ No newline at end of file diff --git a/src/legacy/core_plugins/kibana/public/discover/components/histogram/directive.js b/src/legacy/core_plugins/kibana/public/discover/components/histogram/directive.js new file mode 100644 index 000000000000000..29b7c1d98a78dad --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/discover/components/histogram/directive.js @@ -0,0 +1,28 @@ +/* + * 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. + */ + +import 'ngreact'; +import { uiModules } from 'ui/modules'; +import { DiscoverHistogram } from './histogram'; + +import { wrapInI18nContext } from 'ui/i18n'; + +const app = uiModules.get('apps/discover', ['react']); + +app.directive('discoverHistogram', reactDirective => reactDirective(wrapInI18nContext(DiscoverHistogram))); diff --git a/src/legacy/core_plugins/kibana/public/discover/components/histogram/histogram.tsx b/src/legacy/core_plugins/kibana/public/discover/components/histogram/histogram.tsx new file mode 100644 index 000000000000000..78665aa005a32b0 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/discover/components/histogram/histogram.tsx @@ -0,0 +1,181 @@ +/* + * 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. + */ + +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiSpacer } from '@elastic/eui'; +import moment from 'moment'; +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +import { + AnnotationDomainTypes, + Axis, + Chart, + HistogramBarSeries, + getAnnotationId, + getAxisId, + getSpecId, + LineAnnotation, + Position, + ScaleType, + Settings, + RectAnnotation, + TooltipValue, +} from '@elastic/charts'; + +export interface DiscoverHistogramProps { + chartData: any; // TODO: make this unknown? +} + +export class DiscoverHistogram extends Component { + static propTypes = { + chartData: PropTypes.object, + }; + + render() { + const { chartData } = this.props; + + if (!chartData || !chartData.series[0]) { + return null; + } + + const data = chartData.series[0].values; + const format = chartData.xAxisFormat.params.pattern; + const xInterval = chartData.ordered.interval; + const xValues = chartData.xAxisOrderedValues; + const lastXValue = xValues[xValues.length - 1]; + + const formatter = (val: string) => { + return moment(val).format(format); + }; + + const currentTime = { + dataValue: moment(), + details: '', + }; + + const lineAnnotationStyle = { + line: { + strokeWidth: 2, + stroke: '#c80000', + opacity: 0.3, + }, + }; + + const domain = chartData.ordered; + const domainStart = domain.min.valueOf(); + const domainEnd = domain.max.valueOf(); + + const rectAnnotations = [ + { + coordinates: { + x0: domainStart, + }, + details: 'This area may contain partial data', + }, + { + coordinates: { + x1: domainEnd, + }, + details: 'This area may contain partial data', + }, + ]; + + const domainMin = data[0].x > domainStart ? domainStart : data[0].x; + const xDomain = { + domainRange: { + min: domainMin, + max: lastXValue, + }, + minInterval: xInterval, + }; + + const onBrushEnd = (min: number, max: number) => { + // console.log(min, max); + }; + + // TODO: localize + const partialDataText = + 'Part of this bucket may contain partial data. The selected time range does not fully cover it.'; + + const tooltipHeaderFormater = (headerData: TooltipValue): JSX.Element | string => { + const headerDataValue = headerData.value; + const formattedValue = formatter(headerDataValue); + + if (headerDataValue < domainStart || headerDataValue + xInterval > domainEnd) { + return ( + + + + + + {partialDataText} + + +

{formattedValue}

+
+ ); + } + + return formattedValue; + }; + + const tooltipProps = { + headerFormatter: tooltipHeaderFormater, + }; + + return ( + + + + + + + + + ); + } +} diff --git a/src/legacy/core_plugins/kibana/public/discover/components/histogram/index.js b/src/legacy/core_plugins/kibana/public/discover/components/histogram/index.js new file mode 100644 index 000000000000000..b8fdf0672964098 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/discover/components/histogram/index.js @@ -0,0 +1,20 @@ +/* + * 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. + */ + +import './directive'; diff --git a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js index 112894dce927237..e9d386cd95352b7 100644 --- a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js +++ b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js @@ -56,6 +56,7 @@ import { VisualizeLoaderProvider } from 'ui/visualize/loader/visualize_loader'; import { recentlyAccessed } from 'ui/persisted_log'; import { getDocLink } from 'ui/documentation_links'; import '../components/fetch_error'; +import '../components/histogram'; import { getPainlessError } from './get_painless_error'; import { showShareContextMenu, ShareContextMenuExtensionsRegistryProvider } from 'ui/share'; import { getUnhashableStatesProvider } from 'ui/state_management/state_hashing'; @@ -739,6 +740,7 @@ function discoverController( .resolve(buildVislibDimensions($scope.vis, { timeRange: $scope.timeRange, searchSource: $scope.searchSource })) .then(resp => responseHandler(tabifiedData, resp)) .then(resp => { + $scope.histogramData = resp; visualizeHandler.render({ as: 'visualization', value: { diff --git a/src/legacy/core_plugins/kibana/public/discover/index.html b/src/legacy/core_plugins/kibana/public/discover/index.html index 7a7dc9ca3f4b88d..009f09cc7aef610 100644 --- a/src/legacy/core_plugins/kibana/public/discover/index.html +++ b/src/legacy/core_plugins/kibana/public/discover/index.html @@ -166,6 +166,13 @@

+