func (g *GridType) TickmarksExtentY(min, div float64, count int) {
	g.yTicks, g.yPrecision = extent(min, div, count)
	g.ym, g.yb = linearTickmark(g.yTicks, g.y+g.h, g.y)
}
TickmarksExtentY sets the tickmarks to be shown by Grid() in the vertical
dimension. count specifies number of major tickmark subdivisions to be
graphed. min specifies the bottommost data value. div specifies, in data
units, the extent of each major tickmark subdivision.

See TickmarkContainY() for an alternative to this method to be used when
viewer-friendly tickmarks are to be determined automatically.
package gofpdf
import (
	"math"
	"strconv"
)
func unused(args ...interface{}) {
}
type RGBType struct {
	R, G, B int
}
type RGBAType struct {
	R, G, B int
	Alpha   float64
}
type StateType struct {
	clrDraw, clrText, clrFill RGBType
	lineWd                    float64
	fontSize                  float64
	alpha                     float64
	blendStr                  string
	cellMargin                float64
}
func StateGet(pdf *Fpdf) (st StateType) {
	st.clrDraw.R, st.clrDraw.G, st.clrDraw.B = pdf.GetDrawColor()
	st.clrFill.R, st.clrFill.G, st.clrFill.B = pdf.GetFillColor()
	st.clrText.R, st.clrText.G, st.clrText.B = pdf.GetTextColor()
	st.lineWd = pdf.GetLineWidth()
	_, st.fontSize = pdf.GetFontSize()
	st.alpha, st.blendStr = pdf.GetAlpha()
	st.cellMargin = pdf.GetCellMargin()
	return
}
func (st StateType) Put(pdf *Fpdf) {
	pdf.SetDrawColor(st.clrDraw.R, st.clrDraw.G, st.clrDraw.B)
	pdf.SetFillColor(st.clrFill.R, st.clrFill.G, st.clrFill.B)
	pdf.SetTextColor(st.clrText.R, st.clrText.G, st.clrText.B)
	pdf.SetLineWidth(st.lineWd)
	pdf.SetFontUnitSize(st.fontSize)
	pdf.SetAlpha(st.alpha, st.blendStr)
	pdf.SetCellMargin(st.cellMargin)
}
type TickFormatFncType func(val float64, precision int) string
func defaultFormatter(val float64, precision int) string {
	return strconv.FormatFloat(val, 'f', precision, 64)
}
type GridType struct {
	x, y, w, h float64
	xm, xb, ym, yb float64
	xTicks, yTicks []float64
	XLabelIn, YLabelIn bool
	XLabelRotate bool
	XTickStr, YTickStr TickFormatFncType
	XDiv, YDiv int
	xPrecision, yPrecision int
	ClrText, ClrMain, ClrSub RGBAType
	WdMain, WdSub float64
	TextSize float64
}
func linear(x1, y1, x2, y2 float64) (slope, intercept float64) {
	if x2 != x1 {
		slope = (y2 - y1) / (x2 - x1)
		intercept = y2 - x2*slope
	}
	return
}
func linearTickmark(tm []float64, lo, hi float64) (slope, intercept float64) {
	ln := len(tm)
	if ln > 0 {
		slope, intercept = linear(tm[0], lo, tm[ln-1], hi)
	}
	return
}
func NewGrid(x, y, w, h float64) (grid GridType) {
	grid.x = x
	grid.y = y
	grid.w = w
	grid.h = h
	grid.TextSize = 7  
	grid.TickmarksExtentX(0, 1, 1)
	grid.TickmarksExtentY(0, 1, 1)
	grid.XLabelIn = false
	grid.YLabelIn = false
	grid.XLabelRotate = false
	grid.XDiv = 10
	grid.YDiv = 10
	grid.ClrText = RGBAType{R: 0, G: 0, B: 0, Alpha: 1}
	grid.ClrMain = RGBAType{R: 128, G: 160, B: 128, Alpha: 1}
	grid.ClrSub = RGBAType{R: 192, G: 224, B: 192, Alpha: 1}
	grid.WdMain = 0.1
	grid.WdSub = 0.1
	grid.YTickStr = defaultFormatter
	grid.XTickStr = defaultFormatter
	return
}
func (g GridType) WdAbs(dataWd float64) float64 {
	return math.Abs(g.xm * dataWd)
}
func (g GridType) Wd(dataWd float64) float64 {
	return g.xm * dataWd
}
func (g GridType) XY(dataX, dataY float64) (x, y float64) {
	return g.xm*dataX + g.xb, g.ym*dataY + g.yb
}
func (g GridType) Pos(xRel, yRel float64) (x, y float64) {
	x = g.w*xRel + g.x
	y = g.h*(1-yRel) + g.y
	return
}
func (g GridType) X(dataX float64) float64 {
	return g.xm*dataX + g.xb
}
func (g GridType) HtAbs(dataHt float64) float64 {
	return math.Abs(g.ym * dataHt)
}
func (g GridType) Ht(dataHt float64) float64 {
	return g.ym * dataHt
}
func (g GridType) Y(dataY float64) float64 {
	return g.ym*dataY + g.yb
}
func (g GridType) XRange() (min, max float64) {
	min = g.xTicks[0]
	max = g.xTicks[len(g.xTicks)-1]
	return
}
func (g GridType) YRange() (min, max float64) {
	min = g.yTicks[0]
	max = g.yTicks[len(g.yTicks)-1]
	return
}
func (g *GridType) TickmarksContainX(min, max float64) {
	g.xTicks, g.xPrecision = Tickmarks(min, max)
	g.xm, g.xb = linearTickmark(g.xTicks, g.x, g.x+g.w)
}
func (g *GridType) TickmarksContainY(min, max float64) {
	g.yTicks, g.yPrecision = Tickmarks(min, max)
	g.ym, g.yb = linearTickmark(g.yTicks, g.y+g.h, g.y)
}
func extent(min, div float64, count int) (tm []float64, precision int) {
	tm = make([]float64, count+1)
	for j := 0; j <= count; j++ {
		tm[j] = min
		min += div
	}
	precision = TickmarkPrecision(div)
	return
}
func (g *GridType) TickmarksExtentX(min, div float64, count int) {
	g.xTicks, g.xPrecision = extent(min, div, count)
	g.xm, g.xb = linearTickmark(g.xTicks, g.x, g.x+g.w)
}