  
  [1X3 [33X[0;0YUsing the low-level API[133X[101X
  
  
  [1X3.1 [33X[0;0YThe [10XCreateVisualization[110X[101X[1X function[133X[101X
  
  [33X[0;0YThe low-level API is accessed through just one function, [2XCreateVisualization[102X
  ([14X7.2-5[114X).  You  can view its complete documentation in the function reference
  in Chapter [14X7[114X, but examples are given in this chapter.[133X
  
  [33X[0;0YNearly  all  visualizations  in  this  package are created by passing to the
  [2XCreateVisualization[102X  ([14X7.2-5[114X)  function records describing what to draw. Even
  visualizations  created  by  the high-level API documented in Chapter [14X2[114X call
  the  [2XCreateVisualization[102X  ([14X7.2-5[114X) function under the hood. Those records are
  converted  into  JSON  ([7Xhttp://www.json.org/[107X)  form by the [5Xjson[105X package, and
  handed  to  whichever JavaScript toolkit you have chosen to use for creating
  the  visualization (or the default tool if you use a high-level function and
  do not specify).[133X
  
  [33X[0;0YThe   sections   below   describe  how  to  communicate  with  each  of  the
  visualization  tools this package makes available, using [2XCreateVisualization[102X
  ([14X7.2-5[114X).[133X
  
  
  [1X3.2 [33X[0;0YLooking beneath the high-level API[133X[101X
  
  [33X[0;0YThere  are  a few techniques for taking a call to the high-level API (either
  to  [2XPlot[102X  ([14X7.1-1[114X) or [2XPlotGraph[102X ([14X7.1-3[114X)) and computing what data it eventally
  passes  to  [2XCreateVisualization[102X  ([14X7.2-5[114X). This is a great starting point for
  learning  the  data  formats  that  [2XCreateVisualization[102X  ([14X7.2-5[114X) expects, in
  preparation for either tweaking them or creating them from scratch. We cover
  two examples here.[133X
  
  
  [1X3.2-1 [33X[0;0YLooking beneath [10XPlot[110X[101X[1X[133X[101X
  
  [33X[0;0YAssume  that  you  have a plot that you're creating with the high-level API,
  like the following example.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28XPlot( x -> x^0.5, rec( tool := "canvasjs" ) );[128X[104X
  [4X[32X[104X
  
  [33X[0;0YYou  can  find  out  what  kind  of data is being passed, under the hood, to
  [2XCreateVisualization[102X ([14X7.2-5[114X) by running the following code.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28XdataSeries := JUPVIZMakePlotDataSeries( x -> x^0.5 );;[128X[104X
    [4X[28Xbig := ConvertDataSeriesForTool.canvasjs( [ dataSeries ] );[128X[104X
    [4X[28X# The result is the following GAP record:[128X[104X
    [4X[28X# rec([128X[104X
    [4X[28X#     animationEnabled := true,[128X[104X
    [4X[28X#     data := [[128X[104X
    [4X[28X#         rec([128X[104X
    [4X[28X#             dataPoints := [[128X[104X
    [4X[28X#                 rec( x := 1, y := 1 ),[128X[104X
    [4X[28X#                 rec( x := 2, y := 1.4142135623730951 ),[128X[104X
    [4X[28X#                 rec( x := 3, y := 1.7320508075688772 ),[128X[104X
    [4X[28X#                 rec( x := 4, y := 2. ),[128X[104X
    [4X[28X#                 rec( x := 5, y := 2.2360679774997898 )[128X[104X
    [4X[28X#             ],[128X[104X
    [4X[28X#             type := "line"[128X[104X
    [4X[28X#         )[128X[104X
    [4X[28X#     ],[128X[104X
    [4X[28X#     height := 400[128X[104X
    [4X[28X# )[128X[104X
  [4X[32X[104X
  
  [33X[0;0YThat  record  is  passed to [2XCreateVisualization[102X ([14X7.2-5[114X) with a call like the
  following.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28XCreateVisualization( rec( tool := "canvasjs", data := big ) );[128X[104X
  [4X[32X[104X
  
  [33X[0;0YIf  you  wanted  to  change any of the internal options, such as the default
  [10XanimationEnabled  :=  true[110X or the default [10Xheight := 400[110X, you could alter the
  record yourself before passing it on to [2XCreateVisualization[102X ([14X7.2-5[114X).[133X
  
  [33X[0;0YSuch  options  may  be  specific  to  the  tool  you've  chosen, and are not
  guaranteed  to  work  with  other  tools.  For  example,  you  can't  change
  [10X"canvasjs"[110X  to  [10X"anychart"[110X  and expect the [10XanimationEnabled[110X setting to work,
  because it is specific to CanvasJS. See Section [14X3.4[114X for links to each tool's
  documentation, which give detailed data formats.[133X
  
  [33X[0;0YIf  you  had  researched  other options about CanvasJS and wanted to include
  those, you could do so as well, as shown below.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28Xbig.animationEnabled := false;;     # changing an option[128X[104X
    [4X[28Xbig.height := 500;;                 # changing an option[128X[104X
    [4X[28Xbig.backgroundColor := "#F5DEB3";;  # adding an option[128X[104X
    [4X[28XCreateVisualization( rec( tool := "canvasjs", data := big ) );[128X[104X
  [4X[32X[104X
  
  [33X[0;0YResulting image not shown here.[133X
  
  
  [1X3.2-2 [33X[0;0YLooking beneath [10XPlotGraph[110X[101X[1X[133X[101X
  
  [33X[0;0YIn  the  previous  section, we saw how you could take a call to [2XPlot[102X ([14X7.1-1[114X)
  and  find out what data that call would pass to [2XCreateVisualization[102X ([14X7.2-5[114X).
  You can do the same with [2XPlotGraph[102X ([14X7.1-3[114X), but it takes a few more steps.[133X
  
  [33X[0;0YFirst, we you must have a list of your graph's vertices. Here we will assume
  it  is  in  a variable called [10Xvertices[110X. Second, you must have a list of your
  graph's edges. Similarly, we will assume it is in a variable called [10Xedges[110X.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28Xvertices := [ 1, 2, 3, 4 ];[128X[104X
    [4X[28Xedges := [ [ 1, 2 ], [ 2, 3 ], [ 2, 4 ] ];[128X[104X
  [4X[32X[104X
  
  [33X[0;0YYou   can   then   convert   your   graph   into   the   format   passed  to
  [2XCreateVisualization[102X  ([14X7.2-5[114X)  as  follows.  Note  that  at  the time of this
  writing,  there  is  only one graph visualization tool, cytoscape, so we use
  that one directly.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28Xbig := ConvertGraphForTool.cytoscape( rec([128X[104X
    [4X[28X    vertices := vertices,[128X[104X
    [4X[28X    edges := edges,[128X[104X
    [4X[28X    options := rec() # or any options you like here[128X[104X
    [4X[28X) );[128X[104X
    [4X[28X# The result is the following GAP record:[128X[104X
    [4X[28X# rec([128X[104X
    [4X[28X#     elements := [[128X[104X
    [4X[28X#         rec( data := rec( id := "1" ) ),[128X[104X
    [4X[28X#         rec( data := rec( id := "2" ) ),[128X[104X
    [4X[28X#         rec( data := rec( id := "3" ) ),[128X[104X
    [4X[28X#         rec( data := rec( id := "4" ) ),[128X[104X
    [4X[28X#         rec( data := rec( source := "1", target := "2" ) ),[128X[104X
    [4X[28X#         rec( data := rec( source := "2", target := "3" ) ),[128X[104X
    [4X[28X#         rec( data := rec( source := "2", target := "4" ) )[128X[104X
    [4X[28X#     ],[128X[104X
    [4X[28X#     layout := rec( name := "cose" ),[128X[104X
    [4X[28X#     style := [[128X[104X
    [4X[28X#         rec([128X[104X
    [4X[28X#             selector := "node",[128X[104X
    [4X[28X#             style := rec( content := "data(id)" )[128X[104X
    [4X[28X#         )[128X[104X
    [4X[28X#     ][128X[104X
    [4X[28X# )[128X[104X
  [4X[32X[104X
  
  [33X[0;0YThat  record  is  passed to [2XCreateVisualization[102X ([14X7.2-5[114X) with a call like the
  following. Note the inclusion of a default height, if you don't provide one.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28XCreateVisualization( rec([128X[104X
    [4X[28X    tool := "cytoscape", data := big, height := 400[128X[104X
    [4X[28X) );[128X[104X
  [4X[32X[104X
  
  [33X[0;0YIf  you  wanted  to  change  any of the internal options, including creating
  elements  not  supported  by  the  simple high-level API, you could alter or
  recreate  the  contents  of the [10Xbig[110X record. We do so here, using features we
  could  learn  from the cytoscape JSON format reference, linked to in Section
  [14X3.4[114X.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28XCreateVisualization( rec([128X[104X
    [4X[28X    tool := "cytoscape",[128X[104X
    [4X[28X    height := 400,[128X[104X
    [4X[28X    data := rec([128X[104X
    [4X[28X        elements := [[128X[104X
    [4X[28X            rec( # node 1[128X[104X
    [4X[28X                group := "nodes",[128X[104X
    [4X[28X                data := rec( id := "Child1", parent := "Parent" ),[128X[104X
    [4X[28X                position := rec( x := 100, y := 100 ),[128X[104X
    [4X[28X                selected := false,[128X[104X
    [4X[28X                selectable := true,[128X[104X
    [4X[28X                locked := false,[128X[104X
    [4X[28X                grabbable := true[128X[104X
    [4X[28X            ),[128X[104X
    [4X[28X            rec( # node 2[128X[104X
    [4X[28X                data := rec( id := "Friend" ),[128X[104X
    [4X[28X                renderedPosition := rec( x := 200, y := 200 )[128X[104X
    [4X[28X            ),[128X[104X
    [4X[28X            rec( # node 3[128X[104X
    [4X[28X                data := rec( id := "Child2", parent := "Parent" ),[128X[104X
    [4X[28X                position := rec( x := 123, y := 234 )[128X[104X
    [4X[28X            ),[128X[104X
    [4X[28X            rec( # node parent[128X[104X
    [4X[28X                data := rec([128X[104X
    [4X[28X                    id := "Parent",[128X[104X
    [4X[28X                    position := rec( x := 200, y := 100 )[128X[104X
    [4X[28X                )[128X[104X
    [4X[28X            ),[128X[104X
    [4X[28X            rec( # edge 1[128X[104X
    [4X[28X                data := rec([128X[104X
    [4X[28X                    id := "Edge1",[128X[104X
    [4X[28X                    source := "Child1",[128X[104X
    [4X[28X                    target := "Friend"[128X[104X
    [4X[28X                )[128X[104X
    [4X[28X            )[128X[104X
    [4X[28X        ],[128X[104X
    [4X[28X        layout := rec( name := "preset" ),[128X[104X
    [4X[28X        style := [[128X[104X
    [4X[28X            rec([128X[104X
    [4X[28X                selector := "node",[128X[104X
    [4X[28X                style := rec( content := "data(id)" )[128X[104X
    [4X[28X            )[128X[104X
    [4X[28X        ][128X[104X
    [4X[28X    )[128X[104X
    [4X[28X) );[128X[104X
  [4X[32X[104X
  
  [33X[0;0YResulting image not shown here.[133X
  
  
  [1X3.3 [33X[0;0YUsing JSON from a file[133X[101X
  
  [33X[0;0YAs  the  documentation  cited  in  Section [14X3.4[114X states, all of the underlying
  visualization  tools  used  by  this  package accept input in JSON form. You
  might  have some data in that form generated by another source or downloaded
  from  the web. For example, in this package's directory, the file [11Xexample/EV
  Charge  Points.json[111X contains JSON data from one of the Plotly project's blog
  posts
  (
  https://medium.com/@plotlygraphs/leading-the-charge-10-charts-on-electric-vehicles-in-plotly-d951acdc49c1
  ).[133X
  
  [33X[0;0YYou can load it and use it in a visualization as follows.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28X# read file and convert JSON into a GAP record[128X[104X
    [4X[28XjsonText := ReadAll( InputTextFile( "EV Charge Points.json" ) );;[128X[104X
    [4X[28XgapRecord := JsonStringToGap( jsonText );;[128X[104X
    [4X[28X[128X[104X
    [4X[28X# ensure it's big enough to be visible:[128X[104X
    [4X[28Xif IsBound( gapRecord.layout ) then[128X[104X
    [4X[28X    gapRecord.layout.height := 500;;[128X[104X
    [4X[28Xelse[128X[104X
    [4X[28X    gapRecord.layout := rec( height := 500 );;[128X[104X
    [4X[28Xfi;[128X[104X
    [4X[28X[128X[104X
    [4X[28X# show it[128X[104X
    [4X[28XCreateVisualization( rec( tool := "plotly", data := gapRecord ) );[128X[104X
  [4X[32X[104X
  
  [33X[0;0YResulting image not shown here.[133X
  
  
  [1X3.4 [33X[0;0YDocumentation for each visualization tool[133X[101X
  
  [33X[0;0YThis  section provides links to documentation on the web for each JavaScript
  visualization  tool  supported  by  this  package.  When  possible,  we link
  directly  to  that  portion of the tool's documentation that covers its JSON
  data format requirements.[133X
  
  
  [1X3.4-1 [33X[0;0YCharting and plotting tools[133X[101X
  
  [30X    [33X[0;6Y[10Xanychart[110X's JSON data format is given here:[133X
  
        [33X[0;6Y[7Xhttps://docs.anychart.com/Working_with_Data/Data_From_JSON[107X[133X
  
  [30X    [33X[0;6Y[10Xcanvasjs[110X's JSON data format is given here:[133X
  
        [33X[0;6Y[7Xhttps://canvasjs.com/docs/charts/chart-types/[107X[133X
  
  [30X    [33X[0;6Y[10Xchartjs[110X's JSON data format is given here:[133X
  
        [33X[0;6Y[7Xhttp://www.chartjs.org/docs/latest/getting-started/usage.html[107X[133X
  
  [30X    [33X[0;6Y[10Xplotly[110X's JSON data format is given here:[133X
  
        [33X[0;6Y[7Xhttps://plot.ly/javascript/plotlyjs-function-reference/#plotlynewplot[107X[133X
  
  
  [1X3.4-2 [33X[0;0YGraph drawing tools[133X[101X
  
  [30X    [33X[0;6Y[10Xcytoscape[110X's JSON data format is given here:[133X
  
        [33X[0;6Y[7Xhttp://js.cytoscape.org/#notation/elements-json[107X[133X
  
  
  [1X3.4-3 [33X[0;0YGeneral-purpose tools for custom visualizations[133X[101X
  
  [30X    [33X[0;6Y[10Xcanvas[110X  is  a regular HTML canvas element, on which you can draw using
        arbitrary JavaScript included in the [3Xcode[103X parameter[133X
  
  [30X    [33X[0;6Y[10Xd3[110X  is  loaded  into an SVG element in the notebook's output cell, and
        the  caller  can call any D3 methods on that element thereafter, using
        arbitrary  JavaScript  included  in  the  [3Xcode[103X  parameter. It does not
        support   creating   charts   from  JSON  input  only,  but  its  full
        documentation appears here: [7Xhttps://github.com/d3/d3/wiki[107X[133X
  
  [30X    [33X[0;6Y[10Xhtml[110X  fills  the  output element with arbitrary HTML, which the caller
        should  provide  as  a string in the [10Xhtml[110X field of [3Xdata[103X, as documented
        below[133X
  
  
  [1X3.5 [33X[0;0YExample uses of the low-level API[133X[101X
  
  
  [1X3.5-1 [33X[0;0YExample: AnyChart[133X[101X
  
  [33X[0;0YFollowing  the  conventions  in  the AnyChart documentation linked to in the
  previous section, we could give AnyChart the following JSON to produce a pie
  chart.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28X{[128X[104X
    [4X[28X    "chart" : {[128X[104X
    [4X[28X        "type" : "pie",[128X[104X
    [4X[28X        "data" : [[128X[104X
    [4X[28X            { "x" : "Subgroups of order 6", "value" : 1 },[128X[104X
    [4X[28X            { "x" : "Subgroups of order 3", "value" : 1 },[128X[104X
    [4X[28X            { "x" : "Subgroups of order 2", "value" : 3 },[128X[104X
    [4X[28X            { "x" : "Subgroups of order 1", "value" : 1 }[128X[104X
    [4X[28X        ][128X[104X
    [4X[28X    }[128X[104X
    [4X[28X}[128X[104X
  [4X[32X[104X
  
  [33X[0;0YIn [5XGAP[105X, the same data would be represented with a record, as follows.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28XmyChartData := rec([128X[104X
    [4X[28X    chart := rec([128X[104X
    [4X[28X        type := "pie",[128X[104X
    [4X[28X        data := [[128X[104X
    [4X[28X            rec( x := "Subgroups of order 6", value := 1 ),[128X[104X
    [4X[28X            rec( x := "Subgroups of order 3", value := 1 ),[128X[104X
    [4X[28X            rec( x := "Subgroups of order 2", value := 3 ),[128X[104X
    [4X[28X            rec( x := "Subgroups of order 1", value := 1 )[128X[104X
    [4X[28X        ][128X[104X
    [4X[28X    )[128X[104X
    [4X[28X);[128X[104X
  [4X[32X[104X
  
  [33X[0;0YWe can pass that data directly to [2XCreateVisualization[102X ([14X7.2-5[114X). We wrap it in
  a  record  that  specifies  the tool to use and optionally other details not
  used in this example.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28XCreateVisualization( rec( tool := "anychart", data := myChartData ) );[128X[104X
  [4X[32X[104X
  
  [33X[0;0YResulting image not shown here.[133X
  
  
  [1X3.5-2 [33X[0;0YExample: Cytoscape[133X[101X
  
  [33X[0;0YUnlike  AnyChart,  which  is  for  charts  and plots, Cytoscape is for graph
  drawing.  A  tiny  Cytoscape  graph  (just  [23XA\to  B[123X)  is  represented by the
  following JSON.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28X{[128X[104X
    [4X[28X    elements : [[128X[104X
    [4X[28X        { data : { id : "A" } },[128X[104X
    [4X[28X        { data : { id : "B" } },[128X[104X
    [4X[28X        { data : { id : "edge", source : "A", target : "B" } }[128X[104X
    [4X[28X    ],[128X[104X
    [4X[28X    layout : { name : "grid", rows : 1 }[128X[104X
    [4X[28X}[128X[104X
  [4X[32X[104X
  
  [33X[0;0YCytoscape graphs can also have style attributes not shown here. Refer to its
  documentation, linked to in the previous section.[133X
  
  [33X[0;0YRather  than  copy this data directly into [5XGAP[105X, let's generate graph data in
  the  same  format  using  [5XGAP[105X  code.  Here  we  make a graph of the first 50
  positive integers, with [23Xn\to m[123X iff [23Xn\mid m[123X (ordinary integer divisibility).[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28XN := 50;[128X[104X
    [4X[28Xelements := [ ];[128X[104X
    [4X[28Xfor i in [2..N] do[128X[104X
    [4X[28X    Add( elements, rec( data := rec( id := String( i ) ) ) );[128X[104X
    [4X[28X    for j in [2..i-1] do[128X[104X
    [4X[28X        if i mod j = 0 then[128X[104X
    [4X[28X            Add( elements, rec( data := rec([128X[104X
    [4X[28X                source := String( j ),[128X[104X
    [4X[28X                target := String( i ) ) ) );[128X[104X
    [4X[28X        fi;[128X[104X
    [4X[28X    od;[128X[104X
    [4X[28Xod;[128X[104X
  [4X[32X[104X
  
  [33X[0;0YWe  then  need  to  choose  a  layout algorithm. The Cytoscape documentation
  suggests that the "cose" layout works well as a force-directed layout. Here,
  we do choose a height (in pixels) for the result, because Cytoscape does not
  automaticlly  resize visualizations to fit their containing HTML element. We
  also  set  the  style  for each node to display its ID (which is the integer
  associated with it).[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28XCreateVisualization( rec([128X[104X
    [4X[28X    tool := "cytoscape",[128X[104X
    [4X[28X    height := 600,[128X[104X
    [4X[28X    data := rec([128X[104X
    [4X[28X        elements := elements, # computed in the code above[128X[104X
    [4X[28X        layout := rec( name := "cose" ),[128X[104X
    [4X[28X        style := [[128X[104X
    [4X[28X            rec( selector := "node", style := rec( content := "data(id)" ) )[128X[104X
    [4X[28X        ][128X[104X
    [4X[28X    )[128X[104X
    [4X[28X) );[128X[104X
  [4X[32X[104X
  
  [33X[0;0YResulting image not shown here.[133X
  
