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
d5266470
Unverified
Commit
d5266470
authored
May 29, 2020
by
Ryan McKinley
Committed by
GitHub
May 29, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Stats: include all fields (#24829)
parent
2a6ac88a
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
168 additions
and
31 deletions
+168
-31
packages/grafana-data/src/field/fieldDisplay.ts
+15
-1
packages/grafana-data/src/field/overrides/processors.ts
+6
-0
packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts
+8
-0
packages/grafana-data/src/types/fieldOverrides.ts
+3
-15
packages/grafana-ui/src/components/OptionsUI/select.tsx
+71
-7
packages/grafana-ui/src/utils/standardEditors.tsx
+2
-4
public/app/features/dashboard/components/PanelEditor/PanelOptionsEditor.tsx
+22
-2
public/app/features/dashboard/components/PanelEditor/PanelOptionsTab.tsx
+2
-0
public/app/plugins/panel/stat/types.ts
+39
-2
No files found.
packages/grafana-data/src/field/fieldDisplay.ts
View file @
d5266470
...
...
@@ -21,6 +21,8 @@ import { GrafanaTheme } from '../types/theme';
import
{
reduceField
,
ReducerID
}
from
'../transformations/fieldReducer'
;
import
{
ScopedVars
}
from
'../types/ScopedVars'
;
import
{
getTimeField
}
from
'../dataframe/processDataFrame'
;
import
{
getFieldMatcher
}
from
'../transformations'
;
import
{
FieldMatcherID
}
from
'../transformations/matchers/ids'
;
/**
* Options for how to turn DataFrames into an array of display values
...
...
@@ -32,6 +34,8 @@ export interface ReduceDataOptions {
limit
?:
number
;
/** When !values, pick one value for the whole field */
calcs
:
string
[];
/** Which fields to show. By default this is only numeric fields */
fields
?:
string
;
}
// TODO: use built in variables, same as for data links?
...
...
@@ -84,6 +88,16 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi
const
calcs
=
reduceOptions
.
calcs
.
length
?
reduceOptions
.
calcs
:
[
ReducerID
.
last
];
const
values
:
FieldDisplay
[]
=
[];
const
fieldMatcher
=
getFieldMatcher
(
reduceOptions
.
fields
?
{
id
:
FieldMatcherID
.
byRegexp
,
options
:
reduceOptions
.
fields
,
}
:
{
id
:
FieldMatcherID
.
numeric
,
}
);
if
(
options
.
data
)
{
// Field overrides are applied already
...
...
@@ -104,7 +118,7 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi
const
fieldLinksSupplier
=
field
.
getLinks
;
// To filter out time field, need an option for this
if
(
field
.
type
!==
FieldType
.
number
)
{
if
(
!
fieldMatcher
(
field
,
series
,
data
)
)
{
continue
;
}
...
...
packages/grafana-data/src/field/overrides/processors.ts
View file @
d5266470
...
...
@@ -45,7 +45,13 @@ export const valueMappingsOverrideProcessor = (
};
export
interface
SelectFieldConfigSettings
<
T
>
{
allowCustomValue
?:
boolean
;
/** The default options */
options
:
Array
<
SelectableValue
<
T
>>
;
/** Optionally use the context to define the options */
getOptions
?:
(
context
:
FieldOverrideContext
)
=>
Promise
<
Array
<
SelectableValue
<
T
>>>
;
}
export
const
selectOverrideProcessor
=
(
...
...
packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts
View file @
d5266470
import
{
Registry
,
RegistryItem
}
from
'../utils/Registry'
;
import
{
ComponentType
}
from
'react'
;
import
{
FieldConfigOptionsRegistry
}
from
'./FieldConfigOptionsRegistry'
;
import
{
DataFrame
,
InterpolateFunction
,
VariableSuggestionsScope
,
VariableSuggestion
}
from
'../types'
;
export
interface
StandardEditorContext
{
data
?:
DataFrame
[];
// All results
replaceVariables
?:
InterpolateFunction
;
getSuggestions
?:
(
scope
?:
VariableSuggestionsScope
)
=>
VariableSuggestion
[];
}
export
interface
StandardEditorProps
<
TValue
=
any
,
TSettings
=
any
>
{
value
:
TValue
;
onChange
:
(
value
?:
TValue
)
=>
void
;
item
:
StandardEditorsRegistryItem
<
TValue
,
TSettings
>
;
context
:
StandardEditorContext
;
}
export
interface
StandardEditorsRegistryItem
<
TValue
=
any
,
TSettings
=
any
>
extends
RegistryItem
{
editor
:
ComponentType
<
StandardEditorProps
<
TValue
,
TSettings
>>
;
...
...
packages/grafana-data/src/types/fieldOverrides.ts
View file @
d5266470
import
{
ComponentType
}
from
'react'
;
import
{
MatcherConfig
,
FieldConfig
,
Field
,
DataFrame
,
VariableSuggestionsScope
,
VariableSuggestion
,
GrafanaTheme
,
TimeZone
,
}
from
'../types'
;
import
{
MatcherConfig
,
FieldConfig
,
Field
,
DataFrame
,
GrafanaTheme
,
TimeZone
}
from
'../types'
;
import
{
InterpolateFunction
}
from
'./panel'
;
import
{
StandardEditorProps
,
FieldConfigOptionsRegistry
}
from
'../field'
;
import
{
StandardEditorProps
,
FieldConfigOptionsRegistry
,
StandardEditorContext
}
from
'../field'
;
import
{
OptionsEditorItem
}
from
'./OptionsUIRegistryBuilder'
;
export
interface
DynamicConfigValue
{
...
...
@@ -31,14 +22,11 @@ export interface FieldConfigSource<TOptions extends object = any> {
overrides
:
ConfigOverrideRule
[];
}
export
interface
FieldOverrideContext
{
export
interface
FieldOverrideContext
extends
StandardEditorContext
{
field
?:
Field
;
dataFrameIndex
?:
number
;
// The index for the selected field frame
data
:
DataFrame
[];
// All results
replaceVariables
?:
InterpolateFunction
;
getSuggestions
?:
(
scope
?:
VariableSuggestionsScope
)
=>
VariableSuggestion
[];
}
export
interface
FieldConfigEditorProps
<
TValue
,
TSettings
>
extends
Omit
<
StandardEditorProps
<
TValue
,
TSettings
>
,
'item'
>
{
item
:
FieldConfigPropertyItem
<
TValue
,
TSettings
>
;
// The property info
...
...
packages/grafana-ui/src/components/OptionsUI/select.tsx
View file @
d5266470
import
React
from
'react'
;
import
{
FieldConfigEditorProps
,
SelectFieldConfigSettings
}
from
'@grafana/data'
;
import
{
FieldConfigEditorProps
,
SelectFieldConfigSettings
,
SelectableValue
}
from
'@grafana/data'
;
import
{
Select
}
from
'../Select/Select'
;
export
function
SelectValueEditor
<
T
>
({
value
,
onChange
,
item
,
}:
FieldConfigEditorProps
<
T
,
SelectFieldConfigSettings
<
T
>>
)
{
return
<
Select
<
T
>
defaultValue=
{
value
}
onChange=
{
e
=>
onChange
(
e
.
value
)
}
options=
{
item
.
settings
?.
options
}
/
>
;
interface
State
<
T
>
{
isLoading
:
boolean
;
options
:
Array
<
SelectableValue
<
T
>>
;
}
type
Props
<
T
>
=
FieldConfigEditorProps
<
T
,
SelectFieldConfigSettings
<
T
>>
;
export
class
SelectValueEditor
<
T
>
extends
React
.
PureComponent
<
Props
<
T
>
,
State
<
T
>>
{
state
:
State
<
T
>
=
{
isLoading
:
true
,
options
:
[],
};
componentDidMount
()
{
this
.
updateOptions
();
}
componentDidUpdate
(
oldProps
:
Props
<
T
>
)
{
const
old
=
oldProps
.
item
?.
settings
;
const
now
=
this
.
props
.
item
?.
settings
;
if
(
old
!==
now
)
{
this
.
updateOptions
();
}
else
if
(
now
.
getOptions
)
{
const
old
=
oldProps
.
context
?.
data
;
const
now
=
this
.
props
.
context
?.
data
;
if
(
old
!==
now
)
{
this
.
updateOptions
();
}
}
}
updateOptions
=
async
()
=>
{
const
{
item
}
=
this
.
props
;
const
{
settings
}
=
item
;
let
options
:
Array
<
SelectableValue
<
T
>>
=
item
.
settings
?.
options
||
[];
if
(
settings
?.
getOptions
)
{
options
=
await
settings
.
getOptions
(
this
.
props
.
context
);
}
if
(
this
.
state
.
options
!==
options
)
{
this
.
setState
({
isLoading
:
false
,
options
,
});
}
};
render
()
{
const
{
options
,
isLoading
}
=
this
.
state
;
const
{
value
,
onChange
,
item
}
=
this
.
props
;
const
{
settings
}
=
item
;
const
{
allowCustomValue
}
=
settings
;
let
current
=
options
.
find
(
v
=>
v
.
value
===
value
);
if
(
!
current
&&
value
)
{
current
=
{
label
:
`
${
value
}
`
,
value
,
};
}
return
(
<
Select
<
T
>
isLoading=
{
isLoading
}
value=
{
current
}
defaultValue=
{
value
}
allowCustomValue=
{
allowCustomValue
}
onChange=
{
e
=>
onChange
(
e
.
value
)
}
options=
{
options
}
/
>
);
}
}
packages/grafana-ui/src/utils/standardEditors.tsx
View file @
d5266470
...
...
@@ -20,7 +20,7 @@ import {
}
from
'@grafana/data'
;
import
{
Switch
}
from
'../components/Switch/Switch'
;
import
{
NumberValueEditor
,
RadioButtonGroup
,
StringValueEditor
,
Select
}
from
'../components'
;
import
{
NumberValueEditor
,
RadioButtonGroup
,
StringValueEditor
,
Select
ValueEditor
}
from
'../components'
;
import
{
ValueMappingsValueEditor
}
from
'../components/OptionsUI/mappings'
;
import
{
ThresholdsValueEditor
}
from
'../components/OptionsUI/thresholds'
;
import
{
UnitValueEditor
}
from
'../components/OptionsUI/units'
;
...
...
@@ -238,9 +238,7 @@ export const getStandardOptionEditors = () => {
id
:
'select'
,
name
:
'Select'
,
description
:
'Allows option selection'
,
editor
:
props
=>
(
<
Select
value=
{
props
.
value
}
onChange=
{
e
=>
props
.
onChange
(
e
.
value
)
}
options=
{
props
.
item
.
settings
?.
options
}
/>
),
editor
:
SelectValueEditor
as
any
,
};
const
radio
:
StandardEditorsRegistryItem
<
any
>
=
{
...
...
public/app/features/dashboard/components/PanelEditor/PanelOptionsEditor.tsx
View file @
d5266470
import
React
,
{
useMemo
}
from
'react'
;
import
{
PanelOptionsEditorItem
,
PanelPlugin
}
from
'@grafana/data'
;
import
{
PanelOptionsEditorItem
,
PanelPlugin
,
DataFrame
,
StandardEditorContext
,
InterpolateFunction
,
}
from
'@grafana/data'
;
import
{
get
as
lodashGet
,
set
as
lodashSet
}
from
'lodash'
;
import
{
Field
,
Label
}
from
'@grafana/ui'
;
import
groupBy
from
'lodash/groupBy'
;
...
...
@@ -7,11 +13,19 @@ import { OptionsGroup } from './OptionsGroup';
interface
PanelOptionsEditorProps
<
TOptions
>
{
plugin
:
PanelPlugin
;
data
?:
DataFrame
[];
replaceVariables
:
InterpolateFunction
;
options
:
TOptions
;
onChange
:
(
options
:
TOptions
)
=>
void
;
}
export
const
PanelOptionsEditor
:
React
.
FC
<
PanelOptionsEditorProps
<
any
>>
=
({
plugin
,
options
,
onChange
})
=>
{
export
const
PanelOptionsEditor
:
React
.
FC
<
PanelOptionsEditorProps
<
any
>>
=
({
plugin
,
options
,
onChange
,
data
,
replaceVariables
,
})
=>
{
const
optionEditors
=
useMemo
<
Record
<
string
,
PanelOptionsEditorItem
[]
>>
(()
=>
{
return
groupBy
(
plugin
.
optionEditors
.
list
(),
i
=>
{
return
i
.
category
?
i
.
category
[
0
]
:
'Display'
;
...
...
@@ -23,6 +37,11 @@ export const PanelOptionsEditor: React.FC<PanelOptionsEditorProps<any>> = ({ plu
onChange
(
newOptions
);
};
const
context
:
StandardEditorContext
=
{
data
:
data
??
[],
replaceVariables
,
};
return
(
<>
{
Object
.
keys
(
optionEditors
).
map
((
c
,
i
)
=>
{
...
...
@@ -43,6 +62,7 @@ export const PanelOptionsEditor: React.FC<PanelOptionsEditorProps<any>> = ({ plu
value=
{
lodashGet
(
options
,
e
.
path
)
}
onChange=
{
value
=>
onOptionChange
(
e
.
path
,
value
)
}
item=
{
e
}
context=
{
context
}
/>
</
Field
>
);
...
...
public/app/features/dashboard/components/PanelEditor/PanelOptionsTab.tsx
View file @
d5266470
...
...
@@ -83,7 +83,9 @@ export const PanelOptionsTab: FC<Props> = ({
key=
"panel options"
options=
{
panel
.
getOptions
()
}
onChange=
{
onPanelOptionsChanged
}
replaceVariables=
{
panel
.
replaceVariables
}
plugin=
{
plugin
}
data=
{
data
?.
series
}
/>
);
}
...
...
public/app/plugins/panel/stat/types.ts
View file @
d5266470
import
{
SingleStatBaseOptions
,
BigValueColorMode
,
BigValueGraphMode
,
BigValueJustifyMode
}
from
'@grafana/ui'
;
import
{
ReducerID
,
SelectableValue
,
standardEditorsRegistry
}
from
'@grafana/data'
;
import
{
ReducerID
,
SelectableValue
,
standardEditorsRegistry
,
FieldOverrideContext
,
getFieldDisplayName
,
escapeStringForRegex
,
}
from
'@grafana/data'
;
import
{
PanelOptionsEditorBuilder
}
from
'@grafana/data'
;
// Structure copied from angular
...
...
@@ -26,7 +33,8 @@ export const justifyModes: Array<SelectableValue<BigValueJustifyMode>> = [
export
function
addStandardDataReduceOptions
(
builder
:
PanelOptionsEditorBuilder
<
SingleStatBaseOptions
>
,
includeOrientation
=
true
includeOrientation
=
true
,
includeFieldMatcher
=
true
)
{
builder
.
addRadio
({
path
:
'reduceOptions.values'
,
...
...
@@ -65,6 +73,35 @@ export function addStandardDataReduceOptions(
showIf
:
currentConfig
=>
currentConfig
.
reduceOptions
.
values
===
false
,
});
if
(
includeFieldMatcher
)
{
builder
.
addSelect
({
path
:
'reduceOptions.fields'
,
name
:
'Fields'
,
description
:
'Select the fields that should be included in the panel'
,
settings
:
{
allowCustomValue
:
true
,
options
:
[],
getOptions
:
async
(
context
:
FieldOverrideContext
)
=>
{
const
options
=
[
{
value
:
''
,
label
:
'Numeric Fields'
},
{
value
:
'/.*/'
,
label
:
'All Fields'
},
];
if
(
context
&&
context
.
data
)
{
for
(
const
frame
of
context
.
data
)
{
for
(
const
field
of
frame
.
fields
)
{
const
name
=
getFieldDisplayName
(
field
,
frame
,
context
.
data
);
const
value
=
`/^
${
escapeStringForRegex
(
name
)}
$/`
;
options
.
push
({
value
,
label
:
name
});
}
}
}
return
Promise
.
resolve
(
options
);
},
},
defaultValue
:
''
,
});
}
if
(
includeOrientation
)
{
builder
.
addRadio
({
path
:
'orientation'
,
...
...
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