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
560aec50
Commit
560aec50
authored
Mar 13, 2018
by
Alexander Zobnin
Browse files
Options
Browse Files
Download
Plain Diff
Merge PR #8613
parents
87bc60b9
30d077d1
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
106 additions
and
22 deletions
+106
-22
public/app/plugins/panel/graph/data_processor.ts
+11
-6
public/app/plugins/panel/graph/graph.ts
+10
-6
public/app/plugins/panel/graph/histogram.ts
+37
-6
public/app/plugins/panel/graph/specs/graph_specs.ts
+44
-0
public/app/plugins/panel/graph/specs/histogram.jest.ts
+3
-3
public/app/plugins/panel/graph/tab_display.html
+1
-1
No files found.
public/app/plugins/panel/graph/data_processor.ts
View file @
560aec50
...
...
@@ -29,12 +29,17 @@ export class DataProcessor {
});
}
case
'histogram'
:
{
let
histogramDataList
=
[
{
target
:
'count'
,
datapoints
:
_
.
concat
([],
_
.
flatten
(
_
.
map
(
options
.
dataList
,
'datapoints'
))),
},
];
let
histogramDataList
;
if
(
this
.
panel
.
stack
)
{
histogramDataList
=
options
.
dataList
;
}
else
{
histogramDataList
=
[
{
target
:
'count'
,
datapoints
:
_
.
concat
([],
_
.
flatten
(
_
.
map
(
options
.
dataList
,
'datapoints'
))),
},
];
}
return
histogramDataList
.
map
((
item
,
index
)
=>
{
return
this
.
timeSeriesHandler
(
item
,
index
,
options
);
});
...
...
public/app/plugins/panel/graph/graph.ts
View file @
560aec50
...
...
@@ -17,7 +17,7 @@ import { appEvents, coreModule, updateLegendValues } from 'app/core/core';
import
GraphTooltip
from
'./graph_tooltip'
;
import
{
ThresholdManager
}
from
'./threshold_manager'
;
import
{
EventManager
}
from
'app/features/annotations/all'
;
import
{
convert
ValuesToHistogram
,
getSeriesValues
}
from
'./histogram'
;
import
{
convert
ToHistogramData
}
from
'./histogram'
;
import
config
from
'app/core/config'
;
/** @ngInject **/
...
...
@@ -236,16 +236,14 @@ function graphDirective(timeSrv, popoverSrv, contextSrv) {
}
case
'histogram'
:
{
let
bucketSize
:
number
;
let
values
=
getSeriesValues
(
data
);
if
(
data
.
length
&&
values
.
length
)
{
if
(
data
.
length
)
{
let
histMin
=
_
.
min
(
_
.
map
(
data
,
s
=>
s
.
stats
.
min
));
let
histMax
=
_
.
max
(
_
.
map
(
data
,
s
=>
s
.
stats
.
max
));
let
ticks
=
panel
.
xaxis
.
buckets
||
panelWidth
/
50
;
bucketSize
=
tickStep
(
histMin
,
histMax
,
ticks
);
let
histogram
=
convertValuesToHistogram
(
values
,
bucketSize
);
data
[
0
].
data
=
histogram
;
options
.
series
.
bars
.
barWidth
=
bucketSize
*
0.8
;
data
=
convertToHistogramData
(
data
,
bucketSize
,
ctrl
.
hiddenSeries
,
histMin
,
histMax
);
}
else
{
bucketSize
=
0
;
}
...
...
@@ -413,7 +411,13 @@ function graphDirective(timeSrv, popoverSrv, contextSrv) {
let
defaultTicks
=
panelWidth
/
50
;
if
(
data
.
length
&&
bucketSize
)
{
ticks
=
_
.
map
(
data
[
0
].
data
,
point
=>
point
[
0
]);
let
tick_values
=
[];
for
(
let
d
of
data
)
{
for
(
let
point
of
d
.
data
)
{
tick_values
[
point
[
0
]]
=
true
;
}
}
ticks
=
Object
.
keys
(
tick_values
).
map
(
v
=>
Number
(
v
));
min
=
_
.
min
(
ticks
);
max
=
_
.
max
(
ticks
);
...
...
public/app/plugins/panel/graph/histogram.ts
View file @
560aec50
...
...
@@ -29,16 +29,22 @@ export function getSeriesValues(dataList: TimeSeries[]): number[] {
* @param values
* @param bucketSize
*/
export
function
convertValuesToHistogram
(
values
:
number
[],
bucketSize
:
number
):
any
[]
{
export
function
convertValuesToHistogram
(
values
:
number
[],
bucketSize
:
number
,
min
:
number
,
max
:
number
):
any
[]
{
let
histogram
=
{};
let
minBound
=
getBucketBound
(
min
,
bucketSize
);
let
maxBound
=
getBucketBound
(
max
,
bucketSize
);
let
bound
=
minBound
;
let
n
=
0
;
while
(
bound
<=
maxBound
)
{
histogram
[
bound
]
=
0
;
bound
=
minBound
+
bucketSize
*
n
;
n
++
;
}
for
(
let
i
=
0
;
i
<
values
.
length
;
i
++
)
{
let
bound
=
getBucketBound
(
values
[
i
],
bucketSize
);
if
(
histogram
[
bound
])
{
histogram
[
bound
]
=
histogram
[
bound
]
+
1
;
}
else
{
histogram
[
bound
]
=
1
;
}
histogram
[
bound
]
=
histogram
[
bound
]
+
1
;
}
let
histogam_series
=
_
.
map
(
histogram
,
(
count
,
bound
)
=>
{
...
...
@@ -49,6 +55,31 @@ export function convertValuesToHistogram(values: number[], bucketSize: number):
return
_
.
sortBy
(
histogam_series
,
point
=>
point
[
0
]);
}
/**
* Convert series into array of histogram data.
* @param data Array of series
* @param bucketSize
*/
export
function
convertToHistogramData
(
data
:
any
,
bucketSize
:
number
,
hiddenSeries
:
any
,
min
:
number
,
max
:
number
):
any
[]
{
return
data
.
map
(
series
=>
{
let
values
=
getSeriesValues
([
series
]);
series
.
histogram
=
true
;
if
(
!
hiddenSeries
[
series
.
alias
])
{
let
histogram
=
convertValuesToHistogram
(
values
,
bucketSize
,
min
,
max
);
series
.
data
=
histogram
;
}
else
{
series
.
data
=
[];
}
return
series
;
});
}
function
getBucketBound
(
value
:
number
,
bucketSize
:
number
):
number
{
return
Math
.
floor
(
value
/
bucketSize
)
*
bucketSize
;
}
public/app/plugins/panel/graph/specs/graph_specs.ts
View file @
560aec50
...
...
@@ -407,4 +407,48 @@ describe('grafanaGraph', function() {
},
10
);
graphScenario
(
'when graph is histogram, and enable stack'
,
function
(
ctx
)
{
ctx
.
setup
(
function
(
ctrl
,
data
)
{
ctrl
.
panel
.
xaxis
.
mode
=
'histogram'
;
ctrl
.
panel
.
stack
=
true
;
ctrl
.
hiddenSeries
=
{};
data
[
0
]
=
new
TimeSeries
({
datapoints
:
[[
100
,
1
],
[
100
,
2
],
[
200
,
3
],
[
300
,
4
]],
alias
:
'series1'
,
});
data
[
1
]
=
new
TimeSeries
({
datapoints
:
[[
100
,
1
],
[
100
,
2
],
[
200
,
3
],
[
300
,
4
]],
alias
:
'series2'
,
});
});
it
(
'should calculate correct histogram'
,
function
()
{
expect
(
ctx
.
plotData
[
0
].
data
[
0
][
0
]).
to
.
be
(
100
);
expect
(
ctx
.
plotData
[
0
].
data
[
0
][
1
]).
to
.
be
(
2
);
expect
(
ctx
.
plotData
[
1
].
data
[
0
][
0
]).
to
.
be
(
100
);
expect
(
ctx
.
plotData
[
1
].
data
[
0
][
1
]).
to
.
be
(
2
);
});
});
graphScenario
(
'when graph is histogram, and some series are hidden'
,
function
(
ctx
)
{
ctx
.
setup
(
function
(
ctrl
,
data
)
{
ctrl
.
panel
.
xaxis
.
mode
=
'histogram'
;
ctrl
.
panel
.
stack
=
false
;
ctrl
.
hiddenSeries
=
{
series2
:
true
};
data
[
0
]
=
new
TimeSeries
({
datapoints
:
[[
100
,
1
],
[
100
,
2
],
[
200
,
3
],
[
300
,
4
]],
alias
:
'series1'
,
});
data
[
1
]
=
new
TimeSeries
({
datapoints
:
[[
100
,
1
],
[
100
,
2
],
[
200
,
3
],
[
300
,
4
]],
alias
:
'series2'
,
});
});
it
(
'should calculate correct histogram'
,
function
()
{
expect
(
ctx
.
plotData
[
0
].
data
[
0
][
0
]).
to
.
be
(
100
);
expect
(
ctx
.
plotData
[
0
].
data
[
0
][
1
]).
to
.
be
(
2
);
});
});
});
public/app/plugins/panel/graph/specs/histogram.jest.ts
View file @
560aec50
...
...
@@ -13,15 +13,15 @@ describe('Graph Histogam Converter', function() {
bucketSize
=
10
;
let
expected
=
[[
0
,
2
],
[
10
,
3
],
[
20
,
2
]];
let
histogram
=
convertValuesToHistogram
(
values
,
bucketSize
);
let
histogram
=
convertValuesToHistogram
(
values
,
bucketSize
,
1
,
29
);
expect
(
histogram
).
toMatchObject
(
expected
);
});
it
(
'Should not add empty buckets'
,
()
=>
{
bucketSize
=
5
;
let
expected
=
[[
0
,
2
],
[
10
,
2
],
[
15
,
1
],
[
20
,
1
],
[
25
,
1
]];
let
expected
=
[[
0
,
2
],
[
5
,
0
],
[
10
,
2
],
[
15
,
1
],
[
20
,
1
],
[
25
,
1
]];
let
histogram
=
convertValuesToHistogram
(
values
,
bucketSize
);
let
histogram
=
convertValuesToHistogram
(
values
,
bucketSize
,
1
,
29
);
expect
(
histogram
).
toMatchObject
(
expected
);
});
});
...
...
public/app/plugins/panel/graph/tab_display.html
View file @
560aec50
...
...
@@ -71,7 +71,7 @@
<div
class=
"section gf-form-group"
>
<h5
class=
"section-heading"
>
Stacking
&
Null value
</h5>
<gf-form-switch
class=
"gf-form"
label=
"Stack"
label-class=
"width-7"
checked=
"ctrl.panel.stack"
on-change=
"ctrl.re
nder
()"
>
<gf-form-switch
class=
"gf-form"
label=
"Stack"
label-class=
"width-7"
checked=
"ctrl.panel.stack"
on-change=
"ctrl.re
fresh
()"
>
</gf-form-switch>
<gf-form-switch
class=
"gf-form"
ng-show=
"ctrl.panel.stack"
label=
"Percent"
label-class=
"width-7"
checked=
"ctrl.panel.percentage"
on-change=
"ctrl.render()"
>
</gf-form-switch>
...
...
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