mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge remote-tracking branch 'grafana/master' into alpha-text2
* grafana/master: Explore: Enable click on name label Bumping grafana ui version (#15669) Need this to be available for plugins docs: 6.0 whats new Updated latest.json with 6.0 Update CHANGELOG.md docs: grafana 6.0 has been released. moves social package to /login moves tracing packge into /infra Update CHANGELOG.md changelog: adds notes for #14509 and #15179 graph: fixes click after scroll in series override menu moves metric package to /infra stackdriver: change reducer mapping for distribution metrics stackdriver: fix for float64 bounds for distribution metrics Fixed value dropdown not updating when it's current value updates, fixes #15566
This commit is contained in:
commit
d3cbc5638c
@ -1,4 +1,10 @@
|
||||
# Unreleased
|
||||
# 6.0.0 stable (2019-02-25)
|
||||
|
||||
### Bug Fixes
|
||||
* **Stackdriver**: fix for float64 bounds for distribution metrics [#14509](https://github.com/grafana/grafana/issues/14509)
|
||||
* **Stackdriver**: no reducers available for distribution type [#15179](https://github.com/grafana/grafana/issues/15179)
|
||||
* **Dashboard**: fixes click after scroll in series override menu [#15621](https://github.com/grafana/grafana/issues/15621)
|
||||
* **MySQL**: fix mysql query using _interval_ms variable throws error [#14507](https://github.com/grafana/grafana/issues/14507)
|
||||
|
||||
# 6.0.0-beta3 (2019-02-19)
|
||||
|
||||
|
@ -14,8 +14,6 @@ weight = -11
|
||||
|
||||
This update to Grafana introduces a new way of exploring your data, support for log data and tons of other features.
|
||||
|
||||
Grafana v6.0 is out in **Beta**, [Download Now!](https://grafana.com/grafana/download/beta)
|
||||
|
||||
The main highlights are:
|
||||
|
||||
- [Explore]({{< relref "#explore" >}}) - A new query focused workflow for ad-hoc data exploration and troubleshooting.
|
||||
@ -107,9 +105,9 @@ continue to refine and start using in other panels.
|
||||
### React Panels & Query Editors
|
||||
|
||||
A major part of all the work that has gone into Grafana v6.0 has been on the migration to React. This investment
|
||||
is part of the future proofing of Grafana and it's code base and ecosystem. Starting in v6.0 **Panels** and **Data
|
||||
is part of the future proofing of Grafana's code base and ecosystem. Starting in v6.0 **Panels** and **Data
|
||||
source** plugins can be written in React using our published `@grafana/ui` sdk library. More information on this
|
||||
will be shared closer to or just after release.
|
||||
will be shared soon.
|
||||
|
||||
{{< docs-imagebox img="/img/docs/v60/react_panels.png" max-width="600px" caption="React Panel" >}}
|
||||
<br />
|
||||
@ -122,7 +120,7 @@ To get started read the guide: [Using Google Stackdriver in Grafana](/features/d
|
||||
|
||||
## Azure Monitor Datasource
|
||||
|
||||
One of the goals of the Grafana v6.0 release is to add support for the three major clouds. Amazon Cloudwatch has been a core datasource for years and Google Stackdriver is also now supported. We developed an external plugin for Azure Monitor last year and for this release the [plugin](https://grafana.com/plugins/grafana-azure-monitor-datasource) is being moved into Grafana to be one of the built-in datasources. For users of the external plugin, Grafana will automatically start using the built-in version. As a core datasource, the Azure Monitor datasource will get alerting support for the official 6.0 release.
|
||||
One of the goals of the Grafana v6.0 release is to add support for the three major clouds. Amazon Cloudwatch has been a core datasource for years and Google Stackdriver is also now supported. We developed an external plugin for Azure Monitor last year and for this release the [plugin](https://grafana.com/plugins/grafana-azure-monitor-datasource) is being moved into Grafana to be one of the built-in datasources. For users of the external plugin, Grafana will automatically start using the built-in version. As a core datasource, the Azure Monitor datasource is able to get alerting support, in the 6.0 release alerting is supported for the Azure Monitor service, with the rest to follow.
|
||||
|
||||
The Azure Monitor datasource integrates four Azure services with Grafana - Azure Monitor, Azure Log Analytics, Azure Application Insights and Azure Application Insights Analytics.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"stable": "5.4.3",
|
||||
"testing": "5.4.3"
|
||||
"stable": "6.0.0",
|
||||
"testing": "6.0.0"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@grafana/ui",
|
||||
"version": "6.0.0-alpha.0",
|
||||
"version": "6.0.1-alpha.0",
|
||||
"description": "Grafana Components Library",
|
||||
"keywords": [
|
||||
"typescript",
|
||||
|
@ -2,3 +2,4 @@ export * from './processTimeSeries';
|
||||
export * from './valueFormats/valueFormats';
|
||||
export * from './colors';
|
||||
export * from './namedColorsPalette';
|
||||
export { getMappedValue } from './valueMappings';
|
||||
|
@ -3,7 +3,7 @@ package api
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
@ -13,8 +13,8 @@ import (
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/dashdiffs"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
|
@ -2,7 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/api/pluginproxy"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
)
|
||||
|
@ -7,9 +7,9 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/login"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
|
@ -16,12 +16,12 @@ import (
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/login"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/login/social"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/social"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -3,7 +3,7 @@ package api
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/events"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/search"
|
||||
)
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/events"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
|
@ -14,8 +14,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/extensions"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
_ "github.com/grafana/grafana/pkg/services/alerting/conditions"
|
||||
_ "github.com/grafana/grafana/pkg/services/alerting/notifiers"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
|
@ -16,9 +16,9 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/login"
|
||||
"github.com/grafana/grafana/pkg/login/social"
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
"github.com/grafana/grafana/pkg/registry"
|
||||
"github.com/grafana/grafana/pkg/social"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
@ -28,8 +28,9 @@ import (
|
||||
|
||||
// self registering services
|
||||
_ "github.com/grafana/grafana/pkg/extensions"
|
||||
_ "github.com/grafana/grafana/pkg/infra/metrics"
|
||||
_ "github.com/grafana/grafana/pkg/infra/serverlock"
|
||||
_ "github.com/grafana/grafana/pkg/metrics"
|
||||
_ "github.com/grafana/grafana/pkg/infra/tracing"
|
||||
_ "github.com/grafana/grafana/pkg/plugins"
|
||||
_ "github.com/grafana/grafana/pkg/services/alerting"
|
||||
_ "github.com/grafana/grafana/pkg/services/auth"
|
||||
@ -39,7 +40,6 @@ import (
|
||||
_ "github.com/grafana/grafana/pkg/services/rendering"
|
||||
_ "github.com/grafana/grafana/pkg/services/search"
|
||||
_ "github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
_ "github.com/grafana/grafana/pkg/tracing"
|
||||
)
|
||||
|
||||
func NewGrafanaServer() *GrafanaServerImpl {
|
||||
|
@ -3,8 +3,8 @@ package metrics
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/metrics/graphitebridge"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/metrics/graphitebridge"
|
||||
"github.com/grafana/grafana/pkg/registry"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/metrics/graphitebridge"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics/graphitebridge"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
@ -5,8 +5,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/login/social"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/social"
|
||||
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/registry"
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
|
@ -5,8 +5,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
)
|
||||
|
||||
type DefaultEvalHandler struct {
|
||||
|
@ -7,8 +7,8 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/imguploader"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/services/rendering"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
|
||||
|
@ -5,8 +5,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
|
@ -5,8 +5,8 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/annotations"
|
||||
"github.com/grafana/grafana/pkg/services/rendering"
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/search"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/securejsondata"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
|
@ -24,7 +24,7 @@ import (
|
||||
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi/resourcegroupstaggingapiiface"
|
||||
"github.com/grafana/grafana/pkg/components/null"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
)
|
||||
|
||||
type CloudWatchExecutor struct {
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/tsdb"
|
||||
)
|
||||
|
||||
|
@ -336,6 +336,8 @@ func (e *StackdriverExecutor) unmarshalResponse(res *http.Response) (Stackdriver
|
||||
return StackdriverResponse{}, err
|
||||
}
|
||||
|
||||
// slog.Info("stackdriver", "response", string(body))
|
||||
|
||||
if res.StatusCode/100 != 2 {
|
||||
slog.Error("Request failed", "status", res.Status, "body", string(body))
|
||||
return StackdriverResponse{}, fmt.Errorf(string(body))
|
||||
@ -559,7 +561,7 @@ func calcBucketBound(bucketOptions StackdriverBucketOptions, n int) string {
|
||||
} else if bucketOptions.ExponentialBuckets != nil {
|
||||
bucketBound = strconv.FormatInt(int64(bucketOptions.ExponentialBuckets.Scale*math.Pow(bucketOptions.ExponentialBuckets.GrowthFactor, float64(n-1))), 10)
|
||||
} else if bucketOptions.ExplicitBuckets != nil {
|
||||
bucketBound = strconv.FormatInt(bucketOptions.ExplicitBuckets.Bounds[(n-1)], 10)
|
||||
bucketBound = fmt.Sprintf("%g", bucketOptions.ExplicitBuckets.Bounds[n])
|
||||
}
|
||||
return bucketBound
|
||||
}
|
||||
|
@ -344,8 +344,8 @@ func TestStackdriver(t *testing.T) {
|
||||
})
|
||||
})
|
||||
|
||||
Convey("when data from query is distribution", func() {
|
||||
data, err := loadTestFile("./test-data/3-series-response-distribution.json")
|
||||
Convey("when data from query is distribution with exponential bounds", func() {
|
||||
data, err := loadTestFile("./test-data/3-series-response-distribution-exponential.json")
|
||||
So(err, ShouldBeNil)
|
||||
So(len(data.TimeSeries), ShouldEqual, 1)
|
||||
|
||||
@ -370,6 +370,14 @@ func TestStackdriver(t *testing.T) {
|
||||
So(res.Series[0].Points[2][1].Float64, ShouldEqual, 1536669060000)
|
||||
})
|
||||
|
||||
Convey("bucket bounds should be correct", func() {
|
||||
So(res.Series[0].Name, ShouldEqual, "0")
|
||||
So(res.Series[1].Name, ShouldEqual, "1")
|
||||
So(res.Series[2].Name, ShouldEqual, "2")
|
||||
So(res.Series[3].Name, ShouldEqual, "4")
|
||||
So(res.Series[4].Name, ShouldEqual, "8")
|
||||
})
|
||||
|
||||
Convey("value should be correct", func() {
|
||||
So(res.Series[8].Points[0][0].Float64, ShouldEqual, 1)
|
||||
So(res.Series[9].Points[0][0].Float64, ShouldEqual, 1)
|
||||
@ -383,6 +391,45 @@ func TestStackdriver(t *testing.T) {
|
||||
})
|
||||
})
|
||||
|
||||
Convey("when data from query is distribution with explicit bounds", func() {
|
||||
data, err := loadTestFile("./test-data/4-series-response-distribution-explicit.json")
|
||||
So(err, ShouldBeNil)
|
||||
So(len(data.TimeSeries), ShouldEqual, 1)
|
||||
|
||||
res := &tsdb.QueryResult{Meta: simplejson.New(), RefId: "A"}
|
||||
query := &StackdriverQuery{AliasBy: "{{bucket}}"}
|
||||
err = executor.parseResponse(res, data, query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(res.Series), ShouldEqual, 33)
|
||||
for i := 0; i < 33; i++ {
|
||||
if i == 0 {
|
||||
So(res.Series[i].Name, ShouldEqual, "0")
|
||||
}
|
||||
So(len(res.Series[i].Points), ShouldEqual, 2)
|
||||
}
|
||||
|
||||
Convey("timestamps should be in ascending order", func() {
|
||||
So(res.Series[0].Points[0][1].Float64, ShouldEqual, 1550859086000)
|
||||
So(res.Series[0].Points[1][1].Float64, ShouldEqual, 1550859146000)
|
||||
})
|
||||
|
||||
Convey("bucket bounds should be correct", func() {
|
||||
So(res.Series[0].Name, ShouldEqual, "0")
|
||||
So(res.Series[1].Name, ShouldEqual, "0.01")
|
||||
So(res.Series[2].Name, ShouldEqual, "0.05")
|
||||
So(res.Series[3].Name, ShouldEqual, "0.1")
|
||||
})
|
||||
|
||||
Convey("value should be correct", func() {
|
||||
So(res.Series[8].Points[0][0].Float64, ShouldEqual, 381)
|
||||
So(res.Series[9].Points[0][0].Float64, ShouldEqual, 212)
|
||||
So(res.Series[10].Points[0][0].Float64, ShouldEqual, 56)
|
||||
So(res.Series[8].Points[1][0].Float64, ShouldEqual, 375)
|
||||
So(res.Series[9].Points[1][0].Float64, ShouldEqual, 213)
|
||||
So(res.Series[10].Points[1][0].Float64, ShouldEqual, 56)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Convey("when interpolating filter wildcards", func() {
|
||||
|
@ -0,0 +1,209 @@
|
||||
{
|
||||
"timeSeries": [
|
||||
{
|
||||
"metric": {
|
||||
"type": "custom.googleapis.com\/opencensus\/grpc.io\/client\/roundtrip_latency"
|
||||
},
|
||||
"resource": {
|
||||
"type": "global",
|
||||
"labels": {
|
||||
"project_id": "grafana-demo"
|
||||
}
|
||||
},
|
||||
"metricKind": "DELTA",
|
||||
"valueType": "DISTRIBUTION",
|
||||
"points": [
|
||||
{
|
||||
"interval": {
|
||||
"startTime": "2019-02-22T18:11:26Z",
|
||||
"endTime": "2019-02-22T18:12:26Z"
|
||||
},
|
||||
"value": {
|
||||
"distributionValue": {
|
||||
"count": "1878",
|
||||
"mean": 17.813718392255,
|
||||
"sumOfSquaredDeviation": 7141630.651914,
|
||||
"bucketOptions": {
|
||||
"explicitBuckets": {
|
||||
"bounds": [
|
||||
0,
|
||||
0.01,
|
||||
0.05,
|
||||
0.1,
|
||||
0.3,
|
||||
0.6,
|
||||
0.8,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
8,
|
||||
10,
|
||||
13,
|
||||
16,
|
||||
20,
|
||||
25,
|
||||
30,
|
||||
40,
|
||||
50,
|
||||
65,
|
||||
80,
|
||||
100,
|
||||
130,
|
||||
160,
|
||||
200,
|
||||
250,
|
||||
300,
|
||||
400,
|
||||
500,
|
||||
650,
|
||||
800,
|
||||
1000,
|
||||
2000,
|
||||
5000,
|
||||
10000,
|
||||
20000,
|
||||
50000,
|
||||
100000
|
||||
]
|
||||
}
|
||||
},
|
||||
"bucketCounts": [
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"8",
|
||||
"403",
|
||||
"297",
|
||||
"184",
|
||||
"375",
|
||||
"213",
|
||||
"56",
|
||||
"31",
|
||||
"15",
|
||||
"13",
|
||||
"4",
|
||||
"1",
|
||||
"5",
|
||||
"2",
|
||||
"8",
|
||||
"13",
|
||||
"26",
|
||||
"13",
|
||||
"45",
|
||||
"48",
|
||||
"61",
|
||||
"10",
|
||||
"3",
|
||||
"6",
|
||||
"7",
|
||||
"4",
|
||||
"7",
|
||||
"12",
|
||||
"8"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"interval": {
|
||||
"startTime": "2019-02-22T18:10:26Z",
|
||||
"endTime": "2019-02-22T18:11:26Z"
|
||||
},
|
||||
"value": {
|
||||
"distributionValue": {
|
||||
"count": "1887",
|
||||
"mean": 17.654277577766,
|
||||
"sumOfSquaredDeviation": 7082587.2133073,
|
||||
"bucketOptions": {
|
||||
"explicitBuckets": {
|
||||
"bounds": [
|
||||
0,
|
||||
0.01,
|
||||
0.05,
|
||||
0.1,
|
||||
0.3,
|
||||
0.6,
|
||||
0.8,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
8,
|
||||
10,
|
||||
13,
|
||||
16,
|
||||
20,
|
||||
25,
|
||||
30,
|
||||
40,
|
||||
50,
|
||||
65,
|
||||
80,
|
||||
100,
|
||||
130,
|
||||
160,
|
||||
200,
|
||||
250,
|
||||
300,
|
||||
400,
|
||||
500,
|
||||
650,
|
||||
800,
|
||||
1000,
|
||||
2000,
|
||||
5000,
|
||||
10000,
|
||||
20000,
|
||||
50000,
|
||||
100000
|
||||
]
|
||||
}
|
||||
},
|
||||
"bucketCounts": [
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"8",
|
||||
"404",
|
||||
"298",
|
||||
"187",
|
||||
"381",
|
||||
"212",
|
||||
"56",
|
||||
"31",
|
||||
"15",
|
||||
"14",
|
||||
"4",
|
||||
"1",
|
||||
"4",
|
||||
"2",
|
||||
"9",
|
||||
"13",
|
||||
"24",
|
||||
"13",
|
||||
"46",
|
||||
"46",
|
||||
"61",
|
||||
"11",
|
||||
"3",
|
||||
"6",
|
||||
"7",
|
||||
"5",
|
||||
"7",
|
||||
"11",
|
||||
"8"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -26,7 +26,7 @@ type StackdriverBucketOptions struct {
|
||||
Scale float64 `json:"scale"`
|
||||
} `json:"exponentialBuckets"`
|
||||
ExplicitBuckets *struct {
|
||||
Bounds []int64 `json:"bounds"`
|
||||
Bounds []float64 `json:"bounds"`
|
||||
} `json:"explicitBuckets"`
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,7 @@ export function dropdownTypeahead2($compile) {
|
||||
'<input type="text"' + ' class="gf-form-input"' + ' spellcheck="false" style="display:none"></input>';
|
||||
|
||||
const buttonTemplate =
|
||||
'<a class="gf-form-input dropdown-toggle"' +
|
||||
'<a class="{{buttonTemplateClass}} dropdown-toggle"' +
|
||||
' tabindex="1" gf-dropdown="menuItems" data-toggle="dropdown"' +
|
||||
' ><i class="fa fa-plus"></i></a>';
|
||||
|
||||
@ -137,9 +137,15 @@ export function dropdownTypeahead2($compile) {
|
||||
menuItems: '=dropdownTypeahead2',
|
||||
dropdownTypeaheadOnSelect: '&dropdownTypeaheadOnSelect',
|
||||
model: '=ngModel',
|
||||
buttonTemplateClass: '@',
|
||||
},
|
||||
link: ($scope, elem, attrs) => {
|
||||
const $input = $(inputTemplate);
|
||||
|
||||
if (!$scope.buttonTemplateClass) {
|
||||
$scope.buttonTemplateClass = 'gf-form-input';
|
||||
}
|
||||
|
||||
const $button = $(buttonTemplate);
|
||||
const timeoutId = {
|
||||
blur: null,
|
||||
|
@ -240,7 +240,7 @@ export class ValueSelectDropdownCtrl {
|
||||
/** @ngInject */
|
||||
export function valueSelectDropdown($compile, $window, $timeout, $rootScope) {
|
||||
return {
|
||||
scope: { variable: '=', onUpdated: '&' },
|
||||
scope: { dashboard: '=', variable: '=', onUpdated: '&' },
|
||||
templateUrl: 'public/app/partials/valueSelectDropdown.html',
|
||||
controller: 'ValueSelectDropdownCtrl',
|
||||
controllerAs: 'vm',
|
||||
@ -288,13 +288,13 @@ export function valueSelectDropdown($compile, $window, $timeout, $rootScope) {
|
||||
}
|
||||
});
|
||||
|
||||
const cleanUp = $rootScope.$on('template-variable-value-updated', () => {
|
||||
scope.vm.dashboard.on(
|
||||
'template-variable-value-updated',
|
||||
() => {
|
||||
scope.vm.updateLinkText();
|
||||
});
|
||||
|
||||
scope.$on('$destroy', () => {
|
||||
cleanUp();
|
||||
});
|
||||
},
|
||||
scope
|
||||
);
|
||||
|
||||
scope.vm.init();
|
||||
},
|
||||
|
@ -4,7 +4,7 @@
|
||||
<label class="gf-form-label template-variable" ng-hide="variable.hide === 1">
|
||||
{{variable.label || variable.name}}
|
||||
</label>
|
||||
<value-select-dropdown ng-if="variable.type !== 'adhoc' && variable.type !== 'textbox'" variable="variable" on-updated="ctrl.variableUpdated(variable)"></value-select-dropdown>
|
||||
<value-select-dropdown ng-if="variable.type !== 'adhoc' && variable.type !== 'textbox'" dashboard="ctrl.dashboard" variable="variable" on-updated="ctrl.variableUpdated(variable)"></value-select-dropdown>
|
||||
<input type="text" ng-if="variable.type === 'textbox'" ng-model="variable.query" class="gf-form-input width-12" ng-blur="variable.current.value != variable.query && variable.updateOptions() && ctrl.variableUpdated(variable);" ng-keydown="$event.keyCode === 13 && variable.current.value != variable.query && variable.updateOptions() && ctrl.variableUpdated(variable);" ></input>
|
||||
</div>
|
||||
<ad-hoc-filters ng-if="variable.type === 'adhoc'" variable="variable" dashboard="ctrl.dashboard"></ad-hoc-filters>
|
||||
|
@ -1,19 +1,38 @@
|
||||
<query-editor-row query-ctrl="ctrl" can-collapse="true" has-text-edit-mode="true">
|
||||
|
||||
<div ng-if="ctrl.target.rawQuery">
|
||||
<div class="gf-form">
|
||||
<textarea rows="3" class="gf-form-input" ng-model="ctrl.target.query" spellcheck="false" placeholder="InfluxDB Query" ng-model-onblur ng-change="ctrl.refresh()"></textarea>
|
||||
<textarea
|
||||
rows="3"
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.target.query"
|
||||
spellcheck="false"
|
||||
placeholder="InfluxDB Query"
|
||||
ng-model-onblur
|
||||
ng-change="ctrl.refresh()"
|
||||
></textarea>
|
||||
</div>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword">FORMAT AS</label>
|
||||
<div class="gf-form-select-wrapper">
|
||||
<select class="gf-form-input gf-size-auto" ng-model="ctrl.target.resultFormat" ng-options="f.value as f.text for f in ctrl.resultFormats" ng-change="ctrl.refresh()"></select>
|
||||
<select
|
||||
class="gf-form-input gf-size-auto"
|
||||
ng-model="ctrl.target.resultFormat"
|
||||
ng-options="f.value as f.text for f in ctrl.resultFormats"
|
||||
ng-change="ctrl.refresh()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form max-width-25" ng-hide="ctrl.target.resultFormat === 'table'">
|
||||
<label class="gf-form-label query-keyword">ALIAS BY</label>
|
||||
<input type="text" class="gf-form-input" ng-model="ctrl.target.alias" spellcheck='false' placeholder="Naming pattern" ng-blur="ctrl.refresh()">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.target.alias"
|
||||
spellcheck="false"
|
||||
placeholder="Naming pattern"
|
||||
ng-blur="ctrl.refresh()"
|
||||
/>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
@ -22,13 +41,20 @@
|
||||
</div>
|
||||
|
||||
<div ng-if="!ctrl.target.rawQuery">
|
||||
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">FROM</label>
|
||||
|
||||
<metric-segment segment="ctrl.policySegment" get-options="ctrl.getPolicySegments()" on-change="ctrl.policyChanged()"></metric-segment>
|
||||
<metric-segment segment="ctrl.measurementSegment" get-options="ctrl.getMeasurements($query)" on-change="ctrl.measurementChanged()"></metric-segment>
|
||||
<metric-segment
|
||||
segment="ctrl.policySegment"
|
||||
get-options="ctrl.getPolicySegments()"
|
||||
on-change="ctrl.policyChanged()"
|
||||
></metric-segment>
|
||||
<metric-segment
|
||||
segment="ctrl.measurementSegment"
|
||||
get-options="ctrl.getMeasurements($query)"
|
||||
on-change="ctrl.measurementChanged()"
|
||||
></metric-segment>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
@ -36,7 +62,11 @@
|
||||
</div>
|
||||
|
||||
<div class="gf-form" ng-repeat="segment in ctrl.tagSegments">
|
||||
<metric-segment segment="segment" get-options="ctrl.getTagsOrValues(segment, $index)" on-change="ctrl.tagSegmentUpdated(segment, $index)"></metric-segment>
|
||||
<metric-segment
|
||||
segment="segment"
|
||||
get-options="ctrl.getTagsOrValues(segment, $index)"
|
||||
on-change="ctrl.tagSegmentUpdated(segment, $index)"
|
||||
></metric-segment>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
@ -46,20 +76,25 @@
|
||||
|
||||
<div class="gf-form-inline" ng-repeat="selectParts in ctrl.queryModel.selectModels">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">
|
||||
<span ng-show="$index === 0">SELECT</span>
|
||||
</label>
|
||||
<label class="gf-form-label query-keyword width-7"> <span ng-show="$index === 0">SELECT</span> </label>
|
||||
</div>
|
||||
|
||||
<div class="gf-form" ng-repeat="part in selectParts">
|
||||
<query-part-editor class="gf-form-label query-part" part="part" handle-event="ctrl.handleSelectPartEvent(selectParts, part, $event)">
|
||||
<query-part-editor
|
||||
class="gf-form-label query-part"
|
||||
part="part"
|
||||
handle-event="ctrl.handleSelectPartEvent(selectParts, part, $event)"
|
||||
>
|
||||
</query-part-editor>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<label class="dropdown"
|
||||
dropdown-typeahead="ctrl.selectMenu"
|
||||
dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)">
|
||||
<label
|
||||
class="dropdown"
|
||||
dropdown-typeahead2="ctrl.selectMenu"
|
||||
dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)"
|
||||
button-template-class="gf-form-label query-part"
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@ -74,14 +109,21 @@
|
||||
<span>GROUP BY</span>
|
||||
</label>
|
||||
|
||||
<query-part-editor ng-repeat="part in ctrl.queryModel.groupByParts"
|
||||
part="part" class="gf-form-label query-part"
|
||||
handle-event="ctrl.handleGroupByPartEvent(part, $index, $event)">
|
||||
<query-part-editor
|
||||
ng-repeat="part in ctrl.queryModel.groupByParts"
|
||||
part="part"
|
||||
class="gf-form-label query-part"
|
||||
handle-event="ctrl.handleGroupByPartEvent(part, $index, $event)"
|
||||
>
|
||||
</query-part-editor>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<metric-segment segment="ctrl.groupBySegment" get-options="ctrl.getGroupByOptions()" on-change="ctrl.groupByAction(part, $index)"></metric-segment>
|
||||
<metric-segment
|
||||
segment="ctrl.groupBySegment"
|
||||
get-options="ctrl.getGroupByOptions()"
|
||||
on-change="ctrl.groupByAction(part, $index)"
|
||||
></metric-segment>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
@ -92,7 +134,9 @@
|
||||
<div class="gf-form-inline" ng-if="ctrl.target.orderByTime === 'DESC'">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">ORDER BY</label>
|
||||
<label class="gf-form-label pointer" ng-click="ctrl.removeOrderByTime()">time <span class="query-keyword">DESC</span> <i class="fa fa-remove"></i></label>
|
||||
<label class="gf-form-label pointer" ng-click="ctrl.removeOrderByTime()"
|
||||
>time <span class="query-keyword">DESC</span> <i class="fa fa-remove"></i
|
||||
></label>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
@ -102,7 +146,14 @@
|
||||
<div class="gf-form-inline" ng-if="ctrl.target.limit">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">LIMIT</label>
|
||||
<input type="text" class="gf-form-input width-9" ng-model="ctrl.target.limit" spellcheck='false' placeholder="No Limit" ng-blur="ctrl.refresh()">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input width-9"
|
||||
ng-model="ctrl.target.limit"
|
||||
spellcheck="false"
|
||||
placeholder="No Limit"
|
||||
ng-blur="ctrl.refresh()"
|
||||
/>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
@ -112,7 +163,14 @@
|
||||
<div class="gf-form-inline" ng-if="ctrl.target.slimit">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">SLIMIT</label>
|
||||
<input type="text" class="gf-form-input width-9" ng-model="ctrl.target.slimit" spellcheck='false' placeholder="No Limit" ng-blur="ctrl.refresh()">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input width-9"
|
||||
ng-model="ctrl.target.slimit"
|
||||
spellcheck="false"
|
||||
placeholder="No Limit"
|
||||
ng-blur="ctrl.refresh()"
|
||||
/>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
@ -122,7 +180,14 @@
|
||||
<div class="gf-form-inline" ng-if="ctrl.target.tz">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">tz</label>
|
||||
<input type="text" class="gf-form-input width-9" ng-model="ctrl.target.tz" spellcheck='false' placeholder="No Timezone" ng-blur="ctrl.refresh()">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input width-9"
|
||||
ng-model="ctrl.target.tz"
|
||||
spellcheck="false"
|
||||
placeholder="No Timezone"
|
||||
ng-blur="ctrl.refresh()"
|
||||
/>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
@ -133,7 +198,12 @@
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">FORMAT AS</label>
|
||||
<div class="gf-form-select-wrapper">
|
||||
<select class="gf-form-input gf-size-auto" ng-model="ctrl.target.resultFormat" ng-options="f.value as f.text for f in ctrl.resultFormats" ng-change="ctrl.refresh()"></select>
|
||||
<select
|
||||
class="gf-form-input gf-size-auto"
|
||||
ng-model="ctrl.target.resultFormat"
|
||||
ng-options="f.value as f.text for f in ctrl.resultFormats"
|
||||
ng-change="ctrl.refresh()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
@ -144,12 +214,18 @@
|
||||
<div class="gf-form-inline" ng-hide="ctrl.target.resultFormat === 'table'">
|
||||
<div class="gf-form max-width-30">
|
||||
<label class="gf-form-label query-keyword width-7">ALIAS BY</label>
|
||||
<input type="text" class="gf-form-input" ng-model="ctrl.target.alias" spellcheck='false' placeholder="Naming pattern" ng-blur="ctrl.refresh()">
|
||||
<input
|
||||
type="text"
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.target.alias"
|
||||
spellcheck="false"
|
||||
placeholder="Naming pattern"
|
||||
ng-blur="ctrl.refresh()"
|
||||
/>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</query-editor-row>
|
||||
|
@ -45,8 +45,10 @@
|
||||
|
||||
<div class="gf-form">
|
||||
<label class="dropdown"
|
||||
dropdown-typeahead="ctrl.selectMenu"
|
||||
dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)">
|
||||
dropdown-typeahead2="ctrl.selectMenu"
|
||||
dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)"
|
||||
button-template-class="gf-form-label query-part"
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
@ -45,8 +45,10 @@
|
||||
|
||||
<div class="gf-form">
|
||||
<label class="dropdown"
|
||||
dropdown-typeahead="ctrl.selectMenu"
|
||||
dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)">
|
||||
dropdown-typeahead2="ctrl.selectMenu"
|
||||
dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)"
|
||||
button-template-class="gf-form-label query-part"
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
@ -100,7 +100,7 @@ export class ResultTransformer {
|
||||
table.columns.push({ text: 'Time', type: 'time' });
|
||||
_.each(sortedLabels, (label, labelIndex) => {
|
||||
metricLabels[label] = labelIndex + 1;
|
||||
table.columns.push({ text: label, filterable: !label.startsWith('__') });
|
||||
table.columns.push({ text: label, filterable: true });
|
||||
});
|
||||
const valueText = resultCount > 1 || valueWithRefId ? `Value #${refId}` : 'Value';
|
||||
table.columns.push({ text: valueText });
|
||||
|
@ -66,11 +66,12 @@ describe('Prometheus Result Transformer', () => {
|
||||
]);
|
||||
expect(table.columns).toMatchObject([
|
||||
{ text: 'Time', type: 'time' },
|
||||
{ text: '__name__' },
|
||||
{ text: 'instance' },
|
||||
{ text: '__name__', filterable: true },
|
||||
{ text: 'instance', filterable: true },
|
||||
{ text: 'job' },
|
||||
{ text: 'Value' },
|
||||
]);
|
||||
expect(table.columns[4].filterable).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should column title include refId if response count is more than 2', () => {
|
||||
|
@ -49,7 +49,8 @@ describe('Aggregations', () => {
|
||||
});
|
||||
it('', () => {
|
||||
const options = wrapper.state().aggOptions[0].options;
|
||||
expect(options.length).toEqual(5);
|
||||
|
||||
expect(options.length).toEqual(10);
|
||||
expect(options.map(o => o.value)).toEqual(expect.arrayContaining(['REDUCE_NONE']));
|
||||
});
|
||||
});
|
||||
|
@ -73,7 +73,7 @@ export class Aggregations extends React.Component<Props, State> {
|
||||
value={crossSeriesReducer}
|
||||
variables={templateSrv.variables}
|
||||
options={aggOptions}
|
||||
placeholder="Select Aggregation"
|
||||
placeholder="Select Reducer"
|
||||
className="width-15"
|
||||
/>
|
||||
</div>
|
||||
|
@ -185,7 +185,7 @@ export class Metrics extends React.Component<Props, State> {
|
||||
},
|
||||
]}
|
||||
placeholder="Select Metric"
|
||||
className="width-15"
|
||||
className="width-26"
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form gf-form--grow">
|
||||
|
@ -28,7 +28,7 @@ Array [
|
||||
<div
|
||||
className="css-0 gf-form-select-box__placeholder"
|
||||
>
|
||||
Select Aggregation
|
||||
Select Reducer
|
||||
</div>
|
||||
<div
|
||||
className="css-0"
|
||||
|
@ -72,7 +72,7 @@ Array [
|
||||
Metric
|
||||
</span>
|
||||
<div
|
||||
className="css-0 gf-form-input gf-form-input--form-dropdown width-15"
|
||||
className="css-0 gf-form-input gf-form-input--form-dropdown width-26"
|
||||
onKeyDown={[Function]}
|
||||
>
|
||||
<div
|
||||
@ -196,7 +196,7 @@ Array [
|
||||
<div
|
||||
className="css-0 gf-form-select-box__placeholder"
|
||||
>
|
||||
Select Aggregation
|
||||
Select Reducer
|
||||
</div>
|
||||
<div
|
||||
className="css-0"
|
||||
|
@ -189,7 +189,7 @@ export const aggOptions = [
|
||||
ValueTypes.BOOL,
|
||||
ValueTypes.STRING,
|
||||
],
|
||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
|
||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA, MetricKind.CUMULATIVE],
|
||||
},
|
||||
{
|
||||
text: 'count true',
|
||||
@ -207,25 +207,25 @@ export const aggOptions = [
|
||||
text: '99th percentile',
|
||||
value: 'REDUCE_PERCENTILE_99',
|
||||
valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
|
||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
|
||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA, MetricKind.CUMULATIVE],
|
||||
},
|
||||
{
|
||||
text: '95th percentile',
|
||||
value: 'REDUCE_PERCENTILE_95',
|
||||
valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
|
||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
|
||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA, MetricKind.CUMULATIVE],
|
||||
},
|
||||
{
|
||||
text: '50th percentile',
|
||||
value: 'REDUCE_PERCENTILE_50',
|
||||
valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
|
||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
|
||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA, MetricKind.CUMULATIVE],
|
||||
},
|
||||
{
|
||||
text: '5th percentile',
|
||||
value: 'REDUCE_PERCENTILE_05',
|
||||
valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
|
||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
|
||||
metricKinds: [MetricKind.GAUGE, MetricKind.DELTA, MetricKind.CUMULATIVE],
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -11,7 +11,7 @@ export function SeriesOverridesCtrl($scope, $element, popoverSrv) {
|
||||
const option = {
|
||||
text: name,
|
||||
propertyName: propertyName,
|
||||
index: $scope.overrideMenu.lenght,
|
||||
index: $scope.overrideMenu.length,
|
||||
values: values,
|
||||
submenu: _.map(values, value => {
|
||||
return { text: String(value), value: value };
|
||||
|
@ -1,31 +1,72 @@
|
||||
|
||||
<div class="editor-row">
|
||||
<div class="editor-row">
|
||||
<div class="section gf-form-group">
|
||||
<h5 class="section-heading">Draw Modes</h5>
|
||||
<gf-form-switch class="gf-form" label="Bars" label-class="width-5" checked="ctrl.panel.bars" on-change="ctrl.render()"></gf-form-switch>
|
||||
<gf-form-switch class="gf-form" label="Lines" label-class="width-5" checked="ctrl.panel.lines" on-change="ctrl.render()"></gf-form-switch>
|
||||
<gf-form-switch class="gf-form" label="Points" label-class="width-5" checked="ctrl.panel.points" on-change="ctrl.render()"></gf-form-switch>
|
||||
<gf-form-switch
|
||||
class="gf-form"
|
||||
label="Bars"
|
||||
label-class="width-5"
|
||||
checked="ctrl.panel.bars"
|
||||
on-change="ctrl.render()"
|
||||
></gf-form-switch>
|
||||
<gf-form-switch
|
||||
class="gf-form"
|
||||
label="Lines"
|
||||
label-class="width-5"
|
||||
checked="ctrl.panel.lines"
|
||||
on-change="ctrl.render()"
|
||||
></gf-form-switch>
|
||||
<gf-form-switch
|
||||
class="gf-form"
|
||||
label="Points"
|
||||
label-class="width-5"
|
||||
checked="ctrl.panel.points"
|
||||
on-change="ctrl.render()"
|
||||
></gf-form-switch>
|
||||
</div>
|
||||
<div class="section gf-form-group">
|
||||
<h5 class="section-heading">Mode Options</h5>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-8">Fill</label>
|
||||
<div class="gf-form-select-wrapper max-width-5">
|
||||
<select class="gf-form-input" ng-model="ctrl.panel.fill" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()" ng-disabled="!ctrl.panel.lines"></select>
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.panel.fill"
|
||||
ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]"
|
||||
ng-change="ctrl.render()"
|
||||
ng-disabled="!ctrl.panel.lines"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-8">Line Width</label>
|
||||
<div class="gf-form-select-wrapper max-width-5">
|
||||
<select class="gf-form-input" ng-model="ctrl.panel.linewidth" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()" ng-disabled="!ctrl.panel.lines"></select>
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.panel.linewidth"
|
||||
ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]"
|
||||
ng-change="ctrl.render()"
|
||||
ng-disabled="!ctrl.panel.lines"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<gf-form-switch ng-disabled="!ctrl.panel.lines" class="gf-form" label="Staircase" label-class="width-8" checked="ctrl.panel.steppedLine" on-change="ctrl.render()">
|
||||
<gf-form-switch
|
||||
ng-disabled="!ctrl.panel.lines"
|
||||
class="gf-form"
|
||||
label="Staircase"
|
||||
label-class="width-8"
|
||||
checked="ctrl.panel.steppedLine"
|
||||
on-change="ctrl.render()"
|
||||
>
|
||||
</gf-form-switch>
|
||||
<div class="gf-form" ng-if="ctrl.panel.points">
|
||||
<label class="gf-form-label width-8">Point Radius</label>
|
||||
<div class="gf-form-select-wrapper max-width-5">
|
||||
<select class="gf-form-input" ng-model="ctrl.panel.pointradius" ng-options="f for f in [0.5,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.panel.pointradius"
|
||||
ng-options="f for f in [0.5,1,2,3,4,5,6,7,8,9,10]"
|
||||
ng-change="ctrl.render()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -34,45 +75,86 @@
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-9">Mode</label>
|
||||
<div class="gf-form-select-wrapper max-width-8">
|
||||
<select class="gf-form-input" ng-model="ctrl.panel.tooltip.shared" ng-options="f.value as f.text for f in [{text: 'All series', value: true}, {text: 'Single', value: false}]" ng-change="ctrl.render()"></select>
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.panel.tooltip.shared"
|
||||
ng-options="f.value as f.text for f in [{text: 'All series', value: true}, {text: 'Single', value: false}]"
|
||||
ng-change="ctrl.render()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-9">Sort order</label>
|
||||
<div class="gf-form-select-wrapper max-width-8">
|
||||
<select class="gf-form-input" ng-model="ctrl.panel.tooltip.sort" ng-options="f.value as f.text for f in [{text: 'None', value: 0}, {text: 'Increasing', value: 1}, {text: 'Decreasing', value: 2}]" ng-change="ctrl.render()"></select>
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.panel.tooltip.sort"
|
||||
ng-options="f.value as f.text for f in [{text: 'None', value: 0}, {text: 'Increasing', value: 1}, {text: 'Decreasing', value: 2}]"
|
||||
ng-change="ctrl.render()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form" ng-show="ctrl.panel.stack">
|
||||
<label class="gf-form-label width-9">Stacked value</label>
|
||||
<div class="gf-form-select-wrapper max-width-8">
|
||||
<select class="gf-form-input" ng-model="ctrl.panel.tooltip.value_type" ng-options="f for f in ['cumulative','individual']" ng-change="ctrl.render()"></select>
|
||||
<select
|
||||
class="gf-form-input"
|
||||
ng-model="ctrl.panel.tooltip.value_type"
|
||||
ng-options="f for f in ['cumulative','individual']"
|
||||
ng-change="ctrl.render()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section gf-form-group">
|
||||
<h5 class="section-heading">Stacking & Null value</h5>
|
||||
<gf-form-switch class="gf-form" label="Stack" label-class="width-7" checked="ctrl.panel.stack" on-change="ctrl.refresh()">
|
||||
<gf-form-switch
|
||||
class="gf-form"
|
||||
label="Stack"
|
||||
label-class="width-7"
|
||||
checked="ctrl.panel.stack"
|
||||
on-change="ctrl.refresh()"
|
||||
>
|
||||
</gf-form-switch>
|
||||
<gf-form-switch class="gf-form" ng-show="ctrl.panel.stack" label="Percent" label-class="width-7" checked="ctrl.panel.percentage" on-change="ctrl.render()">
|
||||
<gf-form-switch
|
||||
class="gf-form"
|
||||
ng-show="ctrl.panel.stack"
|
||||
label="Percent"
|
||||
label-class="width-7"
|
||||
checked="ctrl.panel.percentage"
|
||||
on-change="ctrl.render()"
|
||||
>
|
||||
</gf-form-switch>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-7">Null value</label>
|
||||
<div class="gf-form-select-wrapper">
|
||||
<select class="gf-form-input max-width-9" ng-model="ctrl.panel.nullPointMode" ng-options="f for f in ['connected', 'null', 'null as zero']" ng-change="ctrl.render()"></select>
|
||||
</div>
|
||||
<select
|
||||
class="gf-form-input max-width-9"
|
||||
ng-model="ctrl.panel.nullPointMode"
|
||||
ng-options="f for f in ['connected', 'null', 'null as zero']"
|
||||
ng-change="ctrl.render()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<div class="gf-form-inline" ng-repeat="override in ctrl.panel.seriesOverrides" ng-controller="SeriesOverridesCtrl">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">alias or regex</label>
|
||||
</div>
|
||||
<div class="gf-form width-15">
|
||||
<input type="text" ng-model="override.alias" bs-typeahead="getSeriesNames" ng-blur="ctrl.render()" data-min-length=0 data-items=100 class="gf-form-input width-15">
|
||||
<input
|
||||
type="text"
|
||||
ng-model="override.alias"
|
||||
bs-typeahead="getSeriesNames"
|
||||
ng-blur="ctrl.render()"
|
||||
data-min-length="0"
|
||||
data-items="100"
|
||||
class="gf-form-input width-15"
|
||||
/>
|
||||
</div>
|
||||
<div class="gf-form" ng-repeat="option in currentOverrides">
|
||||
<label class="gf-form-label">
|
||||
@ -80,14 +162,17 @@
|
||||
<span ng-show="option.propertyName === 'color'">
|
||||
Color: <i class="fa fa-circle" ng-style="{color:option.value}"></i>
|
||||
</span>
|
||||
<span ng-show="option.propertyName !== 'color'">
|
||||
{{option.name}}: {{option.value}}
|
||||
</span>
|
||||
<span ng-show="option.propertyName !== 'color'"> {{ option.name }}: {{ option.value }} </span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<span class="dropdown" dropdown-typeahead="overrideMenu" dropdown-typeahead-on-select="setOverride($item, $subItem)">
|
||||
<span
|
||||
class="dropdown"
|
||||
dropdown-typeahead2="overrideMenu"
|
||||
dropdown-typeahead-on-select="setOverride($item, $subItem)"
|
||||
button-template-class="gf-form-label"
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@ -106,5 +191,4 @@
|
||||
<i class="fa fa-plus"></i> Add series override<tip>Regex match example: /server[0-3]/i </tip>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user