go-hep.org/x/hep@v0.38.1/hplot/line.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" 14 "gonum.org/v1/plot/vg/draw" 15 ) 16 17 // VertLine draws a vertical line at X and colors the 18 // left and right portions of the plot with the provided 19 // colors. 20 type VertLine struct { 21 X float64 22 Line draw.LineStyle 23 Left color.Color 24 Right color.Color 25 } 26 27 // VLine creates a vertical line at x with the default line style. 28 func VLine(x float64, left, right color.Color) *VertLine { 29 return &VertLine{ 30 X: x, 31 Line: plotter.DefaultLineStyle, 32 Left: left, 33 Right: right, 34 } 35 } 36 37 func (vline *VertLine) Plot(c draw.Canvas, plt *plot.Plot) { 38 var ( 39 trX, _ = plt.Transforms(&c) 40 x = trX(vline.X) 41 xmin = c.Min.X 42 xmax = c.Max.X 43 ymin = c.Min.Y 44 ymax = c.Max.Y 45 ) 46 47 if vline.Left != nil && x > xmin { 48 c.SetColor(vline.Left) 49 rect := vg.Rectangle{ 50 Min: vg.Point{X: xmin, Y: ymin}, 51 Max: vg.Point{X: x, Y: ymax}, 52 } 53 c.Fill(rect.Path()) 54 } 55 if vline.Right != nil && x < xmax { 56 c.SetColor(vline.Right) 57 rect := vg.Rectangle{ 58 Min: vg.Point{X: x, Y: ymin}, 59 Max: vg.Point{X: xmax, Y: ymax}, 60 } 61 c.Fill(rect.Path()) 62 } 63 64 if vline.Line.Width != 0 && xmin <= x && x <= xmax { 65 c.StrokeLine2(vline.Line, x, ymin, x, ymax) 66 } 67 } 68 69 // Thumbnail returns the thumbnail for the VertLine, 70 // implementing the plot.Thumbnailer interface. 71 func (vline *VertLine) Thumbnail(c *draw.Canvas) { 72 if vline.Left != nil { 73 minX := c.Min.X 74 maxX := c.Center().X 75 minY := c.Min.Y 76 maxY := c.Max.Y 77 points := []vg.Point{ 78 {X: minX, Y: minY}, 79 {X: minX, Y: maxY}, 80 {X: maxX, Y: maxY}, 81 {X: maxX, Y: minY}, 82 } 83 poly := c.ClipPolygonY(points) 84 c.FillPolygon(vline.Left, poly) 85 } 86 87 if vline.Right != nil { 88 minX := c.Center().X 89 maxX := c.Max.X 90 minY := c.Min.Y 91 maxY := c.Max.Y 92 points := []vg.Point{ 93 {X: minX, Y: minY}, 94 {X: minX, Y: maxY}, 95 {X: maxX, Y: maxY}, 96 {X: maxX, Y: minY}, 97 } 98 poly := c.ClipPolygonY(points) 99 c.FillPolygon(vline.Right, poly) 100 } 101 102 if vline.Line.Width != 0 { 103 x := c.Center().X 104 c.StrokeLine2(vline.Line, x, c.Min.Y, x, c.Max.Y) 105 } 106 } 107 108 // DataRange returns the range of X and Y values. 109 func (vline *VertLine) DataRange() (xmin, xmax, ymin, ymax float64) { 110 xmin = vline.X 111 xmax = vline.X 112 ymin = math.Inf(+1) 113 ymax = math.Inf(-1) 114 return 115 } 116 117 // HorizLine draws a horizontal line at Y and colors the 118 // top and bottom portions of the plot with the provided 119 // colors. 120 type HorizLine struct { 121 Y float64 122 Line draw.LineStyle 123 Top color.Color 124 Bottom color.Color 125 } 126 127 // HLine creates a horizontal line at y with the default line style. 128 func HLine(y float64, top, bottom color.Color) *HorizLine { 129 return &HorizLine{ 130 Y: y, 131 Line: plotter.DefaultLineStyle, 132 Top: top, 133 Bottom: bottom, 134 } 135 } 136 137 func (hline *HorizLine) Plot(c draw.Canvas, plt *plot.Plot) { 138 var ( 139 _, trY = plt.Transforms(&c) 140 y = trY(hline.Y) 141 xmin = c.Min.X 142 xmax = c.Max.X 143 ymin = c.Min.Y 144 ymax = c.Max.Y 145 ) 146 147 if hline.Top != nil && y < ymax { 148 c.SetColor(hline.Top) 149 rect := vg.Rectangle{ 150 Min: vg.Point{X: xmin, Y: y}, 151 Max: vg.Point{X: xmax, Y: ymax}, 152 } 153 c.Fill(rect.Path()) 154 } 155 if hline.Bottom != nil && y > ymin { 156 c.SetColor(hline.Bottom) 157 rect := vg.Rectangle{ 158 Min: vg.Point{X: xmin, Y: ymin}, 159 Max: vg.Point{X: xmax, Y: y}, 160 } 161 c.Fill(rect.Path()) 162 } 163 164 if hline.Line.Width != 0 && ymin <= y && y <= ymax { 165 c.StrokeLine2(hline.Line, xmin, y, xmax, y) 166 } 167 } 168 169 // Thumbnail returns the thumbnail for the VertLine, 170 // implementing the plot.Thumbnailer interface. 171 func (hline *HorizLine) Thumbnail(c *draw.Canvas) { 172 if hline.Top != nil { 173 minX := c.Min.X 174 maxX := c.Max.X 175 minY := c.Center().Y 176 maxY := c.Max.Y 177 points := []vg.Point{ 178 {X: minX, Y: minY}, 179 {X: minX, Y: maxY}, 180 {X: maxX, Y: maxY}, 181 {X: maxX, Y: minY}, 182 } 183 poly := c.ClipPolygonY(points) 184 c.FillPolygon(hline.Top, poly) 185 } 186 187 if hline.Bottom != nil { 188 minX := c.Min.X 189 maxX := c.Max.X 190 minY := c.Min.Y 191 maxY := c.Center().Y 192 points := []vg.Point{ 193 {X: minX, Y: minY}, 194 {X: minX, Y: maxY}, 195 {X: maxX, Y: maxY}, 196 {X: maxX, Y: minY}, 197 } 198 poly := c.ClipPolygonY(points) 199 c.FillPolygon(hline.Bottom, poly) 200 } 201 202 if hline.Line.Width != 0 { 203 y := c.Center().Y 204 c.StrokeLine2(hline.Line, c.Min.X, y, c.Max.X, y) 205 } 206 } 207 208 // DataRange returns the range of X and Y values. 209 func (hline *HorizLine) DataRange() (xmin, xmax, ymin, ymax float64) { 210 xmin = math.Inf(+1) 211 xmax = math.Inf(-1) 212 ymin = hline.Y 213 ymax = hline.Y 214 return 215 } 216 217 var ( 218 _ plot.Plotter = (*VertLine)(nil) 219 _ plot.Plotter = (*HorizLine)(nil) 220 221 _ plot.DataRanger = (*VertLine)(nil) 222 _ plot.DataRanger = (*HorizLine)(nil) 223 224 _ plot.Thumbnailer = (*VertLine)(nil) 225 _ plot.Thumbnailer = (*HorizLine)(nil) 226 )