mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
react panels: working on changing type
This commit is contained in:
parent
e052e165e9
commit
761283231c
@ -1,4 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import { PanelPlugin } from 'app/types/plugins';
|
||||
|
||||
export interface BuildInfo {
|
||||
version: string;
|
||||
@ -7,17 +8,6 @@ export interface BuildInfo {
|
||||
env: string;
|
||||
}
|
||||
|
||||
export interface PanelPlugin {
|
||||
id: string;
|
||||
name: string;
|
||||
meta: any;
|
||||
hideFromList: boolean;
|
||||
module: string;
|
||||
baseUrl: string;
|
||||
info: any;
|
||||
sort: number;
|
||||
}
|
||||
|
||||
export class Settings {
|
||||
datasources: any;
|
||||
panels: PanelPlugin[];
|
||||
|
@ -171,6 +171,7 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
|
||||
|
||||
renderPanels() {
|
||||
const panelElements = [];
|
||||
console.log('render panels');
|
||||
|
||||
for (let panel of this.props.dashboard.panels) {
|
||||
const panelClasses = classNames({ panel: true, 'panel--fullscreen': panel.fullscreen });
|
||||
|
@ -5,8 +5,10 @@ import { DashboardModel } from '../dashboard_model';
|
||||
import { getAngularLoader, AngularComponent } from 'app/core/services/angular_loader';
|
||||
import { DashboardRow } from './DashboardRow';
|
||||
import { AddPanelPanel } from './AddPanelPanel';
|
||||
import { importPluginModule, PluginExports } from 'app/features/plugins/plugin_loader';
|
||||
import { importPluginModule } from 'app/features/plugins/plugin_loader';
|
||||
import { PluginExports } from 'app/types/plugins';
|
||||
import { PanelChrome } from './PanelChrome';
|
||||
import { PanelEditor } from './PanelEditor';
|
||||
|
||||
export interface Props {
|
||||
panel: PanelModel;
|
||||
@ -29,15 +31,11 @@ export class DashboardPanel extends React.Component<Props, State> {
|
||||
|
||||
this.specialPanels['row'] = this.renderRow.bind(this);
|
||||
this.specialPanels['add-panel'] = this.renderAddPanel.bind(this);
|
||||
this.props.panel.events.on('panel-size-changed', this.triggerForceUpdate.bind(this));
|
||||
}
|
||||
|
||||
if (!this.isSpecial()) {
|
||||
this.pluginInfo = config.panels[this.props.panel.type];
|
||||
|
||||
// load panel plugin
|
||||
importPluginModule(this.pluginInfo.module).then(pluginExports => {
|
||||
this.setState({ pluginExports: pluginExports });
|
||||
});
|
||||
}
|
||||
triggerForceUpdate() {
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
||||
isSpecial() {
|
||||
@ -52,8 +50,33 @@ export class DashboardPanel extends React.Component<Props, State> {
|
||||
return <AddPanelPanel panel={this.props.panel} dashboard={this.props.dashboard} />;
|
||||
}
|
||||
|
||||
loadPlugin() {
|
||||
if (this.isSpecial()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// handle plugin loading & changing of plugin type
|
||||
if (!this.pluginInfo || this.pluginInfo.id !== this.props.panel.type) {
|
||||
this.pluginInfo = config.panels[this.props.panel.type];
|
||||
|
||||
if (this.pluginInfo.exports) {
|
||||
this.setState({ pluginExports: this.pluginInfo.exports });
|
||||
} else {
|
||||
importPluginModule(this.pluginInfo.module).then(pluginExports => {
|
||||
this.setState({ pluginExports: pluginExports });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.loadPlugin();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
// skip loading angular component if we have no element or we have already loaded it
|
||||
this.loadPlugin();
|
||||
|
||||
// handle angular plugin loading
|
||||
if (!this.element || this.angularPanel) {
|
||||
return;
|
||||
}
|
||||
@ -70,25 +93,43 @@ export class DashboardPanel extends React.Component<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
renderReactPanel() {
|
||||
const { pluginExports } = this.state;
|
||||
const containerClass = this.props.panel.isEditing ? 'panel-editor-container' : 'panel-height-helper';
|
||||
const panelWrapperClass = this.props.panel.isEditing ? 'panel-editor-container__panel' : 'panel-height-helper';
|
||||
|
||||
// this might look strange with these classes that change when edit, but
|
||||
// I want to try to keep markup (parents) for panel the same in edit mode to avoide unmount / new mount of panel
|
||||
// plugin component
|
||||
return (
|
||||
<div className={containerClass}>
|
||||
<div className={panelWrapperClass}>
|
||||
<PanelChrome
|
||||
component={pluginExports.PanelComponent}
|
||||
panel={this.props.panel}
|
||||
dashboard={this.props.dashboard}
|
||||
/>
|
||||
</div>
|
||||
{this.props.panel.isEditing && (
|
||||
<div className="panel-editor-container__editor">
|
||||
<PanelEditor panel={this.props.panel} dashboard={this.props.dashboard} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.isSpecial()) {
|
||||
return this.specialPanels[this.props.panel.type]();
|
||||
}
|
||||
|
||||
if (!pluginExports) {
|
||||
if (!this.state.pluginExports) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (pluginExports.PanelComponent) {
|
||||
return (
|
||||
<PanelChrome
|
||||
component={pluginExports.PanelComponent}
|
||||
panel={this.props.panel}
|
||||
dashboard={this.props.dashboard}
|
||||
/>
|
||||
);
|
||||
if (this.state.pluginExports.PanelComponent) {
|
||||
return this.renderReactPanel();
|
||||
}
|
||||
|
||||
// legacy angular rendering
|
||||
|
@ -2,23 +2,16 @@ import React, { ComponentClass } from 'react';
|
||||
import $ from 'jquery';
|
||||
import { PanelModel } from '../panel_model';
|
||||
import { DashboardModel } from '../dashboard_model';
|
||||
import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN } from 'app/core/constants';
|
||||
import { PanelHeader } from './PanelHeader';
|
||||
import { PanelEditor } from './PanelEditor';
|
||||
import { DataPanel, PanelProps, DataPanelWrapper } from './DataPanel';
|
||||
|
||||
const TITLE_HEIGHT = 27;
|
||||
const PANEL_BORDER = 2;
|
||||
|
||||
export interface Props {
|
||||
panel: PanelModel;
|
||||
dashboard: DashboardModel;
|
||||
component: ComponentClass<PanelProps>;
|
||||
}
|
||||
|
||||
interface State {
|
||||
height: number;
|
||||
}
|
||||
interface State {}
|
||||
|
||||
export class PanelChrome extends React.Component<Props, State> {
|
||||
panelComponent: DataPanel;
|
||||
@ -26,20 +19,9 @@ export class PanelChrome extends React.Component<Props, State> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
height: this.getPanelHeight(),
|
||||
};
|
||||
|
||||
this.panelComponent = DataPanelWrapper(this.props.component);
|
||||
this.props.panel.events.on('panel-size-changed', this.onPanelSizeChanged);
|
||||
}
|
||||
|
||||
onPanelSizeChanged = () => {
|
||||
this.setState({
|
||||
height: this.getPanelHeight(),
|
||||
});
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
console.log('panel chrome mounted');
|
||||
}
|
||||
@ -48,31 +30,10 @@ export class PanelChrome extends React.Component<Props, State> {
|
||||
let PanelComponent = this.panelComponent;
|
||||
|
||||
return (
|
||||
<div className="panel-editor-container">
|
||||
<div className="panel-container">
|
||||
<PanelHeader panel={this.props.panel} dashboard={this.props.dashboard} />
|
||||
<div className="panel-content" style={{ height: this.state.height }}>
|
||||
{<PanelComponent type={'test'} queries={[]} isVisible={true} />}
|
||||
</div>
|
||||
</div>
|
||||
{this.props.panel.isEditing && <PanelEditor panel={this.props.panel} dashboard={this.props.dashboard} />}
|
||||
<div className="panel-container">
|
||||
<PanelHeader panel={this.props.panel} dashboard={this.props.dashboard} />
|
||||
<div className="panel-content">{<PanelComponent type={'test'} queries={[]} isVisible={true} />}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
getPanelHeight() {
|
||||
const panel = this.props.panel;
|
||||
let height = 0;
|
||||
|
||||
if (panel.fullscreen) {
|
||||
var docHeight = $(window).height();
|
||||
var editHeight = Math.floor(docHeight * 0.3);
|
||||
var fullscreenHeight = Math.floor(docHeight * 0.8);
|
||||
height = panel.isEditing ? editHeight : fullscreenHeight;
|
||||
} else {
|
||||
height = panel.gridPos.h * GRID_CELL_HEIGHT + (panel.gridPos.h - 1) * GRID_CELL_VMARGIN;
|
||||
}
|
||||
|
||||
return height - (PANEL_BORDER + TITLE_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { DashboardModel } from '../dashboard_model';
|
||||
import { store } from 'app/stores/store';
|
||||
import { observer } from 'mobx-react';
|
||||
import { QueriesTab } from './QueriesTab';
|
||||
import { PanelPlugin } from 'app/core/config';
|
||||
import { PanelPlugin } from 'app/types/plugins';
|
||||
import { VizTypePicker } from './VizTypePicker';
|
||||
|
||||
interface PanelEditorProps {
|
||||
@ -50,8 +50,8 @@ export class PanelEditor extends React.Component<PanelEditorProps, any> {
|
||||
}
|
||||
|
||||
onVizTypeChanged = (plugin: PanelPlugin) => {
|
||||
this.props.panel.type = plugin.id;
|
||||
this.forceUpdate();
|
||||
console.log('changing type to ', plugin.id);
|
||||
this.props.panel.changeType(plugin.id);
|
||||
};
|
||||
|
||||
onChangeTab = (tab: PanelEditorTab) => {
|
||||
|
@ -21,6 +21,16 @@ export class PanelHeader extends React.Component<PanelHeaderProps, any> {
|
||||
);
|
||||
};
|
||||
|
||||
onViewPanel = () => {
|
||||
store.view.updateQuery(
|
||||
{
|
||||
panelId: this.props.panel.id,
|
||||
fullscreen: true,
|
||||
},
|
||||
false
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
let isFullscreen = false;
|
||||
let isLoading = false;
|
||||
@ -52,7 +62,9 @@ export class PanelHeader extends React.Component<PanelHeaderProps, any> {
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="asd">asd</a>
|
||||
<a onClick={this.onViewPanel}>
|
||||
<i className="fa fa-fw fa-eye" /> View
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import config, { PanelPlugin } from 'app/core/config';
|
||||
import config from 'app/core/config';
|
||||
import { PanelPlugin } from 'app/types/plugins';
|
||||
import _ from 'lodash';
|
||||
|
||||
interface Props {
|
||||
|
@ -97,6 +97,11 @@ export class PanelModel {
|
||||
this.events.emit('panel-init-edit-mode');
|
||||
}
|
||||
|
||||
changeType(newType: string) {
|
||||
this.type = newType;
|
||||
this.events.emit('panel-size-changed');
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.events.removeAllListeners();
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import * as mssqlPlugin from 'app/plugins/datasource/mssql/module';
|
||||
|
||||
import * as textPanel from 'app/plugins/panel/text/module';
|
||||
import * as text2Panel from 'app/plugins/panel/text2/module';
|
||||
import * as graph2Panel from 'app/plugins/panel/graph2/module';
|
||||
import * as graphPanel from 'app/plugins/panel/graph/module';
|
||||
import * as dashListPanel from 'app/plugins/panel/dashlist/module';
|
||||
import * as pluginsListPanel from 'app/plugins/panel/pluginlist/module';
|
||||
@ -41,6 +42,7 @@ const builtInPlugins = {
|
||||
|
||||
'app/plugins/panel/text/module': textPanel,
|
||||
'app/plugins/panel/text2/module': text2Panel,
|
||||
'app/plugins/panel/graph2/module': graph2Panel,
|
||||
'app/plugins/panel/graph/module': graphPanel,
|
||||
'app/plugins/panel/dashlist/module': dashListPanel,
|
||||
'app/plugins/panel/pluginlist/module': pluginsListPanel,
|
||||
|
@ -18,6 +18,7 @@ import config from 'app/core/config';
|
||||
import TimeSeries from 'app/core/time_series2';
|
||||
import TableModel from 'app/core/table_model';
|
||||
import { coreModule, appEvents, contextSrv } from 'app/core/core';
|
||||
import { PluginExports } from 'app/types/plugins';
|
||||
import * as datemath from 'app/core/utils/datemath';
|
||||
import * as fileExport from 'app/core/utils/file_export';
|
||||
import * as flatten from 'app/core/utils/flatten';
|
||||
@ -143,16 +144,6 @@ for (let flotDep of flotDeps) {
|
||||
exposeToPlugin(flotDep, { fakeDep: 1 });
|
||||
}
|
||||
|
||||
export interface PluginExports {
|
||||
PanelCtrl?;
|
||||
any;
|
||||
PanelComponent?: any;
|
||||
Datasource?: any;
|
||||
QueryCtrl?: any;
|
||||
ConfigCtrl?: any;
|
||||
AnnotationsQueryCtrl?: any;
|
||||
}
|
||||
|
||||
export function importPluginModule(path: string): Promise<PluginExports> {
|
||||
let builtIn = builtInPlugins[path];
|
||||
if (builtIn) {
|
||||
|
5
public/app/plugins/panel/graph2/README.md
Normal file
5
public/app/plugins/panel/graph2/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Text Panel - Native Plugin
|
||||
|
||||
The Text Panel is **included** with Grafana.
|
||||
|
||||
The Text Panel is a very simple panel that displays text. The source text is written in the Markdown syntax meaning you can format the text. Read [GitHub's Mastering Markdown](https://guides.github.com/features/mastering-markdown/) to learn more.
|
186
public/app/plugins/panel/graph2/img/icn-graph-panel.svg
Normal file
186
public/app/plugins/panel/graph2/img/icn-graph-panel.svg
Normal file
@ -0,0 +1,186 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="100px" height="100px" viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
|
||||
<polyline style="fill:none;stroke:#898989;stroke-width:2;stroke-miterlimit:10;" points="4.734,34.349 36.05,19.26 64.876,36.751
|
||||
96.308,6.946 "/>
|
||||
<circle style="fill:#898989;" cx="4.885" cy="33.929" r="4.885"/>
|
||||
<circle style="fill:#898989;" cx="35.95" cy="19.545" r="4.885"/>
|
||||
<circle style="fill:#898989;" cx="65.047" cy="36.046" r="4.885"/>
|
||||
<circle style="fill:#898989;" cx="94.955" cy="7.135" r="4.885"/>
|
||||
<g>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="5" y1="103.7019" x2="5" y2="32.0424">
|
||||
<stop offset="0" style="stop-color:#FFF33B"/>
|
||||
<stop offset="0" style="stop-color:#FFD53F"/>
|
||||
<stop offset="0" style="stop-color:#FBBC40"/>
|
||||
<stop offset="0" style="stop-color:#F7A840"/>
|
||||
<stop offset="0" style="stop-color:#F59B40"/>
|
||||
<stop offset="0" style="stop-color:#F3933F"/>
|
||||
<stop offset="0" style="stop-color:#F3903F"/>
|
||||
<stop offset="0.8423" style="stop-color:#ED683C"/>
|
||||
<stop offset="1" style="stop-color:#E93E3A"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_1_);" d="M9.001,48.173H0.999C0.447,48.173,0,48.62,0,49.172V100h10V49.172
|
||||
C10,48.62,9.553,48.173,9.001,48.173z"/>
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="5" y1="98.9423" x2="5" y2="53.1961">
|
||||
<stop offset="0" style="stop-color:#FEBC11"/>
|
||||
<stop offset="1" style="stop-color:#F99B1C"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_2_);" d="M0,69.173v30.563h10V69.173"/>
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="5" y1="99.4343" x2="5" y2="74.4359">
|
||||
<stop offset="0" style="stop-color:#FEBC11"/>
|
||||
<stop offset="1" style="stop-color:#FFDE17"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_3_);" d="M0,83.166v16.701h10V83.166"/>
|
||||
</g>
|
||||
<g>
|
||||
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="20" y1="103.7019" x2="20" y2="32.0424">
|
||||
<stop offset="0" style="stop-color:#FFF33B"/>
|
||||
<stop offset="0" style="stop-color:#FFD53F"/>
|
||||
<stop offset="0" style="stop-color:#FBBC40"/>
|
||||
<stop offset="0" style="stop-color:#F7A840"/>
|
||||
<stop offset="0" style="stop-color:#F59B40"/>
|
||||
<stop offset="0" style="stop-color:#F3933F"/>
|
||||
<stop offset="0" style="stop-color:#F3903F"/>
|
||||
<stop offset="0.8423" style="stop-color:#ED683C"/>
|
||||
<stop offset="1" style="stop-color:#E93E3A"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_4_);" d="M24.001,40.769h-8.002c-0.552,0-0.999,0.447-0.999,0.999V100h10V41.768
|
||||
C25,41.216,24.553,40.769,24.001,40.769z"/>
|
||||
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="20" y1="98.9423" x2="20" y2="53.1961">
|
||||
<stop offset="0" style="stop-color:#FEBC11"/>
|
||||
<stop offset="1" style="stop-color:#F99B1C"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_5_);" d="M15,64.716v35.02h10v-35.02"/>
|
||||
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="20" y1="99.4343" x2="20" y2="74.4359">
|
||||
<stop offset="0" style="stop-color:#FEBC11"/>
|
||||
<stop offset="1" style="stop-color:#FFDE17"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_6_);" d="M15,80.731v19.137h10V80.731"/>
|
||||
</g>
|
||||
<g>
|
||||
<linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="35" y1="103.7019" x2="35" y2="32.0424">
|
||||
<stop offset="0" style="stop-color:#FFF33B"/>
|
||||
<stop offset="0" style="stop-color:#FFD53F"/>
|
||||
<stop offset="0" style="stop-color:#FBBC40"/>
|
||||
<stop offset="0" style="stop-color:#F7A840"/>
|
||||
<stop offset="0" style="stop-color:#F59B40"/>
|
||||
<stop offset="0" style="stop-color:#F3933F"/>
|
||||
<stop offset="0" style="stop-color:#F3903F"/>
|
||||
<stop offset="0.8423" style="stop-color:#ED683C"/>
|
||||
<stop offset="1" style="stop-color:#E93E3A"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_7_);" d="M39.001,34.423h-8.002c-0.552,0-0.999,0.447-0.999,0.999V100h10V35.422
|
||||
C40,34.87,39.553,34.423,39.001,34.423z"/>
|
||||
<linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="35" y1="98.9423" x2="35" y2="53.1961">
|
||||
<stop offset="0" style="stop-color:#FEBC11"/>
|
||||
<stop offset="1" style="stop-color:#F99B1C"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_8_);" d="M30,60.895v38.84h10v-38.84"/>
|
||||
<linearGradient id="SVGID_9_" gradientUnits="userSpaceOnUse" x1="35" y1="99.4343" x2="35" y2="74.4359">
|
||||
<stop offset="0" style="stop-color:#FEBC11"/>
|
||||
<stop offset="1" style="stop-color:#FFDE17"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_9_);" d="M30,78.643v21.225h10V78.643"/>
|
||||
</g>
|
||||
<g>
|
||||
<linearGradient id="SVGID_10_" gradientUnits="userSpaceOnUse" x1="50" y1="103.7019" x2="50" y2="32.0424">
|
||||
<stop offset="0" style="stop-color:#FFF33B"/>
|
||||
<stop offset="0" style="stop-color:#FFD53F"/>
|
||||
<stop offset="0" style="stop-color:#FBBC40"/>
|
||||
<stop offset="0" style="stop-color:#F7A840"/>
|
||||
<stop offset="0" style="stop-color:#F59B40"/>
|
||||
<stop offset="0" style="stop-color:#F3933F"/>
|
||||
<stop offset="0" style="stop-color:#F3903F"/>
|
||||
<stop offset="0.8423" style="stop-color:#ED683C"/>
|
||||
<stop offset="1" style="stop-color:#E93E3A"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_10_);" d="M54.001,41.827h-8.002c-0.552,0-0.999,0.447-0.999,0.999V100h10V42.826
|
||||
C55,42.274,54.553,41.827,54.001,41.827z"/>
|
||||
<linearGradient id="SVGID_11_" gradientUnits="userSpaceOnUse" x1="50" y1="98.9423" x2="50" y2="53.1961">
|
||||
<stop offset="0" style="stop-color:#FEBC11"/>
|
||||
<stop offset="1" style="stop-color:#F99B1C"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_11_);" d="M45,65.352v34.383h10V65.352"/>
|
||||
<linearGradient id="SVGID_12_" gradientUnits="userSpaceOnUse" x1="50" y1="99.4343" x2="50" y2="74.4359">
|
||||
<stop offset="0" style="stop-color:#FEBC11"/>
|
||||
<stop offset="1" style="stop-color:#FFDE17"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_12_);" d="M45,81.079v18.789h10V81.079"/>
|
||||
</g>
|
||||
<g>
|
||||
<linearGradient id="SVGID_13_" gradientUnits="userSpaceOnUse" x1="65" y1="103.8575" x2="65" y2="29.1875">
|
||||
<stop offset="0" style="stop-color:#FFF33B"/>
|
||||
<stop offset="0" style="stop-color:#FFD53F"/>
|
||||
<stop offset="0" style="stop-color:#FBBC40"/>
|
||||
<stop offset="0" style="stop-color:#F7A840"/>
|
||||
<stop offset="0" style="stop-color:#F59B40"/>
|
||||
<stop offset="0" style="stop-color:#F3933F"/>
|
||||
<stop offset="0" style="stop-color:#F3903F"/>
|
||||
<stop offset="0.8423" style="stop-color:#ED683C"/>
|
||||
<stop offset="1" style="stop-color:#E93E3A"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_13_);" d="M69.001,50.404h-8.002c-0.552,0-0.999,0.447-0.999,0.999V100h10V51.403
|
||||
C70,50.851,69.553,50.404,69.001,50.404z"/>
|
||||
<linearGradient id="SVGID_14_" gradientUnits="userSpaceOnUse" x1="65" y1="98.8979" x2="65" y2="51.2298">
|
||||
<stop offset="0" style="stop-color:#FEBC11"/>
|
||||
<stop offset="1" style="stop-color:#F99B1C"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_14_);" d="M60,70.531v29.193h10V70.531"/>
|
||||
<linearGradient id="SVGID_15_" gradientUnits="userSpaceOnUse" x1="65" y1="99.4105" x2="65" y2="73.3619">
|
||||
<stop offset="0" style="stop-color:#FEBC11"/>
|
||||
<stop offset="1" style="stop-color:#FFDE17"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_15_);" d="M60,83.909v15.953h10V83.909"/>
|
||||
</g>
|
||||
<g>
|
||||
<linearGradient id="SVGID_16_" gradientUnits="userSpaceOnUse" x1="80" y1="104.4108" x2="80" y2="19.0293">
|
||||
<stop offset="0" style="stop-color:#FFF33B"/>
|
||||
<stop offset="0" style="stop-color:#FFD53F"/>
|
||||
<stop offset="0" style="stop-color:#FBBC40"/>
|
||||
<stop offset="0" style="stop-color:#F7A840"/>
|
||||
<stop offset="0" style="stop-color:#F59B40"/>
|
||||
<stop offset="0" style="stop-color:#F3933F"/>
|
||||
<stop offset="0" style="stop-color:#F3903F"/>
|
||||
<stop offset="0.8423" style="stop-color:#ED683C"/>
|
||||
<stop offset="1" style="stop-color:#E93E3A"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_16_);" d="M84.001,40.769h-8.002c-0.552,0-0.999,0.447-0.999,0.999V100h10V41.768
|
||||
C85,41.216,84.553,40.769,84.001,40.769z"/>
|
||||
<linearGradient id="SVGID_17_" gradientUnits="userSpaceOnUse" x1="80" y1="98.9423" x2="80" y2="53.1961">
|
||||
<stop offset="0" style="stop-color:#FEBC11"/>
|
||||
<stop offset="1" style="stop-color:#F99B1C"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_17_);" d="M75,64.716v35.02h10v-35.02"/>
|
||||
<linearGradient id="SVGID_18_" gradientUnits="userSpaceOnUse" x1="80" y1="99.4343" x2="80" y2="74.4359">
|
||||
<stop offset="0" style="stop-color:#FEBC11"/>
|
||||
<stop offset="1" style="stop-color:#FFDE17"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_18_);" d="M75,80.731v19.137h10V80.731"/>
|
||||
</g>
|
||||
<g>
|
||||
<linearGradient id="SVGID_19_" gradientUnits="userSpaceOnUse" x1="95" y1="103.5838" x2="95" y2="34.2115">
|
||||
<stop offset="0" style="stop-color:#FFF33B"/>
|
||||
<stop offset="0" style="stop-color:#FFD53F"/>
|
||||
<stop offset="0" style="stop-color:#FBBC40"/>
|
||||
<stop offset="0" style="stop-color:#F7A840"/>
|
||||
<stop offset="0" style="stop-color:#F59B40"/>
|
||||
<stop offset="0" style="stop-color:#F3933F"/>
|
||||
<stop offset="0" style="stop-color:#F3903F"/>
|
||||
<stop offset="0.8423" style="stop-color:#ED683C"/>
|
||||
<stop offset="1" style="stop-color:#E93E3A"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_19_);" d="M99.001,21.157h-8.002c-0.552,0-0.999,0.447-0.999,0.999V100h10V22.156
|
||||
C100,21.604,99.553,21.157,99.001,21.157z"/>
|
||||
<linearGradient id="SVGID_20_" gradientUnits="userSpaceOnUse" x1="95" y1="98.9761" x2="95" y2="54.69">
|
||||
<stop offset="0" style="stop-color:#FEBC11"/>
|
||||
<stop offset="1" style="stop-color:#F99B1C"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_20_);" d="M90,52.898v46.846h10V52.898"/>
|
||||
<linearGradient id="SVGID_21_" gradientUnits="userSpaceOnUse" x1="95" y1="99.4524" x2="95" y2="75.2518">
|
||||
<stop offset="0" style="stop-color:#FEBC11"/>
|
||||
<stop offset="1" style="stop-color:#FFDE17"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_21_);" d="M90,74.272v25.6h10v-25.6"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.8 KiB |
21
public/app/plugins/panel/graph2/module.tsx
Normal file
21
public/app/plugins/panel/graph2/module.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { PanelProps } from 'app/features/dashboard/dashgrid/DataPanel';
|
||||
|
||||
export class ReactTestPanel extends PureComponent<PanelProps> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { data } = this.props;
|
||||
let value = 0;
|
||||
|
||||
if (data.length) {
|
||||
value = data[0].value;
|
||||
}
|
||||
|
||||
return <h2>Graph Panel! {value}</h2>;
|
||||
}
|
||||
}
|
||||
|
||||
export { ReactTestPanel as PanelComponent };
|
17
public/app/plugins/panel/graph2/plugin.json
Normal file
17
public/app/plugins/panel/graph2/plugin.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"type": "panel",
|
||||
"name": "React Graph",
|
||||
"id": "graph2",
|
||||
|
||||
"info": {
|
||||
"author": {
|
||||
"name": "Grafana Project",
|
||||
"url": "https://grafana.com"
|
||||
},
|
||||
"logos": {
|
||||
"small": "img/icn-graph-panel.svg",
|
||||
"large": "img/icn-graph-panel.svg"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ export class ReactTestPanel extends PureComponent<PanelProps> {
|
||||
value = data[0].value;
|
||||
}
|
||||
|
||||
return <h2>I am a react value: {value}</h2>;
|
||||
return <h2>Text Panel {value}</h2>;
|
||||
}
|
||||
}
|
||||
|
||||
|
20
public/app/types/plugins.ts
Normal file
20
public/app/types/plugins.ts
Normal file
@ -0,0 +1,20 @@
|
||||
export interface PluginExports {
|
||||
PanelCtrl?;
|
||||
PanelComponent?: any;
|
||||
Datasource?: any;
|
||||
QueryCtrl?: any;
|
||||
ConfigCtrl?: any;
|
||||
AnnotationsQueryCtrl?: any;
|
||||
}
|
||||
|
||||
export interface PanelPlugin {
|
||||
id: string;
|
||||
name: string;
|
||||
meta: any;
|
||||
hideFromList: boolean;
|
||||
module: string;
|
||||
baseUrl: string;
|
||||
info: any;
|
||||
sort: number;
|
||||
exports?: PluginExports;
|
||||
}
|
@ -35,11 +35,20 @@ div.flot-text {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.panel-editor-container__panel {
|
||||
height: 35%;
|
||||
}
|
||||
|
||||
.panel-editor-container__editor {
|
||||
height: 65%;
|
||||
}
|
||||
|
||||
.panel-container {
|
||||
background-color: $panel-bg;
|
||||
border: $panel-border;
|
||||
position: relative;
|
||||
border-radius: 3px;
|
||||
height: 100%;
|
||||
|
||||
&.panel-transparent {
|
||||
background-color: transparent;
|
||||
|
Loading…
Reference in New Issue
Block a user