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)
}
TickmarksContainX sets the tickmarks to be shown by Grid() in the horizontal
dimension. The argument min and max specify the minimum and maximum values
to be contained within the grid. The tickmark values that are generated are
suitable for general purpose graphs.

See TickmarkExtentX() for an alternative to this method to be used when the
exact values of the tickmarks are to be set by the application.
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
}