1 module ggplotd.legend; 2 3 import cairo = cairo; 4 5 import ggplotd.colour : ColourGradient; 6 7 package struct Legend 8 { 9 string type = "continuous"; 10 int height = 70; 11 int width = 80; 12 } 13 14 /++ 15 Create a legend using a continuous scale 16 17 Params: 18 width = Optional width in pixels 19 height = Optional height in pixels 20 +/ 21 auto continuousLegend(int width = 80, int height = 70) 22 { 23 return Legend("continuous", width, height); 24 } 25 26 /++ 27 Create a legend using a discrete scale 28 29 Params: 30 width = Optional width in pixels 31 height = Optional height in pixels 32 +/ 33 auto discreteLegend(int width = 80, int height = 70) 34 { 35 return Legend("discrete", width, height); 36 } 37 38 39 /// Draw a legend for a continuous value to the given surface 40 auto drawContinuousLegend(CR, CG) 41 (ref cairo.Surface surface, int width, int height, 42 CR colourStore, CG colourGradient ) 43 { 44 import std.algorithm : reduce; 45 import std.typecons : tuple; 46 47 import ggplotd.ggplotd : GGPlotD, Margins; 48 import ggplotd.algorithm : safeMin, safeMax; 49 import ggplotd.aes : Aes; 50 import ggplotd.geom : geomPolygon; 51 import ggplotd.axes : xaxisShow; 52 // TODO: constify 53 // TODO: make sure to test with alternative coloursceme (the hist2D examples, should suffice) 54 auto gg = GGPlotD(); 55 gg.put(Margins(15, 0, 0, 0)); 56 gg.put( colourGradient ); 57 58 auto aes = Aes!( double[], "x", double[], "y", double[], "colour" ) 59 ( [0.0,0,1,1], 60 [colourStore.min(), colourStore.max(), colourStore.max(), colourStore.min()], 61 [colourStore.min(), colourStore.max(), colourStore.max(), colourStore.min()]); 62 gg.put( geomPolygon(aes) ); 63 gg.put( xaxisShow(false) ); 64 65 gg.drawToSurface( surface, width, height ); 66 return surface; 67 } 68 69 /// Draw a legend for a discrete value to the given surface 70 auto drawDiscreteLegend(CR, CG) 71 (ref cairo.Surface surface, int width, int height, 72 CR colourStore, CG colourGradient ) 73 { 74 import std.algorithm : map; 75 import std.array : array; 76 import std.conv : to; 77 import std.range : repeat, walkLength; 78 import std.typecons : tuple; 79 80 import ggplotd.ggplotd : GGPlotD, Margins; 81 import ggplotd.algorithm : safeMin, safeMax; 82 import ggplotd.aes : Aes; 83 import ggplotd.geom : geomRectangle; 84 import ggplotd.axes : xaxisShow, xaxisRange; 85 import ggplotd.range : uniquer; 86 // TODO: constify 87 // TODO: make sure to test with alternative coloursceme (the hist2D examples, should suffice) 88 auto gg = GGPlotD(); 89 gg.put(Margins(15, 0, 0, 0)); 90 gg.put(colourGradient); 91 92 //auto ys = colourRange.uniquer.map!((a) => a.to!double); 93 auto cols = colourStore.store; 94 auto xs = (1.0).repeat(cols.walkLength); 95 auto dims = (0.8).repeat(cols.walkLength); 96 auto aes = Aes!( typeof(xs), "x", typeof(cols), "y", 97 typeof(cols), "colour", typeof(dims), "width", 98 typeof(dims), "height", typeof(xs), "fill") 99 ( xs, cols, cols, dims, dims, xs); 100 gg.put( geomRectangle(aes) ); 101 102 gg.put( xaxisShow(false) ); 103 gg.put( xaxisRange(0.5, 1.0) ); 104 gg.drawToSurface( surface, width, height ); 105 return surface; 106 }