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
6fd37779
Commit
6fd37779
authored
May 15, 2015
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More work on new influxdb query editor, #1525
parent
d14b570d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
203 additions
and
27 deletions
+203
-27
public/app/plugins/datasource/influxdb/partials/query.editor.html
+1
-1
public/app/plugins/datasource/influxdb/queryBuilder.js
+11
-5
public/app/plugins/datasource/influxdb/queryCtrl.js
+63
-16
public/css/less/grafana.less
+12
-0
public/test/specs/influx09-querybuilder-specs.js
+32
-3
public/test/specs/influxdbQueryCtrl-specs.js
+84
-2
No files found.
public/app/plugins/datasource/influxdb/partials/query.editor.html
View file @
6fd37779
...
...
@@ -91,7 +91,7 @@
time($interval)
</li>
<li
ng-repeat=
"segment in groupBySegments"
>
<metric-segment
segment=
"segment"
get-alt-segments=
"get
TagsOrValue
s(segment, 0)"
on-value-changed=
"groupByTagUpdated(segment, $index)"
></metric-segment>
<metric-segment
segment=
"segment"
get-alt-segments=
"get
GroupByTagSegment
s(segment, 0)"
on-value-changed=
"groupByTagUpdated(segment, $index)"
></metric-segment>
</li>
<li
class=
"dropdown"
>
<a
class=
"tight-form-item pointer"
data-toggle=
"dropdown"
bs-tooltip=
"'Insert missing values, important when stacking'"
data-placement=
"right"
>
...
...
public/app/plugins/datasource/influxdb/queryBuilder.js
View file @
6fd37779
define
([
'lodash'
'lodash'
],
function
(
_
)
{
'use strict'
;
...
...
@@ -32,12 +32,18 @@ function (_) {
}
query
+=
aggregationFunc
+
'(value)'
;
query
+=
' FROM '
+
measurement
+
' WHERE $timeFilter'
;
query
+=
_
.
map
(
target
.
tags
,
function
(
tag
)
{
return
' AND '
+
tag
.
key
+
'='
+
"'"
+
tag
.
value
+
"'"
;
}).
join
(
''
);
query
+=
' FROM '
+
measurement
+
' WHERE '
;
var
conditions
=
_
.
map
(
target
.
tags
,
function
(
tag
)
{
return
tag
.
key
+
'='
+
"'"
+
tag
.
value
+
"' "
;
});
conditions
.
push
(
'$timeFilter'
);
query
+=
conditions
.
join
(
'AND '
);
query
+=
' GROUP BY time($interval)'
;
if
(
target
.
groupByTags
&&
target
.
groupByTags
.
length
>
0
)
{
query
+=
', '
+
target
.
groupByTags
.
join
();
}
if
(
target
.
fill
)
{
query
+=
' fill('
+
target
.
fill
+
')'
;
...
...
public/app/plugins/datasource/influxdb/queryCtrl.js
View file @
6fd37779
...
...
@@ -35,14 +35,12 @@ function (angular, _) {
if
(
tag
.
condition
)
{
$scope
.
tagSegments
.
push
(
MetricSegment
.
newCondition
(
tag
.
condition
));
}
$scope
.
tagSegments
.
push
(
new
MetricSegment
({
value
:
tag
.
key
,
type
:
'key'
}));
$scope
.
tagSegments
.
push
(
new
MetricSegment
({
fake
:
true
,
value
:
"="
}));
$scope
.
tagSegments
.
push
(
new
MetricSegment
({
value
:
tag
.
value
,
type
:
'value'
}));
$scope
.
tagSegments
.
push
(
new
MetricSegment
({
value
:
tag
.
key
,
type
:
'key'
,
cssClass
:
'query-segment-key'
}));
$scope
.
tagSegments
.
push
(
new
MetricSegment
({
fake
:
true
,
value
:
"="
,
cssClass
:
'query-segment-operator'
}));
$scope
.
tagSegments
.
push
(
new
MetricSegment
({
value
:
tag
.
value
,
type
:
'value'
,
cssClass
:
'query-segment-value'
}));
});
if
(
$scope
.
tagSegments
.
length
%
3
===
0
)
{
$scope
.
tagSegments
.
push
(
MetricSegment
.
newPlusButton
());
}
$scope
.
fixTagSegments
();
$scope
.
groupBySegments
=
[];
_
.
each
(
target
.
groupByTags
,
function
(
tag
)
{
...
...
@@ -50,12 +48,37 @@ function (angular, _) {
});
$scope
.
groupBySegments
.
push
(
MetricSegment
.
newPlusButton
());
$scope
.
removeTagFilterSegment
=
new
MetricSegment
({
fake
:
true
,
value
:
'remove tag filter'
});
$scope
.
removeGroupBySegment
=
new
MetricSegment
({
fake
:
true
,
value
:
'remove group by'
});
};
$scope
.
fixTagSegments
=
function
()
{
var
count
=
$scope
.
tagSegments
.
length
;
var
lastSegment
=
$scope
.
tagSegments
[
Math
.
max
(
count
-
1
,
0
)];
if
(
!
lastSegment
||
lastSegment
.
type
!==
'plus-button'
)
{
$scope
.
tagSegments
.
push
(
MetricSegment
.
newPlusButton
());
}
};
$scope
.
groupByTagUpdated
=
function
(
segment
,
index
)
{
if
(
segment
.
value
===
$scope
.
removeGroupBySegment
.
value
)
{
$scope
.
target
.
groupByTags
.
splice
(
index
,
1
);
$scope
.
groupBySegments
.
splice
(
index
,
1
);
$scope
.
$parent
.
get_data
();
return
;
}
if
(
index
===
$scope
.
groupBySegments
.
length
-
1
)
{
$scope
.
groupBySegments
.
push
(
MetricSegment
.
newPlusButton
());
}
segment
.
type
=
'group-by-key'
;
segment
.
fake
=
false
;
$scope
.
target
.
groupByTags
[
index
]
=
segment
.
value
;
$scope
.
$parent
.
get_data
();
};
$scope
.
changeFunction
=
function
(
func
)
{
...
...
@@ -65,7 +88,6 @@ function (angular, _) {
$scope
.
measurementChanged
=
function
()
{
$scope
.
target
.
measurement
=
$scope
.
measurementSegment
.
value
;
console
.
log
(
'measurement updated'
,
$scope
.
target
.
measurement
);
$scope
.
$parent
.
get_data
();
};
...
...
@@ -126,8 +148,23 @@ function (angular, _) {
.
then
(
$scope
.
transformToSegments
)
.
then
(
$scope
.
addTemplateVariableSegments
)
.
then
(
function
(
results
)
{
if
(
queryType
===
'TAG_KEYS'
&&
segment
.
type
!==
'plus-button'
)
{
results
.
push
(
new
MetricSegment
({
fake
:
true
,
value
:
'remove tag filter'
}));
if
(
queryType
===
'TAG_KEYS'
&&
segment
.
type
===
'key'
)
{
results
.
push
(
angular
.
copy
(
$scope
.
removeTagFilterSegment
));
}
return
results
;
})
.
then
(
null
,
$scope
.
handleQueryError
);
};
$scope
.
getGroupByTagSegments
=
function
(
segment
)
{
var
query
=
'SHOW TAG KEYS FROM "'
+
$scope
.
target
.
measurement
+
'"'
;
return
$scope
.
datasource
.
metricFindQuery
(
query
,
'TAG_KEYS'
)
.
then
(
$scope
.
transformToSegments
)
.
then
(
$scope
.
addTemplateVariableSegments
)
.
then
(
function
(
results
)
{
if
(
segment
.
type
!==
'plus-button'
)
{
results
.
push
(
angular
.
copy
(
$scope
.
removeGroupBySegment
));
}
return
results
;
})
...
...
@@ -137,13 +174,15 @@ function (angular, _) {
$scope
.
tagSegmentUpdated
=
function
(
segment
,
index
)
{
$scope
.
tagSegments
[
index
]
=
segment
;
if
(
segment
.
value
===
'remove tag filter'
)
{
if
(
segment
.
value
===
$scope
.
removeTagFilterSegment
.
value
)
{
$scope
.
tagSegments
.
splice
(
index
,
3
);
if
(
$scope
.
tagSegments
.
length
===
0
)
{
$scope
.
tagSegments
.
push
(
MetricSegment
.
newPlusButton
());
}
else
{
$scope
.
tagSegments
.
splice
(
index
-
1
,
1
);
$scope
.
tagSegments
.
push
(
MetricSegment
.
newPlusButton
());
}
else
if
(
$scope
.
tagSegments
.
length
>
2
)
{
$scope
.
tagSegments
.
splice
(
Math
.
max
(
index
-
1
,
0
),
1
);
if
(
$scope
.
tagSegments
[
$scope
.
tagSegments
.
length
-
1
].
type
!==
'plus-button'
)
{
$scope
.
tagSegments
.
push
(
MetricSegment
.
newPlusButton
());
}
}
}
else
{
...
...
@@ -151,9 +190,10 @@ function (angular, _) {
if
(
index
>
2
)
{
$scope
.
tagSegments
.
splice
(
index
,
0
,
MetricSegment
.
newCondition
(
'AND'
));
}
$scope
.
tagSegments
.
push
(
new
MetricSegment
({
fake
:
true
,
value
:
'='
,
type
:
'operator'
}
));
$scope
.
tagSegments
.
push
(
new
MetricSegment
({
fake
:
true
,
value
:
'select tag value'
,
type
:
'value'
}
));
$scope
.
tagSegments
.
push
(
MetricSegment
.
newFake
(
'='
,
'operator'
,
'query-segment-operator'
));
$scope
.
tagSegments
.
push
(
MetricSegment
.
newFake
(
'select tag value'
,
'value'
,
'query-segment-value'
));
segment
.
type
=
'key'
;
segment
.
cssClass
=
'query-segment-key'
;
}
if
((
index
+
1
)
===
$scope
.
tagSegments
.
length
)
{
...
...
@@ -165,10 +205,13 @@ function (angular, _) {
};
$scope
.
rebuildTargetTagConditions
=
function
()
{
var
tags
=
[
{}
];
var
tags
=
[];
var
tagIndex
=
0
;
_
.
each
(
$scope
.
tagSegments
,
function
(
segment2
)
{
if
(
segment2
.
type
===
'key'
)
{
if
(
tags
.
length
===
0
)
{
tags
.
push
({});
}
tags
[
tagIndex
].
key
=
segment2
.
value
;
}
else
if
(
segment2
.
type
===
'value'
)
{
...
...
@@ -211,6 +254,10 @@ function (angular, _) {
return
new
MetricSegment
({
value
:
'select measurement'
,
fake
:
true
});
};
MetricSegment
.
newFake
=
function
(
text
,
type
,
cssClass
)
{
return
new
MetricSegment
({
value
:
text
,
fake
:
true
,
type
:
type
,
cssClass
:
cssClass
});
};
MetricSegment
.
newCondition
=
function
(
condition
)
{
return
new
MetricSegment
({
value
:
condition
,
type
:
'condition'
,
cssClass
:
'query-keyword'
});
};
...
...
public/css/less/grafana.less
View file @
6fd37779
...
...
@@ -343,4 +343,16 @@
color: @blue;
}
.query-segment-key {
border-right: none;
padding-right: 1px;
}
.query-segment-operator {
padding-right: 1px;
border-right: none;
color: @orange;
}
public/test/specs/influx09-querybuilder-specs.js
View file @
6fd37779
...
...
@@ -18,7 +18,7 @@ define([
});
describe
(
'series with
tags
only'
,
function
()
{
describe
(
'series with
single tag
only'
,
function
()
{
var
builder
=
new
InfluxQueryBuilder
({
measurement
:
'cpu'
,
tags
:
[{
key
:
'hostname'
,
value
:
'server1'
}]
...
...
@@ -27,10 +27,39 @@ define([
var
query
=
builder
.
build
();
it
(
'should generate correct query'
,
function
()
{
expect
(
query
).
to
.
be
(
'SELECT mean(value) FROM "cpu" WHERE $timeFilter '
+
'AND hostname=
\'
server1
\'
GROUP BY time($interval) ORDER BY asc'
);
expect
(
query
).
to
.
be
(
'SELECT mean(value) FROM "cpu" WHERE hostname=
\'
server1
\'
AND $timeFilter'
+
' GROUP BY time($interval) ORDER BY asc'
);
});
});
describe
(
'series with multiple tags only'
,
function
()
{
var
builder
=
new
InfluxQueryBuilder
({
measurement
:
'cpu'
,
tags
:
[{
key
:
'hostname'
,
value
:
'server1'
},
{
key
:
'app'
,
value
:
'email'
,
condition
:
"AND"
}]
});
var
query
=
builder
.
build
();
it
(
'should generate correct query'
,
function
()
{
expect
(
query
).
to
.
be
(
'SELECT mean(value) FROM "cpu" WHERE hostname=
\'
server1
\'
AND app=
\'
email
\'
AND '
+
'$timeFilter GROUP BY time($interval) ORDER BY asc'
);
});
});
describe
(
'series with groupByTag'
,
function
()
{
var
builder
=
new
InfluxQueryBuilder
({
measurement
:
'cpu'
,
tags
:
[],
groupByTags
:
[
"host"
]
});
var
query
=
builder
.
build
();
it
(
'should generate correct query'
,
function
()
{
expect
(
query
).
to
.
be
(
'SELECT mean(value) FROM "cpu" WHERE $timeFilter '
+
'GROUP BY time($interval), host ORDER BY asc'
);
});
});
});
...
...
public/test/specs/influxdbQueryCtrl-specs.js
View file @
6fd37779
...
...
@@ -101,13 +101,31 @@ define([
});
});
describe
(
'when deleting is changed'
,
function
()
{
describe
(
'when deleting first tag filter after value is selected'
,
function
()
{
beforeEach
(
function
()
{
ctx
.
scope
.
init
();
ctx
.
scope
.
tagSegmentUpdated
({
value
:
'asd'
,
type
:
'plus-button'
},
0
);
ctx
.
scope
.
tagSegmentUpdated
({
value
:
'server1'
,
type
:
'value'
},
2
);
ctx
.
scope
.
tagSegmentUpdated
(
ctx
.
scope
.
removeTagFilterSegment
,
0
);
});
it
(
'should remove tags'
,
function
()
{
expect
(
ctx
.
scope
.
target
.
tags
.
length
).
to
.
be
(
0
);
});
it
(
'should remove all segment after 2 and replace with plus button'
,
function
()
{
expect
(
ctx
.
scope
.
tagSegments
.
length
).
to
.
be
(
1
);
expect
(
ctx
.
scope
.
tagSegments
[
0
].
type
).
to
.
be
(
'plus-button'
);
});
});
describe
(
'when deleting second tag value before second tag value is complete'
,
function
()
{
beforeEach
(
function
()
{
ctx
.
scope
.
init
();
ctx
.
scope
.
tagSegmentUpdated
({
value
:
'asd'
,
type
:
'plus-button'
},
0
);
ctx
.
scope
.
tagSegmentUpdated
({
value
:
'server1'
,
type
:
'value'
},
2
);
ctx
.
scope
.
tagSegmentUpdated
({
value
:
'key2'
,
type
:
'plus-button'
},
3
);
ctx
.
scope
.
tagSegmentUpdated
(
{
value
:
'remove tag filter'
,
type
:
'key'
}
,
4
);
ctx
.
scope
.
tagSegmentUpdated
(
ctx
.
scope
.
removeTagFilterSegment
,
4
);
});
it
(
'should remove all segment after 2 and replace with plus button'
,
function
()
{
...
...
@@ -116,5 +134,69 @@ define([
});
});
describe
(
'when deleting second tag value before second tag value is complete'
,
function
()
{
beforeEach
(
function
()
{
ctx
.
scope
.
init
();
ctx
.
scope
.
tagSegmentUpdated
({
value
:
'asd'
,
type
:
'plus-button'
},
0
);
ctx
.
scope
.
tagSegmentUpdated
({
value
:
'server1'
,
type
:
'value'
},
2
);
ctx
.
scope
.
tagSegmentUpdated
({
value
:
'key2'
,
type
:
'plus-button'
},
3
);
ctx
.
scope
.
tagSegmentUpdated
(
ctx
.
scope
.
removeTagFilterSegment
,
4
);
});
it
(
'should remove all segment after 2 and replace with plus button'
,
function
()
{
expect
(
ctx
.
scope
.
tagSegments
.
length
).
to
.
be
(
4
);
expect
(
ctx
.
scope
.
tagSegments
[
3
].
type
).
to
.
be
(
'plus-button'
);
});
});
describe
(
'when deleting second tag value after second tag filter is complete'
,
function
()
{
beforeEach
(
function
()
{
ctx
.
scope
.
init
();
ctx
.
scope
.
tagSegmentUpdated
({
value
:
'asd'
,
type
:
'plus-button'
},
0
);
ctx
.
scope
.
tagSegmentUpdated
({
value
:
'server1'
,
type
:
'value'
},
2
);
ctx
.
scope
.
tagSegmentUpdated
({
value
:
'key2'
,
type
:
'plus-button'
},
3
);
ctx
.
scope
.
tagSegmentUpdated
({
value
:
'value'
,
type
:
'value'
},
6
);
ctx
.
scope
.
tagSegmentUpdated
(
ctx
.
scope
.
removeTagFilterSegment
,
4
);
});
it
(
'should remove all segment after 2 and replace with plus button'
,
function
()
{
expect
(
ctx
.
scope
.
tagSegments
.
length
).
to
.
be
(
4
);
expect
(
ctx
.
scope
.
tagSegments
[
3
].
type
).
to
.
be
(
'plus-button'
);
});
});
describe
(
'when adding group by'
,
function
()
{
beforeEach
(
function
()
{
ctx
.
scope
.
init
();
ctx
.
scope
.
groupByTagUpdated
({
value
:
'host'
,
type
:
'plus-button'
},
0
);
});
it
(
'should add group by'
,
function
()
{
expect
(
ctx
.
scope
.
target
.
groupByTags
.
length
).
to
.
be
(
1
);
expect
(
ctx
.
scope
.
target
.
groupByTags
[
0
]).
to
.
be
(
'host'
);
});
it
(
'should add another plus button segment'
,
function
()
{
expect
(
ctx
.
scope
.
groupBySegments
[
1
].
type
).
to
.
be
(
'plus-button'
);
});
});
describe
(
'when removing group by'
,
function
()
{
beforeEach
(
function
()
{
ctx
.
scope
.
init
();
ctx
.
scope
.
groupByTagUpdated
({
value
:
'host'
,
type
:
'plus-button'
},
0
);
ctx
.
scope
.
groupByTagUpdated
(
ctx
.
scope
.
removeGroupBySegment
,
0
);
});
it
(
'should add group by'
,
function
()
{
expect
(
ctx
.
scope
.
target
.
groupByTags
.
length
).
to
.
be
(
0
);
});
it
(
'should remove segment'
,
function
()
{
expect
(
ctx
.
scope
.
groupBySegments
.
length
).
to
.
be
(
1
);
expect
(
ctx
.
scope
.
groupBySegments
[
0
].
type
).
to
.
be
(
'plus-button'
);
});
});
});
});
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