lib/*.gd
¶LoadPackage( "jupyterviz" );
CreateVisualization(
rec(
# put your data here, as in previous sections
),
"visualization.style.border = '5px solid black'"
)
CreateVisualization(
rec( tool := "canvas", height := 300 ),
"""
// visualization is the canvas element
var context = visualization.getContext( '2d' );
// draw an X
context.moveTo( 0, 0 );
context.lineTo( 100, 100 );
context.moveTo( 100, 0 );
context.lineTo( 0, 100 );
context.stroke();
"""
);
CreateVisualiation(
rec(
tool := "html",
data := rec(
html := "<i>Any</i> HTML can go here. Tables, buttons, whatever."
)
),
"""
// Here you could install event handlers on tools created above.
// For example, if you had created a button with id="myButton":
var button = document.getElementById( "myButton" );
button.addEventListener( "click", function () {
alert( "My button was clicked." );
} );
"""
);
runGAP( "2^100;", function ( result, error ) {
if ( result )
alert( "2^100 = " + result );
else
alert( "GAP gave this error: " + error );
} );
CreateVisualization(
rec( tool := "d3" ),
"""
// arbitrary JavaScript code can go here to interact with D3, like so:
d3.select( visualization ).append( "circle" )
.attr( "r", 50 ).attr( "cx", 55 ).attr( "cy", 55 )
.style( "stroke", "red" ).style( "fill", "pink" );
"""
);
Plot( x -> x^0.5, rec( tool := "canvasjs" ) );
dataSeries := JUPVIZMakePlotDataSeries( x -> x^0.5 );;
big := ConvertDataSeriesForTool.canvasjs( [ dataSeries ] );
# yields:
# rec(
# animationEnabled := true,
# data := [
# rec(
# dataPoints := [
# rec( x := 1, y := 1 ),
# rec( x := 2, y := 1.4142135623730951 ),
# rec( x := 3, y := 1.7320508075688772 ),
# rec( x := 4, y := 2. ),
# rec( x := 5, y := 2.2360679774997898 )
# ],
# type := "line"
# )
# ],
# height := 400
# )
CreateVisualization( rec( tool := "canvasjs", data := big ) );
big.animationEnabled := false;; # changing an option
big.height := 500;; # changing an option
big.backgroundColor := "#F5DEB3";; # adding an option
CreateVisualization( rec( tool := "canvasjs", data := big ) );
vertices := [ 1, 2, 3, 4 ];
edges := [ [ 1, 2 ], [ 2, 3 ], [ 2, 4 ] ];
big := ConvertGraphForTool.cytoscape( rec(
vertices := vertices,
edges := edges,
options := rec() # or any options you like here
) );
# yields:
# rec(
# elements := [
# rec( data := rec( id := "1" ) ),
# rec( data := rec( id := "2" ) ),
# rec( data := rec( id := "3" ) ),
# rec( data := rec( id := "4" ) ),
# rec( data := rec( source := "1", target := "2" ) ),
# rec( data := rec( source := "2", target := "3" ) ),
# rec( data := rec( source := "2", target := "4" ) )
# ],
# layout := rec( name := "cose" ),
# style := [
# rec(
# selector := "node",
# style := rec( content := "data(id)" )
# )
# ]
# )
CreateVisualization( rec(
tool := "cytoscape", data := big, height := 400
) );
CreateVisualization( rec(
tool := "cytoscape",
height := 400,
data := rec(
elements := [
rec( # node 1
group := "nodes",
data := rec( id := "Child1", parent := "Parent" ),
position := rec( x := 100, y := 100 ),
selected := false,
selectable := true,
locked := false,
grabbable := true
),
rec( # node 2
data := rec( id := "Friend" ),
renderedPosition := rec( x := 200, y := 200 )
),
rec( # node 3
data := rec( id := "Child2", parent := "Parent" ),
position := rec( x := 123, y := 234 )
),
rec( # node parent
data := rec(
id := "Parent",
position := rec( x := 200, y := 100 )
)
),
rec( # edge 1
data := rec(
id := "Edge1",
source := "Child1",
target := "Friend"
)
)
],
layout := rec( name := "preset" ),
style := [
rec(
selector := "node",
style := rec( content := "data(id)" )
)
]
)
) );
# read file and convert JSON into a GAP record
jsonText := ReadAll( InputTextFile( "EV Charge Points.json" ) );;
gapRecord := JsonStringToGap( jsonText );;
# ensure it's big enough to be visible:
if IsBound( gapRecord.layout ) then
gapRecord.layout.height := 500;;
else
gapRecord.layout := rec( height := 500 );;
fi;
# show it
CreateVisualization( rec( tool := "plotly", data := gapRecord ) );
{
"chart" : {
"type" : "pie",
"data" : [
{ "x" : "Subgroups of order 6", "value" : 1 },
{ "x" : "Subgroups of order 3", "value" : 1 },
{ "x" : "Subgroups of order 2", "value" : 3 },
{ "x" : "Subgroups of order 1", "value" : 1 }
]
}
}
myChartData := rec(
chart := rec(
type := "pie",
data := [
rec( x := "Subgroups of order 6", value := 1 ),
rec( x := "Subgroups of order 3", value := 1 ),
rec( x := "Subgroups of order 2", value := 3 ),
rec( x := "Subgroups of order 1", value := 1 )
]
)
);
CreateVisualization( rec( tool := "anychart", data := myChartData ) );
{
elements : [
{ data : { id : "A" } },
{ data : { id : "B" } },
{ data : { id : "edge", source : "A", target : "B" } }
],
layout : { name : "grid", rows : 1 }
}
N := 50;
elements := [ ];
for i in [2..N] do
Add( elements, rec( data := rec( id := String( i ) ) ) );
for j in [2..i-1] do
if i mod j = 0 then
Add( elements, rec( data := rec(
source := String( j ),
target := String( i ) ) ) );
fi;
od;
od;
CreateVisualization( rec(
tool := "cytoscape",
height := 600,
data := rec(
elements := elements, # computed in the code above
layout := rec( name := "cose" ),
style := [
rec( selector := "node", style := rec( content := "data(id)" ) )
]
)
) );
# Plot the number of small groups of order n, from n=1 to n=50:
Plot( [1..50], NrSmallGroups );
# Plot how much Andrea has been jogging lately:
Plot( ["Jan","Feb","Mar"], [46,59,61],
rec( title := "Andrea's Jogging", yaxis := "miles per month" ) );
# Plot the subgroup lattice for a small group:
G := Group((1,2),(2,3));
PlotGraph( AllSubgroups(G), IsSubgroup );
# Plot a random graph on 5 vertices:
# (The results change from one run to the next, of course.)
PlotGraph( RandomMat(5,5) );
CreateVisualization( rec(
tool := "html",
data := rec( html := "I am <i>SO</i> excited about this." )
), "console.log( 'Visualization created.' );" );
JUPVIZRunJavaScriptUsingLibraries( [ "mylib.js" ],
"alert( 'My Lib defines foo to be: ' + window.foo );" );
# Equivalently:
JUPVIZRunJavaScriptUsingLibraries( "mylib.js",
"alert( 'My Lib defines foo to be: ' + window.foo );" );
myRec := rec( height := 50, width := 50, title := rec(
text := "GAP", fontSize := 20
) );
JUPVIZRecordKeychainLookup( myRec, [ "height" ], 10 ); # = 50
JUPVIZRecordKeychainLookup( myRec, [ "width" ], 10 ); # = 50
JUPVIZRecordKeychainLookup( myRec, [ "depth" ], 10 ); # = 10
JUPVIZRecordKeychainLookup( myRec, [ "title", "text" ], "Title" ); # = "GAP"
JUPVIZRecordKeychainLookup( myRec, [ "title", "color" ], "black" ); # = "black"
JUPVIZRecordKeychainLookup( myRec, [ "one", "two", "three" ], fail ); # = fail
myRecs := [
rec( height := 50, width := 50, title := rec(
text := "GAP", fontSize := 20
) ),
rec( width := 10, depth := 10, color := "blue" )
];
JUPVIZRecordsKeychainLookup( myRecs, [ "height" ], 0 ); # = 50
JUPVIZRecordsKeychainLookup( myRecs, [ "width" ], 0 ); # = 50
JUPVIZRecordsKeychainLookup( myRecs, [ "depth" ], 0 ); # = 10
JUPVIZRecordsKeychainLookup( myRecs, [ "title", "text" ], "Title" ); # = "GAP"
JUPVIZRecordsKeychainLookup( myRecs, [ "color" ], "" ); # = "blue"
JUPVIZRecordsKeychainLookup( myRecs, [ "flavor" ], fail ); # = fail
# Trivial examples:
myRec := rec( a := 5 );
myRecs := [ rec( b := 3 ), rec( a := 6 ) ];
f := function ( x ) Print( x, "\n" ); end;
JUPVIZFetchWithDefault( myRec, myRecs, "a", 0, f ); # prints 5
JUPVIZFetchWithDefault( myRec, myRecs, "b", 0, f ); # prints 3
JUPVIZFetchWithDefault( myRec, myRecs, "c", 0, f ); # prints 0
JUPVIZFetchWithDefault( myRec, myRecs, ["a","b"], 0, f ); # prints 0
# Useful example:
JUPVIZFetchWithDefault( primaryRecord, secondaryRecordsList,
[ "options", "height" ], 400,
function ( h ) myGraphJSON.height := h; end
);
myRec := rec( a := 5 );
myRecs := [ rec( b := 3 ), rec( a := 6 ) ];
f := function ( x ) Print( x, "\n" ); end;
JUPVIZFetchIfPresent( myRec, myRecs, "a", 0, f ); # prints 5
JUPVIZFetchIfPresent( myRec, myRecs, "b", 0, f ); # prints 3
JUPVIZFetchIfPresent( myRec, myRecs, "c", 0, f ); # does nothing
JUPVIZFetchIfPresent( myRec, myRecs, ["a","b"], 0, f ); # does nothing
window.requirejs.config( {
paths : {
NEWTOOL : 'https://cdn.example.com/NEWTOOL.min.js'
}
} );
CreateVisualization( rec(
tool := "NEWTOOL",
# any other data you need goes here
) );
ConvertDataSeriesForTool.NEWTOOL := function ( series )
local result;
# Write the code here that builds the components of the
# GAP record you need, stored in result.
# You can leverage series.x, series.y, and series.options.
return result;
end;
ConvertGraphForTool.NEWTOOL := function ( graph )
local result;
# Write the code here that builds the components of the
# GAP record you need, stored in result.
# You can leverage graph.vertices, graph.edges, and graph.options.
return result;
end;
# for plots:
Plot( x -> x^2, rec( tool := "NEWTOOL" ) );
# or for graphs:
PlotGraph( RandomMat( 5, 5 ), rec( tool := "NEWTOOL" ) );
// No need to import any library from a CDN for this baby example.
window.VisualizationTools.color = function ( element, json, callback ) {
// just writes json.text in json.color, that's all
var span = document.createElement( 'span' );
span.textContent = json.text;
span.style.color = json.color;
callback( element, span );
};
CreateVisualization( rec(
tool := "color",
text := "Happy St. Patrick's Day.",
color := "green"
) );
InstallVisualizationTool( "TOOL_NAME_HERE", S );
# GAP code to install a new visualization tool:
InstallVisualizationTool( "smallExample",
"""
window.VisualizationTool.smallExample =
function ( element, json, callback ) {
element.innerHTML = '<span color=red>' + json.text + '</span>';
callback( element, element.childNodes[0] );
}
"""
) );
# GAP code to use that new visualization tool:
CreateVisualization( rec(
tool := "smallExample",
text := "This text will show up red."
) );
InstallVisualizationToolFromTemplate( "smallExample",
"""
element.innerHTML = '<span color=red>' + json.text + '</span>';
callback( element, element.childNodes[0] );
"""
) );
InstallVisualizationToolFromTemplate( "canvasjs",
"""
( new window.CanvasJS.Chart( element, json.data ) ).render();
window.resizeToShowContents( element );
callback( element, element.childNodes[0] );
""",
"https://cdnjs.cloudflare.com/ajax/libs/canvasjs/1.7.0/canvasjs.min.js"
) );
Plot( [ 6.2, 0.3, 9.1, 8.8 ] );
Plot( [ 1 .. 4 ], [ 6.2, 0.3, 9.1, 8.8 ] );
Plot( [ "Mon", "Tue", "Wed", "Thu" ], [ 6.2, 0.3, 9.1, 8.8 ] );
Plot( [ "Mon", 6.2 ], [ "Tue", 0.3 ], [ "Wed", 9.1 ], [ "Thu", 8.8 ] ] );
Plot( x -> x^0.5 );
Plot( [1..50], NrSmallGroups );
Plot( [1..50], n -> Length( DivisorsInt( n ) ),
rec(
tool := "chartjs",
title := "Number of divisors of some small integers",
xaxis := "n",
yaxis := "number of divisors of n"
)
);
# We're combining Plot( [1..50], NrSmallGroups );
# with Plot( [1..50], n -> Length( DivisorsInt( n ) ) );
# and adding some options:
Plot(
[ [1..50], NrSmallGroups,
rec( title := "Comparison", tool := "anychart" ) ],
[ [1..50], n -> Length( DivisorsInt( n ) ) ]
);
G := Group( (1,2,3,4,5,6,7), (1,2) );;
CCs := List( ConjugacyClasses( G ), Set );;
Plot(
# x values are class labels; we'll use the first element in the class
List( CCs, C -> PrintString( C[1] ) ),
# y values are class sizes; these determine the size of pie slices
List( CCs, Length ),
# ask for a pie chart with enough height that we can read the legend
rec( type := "pie", height := 500 )
);
PlotGraph( [ [ "start", "option1" ], [ "start", "option2" ],
[ "option1", "end" ], [ "option2", "end" ] ] );
PlotGraph( [ 2 .. 10 ],
[ [ 2, 4 ], [ 2, 6 ], [ 2, 8 ], [ 2, 10 ],
[ 3, 6 ], [ 3, 9 ], [ 4, 8 ], [ 5, 10 ] ] );
G := Group( (1,2,3), (1,2) );
S := function ( H, G )
return IsSubgroup( G, H ) and H <> G;
end;
PlotGraph( AllSubgroups( G ), S );
G := Group( (1,2,3), (1,2) );
S := function ( H, G )
return IsSubgroup( G, H ) and H <> G;
end;
PlotGraph( AllSubgroups( G ), S,
rec( directed := true, layout := "grid", arrowscale := 3 ) );