{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Francy Package\n", "\n", "Francy is responsible for creating a representational structure that can be rendered using pretty much any UI framework\n", "in any language for any OS.\n", "\n", "Francy JS renders this model in Jupyter, and allows interactivity with GAP." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Draw\n", "\n", "Draw is the main function of Francy. It renders a canvas and all the child objects in Jupyter environment or any other environment which connects to GAP somehow, e.g. a webssh console with websockets, etc.\n", "\n", "### DrawSplash\n", "\n", "DrawSplash uses Draw to generate the data and creates a Static HTML Page that can be embedded or viewed in any browser, in \"offline\" mode.\n", "\n", "**NOTE: When using this, there will be no interaction back to gap as there is no kernel orchestrating the communication between francy and gap! This might change in the future, but no plans to implement such functionality using websockets at the moment.**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Load Package" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "true" ] }, "execution_count": 1, "metadata": { "text/plain": "" }, "output_type": "execute_result" } ], "source": [ "LoadPackage(\"francy\");" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Canvas\n", "\n", "Canvas are the base where graphics are produced. A Canvas is constituted by a Main Menu and an area where the graphics are produced.\n", "\n", "## How to create a Canvas?\n", "\n", "It is possible to set some default configurations for the canvas:\n", "\n", "```gap\n", "gap> defaults := CanvasDefaults;\n", "gap> Sanitize(defaults);\n", "rec( height := 600, width := 800, zoomToFit := true )\n", "gap> SetWidth(defaults, 830);\n", "gap> SetHeight(defaults, 630);\n", "gap> SetZoomToFit(defaults, false);\n", "gap> SetTexTypesetting(defaults, true);\n", "gap> canvas := Canvas(\"Example Canvas\", defaults);\n", "\n", "```\n", "\n", "Or it can be done after, by:\n", "\n", "```gap\n", "gap> canvas := Canvas(\"Example Canvas\");\n", "gap> SetWidth(canvas, 850);\n", "gap> SetHeight(canvas, 650);\n", "gap> SetZoomToFit(canvas, true);\n", "```" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "application/vnd.francy+json": "{\"version\" : \"1.2.3\",\"mime\" : \"application\\/vnd.francy+json\",\"canvas\" : {\"width\" : 800,\"id\" : \"F1\",\"height\" : 450,\"title\" : \"Callbacks in action\",\"zoomToFit\" : true,\"texTypesetting\" : true,\"menus\" : {\"F6\" : {\"id\" : \"F6\",\"title\" : \"Example Menu Holder\",\"callback\" : {},\"menus\" : {\"F7\" : {\"id\" : \"F7\",\"title\" : \"Hello Menu Action\",\"callback\" : {\"func\" : \"HelloWorld\",\"id\" : \"F4\",\"trigger\" : \"click\",\"knownArgs\" : [],\"requiredArgs\" : {\"F5\" : {\"type\" : \"text\",\"id\" : \"F5\",\"title\" : \"Your Name?\",\"value\" : \"\"}}},\"menus\" : {}}}},\"F7\" : {\"id\" : \"F7\",\"title\" : \"Hello Menu Action\",\"callback\" : {\"func\" : \"HelloWorld\",\"id\" : \"F4\",\"trigger\" : \"click\",\"knownArgs\" : [],\"requiredArgs\" : {\"F5\" : {\"type\" : \"text\",\"id\" : \"F5\",\"title\" : \"Your Name?\",\"value\" : \"\"}}},\"menus\" : {}}},\"graph\" : {\"type\" : \"undirected\",\"id\" : \"F2\",\"simulation\" : true,\"collapsed\" : true,\"nodes\" : {\"F3\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F3\",\"size\" : 10,\"title\" : \"$x^2$\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {\"F7\" : {\"id\" : \"F7\",\"title\" : \"Hello Menu Action\",\"callback\" : {\"func\" : \"HelloWorld\",\"id\" : \"F4\",\"trigger\" : \"click\",\"knownArgs\" : [],\"requiredArgs\" : {\"F5\" : {\"type\" : \"text\",\"id\" : \"F5\",\"title\" : \"Your Name?\",\"value\" : \"\"}}},\"menus\" : {}}},\"messages\" : {},\"callbacks\" : {}}},\"links\" : {}},\"messages\" : {}}}" }, "execution_count": 19, "metadata": { "application/vnd.francy+json": {} }, "output_type": "execute_result" } ], "source": [ "canvas := Canvas(\"Callbacks in action\");;\n", "SetTexTypesetting(canvas, true);;\n", "SetHeight(canvas, 450);;\n", "\n", "graph := Graph(GraphType.UNDIRECTED);; # will go throughout graphs later\n", "shape := Shape(ShapeType.CIRCLE, \"$x^2$\");; # will go throughout shapes later\n", "Add(graph, shape);;\n", "Add(canvas, graph);;\n", "\n", "HelloWorld := function(name)\n", " Add(canvas, FrancyMessage(Concatenation(\"Hello, \", name))); # will go throughout messages later\n", " return Draw(canvas);\n", "end;;\n", "\n", "callback1 := Callback(HelloWorld);;\n", "arg1 := RequiredArg(ArgType.STRING, \"Your Name?\");;\n", "Add(callback1, arg1);;\n", "\n", "menu := Menu(\"Example Menu Holder\");;\n", "menu1 := Menu( \"Hello Menu Action\", callback1 );;\n", "Add(menu, menu1);;\n", "\n", "Add(canvas, menu);;\n", "Add(canvas, menu1);;\n", "Add(shape, menu1);;\n", "\n", "Draw(canvas);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Menus\n", "\n", "Menus can be added to the Canvas, where they will be added to the Main Menu on the Top, or to Shapes, where they will appear as Context Menu - Mouse right click.\n", "\n", "The Main Menu has by default a Menu entry called Francy with 3 Sub Menus: Zoom to Fit, Save to PNG and About. When a Graph is produce the Main Menu will also contain a Menu entry called Graph Options with 3 Sub Menus: Enable/Disable Drag, Enable/Disable Neighbours, Clear Selected Nodes.\n", "\n", "# Callbacks\n", "\n", "A Callback is a function that is triggered in GAP and can be added to Menus and/or Shapes.\n", "\n", "## How to create a Callback?\n", "\n", "Callbacks can be created in many different ways, and it will depend on what you want to do.\n", "\n", "Callbacks are triggered with mouse events. Available TriggerTypes are:\n", "\n", "* TriggerType.DOUBLE_CLICK\n", "* TriggerType.RIGHT_CLICK\n", "* TriggerType.CLICK\n", "\n", "*NOTE: No matter what you choose for TriggerType on a callback that is used on a Menu will always default to TriggerType.CLICK!*\n", "\n", "Calling a Simple function that doesn't require any argument is the simplest form:\n", "\n", "```gap\n", "gap> MyFunction := function()\n", "> # Must return allways! This is because GAP CallFuncList is used and requires it\n", "> return;\n", "> end;\n", "gap> callback := Callback(MyFunction); # defaults to CLICK event\n", "gap> callback := Callback(TriggerType.DOUBLE_CLICK, MyFunction);\n", "```\n", "\n", "Calling a Function with a \"known\" argument is also simple:\n", "\n", "```gap\n", "gap> canvas := Canvas(\"Callbacks in Action!\");\n", "gap> MyFunction := function(someKnownArg)\n", "> # Do some crazy computation\n", "> # Redraw\n", "> return Draw(canvas);\n", "> end;\n", "gap> something := NumericalSemigroup(10,11,19);\n", "gap> callback := Callback(MyFunction, [something]);\n", "```\n", "\n", "What if we want the user to give some input? Well, this is the case you have \"required\" arguments:\n", "\n", "```gap\n", "gap> canvas := Canvas(\"Callbacks in Action!\");\n", "gap> MyFunction := function(someKnownArg, someUserInputArg)\n", "> # Do Some Crazy computation\n", "> # Redraw\n", "> return Draw(canvas);\n", "> end;\n", "gap> something := NumericalSemigroup(10,11,19);\n", "gap> callback := Callback(MyFunction, [something]);\n", "gap> arg := RequiredArg(ArgType.NUMBER, \"Give me a Prime?\");\n", "gap> Add(callback, arg);\n", "```\n", "\n", "It is possible to add a confirmation message that gets displayed before executing the callback:\n", "\n", "```gap\n", "...\n", "gap> SetConfirmMessage(callback, \"This is a confirmation message! Click OK to proceed...\");\n", "```\n", "\n", "Required Arguments type defines the data type. Available ArgTypes are:\n", "\n", "* ArgType.SELECT\n", "* ArgType.BOOLEAN\n", "* ArgType.STRING\n", "* ArgType.NUMBER\n", "\n", "\n", "## How to create a Menu?\n", "\n", "Menus can include a Callback or not. Menus without callback are useful for holding Submenus.\n", "\n", "```gap\n", "gap> callback := Callback(MyCallbackFunction);\n", "gap> menu := Menu(\"Example Holder Menu\");\n", "gap> submenu := Menu(\"I'm a Submenu!\", callback);\n", "gap> Add(menu, submenu);\n", "gap> Add(canvas, menu);\n", "```\n", "\n", "Or as a top Menu:\n", "\n", "```gap\n", "gap> callback := Callback(MyCallbackFunction);\n", "gap> menu := Menu(\"Menu\", callback);\n", "gap> Add(canvas, menu);\n", "```\n", "\n", "The same menu objects can be used in Shapes:\n", "* NOTE: Submenus are flatenned in context menus!*\n", "\n", "```gap\n", "gap> shape := Shape(SpaheType.CIRCLE); # will go throughout shapes and graphs later\n", "gap> Add(shape, menu);\n", "```" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "application/vnd.francy+json": "{\"version\" : \"1.2.3\",\"mime\" : \"application\\/vnd.francy+json\",\"canvas\" : {\"width\" : 800,\"id\" : \"F8\",\"height\" : 450,\"title\" : \"Callbacks in action\",\"zoomToFit\" : true,\"texTypesetting\" : false,\"menus\" : {\"F14\" : {\"id\" : \"F14\",\"title\" : \"Example Menu Holder\",\"callback\" : {},\"menus\" : {\"F15\" : {\"id\" : \"F15\",\"title\" : \"Hello Menu Action\",\"callback\" : {\"func\" : \"HelloWorld\",\"id\" : \"F11\",\"confirm\" : \"This is a confirmation message...\",\"trigger\" : \"click\",\"knownArgs\" : [],\"requiredArgs\" : {\"F12\" : {\"type\" : \"text\",\"id\" : \"F12\",\"title\" : \"Your Name?\",\"value\" : \"\"},\"F13\" : {\"type\" : \"select\",\"id\" : \"F13\",\"title\" : \"Selected Nodes\",\"value\" : \"\"}}},\"menus\" : {}}}},\"F15\" : {\"id\" : \"F15\",\"title\" : \"Hello Menu Action\",\"callback\" : {\"func\" : \"HelloWorld\",\"id\" : \"F11\",\"confirm\" : \"This is a confirmation message...\",\"trigger\" : \"click\",\"knownArgs\" : [],\"requiredArgs\" : {\"F12\" : {\"type\" : \"text\",\"id\" : \"F12\",\"title\" : \"Your Name?\",\"value\" : \"\"},\"F13\" : {\"type\" : \"select\",\"id\" : \"F13\",\"title\" : \"Selected Nodes\",\"value\" : \"\"}}},\"menus\" : {}}},\"graph\" : {\"type\" : \"undirected\",\"id\" : \"F9\",\"simulation\" : true,\"collapsed\" : true,\"nodes\" : {\"F10\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F10\",\"size\" : 10,\"title\" : \"\",\"layer\" : 0,\"color\" : \"#2E8B57\",\"parent\" : \"\",\"menus\" : {\"F15\" : {\"id\" : \"F15\",\"title\" : \"Hello Menu Action\",\"callback\" : {\"func\" : \"HelloWorld\",\"id\" : \"F11\",\"confirm\" : \"This is a confirmation message...\",\"trigger\" : \"click\",\"knownArgs\" : [],\"requiredArgs\" : {\"F12\" : {\"type\" : \"text\",\"id\" : \"F12\",\"title\" : \"Your Name?\",\"value\" : \"\"},\"F13\" : {\"type\" : \"select\",\"id\" : \"F13\",\"title\" : \"Selected Nodes\",\"value\" : \"\"}}},\"menus\" : {}}},\"messages\" : {},\"callbacks\" : {\"F11\" : {\"func\" : \"HelloWorld\",\"id\" : \"F11\",\"confirm\" : \"This is a confirmation message...\",\"trigger\" : \"click\",\"knownArgs\" : [],\"requiredArgs\" : {\"F12\" : {\"type\" : \"text\",\"id\" : \"F12\",\"title\" : \"Your Name?\",\"value\" : \"\"},\"F13\" : {\"type\" : \"select\",\"id\" : \"F13\",\"title\" : \"Selected Nodes\",\"value\" : \"\"}}}}}},\"links\" : {}},\"messages\" : {}}}" }, "execution_count": 41, "metadata": { "application/vnd.francy+json": {} }, "output_type": "execute_result" } ], "source": [ "canvas2 := Canvas(\"Callbacks in action\");;\n", "SetHeight(canvas2, 450);;\n", "\n", "graph := Graph(GraphType.UNDIRECTED);; # will go throughout graphs later\n", "shape := Shape(ShapeType.CIRCLE);; # will go throughout shapes later\n", "SetColor(shape, \"#2E8B57\");;\n", "Add(graph, shape);;\n", "Add(canvas2, graph);;\n", "\n", "HelloWorld := function(name, node)\n", " Add(canvas2, FrancyMessage(Concatenation(\"Hello, \", name, \" - Selected Node ID: \",String(node)))); # will go throughout messages later\n", " return Draw(canvas2);\n", "end;;\n", "\n", "callback1 := Callback(HelloWorld);;\n", "SetConfirmMessage(callback1, \"This is a confirmation message...\");;\n", "arg1 := RequiredArg(ArgType.STRING, \"Your Name?\");;\n", "arg2 := RequiredArg(ArgType.SELECT, \"Selected Nodes\");;\n", "Add(callback1, arg1);;\n", "Add(callback1, arg2);;\n", "\n", "Add(shape, callback1);;\n", "\n", "menu := Menu(\"Example Menu Holder\");;\n", "menu1 := Menu( \"Hello Menu Action\", callback1 );;\n", "Add(menu, menu1);;\n", "\n", "Add(canvas2, menu);;\n", "Add(canvas2, menu1);;\n", "Add(shape, menu1);;\n", "\n", "Draw(canvas2);" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "application/vnd.francy+json": "{\"version\" : \"1.2.3\",\"mime\" : \"application\\/vnd.francy+json\",\"canvas\" : {\"width\" : 800,\"id\" : \"F16\",\"height\" : 450,\"title\" : \"Example Callbacks with Known Arguments\",\"zoomToFit\" : true,\"texTypesetting\" : false,\"menus\" : {},\"graph\" : {\"type\" : \"directed\",\"id\" : \"F17\",\"simulation\" : true,\"collapsed\" : true,\"nodes\" : {\"F18\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F18\",\"size\" : 10,\"title\" : \"Click Me 1\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {\"F20\" : {\"func\" : \"WhichNode\",\"id\" : \"F20\",\"trigger\" : \"click\",\"knownArgs\" : [\"\"],\"requiredArgs\" : {}}}},\"F19\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F19\",\"size\" : 10,\"title\" : \"Click Me 2\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {\"F21\" : {\"func\" : \"WhichNode\",\"id\" : \"F21\",\"trigger\" : \"click\",\"knownArgs\" : [\"\"],\"requiredArgs\" : {}}}}},\"links\" : {\"F22\" : {\"id\" : \"F22\",\"source\" : \"F18\",\"length\" : 0,\"weight\" : 2,\"title\" : \"or\",\"target\" : \"F19\",\"color\" : \"red\",\"invisible\" : false}}},\"messages\" : {}}}" }, "execution_count": 58, "metadata": { "application/vnd.francy+json": {} }, "output_type": "execute_result" } ], "source": [ "canvas3 := Canvas(\"Example Callbacks with Known Arguments\");;\n", "SetHeight(canvas3, 450);;\n", "\n", "graph := Graph(GraphType.DIRECTED);;\n", "\n", "shape := Shape(ShapeType.CIRCLE, \"Click Me 1\");;\n", "shape1 := Shape(ShapeType.CIRCLE, \"Click Me 2\");;\n", "Add(graph, shape);;\n", "Add(graph, shape1);;\n", "\n", "WhichNode := function(node)\n", " Add(canvas3, FrancyMessage(node!.title));\n", " return Draw(canvas3);\n", "end;;\n", "\n", "Add(shape, Callback(WhichNode, [shape]));; # similar to Add(shape, Callback(TriggerEvent.CLICK, WhichNode, [shape]));\n", "Add(shape1, Callback(WhichNode, [shape1]));; # similar to Add(shape1, Callback(TriggerEvent.CLICK, WhichNode, [shape1]));\n", "\n", "link := Link(shape, shape1);;\n", "SetWeight(link, 2);;\n", "SetColor(link, \"red\");;\n", "SetTitle(link, \"or\");;\n", "Add(graph, link);;\n", "\n", "Add(canvas3, graph);;\n", "\n", "Draw(canvas3);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Messages\n", "\n", "Messages are usefull for providing information to the user. Messages can be added to the Canvas and/or to Shapes.\n", "\n", "Messages added to a Canvas are displayed as messages using colors to differentiate types, they appear on the top left corner and can be dismissed by clicking on them.\n", "\n", "Messages added to a Shape are displayed as tooltips and their types are not taken in account, they appear when the user moves the mouse hover the Shape.\n", "\n", "## How to create Messages?\n", "\n", "Once again, creating messages is fairly simple and depends on the purpose of the message.\n", "\n", "Messages can be of the following types:\n", "\n", "* FrancyMessageType.INFO\n", "* FrancyMessageType.ERROR\n", "* FrancyMessageType.SUCCESS\n", "* FrancyMessageType.WARNING\n", "* FrancyMessageType.DEFAULT\n", "\n", "The simplest Message with the default type would be:\n", "\n", "```gap\n", "gap> FrancyMessage(\"Hello\", \"World\"); # title and text\n", "gap> FrancyMessage(\"Hello\"); # without title\n", "```\n", "\n", "Messages with a custom type:\n", "\n", "```gap\n", "gap> FrancyMessage(FrancyMessageType.INFO, \"Hello\", \"World\"); # title and text\n", "gap> FrancyMessage(FrancyMessageType.INFO, \"Hello World\"); # without title\n", "```" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "data": { "application/vnd.francy+json": "{\"version\" : \"1.2.3\",\"mime\" : \"application\\/vnd.francy+json\",\"canvas\" : {\"width\" : 800,\"id\" : \"F23\",\"height\" : 450,\"title\" : \"Example Callbacks with Known Arguments\",\"zoomToFit\" : true,\"texTypesetting\" : false,\"menus\" : {},\"graph\" : {\"type\" : \"directed\",\"id\" : \"F24\",\"simulation\" : true,\"collapsed\" : true,\"nodes\" : {\"F25\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F25\",\"size\" : 10,\"title\" : \"Click Me\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {\"F27\" : {\"func\" : \"WhichNode\",\"id\" : \"F27\",\"trigger\" : \"click\",\"knownArgs\" : [\"\",\"\"],\"requiredArgs\" : {}}}},\"F26\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F26\",\"size\" : 10,\"title\" : \"Click Me\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {\"F28\" : {\"func\" : \"WhichNode\",\"id\" : \"F28\",\"trigger\" : \"click\",\"knownArgs\" : [\"\",\"\"],\"requiredArgs\" : {}}}}},\"links\" : {}},\"messages\" : {}}}" }, "execution_count": 70, "metadata": { "application/vnd.francy+json": {} }, "output_type": "execute_result" } ], "source": [ "canvas4 := Canvas(\"Example Callbacks with Known Arguments\");;\n", "SetHeight(canvas4, 450);;\n", "\n", "graph := Graph(GraphType.DIRECTED);;\n", "Add(canvas4, graph);;\n", "\n", "shape := Shape(ShapeType.CIRCLE, \"Click Me\");;\n", "shape1 := Shape(ShapeType.CIRCLE, \"Click Me\");;\n", "Add(graph, shape);;\n", "Add(graph, shape1);;\n", "\n", "WhichNode := function(c, node)\n", " Add(c, FrancyMessage(String(node!.title)));\n", " return Draw(c);\n", "end;;\n", "\n", "Add(shape, Callback(WhichNode, [canvas4, shape]));; # similar to Add(shape, Callback(TriggerEvent.CLICK, WhichNode, [shape]));\n", "Add(shape1, Callback(WhichNode, [canvas4, shape1]));; # similar to Add(shape1, Callback(TriggerEvent.CLICK, WhichNode, [shape1]));\n", "\n", "Draw(canvas4);" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "data": { "application/vnd.francy+json": "{\"version\" : \"1.2.3\",\"mime\" : \"application\\/vnd.francy+json\",\"canvas\" : {\"width\" : 800,\"id\" : \"F29\",\"height\" : 250,\"title\" : \"Example Canvas \\/ Shape with Messages\",\"zoomToFit\" : true,\"texTypesetting\" : true,\"menus\" : {},\"graph\" : {\"type\" : \"undirected\",\"id\" : \"F30\",\"simulation\" : true,\"collapsed\" : true,\"nodes\" : {\"F31\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F31\",\"size\" : 10,\"title\" : \"\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {\"F33\" : {\"type\" : \"info\",\"id\" : \"F33\",\"text\" : \"Hello $x^2$\",\"title\" : \"\"},\"F35\" : {\"type\" : \"error\",\"id\" : \"F35\",\"text\" : \"Hello\",\"title\" : \"Oops\"},\"F37\" : {\"type\" : \"warning\",\"id\" : \"F37\",\"text\" : \"Hello\",\"title\" : \"\"},\"F39\" : {\"type\" : \"success\",\"id\" : \"F39\",\"text\" : \"Hello\",\"title\" : \"\"},\"F41\" : {\"type\" : \"default\",\"id\" : \"F41\",\"text\" : \"World\",\"title\" : \"Hello\"}},\"callbacks\" : {}}},\"links\" : {}},\"messages\" : {\"F32\" : {\"type\" : \"info\",\"id\" : \"F32\",\"text\" : \"Hello $x^2$\",\"title\" : \"\"},\"F34\" : {\"type\" : \"error\",\"id\" : \"F34\",\"text\" : \"Hello\",\"title\" : \"Oops\"},\"F36\" : {\"type\" : \"warning\",\"id\" : \"F36\",\"text\" : \"Hello\",\"title\" : \"\"},\"F38\" : {\"type\" : \"success\",\"id\" : \"F38\",\"text\" : \"Hello\",\"title\" : \"\"},\"F40\" : {\"type\" : \"default\",\"id\" : \"F40\",\"text\" : \"World\",\"title\" : \"Hello\"}}}}" }, "execution_count": 88, "metadata": { "application/vnd.francy+json": {} }, "output_type": "execute_result" } ], "source": [ "canvas5 := Canvas(\"Example Canvas / Shape with Messages\");;\n", "SetTexTypesetting(canvas5, true);;\n", "SetHeight(canvas5, 250);;\n", "\n", "graph := Graph(GraphType.UNDIRECTED);; # will go throughout graphs later\n", "shape := Shape(ShapeType.CIRCLE);; # will go throughout shapes later\n", "Add(graph, shape);;\n", "Add(canvas5, graph);;\n", "\n", "Add(canvas5, FrancyMessage(FrancyMessageType.INFO, \"Hello $x^2$\"));;\n", "Add(shape, FrancyMessage(FrancyMessageType.INFO, \"Hello $x^2$\"));;\n", "Add(canvas5, FrancyMessage(FrancyMessageType.ERROR, \"Oops\", \"Hello\"));;\n", "Add(shape, FrancyMessage(FrancyMessageType.ERROR, \"Oops\", \"Hello\"));;\n", "Add(canvas5, FrancyMessage(FrancyMessageType.WARNING, \"Hello\"));;\n", "Add(shape, FrancyMessage(FrancyMessageType.WARNING, \"Hello\"));;\n", "Add(canvas5, FrancyMessage(FrancyMessageType.SUCCESS, \"Hello\"));;\n", "Add(shape, FrancyMessage(FrancyMessageType.SUCCESS, \"Hello\"));;\n", "Add(canvas5, FrancyMessage(\"Hello\", \"World\"));;\n", "Add(shape, FrancyMessage(\"Hello\", \"World\"));;\n", "\n", "Draw(canvas5);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Graphs\n", "\n", "Graphs, according to wikipedia: *a graph is a structure amounting to a set of objects in which some pairs of the objects are in some sense \"related\"*\n", "\n", "In Francy, Graphs can be created using Shapes (nodes) and Links (edges). Francy, in this case the D3 library, will try its best to shape the graph according to a set of \"forces\". If the Shapes provide x and y coordinates, these will be used instead and the graph will be fixed to those.\n", "\n", "Supported GraphTypes are:\n", "\n", "* GraphType.UNDIRECTED\n", "* GraphType.DIRECTED\n", "* GraphType.TREE\n", "\n", "By default, Graphs are created with default options set to:\n", "\n", "* GraphDefaults.simulation [true] - does not work on type **tree**. applies d3 forces to the diagram and arranges the nodes without fixed positions\n", "* GraphDefaults.collapsed [true] - only works on type **tree**! whether the graph will be collapsed or not by default.\n", "\n", "Supported ShapeTypes are (Node Shapes):\n", "\n", "* ShapeType.TRIANGLE\n", "* ShapeType.DIAMOND\n", "* ShapeType.CIRCLE\n", "* ShapeType.SQUARE\n", "* ShapeType.CROSS\n", "* ShapeType.STAR\n", "* ShapeType.WYE\n", "\n", "By default, Shapes are created with default options set to:\n", "\n", "* ShapeDefaults.layer [0] - used to create hasse diagrams to set indexes\n", "* ShapeDefaults.size [10]\n", "* ShapeDefaults.x [0] - x position in canvas\n", "* ShapeDefaults.y [0] - y position in canvas\n", "\n", "*NOTE: Please note that Francy is not a Graph Library and thus no graph operations, in mathematical terms, are available*\n", "\n", "## How to create Graphs?\n", "\n", "Let's see how to create a graph of each type, starting with the Hasse. The Hasse diagram requires the layer to be set, in order to fix y positions to this layer option:\n", "\n", "```gap\n", "gap> graph := Graph(GraphType.UNDIRECTED);\n", "gap> shape := Shape(ShapeType.CIRCLE, \"Title\");\n", "gap> SetLayer(shape, 1);\n", "gap> shape1 := Shape(ShapeType.CIRCLE);\n", "gap> SetLayer(shape1, 2);\n", "gap> link := Link(shape, shape1);\n", "gap> Add(graph, shape);\n", "gap> Add(graph, shape1);\n", "gap> Add(graph, link);\n", "```\n", "\n", "*NOTE: This might change in order to ease the creation of HASSE diagrams without having to specify the layer. Suggestions are welcome!*\n", "\n", "A Directed graph instead is simpler:\n", "\n", "```gap\n", "gap> graph := Graph(GraphType.DIRECTED);\n", "gap> shape := Shape(ShapeType.CIRCLE, \"Title\");\n", "gap> shape1 := Shape(ShapeType.CIRCLE);\n", "gap> link := Link(shape, shape1);\n", "gap> Add(graph, shape);\n", "gap> Add(graph, shape1);\n", "gap> Add(graph, link);\n", "```\n", "\n", "Undirected graphs are as simple as Directed ones, but the arrows are not present:\n", "\n", "```gap\n", "gap> graph := Graph(GraphType.UNDIRECTED);\n", "gap> shape := Shape(ShapeType.CIRCLE, \"Title\");\n", "gap> shape1 := Shape(ShapeType.CIRCLE);\n", "gap> link := Link(shape, shape1);\n", "gap> Add(graph, shape);\n", "gap> Add(graph, shape1);\n", "gap> Add(graph, link);\n", "```\n", "\n", "Tree graphs are as simple as the previous ones, but you need to specify the parent node:\n", "\n", "```gap\n", "gap> graph := Graph(GraphType.TREE);\n", "gap> shape := Shape(ShapeType.CIRCLE, \"Title\");\n", "gap> shape1 := Shape(ShapeType.CIRCLE);\n", "gap> Add(graph, shape);\n", "gap> Add(graph, shape1);\n", "gap> SetParentShape(shape1, shape);\n", "```\n", "\n", "**NOTE: Blue nodes are clickable on trees and allows to expand and collapse.**" ] }, { "cell_type": "code", "execution_count": 101, "metadata": {}, "outputs": [ { "data": { "application/vnd.francy+json": "{\"version\" : \"1.2.3\",\"mime\" : \"application\\/vnd.francy+json\",\"canvas\" : {\"width\" : 800,\"id\" : \"F42\",\"height\" : 450,\"title\" : \"Example Hasse Graph\",\"zoomToFit\" : true,\"texTypesetting\" : false,\"menus\" : {},\"graph\" : {\"type\" : \"undirected\",\"id\" : \"F43\",\"simulation\" : true,\"collapsed\" : true,\"nodes\" : {\"F44\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F44\",\"size\" : 10,\"title\" : \"G\",\"layer\" : 1,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}},\"F45\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F45\",\"size\" : 10,\"title\" : \"1\",\"layer\" : 2,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}}},\"links\" : {\"F46\" : {\"id\" : \"F46\",\"source\" : \"F44\",\"length\" : 0,\"weight\" : 0,\"target\" : \"F45\",\"color\" : \"\",\"invisible\" : false}}},\"messages\" : {}}}" }, "execution_count": 101, "metadata": { "application/vnd.francy+json": {} }, "output_type": "execute_result" } ], "source": [ "canvas6 := Canvas(\"Example Hasse Graph\");;\n", "SetHeight(canvas6, 450);;\n", "\n", "graph := Graph(GraphType.UNDIRECTED);;\n", "\n", "shape := Shape(ShapeType.CIRCLE, \"G\");;\n", "SetLayer(shape, 1);;\n", "shape1 := Shape(ShapeType.CIRCLE, \"1\");;\n", "SetLayer(shape1, 2);;\n", "Add(graph, shape);;\n", "Add(graph, shape1);;\n", "\n", "link := Link(shape, shape1);;\n", "Add(graph, link);;\n", "\n", "Add(canvas6, graph);;\n", "\n", "Draw(canvas6);" ] }, { "cell_type": "code", "execution_count": 114, "metadata": {}, "outputs": [ { "data": { "application/vnd.francy+json": "{\"version\" : \"1.2.3\",\"mime\" : \"application\\/vnd.francy+json\",\"canvas\" : {\"width\" : 800,\"id\" : \"F47\",\"height\" : 450,\"title\" : \"Example Directed Graph\",\"zoomToFit\" : true,\"texTypesetting\" : false,\"menus\" : {},\"graph\" : {\"type\" : \"directed\",\"id\" : \"F48\",\"simulation\" : true,\"collapsed\" : true,\"nodes\" : {\"F49\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F49\",\"size\" : 10,\"title\" : \"G\",\"layer\" : 1,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}},\"F50\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F50\",\"size\" : 10,\"title\" : \"1\",\"layer\" : 2,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}}},\"links\" : {\"F51\" : {\"id\" : \"F51\",\"source\" : \"F49\",\"length\" : 0,\"weight\" : 0,\"target\" : \"F50\",\"color\" : \"\",\"invisible\" : false}}},\"messages\" : {}}}" }, "execution_count": 114, "metadata": { "application/vnd.francy+json": {} }, "output_type": "execute_result" } ], "source": [ "canvas7 := Canvas(\"Example Directed Graph\");;\n", "SetHeight(canvas7, 450);;\n", "\n", "graph := Graph(GraphType.DIRECTED);;\n", "\n", "shape := Shape(ShapeType.CIRCLE, \"G\");;\n", "SetLayer(shape, 1);;\n", "shape1 := Shape(ShapeType.CIRCLE, \"1\");;\n", "SetLayer(shape1, 2);;\n", "Add(graph, shape);;\n", "Add(graph, shape1);;\n", "\n", "link := Link(shape, shape1);;\n", "Add(graph, link);;\n", "\n", "Add(canvas7, graph);;\n", "\n", "Draw(canvas7);" ] }, { "cell_type": "code", "execution_count": 127, "metadata": {}, "outputs": [ { "data": { "application/vnd.francy+json": "{\"version\" : \"1.2.3\",\"mime\" : \"application\\/vnd.francy+json\",\"canvas\" : {\"width\" : 800,\"id\" : \"F52\",\"height\" : 450,\"title\" : \"Example Undirected Graph\",\"zoomToFit\" : true,\"texTypesetting\" : false,\"menus\" : {},\"graph\" : {\"type\" : \"undirected\",\"id\" : \"F53\",\"simulation\" : true,\"collapsed\" : true,\"nodes\" : {\"F54\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F54\",\"size\" : 10,\"title\" : \"G\",\"layer\" : 1,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}},\"F55\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F55\",\"size\" : 10,\"title\" : \"1\",\"layer\" : 2,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}}},\"links\" : {\"F56\" : {\"id\" : \"F56\",\"source\" : \"F54\",\"length\" : 0,\"weight\" : 0,\"target\" : \"F55\",\"color\" : \"\",\"invisible\" : false}}},\"messages\" : {}}}" }, "execution_count": 127, "metadata": { "application/vnd.francy+json": {} }, "output_type": "execute_result" } ], "source": [ "canvas8 := Canvas(\"Example Undirected Graph\");;\n", "SetHeight(canvas8, 450);;\n", "\n", "graph := Graph(GraphType.UNDIRECTED);;\n", "\n", "shape := Shape(ShapeType.CIRCLE, \"G\");;\n", "SetLayer(shape, 1);;\n", "shape1 := Shape(ShapeType.CIRCLE, \"1\");;\n", "SetLayer(shape1, 2);;\n", "Add(graph, shape);;\n", "Add(graph, shape1);;\n", "\n", "link := Link(shape, shape1);;\n", "Add(graph, link);;\n", "\n", "Add(canvas8, graph);;\n", "\n", "Draw(canvas8);" ] }, { "cell_type": "code", "execution_count": 151, "metadata": {}, "outputs": [ { "data": { "application/vnd.francy+json": "{\"version\" : \"1.2.3\",\"mime\" : \"application\\/vnd.francy+json\",\"canvas\" : {\"width\" : 800,\"id\" : \"F57\",\"height\" : 450,\"title\" : \"Example Multiple Shapes Graph\",\"zoomToFit\" : true,\"texTypesetting\" : false,\"menus\" : {},\"graph\" : {\"type\" : \"undirected\",\"id\" : \"F58\",\"simulation\" : true,\"collapsed\" : true,\"nodes\" : {\"F59\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"diamond\",\"id\" : \"F59\",\"size\" : 10,\"title\" : \"G\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}},\"F60\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"wye\",\"id\" : \"F60\",\"size\" : 10,\"title\" : \"1\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}},\"F61\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"square\",\"id\" : \"F61\",\"size\" : 10,\"title\" : \"SG1\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}},\"F63\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"triangle\",\"id\" : \"F63\",\"size\" : 10,\"title\" : \"SG2\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}},\"F66\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"cross\",\"id\" : \"F66\",\"size\" : 10,\"title\" : \"SG3\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}},\"F69\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"star\",\"id\" : \"F69\",\"size\" : 10,\"title\" : \"SG4\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}}},\"links\" : {\"F62\" : {\"id\" : \"F62\",\"source\" : \"F59\",\"length\" : 0,\"weight\" : 0,\"target\" : \"F61\",\"color\" : \"\",\"invisible\" : false},\"F64\" : {\"id\" : \"F64\",\"source\" : \"F61\",\"length\" : 0,\"weight\" : 0,\"target\" : \"F63\",\"color\" : \"\",\"invisible\" : false},\"F65\" : {\"id\" : \"F65\",\"source\" : \"F63\",\"length\" : 0,\"weight\" : 0,\"target\" : \"F60\",\"color\" : \"\",\"invisible\" : false},\"F67\" : {\"id\" : \"F67\",\"source\" : \"F61\",\"length\" : 0,\"weight\" : 0,\"target\" : \"F66\",\"color\" : \"\",\"invisible\" : false},\"F68\" : {\"id\" : \"F68\",\"source\" : \"F66\",\"length\" : 0,\"weight\" : 0,\"target\" : \"F60\",\"color\" : \"\",\"invisible\" : false},\"F70\" : {\"id\" : \"F70\",\"source\" : \"F61\",\"length\" : 0,\"weight\" : 0,\"target\" : \"F69\",\"color\" : \"\",\"invisible\" : false},\"F71\" : {\"id\" : \"F71\",\"source\" : \"F69\",\"length\" : 0,\"weight\" : 0,\"target\" : \"F60\",\"color\" : \"\",\"invisible\" : false}}},\"messages\" : {}}}" }, "execution_count": 151, "metadata": { "application/vnd.francy+json": {} }, "output_type": "execute_result" } ], "source": [ "canvas9 := Canvas(\"Example Multiple Shapes Graph\");;\n", "SetHeight(canvas9, 450);;\n", "\n", "graph := Graph(GraphType.UNDIRECTED);;\n", "\n", "shapeG := Shape(ShapeType.DIAMOND, \"G\");;\n", "Add(graph, shapeG);;\n", "shape1 := Shape(ShapeType.WYE, \"1\");;\n", "Add(graph, shape1);;\n", "\n", "shapeSG1 := Shape(ShapeType.SQUARE, \"SG1\");;\n", "Add(graph, shapeSG1);;\n", "Add(graph, Link(shapeG, shapeSG1));;\n", "\n", "shapeSG2 := Shape(ShapeType.TRIANGLE, \"SG2\");;\n", "Add(graph, shapeSG2);;\n", "Add(graph, Link(shapeSG1, shapeSG2));;\n", "Add(graph, Link(shapeSG2, shape1));;\n", "\n", "shapeSG3 := Shape(ShapeType.CROSS, \"SG3\");;\n", "Add(graph, shapeSG3);;\n", "Add(graph, Link(shapeSG1, shapeSG3));;\n", "Add(graph, Link(shapeSG3, shape1));;\n", "\n", "shapeSG4 := Shape(ShapeType.STAR, \"SG4\");;\n", "Add(graph, shapeSG4);;\n", "Add(graph, Link(shapeSG1, shapeSG4));;\n", "Add(graph, Link(shapeSG4, shape1));;\n", "\n", "Add(canvas9, graph);;\n", "\n", "Draw(canvas9);" ] }, { "cell_type": "code", "execution_count": 168, "metadata": {}, "outputs": [ { "data": { "application/vnd.francy+json": "{\"version\" : \"1.2.3\",\"mime\" : \"application\\/vnd.francy+json\",\"canvas\" : {\"width\" : 800,\"id\" : \"F72\",\"height\" : 450,\"title\" : \"Example Tree Graph\",\"zoomToFit\" : true,\"texTypesetting\" : false,\"menus\" : {},\"graph\" : {\"type\" : \"tree\",\"id\" : \"F73\",\"simulation\" : true,\"collapsed\" : false,\"nodes\" : {\"F74\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F74\",\"size\" : 10,\"title\" : \"G\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"F75\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}},\"F75\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"square\",\"id\" : \"F75\",\"size\" : 10,\"title\" : \"1\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}},\"F76\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F76\",\"size\" : 10,\"title\" : \"SG1\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"F74\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}},\"F77\" : {\"x\" : 0,\"y\" : 0,\"type\" : \"circle\",\"id\" : \"F77\",\"size\" : 10,\"title\" : \"SG2\",\"layer\" : 0,\"color\" : \"\",\"parent\" : \"F74\",\"menus\" : {},\"messages\" : {},\"callbacks\" : {}}},\"links\" : {}},\"messages\" : {}}}" }, "execution_count": 168, "metadata": { "application/vnd.francy+json": {} }, "output_type": "execute_result" } ], "source": [ "canvas10 := Canvas(\"Example Tree Graph\");;\n", "SetHeight(canvas10, 450);;\n", "\n", "graph := Graph(GraphType.TREE);;\n", "SetCollapsed(graph, false);;\n", "\n", "shapeG := Shape(ShapeType.CIRCLE, \"G\");;\n", "Add(graph, shapeG);;\n", "\n", "shape1 := Shape(ShapeType.SQUARE, \"1\");;\n", "Add(graph, shape1);;\n", "\n", "shapeSG1 := Shape(ShapeType.CIRCLE, \"SG1\");;\n", "Add(graph, shapeSG1);;\n", "\n", "shapeSG2 := Shape(ShapeType.CIRCLE, \"SG2\");;\n", "Add(graph, shapeSG2);;\n", "\n", "\n", "SetParentShape(shapeG, shape1);;\n", "SetParentShape(shapeSG1, shapeG);;\n", "SetParentShape(shapeSG2, shapeG);;\n", "\n", "Add(canvas10, graph);;\n", "\n", "Draw(canvas10);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Charts\n", "\n", "Charts are another graphical way to represent data.\n", "\n", "Supported ChartTypes:\n", "\n", "* ChartType.LINE\n", "* ChartType.BAR\n", "* ChartType.SCATTER\n", "\n", "By default, Chart are created with default options set to:\n", "\n", "* ChartDefaults.labels [true]\n", "* ChartDefaults.legend [true]\n", "\n", "## How to create Charts?\n", "\n", "Let's see how to create a Chart of each type, starting with the LINE. LINE Charts don't support providing a custom domain, this needs more work!\n", "\n", "```gap\n", "gap> chart := Chart(ChartType.LINE);\n", "gap> SetAxisXTitle(chart, \"X Axis\");\n", "gap> SetAxisYTitle(chart, \"Y Axis\");\n", "\n", "gap> data1 := Dataset(\"data1\", [100,20,30,47,90]);\n", "gap> data2 := Dataset(\"data2\", [51,60,72,38,97]);\n", "gap> data3 := Dataset(\"data3\", [50,60,70,80,90]);\n", "\n", "gap> Add(chart, [data1, data2, data3]);\n", "```\n", "\n", "The same data in a Bar Chart:\n", "\n", "```gap\n", "gap> chart := Chart(ChartType.BAR);\n", "gap> SetAxisXTitle(chart, \"X Axis\");\n", "gap> SetAxisXDomain(chart, [\"domain1\", \"domain2\", \"domain3\", \"domain4\", \"domain5\"]);\n", "gap> SetAxisYTitle(chart, \"Y Axis\");\n", "\n", "gap> data1 := Dataset(\"data1\", [100,20,30,47,90]);\n", "gap> data2 := Dataset(\"data2\", [51,60,72,38,97]);\n", "gap> data3 := Dataset(\"data3\", [50,60,70,80,90]);\n", "\n", "gap> Add(chart, [data1, data2, data3]);\n", "```\n", "\n", "Same data in a SCATTER Chart:\n", "\n", "\n", "```gap\n", "gap> chart := Chart(ChartType.SCATTER);\n", "gap> SetAxisXTitle(chart, \"X Axis\");\n", "gap> SetAxisYTitle(chart, \"Y Axis\");\n", "\n", "gap> data1 := Dataset(\"data1\", [100,20,30,47,90]);\n", "gap> data2 := Dataset(\"data2\", [51,60,72,38,97]);\n", "gap> data3 := Dataset(\"data3\", [50,60,70,80,90]);\n", "\n", "gap> Add(chart, [data1, data2, data3]);\n", "```\n", "\n", "**NOTE: Charts need more work in general**" ] }, { "cell_type": "code", "execution_count": 179, "metadata": {}, "outputs": [ { "data": { "application/vnd.francy+json": "{\"version\" : \"1.2.3\",\"mime\" : \"application\\/vnd.francy+json\",\"canvas\" : {\"width\" : 800,\"id\" : \"F78\",\"height\" : 400,\"title\" : \"Example Line Chart\",\"zoomToFit\" : true,\"texTypesetting\" : false,\"menus\" : {},\"chart\" : {\"type\" : \"line\",\"data\" : {\"data1\" : [\"100\",\"20\",\"30\",\"47\",\"90\"],\"data2\" : [\"51\",\"60\",\"72\",\"38\",\"97\"],\"data3\" : [\"50\",\"60\",\"70\",\"80\",\"90\"]},\"id\" : \"F79\",\"showLegend\" : true,\"axis\" : {\"x\" : {\"domain\" : [],\"title\" : \"X Axis\",\"scale\" : \"linear\"},\"y\" : {\"domain\" : [],\"title\" : \"Y Axis\",\"scale\" : \"linear\"}}},\"messages\" : {}}}" }, "execution_count": 179, "metadata": { "application/vnd.francy+json": {} }, "output_type": "execute_result" } ], "source": [ "canvas11 := Canvas(\"Example Line Chart\");;\n", "SetHeight(canvas11, 400);;\n", "\n", "chart := Chart(ChartType.LINE);;\n", "SetAxisXTitle(chart, \"X Axis\");;\n", "SetAxisYTitle(chart, \"Y Axis\");;\n", "\n", "data1 := Dataset(\"data1\", [100,20,30,47,90]);;\n", "data2 := Dataset(\"data2\", [51,60,72,38,97]);;\n", "data3 := Dataset(\"data3\", [50,60,70,80,90]);;\n", "\n", "Add(chart, [data1, data2, data3]);;\n", "Add(canvas11, chart);;\n", "\n", "Draw(canvas11);" ] }, { "cell_type": "code", "execution_count": 191, "metadata": {}, "outputs": [ { "data": { "application/vnd.francy+json": "{\"version\" : \"1.2.3\",\"mime\" : \"application\\/vnd.francy+json\",\"canvas\" : {\"width\" : 800,\"id\" : \"F80\",\"height\" : 400,\"title\" : \"Example Bar Chart\",\"zoomToFit\" : true,\"texTypesetting\" : false,\"menus\" : {},\"chart\" : {\"type\" : \"bar\",\"data\" : {\"data1\" : [\"100\",\"20\",\"30\",\"47\",\"90\"],\"data2\" : [\"51\",\"60\",\"72\",\"38\",\"97\"],\"data3\" : [\"50\",\"60\",\"70\",\"80\",\"90\"]},\"id\" : \"F81\",\"showLegend\" : true,\"axis\" : {\"x\" : {\"domain\" : [\"domain1\",\"domain2\",\"domain3\",\"domain4\",\"domain5\"],\"title\" : \"X Axis\",\"scale\" : \"band\"},\"y\" : {\"domain\" : [],\"title\" : \"Y Axis\",\"scale\" : \"linear\"}}},\"messages\" : {}}}" }, "execution_count": 191, "metadata": { "application/vnd.francy+json": {} }, "output_type": "execute_result" } ], "source": [ "canvas12 := Canvas(\"Example Bar Chart\");;\n", "SetHeight(canvas12, 400);;\n", "\n", "chart := Chart(ChartType.BAR);;\n", "SetAxisXTitle(chart, \"X Axis\");;\n", "SetAxisXDomain(chart, [\"domain1\", \"domain2\", \"domain3\", \"domain4\", \"domain5\"]);;\n", "SetAxisYTitle(chart, \"Y Axis\");;\n", "\n", "data1 := Dataset(\"data1\", [100,20,30,47,90]);;\n", "data2 := Dataset(\"data2\", [51,60,72,38,97]);;\n", "data3 := Dataset(\"data3\", [50,60,70,80,90]);;\n", "\n", "Add(chart, [data1, data2, data3]);;\n", "Add(canvas12, chart);;\n", "\n", "Draw(canvas12);" ] }, { "cell_type": "code", "execution_count": 202, "metadata": {}, "outputs": [ { "data": { "application/vnd.francy+json": "{\"version\" : \"1.2.3\",\"mime\" : \"application\\/vnd.francy+json\",\"canvas\" : {\"width\" : 800,\"id\" : \"F82\",\"height\" : 400,\"title\" : \"Example Scatter Chart\",\"zoomToFit\" : true,\"texTypesetting\" : false,\"menus\" : {},\"chart\" : {\"type\" : \"scatter\",\"data\" : {\"data1\" : [\"100\",\"20\",\"30\",\"47\",\"90\"],\"data2\" : [\"51\",\"60\",\"72\",\"38\",\"97\"],\"data3\" : [\"50\",\"60\",\"70\",\"80\",\"90\"]},\"id\" : \"F83\",\"showLegend\" : true,\"axis\" : {\"x\" : {\"domain\" : [],\"title\" : \"X Axis\",\"scale\" : \"linear\"},\"y\" : {\"domain\" : [],\"title\" : \"Y Axis\",\"scale\" : \"linear\"}}},\"messages\" : {}}}" }, "execution_count": 202, "metadata": { "application/vnd.francy+json": {} }, "output_type": "execute_result" } ], "source": [ "canvas13 := Canvas(\"Example Scatter Chart\");;\n", "SetHeight(canvas13, 400);;\n", "\n", "chart := Chart(ChartType.SCATTER);;\n", "SetAxisXTitle(chart, \"X Axis\");;\n", "SetAxisYTitle(chart, \"Y Axis\");;\n", "\n", "data1 := Dataset(\"data1\", [100,20,30,47,90]);;\n", "data2 := Dataset(\"data2\", [51,60,72,38,97]);;\n", "data3 := Dataset(\"data3\", [50,60,70,80,90]);;\n", "\n", "Add(chart, [data1, data2, data3]);;\n", "Add(canvas13, chart);;\n", "\n", "Draw(canvas13);" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "GAP 4", "language": "gap", "name": "gap-4" }, "language_info": { "codemirror_mode": "gap", "file_extension": ".g", "mimetype": "text/x-gap", "name": "GAP 4", "nbconvert_exporter": "", "pygments_lexer": "gap", "version": "4.dev" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 2 }