import _ from 'lodash' ; import React , { PureComponent } from 'react' ; import { getDataSourceSrv } from '@grafana/runtime' ; import { PanelEditorProps , FieldConfig , DataSourceSelectItem } from '@grafana/data' ; import { Switch , LegendOptions , GraphTooltipOptions , PanelOptionsGrid , PanelOptionsGroup , FieldPropertiesEditor , Select , Input } from '@grafana/ui' ; import { Options , GraphOptions , GraphDatasourceOptions } from './types' ; import { GraphLegendEditor } from './GraphLegendEditor' ; export class GraphPanelEditor extends PureComponent < PanelEditorProps < Options > > { datasources : DataSourceSelectItem [ ] = getDataSourceSrv ( ) . getMetricSources ( ) ; constructor ( props ) { super ( props ) ; } datasourcesList = function ( ) { var res = new Array ( { label : 'Not selected' , value : '' } ) ; this . datasources . forEach ( function ( val ) { if ( val . meta . id === 'loudml-datasource' ) { res . push ( { label : val . name , value : val . value } ) ; } } ) ; return res ; } ; onChangeDataSource = ( value ) => { this . props . options . datasourceOptions . datasource = value . value ; this . setState ( { value : value . value } ) ; } ; onChangeInputBucket = ( event ) => { this . props . options . datasourceOptions . input_bucket = event . target . value ; this . setState ( { value : event . target . value } ) ; } ; onBlurInputBucket = ( ) => { } ; onChangeOutputBucket = ( event ) => { this . props . options . datasourceOptions . output_bucket = event . target . value ; this . setState ( { value : event . target . value } ) ; } ; onBlurOutputBucket = ( ) => { } ; onGraphOptionsChange = ( options ) => { this . props . onOptionsChange ( { ... this . props . options , graph : { ... this . props . options . graph , ... options , } , } ) ; } ; onLegendOptionsChange = ( options ) => { this . props . onOptionsChange ( { ... this . props . options , legend : options } ) ; } ; onTooltipOptionsChange = ( options ) => { this . props . onOptionsChange ( { ... this . props . options , tooltipOptions : options } ) ; } ; onToggleLines = ( ) => { this . onGraphOptionsChange ( { showLines : ! this . props . options . graph . showLines } ) ; } ; onToggleBars = ( ) => { this . onGraphOptionsChange ( { showBars : ! this . props . options . graph . showBars } ) ; } ; onTogglePoints = ( ) => { this . onGraphOptionsChange ( { showPoints : ! this . props . options . graph . showPoints } ) ; } ; onToggleisStacked = ( ) => { this . onGraphOptionsChange ( { isStacked : ! this . props . options . graph . isStacked } ) ; } ; onChangeFill = ( value ) => { this . onGraphOptionsChange ( { fill : value . value } ) ; this . setState ( { value : value . value } ) ; } ; onChangeFillGradient = ( value ) => { this . onGraphOptionsChange ( { fillGradient : value . value } ) ; this . setState ( { value : value . value } ) ; } ; onChangeLineWidth = ( value ) => { this . onGraphOptionsChange ( { lineWidth : value . value } ) ; this . setState ( { value : value . value } ) ; } ; onDefaultsChange = ( field ) => { this . props . onOptionsChange ( { ... this . props . options , fieldOptions : { ... this . props . options . fieldOptions , defaults : field , } , } ) ; } ; render ( ) { const { graph : { showBars , showPoints , showLines , isStacked , lineWidth , fill , fillGradient } , tooltipOptions : { mode } , datasourceOptions : { datasource , input_bucket , output_bucket } , } = this . props . options ; return ( < > < PanelOptionsGroup title = "Loud ML" > < div className = "gf-form max-width-40" > < span className = "gf-form-label width-10" > Loud ML Server < /span> < Select value = { { value : datasource , label : datasource } } onChange = { value => { this . onChangeDataSource ( { value : value . value as any } ) ; } } options = { this . datasourcesList ( ) } / > < /div> < div className = "gf-form max-width-40" > < span className = "gf-form-label width-10" > Input Bucket < /span> < Input value = { this . props . options . datasourceOptions . input_bucket } className = "gf-form-input" type = "text" placeholder = "Datasource/Database used in Query" min - length = "0" onBlur = { this . onBlurInputBucket } onChange = { this . onChangeInputBucket } / > < /div> < p > Bucket to get data for ML Model ( Equal to Datasource used on Query tab ; it should be in Loud ML YAML config ) < /p> < div className = "gf-form max-width-40" > < span className = "gf-form-label width-10" > Output Bucket < /span> < Input value = { this . props . options . datasourceOptions . output_bucket } className = "gf-form-input" type = "text" placeholder = "Database to store ML Model training results" min - length = "0" onBlur = { this . onBlurOutputBucket } onChange = { this . onChangeOutputBucket } / > < /div> < p > Specify a bucket to store ML training results ( It should be in Loud ML YAML config ) < /p> < /PanelOptionsGroup> < PanelOptionsGroup title = "Draw" > < div className = "section gf-form-group" > < h5 className = "section-heading" > Draw Modes < /h5> < Switch label = "Lines" labelClass = "width-5" checked = { showLines } onChange = { this . onToggleLines } / > < Switch label = "Bars" labelClass = "width-5" checked = { showBars } onChange = { this . onToggleBars } / > < Switch label = "Points" labelClass = "width-5" checked = { showPoints } onChange = { this . onTogglePoints } / > < /div> < div className = "section gf-form-group" > < h5 className = "section-heading" > Mode Options < /h5> < div className = "gf-form max-width-20" > < span className = "gf-form-label width-8" > Fill < /span> < Select className = "width-5" value = { { value : fill , label : fill } } onChange = { value => { this . onChangeFill ( { value : value . value as any } ) ; } } options = { [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] . map ( t => ( { value : t , label : t } ) ) } / > < /div> < div className = "gf-form max-width-20" > < span className = "gf-form-label width-8" > Fill Gradient < /span> < Select className = "width-5" value = { { value : fillGradient , label : fillGradient } } onChange = { value => { this . onChangeFillGradient ( { value : value . value as any } ) ; } } options = { [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] . map ( t => ( { value : t , label : t } ) ) } / > < /div> < div className = "gf-form max-width-20" > < span className = "gf-form-label width-8" > Line Width < /span> < Select className = "width-5" value = { { value : lineWidth , label : lineWidth } } onChange = { value => { this . onChangeLineWidth ( { value : value . value as any } ) ; } } options = { [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] . map ( t => ( { value : t , label : t } ) ) } / > < /div> < /div> < div className = "section gf-form-group" > < h5 className = "section-heading" > Stacking & Null value < /h5> < div className = "gf-form max-width-20" > < Switch label = "Stack" labelClass = "width-5" checked = { isStacked } onChange = { this . onToggleisStacked } / > < /div> < /div> < /PanelOptionsGroup> < PanelOptionsGrid > < PanelOptionsGroup title = "Field" > < FieldPropertiesEditor showMinMax = { false } onChange = { this . onDefaultsChange } value = { this . props . options . fieldOptions . defaults } / > < /PanelOptionsGroup> < PanelOptionsGroup title = "Tooltip" > < Select value = { { value : mode , label : mode === 'single' ? 'Single' : 'All series' } } onChange = { value => { this . onTooltipOptionsChange ( { mode : value . value as any } ) ; } } options = { [ { label : 'All series' , value : 'multi' } , { label : 'Single' , value : 'single' } , ] } / > < /PanelOptionsGroup> < GraphLegendEditor options = { this . props . options . legend } onChange = { this . onLegendOptionsChange } / > < /PanelOptionsGrid> < />); } }