1216 lines
42 KiB
Go
1216 lines
42 KiB
Go
package influxdb
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/url"
|
|
"sort"
|
|
"time"
|
|
|
|
"github.com/influxdata/influxdb/v2/kit/platform"
|
|
"github.com/influxdata/influxdb/v2/kit/platform/errors"
|
|
)
|
|
|
|
// ErrDashboardNotFound is the error msg for a missing dashboard.
|
|
const ErrDashboardNotFound = "dashboard not found"
|
|
|
|
// ErrCellNotFound is the error msg for a missing cell.
|
|
const ErrCellNotFound = "cell not found"
|
|
|
|
// ErrViewNotFound is the error msg for a missing View.
|
|
const ErrViewNotFound = "view not found"
|
|
|
|
// ops for dashboard service.
|
|
const (
|
|
OpFindDashboardByID = "FindDashboardByID"
|
|
OpFindDashboards = "FindDashboards"
|
|
OpCreateDashboard = "CreateDashboard"
|
|
OpUpdateDashboard = "UpdateDashboard"
|
|
OpAddDashboardCell = "AddDashboardCell"
|
|
OpRemoveDashboardCell = "RemoveDashboardCell"
|
|
OpUpdateDashboardCell = "UpdateDashboardCell"
|
|
OpGetDashboardCellView = "GetDashboardCellView"
|
|
OpUpdateDashboardCellView = "UpdateDashboardCellView"
|
|
OpDeleteDashboard = "DeleteDashboard"
|
|
OpReplaceDashboardCells = "ReplaceDashboardCells"
|
|
)
|
|
|
|
// DashboardService represents a service for managing dashboard data.
|
|
type DashboardService interface {
|
|
// FindDashboardByID returns a single dashboard by ID.
|
|
FindDashboardByID(ctx context.Context, id platform.ID) (*Dashboard, error)
|
|
|
|
// FindDashboards returns a list of dashboards that match filter and the total count of matching dashboards.
|
|
// Additional options provide pagination & sorting.
|
|
FindDashboards(ctx context.Context, filter DashboardFilter, opts FindOptions) ([]*Dashboard, int, error)
|
|
|
|
// CreateDashboard creates a new dashboard and sets b.ID with the new identifier.
|
|
CreateDashboard(ctx context.Context, b *Dashboard) error
|
|
|
|
// UpdateDashboard updates a single dashboard with changeset.
|
|
// Returns the new dashboard state after update.
|
|
UpdateDashboard(ctx context.Context, id platform.ID, upd DashboardUpdate) (*Dashboard, error)
|
|
|
|
// AddDashboardCell adds a cell to a dashboard.
|
|
AddDashboardCell(ctx context.Context, id platform.ID, c *Cell, opts AddDashboardCellOptions) error
|
|
|
|
// RemoveDashboardCell removes a dashboard.
|
|
RemoveDashboardCell(ctx context.Context, dashboardID, cellID platform.ID) error
|
|
|
|
// UpdateDashboardCell replaces the dashboard cell with the provided ID.
|
|
UpdateDashboardCell(ctx context.Context, dashboardID, cellID platform.ID, upd CellUpdate) (*Cell, error)
|
|
|
|
// GetDashboardCellView retrieves a dashboard cells view.
|
|
GetDashboardCellView(ctx context.Context, dashboardID, cellID platform.ID) (*View, error)
|
|
|
|
// UpdateDashboardCellView retrieves a dashboard cells view.
|
|
UpdateDashboardCellView(ctx context.Context, dashboardID, cellID platform.ID, upd ViewUpdate) (*View, error)
|
|
|
|
// DeleteDashboard removes a dashboard by ID.
|
|
DeleteDashboard(ctx context.Context, id platform.ID) error
|
|
|
|
// ReplaceDashboardCells replaces all cells in a dashboard
|
|
ReplaceDashboardCells(ctx context.Context, id platform.ID, c []*Cell) error
|
|
}
|
|
|
|
// Dashboard represents all visual and query data for a dashboard.
|
|
type Dashboard struct {
|
|
ID platform.ID `json:"id,omitempty"`
|
|
OrganizationID platform.ID `json:"orgID,omitempty"`
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
Cells []*Cell `json:"cells"`
|
|
Meta DashboardMeta `json:"meta"`
|
|
OwnerID *platform.ID `json:"owner,omitempty"`
|
|
}
|
|
|
|
// DashboardMeta contains meta information about dashboards
|
|
type DashboardMeta struct {
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
UpdatedAt time.Time `json:"updatedAt"`
|
|
}
|
|
|
|
// DefaultDashboardFindOptions are the default find options for dashboards
|
|
var DefaultDashboardFindOptions = FindOptions{
|
|
SortBy: "ID",
|
|
}
|
|
|
|
// SortDashboards sorts a slice of dashboards by a field.
|
|
func SortDashboards(opts FindOptions, ds []*Dashboard) {
|
|
var sorter func(i, j int) bool
|
|
switch opts.SortBy {
|
|
case "CreatedAt":
|
|
sorter = func(i, j int) bool {
|
|
return ds[j].Meta.CreatedAt.After(ds[i].Meta.CreatedAt)
|
|
}
|
|
case "UpdatedAt":
|
|
sorter = func(i, j int) bool {
|
|
return ds[j].Meta.UpdatedAt.After(ds[i].Meta.UpdatedAt)
|
|
}
|
|
case "Name":
|
|
sorter = func(i, j int) bool {
|
|
return ds[i].Name < ds[j].Name
|
|
}
|
|
default:
|
|
sorter = func(i, j int) bool {
|
|
if opts.Descending {
|
|
return ds[i].ID > ds[j].ID
|
|
}
|
|
return ds[i].ID < ds[j].ID
|
|
}
|
|
}
|
|
|
|
sort.Slice(ds, sorter)
|
|
}
|
|
|
|
// Cell holds positional information about a cell on dashboard and a reference to a cell.
|
|
type Cell struct {
|
|
ID platform.ID `json:"id,omitempty"`
|
|
CellProperty
|
|
View *View `json:"-"`
|
|
}
|
|
|
|
// Marshals the cell
|
|
func (c *Cell) MarshalJSON() ([]byte, error) {
|
|
type resp struct {
|
|
ID *platform.ID `json:"id,omitempty"`
|
|
Name string `json:"name,omitempty"`
|
|
ViewProperties json.RawMessage `json:"properties,omitempty"`
|
|
CellProperty
|
|
}
|
|
response := resp{
|
|
CellProperty: c.CellProperty,
|
|
}
|
|
if c.ID != 0 {
|
|
response.ID = &c.ID
|
|
}
|
|
if c.View != nil {
|
|
response.Name = c.View.Name
|
|
rawJSON, err := MarshalViewPropertiesJSON(c.View.Properties)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
response.ViewProperties = rawJSON
|
|
}
|
|
return json.Marshal(response)
|
|
}
|
|
|
|
func (c *Cell) UnmarshalJSON(b []byte) error {
|
|
var newCell struct {
|
|
ID platform.ID `json:"id,omitempty"`
|
|
Name string `json:"name,omitempty"`
|
|
ViewProperties json.RawMessage `json:"properties,omitempty"`
|
|
CellProperty
|
|
}
|
|
if err := json.Unmarshal(b, &newCell); err != nil {
|
|
return err
|
|
}
|
|
|
|
c.ID = newCell.ID
|
|
c.CellProperty = newCell.CellProperty
|
|
|
|
if newCell.Name != "" {
|
|
if c.View == nil {
|
|
c.View = new(View)
|
|
}
|
|
c.View.Name = newCell.Name
|
|
}
|
|
|
|
props, err := UnmarshalViewPropertiesJSON(newCell.ViewProperties)
|
|
if err == nil {
|
|
if c.View == nil {
|
|
c.View = new(View)
|
|
}
|
|
c.View.Properties = props
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// CellProperty contains the properties of a cell.
|
|
type CellProperty struct {
|
|
X int32 `json:"x"`
|
|
Y int32 `json:"y"`
|
|
W int32 `json:"w"`
|
|
H int32 `json:"h"`
|
|
}
|
|
|
|
// DashboardFilter is a filter for dashboards.
|
|
type DashboardFilter struct {
|
|
IDs []*platform.ID
|
|
OrganizationID *platform.ID
|
|
Organization *string
|
|
OwnerID *platform.ID
|
|
}
|
|
|
|
// QueryParams turns a dashboard filter into query params
|
|
//
|
|
// It implements PagingFilter.
|
|
func (f DashboardFilter) QueryParams() map[string][]string {
|
|
qp := url.Values{}
|
|
for _, id := range f.IDs {
|
|
if id != nil {
|
|
qp.Add("id", id.String())
|
|
}
|
|
}
|
|
|
|
if f.OrganizationID != nil {
|
|
qp.Add("orgID", f.OrganizationID.String())
|
|
}
|
|
|
|
if f.Organization != nil {
|
|
qp.Add("org", *f.Organization)
|
|
}
|
|
|
|
if f.OwnerID != nil {
|
|
qp.Add("owner", f.OwnerID.String())
|
|
}
|
|
|
|
return qp
|
|
}
|
|
|
|
// DashboardUpdate is the patch structure for a dashboard.
|
|
type DashboardUpdate struct {
|
|
Name *string `json:"name"`
|
|
Description *string `json:"description"`
|
|
Cells *[]*Cell `json:"cells"`
|
|
}
|
|
|
|
// Apply applies an update to a dashboard.
|
|
func (u DashboardUpdate) Apply(d *Dashboard) error {
|
|
if u.Name != nil {
|
|
d.Name = *u.Name
|
|
}
|
|
|
|
if u.Description != nil {
|
|
d.Description = *u.Description
|
|
}
|
|
|
|
if u.Cells != nil {
|
|
d.Cells = *u.Cells
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Valid returns an error if the dashboard update is invalid.
|
|
func (u DashboardUpdate) Valid() *errors.Error {
|
|
if u.Name == nil && u.Description == nil {
|
|
return &errors.Error{
|
|
Code: errors.EInvalid,
|
|
Msg: "must update at least one attribute",
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AddDashboardCellOptions are options for adding a dashboard.
|
|
type AddDashboardCellOptions struct {
|
|
View *View
|
|
}
|
|
|
|
// CellUpdate is the patch structure for a cell.
|
|
type CellUpdate struct {
|
|
X *int32 `json:"x"`
|
|
Y *int32 `json:"y"`
|
|
W *int32 `json:"w"`
|
|
H *int32 `json:"h"`
|
|
}
|
|
|
|
// Apply applies an update to a Cell.
|
|
func (u CellUpdate) Apply(c *Cell) error {
|
|
if u.X != nil {
|
|
c.X = *u.X
|
|
}
|
|
|
|
if u.Y != nil {
|
|
c.Y = *u.Y
|
|
}
|
|
|
|
if u.W != nil {
|
|
c.W = *u.W
|
|
}
|
|
|
|
if u.H != nil {
|
|
c.H = *u.H
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Valid returns an error if the cell update is invalid.
|
|
func (u CellUpdate) Valid() *errors.Error {
|
|
if u.H == nil && u.W == nil && u.Y == nil && u.X == nil {
|
|
return &errors.Error{
|
|
Code: errors.EInvalid,
|
|
Msg: "must update at least one attribute",
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ViewUpdate is a struct for updating Views.
|
|
type ViewUpdate struct {
|
|
ViewContentsUpdate
|
|
Properties ViewProperties
|
|
}
|
|
|
|
// Valid validates the update struct. It expects minimal values to be set.
|
|
func (u ViewUpdate) Valid() *errors.Error {
|
|
_, ok := u.Properties.(EmptyViewProperties)
|
|
if u.Name == nil && ok {
|
|
return &errors.Error{
|
|
Code: errors.EInvalid,
|
|
Msg: "expected at least one attribute to be updated",
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Apply updates a view with the view updates properties.
|
|
func (u ViewUpdate) Apply(v *View) error {
|
|
if err := u.Valid(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if u.Name != nil {
|
|
v.Name = *u.Name
|
|
}
|
|
|
|
if u.Properties != nil {
|
|
v.Properties = u.Properties
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ViewContentsUpdate is a struct for updating the non properties content of a View.
|
|
type ViewContentsUpdate struct {
|
|
Name *string `json:"name"`
|
|
}
|
|
|
|
// ViewFilter represents a set of filter that restrict the returned results.
|
|
type ViewFilter struct {
|
|
ID *platform.ID
|
|
Types []string
|
|
}
|
|
|
|
// View holds positional and visual information for a View.
|
|
type View struct {
|
|
ViewContents
|
|
Properties ViewProperties
|
|
}
|
|
|
|
// ViewContents is the id and name of a specific view.
|
|
type ViewContents struct {
|
|
ID platform.ID `json:"id,omitempty"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
// Values for all supported view property types.
|
|
const (
|
|
ViewPropertyTypeCheck = "check"
|
|
ViewPropertyTypeGauge = "gauge"
|
|
ViewPropertyTypeHeatMap = "heatmap"
|
|
ViewPropertyTypeHistogram = "histogram"
|
|
ViewPropertyTypeLogViewer = "log-viewer"
|
|
ViewPropertyTypeMarkdown = "markdown"
|
|
ViewPropertyTypeScatter = "scatter"
|
|
ViewPropertyTypeSingleStat = "single-stat"
|
|
ViewPropertyTypeSingleStatPlusLine = "line-plus-single-stat"
|
|
ViewPropertyTypeTable = "table"
|
|
ViewPropertyTypeXY = "xy"
|
|
ViewPropertyTypeMosaic = "mosaic"
|
|
ViewPropertyTypeBand = "band"
|
|
ViewPropertyTypeGeo = "geo"
|
|
)
|
|
|
|
// ViewProperties is used to mark other structures as conforming to a View.
|
|
type ViewProperties interface {
|
|
viewProperties()
|
|
GetType() string
|
|
}
|
|
|
|
// EmptyViewProperties is visualization that has no values
|
|
type EmptyViewProperties struct{}
|
|
|
|
func (v EmptyViewProperties) viewProperties() {}
|
|
|
|
func (v EmptyViewProperties) GetType() string { return "" }
|
|
|
|
// UnmarshalViewPropertiesJSON unmarshals JSON bytes into a ViewProperties.
|
|
func UnmarshalViewPropertiesJSON(b []byte) (ViewProperties, error) {
|
|
var v struct {
|
|
B json.RawMessage `json:"properties"`
|
|
}
|
|
|
|
if err := json.Unmarshal(b, &v); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(v.B) == 0 {
|
|
// Then there wasn't any visualization field, so there's no need unmarshal it
|
|
return EmptyViewProperties{}, nil
|
|
}
|
|
|
|
var t struct {
|
|
Shape string `json:"shape"`
|
|
Type string `json:"type"`
|
|
}
|
|
|
|
if err := json.Unmarshal(v.B, &t); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var vis ViewProperties
|
|
switch t.Shape {
|
|
case "chronograf-v2":
|
|
switch t.Type {
|
|
case ViewPropertyTypeCheck:
|
|
var cv CheckViewProperties
|
|
if err := json.Unmarshal(v.B, &cv); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = cv
|
|
case ViewPropertyTypeXY:
|
|
var xyv XYViewProperties
|
|
if err := json.Unmarshal(v.B, &xyv); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = xyv
|
|
case ViewPropertyTypeSingleStat:
|
|
var ssv SingleStatViewProperties
|
|
if err := json.Unmarshal(v.B, &ssv); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = ssv
|
|
case ViewPropertyTypeGauge:
|
|
var gv GaugeViewProperties
|
|
if err := json.Unmarshal(v.B, &gv); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = gv
|
|
case ViewPropertyTypeGeo:
|
|
var gvw GeoViewProperties
|
|
if err := json.Unmarshal(v.B, &gvw); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = gvw
|
|
case ViewPropertyTypeTable:
|
|
var tv TableViewProperties
|
|
if err := json.Unmarshal(v.B, &tv); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = tv
|
|
case ViewPropertyTypeMarkdown:
|
|
var mv MarkdownViewProperties
|
|
if err := json.Unmarshal(v.B, &mv); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = mv
|
|
case ViewPropertyTypeLogViewer: // happens in log viewer stays in log viewer.
|
|
var lv LogViewProperties
|
|
if err := json.Unmarshal(v.B, &lv); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = lv
|
|
case ViewPropertyTypeSingleStatPlusLine:
|
|
var lv LinePlusSingleStatProperties
|
|
if err := json.Unmarshal(v.B, &lv); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = lv
|
|
case ViewPropertyTypeHistogram:
|
|
var hv HistogramViewProperties
|
|
if err := json.Unmarshal(v.B, &hv); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = hv
|
|
case ViewPropertyTypeHeatMap:
|
|
var hv HeatmapViewProperties
|
|
if err := json.Unmarshal(v.B, &hv); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = hv
|
|
case ViewPropertyTypeScatter:
|
|
var sv ScatterViewProperties
|
|
if err := json.Unmarshal(v.B, &sv); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = sv
|
|
case ViewPropertyTypeMosaic:
|
|
var mv MosaicViewProperties
|
|
if err := json.Unmarshal(v.B, &mv); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = mv
|
|
case ViewPropertyTypeBand:
|
|
var bv BandViewProperties
|
|
if err := json.Unmarshal(v.B, &bv); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = bv
|
|
}
|
|
case "empty":
|
|
var ev EmptyViewProperties
|
|
if err := json.Unmarshal(v.B, &ev); err != nil {
|
|
return nil, err
|
|
}
|
|
vis = ev
|
|
default:
|
|
return nil, fmt.Errorf("unknown shape %v", t.Shape)
|
|
}
|
|
|
|
return vis, nil
|
|
}
|
|
|
|
// MarshalViewPropertiesJSON encodes a view into JSON bytes.
|
|
func MarshalViewPropertiesJSON(v ViewProperties) ([]byte, error) {
|
|
var s interface{}
|
|
switch vis := v.(type) {
|
|
case SingleStatViewProperties:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
SingleStatViewProperties
|
|
}{
|
|
Shape: "chronograf-v2",
|
|
|
|
SingleStatViewProperties: vis,
|
|
}
|
|
case TableViewProperties:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
TableViewProperties
|
|
}{
|
|
Shape: "chronograf-v2",
|
|
|
|
TableViewProperties: vis,
|
|
}
|
|
case GaugeViewProperties:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
GaugeViewProperties
|
|
}{
|
|
Shape: "chronograf-v2",
|
|
|
|
GaugeViewProperties: vis,
|
|
}
|
|
case GeoViewProperties:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
GeoViewProperties
|
|
}{
|
|
Shape: "chronograf-v2",
|
|
GeoViewProperties: vis,
|
|
}
|
|
case XYViewProperties:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
XYViewProperties
|
|
}{
|
|
Shape: "chronograf-v2",
|
|
|
|
XYViewProperties: vis,
|
|
}
|
|
case BandViewProperties:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
BandViewProperties
|
|
}{
|
|
Shape: "chronograf-v2",
|
|
|
|
BandViewProperties: vis,
|
|
}
|
|
case LinePlusSingleStatProperties:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
LinePlusSingleStatProperties
|
|
}{
|
|
Shape: "chronograf-v2",
|
|
|
|
LinePlusSingleStatProperties: vis,
|
|
}
|
|
case HistogramViewProperties:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
HistogramViewProperties
|
|
}{
|
|
Shape: "chronograf-v2",
|
|
|
|
HistogramViewProperties: vis,
|
|
}
|
|
case HeatmapViewProperties:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
HeatmapViewProperties
|
|
}{
|
|
Shape: "chronograf-v2",
|
|
|
|
HeatmapViewProperties: vis,
|
|
}
|
|
case ScatterViewProperties:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
ScatterViewProperties
|
|
}{
|
|
Shape: "chronograf-v2",
|
|
|
|
ScatterViewProperties: vis,
|
|
}
|
|
case MosaicViewProperties:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
MosaicViewProperties
|
|
}{
|
|
Shape: "chronograf-v2",
|
|
|
|
MosaicViewProperties: vis,
|
|
}
|
|
case MarkdownViewProperties:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
MarkdownViewProperties
|
|
}{
|
|
Shape: "chronograf-v2",
|
|
|
|
MarkdownViewProperties: vis,
|
|
}
|
|
case LogViewProperties:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
LogViewProperties
|
|
}{
|
|
Shape: "chronograf-v2",
|
|
LogViewProperties: vis,
|
|
}
|
|
case CheckViewProperties:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
CheckViewProperties
|
|
}{
|
|
Shape: "chronograf-v2",
|
|
|
|
CheckViewProperties: vis,
|
|
}
|
|
default:
|
|
s = struct {
|
|
Shape string `json:"shape"`
|
|
EmptyViewProperties
|
|
}{
|
|
Shape: "empty",
|
|
EmptyViewProperties: EmptyViewProperties{},
|
|
}
|
|
}
|
|
return json.Marshal(s)
|
|
}
|
|
|
|
// MarshalJSON encodes a view to JSON bytes.
|
|
func (v View) MarshalJSON() ([]byte, error) {
|
|
viewProperties, err := MarshalViewPropertiesJSON(v.Properties)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return json.Marshal(struct {
|
|
ViewContents
|
|
ViewProperties json.RawMessage `json:"properties"`
|
|
}{
|
|
ViewContents: v.ViewContents,
|
|
ViewProperties: viewProperties,
|
|
})
|
|
}
|
|
|
|
// UnmarshalJSON decodes JSON bytes into the corresponding view type (those that implement ViewProperties).
|
|
func (c *View) UnmarshalJSON(b []byte) error {
|
|
if err := json.Unmarshal(b, &c.ViewContents); err != nil {
|
|
return err
|
|
}
|
|
|
|
v, err := UnmarshalViewPropertiesJSON(b)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
c.Properties = v
|
|
return nil
|
|
}
|
|
|
|
// UnmarshalJSON decodes JSON bytes into the corresponding view update type (those that implement ViewProperties).
|
|
func (u *ViewUpdate) UnmarshalJSON(b []byte) error {
|
|
if err := json.Unmarshal(b, &u.ViewContentsUpdate); err != nil {
|
|
return err
|
|
}
|
|
|
|
v, err := UnmarshalViewPropertiesJSON(b)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
u.Properties = v
|
|
return nil
|
|
}
|
|
|
|
// MarshalJSON encodes a view to JSON bytes.
|
|
func (u ViewUpdate) MarshalJSON() ([]byte, error) {
|
|
vis, err := MarshalViewPropertiesJSON(u.Properties)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return json.Marshal(struct {
|
|
ViewContentsUpdate
|
|
ViewProperties json.RawMessage `json:"properties,omitempty"`
|
|
}{
|
|
ViewContentsUpdate: u.ViewContentsUpdate,
|
|
ViewProperties: vis,
|
|
})
|
|
}
|
|
|
|
// LinePlusSingleStatProperties represents options for line plus single stat view in Chronograf
|
|
type LinePlusSingleStatProperties struct {
|
|
Queries []DashboardQuery `json:"queries"`
|
|
Axes map[string]Axis `json:"axes"`
|
|
Type string `json:"type"`
|
|
StaticLegend StaticLegend `json:"staticLegend"`
|
|
ViewColors []ViewColor `json:"colors"`
|
|
Prefix string `json:"prefix"`
|
|
Suffix string `json:"suffix"`
|
|
DecimalPlaces DecimalPlaces `json:"decimalPlaces"`
|
|
Note string `json:"note"`
|
|
ShowNoteWhenEmpty bool `json:"showNoteWhenEmpty"`
|
|
XColumn string `json:"xColumn"`
|
|
GenerateXAxisTicks []string `json:"generateXAxisTicks"`
|
|
XTotalTicks int `json:"xTotalTicks"`
|
|
XTickStart float64 `json:"xTickStart"`
|
|
XTickStep float64 `json:"xTickStep"`
|
|
YColumn string `json:"yColumn"`
|
|
GenerateYAxisTicks []string `json:"generateYAxisTicks"`
|
|
YTotalTicks int `json:"yTotalTicks"`
|
|
YTickStart float64 `json:"yTickStart"`
|
|
YTickStep float64 `json:"yTickStep"`
|
|
ShadeBelow bool `json:"shadeBelow"`
|
|
Position string `json:"position"`
|
|
TimeFormat string `json:"timeFormat"`
|
|
HoverDimension string `json:"hoverDimension"`
|
|
LegendColorizeRows bool `json:"legendColorizeRows"`
|
|
LegendHide bool `json:"legendHide"`
|
|
LegendOpacity float64 `json:"legendOpacity"`
|
|
LegendOrientationThreshold int `json:"legendOrientationThreshold"`
|
|
}
|
|
|
|
// XYViewProperties represents options for line, bar, step, or stacked view in Chronograf
|
|
type XYViewProperties struct {
|
|
Queries []DashboardQuery `json:"queries"`
|
|
Axes map[string]Axis `json:"axes"`
|
|
Type string `json:"type"`
|
|
StaticLegend StaticLegend `json:"staticLegend"`
|
|
Geom string `json:"geom"` // Either "line", "step", "stacked", or "bar"
|
|
ViewColors []ViewColor `json:"colors"`
|
|
Note string `json:"note"`
|
|
ShowNoteWhenEmpty bool `json:"showNoteWhenEmpty"`
|
|
XColumn string `json:"xColumn"`
|
|
GenerateXAxisTicks []string `json:"generateXAxisTicks"`
|
|
XTotalTicks int `json:"xTotalTicks"`
|
|
XTickStart float64 `json:"xTickStart"`
|
|
XTickStep float64 `json:"xTickStep"`
|
|
YColumn string `json:"yColumn"`
|
|
GenerateYAxisTicks []string `json:"generateYAxisTicks"`
|
|
YTotalTicks int `json:"yTotalTicks"`
|
|
YTickStart float64 `json:"yTickStart"`
|
|
YTickStep float64 `json:"yTickStep"`
|
|
ShadeBelow bool `json:"shadeBelow"`
|
|
Position string `json:"position"`
|
|
TimeFormat string `json:"timeFormat"`
|
|
HoverDimension string `json:"hoverDimension"`
|
|
LegendColorizeRows bool `json:"legendColorizeRows"`
|
|
LegendHide bool `json:"legendHide"`
|
|
LegendOpacity float64 `json:"legendOpacity"`
|
|
LegendOrientationThreshold int `json:"legendOrientationThreshold"`
|
|
}
|
|
|
|
// BandViewProperties represents options for the band view
|
|
type BandViewProperties struct {
|
|
Queries []DashboardQuery `json:"queries"`
|
|
Axes map[string]Axis `json:"axes"`
|
|
Type string `json:"type"`
|
|
StaticLegend StaticLegend `json:"staticLegend"`
|
|
Geom string `json:"geom"`
|
|
ViewColors []ViewColor `json:"colors"`
|
|
Note string `json:"note"`
|
|
ShowNoteWhenEmpty bool `json:"showNoteWhenEmpty"`
|
|
TimeFormat string `json:"timeFormat"`
|
|
HoverDimension string `json:"hoverDimension"`
|
|
XColumn string `json:"xColumn"`
|
|
GenerateXAxisTicks []string `json:"generateXAxisTicks"`
|
|
XTotalTicks int `json:"xTotalTicks"`
|
|
XTickStart float64 `json:"xTickStart"`
|
|
XTickStep float64 `json:"xTickStep"`
|
|
YColumn string `json:"yColumn"`
|
|
GenerateYAxisTicks []string `json:"generateYAxisTicks"`
|
|
YTotalTicks int `json:"yTotalTicks"`
|
|
YTickStart float64 `json:"yTickStart"`
|
|
YTickStep float64 `json:"yTickStep"`
|
|
UpperColumn string `json:"upperColumn"`
|
|
MainColumn string `json:"mainColumn"`
|
|
LowerColumn string `json:"lowerColumn"`
|
|
LegendColorizeRows bool `json:"legendColorizeRows"`
|
|
LegendHide bool `json:"legendHide"`
|
|
LegendOpacity float64 `json:"legendOpacity"`
|
|
LegendOrientationThreshold int `json:"legendOrientationThreshold"`
|
|
}
|
|
|
|
// CheckViewProperties represents options for a view representing a check
|
|
type CheckViewProperties struct {
|
|
Type string `json:"type"`
|
|
CheckID string `json:"checkID"`
|
|
Queries []DashboardQuery `json:"queries"`
|
|
ViewColors []string `json:"colors"`
|
|
LegendColorizeRows bool `json:"legendColorizeRows"`
|
|
LegendHide bool `json:"legendHide"`
|
|
LegendOpacity float64 `json:"legendOpacity"`
|
|
LegendOrientationThreshold int `json:"legendOrientationThreshold"`
|
|
}
|
|
|
|
// SingleStatViewProperties represents options for single stat view in Chronograf
|
|
type SingleStatViewProperties struct {
|
|
Type string `json:"type"`
|
|
Queries []DashboardQuery `json:"queries"`
|
|
Prefix string `json:"prefix"`
|
|
TickPrefix string `json:"tickPrefix"`
|
|
Suffix string `json:"suffix"`
|
|
TickSuffix string `json:"tickSuffix"`
|
|
ViewColors []ViewColor `json:"colors"`
|
|
DecimalPlaces DecimalPlaces `json:"decimalPlaces"`
|
|
Note string `json:"note"`
|
|
ShowNoteWhenEmpty bool `json:"showNoteWhenEmpty"`
|
|
}
|
|
|
|
// HistogramViewProperties represents options for histogram view in Chronograf
|
|
type HistogramViewProperties struct {
|
|
Type string `json:"type"`
|
|
Queries []DashboardQuery `json:"queries"`
|
|
ViewColors []ViewColor `json:"colors"`
|
|
XColumn string `json:"xColumn"`
|
|
FillColumns []string `json:"fillColumns"`
|
|
XDomain []float64 `json:"xDomain,omitempty"`
|
|
XAxisLabel string `json:"xAxisLabel"`
|
|
Position string `json:"position"`
|
|
BinCount int `json:"binCount"`
|
|
Note string `json:"note"`
|
|
ShowNoteWhenEmpty bool `json:"showNoteWhenEmpty"`
|
|
LegendColorizeRows bool `json:"legendColorizeRows"`
|
|
LegendHide bool `json:"legendHide"`
|
|
LegendOpacity float64 `json:"legendOpacity"`
|
|
LegendOrientationThreshold int `json:"legendOrientationThreshold"`
|
|
}
|
|
|
|
// HeatmapViewProperties represents options for heatmap view in Chronograf
|
|
type HeatmapViewProperties struct {
|
|
Type string `json:"type"`
|
|
Queries []DashboardQuery `json:"queries"`
|
|
ViewColors []string `json:"colors"`
|
|
BinSize int32 `json:"binSize"`
|
|
XColumn string `json:"xColumn"`
|
|
GenerateXAxisTicks []string `json:"generateXAxisTicks"`
|
|
XTotalTicks int `json:"xTotalTicks"`
|
|
XTickStart float64 `json:"xTickStart"`
|
|
XTickStep float64 `json:"xTickStep"`
|
|
YColumn string `json:"yColumn"`
|
|
GenerateYAxisTicks []string `json:"generateYAxisTicks"`
|
|
YTotalTicks int `json:"yTotalTicks"`
|
|
YTickStart float64 `json:"yTickStart"`
|
|
YTickStep float64 `json:"yTickStep"`
|
|
XDomain []float64 `json:"xDomain,omitempty"`
|
|
YDomain []float64 `json:"yDomain,omitempty"`
|
|
XAxisLabel string `json:"xAxisLabel"`
|
|
YAxisLabel string `json:"yAxisLabel"`
|
|
XPrefix string `json:"xPrefix"`
|
|
XSuffix string `json:"xSuffix"`
|
|
YPrefix string `json:"yPrefix"`
|
|
YSuffix string `json:"ySuffix"`
|
|
Note string `json:"note"`
|
|
ShowNoteWhenEmpty bool `json:"showNoteWhenEmpty"`
|
|
TimeFormat string `json:"timeFormat"`
|
|
LegendColorizeRows bool `json:"legendColorizeRows"`
|
|
LegendHide bool `json:"legendHide"`
|
|
LegendOpacity float64 `json:"legendOpacity"`
|
|
LegendOrientationThreshold int `json:"legendOrientationThreshold"`
|
|
}
|
|
|
|
// ScatterViewProperties represents options for scatter view in Chronograf
|
|
type ScatterViewProperties struct {
|
|
Type string `json:"type"`
|
|
Queries []DashboardQuery `json:"queries"`
|
|
ViewColors []string `json:"colors"`
|
|
FillColumns []string `json:"fillColumns"`
|
|
SymbolColumns []string `json:"symbolColumns"`
|
|
XColumn string `json:"xColumn"`
|
|
GenerateXAxisTicks []string `json:"generateXAxisTicks"`
|
|
XTotalTicks int `json:"xTotalTicks"`
|
|
XTickStart float64 `json:"xTickStart"`
|
|
XTickStep float64 `json:"xTickStep"`
|
|
YColumn string `json:"yColumn"`
|
|
GenerateYAxisTicks []string `json:"generateYAxisTicks"`
|
|
YTotalTicks int `json:"yTotalTicks"`
|
|
YTickStart float64 `json:"yTickStart"`
|
|
YTickStep float64 `json:"yTickStep"`
|
|
XDomain []float64 `json:"xDomain,omitempty"`
|
|
YDomain []float64 `json:"yDomain,omitempty"`
|
|
XAxisLabel string `json:"xAxisLabel"`
|
|
YAxisLabel string `json:"yAxisLabel"`
|
|
XPrefix string `json:"xPrefix"`
|
|
XSuffix string `json:"xSuffix"`
|
|
YPrefix string `json:"yPrefix"`
|
|
YSuffix string `json:"ySuffix"`
|
|
Note string `json:"note"`
|
|
ShowNoteWhenEmpty bool `json:"showNoteWhenEmpty"`
|
|
TimeFormat string `json:"timeFormat"`
|
|
LegendColorizeRows bool `json:"legendColorizeRows"`
|
|
LegendHide bool `json:"legendHide"`
|
|
LegendOpacity float64 `json:"legendOpacity"`
|
|
LegendOrientationThreshold int `json:"legendOrientationThreshold"`
|
|
}
|
|
|
|
// MosaicViewProperties represents options for mosaic view in Chronograf
|
|
type MosaicViewProperties struct {
|
|
Type string `json:"type"`
|
|
Queries []DashboardQuery `json:"queries"`
|
|
ViewColors []string `json:"colors"`
|
|
FillColumns []string `json:"fillColumns"`
|
|
XColumn string `json:"xColumn"`
|
|
GenerateXAxisTicks []string `json:"generateXAxisTicks"`
|
|
XTotalTicks int `json:"xTotalTicks"`
|
|
XTickStart float64 `json:"xTickStart"`
|
|
XTickStep float64 `json:"xTickStep"`
|
|
YLabelColumnSeparator string `json:"yLabelColumnSeparator"`
|
|
YLabelColumns []string `json:"yLabelColumns"`
|
|
YSeriesColumns []string `json:"ySeriesColumns"`
|
|
XDomain []float64 `json:"xDomain,omitempty"`
|
|
YDomain []float64 `json:"yDomain,omitempty"`
|
|
XAxisLabel string `json:"xAxisLabel"`
|
|
YAxisLabel string `json:"yAxisLabel"`
|
|
XPrefix string `json:"xPrefix"`
|
|
XSuffix string `json:"xSuffix"`
|
|
YPrefix string `json:"yPrefix"`
|
|
YSuffix string `json:"ySuffix"`
|
|
Note string `json:"note"`
|
|
ShowNoteWhenEmpty bool `json:"showNoteWhenEmpty"`
|
|
TimeFormat string `json:"timeFormat"`
|
|
HoverDimension string `json:"hoverDimension"`
|
|
LegendColorizeRows bool `json:"legendColorizeRows"`
|
|
LegendHide bool `json:"legendHide"`
|
|
LegendOpacity float64 `json:"legendOpacity"`
|
|
LegendOrientationThreshold int `json:"legendOrientationThreshold"`
|
|
}
|
|
|
|
// GaugeViewProperties represents options for gauge view in Chronograf
|
|
type GaugeViewProperties struct {
|
|
Type string `json:"type"`
|
|
Queries []DashboardQuery `json:"queries"`
|
|
Prefix string `json:"prefix"`
|
|
TickPrefix string `json:"tickPrefix"`
|
|
Suffix string `json:"suffix"`
|
|
TickSuffix string `json:"tickSuffix"`
|
|
ViewColors []ViewColor `json:"colors"`
|
|
DecimalPlaces DecimalPlaces `json:"decimalPlaces"`
|
|
Note string `json:"note"`
|
|
ShowNoteWhenEmpty bool `json:"showNoteWhenEmpty"`
|
|
}
|
|
|
|
// Geographical coordinates
|
|
type Datum struct {
|
|
Lat float64 `json:"lat"`
|
|
Lon float64 `json:"lon"`
|
|
}
|
|
|
|
// Single visualization layer properties of a chronograf map widget
|
|
type GeoLayer struct {
|
|
Type string `json:"type"`
|
|
RadiusField string `json:"radiusField"`
|
|
ColorField string `json:"colorField"`
|
|
IntensityField string `json:"intensityField"`
|
|
// circle layer properties
|
|
ViewColors []ViewColor `json:"colors"`
|
|
Radius int32 `json:"radius"`
|
|
Blur int32 `json:"blur"`
|
|
RadiusDimension Axis `json:"radiusDimension,omitempty"`
|
|
ColorDimension Axis `json:"colorDimension,omitempty"`
|
|
IntensityDimension Axis `json:"intensityDimension,omitempty"`
|
|
InterpolateColors bool `json:"interpolateColors"`
|
|
// track layer properties
|
|
TrackWidth int32 `json:"trackWidth"`
|
|
Speed int32 `json:"speed"`
|
|
RandomColors bool `json:"randomColors"`
|
|
// point layer properties
|
|
IsClustered bool `json:"isClustered"`
|
|
}
|
|
|
|
// GeoViewProperties represents options for map view in Chronograf
|
|
type GeoViewProperties struct {
|
|
Type string `json:"type"`
|
|
Queries []DashboardQuery `json:"queries"`
|
|
Center Datum `json:"center"`
|
|
Zoom float64 `json:"zoom"`
|
|
MapStyle string `json:"mapStyle"`
|
|
AllowPanAndZoom bool `json:"allowPanAndZoom"`
|
|
DetectCoordinateFields bool `json:"detectCoordinateFields"`
|
|
ViewColor []ViewColor `json:"colors"`
|
|
GeoLayers []GeoLayer `json:"layers"`
|
|
Note string `json:"note"`
|
|
ShowNoteWhenEmpty bool `json:"showNoteWhenEmpty"`
|
|
}
|
|
|
|
// TableViewProperties represents options for table view in Chronograf
|
|
type TableViewProperties struct {
|
|
Type string `json:"type"`
|
|
Queries []DashboardQuery `json:"queries"`
|
|
ViewColors []ViewColor `json:"colors"`
|
|
TableOptions TableOptions `json:"tableOptions"`
|
|
FieldOptions []RenamableField `json:"fieldOptions"`
|
|
TimeFormat string `json:"timeFormat"`
|
|
DecimalPlaces DecimalPlaces `json:"decimalPlaces"`
|
|
Note string `json:"note"`
|
|
ShowNoteWhenEmpty bool `json:"showNoteWhenEmpty"`
|
|
}
|
|
|
|
type MarkdownViewProperties struct {
|
|
Type string `json:"type"`
|
|
Note string `json:"note"`
|
|
}
|
|
|
|
// LogViewProperties represents options for log viewer in Chronograf.
|
|
type LogViewProperties struct {
|
|
Type string `json:"type"`
|
|
Columns []LogViewerColumn `json:"columns"`
|
|
}
|
|
|
|
// LogViewerColumn represents a specific column in a Log Viewer.
|
|
type LogViewerColumn struct {
|
|
Name string `json:"name"`
|
|
Position int32 `json:"position"`
|
|
Settings []LogColumnSetting `json:"settings"`
|
|
}
|
|
|
|
// LogColumnSetting represent the settings for a specific column of a Log Viewer.
|
|
type LogColumnSetting struct {
|
|
Type string `json:"type"`
|
|
Value string `json:"value"`
|
|
Name string `json:"name,omitempty"`
|
|
}
|
|
|
|
func (XYViewProperties) viewProperties() {}
|
|
func (BandViewProperties) viewProperties() {}
|
|
func (LinePlusSingleStatProperties) viewProperties() {}
|
|
func (SingleStatViewProperties) viewProperties() {}
|
|
func (HistogramViewProperties) viewProperties() {}
|
|
func (HeatmapViewProperties) viewProperties() {}
|
|
func (ScatterViewProperties) viewProperties() {}
|
|
func (MosaicViewProperties) viewProperties() {}
|
|
func (GaugeViewProperties) viewProperties() {}
|
|
func (GeoViewProperties) viewProperties() {}
|
|
func (TableViewProperties) viewProperties() {}
|
|
func (MarkdownViewProperties) viewProperties() {}
|
|
func (LogViewProperties) viewProperties() {}
|
|
func (CheckViewProperties) viewProperties() {}
|
|
|
|
func (v XYViewProperties) GetType() string { return v.Type }
|
|
func (v BandViewProperties) GetType() string { return v.Type }
|
|
func (v LinePlusSingleStatProperties) GetType() string { return v.Type }
|
|
func (v SingleStatViewProperties) GetType() string { return v.Type }
|
|
func (v HistogramViewProperties) GetType() string { return v.Type }
|
|
func (v HeatmapViewProperties) GetType() string { return v.Type }
|
|
func (v ScatterViewProperties) GetType() string { return v.Type }
|
|
func (v MosaicViewProperties) GetType() string { return v.Type }
|
|
func (v GaugeViewProperties) GetType() string { return v.Type }
|
|
func (v GeoViewProperties) GetType() string { return v.Type }
|
|
func (v TableViewProperties) GetType() string { return v.Type }
|
|
func (v MarkdownViewProperties) GetType() string { return v.Type }
|
|
func (v LogViewProperties) GetType() string { return v.Type }
|
|
func (v CheckViewProperties) GetType() string { return v.Type }
|
|
|
|
/////////////////////////////
|
|
// Old Chronograf Types
|
|
/////////////////////////////
|
|
|
|
// DashboardQuery represents a query used in a dashboard cell
|
|
type DashboardQuery struct {
|
|
Text string `json:"text"`
|
|
EditMode string `json:"editMode"` // Either "builder" or "advanced"
|
|
Name string `json:"name"` // Term or phrase that refers to the query
|
|
BuilderConfig BuilderConfig `json:"builderConfig"`
|
|
}
|
|
|
|
type BuilderConfig struct {
|
|
Buckets []string `json:"buckets"`
|
|
Tags []struct {
|
|
Key string `json:"key"`
|
|
Values []string `json:"values"`
|
|
AggregateFunctionType string `json:"aggregateFunctionType"`
|
|
} `json:"tags"`
|
|
Functions []struct {
|
|
Name string `json:"name"`
|
|
} `json:"functions"`
|
|
AggregateWindow struct {
|
|
Period string `json:"period"`
|
|
FillValues bool `json:"fillValues"`
|
|
} `json:"aggregateWindow"`
|
|
}
|
|
|
|
// MarshalJSON is necessary for the time being. UI keeps breaking
|
|
// b/c it relies on these slices being populated/not nil. Other
|
|
// consumers may have same issue.
|
|
func (b BuilderConfig) MarshalJSON() ([]byte, error) {
|
|
type alias BuilderConfig
|
|
copyCfg := alias(b)
|
|
if copyCfg.Buckets == nil {
|
|
copyCfg.Buckets = []string{}
|
|
}
|
|
if copyCfg.Tags == nil {
|
|
copyCfg.Tags = []struct {
|
|
Key string `json:"key"`
|
|
Values []string `json:"values"`
|
|
AggregateFunctionType string `json:"aggregateFunctionType"`
|
|
}{}
|
|
}
|
|
if copyCfg.Functions == nil {
|
|
copyCfg.Functions = []struct {
|
|
Name string `json:"name"`
|
|
}{}
|
|
}
|
|
return json.Marshal(copyCfg)
|
|
}
|
|
|
|
// NewBuilderTag is a constructor for the builder config types. This
|
|
// isn't technically required, but working with struct literals with embedded
|
|
// struct tags is really painful. This is to get around that bit. Would be nicer
|
|
// to have these as actual types maybe.
|
|
func NewBuilderTag(key string, functionType string, values ...string) struct {
|
|
Key string `json:"key"`
|
|
Values []string `json:"values"`
|
|
AggregateFunctionType string `json:"aggregateFunctionType"`
|
|
} {
|
|
return struct {
|
|
Key string `json:"key"`
|
|
Values []string `json:"values"`
|
|
AggregateFunctionType string `json:"aggregateFunctionType"`
|
|
}{
|
|
Key: key,
|
|
Values: values,
|
|
AggregateFunctionType: functionType,
|
|
}
|
|
}
|
|
|
|
// Axis represents the visible extents of a visualization
|
|
type Axis struct {
|
|
Bounds []string `json:"bounds"` // bounds are an arbitrary list of client-defined strings that specify the viewport for a View
|
|
LegacyBounds [2]int64 `json:"-"` // legacy bounds are for testing a migration from an earlier version of axis
|
|
Label string `json:"label"` // label is a description of this Axis
|
|
Prefix string `json:"prefix"` // Prefix represents a label prefix for formatting axis values
|
|
Suffix string `json:"suffix"` // Suffix represents a label suffix for formatting axis values
|
|
Base string `json:"base"` // Base represents the radix for formatting axis values
|
|
Scale string `json:"scale"` // Scale is the axis formatting scale. Supported: "log", "linear"
|
|
}
|
|
|
|
// ViewColor represents the encoding of data into visualizations
|
|
type ViewColor struct {
|
|
ID string `json:"id"` // ID is the unique id of the View color
|
|
Type string `json:"type"` // Type is how the color is used. Accepted (min,max,threshold)
|
|
Hex string `json:"hex"` // Hex is the hex number of the color
|
|
Name string `json:"name"` // Name is the user-facing name of the hex color
|
|
Value float64 `json:"value"` // Value is the data value mapped to this color
|
|
}
|
|
|
|
// StaticLegend represents the options specific to the static legend
|
|
type StaticLegend struct {
|
|
ColorizeRows bool `json:"colorizeRows,omitempty"`
|
|
HeightRatio float64 `json:"heightRatio,omitempty"`
|
|
Show bool `json:"show,omitempty"`
|
|
Opacity float64 `json:"opacity,omitempty"`
|
|
OrientationThreshold int `json:"orientationThreshold,omitempty"`
|
|
ValueAxis string `json:"valueAxis,omitempty"`
|
|
WidthRatio float64 `json:"widthRatio,omitempty"`
|
|
}
|
|
|
|
// TableOptions is a type of options for a DashboardView with type Table
|
|
type TableOptions struct {
|
|
VerticalTimeAxis bool `json:"verticalTimeAxis"`
|
|
SortBy RenamableField `json:"sortBy"`
|
|
Wrapping string `json:"wrapping"`
|
|
FixFirstColumn bool `json:"fixFirstColumn"`
|
|
}
|
|
|
|
// RenamableField is a column/row field in a DashboardView of type Table
|
|
type RenamableField struct {
|
|
InternalName string `json:"internalName"`
|
|
DisplayName string `json:"displayName"`
|
|
Visible bool `json:"visible"`
|
|
}
|
|
|
|
// DecimalPlaces indicates whether decimal places should be enforced, and how many digits it should show.
|
|
type DecimalPlaces struct {
|
|
IsEnforced bool `json:"isEnforced"`
|
|
Digits int32 `json:"digits"`
|
|
}
|