Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
eae754a0
Unverified
Commit
eae754a0
authored
Nov 06, 2018
by
Torkel Ödegaard
Committed by
GitHub
Nov 06, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #13971 from grafana/react-panel-options
React panel options
parents
a3196a13
562411af
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
192 additions
and
96 deletions
+192
-96
public/app/features/dashboard/dashgrid/PanelChrome.tsx
+23
-2
public/app/features/dashboard/dashgrid/PanelEditor.tsx
+19
-10
public/app/features/dashboard/panel_model.ts
+15
-4
public/app/features/dashboard/settings/settings.ts
+1
-1
public/app/plugins/panel/graph2/module.tsx
+39
-15
public/app/types/index.ts
+2
-1
public/app/types/panel.ts
+8
-1
public/app/types/plugins.ts
+8
-3
public/app/viz/Graph.tsx
+77
-59
No files found.
public/app/features/dashboard/dashgrid/PanelChrome.tsx
View file @
eae754a0
...
...
@@ -21,6 +21,7 @@ export interface Props {
export
interface
State
{
refreshCounter
:
number
;
renderCounter
:
number
;
timeRange
?:
TimeRange
;
}
...
...
@@ -30,11 +31,13 @@ export class PanelChrome extends PureComponent<Props, State> {
this
.
state
=
{
refreshCounter
:
0
,
renderCounter
:
0
,
};
}
componentDidMount
()
{
this
.
props
.
panel
.
events
.
on
(
'refresh'
,
this
.
onRefresh
);
this
.
props
.
panel
.
events
.
on
(
'render'
,
this
.
onRender
);
this
.
props
.
dashboard
.
panelInitialized
(
this
.
props
.
panel
);
}
...
...
@@ -52,6 +55,13 @@ export class PanelChrome extends PureComponent<Props, State> {
});
};
onRender
=
()
=>
{
console
.
log
(
'onRender'
);
this
.
setState
({
renderCounter
:
this
.
state
.
renderCounter
+
1
,
});
};
get
isVisible
()
{
return
!
this
.
props
.
dashboard
.
otherPanelInFullscreen
(
this
.
props
.
panel
);
}
...
...
@@ -59,9 +69,11 @@ export class PanelChrome extends PureComponent<Props, State> {
render
()
{
const
{
panel
,
dashboard
}
=
this
.
props
;
const
{
datasource
,
targets
}
=
panel
;
const
{
refreshCounter
,
timeRange
}
=
this
.
state
;
const
{
timeRange
,
renderCounter
,
refreshCounter
}
=
this
.
state
;
const
PanelComponent
=
this
.
props
.
component
;
console
.
log
(
'Panel chrome render'
);
return
(
<
div
className=
"panel-container"
>
<
PanelHeader
panel=
{
panel
}
dashboard=
{
dashboard
}
/>
...
...
@@ -74,7 +86,16 @@ export class PanelChrome extends PureComponent<Props, State> {
refreshCounter=
{
refreshCounter
}
>
{
({
loading
,
timeSeries
})
=>
{
return
<
PanelComponent
loading=
{
loading
}
timeSeries=
{
timeSeries
}
timeRange=
{
timeRange
}
/>;
console
.
log
(
'panelcrome inner render'
);
return
(
<
PanelComponent
loading=
{
loading
}
timeSeries=
{
timeSeries
}
timeRange=
{
timeRange
}
options=
{
panel
.
getOptions
()
}
renderCounter=
{
renderCounter
}
/>
);
}
}
</
DataPanel
>
</
div
>
...
...
public/app/features/dashboard/dashgrid/PanelEditor.tsx
View file @
eae754a0
import
React
from
'react'
;
import
React
,
{
PureComponent
}
from
'react'
;
import
classNames
from
'classnames'
;
import
{
PanelModel
}
from
'../panel_model'
;
import
{
DashboardModel
}
from
'../dashboard_model'
;
import
{
store
}
from
'app/store/configureStore'
;
import
{
QueriesTab
}
from
'./QueriesTab'
;
import
{
PanelPlugin
,
PluginExports
}
from
'app/types/plugins'
;
import
{
VizTypePicker
}
from
'./VizTypePicker'
;
import
{
store
}
from
'app/store/configureStore'
;
import
{
updateLocation
}
from
'app/core/actions'
;
import
{
PanelModel
}
from
'../panel_model'
;
import
{
DashboardModel
}
from
'../dashboard_model'
;
import
{
PanelPlugin
,
PluginExports
}
from
'app/types/plugins'
;
interface
PanelEditorProps
{
panel
:
PanelModel
;
dashboard
:
DashboardModel
;
...
...
@@ -22,7 +25,7 @@ interface PanelEditorTab {
icon
:
string
;
}
export
class
PanelEditor
extends
React
.
Component
<
PanelEditorProps
,
any
>
{
export
class
PanelEditor
extends
PureComponent
<
PanelEditorProps
>
{
tabs
:
PanelEditorTab
[];
constructor
(
props
)
{
...
...
@@ -39,16 +42,21 @@ export class PanelEditor extends React.Component<PanelEditorProps, any> {
}
renderPanelOptions
()
{
const
{
pluginExports
}
=
this
.
props
;
const
{
pluginExports
,
panel
}
=
this
.
props
;
if
(
pluginExports
.
PanelOptions
)
{
const
PanelOptions
=
pluginExports
.
PanelOptions
;
return
<
PanelOptions
/>;
if
(
pluginExports
.
PanelOptions
Component
)
{
const
OptionsComponent
=
pluginExports
.
PanelOptionsComponent
;
return
<
OptionsComponent
options=
{
panel
.
getOptions
()
}
onChange=
{
this
.
onPanelOptionsChanged
}
/>;
}
else
{
return
<
p
>
Visualization has no options
</
p
>;
}
}
onPanelOptionsChanged
=
(
options
:
any
)
=>
{
this
.
props
.
panel
.
updateOptions
(
options
);
this
.
forceUpdate
();
};
renderVizTab
()
{
return
(
<
div
className=
"viz-editor"
>
...
...
@@ -70,6 +78,7 @@ export class PanelEditor extends React.Component<PanelEditorProps, any> {
partial
:
true
,
})
);
this
.
forceUpdate
();
};
render
()
{
...
...
public/app/features/dashboard/panel_model.ts
View file @
eae754a0
...
...
@@ -60,6 +60,21 @@ export class PanelModel {
_
.
defaultsDeep
(
this
,
_
.
cloneDeep
(
defaults
));
}
getOptions
()
{
return
this
[
this
.
getOptionsKey
()]
||
{};
}
updateOptions
(
options
:
object
)
{
const
update
:
any
=
{};
update
[
this
.
getOptionsKey
()]
=
options
;
Object
.
assign
(
this
,
update
);
this
.
render
();
}
private
getOptionsKey
()
{
return
this
.
type
+
'Options'
;
}
getSaveModel
()
{
const
model
:
any
=
{};
for
(
const
property
in
this
)
{
...
...
@@ -121,10 +136,6 @@ export class PanelModel {
this
.
events
.
emit
(
'panel-initialized'
);
}
initEditMode
()
{
this
.
events
.
emit
(
'panel-init-edit-mode'
);
}
changeType
(
pluginId
:
string
)
{
this
.
type
=
pluginId
;
...
...
public/app/features/dashboard/settings/settings.ts
View file @
eae754a0
...
...
@@ -32,9 +32,9 @@ export class SettingsCtrl {
this
.
$scope
.
$on
(
'$destroy'
,
()
=>
{
this
.
dashboard
.
updateSubmenuVisibility
();
this
.
dashboard
.
startRefresh
();
setTimeout
(()
=>
{
this
.
$rootScope
.
appEvent
(
'dash-scroll'
,
{
restore
:
true
});
this
.
dashboard
.
startRefresh
();
});
});
...
...
public/app/plugins/panel/graph2/module.tsx
View file @
eae754a0
// Libraries
import
_
from
'lodash'
;
import
React
,
{
PureComponent
}
from
'react'
;
// Components
import
Graph
from
'app/viz/Graph'
;
import
{
getTimeSeriesVMs
}
from
'app/viz/state/timeSeries'
;
import
{
Switch
}
from
'app/core/components/Switch/Switch'
;
// Types
import
{
PanelProps
,
NullValueMode
}
from
'app/types'
;
import
{
getTimeSeriesVMs
}
from
'app/viz/state/timeSeries'
;
import
{
PanelProps
,
PanelOptionsProps
,
NullValueMode
}
from
'app/types'
;
interface
Options
{
showBars
:
boolean
;
}
showLines
:
boolean
;
showPoints
:
boolean
;
interface
Props
extends
PanelProps
{
options
:
Options
;
onChange
:
(
options
:
Options
)
=>
void
;
}
interface
Props
extends
PanelProps
<
Options
>
{}
export
class
Graph2
extends
PureComponent
<
Props
>
{
constructor
(
props
)
{
super
(
props
);
...
...
@@ -25,27 +24,52 @@ export class Graph2 extends PureComponent<Props> {
render
()
{
const
{
timeSeries
,
timeRange
}
=
this
.
props
;
const
{
showLines
,
showBars
,
showPoints
}
=
this
.
props
.
options
;
const
vmSeries
=
getTimeSeriesVMs
({
timeSeries
:
timeSeries
,
nullValueMode
:
NullValueMode
.
Ignore
,
});
return
<
Graph
timeSeries=
{
vmSeries
}
timeRange=
{
timeRange
}
/>;
return
(
<
Graph
timeSeries=
{
vmSeries
}
timeRange=
{
timeRange
}
showLines=
{
showLines
}
showPoints=
{
showPoints
}
showBars=
{
showBars
}
/>
);
}
}
export
class
TextOptions
extends
PureComponent
<
any
>
{
onChange
=
()
=>
{};
export
class
GraphOptions
extends
PureComponent
<
PanelOptionsProps
<
Options
>>
{
onToggleLines
=
()
=>
{
this
.
props
.
onChange
({
...
this
.
props
.
options
,
showLines
:
!
this
.
props
.
options
.
showLines
});
};
onToggleBars
=
()
=>
{
this
.
props
.
onChange
({
...
this
.
props
.
options
,
showBars
:
!
this
.
props
.
options
.
showBars
});
};
onTogglePoints
=
()
=>
{
this
.
props
.
onChange
({
...
this
.
props
.
options
,
showPoints
:
!
this
.
props
.
options
.
showPoints
});
};
render
()
{
const
{
showBars
,
showPoints
,
showLines
}
=
this
.
props
.
options
;
return
(
<
div
className=
"section gf-form-group"
>
<
h5
className=
"section-heading"
>
Draw Modes
</
h5
>
<
Switch
label=
"Lines"
checked=
{
true
}
onChange=
{
this
.
onChange
}
/>
<
div
>
<
div
className=
"section gf-form-group"
>
<
h5
className=
"page-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
>
);
}
}
export
{
Graph2
as
PanelComponent
,
TextOptions
as
PanelOptions
};
export
{
Graph2
as
PanelComponent
,
GraphOptions
as
PanelOptionsComponent
};
public/app/types/index.ts
View file @
eae754a0
...
...
@@ -20,7 +20,7 @@ import {
DataQueryResponse
,
DataQueryOptions
,
}
from
'./series'
;
import
{
PanelProps
}
from
'./panel'
;
import
{
PanelProps
,
PanelOptionsProps
}
from
'./panel'
;
import
{
PluginDashboard
,
PluginMeta
,
Plugin
,
PluginsState
}
from
'./plugins'
;
import
{
Organization
,
OrganizationPreferences
,
OrganizationState
}
from
'./organization'
;
import
{
...
...
@@ -69,6 +69,7 @@ export {
TimeRange
,
LoadingState
,
PanelProps
,
PanelOptionsProps
,
TimeSeries
,
TimeSeriesVM
,
TimeSeriesVMs
,
...
...
public/app/types/panel.ts
View file @
eae754a0
import
{
LoadingState
,
TimeSeries
,
TimeRange
}
from
'./series'
;
export
interface
PanelProps
{
export
interface
PanelProps
<
T
=
any
>
{
timeSeries
:
TimeSeries
[];
timeRange
:
TimeRange
;
loading
:
LoadingState
;
options
:
T
;
renderCounter
:
number
;
}
export
interface
PanelOptionsProps
<
T
=
any
>
{
options
:
T
;
onChange
:
(
options
:
T
)
=>
void
;
}
public/app/types/plugins.ts
View file @
eae754a0
import
{
ComponentClass
}
from
'react'
;
import
{
PanelProps
,
PanelOptionsProps
}
from
'./panel'
;
export
interface
PluginExports
{
PanelCtrl
?;
PanelComponent
?:
any
;
Datasource
?:
any
;
QueryCtrl
?:
any
;
ConfigCtrl
?:
any
;
AnnotationsQueryCtrl
?:
any
;
PanelOptions
?:
any
;
ExploreQueryField
?:
any
;
ExploreStartPage
?:
any
;
// Panel plugin
PanelCtrl
?;
PanelComponent
?:
ComponentClass
<
PanelProps
>
;
PanelOptionsComponent
:
ComponentClass
<
PanelOptionsProps
>
;
}
export
interface
PanelPlugin
{
...
...
public/app/viz/Graph.tsx
View file @
eae754a0
...
...
@@ -8,63 +8,22 @@ import 'vendor/flot/jquery.flot.time';
// Types
import
{
TimeRange
,
TimeSeriesVMs
}
from
'app/types'
;
// Copied from graph.ts
function
time_format
(
ticks
,
min
,
max
)
{
if
(
min
&&
max
&&
ticks
)
{
const
range
=
max
-
min
;
const
secPerTick
=
range
/
ticks
/
1000
;
const
oneDay
=
86400000
;
const
oneYear
=
31536000000
;
if
(
secPerTick
<=
45
)
{
return
'%H:%M:%S'
;
}
if
(
secPerTick
<=
7200
||
range
<=
oneDay
)
{
return
'%H:%M'
;
}
if
(
secPerTick
<=
80000
)
{
return
'%m/%d %H:%M'
;
}
if
(
secPerTick
<=
2419200
||
range
<=
oneYear
)
{
return
'%m/%d'
;
}
return
'%Y-%m'
;
}
return
'%H:%M'
;
}
const
FLOT_OPTIONS
=
{
legend
:
{
show
:
false
,
},
series
:
{
lines
:
{
linewidth
:
1
,
zero
:
false
,
},
shadowSize
:
0
,
},
grid
:
{
minBorderMargin
:
0
,
markings
:
[],
backgroundColor
:
null
,
borderWidth
:
0
,
// hoverable: true,
clickable
:
true
,
color
:
'#a1a1a1'
,
margin
:
{
left
:
0
,
right
:
0
},
labelMarginX
:
0
,
},
};
interface
GraphProps
{
timeSeries
:
TimeSeriesVMs
;
timeRange
:
TimeRange
;
showLines
?:
boolean
;
showPoints
?:
boolean
;
showBars
?:
boolean
;
size
?:
{
width
:
number
;
height
:
number
};
}
export
class
Graph
extends
PureComponent
<
GraphProps
>
{
static
defaultProps
=
{
showLines
:
true
,
showPoints
:
false
,
showBars
:
false
,
};
element
:
any
;
componentDidUpdate
(
prevProps
:
GraphProps
)
{
...
...
@@ -82,7 +41,7 @@ export class Graph extends PureComponent<GraphProps> {
}
draw
()
{
const
{
size
,
timeSeries
,
timeRange
}
=
this
.
props
;
const
{
size
,
timeSeries
,
timeRange
,
showLines
,
showBars
,
showPoints
}
=
this
.
props
;
if
(
!
size
)
{
return
;
...
...
@@ -92,7 +51,31 @@ export class Graph extends PureComponent<GraphProps> {
const
min
=
timeRange
.
from
.
valueOf
();
const
max
=
timeRange
.
to
.
valueOf
();
const
dynamicOptions
=
{
const
flotOptions
=
{
legend
:
{
show
:
false
,
},
series
:
{
lines
:
{
show
:
showLines
,
linewidth
:
1
,
zero
:
false
,
},
points
:
{
show
:
showPoints
,
fill
:
1
,
fillColor
:
false
,
radius
:
2
,
},
bars
:
{
show
:
showBars
,
fill
:
1
,
barWidth
:
1
,
zero
:
false
,
lineWidth
:
0
,
},
shadowSize
:
0
,
},
xaxis
:
{
mode
:
'time'
,
min
:
min
,
...
...
@@ -101,15 +84,24 @@ export class Graph extends PureComponent<GraphProps> {
ticks
:
ticks
,
timeformat
:
time_format
(
ticks
,
min
,
max
),
},
grid
:
{
minBorderMargin
:
0
,
markings
:
[],
backgroundColor
:
null
,
borderWidth
:
0
,
// hoverable: true,
clickable
:
true
,
color
:
'#a1a1a1'
,
margin
:
{
left
:
0
,
right
:
0
},
labelMarginX
:
0
,
},
};
const
options
=
{
...
FLOT_OPTIONS
,
...
dynamicOptions
,
};
console
.
log
(
'plot'
,
timeSeries
,
options
);
$
.
plot
(
this
.
element
,
timeSeries
,
options
);
try
{
$
.
plot
(
this
.
element
,
timeSeries
,
flotOptions
);
}
catch
(
err
)
{
console
.
log
(
'Graph rendering error'
,
err
,
flotOptions
,
timeSeries
);
}
}
render
()
{
...
...
@@ -121,4 +113,30 @@ export class Graph extends PureComponent<GraphProps> {
}
}
// Copied from graph.ts
function
time_format
(
ticks
,
min
,
max
)
{
if
(
min
&&
max
&&
ticks
)
{
const
range
=
max
-
min
;
const
secPerTick
=
range
/
ticks
/
1000
;
const
oneDay
=
86400000
;
const
oneYear
=
31536000000
;
if
(
secPerTick
<=
45
)
{
return
'%H:%M:%S'
;
}
if
(
secPerTick
<=
7200
||
range
<=
oneDay
)
{
return
'%H:%M'
;
}
if
(
secPerTick
<=
80000
)
{
return
'%m/%d %H:%M'
;
}
if
(
secPerTick
<=
2419200
||
range
<=
oneYear
)
{
return
'%m/%d'
;
}
return
'%Y-%m'
;
}
return
'%H:%M'
;
}
export
default
withSize
()(
Graph
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment