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
bfc54b64
Unverified
Commit
bfc54b64
authored
Mar 22, 2019
by
Torkel Ödegaard
Committed by
GitHub
Mar 22, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #16134 from grafana/auto-decimals-graph-panels
Auto decimals react singlestat panels
parents
7cae6d52
dba64a4e
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
122 additions
and
70 deletions
+122
-70
packages/grafana-ui/src/components/BarGauge/BarGauge.tsx
+2
-2
packages/grafana-ui/src/components/Gauge/Gauge.tsx
+2
-3
packages/grafana-ui/src/types/displayValue.ts
+11
-0
packages/grafana-ui/src/types/index.ts
+1
-0
packages/grafana-ui/src/utils/displayValue.test.ts
+31
-2
packages/grafana-ui/src/utils/displayValue.ts
+63
-13
public/app/plugins/panel/singlestat/module.ts
+12
-50
No files found.
packages/grafana-ui/src/components/BarGauge/BarGauge.tsx
View file @
bfc54b64
...
...
@@ -3,10 +3,10 @@ import React, { PureComponent, CSSProperties, ReactNode } from 'react';
import
tinycolor
from
'tinycolor2'
;
// Utils
import
{
getColorFromHexRgbOrName
,
getThresholdForValue
,
DisplayValue
}
from
'../../utils'
;
import
{
getColorFromHexRgbOrName
,
getThresholdForValue
}
from
'../../utils'
;
// Types
import
{
Themeable
,
TimeSeriesValue
,
Threshold
,
VizOrientation
}
from
'../../types'
;
import
{
DisplayValue
,
Themeable
,
TimeSeriesValue
,
Threshold
,
VizOrientation
}
from
'../../types'
;
const
BAR_SIZE_RATIO
=
0.8
;
...
...
packages/grafana-ui/src/components/Gauge/Gauge.tsx
View file @
bfc54b64
import
React
,
{
PureComponent
}
from
'react'
;
import
$
from
'jquery'
;
import
{
Threshold
,
GrafanaThemeType
}
from
'../../types'
;
import
{
getColorFromHexRgbOrName
}
from
'../../utils'
;
import
{
Themeable
}
from
'../../index'
;
import
{
DisplayValue
}
from
'../../utils/displayValue
'
;
import
{
DisplayValue
,
Threshold
,
GrafanaThemeType
,
Themeable
}
from
'../../types
'
;
export
interface
Props
extends
Themeable
{
height
:
number
;
...
...
packages/grafana-ui/src/types/displayValue.ts
0 → 100644
View file @
bfc54b64
export
interface
DisplayValue
{
text
:
string
;
// Show in the UI
numeric
:
number
;
// Use isNaN to check if it is a real number
color
?:
string
;
// color based on configs or Threshold
title
?:
string
;
}
export
interface
DecimalInfo
{
decimals
:
number
;
scaledDecimals
:
number
;
}
packages/grafana-ui/src/types/index.ts
View file @
bfc54b64
...
...
@@ -6,3 +6,4 @@ export * from './datasource';
export
*
from
'./theme'
;
export
*
from
'./threshold'
;
export
*
from
'./input'
;
export
*
from
'./displayValue'
;
packages/grafana-ui/src/utils/displayValue.test.ts
View file @
bfc54b64
import
{
getDisplayProcessor
,
getColorFromThreshold
,
DisplayProcessor
,
Display
Value
}
from
'./displayValue'
;
import
{
MappingType
,
ValueMapping
}
from
'../types/panel
'
;
import
{
getDisplayProcessor
,
getColorFromThreshold
,
DisplayProcessor
,
getDecimalsFor
Value
}
from
'./displayValue'
;
import
{
DisplayValue
,
MappingType
,
ValueMapping
}
from
'../types
'
;
function
assertSame
(
input
:
any
,
processors
:
DisplayProcessor
[],
match
:
DisplayValue
)
{
processors
.
forEach
(
processor
=>
{
...
...
@@ -144,6 +144,20 @@ describe('Format value', () => {
expect
(
result
.
text
).
toEqual
(
'10.0'
);
});
it
(
'should set auto decimals, 1 significant'
,
()
=>
{
const
value
=
'1.23'
;
const
instance
=
getDisplayProcessor
({
decimals
:
null
});
expect
(
instance
(
value
).
text
).
toEqual
(
'1.2'
);
});
it
(
'should set auto decimals, 2 significant'
,
()
=>
{
const
value
=
'0.0245'
;
const
instance
=
getDisplayProcessor
({
decimals
:
null
});
expect
(
instance
(
value
).
text
).
toEqual
(
'0.02'
);
});
it
(
'should return mapped value if there are matching value mappings'
,
()
=>
{
const
valueMappings
:
ValueMapping
[]
=
[
{
id
:
0
,
operator
:
''
,
text
:
'1-20'
,
type
:
MappingType
.
RangeToText
,
from
:
'1'
,
to
:
'20'
},
...
...
@@ -155,3 +169,18 @@ describe('Format value', () => {
expect
(
instance
(
value
).
text
).
toEqual
(
'1-20'
);
});
});
describe
(
'getDecimalsForValue()'
,
()
=>
{
it
(
'should calculate reasonable decimals precision for given value'
,
()
=>
{
expect
(
getDecimalsForValue
(
1.01
)).
toEqual
({
decimals
:
1
,
scaledDecimals
:
4
});
expect
(
getDecimalsForValue
(
9.01
)).
toEqual
({
decimals
:
0
,
scaledDecimals
:
2
});
expect
(
getDecimalsForValue
(
1.1
)).
toEqual
({
decimals
:
1
,
scaledDecimals
:
4
});
expect
(
getDecimalsForValue
(
2
)).
toEqual
({
decimals
:
0
,
scaledDecimals
:
2
});
expect
(
getDecimalsForValue
(
20
)).
toEqual
({
decimals
:
0
,
scaledDecimals
:
1
});
expect
(
getDecimalsForValue
(
200
)).
toEqual
({
decimals
:
0
,
scaledDecimals
:
0
});
expect
(
getDecimalsForValue
(
2000
)).
toEqual
({
decimals
:
0
,
scaledDecimals
:
0
});
expect
(
getDecimalsForValue
(
20000
)).
toEqual
({
decimals
:
0
,
scaledDecimals
:
-
2
});
expect
(
getDecimalsForValue
(
200000
)).
toEqual
({
decimals
:
0
,
scaledDecimals
:
-
3
});
expect
(
getDecimalsForValue
(
200000000
)).
toEqual
({
decimals
:
0
,
scaledDecimals
:
-
6
});
});
});
packages/grafana-ui/src/utils/displayValue.ts
View file @
bfc54b64
import
{
ValueMapping
,
Threshold
}
from
'../types'
;
// Libraries
import
_
from
'lodash'
;
import
{
getValueFormat
,
DecimalCount
}
from
'./valueFormats/valueFormats'
;
import
moment
from
'moment'
;
// Utils
import
{
getValueFormat
}
from
'./valueFormats/valueFormats'
;
import
{
getMappedValue
}
from
'./valueMappings'
;
import
{
GrafanaTheme
,
GrafanaThemeType
}
from
'../types'
;
import
{
getColorFromHexRgbOrName
}
from
'./namedColorsPalette'
;
import
moment
from
'moment'
;
export
interface
DisplayValue
{
text
:
string
;
// Show in the UI
numeric
:
number
;
// Use isNaN to check if it is a real number
color
?:
string
;
// color based on configs or Threshold
}
// Types
import
{
Threshold
,
ValueMapping
,
DecimalInfo
,
DisplayValue
,
GrafanaTheme
,
GrafanaThemeType
}
from
'../types'
;
import
{
DecimalCount
}
from
'./valueFormats/valueFormats'
;
export
type
DisplayProcessor
=
(
value
:
any
)
=>
DisplayValue
;
export
interface
DisplayValueOptions
{
unit
?:
string
;
decimals
?:
DecimalCount
;
scaledDecimals
?:
DecimalCount
;
dateFormat
?:
string
;
// If set try to convert numbers to date
color
?:
string
;
...
...
@@ -32,11 +32,10 @@ export interface DisplayValueOptions {
theme
?:
GrafanaTheme
;
// Will pick 'dark' if not defined
}
export
type
DisplayProcessor
=
(
value
:
any
)
=>
DisplayValue
;
export
function
getDisplayProcessor
(
options
?:
DisplayValueOptions
):
DisplayProcessor
{
if
(
options
&&
!
_
.
isEmpty
(
options
))
{
const
formatFunc
=
getValueFormat
(
options
.
unit
||
'none'
);
return
(
value
:
any
)
=>
{
const
{
prefix
,
suffix
,
mappings
,
thresholds
,
theme
}
=
options
;
let
color
=
options
.
color
;
...
...
@@ -47,12 +46,15 @@ export function getDisplayProcessor(options?: DisplayValueOptions): DisplayProce
let
shouldFormat
=
true
;
if
(
mappings
&&
mappings
.
length
>
0
)
{
const
mappedValue
=
getMappedValue
(
mappings
,
value
);
if
(
mappedValue
)
{
text
=
mappedValue
.
text
;
const
v
=
toNumber
(
text
);
if
(
!
isNaN
(
v
))
{
numeric
=
v
;
}
shouldFormat
=
false
;
}
}
...
...
@@ -67,7 +69,19 @@ export function getDisplayProcessor(options?: DisplayValueOptions): DisplayProce
if
(
!
isNaN
(
numeric
))
{
if
(
shouldFormat
&&
!
_
.
isBoolean
(
value
))
{
text
=
formatFunc
(
numeric
,
options
.
decimals
,
options
.
scaledDecimals
,
options
.
isUtc
);
let
decimals
;
let
scaledDecimals
=
0
;
if
(
!
options
.
decimals
)
{
const
decimalInfo
=
getDecimalsForValue
(
value
);
decimals
=
decimalInfo
.
decimals
;
scaledDecimals
=
decimalInfo
.
scaledDecimals
;
}
else
{
decimals
=
options
.
decimals
;
}
text
=
formatFunc
(
numeric
,
decimals
,
scaledDecimals
,
options
.
isUtc
);
}
if
(
thresholds
&&
thresholds
.
length
>
0
)
{
color
=
getColorFromThreshold
(
numeric
,
thresholds
,
theme
);
...
...
@@ -143,3 +157,39 @@ export function getColorFromThreshold(value: number, thresholds: Threshold[], th
// Use the first threshold as the default color
return
getColorFromHexRgbOrName
(
thresholds
[
0
].
color
,
themeType
);
}
export
function
getDecimalsForValue
(
value
:
number
):
DecimalInfo
{
const
delta
=
value
/
2
;
let
dec
=
-
Math
.
floor
(
Math
.
log
(
delta
)
/
Math
.
LN10
);
const
magn
=
Math
.
pow
(
10
,
-
dec
);
const
norm
=
delta
/
magn
;
// norm is between 1.0 and 10.0
let
size
;
if
(
norm
<
1.5
)
{
size
=
1
;
}
else
if
(
norm
<
3
)
{
size
=
2
;
// special case for 2.5, requires an extra decimal
if
(
norm
>
2.25
)
{
size
=
2.5
;
++
dec
;
}
}
else
if
(
norm
<
7.5
)
{
size
=
5
;
}
else
{
size
=
10
;
}
size
*=
magn
;
// reduce starting decimals if not needed
if
(
Math
.
floor
(
value
)
===
value
)
{
dec
=
0
;
}
const
decimals
=
Math
.
max
(
0
,
dec
);
const
scaledDecimals
=
decimals
-
Math
.
floor
(
Math
.
log
(
size
)
/
Math
.
LN10
)
+
2
;
return
{
decimals
,
scaledDecimals
};
}
public/app/plugins/panel/singlestat/module.ts
View file @
bfc54b64
...
...
@@ -3,6 +3,7 @@ import $ from 'jquery';
import
'vendor/flot/jquery.flot'
;
import
'vendor/flot/jquery.flot.gauge'
;
import
'app/features/panel/panellinks/link_srv'
;
import
{
getDecimalsForValue
}
from
'@grafana/ui'
;
import
kbn
from
'app/core/utils/kbn'
;
import
config
from
'app/core/config'
;
...
...
@@ -190,7 +191,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
data
.
value
=
0
;
data
.
valueRounded
=
0
;
}
else
{
const
decimalInfo
=
this
.
getDecimalsForValue
(
data
.
value
);
const
decimalInfo
=
getDecimalsForValue
(
data
.
value
);
const
formatFunc
=
getValueFormat
(
this
.
panel
.
format
);
data
.
valueFormatted
=
formatFunc
(
...
...
@@ -243,47 +244,6 @@ class SingleStatCtrl extends MetricsPanelCtrl {
this
.
render
();
}
getDecimalsForValue
(
value
)
{
if
(
_
.
isNumber
(
this
.
panel
.
decimals
))
{
return
{
decimals
:
this
.
panel
.
decimals
,
scaledDecimals
:
null
};
}
const
delta
=
value
/
2
;
let
dec
=
-
Math
.
floor
(
Math
.
log
(
delta
)
/
Math
.
LN10
);
const
magn
=
Math
.
pow
(
10
,
-
dec
);
const
norm
=
delta
/
magn
;
// norm is between 1.0 and 10.0
let
size
;
if
(
norm
<
1.5
)
{
size
=
1
;
}
else
if
(
norm
<
3
)
{
size
=
2
;
// special case for 2.5, requires an extra decimal
if
(
norm
>
2.25
)
{
size
=
2.5
;
++
dec
;
}
}
else
if
(
norm
<
7.5
)
{
size
=
5
;
}
else
{
size
=
10
;
}
size
*=
magn
;
// reduce starting decimals if not needed
if
(
Math
.
floor
(
value
)
===
value
)
{
dec
=
0
;
}
const
result
:
any
=
{};
result
.
decimals
=
Math
.
max
(
0
,
dec
);
result
.
scaledDecimals
=
result
.
decimals
-
Math
.
floor
(
Math
.
log
(
size
)
/
Math
.
LN10
)
+
2
;
return
result
;
}
setValues
(
data
)
{
data
.
flotpairs
=
[];
...
...
@@ -319,15 +279,17 @@ class SingleStatCtrl extends MetricsPanelCtrl {
data
.
value
=
this
.
series
[
0
].
stats
[
this
.
panel
.
valueName
];
data
.
flotpairs
=
this
.
series
[
0
].
flotpairs
;
const
decimalInfo
=
this
.
getDecimalsForValue
(
data
.
value
);
let
decimals
=
this
.
panel
.
decimals
;
let
scaledDecimals
=
0
;
data
.
valueFormatted
=
formatFunc
(
data
.
value
,
decimalInfo
.
decimals
,
decimalInfo
.
scaledDecimals
,
this
.
dashboard
.
isTimezoneUtc
()
);
data
.
valueRounded
=
kbn
.
roundValue
(
data
.
value
,
decimalInfo
.
decimals
);
if
(
!
this
.
panel
.
decimals
)
{
const
decimalInfo
=
getDecimalsForValue
(
data
.
value
);
decimals
=
decimalInfo
.
decimals
;
scaledDecimals
=
decimalInfo
.
scaledDecimals
;
}
data
.
valueFormatted
=
formatFunc
(
data
.
value
,
decimals
,
scaledDecimals
,
this
.
dashboard
.
isTimezoneUtc
());
data
.
valueRounded
=
kbn
.
roundValue
(
data
.
value
,
decimals
);
}
// Add $__name variable for using in prefix or postfix
...
...
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