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
f27450ed
Unverified
Commit
f27450ed
authored
Jan 19, 2021
by
Ryan McKinley
Committed by
GitHub
Jan 19, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
GraphNG: sort ascending if the values appear reversed (#30405)
parent
e9e16cee
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
81 additions
and
19 deletions
+81
-19
packages/grafana-ui/src/components/GraphNG/GraphNG.tsx
+1
-1
packages/grafana-ui/src/components/GraphNG/utils.test.ts
+28
-1
packages/grafana-ui/src/components/GraphNG/utils.ts
+52
-17
No files found.
packages/grafana-ui/src/components/GraphNG/GraphNG.tsx
View file @
f27450ed
...
@@ -29,7 +29,7 @@ import { isNumber } from 'lodash';
...
@@ -29,7 +29,7 @@ import { isNumber } from 'lodash';
const
defaultFormatter
=
(
v
:
any
)
=>
(
v
==
null
?
'-'
:
v
.
toFixed
(
1
));
const
defaultFormatter
=
(
v
:
any
)
=>
(
v
==
null
?
'-'
:
v
.
toFixed
(
1
));
export
interface
XYFieldMatchers
{
export
interface
XYFieldMatchers
{
x
:
FieldMatcher
;
x
:
FieldMatcher
;
// first match
y
:
FieldMatcher
;
y
:
FieldMatcher
;
}
}
export
interface
GraphNGProps
extends
Omit
<
PlotProps
,
'data'
|
'config'
>
{
export
interface
GraphNGProps
extends
Omit
<
PlotProps
,
'data'
|
'config'
>
{
...
...
packages/grafana-ui/src/components/GraphNG/utils.test.ts
View file @
f27450ed
import
{
ArrayVector
,
DataFrame
,
FieldType
,
toDataFrame
}
from
'@grafana/data'
;
import
{
ArrayVector
,
DataFrame
,
FieldType
,
toDataFrame
}
from
'@grafana/data'
;
import
{
AlignedFrameWithGapTest
}
from
'../uPlot/types'
;
import
{
AlignedFrameWithGapTest
}
from
'../uPlot/types'
;
import
{
alignDataFrames
}
from
'./utils'
;
import
{
alignDataFrames
,
isLikelyAscendingVector
}
from
'./utils'
;
describe
(
'alignDataFrames'
,
()
=>
{
describe
(
'alignDataFrames'
,
()
=>
{
describe
(
'aligned frame'
,
()
=>
{
describe
(
'aligned frame'
,
()
=>
{
...
@@ -215,4 +215,31 @@ describe('alignDataFrames', () => {
...
@@ -215,4 +215,31 @@ describe('alignDataFrames', () => {
});
});
});
});
});
});
describe
(
'check ascending data'
,
()
=>
{
it
(
'simple ascending'
,
()
=>
{
const
v
=
new
ArrayVector
([
1
,
2
,
3
,
4
,
5
]);
expect
(
isLikelyAscendingVector
(
v
)).
toBeTruthy
();
});
it
(
'simple ascending with null'
,
()
=>
{
const
v
=
new
ArrayVector
([
null
,
2
,
3
,
4
,
null
]);
expect
(
isLikelyAscendingVector
(
v
)).
toBeTruthy
();
});
it
(
'single value'
,
()
=>
{
const
v
=
new
ArrayVector
([
null
,
null
,
null
,
4
,
null
]);
expect
(
isLikelyAscendingVector
(
v
)).
toBeTruthy
();
expect
(
isLikelyAscendingVector
(
new
ArrayVector
([
4
]))).
toBeTruthy
();
expect
(
isLikelyAscendingVector
(
new
ArrayVector
([]))).
toBeTruthy
();
});
it
(
'middle values'
,
()
=>
{
const
v
=
new
ArrayVector
([
null
,
null
,
5
,
4
,
null
]);
expect
(
isLikelyAscendingVector
(
v
)).
toBeFalsy
();
});
it
(
'decending'
,
()
=>
{
expect
(
isLikelyAscendingVector
(
new
ArrayVector
([
7
,
6
,
null
]))).
toBeFalsy
();
expect
(
isLikelyAscendingVector
(
new
ArrayVector
([
7
,
8
,
6
]))).
toBeFalsy
();
});
});
});
});
packages/grafana-ui/src/components/GraphNG/utils.ts
View file @
f27450ed
...
@@ -9,6 +9,8 @@ import {
...
@@ -9,6 +9,8 @@ import {
FieldType
,
FieldType
,
FieldState
,
FieldState
,
DataFrameFieldIndex
,
DataFrameFieldIndex
,
sortDataFrame
,
Vector
,
}
from
'@grafana/data'
;
}
from
'@grafana/data'
;
import
{
AlignedFrameWithGapTest
}
from
'../uPlot/types'
;
import
{
AlignedFrameWithGapTest
}
from
'../uPlot/types'
;
import
uPlot
,
{
AlignedData
,
JoinNullMode
}
from
'uplot'
;
import
uPlot
,
{
AlignedData
,
JoinNullMode
}
from
'uplot'
;
...
@@ -16,24 +18,23 @@ import { XYFieldMatchers } from './GraphNG';
...
@@ -16,24 +18,23 @@ import { XYFieldMatchers } from './GraphNG';
// the results ofter passing though data
// the results ofter passing though data
export
interface
XYDimensionFields
{
export
interface
XYDimensionFields
{
x
:
Field
[];
x
:
Field
;
// independent axis (cause)
y
:
Field
[];
y
:
Field
[];
// dependent axis (effect)
}
}
export
function
mapDimesions
(
match
:
XYFieldMatchers
,
frame
:
DataFrame
,
frames
?:
DataFrame
[]):
XYDimensionFields
{
export
function
mapDimesions
(
match
:
XYFieldMatchers
,
frame
:
DataFrame
,
frames
?:
DataFrame
[]):
XYDimensionFields
{
const
out
:
XYDimensionFields
=
{
let
x
:
Field
|
undefined
;
x
:
[],
const
y
:
Field
[]
=
[];
y
:
[],
};
for
(
const
field
of
frame
.
fields
)
{
for
(
const
field
of
frame
.
fields
)
{
if
(
match
.
x
(
field
,
frame
,
frames
??
[]))
{
if
(
!
x
&&
match
.
x
(
field
,
frame
,
frames
??
[]))
{
out
.
x
.
push
(
field
)
;
x
=
field
;
}
}
if
(
match
.
y
(
field
,
frame
,
frames
??
[]))
{
if
(
match
.
y
(
field
,
frame
,
frames
??
[]))
{
out
.
y
.
push
(
field
);
y
.
push
(
field
);
}
}
}
}
return
out
;
return
{
x
:
x
as
Field
,
y
}
;
}
}
/**
/**
...
@@ -58,26 +59,29 @@ export function alignDataFrames(frames: DataFrame[], fields?: XYFieldMatchers):
...
@@ -58,26 +59,29 @@ export function alignDataFrames(frames: DataFrame[], fields?: XYFieldMatchers):
}
}
for
(
let
frameIndex
=
0
;
frameIndex
<
frames
.
length
;
frameIndex
++
)
{
for
(
let
frameIndex
=
0
;
frameIndex
<
frames
.
length
;
frameIndex
++
)
{
cons
t
frame
=
frames
[
frameIndex
];
le
t
frame
=
frames
[
frameIndex
];
cons
t
dims
=
mapDimesions
(
fields
,
frame
,
frames
);
le
t
dims
=
mapDimesions
(
fields
,
frame
,
frames
);
if
(
!
(
dims
.
x
.
length
&&
dims
.
y
.
length
))
{
if
(
!
(
dims
.
x
&&
dims
.
y
.
length
))
{
continue
;
// no numeric and no time fields
continue
;
// no numeric and no time fields
}
}
if
(
dims
.
x
.
length
>
1
)
{
// Quick check that x is ascending order
throw
new
Error
(
'Only a single x field is supported'
);
if
(
!
isLikelyAscendingVector
(
dims
.
x
.
values
))
{
const
xIndex
=
frame
.
fields
.
indexOf
(
dims
.
x
);
frame
=
sortDataFrame
(
frame
,
xIndex
);
dims
=
mapDimesions
(
fields
,
frame
,
frames
);
}
}
let
nullModesFrame
:
JoinNullMode
[]
=
[
0
];
let
nullModesFrame
:
JoinNullMode
[]
=
[
0
];
// Add the first X axis
// Add the first X axis
if
(
!
sourceFields
.
length
)
{
if
(
!
sourceFields
.
length
)
{
sourceFields
.
push
(
dims
.
x
[
0
]
);
sourceFields
.
push
(
dims
.
x
);
}
}
const
alignedData
:
AlignedData
=
[
const
alignedData
:
AlignedData
=
[
dims
.
x
[
0
]
.
values
.
toArray
(),
// The x axis (time)
dims
.
x
.
values
.
toArray
(),
// The x axis (time)
];
];
for
(
let
fieldIndex
=
0
;
fieldIndex
<
frame
.
fields
.
length
;
fieldIndex
++
)
{
for
(
let
fieldIndex
=
0
;
fieldIndex
<
frame
.
fields
.
length
;
fieldIndex
++
)
{
...
@@ -150,3 +154,34 @@ export function alignDataFrames(frames: DataFrame[], fields?: XYFieldMatchers):
...
@@ -150,3 +154,34 @@ export function alignDataFrames(frames: DataFrame[], fields?: XYFieldMatchers):
},
},
};
};
}
}
// Quick test if the first and last points look to be ascending
export
function
isLikelyAscendingVector
(
data
:
Vector
):
boolean
{
let
first
:
any
=
undefined
;
for
(
let
idx
=
0
;
idx
<
data
.
length
;
idx
++
)
{
const
v
=
data
.
get
(
idx
);
if
(
v
!=
null
)
{
if
(
first
!=
null
)
{
if
(
first
>
v
)
{
return
false
;
// descending
}
break
;
}
first
=
v
;
}
}
let
idx
=
data
.
length
-
1
;
while
(
idx
>=
0
)
{
const
v
=
data
.
get
(
idx
--
);
if
(
v
!=
null
)
{
if
(
first
>
v
)
{
return
false
;
}
return
true
;
}
}
return
true
;
// only one non-null point
}
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