@@ -16,12 +16,19 @@ import {
1616 AnnotationTooltipFormatter ,
1717 LineAnnotation ,
1818 Position ,
19+ RectAnnotation ,
1920} from '@elastic/charts' ;
2021import moment from 'moment' ;
21- import { EuiFlexGroup , EuiFlexItem } from '@elastic/eui' ;
22- import type { EventAnnotationArgs } from '@kbn/event-annotation-plugin/common' ;
22+ import { EuiFlexGroup , EuiFlexItem , EuiText } from '@elastic/eui' ;
23+ import type {
24+ ManualPointEventAnnotationArgs ,
25+ ManualRangeEventAnnotationOutput ,
26+ } from '@kbn/event-annotation-plugin/common' ;
2327import type { FieldFormat } from '@kbn/field-formats-plugin/common' ;
24- import { defaultAnnotationColor } from '@kbn/event-annotation-plugin/public' ;
28+ import {
29+ defaultAnnotationColor ,
30+ defaultAnnotationRangeColor ,
31+ } from '@kbn/event-annotation-plugin/public' ;
2532import type { AnnotationLayerArgs , AnnotationLayerConfigResult } from '../../common/types' ;
2633import { AnnotationIcon , hasIcon , Marker , MarkerBody } from '../helpers' ;
2734import { mapVerticalToHorizontalPlacement , LINES_MARKER_SIZE } from '../helpers' ;
@@ -34,16 +41,18 @@ const getRoundedTimestamp = (timestamp: number, firstTimestamp?: number, minInte
3441} ;
3542
3643export interface AnnotationsProps {
37- groupedAnnotations : CollectiveConfig [ ] ;
44+ groupedLineAnnotations : CollectiveConfig [ ] ;
45+ rangeAnnotations : ManualRangeEventAnnotationOutput [ ] ;
3846 formatter ?: FieldFormat ;
3947 isHorizontal : boolean ;
4048 paddingMap : Partial < Record < Position , number > > ;
4149 hide ?: boolean ;
4250 minInterval ?: number ;
4351 isBarChart ?: boolean ;
52+ outsideDimension : number ;
4453}
4554
46- interface CollectiveConfig extends EventAnnotationArgs {
55+ interface CollectiveConfig extends ManualPointEventAnnotationArgs {
4756 roundedTimestamp : number ;
4857 axisMode : 'bottom' ;
4958 customTooltipDetails ?: AnnotationTooltipFormatter | undefined ;
@@ -55,9 +64,11 @@ const groupVisibleConfigsByInterval = (
5564 firstTimestamp ?: number
5665) => {
5766 return layers
58- . flatMap ( ( { annotations } ) => annotations . filter ( ( a ) => ! a . isHidden ) )
67+ . flatMap ( ( { annotations } ) =>
68+ annotations . filter ( ( a ) => ! a . isHidden && a . type === 'manual_point_event_annotation' )
69+ )
5970 . sort ( ( a , b ) => moment ( a . time ) . valueOf ( ) - moment ( b . time ) . valueOf ( ) )
60- . reduce < Record < string , EventAnnotationArgs [ ] > > ( ( acc , current ) => {
71+ . reduce < Record < string , ManualPointEventAnnotationArgs [ ] > > ( ( acc , current ) => {
6172 const roundedTimestamp = getRoundedTimestamp (
6273 moment ( current . time ) . valueOf ( ) ,
6374 firstTimestamp ,
@@ -72,7 +83,7 @@ const groupVisibleConfigsByInterval = (
7283
7384const createCustomTooltipDetails =
7485 (
75- config : EventAnnotationArgs [ ] ,
86+ config : ManualPointEventAnnotationArgs [ ] ,
7687 formatter ?: FieldFormat
7788 ) : AnnotationTooltipFormatter | undefined =>
7889 ( ) => {
@@ -95,8 +106,8 @@ const createCustomTooltipDetails =
95106 ) ;
96107 } ;
97108
98- function getCommonProperty < T , K extends keyof EventAnnotationArgs > (
99- configArr : EventAnnotationArgs [ ] ,
109+ function getCommonProperty < T , K extends keyof ManualPointEventAnnotationArgs > (
110+ configArr : ManualPointEventAnnotationArgs [ ] ,
100111 propertyName : K ,
101112 fallbackValue : T
102113) {
@@ -107,9 +118,9 @@ function getCommonProperty<T, K extends keyof EventAnnotationArgs>(
107118 return fallbackValue ;
108119}
109120
110- const getCommonStyles = ( configArr : EventAnnotationArgs [ ] ) => {
121+ const getCommonStyles = ( configArr : ManualPointEventAnnotationArgs [ ] ) => {
111122 return {
112- color : getCommonProperty < EventAnnotationArgs [ 'color' ] , 'color' > (
123+ color : getCommonProperty < ManualPointEventAnnotationArgs [ 'color' ] , 'color' > (
113124 configArr ,
114125 'color' ,
115126 defaultAnnotationColor
@@ -120,6 +131,20 @@ const getCommonStyles = (configArr: EventAnnotationArgs[]) => {
120131 } ;
121132} ;
122133
134+ export const getRangeAnnotations = ( layers : AnnotationLayerConfigResult [ ] ) => {
135+ return layers
136+ . flatMap ( ( { annotations } ) =>
137+ annotations . filter (
138+ ( a ) : a is ManualRangeEventAnnotationOutput =>
139+ a . type === 'manual_range_event_annotation' && ! a . isHidden
140+ )
141+ )
142+ . sort ( ( a , b ) => moment ( a . time ) . valueOf ( ) - moment ( b . time ) . valueOf ( ) ) ;
143+ } ;
144+
145+ export const OUTSIDE_RECT_ANNOTATION_WIDTH = 8 ;
146+ export const OUTSIDE_RECT_ANNOTATION_WIDTH_SUGGESTION = 2 ;
147+
123148export const getAnnotationsGroupedByInterval = (
124149 layers : AnnotationLayerConfigResult [ ] ,
125150 minInterval ?: number ,
@@ -147,18 +172,23 @@ export const getAnnotationsGroupedByInterval = (
147172 } ) ;
148173} ;
149174
175+ // todo: remove when closed https://github.com/elastic/elastic-charts/issues/1647
176+ RectAnnotation . displayName = 'RectAnnotation' ;
177+
150178export const Annotations = ( {
151- groupedAnnotations,
179+ groupedLineAnnotations,
180+ rangeAnnotations,
152181 formatter,
153182 isHorizontal,
154183 paddingMap,
155184 hide,
156185 minInterval,
157186 isBarChart,
187+ outsideDimension,
158188} : AnnotationsProps ) => {
159189 return (
160190 < >
161- { groupedAnnotations . map ( ( annotation ) => {
191+ { groupedLineAnnotations . map ( ( annotation ) => {
162192 const markerPositionVertical = Position . Top ;
163193 const markerPosition = isHorizontal
164194 ? mapVerticalToHorizontalPlacement ( markerPositionVertical )
@@ -229,6 +259,40 @@ export const Annotations = ({
229259 />
230260 ) ;
231261 } ) }
262+ { rangeAnnotations . map ( ( { label, time, color, endTime, outside } ) => {
263+ const id = snakeCase ( label ) ;
264+
265+ return (
266+ < RectAnnotation
267+ id = { id }
268+ key = { id }
269+ customTooltip = { ( ) => (
270+ < div className = "echTooltip" >
271+ < EuiText size = "xs" className = "echTooltip__header" >
272+ < h4 >
273+ { formatter
274+ ? `${ formatter . convert ( time ) } — ${ formatter ?. convert ( endTime ) } `
275+ : `${ moment ( time ) . toISOString ( ) } — ${ moment ( endTime ) . toISOString ( ) } ` }
276+ </ h4 >
277+ </ EuiText >
278+ < div className = "xyAnnotationTooltipDetail" > { label } </ div >
279+ </ div >
280+ ) }
281+ dataValues = { [
282+ {
283+ coordinates : {
284+ x0 : moment ( time ) . valueOf ( ) ,
285+ x1 : moment ( endTime ) . valueOf ( ) ,
286+ } ,
287+ details : label ,
288+ } ,
289+ ] }
290+ style = { { fill : color || defaultAnnotationRangeColor , opacity : 1 } }
291+ outside = { Boolean ( outside ) }
292+ outsideDimension = { outsideDimension }
293+ />
294+ ) ;
295+ } ) }
232296 </ >
233297 ) ;
234298} ;
0 commit comments