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
aeaac748
Commit
aeaac748
authored
Feb 01, 2019
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New solo panel route working in all scenarios I can test
parent
c4f55fec
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
58 additions
and
218 deletions
+58
-218
public/app/core/profiler.ts
+1
-102
public/app/features/dashboard/containers/SoloPanelPage.tsx
+30
-8
public/app/features/dashboard/dashgrid/DataPanel.tsx
+0
-3
public/app/features/dashboard/dashgrid/PanelChrome.tsx
+8
-1
public/app/features/panel/all.ts
+0
-1
public/app/features/panel/metrics_panel_ctrl.ts
+0
-11
public/app/features/panel/panel_ctrl.ts
+6
-19
public/app/features/panel/panel_directive.ts
+8
-6
public/app/features/panel/partials/soloPanel.html
+0
-4
public/app/features/panel/solo_panel_ctrl.ts
+0
-58
public/app/plugins/panel/table/module.ts
+0
-1
public/app/routes/routes.ts
+5
-4
No files found.
public/app/core/profiler.ts
View file @
aeaac748
import
$
from
'jquery'
;
import
angular
from
'angular'
;
export
class
Profiler
{
panelsRendered
:
number
;
enabled
:
boolean
;
panelsInitCount
:
any
;
timings
:
any
;
digestCounter
:
any
;
$rootScope
:
any
;
scopeCount
:
any
;
window
:
any
;
init
(
config
,
$rootScope
)
{
this
.
enabled
=
config
.
buildInfo
.
env
===
'development'
;
this
.
timings
=
{};
this
.
timings
.
appStart
=
{
loadStart
:
new
Date
().
getTime
()
};
this
.
$rootScope
=
$rootScope
;
this
.
window
=
window
;
if
(
!
this
.
enabled
)
{
return
;
}
$rootScope
.
$watch
(
()
=>
{
this
.
digestCounter
++
;
return
false
;
},
()
=>
{}
);
$rootScope
.
onAppEvent
(
'refresh'
,
this
.
refresh
.
bind
(
this
),
$rootScope
);
$rootScope
.
onAppEvent
(
'dashboard-fetch-end'
,
this
.
dashboardFetched
.
bind
(
this
),
$rootScope
);
$rootScope
.
onAppEvent
(
'dashboard-initialized'
,
this
.
dashboardInitialized
.
bind
(
this
),
$rootScope
);
$rootScope
.
onAppEvent
(
'panel-initialized'
,
this
.
panelInitialized
.
bind
(
this
),
$rootScope
);
}
refresh
()
{
this
.
timings
.
query
=
0
;
this
.
timings
.
render
=
0
;
setTimeout
(()
=>
{
console
.
log
(
'panel count: '
+
this
.
panelsInitCount
);
console
.
log
(
'total query: '
+
this
.
timings
.
query
);
console
.
log
(
'total render: '
+
this
.
timings
.
render
);
console
.
log
(
'avg render: '
+
this
.
timings
.
render
/
this
.
panelsInitCount
);
},
5000
);
}
dashboardFetched
()
{
this
.
timings
.
dashboardLoadStart
=
new
Date
().
getTime
();
this
.
panelsInitCount
=
0
;
this
.
digestCounter
=
0
;
this
.
panelsInitCount
=
0
;
this
.
panelsRendered
=
0
;
this
.
timings
.
query
=
0
;
this
.
timings
.
render
=
0
;
}
dashboardInitialized
()
{
setTimeout
(()
=>
{
console
.
log
(
'Dashboard::Performance Total Digests: '
+
this
.
digestCounter
);
console
.
log
(
'Dashboard::Performance Total Watchers: '
+
this
.
getTotalWatcherCount
());
console
.
log
(
'Dashboard::Performance Total ScopeCount: '
+
this
.
scopeCount
);
const
timeTaken
=
this
.
timings
.
lastPanelInitializedAt
-
this
.
timings
.
dashboardLoadStart
;
console
.
log
(
'Dashboard::Performance All panels initialized in '
+
timeTaken
+
' ms'
);
// measure digest performance
const
rootDigestStart
=
window
.
performance
.
now
();
for
(
let
i
=
0
;
i
<
30
;
i
++
)
{
this
.
$rootScope
.
$apply
();
}
console
.
log
(
'Dashboard::Performance Root Digest '
+
(
window
.
performance
.
now
()
-
rootDigestStart
)
/
30
);
},
3000
);
}
getTotalWatcherCount
()
{
let
count
=
0
;
let
scopes
=
0
;
const
root
=
$
(
document
.
getElementsByTagName
(
'body'
));
const
f
=
element
=>
{
if
(
element
.
data
().
hasOwnProperty
(
'$scope'
))
{
scopes
++
;
angular
.
forEach
(
element
.
data
().
$scope
.
$$watchers
,
()
=>
{
count
++
;
});
}
angular
.
forEach
(
element
.
children
(),
childElement
=>
{
f
(
$
(
childElement
));
});
};
f
(
root
);
this
.
scopeCount
=
scopes
;
return
count
;
}
renderingCompleted
(
panelId
,
panelTimings
)
{
renderingCompleted
(
panelId
)
{
// add render counter to root scope
// used by phantomjs render.js to know when panel has rendered
this
.
panelsRendered
=
(
this
.
panelsRendered
||
0
)
+
1
;
...
...
@@ -108,21 +22,6 @@ export class Profiler {
// this window variable is used by backend rendering tools to know
// all panels have completed rendering
this
.
window
.
panelsRendered
=
this
.
panelsRendered
;
if
(
this
.
enabled
)
{
panelTimings
.
renderEnd
=
new
Date
().
getTime
();
this
.
timings
.
query
+=
panelTimings
.
queryEnd
-
panelTimings
.
queryStart
;
this
.
timings
.
render
+=
panelTimings
.
renderEnd
-
panelTimings
.
renderStart
;
}
}
panelInitialized
()
{
if
(
!
this
.
enabled
)
{
return
;
}
this
.
panelsInitCount
++
;
this
.
timings
.
lastPanelInitializedAt
=
new
Date
().
getTime
();
}
}
...
...
public/app/features/dashboard/containers/SoloPanelPage.tsx
View file @
aeaac748
...
...
@@ -5,21 +5,27 @@ import { connect } from 'react-redux';
// Utils & Services
import
appEvents
from
'app/core/app_events'
;
import
locationUtil
from
'app/core/utils/location_util'
;
import
{
getBackendSrv
}
from
'app/core/services/backend_srv'
;
// Components
import
{
DashboardPanel
}
from
'../dashgrid/DashboardPanel'
;
// Redux
import
{
updateLocation
}
from
'app/core/actions'
;
// Types
import
{
StoreState
}
from
'app/types'
;
import
{
PanelModel
,
DashboardModel
}
from
'app/features/dashboard/state'
;
interface
Props
{
panelId
:
string
;
uid
?:
string
;
s
lug
?:
string
;
t
ype
?:
string
;
u
rlU
id
?:
string
;
urlS
lug
?:
string
;
urlT
ype
?:
string
;
$scope
:
any
;
$injector
:
any
;
updateLocation
:
typeof
updateLocation
;
}
interface
State
{
...
...
@@ -37,19 +43,34 @@ export class SoloPanelPage extends Component<Props, State> {
};
componentDidMount
()
{
const
{
$injector
,
$scope
,
uid
}
=
this
.
props
;
const
{
$injector
,
$scope
,
urlUid
,
urlType
,
urlSlug
}
=
this
.
props
;
// handle old urls with no uid
if
(
!
urlUid
&&
!
(
urlType
===
'script'
||
urlType
===
'snapshot'
))
{
this
.
redirectToNewUrl
();
return
;
}
const
dashboardLoaderSrv
=
$injector
.
get
(
'dashboardLoaderSrv'
);
// subscribe to event to know when dashboard controller is done with inititalization
appEvents
.
on
(
'dashboard-initialized'
,
this
.
onDashoardInitialized
);
dashboardLoaderSrv
.
loadDashboard
(
''
,
''
,
u
id
).
then
(
result
=>
{
dashboardLoaderSrv
.
loadDashboard
(
urlType
,
urlSlug
,
urlU
id
).
then
(
result
=>
{
result
.
meta
.
soloMode
=
true
;
$scope
.
initDashboard
(
result
,
$scope
);
});
}
redirectToNewUrl
()
{
getBackendSrv
().
getDashboardBySlug
(
this
.
props
.
urlSlug
).
then
(
res
=>
{
if
(
res
)
{
const
url
=
locationUtil
.
stripBaseFromUrl
(
res
.
meta
.
url
.
replace
(
'/d/'
,
'/d-solo/'
));
this
.
props
.
updateLocation
(
url
);
}
});
}
onDashoardInitialized
=
()
=>
{
const
{
$scope
,
panelId
}
=
this
.
props
;
...
...
@@ -89,13 +110,14 @@ export class SoloPanelPage extends Component<Props, State> {
}
const
mapStateToProps
=
(
state
:
StoreState
)
=>
({
uid
:
state
.
location
.
routeParams
.
uid
,
s
lug
:
state
.
location
.
routeParams
.
slug
,
t
ype
:
state
.
location
.
routeParams
.
type
,
u
rlU
id
:
state
.
location
.
routeParams
.
uid
,
urlS
lug
:
state
.
location
.
routeParams
.
slug
,
urlT
ype
:
state
.
location
.
routeParams
.
type
,
panelId
:
state
.
location
.
query
.
panelId
});
const
mapDispatchToProps
=
{
updateLocation
};
export
default
hot
(
module
)(
connect
(
mapStateToProps
,
mapDispatchToProps
)(
SoloPanelPage
));
public/app/features/dashboard/dashgrid/DataPanel.tsx
View file @
aeaac748
...
...
@@ -135,11 +135,8 @@ export class DataPanel extends Component<Props, State> {
cacheTimeout
:
null
,
};
console
.
log
(
'Issuing DataPanel query'
,
queryOptions
);
const
resp
=
await
ds
.
query
(
queryOptions
);
console
.
log
(
'Issuing DataPanel query Resp'
,
resp
);
if
(
this
.
isUnmounted
)
{
return
;
}
...
...
public/app/features/dashboard/dashgrid/PanelChrome.tsx
View file @
aeaac748
...
...
@@ -12,11 +12,12 @@ import { DataPanel } from './DataPanel';
// Utils
import
{
applyPanelTimeOverrides
}
from
'app/features/dashboard/utils/panel'
;
import
{
PANEL_HEADER_HEIGHT
}
from
'app/core/constants'
;
import
{
profiler
}
from
'app/core/profiler'
;
// Types
import
{
DashboardModel
,
PanelModel
}
from
'../state'
;
import
{
PanelPlugin
}
from
'app/types'
;
import
{
TimeRange
}
from
'@grafana/ui'
;
import
{
TimeRange
,
LoadingState
}
from
'@grafana/ui'
;
import
variables
from
'sass/_variables.scss'
;
import
templateSrv
from
'app/features/templating/template_srv'
;
...
...
@@ -98,6 +99,12 @@ export class PanelChrome extends PureComponent<Props, State> {
const
{
timeRange
,
renderCounter
}
=
this
.
state
;
const
PanelComponent
=
plugin
.
exports
.
Panel
;
// This is only done to increase a counter that is used by backend
// image rendering (phantomjs/headless chrome) to know when to capture image
if
(
loading
===
LoadingState
.
Done
)
{
profiler
.
renderingCompleted
(
panel
.
id
);
}
return
(
<
div
className=
"panel-content"
>
<
PanelComponent
...
...
public/app/features/panel/all.ts
View file @
aeaac748
import
'./panel_header'
;
import
'./panel_directive'
;
import
'./solo_panel_ctrl'
;
import
'./query_ctrl'
;
import
'./panel_editor_tab'
;
import
'./query_editor_row'
;
...
...
public/app/features/panel/metrics_panel_ctrl.ts
View file @
aeaac748
...
...
@@ -16,7 +16,6 @@ class MetricsPanelCtrl extends PanelCtrl {
datasourceSrv
:
any
;
timeSrv
:
any
;
templateSrv
:
any
;
timing
:
any
;
range
:
any
;
interval
:
any
;
intervalMs
:
any
;
...
...
@@ -81,7 +80,6 @@ class MetricsPanelCtrl extends PanelCtrl {
this
.
loading
=
true
;
// load datasource service
this
.
setTimeQueryStart
();
this
.
datasourceSrv
.
get
(
this
.
panel
.
datasource
)
.
then
(
this
.
updateTimeRange
.
bind
(
this
))
...
...
@@ -112,14 +110,6 @@ class MetricsPanelCtrl extends PanelCtrl {
});
}
setTimeQueryStart
()
{
this
.
timing
.
queryStart
=
new
Date
().
getTime
();
}
setTimeQueryEnd
()
{
this
.
timing
.
queryEnd
=
new
Date
().
getTime
();
}
updateTimeRange
(
datasource
?)
{
this
.
datasource
=
datasource
||
this
.
datasource
;
this
.
range
=
this
.
timeSrv
.
timeRange
();
...
...
@@ -181,7 +171,6 @@ class MetricsPanelCtrl extends PanelCtrl {
}
handleQueryResult
(
result
)
{
this
.
setTimeQueryEnd
();
this
.
loading
=
false
;
// check for if data source returns subject
...
...
public/app/features/panel/panel_ctrl.ts
View file @
aeaac748
import
_
from
'lodash'
;
import
$
from
'jquery'
;
import
Remarkable
from
'remarkable'
;
import
config
from
'app/core/config'
;
...
...
@@ -13,7 +12,7 @@ import {
sharePanel
as
sharePanelUtil
,
}
from
'app/features/dashboard/utils/panel'
;
import
{
GRID_C
ELL_HEIGHT
,
GRID_CELL_VMARGIN
,
GRID_C
OLUMN_COUNT
,
PANEL_HEADER_HEIGHT
,
PANEL_BORDER
}
from
'app/core/constants'
;
import
{
GRID_COLUMN_COUNT
,
PANEL_HEADER_HEIGHT
,
PANEL_BORDER
}
from
'app/core/constants'
;
export
class
PanelCtrl
{
panel
:
any
;
...
...
@@ -31,8 +30,8 @@ export class PanelCtrl {
height
:
any
;
containerHeight
:
any
;
events
:
Emitter
;
timing
:
any
;
loading
:
boolean
;
timing
:
any
;
maxPanelsPerRowOptions
:
number
[];
constructor
(
$scope
,
$injector
)
{
...
...
@@ -42,7 +41,7 @@ export class PanelCtrl {
this
.
$timeout
=
$injector
.
get
(
'$timeout'
);
this
.
editorTabs
=
[];
this
.
events
=
this
.
panel
.
events
;
this
.
timing
=
{};
this
.
timing
=
{};
// not used but here to not break plugins
const
plugin
=
config
.
panels
[
this
.
panel
.
type
];
if
(
plugin
)
{
...
...
@@ -59,7 +58,7 @@ export class PanelCtrl {
}
renderingCompleted
()
{
profiler
.
renderingCompleted
(
this
.
panel
.
id
,
this
.
timing
);
profiler
.
renderingCompleted
(
this
.
panel
.
id
);
}
refresh
()
{
...
...
@@ -200,24 +199,12 @@ export class PanelCtrl {
return
this
.
dashboard
.
meta
.
fullscreen
&&
!
this
.
panel
.
fullscreen
;
}
calculatePanelHeight
()
{
if
(
this
.
panel
.
isEditing
)
{
this
.
containerHeight
=
$
(
'.panel-wrapper--edit'
).
height
();
}
else
if
(
this
.
panel
.
fullscreen
)
{
this
.
containerHeight
=
$
(
'.panel-wrapper--view'
).
height
();
}
else
{
this
.
containerHeight
=
this
.
panel
.
gridPos
.
h
*
GRID_CELL_HEIGHT
+
(
this
.
panel
.
gridPos
.
h
-
1
)
*
GRID_CELL_VMARGIN
;
}
if
(
this
.
panel
.
soloMode
)
{
this
.
containerHeight
=
$
(
window
).
height
();
}
calculatePanelHeight
(
containerHeight
)
{
this
.
containerHeight
=
containerHeight
;
this
.
height
=
this
.
containerHeight
-
(
PANEL_BORDER
+
PANEL_HEADER_HEIGHT
);
}
render
(
payload
?)
{
this
.
timing
.
renderStart
=
new
Date
().
getTime
();
this
.
events
.
emit
(
'render'
,
payload
);
}
...
...
public/app/features/panel/panel_directive.ts
View file @
aeaac748
...
...
@@ -101,7 +101,7 @@ module.directive('grafanaPanel', ($rootScope, $document, $timeout) => {
});
ctrl
.
events
.
on
(
'panel-size-changed'
,
()
=>
{
ctrl
.
calculatePanelHeight
();
ctrl
.
calculatePanelHeight
(
panelContainer
[
0
].
offsetHeight
);
$timeout
(()
=>
{
resizeScrollableContent
();
ctrl
.
render
();
...
...
@@ -112,19 +112,21 @@ module.directive('grafanaPanel', ($rootScope, $document, $timeout) => {
// first wait one pass for dashboard fullscreen view mode to take effect (classses being applied)
setTimeout
(()
=>
{
// then recalc style
ctrl
.
calculatePanelHeight
();
ctrl
.
calculatePanelHeight
(
panelContainer
[
0
].
offsetHeight
);
// then wait another cycle (this might not be needed)
$timeout
(()
=>
{
ctrl
.
render
();
resizeScrollableContent
();
});
});
}
,
10
);
});
// set initial height
ctrl
.
calculatePanelHeight
();
ctrl
.
events
.
on
(
'render'
,
()
=>
{
// set initial height
if
(
!
ctrl
.
height
)
{
ctrl
.
calculatePanelHeight
(
panelContainer
[
0
].
offsetHeight
);
}
if
(
transparentLastState
!==
ctrl
.
panel
.
transparent
)
{
panelContainer
.
toggleClass
(
'panel-transparent'
,
ctrl
.
panel
.
transparent
===
true
);
transparentLastState
=
ctrl
.
panel
.
transparent
;
...
...
public/app/features/panel/partials/soloPanel.html
deleted
100644 → 0
View file @
c4f55fec
<div
class=
"panel-solo"
ng-if=
"panel"
>
<plugin-component
type=
"panel"
>
</plugin-component>
</div>
public/app/features/panel/solo_panel_ctrl.ts
deleted
100644 → 0
View file @
c4f55fec
import
angular
from
'angular'
;
import
locationUtil
from
'app/core/utils/location_util'
;
import
appEvents
from
'app/core/app_events'
;
export
class
SoloPanelCtrl
{
/** @ngInject */
constructor
(
$scope
,
$routeParams
,
$location
,
dashboardLoaderSrv
,
contextSrv
,
backendSrv
)
{
let
panelId
;
$scope
.
init
=
()
=>
{
contextSrv
.
sidemenu
=
false
;
appEvents
.
emit
(
'toggle-sidemenu-hidden'
);
const
params
=
$location
.
search
();
panelId
=
parseInt
(
params
.
panelId
,
10
);
appEvents
.
on
(
'dashboard-initialized'
,
$scope
.
initPanelScope
);
// if no uid, redirect to new route based on slug
if
(
!
(
$routeParams
.
type
===
'script'
||
$routeParams
.
type
===
'snapshot'
)
&&
!
$routeParams
.
uid
)
{
backendSrv
.
getDashboardBySlug
(
$routeParams
.
slug
).
then
(
res
=>
{
if
(
res
)
{
const
url
=
locationUtil
.
stripBaseFromUrl
(
res
.
meta
.
url
.
replace
(
'/d/'
,
'/d-solo/'
));
$location
.
path
(
url
).
replace
();
}
});
return
;
}
dashboardLoaderSrv
.
loadDashboard
(
$routeParams
.
type
,
$routeParams
.
slug
,
$routeParams
.
uid
).
then
(
result
=>
{
result
.
meta
.
soloMode
=
true
;
$scope
.
initDashboard
(
result
,
$scope
);
});
};
$scope
.
initPanelScope
=
()
=>
{
const
panelInfo
=
$scope
.
dashboard
.
getPanelInfoById
(
panelId
);
// fake row ctrl scope
$scope
.
ctrl
=
{
dashboard
:
$scope
.
dashboard
,
};
$scope
.
panel
=
panelInfo
.
panel
;
$scope
.
panel
.
soloMode
=
true
;
$scope
.
$index
=
0
;
if
(
!
$scope
.
panel
)
{
$scope
.
appEvent
(
'alert-error'
,
[
'Panel not found'
,
''
]);
return
;
}
};
$scope
.
init
();
}
}
angular
.
module
(
'grafana.routes'
).
controller
(
'SoloPanelCtrl'
,
SoloPanelCtrl
);
public/app/plugins/panel/table/module.ts
View file @
aeaac748
...
...
@@ -80,7 +80,6 @@ class TablePanelCtrl extends MetricsPanelCtrl {
this
.
pageIndex
=
0
;
if
(
this
.
panel
.
transform
===
'annotations'
)
{
this
.
setTimeQueryStart
();
return
this
.
annotationsSrv
.
getAnnotations
({
dashboard
:
this
.
dashboard
,
...
...
public/app/routes/routes.ts
View file @
aeaac748
...
...
@@ -59,10 +59,11 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
},
})
.
when
(
'/dashboard-solo/:type/:slug'
,
{
templateUrl
:
'public/app/features/panel/partials/soloPanel.html'
,
controller
:
'SoloPanelCtrl'
,
reloadOnSearch
:
false
,
pageClass
:
'page-dashboard'
,
template
:
'<react-container />'
,
pageClass
:
'dashboard-solo'
,
resolve
:
{
component
:
()
=>
SoloPanelPage
,
},
})
.
when
(
'/dashboard/new'
,
{
templateUrl
:
'public/app/partials/dashboard.html'
,
...
...
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