mirror of https://github.com/grafana/grafana.git
				
				
				
			chore: wip/poc
This commit is contained in:
		
							parent
							
								
									dafedf84ce
								
							
						
					
					
						commit
						b4110b7df6
					
				|  | @ -286,6 +286,7 @@ type UPlotConfigPrepOpts<T extends Record<string, unknown> = {}> = { | |||
|   tweakAxis?: (opts: AxisProps, forField: Field) => AxisProps; | ||||
|   hoverProximity?: number; | ||||
|   orientation?: VizOrientation; | ||||
|   annotations?: DataFrame[]; | ||||
| } & T; | ||||
| 
 | ||||
| /** @alpha */ | ||||
|  |  | |||
|  | @ -40,7 +40,13 @@ export interface GraphNGProps extends Themeable2 { | |||
|   tweakAxis?: (opts: AxisProps, forField: Field) => AxisProps; | ||||
|   onLegendClick?: (event: GraphNGLegendEvent) => void; | ||||
|   children?: (builder: UPlotConfigBuilder, alignedFrame: DataFrame) => React.ReactNode; | ||||
|   prepConfig: (alignedFrame: DataFrame, allFrames: DataFrame[], getTimeRange: () => TimeRange) => UPlotConfigBuilder; | ||||
|   // @todo rename to annoLanes, pass count not frames
 | ||||
|   prepConfig: ( | ||||
|     alignedFrame: DataFrame, | ||||
|     allFrames: DataFrame[], | ||||
|     getTimeRange: () => TimeRange, | ||||
|     annotationFrames?: DataFrame[] | ||||
|   ) => UPlotConfigBuilder; | ||||
|   propsToDiff?: Array<string | PropDiffFn>; | ||||
|   preparePlotFrame?: (frames: DataFrame[], dimFields: XYFieldMatchers) => DataFrame | null; | ||||
|   renderLegend: (config: UPlotConfigBuilder) => React.ReactElement | null; | ||||
|  | @ -63,6 +69,9 @@ export interface GraphNGProps extends Themeable2 { | |||
|    * similar to structureRev. then we can drop propsToDiff entirely. | ||||
|    */ | ||||
|   options?: Record<string, any>; | ||||
| 
 | ||||
|   // Panel annotations
 | ||||
|   annotations?: DataFrame[]; | ||||
| } | ||||
| 
 | ||||
| function sameProps<T extends Record<string, unknown>>( | ||||
|  | @ -191,7 +200,7 @@ export class GraphNG extends Component<GraphNGProps, GraphNGState> { | |||
|       let config = this.state?.config; | ||||
| 
 | ||||
|       if (withConfig) { | ||||
|         config = props.prepConfig(alignedFrameFinal, this.props.frames, this.getTimeRange); | ||||
|         config = props.prepConfig(alignedFrameFinal, this.props.frames, this.getTimeRange, this.props.annotations); | ||||
|         pluginLog('GraphNG', false, 'config prepared', config); | ||||
|       } | ||||
| 
 | ||||
|  | @ -225,12 +234,19 @@ export class GraphNG extends Component<GraphNGProps, GraphNGState> { | |||
|           timeZone !== prevProps.timeZone || | ||||
|           cursorSync !== prevProps.cursorSync || | ||||
|           structureRev !== prevProps.structureRev || | ||||
|           this.props.annotations?.length !== prevProps.annotations?.length || | ||||
|           !structureRev || | ||||
|           propsChanged; | ||||
| 
 | ||||
|         if (shouldReconfig) { | ||||
|           newState.config = this.props.prepConfig(newState.alignedFrame, this.props.frames, this.getTimeRange); | ||||
|           newState.config = this.props.prepConfig( | ||||
|             newState.alignedFrame, | ||||
|             this.props.frames, | ||||
|             this.getTimeRange, | ||||
|             this.props.annotations | ||||
|           ); | ||||
|           pluginLog('GraphNG', false, 'config recreated', newState.config); | ||||
|           console.log('GraphNG', 'config recreated', newState.config); | ||||
|         } | ||||
| 
 | ||||
|         newState.alignedData = newState.config!.prepData!([newState.alignedFrame]) as AlignedData; | ||||
|  |  | |||
|  | @ -13,7 +13,12 @@ const propsToDiff: Array<string | PropDiffFn> = ['legend', 'options', 'theme']; | |||
| type TimeSeriesProps = Omit<GraphNGProps, 'prepConfig' | 'propsToDiff' | 'renderLegend'>; | ||||
| 
 | ||||
| export class UnthemedTimeSeries extends Component<TimeSeriesProps> { | ||||
|   prepConfig = (alignedFrame: DataFrame, allFrames: DataFrame[], getTimeRange: () => TimeRange) => { | ||||
|   prepConfig = ( | ||||
|     alignedFrame: DataFrame, | ||||
|     allFrames: DataFrame[], | ||||
|     getTimeRange: () => TimeRange, | ||||
|     annotationFrames?: DataFrame[] | ||||
|   ) => { | ||||
|     const { theme, timeZone, options, renderers, tweakAxis, tweakScale } = this.props; | ||||
| 
 | ||||
|     return preparePlotConfigBuilder({ | ||||
|  | @ -27,6 +32,7 @@ export class UnthemedTimeSeries extends Component<TimeSeriesProps> { | |||
|       tweakAxis, | ||||
|       hoverProximity: options?.tooltip?.hoverProximity, | ||||
|       orientation: options?.orientation, | ||||
|       annotations: annotationFrames?.length ? annotationFrames : this.props.annotations, | ||||
|     }); | ||||
|   }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -90,7 +90,9 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ({ | |||
|   tweakAxis = (opts) => opts, | ||||
|   hoverProximity, | ||||
|   orientation = VizOrientation.Horizontal, | ||||
|   annotations, | ||||
| }) => { | ||||
|   console.log('preparePlotConfigBuilder', annotations); | ||||
|   // we want the Auto and Horizontal orientation to default to Horizontal
 | ||||
|   const isHorizontal = orientation !== VizOrientation.Vertical; | ||||
|   const builder = new UPlotConfigBuilder(timeZones[0]); | ||||
|  | @ -144,9 +146,29 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ({ | |||
|           } | ||||
|         : undefined; | ||||
| 
 | ||||
|     // HERE
 | ||||
|     // console.log('build axis', annotations)
 | ||||
|     // https://github.com/leeoniya/uPlot/blob/master/src/opts.js#L552
 | ||||
|     const annotationLaneHeight = 5; | ||||
|     const defaultAxisSize = 50; | ||||
|     const annotationLanesSize = ((annotations?.length ?? 1) - 1) * annotationLaneHeight; | ||||
|     const size = defaultAxisSize + annotationLanesSize; | ||||
|     // Add a bit of space below the last annotation lane to show the grid-lines
 | ||||
|     const gapSize = annotationLanesSize + 5; | ||||
| 
 | ||||
|     for (let i = 0; i < timeZones.length; i++) { | ||||
|       const timeZone = timeZones[i]; | ||||
|       // tick length to match the gap length?
 | ||||
|       // want gridlines showing below lowest lane a few px
 | ||||
| 
 | ||||
|       builder.addAxis({ | ||||
|         // HERE update axis size
 | ||||
|         ticks: { | ||||
|           size: gapSize, | ||||
|         }, | ||||
|         gap: gapSize, | ||||
|         size, | ||||
|         // size is everything
 | ||||
|         scaleKey: xScaleKey, | ||||
|         isTime: true, | ||||
|         placement: xFieldAxisPlacement, | ||||
|  |  | |||
|  | @ -131,8 +131,10 @@ export const TimeSeriesPanel = ({ | |||
|       replaceVariables={replaceVariables} | ||||
|       dataLinkPostProcessor={dataLinkPostProcessor} | ||||
|       cursorSync={cursorSync} | ||||
|       annotations={data.annotations} | ||||
|     > | ||||
|       {(uplotConfig, alignedFrame) => { | ||||
|         console.log('time series config (re)loaded', data.annotations?.length, data.annotations); | ||||
|         return ( | ||||
|           <> | ||||
|             <KeyboardPlugin config={uplotConfig} /> | ||||
|  |  | |||
|  | @ -132,7 +132,9 @@ export const AnnotationsPlugin2 = ({ | |||
|       ctx.rect(u.bbox.left, u.bbox.top, u.bbox.width, u.bbox.height); | ||||
|       ctx.clip(); | ||||
| 
 | ||||
|       annos.forEach((frame) => { | ||||
|       annos.forEach((frame, frameIndex) => { | ||||
|         const annotationLaneYOffset = frameIndex * 30; | ||||
|         console.log('annotationLaneYOffset', frameIndex, annotationLaneYOffset); | ||||
|         let vals = getVals(frame); | ||||
| 
 | ||||
|         if (frame.name === 'xymark') { | ||||
|  | @ -166,19 +168,28 @@ export const AnnotationsPlugin2 = ({ | |||
|             ctx.strokeRect(x0, y0, x1 - x0, y1 - y0); | ||||
|           } | ||||
|         } else { | ||||
|           let y0 = u.bbox.top; | ||||
|           let y1 = y0 + u.bbox.height; | ||||
|           // if multiple regions, don't shade
 | ||||
|           // @todo toggle functionality, new annotation config option?
 | ||||
| 
 | ||||
|           let y0 = u.bbox.top - annotationLaneYOffset; | ||||
|           let y1 = y0 + u.bbox.height + annotationLaneYOffset; | ||||
| 
 | ||||
|           ctx.lineWidth = 2; | ||||
|           ctx.setLineDash([5, 5]); | ||||
| 
 | ||||
|           // @todo Don't render the vertical lines if multi lane is enabled
 | ||||
|           //@todo Don't render shaded region if multi-lane is enabled
 | ||||
|           // skipping this loop should do it
 | ||||
| 
 | ||||
|           for (let i = 0; i < vals.time.length; i++) { | ||||
|             let color = getColorByName(vals.color?.[i] || DEFAULT_ANNOTATION_COLOR_HEX8); | ||||
| 
 | ||||
|             let x0 = u.valToPos(vals.time[i], 'x', true); | ||||
|             renderLine(ctx, y0, y1, x0, color); | ||||
| 
 | ||||
|             if (vals.isRegion?.[i]) { | ||||
|             // If dataframe does not have end times, let's omit rendering the region for now
 | ||||
|             // @todo do we want to fix isRegion to render a point when we're missing timeEnd?
 | ||||
|             if (vals.isRegion?.[i] && vals.timeEnd?.[i]) { | ||||
|               let x1 = u.valToPos(vals.timeEnd[i], 'x', true); | ||||
|               renderLine(ctx, y0, y1, x1, color); | ||||
| 
 | ||||
|  | @ -215,6 +226,7 @@ export const AnnotationsPlugin2 = ({ | |||
| 
 | ||||
|       let markers: React.ReactNode[] = []; | ||||
| 
 | ||||
|       const top = frameIdx * 5; | ||||
|       for (let i = 0; i < vals.time.length; i++) { | ||||
|         let color = getColorByName(vals.color?.[i] || DEFAULT_ANNOTATION_COLOR); | ||||
|         let left = Math.round(plot.valToPos(vals.time[i], 'x')) || 0; // handles -0
 | ||||
|  | @ -231,14 +243,14 @@ export const AnnotationsPlugin2 = ({ | |||
|             let clampedLeft = Math.max(0, left); | ||||
|             let clampedRight = Math.min(plot.rect.width, right); | ||||
| 
 | ||||
|             style = { left: clampedLeft, background: color, width: clampedRight - clampedLeft }; | ||||
|             style = { left: clampedLeft, background: color, width: clampedRight - clampedLeft, top }; | ||||
|             className = styles.annoRegion; | ||||
|           } | ||||
|         } else { | ||||
|           isVisible = left >= 0 && left <= plot.rect.width; | ||||
| 
 | ||||
|           if (isVisible) { | ||||
|             style = { left, borderBottomColor: color }; | ||||
|             style = { left, borderBottomColor: color, top }; | ||||
|             className = styles.annoMarker; | ||||
|           } | ||||
|         } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue