Plot implements the plot.Plotter interface.
(c draw.Canvas, plt *plot.Plot)
| 201 | |
| 202 | // Plot implements the plot.Plotter interface. |
| 203 | func (s *Sankey) Plot(c draw.Canvas, plt *plot.Plot) { |
| 204 | trCat, trVal := plt.Transforms(&c) |
| 205 | |
| 206 | // sourceFlowPlaceholder and receptorFlowPlaceholder track |
| 207 | // the current plotting location during |
| 208 | // the plotting process. |
| 209 | sourceFlowPlaceholder := make(map[*stock]float64, len(s.flows)) |
| 210 | receptorFlowPlaceholder := make(map[*stock]float64, len(s.flows)) |
| 211 | |
| 212 | // Here we draw the flows. |
| 213 | for _, f := range s.flows { |
| 214 | startStock := s.stocks[f.SourceCategory][f.SourceLabel] |
| 215 | endStock := s.stocks[f.ReceptorCategory][f.ReceptorLabel] |
| 216 | catStart := trCat(float64(f.SourceCategory)) + s.StockBarWidth/2 |
| 217 | catEnd := trCat(float64(f.ReceptorCategory)) - s.StockBarWidth/2 |
| 218 | valStartLow := trVal(startStock.min + sourceFlowPlaceholder[startStock]) |
| 219 | valEndLow := trVal(endStock.min + receptorFlowPlaceholder[endStock]) |
| 220 | valStartHigh := trVal(startStock.min + sourceFlowPlaceholder[startStock] + f.Value) |
| 221 | valEndHigh := trVal(endStock.min + receptorFlowPlaceholder[endStock] + f.Value) |
| 222 | sourceFlowPlaceholder[startStock] += f.Value |
| 223 | receptorFlowPlaceholder[endStock] += f.Value |
| 224 | |
| 225 | ptsLow := s.bezier( |
| 226 | vg.Point{X: catStart, Y: valStartLow}, |
| 227 | vg.Point{X: catEnd, Y: valEndLow}, |
| 228 | ) |
| 229 | ptsHigh := s.bezier( |
| 230 | vg.Point{X: catEnd, Y: valEndHigh}, |
| 231 | vg.Point{X: catStart, Y: valStartHigh}, |
| 232 | ) |
| 233 | |
| 234 | color, lineStyle := s.FlowStyle(f.Group) |
| 235 | |
| 236 | // Here we fill the flow polygons. |
| 237 | if color != nil { |
| 238 | poly := c.ClipPolygonX(append(ptsLow, ptsHigh...)) |
| 239 | c.FillPolygon(color, poly) |
| 240 | } |
| 241 | |
| 242 | // Here we draw the flow edges. |
| 243 | outline := c.ClipLinesX(ptsLow) |
| 244 | c.StrokeLines(lineStyle, outline...) |
| 245 | outline = c.ClipLinesX(ptsHigh) |
| 246 | c.StrokeLines(lineStyle, outline...) |
| 247 | } |
| 248 | |
| 249 | // Here we draw the stocks. |
| 250 | for _, stk := range s.stockList() { |
| 251 | catLoc := trCat(float64(stk.category)) |
| 252 | if !c.ContainsX(catLoc) { |
| 253 | continue |
| 254 | } |
| 255 | catMin, catMax := catLoc-s.StockBarWidth/2, catLoc+s.StockBarWidth/2 |
| 256 | valMin, valMax := trVal(stk.min), trVal(stk.max) |
| 257 | |
| 258 | label, textStyle, xOff, yOff, color, lineStyle := s.StockStyle(stk.label, stk.category) |
| 259 | |
| 260 | // Here we fill the stock bars. |
nothing calls this directly
no test coverage detected