go-hep.org/x/hep@v0.38.1/hplot/band.go (about)

     1  // Copyright ©2019 The go-hep Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package hplot
     6  
     7  import (
     8  	"image/color"
     9  	"math"
    10  
    11  	"gonum.org/v1/plot"
    12  	"gonum.org/v1/plot/plotter"
    13  	"gonum.org/v1/plot/vg/draw"
    14  )
    15  
    16  // Band implements the plot.Plotter interface, drawing a colored band made of
    17  // two lines.
    18  type Band struct {
    19  	top    plotter.XYs
    20  	bottom plotter.XYs
    21  
    22  	// LineStyle is the style of the line contouring the band.
    23  	// Use zero width to disable.
    24  	draw.LineStyle
    25  
    26  	// FillColor is the color to fill the area between
    27  	// the top and bottom data points.
    28  	// Use nil to disable the filling.
    29  	FillColor color.Color
    30  }
    31  
    32  func NewBand(fill color.Color, top, bottom plotter.XYer) *Band {
    33  	band := &Band{
    34  		top:       make(plotter.XYs, top.Len()),
    35  		bottom:    make(plotter.XYs, bottom.Len()),
    36  		FillColor: fill,
    37  	}
    38  	for i := range band.top {
    39  		x, y := top.XY(i)
    40  		band.top[i].X = x
    41  		band.top[i].Y = y
    42  	}
    43  	for i := range band.bottom {
    44  		x, y := bottom.XY(i)
    45  		band.bottom[i].X = x
    46  		band.bottom[i].Y = y
    47  	}
    48  
    49  	return band
    50  }
    51  
    52  func (band *Band) Plot(c draw.Canvas, plt *plot.Plot) {
    53  	switch {
    54  	case len(band.top) <= 1:
    55  		return
    56  	case len(band.bottom) <= 1:
    57  		return
    58  	}
    59  
    60  	xys := make(plotter.XYs, 0, len(band.top)+len(band.bottom))
    61  	xys = append(xys, band.bottom...)
    62  	for i := range band.top {
    63  		xys = append(xys, band.top[len(band.top)-1-i])
    64  	}
    65  
    66  	poly := plotter.Polygon{
    67  		XYs:       []plotter.XYs{xys},
    68  		LineStyle: band.LineStyle,
    69  		Color:     band.FillColor,
    70  	}
    71  
    72  	poly.Plot(c, plt)
    73  }
    74  
    75  // DataRange returns the minimum and maximum
    76  // x and y values, implementing the plot.DataRanger interface.
    77  func (band *Band) DataRange() (xmin, xmax, ymin, ymax float64) {
    78  	xmin1, xmax1, ymin1, ymax1 := plotter.XYRange(band.top)
    79  	xmin2, xmax2, ymin2, ymax2 := plotter.XYRange(band.bottom)
    80  
    81  	xmin = math.Min(xmin1, xmin2)
    82  	xmax = math.Max(xmax1, xmax2)
    83  	ymin = math.Min(ymin1, ymin2)
    84  	ymax = math.Max(ymax1, ymax2)
    85  
    86  	return xmin, xmax, ymin, ymax
    87  }
    88  
    89  var (
    90  	_ plot.Plotter    = (*VertLine)(nil)
    91  	_ plot.Plotter    = (*HorizLine)(nil)
    92  	_ plot.Plotter    = (*Band)(nil)
    93  	_ plot.DataRanger = (*Band)(nil)
    94  )