diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d1071eef7..62b0b6fb5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ 1. [#1866](https://github.com/influxdata/chronograf/pull/1866): Fix non-persistence of dashboard graph types ### Features +1. [#1859](https://github.com/influxdata/chronograf/pull/1859): Add y-axis controls to the API for layouts ### UI Improvements 1. [#1846](https://github.com/influxdata/chronograf/pull/1846): Increase screen real estate of Query Maker in the Cell Editor Overlay diff --git a/bolt/internal/internal.go b/bolt/internal/internal.go index 6d5fbc6b74..fefa93e785 100644 --- a/bolt/internal/internal.go +++ b/bolt/internal/internal.go @@ -98,6 +98,14 @@ func MarshalLayout(l chronograf.Layout) ([]byte, error) { } } + axes := make(map[string]*Axis, len(c.Axes)) + for a, r := range c.Axes { + axes[a] = &Axis{ + Bounds: r.Bounds, + Label: r.Label, + } + } + cells[i] = &Cell{ X: c.X, Y: c.Y, @@ -107,6 +115,7 @@ func MarshalLayout(l chronograf.Layout) ([]byte, error) { Name: c.Name, Queries: queries, Type: c.Type, + Axes: axes, } } return proto.Marshal(&Layout{ @@ -148,6 +157,13 @@ func UnmarshalLayout(data []byte, l *chronograf.Layout) error { } } } + axes := make(map[string]chronograf.Axis, len(c.Axes)) + for a, r := range c.Axes { + axes[a] = chronograf.Axis{ + Bounds: r.Bounds, + Label: r.Label, + } + } cells[i] = chronograf.Cell{ X: c.X, @@ -158,6 +174,7 @@ func UnmarshalLayout(data []byte, l *chronograf.Layout) error { Name: c.Name, Queries: queries, Type: c.Type, + Axes: axes, } } l.Cells = cells diff --git a/bolt/internal/internal.pb.go b/bolt/internal/internal.pb.go index d8eb0e222f..19a6c8d44e 100644 --- a/bolt/internal/internal.pb.go +++ b/bolt/internal/internal.pb.go @@ -217,16 +217,17 @@ func (m *Layout) GetCells() []*Cell { } type Cell struct { - X int32 `protobuf:"varint,1,opt,name=x,proto3" json:"x,omitempty"` - Y int32 `protobuf:"varint,2,opt,name=y,proto3" json:"y,omitempty"` - W int32 `protobuf:"varint,3,opt,name=w,proto3" json:"w,omitempty"` - H int32 `protobuf:"varint,4,opt,name=h,proto3" json:"h,omitempty"` - Queries []*Query `protobuf:"bytes,5,rep,name=queries" json:"queries,omitempty"` - I string `protobuf:"bytes,6,opt,name=i,proto3" json:"i,omitempty"` - Name string `protobuf:"bytes,7,opt,name=name,proto3" json:"name,omitempty"` - Yranges []int64 `protobuf:"varint,8,rep,name=yranges" json:"yranges,omitempty"` - Ylabels []string `protobuf:"bytes,9,rep,name=ylabels" json:"ylabels,omitempty"` - Type string `protobuf:"bytes,10,opt,name=type,proto3" json:"type,omitempty"` + X int32 `protobuf:"varint,1,opt,name=x,proto3" json:"x,omitempty"` + Y int32 `protobuf:"varint,2,opt,name=y,proto3" json:"y,omitempty"` + W int32 `protobuf:"varint,3,opt,name=w,proto3" json:"w,omitempty"` + H int32 `protobuf:"varint,4,opt,name=h,proto3" json:"h,omitempty"` + Queries []*Query `protobuf:"bytes,5,rep,name=queries" json:"queries,omitempty"` + I string `protobuf:"bytes,6,opt,name=i,proto3" json:"i,omitempty"` + Name string `protobuf:"bytes,7,opt,name=name,proto3" json:"name,omitempty"` + Yranges []int64 `protobuf:"varint,8,rep,name=yranges" json:"yranges,omitempty"` + Ylabels []string `protobuf:"bytes,9,rep,name=ylabels" json:"ylabels,omitempty"` + Type string `protobuf:"bytes,10,opt,name=type,proto3" json:"type,omitempty"` + Axes map[string]*Axis `protobuf:"bytes,11,rep,name=axes" json:"axes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value"` } func (m *Cell) Reset() { *m = Cell{} } @@ -241,6 +242,13 @@ func (m *Cell) GetQueries() []*Query { return nil } +func (m *Cell) GetAxes() map[string]*Axis { + if m != nil { + return m.Axes + } + return nil +} + type Query struct { Command string `protobuf:"bytes,1,opt,name=Command,proto3" json:"Command,omitempty"` DB string `protobuf:"bytes,2,opt,name=DB,proto3" json:"DB,omitempty"` @@ -315,66 +323,67 @@ func init() { func init() { proto.RegisterFile("internal.proto", fileDescriptorInternal) } var fileDescriptorInternal = []byte{ - // 974 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x56, 0xdf, 0x6e, 0xe3, 0xc4, - 0x17, 0xd6, 0xc4, 0x76, 0x12, 0x9f, 0x76, 0xfb, 0xfb, 0x69, 0xb4, 0x62, 0xcd, 0x72, 0x13, 0x2c, - 0x90, 0x02, 0x12, 0x05, 0xed, 0x0a, 0x09, 0x71, 0x97, 0x36, 0x68, 0x55, 0xda, 0x5d, 0xca, 0xa4, - 0x2d, 0xdc, 0xa0, 0xd5, 0xc4, 0x39, 0x4d, 0xac, 0x75, 0x62, 0x33, 0xb6, 0x9b, 0xf8, 0x2d, 0x78, - 0x02, 0x24, 0x24, 0xae, 0xb8, 0xe0, 0x82, 0x17, 0xe0, 0x21, 0x78, 0x21, 0x74, 0x66, 0xc6, 0x7f, - 0xc2, 0x76, 0xd1, 0x5e, 0x71, 0x37, 0xdf, 0x39, 0xe3, 0x6f, 0x66, 0xbe, 0xf3, 0x9d, 0x23, 0xc3, - 0x51, 0xbc, 0x29, 0x50, 0x6d, 0x64, 0x72, 0x9c, 0xa9, 0xb4, 0x48, 0xf9, 0xb0, 0xc6, 0xe1, 0xef, - 0x3d, 0xe8, 0xcf, 0xd2, 0x52, 0x45, 0xc8, 0x8f, 0xa0, 0x77, 0x36, 0x0d, 0xd8, 0x88, 0x8d, 0x1d, - 0xd1, 0x3b, 0x9b, 0x72, 0x0e, 0xee, 0x0b, 0xb9, 0xc6, 0xa0, 0x37, 0x62, 0x63, 0x5f, 0xe8, 0x35, - 0xc5, 0xae, 0xaa, 0x0c, 0x03, 0xc7, 0xc4, 0x68, 0xcd, 0x1f, 0xc3, 0xf0, 0x3a, 0x27, 0xb6, 0x35, - 0x06, 0xae, 0x8e, 0x37, 0x98, 0x72, 0x97, 0x32, 0xcf, 0xb7, 0xa9, 0x5a, 0x04, 0x9e, 0xc9, 0xd5, - 0x98, 0xff, 0x1f, 0x9c, 0x6b, 0x71, 0x11, 0xf4, 0x75, 0x98, 0x96, 0x3c, 0x80, 0xc1, 0x14, 0x6f, - 0x65, 0x99, 0x14, 0xc1, 0x60, 0xc4, 0xc6, 0x43, 0x51, 0x43, 0xe2, 0xb9, 0xc2, 0x04, 0x97, 0x4a, - 0xde, 0x06, 0x43, 0xc3, 0x53, 0x63, 0x7e, 0x0c, 0xfc, 0x6c, 0x93, 0x63, 0x54, 0x2a, 0x9c, 0xbd, - 0x8a, 0xb3, 0x1b, 0x54, 0xf1, 0x6d, 0x15, 0xf8, 0x9a, 0xe0, 0x9e, 0x0c, 0x9d, 0xf2, 0x1c, 0x0b, - 0x49, 0x67, 0x83, 0xa6, 0xaa, 0x21, 0x0f, 0xe1, 0x70, 0xb6, 0x92, 0x0a, 0x17, 0x33, 0x8c, 0x14, - 0x16, 0xc1, 0x81, 0x4e, 0xef, 0xc5, 0xc2, 0x9f, 0x18, 0xf8, 0x53, 0x99, 0xaf, 0xe6, 0xa9, 0x54, - 0x8b, 0xb7, 0xd2, 0xec, 0x13, 0xf0, 0x22, 0x4c, 0x92, 0x3c, 0x70, 0x46, 0xce, 0xf8, 0xe0, 0xc9, - 0xa3, 0xe3, 0xa6, 0x18, 0x0d, 0xcf, 0x29, 0x26, 0x89, 0x30, 0xbb, 0xf8, 0x67, 0xe0, 0x17, 0xb8, - 0xce, 0x12, 0x59, 0x60, 0x1e, 0xb8, 0xfa, 0x13, 0xde, 0x7e, 0x72, 0x65, 0x53, 0xa2, 0xdd, 0x14, - 0xfe, 0xd6, 0x83, 0x07, 0x7b, 0x54, 0xfc, 0x10, 0xd8, 0x4e, 0xdf, 0xca, 0x13, 0x6c, 0x47, 0xa8, - 0xd2, 0x37, 0xf2, 0x04, 0xab, 0x08, 0x6d, 0x75, 0xfd, 0x3c, 0xc1, 0xb6, 0x84, 0x56, 0xba, 0x6a, - 0x9e, 0x60, 0x2b, 0xfe, 0x11, 0x0c, 0x7e, 0x2c, 0x51, 0xc5, 0x98, 0x07, 0x9e, 0x3e, 0xf9, 0x7f, - 0xed, 0xc9, 0xdf, 0x96, 0xa8, 0x2a, 0x51, 0xe7, 0xe9, 0xa5, 0xba, 0xe2, 0xa6, 0x7c, 0x7a, 0x4d, - 0xb1, 0x82, 0xdc, 0x31, 0x30, 0x31, 0x5a, 0x5b, 0x85, 0x4c, 0xcd, 0x48, 0xa1, 0xcf, 0xc1, 0x95, - 0x3b, 0xcc, 0x03, 0x5f, 0xf3, 0xbf, 0xff, 0x06, 0x31, 0x8e, 0x27, 0x3b, 0xcc, 0xbf, 0xda, 0x14, - 0xaa, 0x12, 0x7a, 0xfb, 0xe3, 0x67, 0xe0, 0x37, 0x21, 0x72, 0xce, 0x2b, 0xac, 0xf4, 0x03, 0x7d, - 0x41, 0x4b, 0xfe, 0x01, 0x78, 0x77, 0x32, 0x29, 0x8d, 0xf0, 0x07, 0x4f, 0x8e, 0x5a, 0xda, 0xc9, - 0x2e, 0xce, 0x85, 0x49, 0x7e, 0xd9, 0xfb, 0x82, 0x85, 0xdf, 0x83, 0x4b, 0x21, 0xaa, 0x75, 0x82, - 0x4b, 0x19, 0x55, 0x27, 0x69, 0xb9, 0x59, 0xe4, 0x01, 0x1b, 0x39, 0x63, 0x47, 0xec, 0xc5, 0xf8, - 0x3b, 0xd0, 0x9f, 0x9b, 0x6c, 0x6f, 0xe4, 0x8c, 0x7d, 0x61, 0x11, 0x7f, 0x08, 0x5e, 0x22, 0xe7, - 0x98, 0xd8, 0x36, 0x30, 0x20, 0xfc, 0x93, 0x91, 0x49, 0x4d, 0x51, 0x3a, 0xc6, 0x30, 0xcf, 0x7e, - 0x17, 0x86, 0x54, 0xb0, 0x97, 0x77, 0x52, 0x59, 0x73, 0x0c, 0x08, 0xdf, 0x48, 0xc5, 0x3f, 0x85, - 0xbe, 0xbe, 0xde, 0x3d, 0x06, 0xa9, 0xe9, 0x6e, 0x28, 0x2f, 0xec, 0xb6, 0x46, 0x66, 0xb7, 0x23, - 0x73, 0x73, 0x25, 0xaf, 0x73, 0x25, 0xb2, 0x1e, 0xd5, 0xab, 0xd2, 0x55, 0xba, 0x97, 0xd9, 0x54, - 0xd5, 0xec, 0x0a, 0xaf, 0xe1, 0xc1, 0xde, 0x89, 0xcd, 0x49, 0x6c, 0xff, 0xa4, 0x56, 0x6a, 0xdf, - 0x4a, 0x4b, 0x0d, 0x9a, 0x63, 0x82, 0x51, 0x81, 0x0b, 0xad, 0xca, 0x50, 0x34, 0x38, 0xfc, 0x85, - 0xb5, 0xbc, 0xfa, 0x3c, 0x6a, 0xc1, 0x28, 0x5d, 0xaf, 0xe5, 0x66, 0x61, 0xa9, 0x6b, 0x48, 0xba, - 0x2d, 0xe6, 0x96, 0xba, 0xb7, 0x98, 0x13, 0x56, 0x99, 0xd5, 0xb9, 0xa7, 0x32, 0x3e, 0x82, 0x83, - 0x35, 0xca, 0xbc, 0x54, 0xb8, 0xc6, 0x4d, 0x61, 0x25, 0xe8, 0x86, 0xf8, 0x23, 0x18, 0x14, 0x72, - 0xf9, 0x92, 0x0c, 0x62, 0xb4, 0xe8, 0x17, 0x72, 0x79, 0x8e, 0x15, 0x7f, 0x0f, 0xfc, 0xdb, 0x18, - 0x93, 0x85, 0x4e, 0x19, 0xdb, 0x0e, 0x75, 0xe0, 0x1c, 0xab, 0xf0, 0x57, 0x06, 0xfd, 0x19, 0xaa, - 0x3b, 0x54, 0x6f, 0xd5, 0xd3, 0xdd, 0x99, 0xe7, 0xfc, 0xcb, 0xcc, 0x73, 0xef, 0x9f, 0x79, 0x5e, - 0x3b, 0xf3, 0x1e, 0x82, 0x37, 0x53, 0xd1, 0xd9, 0x54, 0xdf, 0xc8, 0x11, 0x06, 0x90, 0xf3, 0x26, - 0x51, 0x11, 0xdf, 0xa1, 0x1d, 0x84, 0x16, 0x85, 0x3f, 0x33, 0xe8, 0x5f, 0xc8, 0x2a, 0x2d, 0x8b, - 0xd7, 0x1c, 0x36, 0x82, 0x83, 0x49, 0x96, 0x25, 0x71, 0x24, 0x8b, 0x38, 0xdd, 0xd8, 0xdb, 0x76, - 0x43, 0xb4, 0xe3, 0x79, 0x47, 0x3b, 0x73, 0xef, 0x6e, 0x88, 0xda, 0xe8, 0x54, 0x8f, 0x2a, 0x33, - 0x77, 0x3a, 0x6d, 0x64, 0x26, 0x94, 0x4e, 0xd2, 0x03, 0x27, 0x65, 0x91, 0xde, 0x26, 0xe9, 0x56, - 0xbf, 0x64, 0x28, 0x1a, 0x1c, 0xfe, 0xc5, 0xc0, 0xfd, 0xaf, 0x46, 0xd0, 0x21, 0xb0, 0xd8, 0x16, - 0x92, 0xc5, 0xcd, 0x40, 0x1a, 0x74, 0x06, 0x52, 0x00, 0x83, 0x4a, 0xc9, 0xcd, 0x12, 0xf3, 0x60, - 0xa8, 0xfb, 0xbb, 0x86, 0x3a, 0xa3, 0x7b, 0xc4, 0x4c, 0x22, 0x5f, 0xd4, 0xb0, 0xf1, 0x3c, 0xb4, - 0x9e, 0x0f, 0xff, 0x60, 0xe0, 0x35, 0xce, 0x3d, 0xdd, 0x77, 0xee, 0x69, 0xeb, 0xdc, 0xe9, 0x49, - 0xed, 0xdc, 0xe9, 0x09, 0x61, 0x71, 0x59, 0x3b, 0x57, 0x5c, 0x92, 0x6a, 0xcf, 0x54, 0x5a, 0x66, - 0x27, 0x95, 0x91, 0xd7, 0x17, 0x0d, 0xa6, 0x72, 0x7f, 0xb7, 0x42, 0x65, 0xdf, 0xec, 0x0b, 0x8b, - 0xc8, 0x1c, 0x17, 0xba, 0xab, 0xcd, 0x2b, 0x0d, 0xe0, 0x1f, 0x82, 0x27, 0xe8, 0x15, 0xfa, 0xa9, - 0x7b, 0x02, 0xe9, 0xb0, 0x30, 0xd9, 0xf0, 0xa9, 0xdd, 0x46, 0x2c, 0xd7, 0x59, 0x86, 0xca, 0x7a, - 0xda, 0x00, 0xcd, 0x9d, 0x6e, 0xd1, 0x8c, 0x23, 0x47, 0x18, 0x10, 0xfe, 0x00, 0xfe, 0x24, 0x41, - 0x55, 0x88, 0x32, 0x79, 0x7d, 0x88, 0x71, 0x70, 0xbf, 0x9e, 0x7d, 0xf3, 0xa2, 0xee, 0x04, 0x5a, - 0xb7, 0xfe, 0x75, 0xfe, 0xe1, 0xdf, 0x73, 0x99, 0xc9, 0xb3, 0xa9, 0x2e, 0xac, 0x23, 0x2c, 0x0a, - 0x3f, 0x06, 0x97, 0xfa, 0xa4, 0xc3, 0xec, 0xbe, 0xa9, 0xc7, 0xe6, 0x7d, 0xfd, 0xaf, 0xf2, 0xf4, - 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x79, 0x79, 0x87, 0x37, 0xbd, 0x08, 0x00, 0x00, + // 985 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x56, 0xcd, 0x6e, 0x23, 0x45, + 0x10, 0x56, 0xcf, 0x8f, 0xed, 0x29, 0x67, 0x03, 0x6a, 0xad, 0xd8, 0x61, 0xb9, 0x98, 0x11, 0x48, + 0x06, 0x41, 0x40, 0xbb, 0x42, 0x42, 0xdc, 0x9c, 0x18, 0xad, 0x42, 0xb2, 0x4b, 0x68, 0x27, 0x81, + 0x0b, 0x5a, 0xb5, 0xc7, 0x95, 0x64, 0xb4, 0x63, 0xcf, 0xd0, 0x33, 0x13, 0x7b, 0xde, 0x82, 0x27, + 0x40, 0x42, 0xe2, 0xc4, 0x81, 0x03, 0x2f, 0xc0, 0x9d, 0xa7, 0x42, 0xd5, 0xdd, 0x33, 0x1e, 0xb3, + 0x59, 0xb4, 0x17, 0xf6, 0xd6, 0x5f, 0x55, 0xbb, 0xba, 0xe6, 0xab, 0xfa, 0x3e, 0x19, 0xf6, 0x93, + 0x55, 0x89, 0x6a, 0x25, 0xd3, 0x83, 0x5c, 0x65, 0x65, 0xc6, 0x07, 0x0d, 0x8e, 0xfe, 0x70, 0xa0, + 0x37, 0xcb, 0x2a, 0x15, 0x23, 0xdf, 0x07, 0xe7, 0x78, 0x1a, 0xb2, 0x11, 0x1b, 0xbb, 0xc2, 0x39, + 0x9e, 0x72, 0x0e, 0xde, 0x33, 0xb9, 0xc4, 0xd0, 0x19, 0xb1, 0x71, 0x20, 0xf4, 0x99, 0x62, 0xe7, + 0x75, 0x8e, 0xa1, 0x6b, 0x62, 0x74, 0xe6, 0x0f, 0x61, 0x70, 0x51, 0x50, 0xb5, 0x25, 0x86, 0x9e, + 0x8e, 0xb7, 0x98, 0x72, 0x67, 0xb2, 0x28, 0xd6, 0x99, 0x5a, 0x84, 0xbe, 0xc9, 0x35, 0x98, 0xbf, + 0x0d, 0xee, 0x85, 0x38, 0x0d, 0x7b, 0x3a, 0x4c, 0x47, 0x1e, 0x42, 0x7f, 0x8a, 0x57, 0xb2, 0x4a, + 0xcb, 0xb0, 0x3f, 0x62, 0xe3, 0x81, 0x68, 0x20, 0xd5, 0x39, 0xc7, 0x14, 0xaf, 0x95, 0xbc, 0x0a, + 0x07, 0xa6, 0x4e, 0x83, 0xf9, 0x01, 0xf0, 0xe3, 0x55, 0x81, 0x71, 0xa5, 0x70, 0xf6, 0x22, 0xc9, + 0x2f, 0x51, 0x25, 0x57, 0x75, 0x18, 0xe8, 0x02, 0x77, 0x64, 0xe8, 0x95, 0xa7, 0x58, 0x4a, 0x7a, + 0x1b, 0x74, 0xa9, 0x06, 0xf2, 0x08, 0xf6, 0x66, 0x37, 0x52, 0xe1, 0x62, 0x86, 0xb1, 0xc2, 0x32, + 0x1c, 0xea, 0xf4, 0x4e, 0x2c, 0xfa, 0x99, 0x41, 0x30, 0x95, 0xc5, 0xcd, 0x3c, 0x93, 0x6a, 0xf1, + 0x5a, 0x9c, 0x7d, 0x0a, 0x7e, 0x8c, 0x69, 0x5a, 0x84, 0xee, 0xc8, 0x1d, 0x0f, 0x1f, 0x3d, 0x38, + 0x68, 0x87, 0xd1, 0xd6, 0x39, 0xc2, 0x34, 0x15, 0xe6, 0x16, 0xff, 0x1c, 0x82, 0x12, 0x97, 0x79, + 0x2a, 0x4b, 0x2c, 0x42, 0x4f, 0xff, 0x84, 0x6f, 0x7f, 0x72, 0x6e, 0x53, 0x62, 0x7b, 0x29, 0xfa, + 0xdd, 0x81, 0x7b, 0x3b, 0xa5, 0xf8, 0x1e, 0xb0, 0x8d, 0xee, 0xca, 0x17, 0x6c, 0x43, 0xa8, 0xd6, + 0x1d, 0xf9, 0x82, 0xd5, 0x84, 0xd6, 0x7a, 0x7e, 0xbe, 0x60, 0x6b, 0x42, 0x37, 0x7a, 0x6a, 0xbe, + 0x60, 0x37, 0xfc, 0x23, 0xe8, 0xff, 0x54, 0xa1, 0x4a, 0xb0, 0x08, 0x7d, 0xfd, 0xf2, 0x5b, 0xdb, + 0x97, 0xbf, 0xab, 0x50, 0xd5, 0xa2, 0xc9, 0xd3, 0x97, 0xea, 0x89, 0x9b, 0xf1, 0xe9, 0x33, 0xc5, + 0x4a, 0xda, 0x8e, 0xbe, 0x89, 0xd1, 0xd9, 0x32, 0x64, 0x66, 0x46, 0x0c, 0x7d, 0x01, 0x9e, 0xdc, + 0x60, 0x11, 0x06, 0xba, 0xfe, 0xfb, 0xaf, 0x20, 0xe3, 0x60, 0xb2, 0xc1, 0xe2, 0xeb, 0x55, 0xa9, + 0x6a, 0xa1, 0xaf, 0x3f, 0x7c, 0x02, 0x41, 0x1b, 0xa2, 0xcd, 0x79, 0x81, 0xb5, 0xfe, 0xc0, 0x40, + 0xd0, 0x91, 0x7f, 0x00, 0xfe, 0xad, 0x4c, 0x2b, 0x43, 0xfc, 0xf0, 0xd1, 0xfe, 0xb6, 0xec, 0x64, + 0x93, 0x14, 0xc2, 0x24, 0xbf, 0x72, 0xbe, 0x64, 0xd1, 0x0f, 0xe0, 0x51, 0x88, 0x66, 0x9d, 0xe2, + 0xb5, 0x8c, 0xeb, 0xc3, 0xac, 0x5a, 0x2d, 0x8a, 0x90, 0x8d, 0xdc, 0xb1, 0x2b, 0x76, 0x62, 0xfc, + 0x1d, 0xe8, 0xcd, 0x4d, 0xd6, 0x19, 0xb9, 0xe3, 0x40, 0x58, 0xc4, 0xef, 0x83, 0x9f, 0xca, 0x39, + 0xa6, 0x56, 0x06, 0x06, 0x44, 0x7f, 0x31, 0x5a, 0x52, 0x33, 0x94, 0xce, 0x62, 0x98, 0xcf, 0x7e, + 0x17, 0x06, 0x34, 0xb0, 0xe7, 0xb7, 0x52, 0xd9, 0xe5, 0xe8, 0x13, 0xbe, 0x94, 0x8a, 0x7f, 0x06, + 0x3d, 0xdd, 0xde, 0x1d, 0x0b, 0xd2, 0x94, 0xbb, 0xa4, 0xbc, 0xb0, 0xd7, 0x5a, 0x9a, 0xbd, 0x0e, + 0xcd, 0x6d, 0x4b, 0x7e, 0xa7, 0x25, 0x5a, 0x3d, 0x9a, 0x57, 0xad, 0xa7, 0x74, 0x67, 0x65, 0x33, + 0x55, 0x73, 0x2b, 0xba, 0x80, 0x7b, 0x3b, 0x2f, 0xb6, 0x2f, 0xb1, 0xdd, 0x97, 0xb6, 0x54, 0x07, + 0x96, 0x5a, 0x12, 0x68, 0x81, 0x29, 0xc6, 0x25, 0x2e, 0x34, 0x2b, 0x03, 0xd1, 0xe2, 0xe8, 0x57, + 0xb6, 0xad, 0xab, 0xdf, 0x23, 0x09, 0xc6, 0xd9, 0x72, 0x29, 0x57, 0x0b, 0x5b, 0xba, 0x81, 0xc4, + 0xdb, 0x62, 0x6e, 0x4b, 0x3b, 0x8b, 0x39, 0x61, 0x95, 0x5b, 0x9e, 0x1d, 0x95, 0xf3, 0x11, 0x0c, + 0x97, 0x28, 0x8b, 0x4a, 0xe1, 0x12, 0x57, 0xa5, 0xa5, 0xa0, 0x1b, 0xe2, 0x0f, 0xa0, 0x5f, 0xca, + 0xeb, 0xe7, 0xb4, 0x20, 0x86, 0x8b, 0x5e, 0x29, 0xaf, 0x4f, 0xb0, 0xe6, 0xef, 0x41, 0x70, 0x95, + 0x60, 0xba, 0xd0, 0x29, 0xb3, 0xb6, 0x03, 0x1d, 0x38, 0xc1, 0x3a, 0xfa, 0x8d, 0x41, 0x6f, 0x86, + 0xea, 0x16, 0xd5, 0x6b, 0x69, 0xba, 0xeb, 0x79, 0xee, 0x7f, 0x78, 0x9e, 0x77, 0xb7, 0xe7, 0xf9, + 0x5b, 0xcf, 0xbb, 0x0f, 0xfe, 0x4c, 0xc5, 0xc7, 0x53, 0xdd, 0x91, 0x2b, 0x0c, 0xa0, 0xcd, 0x9b, + 0xc4, 0x65, 0x72, 0x8b, 0xd6, 0x08, 0x2d, 0x8a, 0x7e, 0x61, 0xd0, 0x3b, 0x95, 0x75, 0x56, 0x95, + 0x2f, 0x6d, 0xd8, 0x08, 0x86, 0x93, 0x3c, 0x4f, 0x93, 0x58, 0x96, 0x49, 0xb6, 0xb2, 0xdd, 0x76, + 0x43, 0x74, 0xe3, 0x69, 0x87, 0x3b, 0xd3, 0x77, 0x37, 0x44, 0x32, 0x3a, 0xd2, 0x56, 0x65, 0x7c, + 0xa7, 0x23, 0x23, 0xe3, 0x50, 0x3a, 0x49, 0x1f, 0x38, 0xa9, 0xca, 0xec, 0x2a, 0xcd, 0xd6, 0xfa, + 0x4b, 0x06, 0xa2, 0xc5, 0xd1, 0xdf, 0x0e, 0x78, 0x6f, 0xca, 0x82, 0xf6, 0x80, 0x25, 0x76, 0x90, + 0x2c, 0x69, 0x0d, 0xa9, 0xdf, 0x31, 0xa4, 0x10, 0xfa, 0xb5, 0x92, 0xab, 0x6b, 0x2c, 0xc2, 0x81, + 0xd6, 0x77, 0x03, 0x75, 0x46, 0x6b, 0xc4, 0x38, 0x51, 0x20, 0x1a, 0xd8, 0xee, 0x3c, 0x74, 0x76, + 0xfe, 0x13, 0x6b, 0x5a, 0x43, 0xdd, 0x51, 0xb8, 0x4b, 0xcb, 0xff, 0xe7, 0x55, 0x7f, 0x32, 0xf0, + 0x5b, 0xc1, 0x1c, 0xed, 0x0a, 0xe6, 0x68, 0x2b, 0x98, 0xe9, 0x61, 0x23, 0x98, 0xe9, 0x21, 0x61, + 0x71, 0xd6, 0x08, 0x46, 0x9c, 0xd1, 0xb0, 0x9e, 0xa8, 0xac, 0xca, 0x0f, 0x6b, 0x33, 0xd5, 0x40, + 0xb4, 0x98, 0xb6, 0xec, 0xfb, 0x1b, 0x54, 0x96, 0xea, 0x40, 0x58, 0x44, 0x3b, 0x79, 0xaa, 0xcd, + 0xc4, 0x90, 0x6b, 0x00, 0xff, 0x10, 0x7c, 0x41, 0xe4, 0x69, 0x86, 0x77, 0xe6, 0xa2, 0xc3, 0xc2, + 0x64, 0xa3, 0xc7, 0xf6, 0x1a, 0x55, 0xb9, 0xc8, 0x73, 0x54, 0x56, 0x4a, 0x06, 0xe8, 0xda, 0xd9, + 0x1a, 0x8d, 0x0b, 0xba, 0xc2, 0x80, 0xe8, 0x47, 0x08, 0x26, 0x29, 0xaa, 0x52, 0x54, 0xe9, 0xcb, + 0xde, 0xc9, 0xc1, 0xfb, 0x66, 0xf6, 0xed, 0xb3, 0x46, 0x80, 0x74, 0xde, 0xca, 0xc6, 0xfd, 0x97, + 0x6c, 0x4e, 0x64, 0x2e, 0x8f, 0xa7, 0x7a, 0x9f, 0x5c, 0x61, 0x51, 0xf4, 0x31, 0x78, 0x24, 0xcf, + 0x4e, 0x65, 0xef, 0x55, 0xd2, 0x9e, 0xf7, 0xf4, 0x5f, 0xa4, 0xc7, 0xff, 0x04, 0x00, 0x00, 0xff, + 0xff, 0x5a, 0xf0, 0x92, 0xd4, 0x34, 0x09, 0x00, 0x00, } diff --git a/bolt/internal/internal.proto b/bolt/internal/internal.proto index c2c208693d..b146cfd0a0 100644 --- a/bolt/internal/internal.proto +++ b/bolt/internal/internal.proto @@ -93,6 +93,7 @@ message Cell { repeated int64 yranges = 8; // Limits of the y-axes repeated string ylabels = 9; // Labels of the y-axes string type = 10; // Cell visualization type + map axes = 11; // Axes represent the graphical viewport for a cell's visualizations } message Query { diff --git a/bolt/internal/internal_test.go b/bolt/internal/internal_test.go index 2a17f67378..7a53243d2d 100644 --- a/bolt/internal/internal_test.go +++ b/bolt/internal/internal_test.go @@ -108,6 +108,12 @@ func TestMarshalLayout(t *testing.T) { I: "anotherid", Type: "line", Name: "cell1", + Axes: map[string]chronograf.Axis{ + "y": chronograf.Axis{ + Bounds: []string{"0", "100"}, + Label: "foo", + }, + }, Queries: []chronograf.Query{ { Range: &chronograf.Range{ @@ -133,8 +139,8 @@ func TestMarshalLayout(t *testing.T) { t.Fatal(err) } else if err := internal.UnmarshalLayout(buf, &vv); err != nil { t.Fatal(err) - } else if !reflect.DeepEqual(layout, vv) { - t.Fatalf("source protobuf copy error: got %#v, expected %#v", vv, layout) + } else if !cmp.Equal(layout, vv) { + t.Fatal("source protobuf copy error: diff:\n", cmp.Diff(layout, vv)) } } diff --git a/chronograf.go b/chronograf.go index aa9c6bc6c9..535adfe1e1 100644 --- a/chronograf.go +++ b/chronograf.go @@ -675,14 +675,15 @@ type DashboardsStore interface { // Cell is a rectangle and multiple time series queries to visualize. type Cell struct { - X int32 `json:"x"` - Y int32 `json:"y"` - W int32 `json:"w"` - H int32 `json:"h"` - I string `json:"i"` - Name string `json:"name"` - Queries []Query `json:"queries"` - Type string `json:"type"` + X int32 `json:"x"` + Y int32 `json:"y"` + W int32 `json:"w"` + H int32 `json:"h"` + I string `json:"i"` + Name string `json:"name"` + Queries []Query `json:"queries"` + Axes map[string]Axis `json:"axes"` + Type string `json:"type"` } // Layout is a collection of Cells for visualization diff --git a/mocks/layouts.go b/mocks/layouts.go new file mode 100644 index 0000000000..13ca28de84 --- /dev/null +++ b/mocks/layouts.go @@ -0,0 +1,37 @@ +package mocks + +import ( + "context" + + "github.com/influxdata/chronograf" +) + +var _ chronograf.LayoutStore = &LayoutStore{} + +type LayoutStore struct { + AddF func(ctx context.Context, layout chronograf.Layout) (chronograf.Layout, error) + AllF func(ctx context.Context) ([]chronograf.Layout, error) + DeleteF func(ctx context.Context, layout chronograf.Layout) error + GetF func(ctx context.Context, id string) (chronograf.Layout, error) + UpdateF func(ctx context.Context, layout chronograf.Layout) error +} + +func (s *LayoutStore) Add(ctx context.Context, layout chronograf.Layout) (chronograf.Layout, error) { + return s.AddF(ctx, layout) +} + +func (s *LayoutStore) All(ctx context.Context) ([]chronograf.Layout, error) { + return s.AllF(ctx) +} + +func (s *LayoutStore) Delete(ctx context.Context, layout chronograf.Layout) error { + return s.DeleteF(ctx, layout) +} + +func (s *LayoutStore) Get(ctx context.Context, id string) (chronograf.Layout, error) { + return s.GetF(ctx, id) +} + +func (s *LayoutStore) Update(ctx context.Context, layout chronograf.Layout) error { + return s.UpdateF(ctx, layout) +} diff --git a/server/layout.go b/server/layout.go index 4631a4d495..8cc53068e3 100644 --- a/server/layout.go +++ b/server/layout.go @@ -23,6 +23,23 @@ func newLayoutResponse(layout chronograf.Layout) layoutResponse { httpAPILayouts := "/chronograf/v1/layouts" href := fmt.Sprintf("%s/%s", httpAPILayouts, layout.ID) rel := "self" + + for idx, cell := range layout.Cells { + axes := []string{"x", "y", "y2"} + + if cell.Axes == nil { + layout.Cells[idx].Axes = make(map[string]chronograf.Axis, len(axes)) + } + + for _, axis := range axes { + if _, found := cell.Axes[axis]; !found { + layout.Cells[idx].Axes[axis] = chronograf.Axis{ + Bounds: []string{}, + } + } + } + } + return layoutResponse{ Layout: layout, Link: link{ diff --git a/server/layout_test.go b/server/layout_test.go index 605f44c46f..16380da308 100644 --- a/server/layout_test.go +++ b/server/layout_test.go @@ -1,79 +1,183 @@ package server_test -/* -func TestNewLayout(t *testing.T) { - t.Parallel() - var tests = []struct { - Desc string - AddError error - ExistingLayouts map[string]chronograf.Layout - NewLayout *models.Layout - ExpectedID int - ExpectedHref string - ExpectedStatus int +import ( + "context" + "encoding/json" + "net/http/httptest" + "net/url" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/influxdata/chronograf" + "github.com/influxdata/chronograf/mocks" + "github.com/influxdata/chronograf/server" +) + +func Test_Layouts(t *testing.T) { + layoutTests := []struct { + name string + expected chronograf.Layout + allLayouts []chronograf.Layout + focusedApp string // should filter all layouts to this app only + shouldErr bool }{ { - Desc: "Test that an error in datastore returns 500 status", - AddError: errors.New("error"), - NewLayout: &models.Layout{ - Measurement: new(string), - App: new(string), - Cells: []*models.Cell{ - &models.Cell{ - X: new(int32), - Y: new(int32), - W: new(int32), - H: new(int32), - }, - }, - }, - ExpectedStatus: http.StatusInternalServerError, + "empty layout", + chronograf.Layout{}, + []chronograf.Layout{}, + "", + false, }, { - Desc: "Test that creating a layout returns 201 status", - ExistingLayouts: map[string]chronograf.Layout{}, - NewLayout: &models.Layout{ - Measurement: new(string), - App: new(string), - Cells: []*models.Cell{ - &models.Cell{ - X: new(int32), - Y: new(int32), - W: new(int32), - H: new(int32), + "several layouts", + chronograf.Layout{ + ID: "d20a21c8-69f1-4780-90fe-e69f5e4d138c", + Application: "influxdb", + Measurement: "influxdb", + }, + []chronograf.Layout{ + chronograf.Layout{ + ID: "d20a21c8-69f1-4780-90fe-e69f5e4d138c", + Application: "influxdb", + Measurement: "influxdb", + }, + }, + "", + false, + }, + { + "filtered app", + chronograf.Layout{ + ID: "d20a21c8-69f1-4780-90fe-e69f5e4d138c", + Application: "influxdb", + Measurement: "influxdb", + }, + []chronograf.Layout{ + chronograf.Layout{ + ID: "d20a21c8-69f1-4780-90fe-e69f5e4d138c", + Application: "influxdb", + Measurement: "influxdb", + }, + chronograf.Layout{ + ID: "b020101b-ea6b-4c8c-9f0e-db0ba501f4ef", + Application: "chronograf", + Measurement: "chronograf", + }, + }, + "influxdb", + false, + }, + { + "axis zero values", + chronograf.Layout{ + ID: "d20a21c8-69f1-4780-90fe-e69f5e4d138c", + Application: "influxdb", + Measurement: "influxdb", + Cells: []chronograf.Cell{ + { + X: 0, + Y: 0, + W: 4, + H: 4, + I: "3b0e646b-2ca3-4df2-95a5-fd80915459dd", + Name: "A Graph", + Axes: map[string]chronograf.Axis{ + "x": chronograf.Axis{ + Bounds: []string{}, + }, + "y": chronograf.Axis{ + Bounds: []string{}, + }, + "y2": chronograf.Axis{ + Bounds: []string{}, + }, + }, }, }, }, - ExpectedID: 0, - ExpectedHref: "/chronograf/v1/layouts/0", - ExpectedStatus: http.StatusCreated, + []chronograf.Layout{ + chronograf.Layout{ + ID: "d20a21c8-69f1-4780-90fe-e69f5e4d138c", + Application: "influxdb", + Measurement: "influxdb", + Cells: []chronograf.Cell{ + { + X: 0, + Y: 0, + W: 4, + H: 4, + I: "3b0e646b-2ca3-4df2-95a5-fd80915459dd", + Name: "A Graph", + }, + }, + }, + }, + "", + false, }, } - for _, test := range tests { - // The mocked backing store will be used to - // check stored values. - store := server.Store{ - LayoutStore: &mock.LayoutStore{ - AddError: test.AddError, - Layouts: test.ExistingLayouts, - }, - } + for _, test := range layoutTests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() - // Send the test layout to the mocked store. - params := op.PostLayoutsParams{ - Layout: test.NewLayout, - } - resp := store.NewLayout(context.Background(), params) - w := httptest.NewRecorder() - resp.WriteResponse(w, runtime.JSONProducer()) - if w.Code != test.ExpectedStatus { - t.Fatalf("Expected status %d; actual %d", test.ExpectedStatus, w.Code) - } - loc := w.Header().Get("Location") - if loc != test.ExpectedHref { - t.Fatalf("Expected status %s; actual %s", test.ExpectedHref, loc) - } + // setup mock chronograf.Service and mock logger + lg := &mocks.TestLogger{} + svc := server.Service{ + LayoutStore: &mocks.LayoutStore{ + AllF: func(ctx context.Context) ([]chronograf.Layout, error) { + if len(test.allLayouts) == 0 { + return []chronograf.Layout{ + test.expected, + }, nil + } else { + return test.allLayouts, nil + } + }, + }, + Logger: lg, + } + + // setup mock request and response + rr := httptest.NewRecorder() + reqURL := url.URL{ + Path: "/chronograf/v1/layouts", + } + params := reqURL.Query() + + // add query params required by test + if test.focusedApp != "" { + params.Add("app", test.focusedApp) + } + + // re-inject query params + reqURL.RawQuery = params.Encode() + + req := httptest.NewRequest("GET", reqURL.RequestURI(), strings.NewReader("")) + + // invoke handler for layouts endpoint + svc.Layouts(rr, req) + + // create a throwaway frame to unwrap Layouts + respFrame := struct { + Layouts []struct { + chronograf.Layout + Link interface{} `json:"-"` + } `json:"layouts"` + }{} + + // decode resp into respFrame + resp := rr.Result() + if err := json.NewDecoder(resp.Body).Decode(&respFrame); err != nil { + t.Fatalf("%q - Error unmarshaling JSON: err: %s", test.name, err.Error()) + } + + // compare actual and expected + if !cmp.Equal(test.expected, respFrame.Layouts[0].Layout) { + t.Fatalf("%q - Expected layouts to be equal: diff:\n\t%s", test.name, cmp.Diff(test.expected, respFrame.Layouts[0].Layout)) + } + }) } } -*/