mirror of
https://github.com/mum4k/termdash.git
synced 2025-05-01 22:17:51 +08:00
Merge pull request #267 from fgksgf/api
Design APIs of the HeatMap widget
This commit is contained in:
commit
289e1dd004
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,5 @@
|
|||||||
# Exclude MacOS attribute files.
|
# Exclude MacOS attribute files.
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
# Exclude IDE files.
|
||||||
|
.idea/
|
153
widgets/heatmap/heatmap.go
Normal file
153
widgets/heatmap/heatmap.go
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
// Copyright 2020 Google Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// Package heatmap contains a widget that displays heat maps.
|
||||||
|
package heatmap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"image"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/mum4k/termdash/cell"
|
||||||
|
"github.com/mum4k/termdash/private/canvas"
|
||||||
|
"github.com/mum4k/termdash/terminal/terminalapi"
|
||||||
|
"github.com/mum4k/termdash/widgetapi"
|
||||||
|
"github.com/mum4k/termdash/widgets/heatmap/internal/axes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HeatMap draws heat map charts.
|
||||||
|
//
|
||||||
|
// Heatmap consists of several cells. Each cell represents a value.
|
||||||
|
// The larger the value, the darker the color of the cell (from white to black).
|
||||||
|
//
|
||||||
|
// The two dimensions of the values (cells) array are determined by the length of
|
||||||
|
// the xLabels and yLabels arrays respectively.
|
||||||
|
//
|
||||||
|
// HeatMap does not support mouse based zoom.
|
||||||
|
//
|
||||||
|
// Implements widgetapi.Widget. This object is thread-safe.
|
||||||
|
type HeatMap struct {
|
||||||
|
// values are the values in the heat map.
|
||||||
|
values [][]float64
|
||||||
|
|
||||||
|
// xLabels are the labels on the X axis in an increasing order.
|
||||||
|
xLabels []string
|
||||||
|
// yLabels are the labels on the Y axis in an increasing order.
|
||||||
|
yLabels []string
|
||||||
|
|
||||||
|
// minValue and maxValue are the Min and Max values in the values,
|
||||||
|
// which will be used to calculate the color of each cell.
|
||||||
|
minValue, maxValue float64
|
||||||
|
|
||||||
|
// lastWidth is the width of the canvas as of the last time when Draw was called.
|
||||||
|
lastWidth int
|
||||||
|
|
||||||
|
// opts are the provided options.
|
||||||
|
opts *options
|
||||||
|
|
||||||
|
// mu protects the HeatMap widget.
|
||||||
|
mu sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a new HeatMap widget.
|
||||||
|
func New(opts ...Option) (*HeatMap, error) {
|
||||||
|
return nil, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values sets the values to be displayed by the HeatMap.
|
||||||
|
//
|
||||||
|
// Each value in values has a xLabel and a yLabel, which means
|
||||||
|
// len(yLabels) == len(values) and len(xLabels) == len(values[i]).
|
||||||
|
// But labels could be empty strings.
|
||||||
|
// When no labels are provided, labels will be "0", "1", "2"...
|
||||||
|
//
|
||||||
|
// Each call to Values overwrites any previously provided values.
|
||||||
|
// Provided options override values set when New() was called.
|
||||||
|
func (hp *HeatMap) Values(xLabels []string, yLabels []string, values [][]float64, opts ...Option) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearXLabels clear the X labels.
|
||||||
|
func (hp *HeatMap) ClearXLabels() {
|
||||||
|
hp.xLabels = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearYLabels clear the Y labels.
|
||||||
|
func (hp *HeatMap) ClearYLabels() {
|
||||||
|
hp.yLabels = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValueCapacity returns the number of values that can fit into the canvas.
|
||||||
|
// This is essentially the number of available cells on the canvas as observed
|
||||||
|
// on the last call to draw. Returns zero if draw wasn't called.
|
||||||
|
//
|
||||||
|
// Note that this capacity changes each time the terminal resizes, so there is
|
||||||
|
// no guarantee this remains the same next time Draw is called.
|
||||||
|
// Should be used as a hint only.
|
||||||
|
func (hp *HeatMap) ValueCapacity() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// axesDetails determines the details about the X and Y axes.
|
||||||
|
func (hp *HeatMap) axesDetails(cvs *canvas.Canvas) (*axes.XDetails, *axes.YDetails, error) {
|
||||||
|
return nil, nil, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw draws cells, X labels and Y labels as HeatMap.
|
||||||
|
// Implements widgetapi.Widget.Draw.
|
||||||
|
func (hp *HeatMap) Draw(cvs *canvas.Canvas, meta *widgetapi.Meta) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// drawCells draws m*n cells (rectangles) representing the stored values.
|
||||||
|
// The height of each cell is 1 and the default width is 3.
|
||||||
|
func (hp *HeatMap) drawCells(cvs *canvas.Canvas, xd *axes.XDetails, yd *axes.YDetails) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// drawAxes draws X labels (under the cells) and Y Labels (on the left side of the cell).
|
||||||
|
func (hp *HeatMap) drawLabels(cvs *canvas.Canvas, xd *axes.XDetails, yd *axes.YDetails) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// minSize determines the minimum required size to draw HeatMap.
|
||||||
|
func (hp *HeatMap) minSize() image.Point {
|
||||||
|
return image.Point{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard input isn't supported on the HeatMap widget.
|
||||||
|
func (*HeatMap) Keyboard(k *terminalapi.Keyboard) error {
|
||||||
|
return errors.New("the HeatMap widget doesn't support keyboard events")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mouse input isn't supported on the HeatMap widget.
|
||||||
|
func (*HeatMap) Mouse(m *terminalapi.Mouse) error {
|
||||||
|
return errors.New("the HeatMap widget doesn't support mouse events")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options implements widgetapi.Widget.Options.
|
||||||
|
func (hp *HeatMap) Options() widgetapi.Options {
|
||||||
|
hp.mu.Lock()
|
||||||
|
defer hp.mu.Unlock()
|
||||||
|
return widgetapi.Options{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getCellColor returns the color of the cell according to its value.
|
||||||
|
// The larger the value, the darker the color.
|
||||||
|
// The color range is in Xterm color, from 232 to 255.
|
||||||
|
// Refer to https://jonasjacek.github.io/colors/.
|
||||||
|
func (hp *HeatMap) getCellColor(value float64) cell.Color {
|
||||||
|
return cell.ColorDefault
|
||||||
|
}
|
15
widgets/heatmap/heatmap_test.go
Normal file
15
widgets/heatmap/heatmap_test.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright 2020 Google Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package heatmap
|
64
widgets/heatmap/heatmapdemo/heatmapdemo.go
Normal file
64
widgets/heatmap/heatmapdemo/heatmapdemo.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright 2020 Google Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// Binary heatmapdemo displays a heatmap widget.
|
||||||
|
// Exist when 'q' is pressed.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/mum4k/termdash"
|
||||||
|
"github.com/mum4k/termdash/container"
|
||||||
|
"github.com/mum4k/termdash/linestyle"
|
||||||
|
"github.com/mum4k/termdash/terminal/tcell"
|
||||||
|
"github.com/mum4k/termdash/terminal/terminalapi"
|
||||||
|
"github.com/mum4k/termdash/widgets/heatmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
t, err := tcell.New()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer t.Close()
|
||||||
|
|
||||||
|
hp, err := heatmap.New()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: set heatmap's data
|
||||||
|
|
||||||
|
c, err := container.New(
|
||||||
|
t,
|
||||||
|
container.Border(linestyle.Light),
|
||||||
|
container.BorderTitle("PRESS Q TO QUIT"),
|
||||||
|
container.PlaceWidget(hp),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
|
quitter := func(k *terminalapi.Keyboard) {
|
||||||
|
if k.Key == 'q' || k.Key == 'Q' {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := termdash.Run(ctx, t, c, termdash.KeyboardSubscriber(quitter)); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
4
widgets/heatmap/internal/README.md
Normal file
4
widgets/heatmap/internal/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Internal termdash libraries
|
||||||
|
|
||||||
|
The packages under this directory are private to termdash. Stability of the
|
||||||
|
private packages isn't guaranteed and changes won't be backward compatible.
|
87
widgets/heatmap/internal/axes/axes.go
Normal file
87
widgets/heatmap/internal/axes/axes.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// Copyright 2020 Google Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// Package axes calculates the required layout and draws the X and Y axes of a heat map.
|
||||||
|
package axes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"image"
|
||||||
|
|
||||||
|
"github.com/mum4k/termdash/private/runewidth"
|
||||||
|
)
|
||||||
|
|
||||||
|
// axisWidth is width of an axis.
|
||||||
|
const axisWidth = 1
|
||||||
|
|
||||||
|
// YDetails contain information about the Y axis
|
||||||
|
// that will NOT be drawn onto the canvas, but will take up space.
|
||||||
|
type YDetails struct {
|
||||||
|
// Width in character cells of the Y axis and its character labels.
|
||||||
|
Width int
|
||||||
|
|
||||||
|
// Start is the point where the Y axis starts.
|
||||||
|
// The Y coordinate of Start is less than the Y coordinate of End.
|
||||||
|
Start image.Point
|
||||||
|
|
||||||
|
// End is the point where the Y axis ends.
|
||||||
|
End image.Point
|
||||||
|
|
||||||
|
// Labels are the labels for values on the Y axis in an increasing order.
|
||||||
|
Labels []*Label
|
||||||
|
}
|
||||||
|
|
||||||
|
// RequiredWidth calculates the minimum width required
|
||||||
|
// in order to draw the Y axis and its labels.
|
||||||
|
// The parameter ls is the longest string in yLabels.
|
||||||
|
func RequiredWidth(ls string) int {
|
||||||
|
return runewidth.StringWidth(ls) + axisWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewYDetails retrieves details about the Y axis required
|
||||||
|
// to draw it on a canvas of the provided area.
|
||||||
|
func NewYDetails(labels []string) (*YDetails, error) {
|
||||||
|
return nil, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LongestString returns the length of the longest string in the string array.
|
||||||
|
func LongestString(strings []string) int {
|
||||||
|
var widest int
|
||||||
|
for _, s := range strings {
|
||||||
|
if l := runewidth.StringWidth(s); l > widest {
|
||||||
|
widest = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return widest
|
||||||
|
}
|
||||||
|
|
||||||
|
// XDetails contain information about the X axis
|
||||||
|
// that will NOT be drawn onto the canvas.
|
||||||
|
type XDetails struct {
|
||||||
|
// Start is the point where the X axis starts.
|
||||||
|
// Both coordinates of Start are less than End.
|
||||||
|
Start image.Point
|
||||||
|
// End is the point where the X axis ends.
|
||||||
|
End image.Point
|
||||||
|
|
||||||
|
// Labels are the labels for values on the X axis in an increasing order.
|
||||||
|
Labels []*Label
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewXDetails retrieves details about the X axis required to draw it on a canvas
|
||||||
|
// of the provided area.
|
||||||
|
// The yEnd is the point where the Y axis ends.
|
||||||
|
func NewXDetails(cvsAr image.Rectangle, yEnd image.Point, labels []string, cellWidth int) (*XDetails, error) {
|
||||||
|
return nil, errors.New("not implemented")
|
||||||
|
}
|
15
widgets/heatmap/internal/axes/axes_test.go
Normal file
15
widgets/heatmap/internal/axes/axes_test.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright 2020 Google Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package axes
|
64
widgets/heatmap/internal/axes/label.go
Normal file
64
widgets/heatmap/internal/axes/label.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright 2020 Google Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package axes
|
||||||
|
|
||||||
|
// label.go contains code that calculates the positions of labels on the axes.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"image"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Label is one text label on an axis.
|
||||||
|
type Label struct {
|
||||||
|
// Label content.
|
||||||
|
Text string
|
||||||
|
|
||||||
|
// Position of the label within the canvas.
|
||||||
|
Pos image.Point
|
||||||
|
}
|
||||||
|
|
||||||
|
// yLabels returns labels that should be placed next to the cells.
|
||||||
|
// The labelWidth is the width of the area from the left-most side of the
|
||||||
|
// canvas until the Y axis (not including the Y axis). This is the area where
|
||||||
|
// the labels will be placed and aligned.
|
||||||
|
// Labels are returned with Y coordinates in ascending order.
|
||||||
|
// Y coordinates grow down.
|
||||||
|
func yLabels(graphHeight, labelWidth int, labels []string) ([]*Label, error) {
|
||||||
|
return nil, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// rowLabel returns one label for the specified row.
|
||||||
|
// The row is the Y coordinate of the row, Y coordinates grow down.
|
||||||
|
func rowLabel(row int, label string, labelWidth int) (*Label, error) {
|
||||||
|
return nil, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// xLabels returns labels that should be placed under the cells.
|
||||||
|
// Labels are returned with X coordinates in ascending order.
|
||||||
|
// X coordinates grow right.
|
||||||
|
func xLabels(yEnd image.Point, graphWidth int, labels []string, cellWidth int) ([]*Label, error) {
|
||||||
|
return nil, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// paddedLabelLength calculates the length of the padded X label and
|
||||||
|
// the column index corresponding to the label.
|
||||||
|
// For example, the longest X label's length is 5, like '12:34', and the cell's width is 3.
|
||||||
|
// So in order to better display, every three columns of cells will display a X label,
|
||||||
|
// the X label belongs to the middle column of the three columns,
|
||||||
|
// and the padded length is 3*3 (cellWidth multiplies the number of columns), which is 9.
|
||||||
|
func paddedLabelLength(graphWidth, longest, cellWidth int) (l, index int) {
|
||||||
|
return
|
||||||
|
}
|
15
widgets/heatmap/internal/axes/label_test.go
Normal file
15
widgets/heatmap/internal/axes/label_test.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright 2020 Google Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package axes
|
82
widgets/heatmap/options.go
Normal file
82
widgets/heatmap/options.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// Copyright 2020 Google Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package heatmap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/mum4k/termdash/cell"
|
||||||
|
)
|
||||||
|
|
||||||
|
// options.go contains configurable options for HeatMap.
|
||||||
|
|
||||||
|
// Option is used to provide options.
|
||||||
|
type Option interface {
|
||||||
|
// set sets the provided option.
|
||||||
|
set(*options)
|
||||||
|
}
|
||||||
|
|
||||||
|
// options stores the provided options.
|
||||||
|
type options struct {
|
||||||
|
// The default value is 3
|
||||||
|
cellWidth int
|
||||||
|
xLabelCellOpts []cell.Option
|
||||||
|
yLabelCellOpts []cell.Option
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate validates the provided options.
|
||||||
|
func (o *options) validate() error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// newOptions returns a new options instance.
|
||||||
|
func newOptions(opts ...Option) *options {
|
||||||
|
opt := &options{
|
||||||
|
cellWidth: 3,
|
||||||
|
}
|
||||||
|
for _, o := range opts {
|
||||||
|
o.set(opt)
|
||||||
|
}
|
||||||
|
return opt
|
||||||
|
}
|
||||||
|
|
||||||
|
// option implements Option.
|
||||||
|
type option func(*options)
|
||||||
|
|
||||||
|
// set implements Option.set.
|
||||||
|
func (o option) set(opts *options) {
|
||||||
|
o(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CellWidth set the width of cells (or grids) in the heat map, not the terminal cell.
|
||||||
|
// The default height of each cell (grid) is 1 and the width is 3.
|
||||||
|
func CellWidth(w int) Option {
|
||||||
|
return option(func(opts *options) {
|
||||||
|
opts.cellWidth = w
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// XLabelCellOpts set the cell options for the labels on the X axis.
|
||||||
|
func XLabelCellOpts(co ...cell.Option) Option {
|
||||||
|
return option(func(opts *options) {
|
||||||
|
opts.xLabelCellOpts = co
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// YLabelCellOpts set the cell options for the labels on the Y axis.
|
||||||
|
func YLabelCellOpts(co ...cell.Option) Option {
|
||||||
|
return option(func(opts *options) {
|
||||||
|
opts.yLabelCellOpts = co
|
||||||
|
})
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user