func (g *graph) syncGraph(series render.Series, color cell.Color) error {
	values := make([]float64, len(series.Values))
	for i, value := range series.Values {
		v := math.NaN()
		if value != nil {
			v = float64(*value)
		}
		values[i] = v
	}
	err := g.widgetGraph.Series(series.Label, values,
		linechart.SeriesCellOpts(cell.FgColor(color)),
		linechart.SeriesXLabels(xLabelsSliceToMap(series.XLabels)))
	if err != nil {
		return err
	}
	return nil
}
syncGraph will set one series of metrics on the graph.
package termdash
import (
	"fmt"
	"math"
	"github.com/mum4k/termdash/cell"
	"github.com/mum4k/termdash/container"
	"github.com/mum4k/termdash/container/grid"
	"github.com/mum4k/termdash/linestyle"
	"github.com/mum4k/termdash/widgets/linechart"
	"github.com/mum4k/termdash/widgets/text"
	"github.com/slok/grafterm/internal/model"
	"github.com/slok/grafterm/internal/service/unit"
	"github.com/slok/grafterm/internal/view/render"
)
const (
	fullPerc              = 99
	graphHorizontalPerc   = 80
	legendHorizontalPerc  = 19
	paddingHorizontalPerc = 10
	graphVerticalPerc     = 90
	legendVerticalPerc    = 4
	paddingVerticalPerc   = 50
	legendCharacter       = `⠤⠤`
	axesColor             = 8
	yAxisLabelsColor      = 15
	xAxisLabelsColor      = 248
)
type graph struct {
	cfg model.Widget
	widgetGraph  *linechart.LineChart
	widgetLegend *text.Text
	element      grid.Element
}
func newGraph(cfg model.Widget) (*graph, error) {
	vf, err := termdashValueFormatter(cfg)
	if err != nil {
		return nil, err
	}
	lc, err := linechart.New(
		linechart.AxesCellOpts(cell.FgColor(cell.ColorNumber(axesColor))),
		linechart.YLabelCellOpts(cell.FgColor(cell.ColorNumber(yAxisLabelsColor))),
		linechart.XLabelCellOpts(cell.FgColor(cell.ColorNumber(xAxisLabelsColor))),
		linechart.YAxisAdaptive(),
		linechart.YAxisFormattedValues(vf),
	)
	if err != nil {
		return nil, err
	}
	var element grid.Element
	var txt *text.Text
	if !cfg.Graph.Visualization.Legend.Disable {
		txt, err = text.New(text.WrapAtRunes())
		if err != nil {
			return nil, err
		}
	}
	element = elementFromGraphAndLegend(cfg, lc, txt)
	return &graph{
		widgetGraph:  lc,
		widgetLegend: txt,
		cfg:          cfg,
		element:      element,
	}, nil
}
func termdashValueFormatter(cfg model.Widget) (linechart.ValueFormatter, error) {
	axisUnit := cfg.Graph.Visualization.YAxis.Unit
	axisDecimals := cfg.Graph.Visualization.YAxis.Decimals
	f, err := unit.NewUnitFormatter(axisUnit)
	if err != nil {
		return nil, err
	}
	if axisUnit == "" && axisDecimals == 0 {
		axisDecimals = 2
	}
	return func(value float64) string {
		return f(value, axisDecimals)
	}, nil
}
func elementFromGraphAndLegend(cfg model.Widget, graph *linechart.LineChart, legend *text.Text) grid.Element {
	graphElement := grid.Widget(graph)
	elements := []grid.Element{}
	switch {
	case cfg.Graph.Visualization.Legend.Disable:
		elements = []grid.Element{
			grid.ColWidthPerc(fullPerc, graphElement),
		}
	case cfg.Graph.Visualization.Legend.RightSide:
		legendElement := grid.ColWidthPercWithOpts(
			fullPerc,
			[]container.Option{container.PaddingLeftPercent(paddingHorizontalPerc)},
			grid.Widget(legend))
		elements = []grid.Element{
			grid.ColWidthPerc(graphHorizontalPerc, graphElement),
			grid.ColWidthPerc(legendHorizontalPerc, legendElement),
		}
	default:
		legendElement := grid.RowHeightPercWithOpts(
			fullPerc,
			[]container.Option{container.PaddingTopPercent(paddingVerticalPerc)},
			grid.Widget(legend))
		elements = []grid.Element{
			grid.RowHeightPerc(graphVerticalPerc, graphElement),
			grid.RowHeightPerc(legendVerticalPerc, legendElement),
		}
	}
	opts := []container.Option{
		container.Border(linestyle.Light),
		container.BorderTitle(cfg.Title),
	}
	element := grid.RowHeightPercWithOpts(fullPerc, opts, elements...)
	return element
}
func (g *graph) getElement() grid.Element {
	return g.element
}
func (g *graph) GetWidgetCfg() model.Widget {
	return g.cfg
}
func (g *graph) Sync(series []render.Series) error {
	if !g.cfg.Graph.Visualization.Legend.Disable {
		g.widgetLegend.Reset()
	}
	for _, s := range series {
		err := g.syncSeries(s)
		if err != nil {
			return err
		}
	}
	return nil
}
func (g *graph) syncSeries(series render.Series) error {
	color, err := colorHexToTermdash(series.Color)
	if err != nil {
		return err
	}
	err = g.syncGraph(series, color)
	if err != nil {
		return err
	}
	err = g.syncLegend(series, color)
	if err != nil {
		return err
	}
	return nil
}