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
23246605
Commit
23246605
authored
Sep 22, 2016
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(graph panel): working on adding non time series support to graph panel
parent
f3d4a97f
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
250 additions
and
140 deletions
+250
-140
public/app/core/core.ts
+2
-0
public/app/core/directives/metric_segment.js
+11
-3
public/app/core/utils/colors.ts
+12
-0
public/app/plugins/panel/graph/axes_edit_tab.ts
+25
-0
public/app/plugins/panel/graph/data_processor.ts
+164
-0
public/app/plugins/panel/graph/module.ts
+32
-129
public/app/plugins/panel/graph/tab_axes.html
+4
-8
No files found.
public/app/core/core.ts
View file @
23246605
...
...
@@ -41,6 +41,7 @@ import 'app/core/routes/routes';
import
'./filters/filters'
;
import
coreModule
from
'./core_module'
;
import
appEvents
from
'./app_events'
;
import
colors
from
'./utils/colors'
;
export
{
...
...
@@ -60,4 +61,5 @@ export {
dashboardSelector
,
queryPartEditorDirective
,
WizardFlow
,
colors
,
};
public/app/core/directives/metric_segment.js
View file @
23246605
...
...
@@ -170,6 +170,7 @@ function (_, $, coreModule) {
},
link
:
{
pre
:
function
postLink
(
$scope
,
elem
,
attrs
)
{
var
cachedOptions
;
$scope
.
valueToSegment
=
function
(
value
)
{
var
option
=
_
.
find
(
$scope
.
options
,
{
value
:
value
});
...
...
@@ -189,13 +190,20 @@ function (_, $, coreModule) {
});
return
$q
.
when
(
optionSegments
);
}
else
{
return
$scope
.
getOptions
();
return
$scope
.
getOptions
().
then
(
function
(
options
)
{
cachedOptions
=
options
;
return
_
.
map
(
options
,
function
(
option
)
{
return
uiSegmentSrv
.
newSegment
({
value
:
option
.
text
});
});
});
}
};
$scope
.
onSegmentChange
=
function
()
{
if
(
$scope
.
options
)
{
var
option
=
_
.
find
(
$scope
.
options
,
{
text
:
$scope
.
segment
.
value
});
var
options
=
$scope
.
options
||
cachedOptions
;
if
(
options
)
{
var
option
=
_
.
find
(
options
,
{
text
:
$scope
.
segment
.
value
});
if
(
option
&&
option
.
value
!==
$scope
.
property
)
{
$scope
.
property
=
option
.
value
;
}
else
if
(
attrs
.
custom
!==
'false'
)
{
...
...
public/app/core/utils/colors.ts
0 → 100644
View file @
23246605
export
default
[
"#7EB26D"
,
"#EAB839"
,
"#6ED0E0"
,
"#EF843C"
,
"#E24D42"
,
"#1F78C1"
,
"#BA43A9"
,
"#705DA0"
,
"#508642"
,
"#CCA300"
,
"#447EBC"
,
"#C15C17"
,
"#890F02"
,
"#0A437C"
,
"#6D1F62"
,
"#584477"
,
"#B7DBAB"
,
"#F4D598"
,
"#70DBED"
,
"#F9BA8F"
,
"#F29191"
,
"#82B5D8"
,
"#E5A8E2"
,
"#AEA2E0"
,
"#629E51"
,
"#E5AC0E"
,
"#64B0C8"
,
"#E0752D"
,
"#BF1B00"
,
"#0A50A1"
,
"#962D82"
,
"#614D93"
,
"#9AC48A"
,
"#F2C96D"
,
"#65C5DB"
,
"#F9934E"
,
"#EA6460"
,
"#5195CE"
,
"#D683CE"
,
"#806EB7"
,
"#3F6833"
,
"#967302"
,
"#2F575E"
,
"#99440A"
,
"#58140C"
,
"#052B51"
,
"#511749"
,
"#3F2B5B"
,
"#E0F9D7"
,
"#FCEACA"
,
"#CFFAFF"
,
"#F9E2D2"
,
"#FCE2DE"
,
"#BADFF4"
,
"#F9D9F9"
,
"#DEDAF7"
];
public/app/plugins/panel/graph/axes_edit_tab.ts
0 → 100644
View file @
23246605
///<reference path="../../../headers/common.d.ts" />
export
class
AxesEditTabCtrl
{
panel
:
any
;
panelCtrl
:
any
;
/** @ngInject **/
constructor
(
$scope
)
{
this
.
panelCtrl
=
$scope
.
ctrl
;
this
.
panel
=
this
.
panelCtrl
.
panel
;
$scope
.
ctrl
=
this
;
}
}
/** @ngInject **/
export
function
axesTabCtrl
()
{
'use strict'
;
return
{
restrict
:
'E'
,
scope
:
true
,
templateUrl
:
'public/app/plugins/panel/graph/tab_axes.html'
,
controller
:
AxesEditTabCtrl
,
};
}
public/app/plugins/panel/graph/data_processor.ts
0 → 100644
View file @
23246605
///<reference path="../../../headers/common.d.ts" />
import
kbn
from
'app/core/utils/kbn'
;
import
_
from
'lodash'
;
import
TimeSeries
from
'app/core/time_series2'
;
import
{
colors
}
from
'app/core/core'
;
export
class
DataProcessor
{
constructor
(
private
panel
)
{
}
getSeriesList
(
options
)
{
switch
(
this
.
panel
.
xaxis
.
mode
)
{
case
'series'
:
case
'time'
:
{
return
options
.
dataList
.
map
(
this
.
timeSeriesHandler
.
bind
(
this
));
}
case
'table'
:
{
// Table panel uses only first enabled target, so we can use dataList[0]
// dataList.splice(1, dataList.length - 1);
// dataHandler = this.tableHandler;
break
;
}
case
'json'
:
{
break
;
}
}
}
seriesHandler
(
seriesData
,
index
,
datapoints
,
alias
)
{
var
colorIndex
=
index
%
colors
.
length
;
var
color
=
this
.
panel
.
aliasColors
[
alias
]
||
colors
[
colorIndex
];
var
series
=
new
TimeSeries
({
datapoints
:
datapoints
,
alias
:
alias
,
color
:
color
,
unit
:
seriesData
.
unit
});
// if (datapoints && datapoints.length > 0) {
// var last = moment.utc(datapoints[datapoints.length - 1][1]);
// var from = moment.utc(this.range.from);
// if (last - from < -10000) {
// this.datapointsOutside = true;
// }
//
// this.datapointsCount += datapoints.length;
// this.panel.tooltip.msResolution = this.panel.tooltip.msResolution || series.isMsResolutionNeeded();
// }
return
series
;
}
timeSeriesHandler
(
seriesData
,
index
)
{
var
datapoints
=
seriesData
.
datapoints
;
var
alias
=
seriesData
.
target
;
return
this
.
seriesHandler
(
seriesData
,
index
,
datapoints
,
alias
);
}
tableHandler
(
seriesData
,
index
)
{
var
xColumnIndex
=
Number
(
this
.
panel
.
xaxis
.
columnIndex
);
var
valueColumnIndex
=
Number
(
this
.
panel
.
xaxis
.
valueColumnIndex
);
var
datapoints
=
_
.
map
(
seriesData
.
rows
,
(
row
)
=>
{
var
value
=
valueColumnIndex
?
row
[
valueColumnIndex
]
:
_
.
last
(
row
);
return
[
value
,
// Y value
row
[
xColumnIndex
]
// X value
];
});
var
alias
=
seriesData
.
columns
[
valueColumnIndex
].
text
;
return
this
.
seriesHandler
(
seriesData
,
index
,
datapoints
,
alias
);
}
// esRawDocHandler(seriesData, index) {
// let xField = this.panel.xaxis.esField;
// let valueField = this.panel.xaxis.esValueField;
// let datapoints = _.map(seriesData.datapoints, (doc) => {
// return [
// pluckDeep(doc, valueField), // Y value
// pluckDeep(doc, xField) // X value
// ];
// });
//
// // Remove empty points
// datapoints = _.filter(datapoints, (point) => {
// return point[0] !== undefined;
// });
//
// var alias = valueField;
// return this.seriesHandler(seriesData, index, datapoints, alias);
// }
//
validateXAxisSeriesValue
()
{
switch
(
this
.
panel
.
xaxis
.
mode
)
{
case
'series'
:
{
if
(
this
.
panel
.
xaxis
.
values
.
length
===
0
)
{
this
.
panel
.
xaxis
.
values
=
[
'total'
];
return
;
}
var
validOptions
=
this
.
getXAxisValueOptions
({});
var
found
=
_
.
find
(
validOptions
,
{
value
:
this
.
panel
.
xaxis
.
values
[
0
]});
if
(
!
found
)
{
this
.
panel
.
xaxis
.
values
=
[
'total'
];
}
return
;
}
}
}
getXAxisValueOptions
(
options
)
{
switch
(
this
.
panel
.
xaxis
.
mode
)
{
case
'time'
:
{
return
[];
}
case
'series'
:
{
return
[
{
text
:
'Avg'
,
value
:
'avg'
},
{
text
:
'Min'
,
value
:
'min'
},
{
text
:
'Max'
,
value
:
'min'
},
{
text
:
'Total'
,
value
:
'total'
},
{
text
:
'Count'
,
value
:
'count'
},
];
}
}
}
}
// function getFieldsFromESDoc(doc) {
// let fields = [];
// let fieldNameParts = [];
//
// function getFieldsRecursive(obj) {
// _.forEach(obj, (value, key) => {
// if (_.isObject(value)) {
// fieldNameParts.push(key);
// getFieldsRecursive(value);
// } else {
// let field = fieldNameParts.concat(key).join('.');
// fields.push(field);
// }
// });
// fieldNameParts.pop();
// }
//
// getFieldsRecursive(doc);
// return fields;
// }
//
// function pluckDeep(obj: any, property: string) {
// let propertyParts = property.split('.');
// let value = obj;
// for (let i = 0; i < propertyParts.length; ++i) {
// if (value[propertyParts[i]]) {
// value = value[propertyParts[i]];
// } else {
// return undefined;
// }
// }
// return value;
// }
public/app/plugins/panel/graph/module.ts
View file @
23246605
...
...
@@ -14,15 +14,18 @@ import TimeSeries from 'app/core/time_series2';
import
config
from
'app/core/config'
;
import
*
as
fileExport
from
'app/core/utils/file_export'
;
import
{
MetricsPanelCtrl
,
alertTab
}
from
'app/plugins/sdk'
;
import
{
DataProcessor
}
from
'./data_processor'
;
class
GraphCtrl
extends
MetricsPanelCtrl
{
static
template
=
template
;
hiddenSeries
:
any
=
{};
seriesList
:
any
=
[];
dataList
:
any
=
[];
logScales
:
any
;
unitFormats
:
any
;
xAxisModes
:
any
;
xAxisStatOptions
:
any
;
xNameSegment
:
any
;
annotationsPromise
:
any
;
datapointsCount
:
number
;
...
...
@@ -30,6 +33,7 @@ class GraphCtrl extends MetricsPanelCtrl {
datapointsWarning
:
boolean
;
colors
:
any
=
[];
subTabIndex
:
number
;
processor
:
DataProcessor
;
panelDefaults
=
{
// datasource name, null = default datasource
...
...
@@ -118,7 +122,7 @@ class GraphCtrl extends MetricsPanelCtrl {
_
.
defaults
(
this
.
panel
.
legend
,
this
.
panelDefaults
.
legend
);
_
.
defaults
(
this
.
panel
.
xaxis
,
this
.
panelDefaults
.
xaxis
);
this
.
colors
=
$scope
.
$root
.
colors
;
this
.
processor
=
new
DataProcessor
(
this
.
panel
)
;
this
.
events
.
on
(
'render'
,
this
.
onRender
.
bind
(
this
));
this
.
events
.
on
(
'data-received'
,
this
.
onDataReceived
.
bind
(
this
));
...
...
@@ -144,6 +148,7 @@ class GraphCtrl extends MetricsPanelCtrl {
'log (base 32)'
:
32
,
'log (base 1024)'
:
1024
};
this
.
unitFormats
=
kbn
.
getUnitFormats
();
this
.
xAxisModes
=
{
...
...
@@ -153,6 +158,14 @@ class GraphCtrl extends MetricsPanelCtrl {
'Json'
:
'json'
};
this
.
xAxisStatOptions
=
[
{
text
:
'Avg'
,
value
:
'avg'
},
{
text
:
'Min'
,
value
:
'min'
},
{
text
:
'Max'
,
value
:
'min'
},
{
text
:
'Total'
,
value
:
'total'
},
{
text
:
'Count'
,
value
:
'count'
},
];
this
.
subTabIndex
=
0
;
}
...
...
@@ -199,25 +212,8 @@ class GraphCtrl extends MetricsPanelCtrl {
this
.
datapointsCount
=
0
;
this
.
datapointsOutside
=
false
;
let
dataHandler
:
(
seriesData
,
index
)
=>
any
;
switch
(
this
.
panel
.
xaxis
.
mode
)
{
case
'series'
:
case
'time'
:
{
dataHandler
=
this
.
timeSeriesHandler
;
break
;
}
case
'table'
:
{
// Table panel uses only first enabled target, so we can use dataList[0]
dataList
.
splice
(
1
,
dataList
.
length
-
1
);
dataHandler
=
this
.
tableHandler
;
break
;
}
case
'json'
:
{
break
;
}
}
this
.
seriesList
=
dataList
.
map
(
dataHandler
.
bind
(
this
));
this
.
dataList
=
dataList
;
this
.
seriesList
=
this
.
processor
.
getSeriesList
({
dataList
:
dataList
,
range
:
this
.
range
});
this
.
datapointsWarning
=
this
.
datapointsCount
===
0
||
this
.
datapointsOutside
;
this
.
annotationsPromise
.
then
(
annotations
=>
{
...
...
@@ -230,73 +226,6 @@ class GraphCtrl extends MetricsPanelCtrl {
});
}
seriesHandler
(
seriesData
,
index
,
datapoints
,
alias
)
{
var
colorIndex
=
index
%
this
.
colors
.
length
;
var
color
=
this
.
panel
.
aliasColors
[
alias
]
||
this
.
colors
[
colorIndex
];
var
series
=
new
TimeSeries
({
datapoints
:
datapoints
,
alias
:
alias
,
color
:
color
,
unit
:
seriesData
.
unit
,
});
if
(
datapoints
&&
datapoints
.
length
>
0
)
{
var
last
=
moment
.
utc
(
datapoints
[
datapoints
.
length
-
1
][
1
]);
var
from
=
moment
.
utc
(
this
.
range
.
from
);
if
(
last
-
from
<
-
10000
)
{
this
.
datapointsOutside
=
true
;
}
this
.
datapointsCount
+=
datapoints
.
length
;
this
.
panel
.
tooltip
.
msResolution
=
this
.
panel
.
tooltip
.
msResolution
||
series
.
isMsResolutionNeeded
();
}
return
series
;
}
timeSeriesHandler
(
seriesData
,
index
)
{
var
datapoints
=
seriesData
.
datapoints
;
var
alias
=
seriesData
.
target
;
return
this
.
seriesHandler
(
seriesData
,
index
,
datapoints
,
alias
);
}
tableHandler
(
seriesData
,
index
)
{
var
xColumnIndex
=
Number
(
this
.
panel
.
xaxis
.
columnIndex
);
var
valueColumnIndex
=
Number
(
this
.
panel
.
xaxis
.
valueColumnIndex
);
var
datapoints
=
_
.
map
(
seriesData
.
rows
,
(
row
)
=>
{
var
value
=
valueColumnIndex
?
row
[
valueColumnIndex
]
:
_
.
last
(
row
);
return
[
value
,
// Y value
row
[
xColumnIndex
]
// X value
];
});
var
alias
=
seriesData
.
columns
[
valueColumnIndex
].
text
;
return
this
.
seriesHandler
(
seriesData
,
index
,
datapoints
,
alias
);
}
esRawDocHandler
(
seriesData
,
index
)
{
let
xField
=
this
.
panel
.
xaxis
.
esField
;
let
valueField
=
this
.
panel
.
xaxis
.
esValueField
;
let
datapoints
=
_
.
map
(
seriesData
.
datapoints
,
(
doc
)
=>
{
return
[
pluckDeep
(
doc
,
valueField
),
// Y value
pluckDeep
(
doc
,
xField
)
// X value
];
});
// Remove empty points
datapoints
=
_
.
filter
(
datapoints
,
(
point
)
=>
{
return
point
[
0
]
!==
undefined
;
});
var
alias
=
valueField
;
return
this
.
seriesHandler
(
seriesData
,
index
,
datapoints
,
alias
);
}
onRender
()
{
if
(
!
this
.
seriesList
)
{
return
;
}
...
...
@@ -380,13 +309,11 @@ class GraphCtrl extends MetricsPanelCtrl {
this
.
render
();
}
// Called from panel menu
toggleLegend
()
{
this
.
panel
.
legend
.
show
=
!
this
.
panel
.
legend
.
show
;
this
.
refresh
();
}
legendValuesOptionChanged
()
{
var
legend
=
this
.
panel
.
legend
;
legend
.
values
=
legend
.
min
||
legend
.
max
||
legend
.
avg
||
legend
.
current
||
legend
.
total
;
...
...
@@ -401,9 +328,21 @@ class GraphCtrl extends MetricsPanelCtrl {
fileExport
.
exportSeriesListToCsvColumns
(
this
.
seriesList
);
}
xAxisModeChanged
()
{
// set defaults
this
.
refresh
();
xAxisOptionChanged
()
{
switch
(
this
.
panel
.
xaxis
.
mode
)
{
case
'time'
:
{
this
.
panel
.
tooltip
.
shared
=
true
;
this
.
panel
.
xaxis
.
values
=
[];
this
.
onDataReceived
(
this
.
dataList
);
break
;
}
case
'series'
:
{
this
.
panel
.
tooltip
.
shared
=
false
;
this
.
processor
.
validateXAxisSeriesValue
();
this
.
onDataReceived
(
this
.
dataList
);
break
;
}
}
}
getXAxisNameOptions
()
{
...
...
@@ -413,44 +352,8 @@ class GraphCtrl extends MetricsPanelCtrl {
}
getXAxisValueOptions
()
{
return
this
.
$q
.
when
([
{
text
:
'Avg'
,
value
:
'avg'
}
]);
}
}
function
getFieldsFromESDoc
(
doc
)
{
let
fields
=
[];
let
fieldNameParts
=
[];
function
getFieldsRecursive
(
obj
)
{
_
.
forEach
(
obj
,
(
value
,
key
)
=>
{
if
(
_
.
isObject
(
value
))
{
fieldNameParts
.
push
(
key
);
getFieldsRecursive
(
value
);
}
else
{
let
field
=
fieldNameParts
.
concat
(
key
).
join
(
'.'
);
fields
.
push
(
field
);
}
});
fieldNameParts
.
pop
();
}
getFieldsRecursive
(
doc
);
return
fields
;
}
function
pluckDeep
(
obj
:
any
,
property
:
string
)
{
let
propertyParts
=
property
.
split
(
'.'
);
let
value
=
obj
;
for
(
let
i
=
0
;
i
<
propertyParts
.
length
;
++
i
)
{
if
(
value
[
propertyParts
[
i
]])
{
value
=
value
[
propertyParts
[
i
]];
}
else
{
return
undefined
;
}
return
this
.
$q
.
when
(
this
.
processor
.
getXAxisValueOptions
({
dataList
:
this
.
dataList
}));
}
return
value
;
}
export
{
GraphCtrl
,
GraphCtrl
as
PanelCtrl
}
public/app/plugins/panel/graph/tab_axes.html
View file @
23246605
...
...
@@ -44,24 +44,20 @@
<div
class=
"gf-form"
>
<label
class=
"gf-form-label width-5"
>
Mode
</label>
<div
class=
"gf-form-select-wrapper max-width-15"
>
<select
class=
"gf-form-input"
ng-model=
"ctrl.panel.xaxis.mode"
ng-options=
"v as k for (k, v) in ctrl.xAxisModes"
ng-change=
"ctrl.xAxisModeChanged()"
>
</select>
<select
class=
"gf-form-input"
ng-model=
"ctrl.panel.xaxis.mode"
ng-options=
"v as k for (k, v) in ctrl.xAxisModes"
ng-change=
"ctrl.xAxisOptionChanged()"
>
</select>
</div>
</div>
<!-- Table mode -->
<div
class=
"gf-form"
ng-if=
"ctrl.panel.xaxis.mode === 'table' || ctrl.panel.xaxis.mode === 'json'"
>
<label
class=
"gf-form-label width-5"
>
Name
</label>
<metric-segment-model
property=
"ctrl.panel.xaxis.name"
get-options=
"ctrl.getXAxisNameOptions()"
on-change=
"ctrl.
render
()"
custom=
"false"
css-class=
"width-10"
select-mode=
"true"
></metric-segment-model>
<metric-segment-model
property=
"ctrl.panel.xaxis.name"
get-options=
"ctrl.getXAxisNameOptions()"
on-change=
"ctrl.
xAxisOptionChanged
()"
custom=
"false"
css-class=
"width-10"
select-mode=
"true"
></metric-segment-model>
</div>
<!-- Series mode -->
<div
class=
"gf-form"
ng-if=
"ctrl.panel.xaxis.mode
!== 'time
'"
>
<div
class=
"gf-form"
ng-if=
"ctrl.panel.xaxis.mode
=== 'series
'"
>
<label
class=
"gf-form-label width-5"
>
Value
</label>
<metric-segment-model
property=
"ctrl.panel.xaxis.values[0]"
get-options=
"ctrl.getXAxisValueOptions()"
on-change=
"ctrl.render
()"
custom=
"false"
css-class=
"width-10"
select-mode=
"true"
></metric-segment-model>
<metric-segment-model
property=
"ctrl.panel.xaxis.values[0]"
options=
"ctrl.xAxisStatOptions"
on-change=
"ctrl.xAxisOptionChanged
()"
custom=
"false"
css-class=
"width-10"
select-mode=
"true"
></metric-segment-model>
</div>
</div>
...
...
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