~sircmpwn/chartsrv

99197599e7734a93875f5195d1af1286764df361 — Drew DeVault 4 years ago e0436f2
Add until option
4 files changed, 37 insertions(+), 3 deletions(-)

M README.md
M go.mod
M go.sum
M main.go
M README.md => README.md +2 -2
@@ 30,8 30,8 @@ set the query parameters as appropriate:
- **query**: required. Prometheus query to execute.
- **title**: chart title
- **stacked**: set to create an area chart instead of a line chart
- **since**: [time.ParseDuration][1] to set distance in the past to start
  charting from
- **since**, **until**: [time.ParseDuration][1] to set distance in the past to
  start charting from or until
- **width**, **height**: adjust chart dimensions in inches
- **step**: number of seconds between data points
- **min**, **max**: Y axis limits

M go.mod => go.mod +1 -0
@@ 3,6 3,7 @@ module git.sr.ht/~sircmpwn/chartsrv
go 1.15

require (
	github.com/dustin/go-humanize v1.0.0 // indirect
	github.com/go-chi/chi v4.1.2+incompatible
	gonum.org/v1/plot v0.8.0
)

M go.sum => go.sum +2 -0
@@ 5,6 5,8 @@ github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af h1:wVe6/Ea46ZMeNkQjj
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=

M main.go => main.go +32 -1
@@ 13,6 13,7 @@ import (
	"strings"
	"time"

	"github.com/dustin/go-humanize"
	"github.com/go-chi/chi"
	"github.com/go-chi/chi/middleware"
	"gonum.org/v1/plot"


@@ 154,6 155,10 @@ func main() {
			d, _ := time.ParseDuration(s[0])
			start = time.Now().Add(-d)
		}
		if u, ok := args["until"]; ok {
			d, _ := time.ParseDuration(u[0])
			end = time.Now().Add(-d)
		}

		width := 12*vg.Inch
		height := 6*vg.Inch


@@ 166,6 171,12 @@ func main() {
			height = vg.Length(h)*vg.Inch
		}

		// Undocumented option
		var legend string
		if l, ok := args["legend"]; ok {
			legend = l[0]
		}

		// Set step so that there's approximately 25 data points per inch
		step := int(end.Sub(start).Seconds() / (25 * float64(width / vg.Inch)))
		if s, ok := args["step"]; ok {


@@ 194,6 205,8 @@ func main() {
			m, _ := strconv.ParseFloat(ms[0], 64)
			p.Y.Max = m
		}

		p.Y.Tick.Marker = humanTicks{}
		if ms, ok := args["min"]; ok {
			m, _ := strconv.ParseFloat(ms[0], 64)
			p.Y.Min = m


@@ 238,7 251,11 @@ func main() {
				nextColor = 0
			}
			plotters[i] = l
			p.Legend.Add(res.Metric, l)
			if legend != "" {
				p.Legend.Add(legend, l)
			} else {
				p.Legend.Add(res.Metric, l)
			}
		}
		for i := len(plotters) - 1; i >= 0; i-- {
			p.Add(plotters[i])


@@ 287,3 304,17 @@ func (dt dateTicks) Ticks(min, max float64) []plot.Tick {
	}
	return tks
}

type humanTicks struct{}

func (ht humanTicks) Ticks(min, max float64) []plot.Tick {
	tks := plot.DefaultTicks{}.Ticks(min, max)
	for i, t := range tks {
		if t.Label == "" { // Skip minor ticks, they are fine.
			continue
		}
		d, _ := strconv.ParseFloat(t.Label, 64)
		tks[i].Label = humanize.SI(d, "")
	}
	return tks
}