1# 2# francy: Interactive Discrete Mathematics in GAP 3# 4 5############################################################################# 6## 7#M Canvas( <title>, <options> ) . . . . . a new graphic canvas 8## 9InstallMethod(Canvas, 10 "a title string, a default configurations record", 11 true, 12 [IsString, 13 IsCanvasDefaults], 14 0, 15function(title, options) 16 return MergeObjects(Objectify(CanvasObjectType, rec( 17 id := GenerateID(), 18 menus := rec(), 19 graph := rec(), 20 chart := rec(), 21 messages := rec(), 22 title := title 23 )), options); 24end); 25 26InstallOtherMethod(Canvas, 27 "a title string", 28 true, 29 [IsString], 30 0, 31function(title) 32 return Canvas(title, CanvasDefaults); 33end); 34 35############################################################################# 36## 37#M Add( <canvas>, <francy object> ) . . . . . add objects to canvas 38## 39InstallOtherMethod(Add, 40 "a canvas, a graph", 41 true, 42 [IsCanvas, 43 IsFrancyGraph], 44 0, 45function(canvas, graph) 46 canvas!.graph := graph; 47 # unbind the chart, only graph should exist! 48 Unbind(canvas!.chart); 49 return canvas; 50end); 51 52InstallOtherMethod(Add, 53 "a canvas, a chart", 54 true, 55 [IsCanvas, 56 IsChart], 57 0, 58function(canvas, chart) 59 canvas!.chart := chart; 60 # unbind the graph, only chart should exist! 61 Unbind(canvas!.graph); 62 return canvas; 63end); 64 65InstallOtherMethod(Add, 66 "a canvas, a menu", 67 true, 68 [IsCanvas, 69 IsMenu], 70 0, 71function(canvas, menu) 72 canvas!.menus!.(menu!.id) := menu; 73 return canvas; 74end); 75 76InstallOtherMethod(Add, 77 "a canvas, a message", 78 true, 79 [IsCanvas, 80 IsFrancyMessage], 81 0, 82function(canvas, message) 83 canvas!.messages!.(message!.id) := message; 84 return canvas; 85end); 86 87InstallOtherMethod(Add, 88 "a canvas, a list of francy objects", 89 true, 90 [IsCanvas, 91 IsList], 92 0, 93function(canvas, objects) 94 local object; 95 for object in objects do 96 Add(canvas, object); 97 od; 98 return canvas; 99end); 100 101############################################################################# 102## 103#M Remove( <canvas>, <francy object> ) . . . . . remove object from canvas 104## 105InstallOtherMethod(Remove, 106 "a canvas, a graph", 107 true, 108 [IsCanvas, 109 IsFrancyGraph], 110 0, 111function(canvas, graph) 112 Unbind(canvas!.graph); 113 canvas!.graph := rec(); 114 canvas!.chart := rec(); 115 return canvas; 116end); 117 118InstallOtherMethod(Remove, 119 "a canvas, a chart", 120 true, 121 [IsCanvas, 122 IsChart], 123 0, 124function(canvas, chart) 125 Unbind(canvas!.chart); 126 canvas!.graph := rec(); 127 canvas!.chart := rec(); 128 return canvas; 129end); 130 131InstallOtherMethod(Remove, 132 "a canvas, a menu", 133 true, 134 [IsCanvas, 135 IsMenu], 136 0, 137function(canvas, menu) 138 Unbind(canvas!.menus!.(menu!.id)); 139 return canvas; 140end); 141 142InstallOtherMethod(Remove, 143 "a canvas, a message", 144 true, 145 [IsCanvas, 146 IsFrancyMessage], 147 0, 148function(canvas, message) 149 Unbind(canvas!.messages!.(message!.id)); 150 return canvas; 151end); 152 153InstallOtherMethod(Remove, 154 "a canvas, a list of francy objects", 155 true, 156 [IsCanvas, 157 IsList], 158 0, 159function(canvas, objects) 160 local object; 161 for object in objects do 162 Remove(canvas, object); 163 od; 164 return canvas; 165end); 166 167############################################################################# 168## 169#M Draw( ) . . . . . 170## 171InstallMethod(Draw, 172 "a canvas", 173 true, 174 [IsCanvas], 175 0, 176function(canvas) 177 local object; 178 object := rec(); 179 object!.mime := FrancyMIMEType; 180 object!.version := InstalledPackageVersion("francy"); 181 object!.canvas := Sanitize(canvas); 182 return Objectify( 183 JupyterRenderableType, 184 rec( 185 data := rec((FrancyMIMEType) := GapToJsonString(object)), 186 metadata := rec((FrancyMIMEType) := rec()) 187 ) 188 ); 189end); 190 191############################################################################# 192## 193#M DrawSplash( ) . . . . . 194## 195InstallMethod(DrawSplash, 196 "a canvas", 197 true, 198 [IsCanvas], 199 0, 200function(canvas) 201 local name, result, page; 202 203 name := Filename(DirectoryTemporary(), Concatenation("francy_", LowercaseString(ReplacedString(canvas!.title, " ", "_")) ,".html")); 204 205 result := Draw(canvas); 206 207 page := Concatenation( 208 "<!DOCTYPE html>\n\ 209 <html>\n\ 210 <head>\n\ 211 <meta charset=\"utf-8\" content=\"text/html\" property=\"GAP,francy,d3.v5\"></meta>\n\ 212 <link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdn.rawgit.com/mcmartins/francy/develop/js/extensions/browser/index.css\"></link>\n\ 213 <script src=\"https://d3js.org/d3.v5.js\"></script>\n\ 214 <script src=\"https://cdn.rawgit.com/mcmartins/francy/master/js/extensions/browser/francy.bundle.js\"></script>\n\ 215 <title>Francy</title>\n\ 216 </head>\n\ 217 <body>\n\ 218 <div id=\"francy\"></div>\n\ 219 <script>\n\ 220 var francy = new Francy({verbose: true, appendTo: 'body', callbackHandler: console.log});\n\ 221 francy.load(", result!.data!.(FrancyMIMEType), ").render();\n\ 222 </script>\n\ 223 </body>\n\ 224 </html>"); 225 226 PrintTo(name, page); 227 228 if ARCH_IS_MAC_OS_X() or ARCH_IS_UNIX() then 229 Exec("open ",name); 230 elif ARCH_IS_WINDOWS() then 231 Exec("start ",name); 232 fi; 233 234 return page; 235end); 236