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
e8ae6fd0
Unverified
Commit
e8ae6fd0
authored
Dec 08, 2020
by
Ryan McKinley
Committed by
GitHub
Dec 08, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
GraphNG: simple settings migration from flot panel (#29599)
parent
3ce93050
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
593 additions
and
0 deletions
+593
-0
public/app/plugins/panel/graph3/__snapshots__/migrations.test.ts.snap
+122
-0
public/app/plugins/panel/graph3/migrations.test.ts
+203
-0
public/app/plugins/panel/graph3/migrations.ts
+266
-0
public/app/plugins/panel/graph3/module.tsx
+2
-0
No files found.
public/app/plugins/panel/graph3/__snapshots__/migrations.test.ts.snap
0 → 100644
View file @
e8ae6fd0
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Graph Migrations simple bars 1`] = `
Object {
"fieldConfig": Object {
"defaults": Object {
"custom": Object {
"drawStyle": "bars",
"fillOpacity": 1,
"showPoints": "never",
"spanNulls": false,
},
},
"overrides": Array [],
},
"options": Object {
"graph": Object {},
"legend": Object {
"displayMode": "list",
"placement": "bottom",
},
"tooltipOptions": Object {
"mode": "single",
},
},
}
`;
exports[`Graph Migrations stairscase 1`] = `
Object {
"fieldConfig": Object {
"defaults": Object {
"custom": Object {
"axisPlacement": "hidden",
"drawStyle": "line",
"fillOpacity": 0.5,
"lineInterpolation": "stepAfter",
"pointSize": 2,
"showPoints": "never",
"spanNulls": true,
},
"displayName": "DISPLAY NAME",
"nullValueMode": "null",
"unit": "short",
},
"overrides": Array [],
},
"options": Object {
"graph": Object {},
"legend": Object {
"displayMode": "list",
"placement": "bottom",
},
"tooltipOptions": Object {
"mode": "single",
},
},
}
`;
exports[`Graph Migrations twoYAxis 1`] = `
Object {
"fieldConfig": Object {
"defaults": Object {
"custom": Object {
"axisLabel": "Y111",
"axisPlacement": "auto",
"drawStyle": "line",
"fillOpacity": 0.1,
"pointSize": 2,
"showPoints": "never",
"spanNulls": true,
},
"decimals": 3,
"max": 1000,
"min": 0,
"nullValueMode": "null",
"unit": "areaMI2",
},
"overrides": Array [
Object {
"matcher": Object {
"id": "byName",
"options": "B-series",
},
"properties": Array [
Object {
"id": "unit",
"value": "degree",
},
Object {
"id": "decimals",
"value": 2,
},
Object {
"id": "min",
"value": -10,
},
Object {
"id": "max",
"value": 25,
},
Object {
"id": "custom.axisLabel",
"value": "Y222",
},
],
},
],
},
"options": Object {
"graph": Object {},
"legend": Object {
"displayMode": "list",
"placement": "bottom",
},
"tooltipOptions": Object {
"mode": "single",
},
},
}
`;
public/app/plugins/panel/graph3/migrations.test.ts
0 → 100644
View file @
e8ae6fd0
import
{
PanelModel
}
from
'@grafana/data'
;
import
{
graphPanelChangedHandler
}
from
'./migrations'
;
describe
(
'Graph Migrations'
,
()
=>
{
it
(
'simple bars'
,
()
=>
{
const
old
:
any
=
{
angular
:
{
bars
:
true
,
},
};
const
panel
=
{}
as
PanelModel
;
panel
.
options
=
graphPanelChangedHandler
(
panel
,
'graph'
,
old
);
expect
(
panel
).
toMatchSnapshot
();
});
it
(
'stairscase'
,
()
=>
{
const
old
:
any
=
{
angular
:
stairscase
,
};
const
panel
=
{}
as
PanelModel
;
panel
.
options
=
graphPanelChangedHandler
(
panel
,
'graph'
,
old
);
expect
(
panel
).
toMatchSnapshot
();
});
it
(
'twoYAxis'
,
()
=>
{
const
old
:
any
=
{
angular
:
twoYAxis
,
};
const
panel
=
{}
as
PanelModel
;
panel
.
options
=
graphPanelChangedHandler
(
panel
,
'graph'
,
old
);
expect
(
panel
).
toMatchSnapshot
();
});
});
const
stairscase
=
{
fieldConfig
:
{
defaults
:
{
custom
:
{},
unit
:
'areaF2'
,
displayName
:
'DISPLAY NAME'
,
},
overrides
:
[],
},
aliasColors
:
{},
dashLength
:
10
,
fill
:
5
,
fillGradient
:
6
,
legend
:
{
avg
:
true
,
current
:
true
,
max
:
true
,
min
:
true
,
show
:
true
,
total
:
true
,
values
:
true
,
alignAsTable
:
true
,
},
lines
:
true
,
linewidth
:
1
,
nullPointMode
:
'null'
,
options
:
{
alertThreshold
:
true
,
},
pointradius
:
2
,
seriesOverrides
:
[],
spaceLength
:
10
,
steppedLine
:
true
,
thresholds
:
[],
timeRegions
:
[],
title
:
'Panel Title'
,
tooltip
:
{
shared
:
true
,
sort
:
0
,
value_type
:
'individual'
,
},
type
:
'graph'
,
xaxis
:
{
buckets
:
null
,
mode
:
'time'
,
name
:
null
,
show
:
true
,
values
:
[],
},
yaxes
:
[
{
$
$hashKey
:
'object:42'
,
format
:
'short'
,
label
:
null
,
logBase
:
1
,
max
:
null
,
min
:
null
,
show
:
false
,
},
{
$
$hashKey
:
'object:43'
,
format
:
'short'
,
label
:
null
,
logBase
:
1
,
max
:
null
,
min
:
null
,
show
:
true
,
},
],
yaxis
:
{
align
:
false
,
alignLevel
:
null
,
},
timeFrom
:
null
,
timeShift
:
null
,
bars
:
false
,
dashes
:
false
,
hiddenSeries
:
false
,
percentage
:
false
,
points
:
false
,
stack
:
false
,
decimals
:
1
,
datasource
:
null
,
};
const
twoYAxis
=
{
yaxes
:
[
{
label
:
'Y111'
,
show
:
true
,
logBase
:
10
,
min
:
'0'
,
max
:
'1000'
,
format
:
'areaMI2'
,
$
$hashKey
:
'object:19'
,
decimals
:
3
,
},
{
label
:
'Y222'
,
show
:
true
,
logBase
:
1
,
min
:
'-10'
,
max
:
'25'
,
format
:
'degree'
,
$
$hashKey
:
'object:20'
,
decimals
:
2
,
},
],
xaxis
:
{
show
:
true
,
mode
:
'time'
,
name
:
null
,
values
:
[],
buckets
:
null
,
},
yaxis
:
{
align
:
false
,
alignLevel
:
null
,
},
lines
:
true
,
fill
:
1
,
linewidth
:
1
,
dashLength
:
10
,
spaceLength
:
10
,
pointradius
:
2
,
legend
:
{
show
:
true
,
values
:
false
,
min
:
false
,
max
:
false
,
current
:
false
,
total
:
false
,
avg
:
false
,
},
nullPointMode
:
'null'
,
tooltip
:
{
value_type
:
'individual'
,
shared
:
true
,
sort
:
0
,
},
aliasColors
:
{},
seriesOverrides
:
[
{
alias
:
'B-series'
,
yaxis
:
2
,
},
],
thresholds
:
[],
timeRegions
:
[],
targets
:
[
{
refId
:
'A'
,
},
{
refId
:
'B'
,
},
],
fillGradient
:
0
,
dashes
:
false
,
hiddenSeries
:
false
,
points
:
false
,
bars
:
false
,
stack
:
false
,
percentage
:
false
,
steppedLine
:
false
,
timeFrom
:
null
,
timeShift
:
null
,
datasource
:
null
,
};
public/app/plugins/panel/graph3/migrations.ts
0 → 100644
View file @
e8ae6fd0
import
{
FieldConfig
,
FieldConfigSource
,
NullValueMode
,
PanelModel
,
fieldReducers
,
ConfigOverrideRule
,
FieldMatcherID
,
DynamicConfigValue
,
}
from
'@grafana/data'
;
import
{
GraphFieldConfig
,
LegendDisplayMode
}
from
'@grafana/ui'
;
import
{
AxisPlacement
,
DrawStyle
,
LineInterpolation
,
PointVisibility
}
from
'@grafana/ui/src/components/uPlot/config'
;
import
{
Options
}
from
'./types'
;
import
omitBy
from
'lodash/omitBy'
;
import
isNil
from
'lodash/isNil'
;
import
{
isNumber
,
isString
}
from
'lodash'
;
/**
* This is called when the panel changes from another panel
*/
export
const
graphPanelChangedHandler
=
(
panel
:
PanelModel
<
Partial
<
Options
>>
|
any
,
prevPluginId
:
string
,
prevOptions
:
any
)
=>
{
// Changing from angular/flot panel to react/uPlot
if
(
prevPluginId
===
'graph'
&&
prevOptions
.
angular
)
{
const
{
fieldConfig
,
options
}
=
flotToGraphOptions
(
prevOptions
.
angular
);
panel
.
fieldConfig
=
fieldConfig
;
// Mutates the incoming panel
return
options
;
}
return
{};
};
export
function
flotToGraphOptions
(
angular
:
any
):
{
fieldConfig
:
FieldConfigSource
;
options
:
Options
}
{
const
overrides
:
ConfigOverrideRule
[]
=
angular
.
fieldConfig
?.
overrides
??
[];
const
yaxes
=
angular
.
yaxes
??
[];
let
y1
=
getFieldConfigFromOldAxis
(
yaxes
[
0
]);
if
(
angular
.
fieldConfig
?.
defaults
)
{
y1
=
{
...
angular
.
fieldConfig
?.
defaults
,
...
y1
,
// Keep the y-axis unit and custom
};
}
// "seriesOverrides": [
// {
// "$$hashKey": "object:183",
// "alias": "B-series",
// "fill": 3,
// "nullPointMode": "null as zero",
// "lines": true,
// "linewidth": 2
// }
// ],
if
(
angular
.
seriesOverrides
?.
length
)
{
for
(
const
seriesOverride
of
angular
.
seriesOverrides
)
{
if
(
!
seriesOverride
.
alias
)
{
continue
;
// the matcher config
}
const
rule
:
ConfigOverrideRule
=
{
matcher
:
{
id
:
FieldMatcherID
.
byName
,
options
:
seriesOverride
.
alias
,
},
properties
:
[],
};
for
(
const
p
of
Object
.
keys
(
seriesOverride
))
{
const
v
=
seriesOverride
[
p
];
switch
(
p
)
{
// Ignore
case
'alias'
:
case
'$$hashKey'
:
break
;
// Link to y axis settings
case
'yaxis'
:
if
(
2
===
v
)
{
const
y2
=
getFieldConfigFromOldAxis
(
yaxes
[
1
]);
fillY2DynamicValues
(
y1
,
y2
,
rule
.
properties
);
}
break
;
case
'fill'
:
rule
.
properties
.
push
({
id
:
'custom.fillOpacity'
,
value
:
v
/
10.0
,
// was 0-10
});
break
;
case
'points'
:
rule
.
properties
.
push
({
id
:
'custom.showPoints'
,
value
:
v
?
PointVisibility
.
Always
:
PointVisibility
.
Never
,
});
break
;
case
'bars'
:
if
(
v
)
{
rule
.
properties
.
push
({
id
:
'custom.drawStyle'
,
value
:
DrawStyle
.
Bars
,
});
rule
.
properties
.
push
({
id
:
'custom.fillOpacity'
,
value
:
1
,
// solid bars
});
}
else
{
rule
.
properties
.
push
({
id
:
'custom.drawStyle'
,
value
:
DrawStyle
.
Line
,
// Change from bars
});
}
break
;
case
'lineWidth'
:
rule
.
properties
.
push
({
id
:
'custom.lineWidth'
,
value
:
v
,
});
break
;
case
'pointradius'
:
rule
.
properties
.
push
({
id
:
'custom.pointSize'
,
value
:
v
,
});
break
;
default
:
console
.
log
(
'Ignore override migration:'
,
seriesOverride
.
alias
,
p
,
v
);
}
}
if
(
rule
.
properties
.
length
)
{
overrides
.
push
(
rule
);
}
}
}
const
graph
=
y1
.
custom
??
({}
as
GraphFieldConfig
);
graph
.
drawStyle
=
angular
.
bars
?
DrawStyle
.
Bars
:
angular
.
lines
?
DrawStyle
.
Line
:
DrawStyle
.
Points
;
if
(
angular
.
points
)
{
graph
.
showPoints
=
PointVisibility
.
Always
;
}
else
if
(
graph
.
drawStyle
!==
DrawStyle
.
Points
)
{
graph
.
showPoints
=
PointVisibility
.
Never
;
}
if
(
graph
.
drawStyle
===
DrawStyle
.
Bars
)
{
graph
.
fillOpacity
=
1.0
;
// bars were always
}
graph
.
lineWidth
=
angular
.
lineWidth
;
graph
.
pointSize
=
angular
.
pointradius
;
if
(
isNumber
(
angular
.
fill
))
{
graph
.
fillOpacity
=
angular
.
fill
/
10
;
// fill is 0-10
}
graph
.
spanNulls
=
angular
.
nullPointMode
===
NullValueMode
.
Null
;
if
(
angular
.
steppedLine
)
{
graph
.
lineInterpolation
=
LineInterpolation
.
StepAfter
;
}
y1
.
custom
=
omitBy
(
graph
,
isNil
);
y1
.
nullValueMode
=
angular
.
nullPointMode
as
NullValueMode
;
const
options
:
Options
=
{
graph
:
{},
legend
:
{
displayMode
:
LegendDisplayMode
.
List
,
placement
:
'bottom'
,
},
tooltipOptions
:
{
mode
:
'single'
,
},
};
if
(
angular
.
legend
?.
values
)
{
const
show
=
getReducersFromLegend
(
angular
.
legend
?.
values
);
console
.
log
(
'Migrate Legend'
,
show
);
}
return
{
fieldConfig
:
{
defaults
:
omitBy
(
y1
,
isNil
),
overrides
,
},
options
,
};
}
// {
// "label": "Y111",
// "show": true,
// "logBase": 10,
// "min": "0",
// "max": "1000",
// "format": "areaMI2",
// "$$hashKey": "object:19",
// "decimals": 3
// },
function
getFieldConfigFromOldAxis
(
obj
:
any
):
FieldConfig
<
GraphFieldConfig
>
{
if
(
!
obj
)
{
return
{};
}
const
graph
:
GraphFieldConfig
=
{
axisPlacement
:
obj
.
show
?
AxisPlacement
.
Auto
:
AxisPlacement
.
Hidden
,
};
if
(
obj
.
label
)
{
graph
.
axisLabel
=
obj
.
label
;
}
return
omitBy
(
{
unit
:
obj
.
format
,
decimals
:
validNumber
(
obj
.
decimals
),
min
:
validNumber
(
obj
.
min
),
max
:
validNumber
(
obj
.
max
),
custom
:
graph
,
},
isNil
);
}
function
fillY2DynamicValues
(
y1
:
FieldConfig
<
GraphFieldConfig
>
,
y2
:
FieldConfig
<
GraphFieldConfig
>
,
props
:
DynamicConfigValue
[]
)
{
// The standard properties
for
(
const
key
of
Object
.
keys
(
y2
))
{
const
value
=
(
y2
as
any
)[
key
];
if
(
key
!==
'custom'
&&
value
!==
(
y1
as
any
)[
key
])
{
props
.
push
({
id
:
key
,
value
,
});
}
}
// Add any custom property
const
y1G
=
y1
.
custom
??
{};
const
y2G
=
y2
.
custom
??
{};
for
(
const
key
of
Object
.
keys
(
y2G
))
{
const
value
=
(
y2G
as
any
)[
key
];
if
(
value
!==
(
y1G
as
any
)[
key
])
{
props
.
push
({
id
:
`custom.
${
key
}
`
,
value
,
});
}
}
}
function
validNumber
(
val
:
any
):
number
|
undefined
{
if
(
isNumber
(
val
))
{
return
val
;
}
if
(
isString
(
val
))
{
const
num
=
Number
(
val
);
if
(
!
isNaN
(
num
))
{
return
num
;
}
}
return
undefined
;
}
function
getReducersFromLegend
(
obj
:
Record
<
string
,
any
>
):
string
[]
{
const
ids
:
string
[]
=
[];
for
(
const
key
of
Object
.
keys
(
obj
))
{
const
r
=
fieldReducers
.
getIfExists
(
key
);
if
(
r
)
{
ids
.
push
(
r
.
id
);
}
}
return
ids
;
}
public/app/plugins/panel/graph3/module.tsx
View file @
e8ae6fd0
...
@@ -8,9 +8,11 @@ import {
...
@@ -8,9 +8,11 @@ import {
graphFieldOptions
,
graphFieldOptions
,
}
from
'@grafana/ui/src/components/uPlot/config'
;
}
from
'@grafana/ui/src/components/uPlot/config'
;
import
{
GraphPanel
}
from
'./GraphPanel'
;
import
{
GraphPanel
}
from
'./GraphPanel'
;
import
{
graphPanelChangedHandler
}
from
'./migrations'
;
import
{
Options
}
from
'./types'
;
import
{
Options
}
from
'./types'
;
export
const
plugin
=
new
PanelPlugin
<
Options
,
GraphFieldConfig
>
(
GraphPanel
)
export
const
plugin
=
new
PanelPlugin
<
Options
,
GraphFieldConfig
>
(
GraphPanel
)
.
setPanelChangeHandler
(
graphPanelChangedHandler
)
.
useFieldConfig
({
.
useFieldConfig
({
standardOptions
:
{
standardOptions
:
{
[
FieldConfigProperty
.
Color
]:
{
[
FieldConfigProperty
.
Color
]:
{
...
...
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