import React, { PureComponent } from 'react'; import { PanelProps } from '@grafana/data'; import { getTemplateSrv, getLocationSrv } from '@grafana/runtime'; import { SimpleOptions, defaults } from 'types'; import merge from 'deepmerge'; import _ from 'lodash'; // tslint:disable import Plot from 'react-plotly.js'; // @ts-ignore import Plotly from 'plotly.js/dist/plotly'; //declare plolty as global declare global { interface Window { Plotly: any; //LocationSrv: any; } } window.Plotly = Plotly; //window.LocationSrv = getLocationSrv(); let templateSrv: any = getTemplateSrv(); interface Props extends PanelProps<SimpleOptions> {} export class SimplePanel extends PureComponent<Props> { render() { //Get all variables const context = { //interval: templateSrv.getBuiltInIntervalValue(),//dataSource.templateSrv.builtIns.__interval.value, __from: this.props.replaceVariables('$__from'), __to: this.props.replaceVariables('$__to'), __interval: this.props.replaceVariables('$__interval'), __interval_ms: this.props.replaceVariables('$__interval_ms'), } as any; templateSrv.getVariables().forEach((elt: any) => { context[elt.name] = elt.current.text; }); //const NbValues = data.series[0].rows.length; let config = this.props.options.config || defaults.config; let data = this.props.options.data || defaults.data; let layout = this.props.options.layout || defaults.layout; let frames = this.props.options.frames || defaults.frames; let parameters: any; parameters = [this.props.options.data, layout, config]; let error: any; try { if (this.props.options.script !== '' && this.props.data.state !== 'Error') { var f = new Function('data,variables', this.props.options.script); parameters = f(this.props.data, context); if (!parameters) { throw new Error('Script must return values'); } } } catch (e) { error = e; console.error(e); //Can't update chart when script is changing if throw error?!? //throw new Error('There\'s an error in your script. Check the console to see error\'s details'); } const combineMerge = (target, source, options) => { const destination = target.slice(); source.forEach((item, index) => { if (typeof destination[index] === 'undefined') { destination[index] = options.cloneUnlessOtherwiseSpecified(item, options); } else if (options.isMergeableObject(item)) { destination[index] = merge(target[index], item, options); } else if (target.indexOf(item) === -1) { destination.push(item); } }); return destination; }; //Merge data field and data transformed by script /*let series: any[] = []; if (data2.length && data2.length > 0) { data2.forEach((serie, index) => { let options = this.props.options.data[index]; series.push({ ...options, ...data2[index], }); }); }*/ layout = { ...layout, autosize: true, height: this.props.height }; let display: any; if (error) { let matches = error.stack.match(/anonymous>:.*\)/m); let lines = matches ? matches[0].slice(0, -1).split(':') : null; display = ( <div> There's an error in your script : <br /> <span style={{ color: '#D00' }}>{error.toString()}</span>{' '} {lines ? '- line ' + (parseInt(lines[1], 10) - 2) + ':' + lines[2] : ''} (Check your console for more details) </div> ); } else { display = ( <Plot style={{ width: '100%', height: '100%', }} data={parameters.data ? merge(data, parameters.data, { arrayMerge: combineMerge }) : data} frames={parameters.frames ? merge(data, parameters.frames, { arrayMerge: combineMerge }) : frames} onInitialized={(figure: any, graphDiv: any) => this.setState({ figure: figure, graphDiv: graphDiv })} //layout={ {autosize:true, height:this.props.height, title: this.props.options.title} } layout={parameters.layout ? merge(layout, parameters.layout) : layout} config={parameters.config ? merge(config, parameters.config) : config} useResizeHandler={true} onClick={(data) => { //console.log(data) var f = new Function('data', 'getLocationSrv', 'getTemplateSrv', this.props.options.onclick); f(data, getLocationSrv, getTemplateSrv); }} ></Plot> ); } return display; } }