menu

Display, colours, and UI

Setting up colours maps:

In Cacatoo, the "state" of grid points (i.e. the properties of individuals) are linked to colours by setting up a colour map.

In this map, state-colour pairs are stored, where a state can be:
  • whole numbers (e.g. '0' or '1' for dead and living individuals),
  • real numbers (e.g. 5.0 for the 'uptake rate' of cells in a colony),
  • the names of species (e.g. 'predator' and 'prey')
A colour can be:
  • The name of one of the default colours in Cacatoo (see colour table),
  • An array of length 3 with RGB values (e.g. [255,0,0] for red),
  • A hexadecimal color code (e.g. #00FF00 for green),

Default colour map:

0: black
1: white
2: red
3: blue
4: green
5: darkgrey
6: lightgrey
7: violet
8: turquoise
9: orange
10: gold
11: grey
12: yellow
13: cyan
14: silver
15: darkgreen
16: olive
17: teal
18: navy

To avoid users having to define colours manually, a set of useful functions is provided to link states to either default colours (see colour table), random colours, or colour gradients. Firstly, one can assign colours directly in the configuration file by assigning a property 'default', 'random', 'inferno', or 'viridis'. For example, to generate 50 random colours:
    // generate 50 random colours
    let config = {
    title="MyModel",
    ncol:100,
    nrow:100,
    num_colours: 50,
    statecolours: { colour: 'random' }
    }
One can also each state-colour pair individually:
    let config = {
    title="MyModel",
    ncol:100,
    nrow:100,
    statecolours: { colour:
    1: 'red',
    2: '#EE00FF',
    3: [0,0,145], ...
    }
    }
Colour gradients can also be manually defined by using one of the following functions:
sim.model.colourGradient(statename, num_colours, array_1, array_2, ..., array_n)
sim.model.colourVidiris(statename, num_colours)

Which is for example done in the example "ode_lotka.html"
sim.lotka.colourGradient('numpred', 200, [0, 0, 0], [240, 200, 0])

Once the colour maps have been set up, it is time to set up the display.

Setting up a display for (simple) discrete states:

After having set up your colours for a certain property (e.g. 'alive' in Game of Life), a display can be added like this:
sim.createDisplay(name_of_gridmodel, property, title)

Which is for example done in the example "cheater.js"
sim.createDisplay("cheater", "species", "Mutualists and cheater")

Setting up a display for continuous variables:

Because setting up a display can sometimes have many more parameters, one can instead passes a configuration object (much like how the simulation is configured), as seen in the example "ode_turing.html":
sim.turing.colourViridis("activator",100)
sim.createDisplay_continuous({model:"turing", property:"activator", label:"Activator density", minval:0, maxval:100})

Or you can combine these two line by passing a "fill" to the last function:
sim.createDisplay_continuous({model:"turing", property:"activator", label:"Activator density", minval:0, maxval:100, num_colours: 100, fill:"viridis", na_colour: 'black'})

You can also draw dots, instead of pixels:
sim.createDisplay_continuous({model:"turing", property:"activator", label:"Activator density", minval:0, maxval:100, num_colours: 100, fill:"viridis", na_colour: 'black', drawdots:true, stroke:true, strokeStyle: 'yellow', strokeWidth: 2, radius:"internal_resources", min_radius: 1, max_radius:6, scale_radius: 5})

This way of setting up displays also works for discrete variables, like in Game of Life:
sim.createDisplay_discrete({model:"gol",property:"alive",label:"Game of life (white=alive)",drawdots:true,radius:5})

Setting up space-time plot:

A space-time plot allows you to track how your grid changes over time. A single column (y-axis) from the original grid is plotted for each time point (on the x-axis).
sim.spaceTimePlot(gridmodel, name_of_original_grid, name_of_spacetime_grid, which_column, width)

Which is for example done in the example "spirals.html"
sim.spaceTimePlot("spirals", "Colours represent different species", "Space-time plot", 100, sim.ncol*2)

Adding UI elements

Interactive graphs

Cacatoo uses the dygraphs library to plot interactive graphs. Because these graphs are updated every time step, they need to be placed in the update loop (see for example the cheater.js example), where we use:
plotPopsizes(property_to_count, values_to_count)
plotArray([group_labels], [group_values], [group_colours], plot_title, {dygraph_options})
plotXY([group_labels], [group_values], [group_colours], plot_title, {dygraph_options})
plotPoints(array_with_values, title, {dygraph_options})

To manipulate what the graph looks like, you pass an object with dygraphs options:
let graph_opts = { width: 1000, heigh:300, strokeWidth: 2, drawPoints: true, strokePattern: [1,2]}



Buttons and sliders:

addSlider(name_of_var)
addButton("button_text", function)
addCustomSlider(label,function, min = 0.0, max = 2.0, step = 0.01, default_value=0)
addPatternButton(model, property_to_set) // Note: needs a live server to be run for browser security reasons




Painting on the grid:

To add the ability to paint on the grid (which can be surprisingly useful for debugging), use the following functions:
addStatebrush(gridmodel, property_to_change, value_to_put, brushsize, [brushflow, canvas])
addObjectbrush(gridmodel, object_to_draw, brushsize, [brushflow, canvas])

The 'brushflow' and 'canvas' arguments are optional. Brushflow allows you to draw smoother lines when the framerate is limiting, with high numbers meaning more smooth drawing (at the cost of performance). By default, the first canvas of the gridmodel will be used to draw on, but you can also pass the name of another canvas.

Use cases: for example in 01_beginner/spiral.html, 02_advanced/petridish_dot.html, and 04_even_more_examples/consumer_resource.html



Parse variable from URL

You can also use javascript to read variables from the address bar. This can be userful if you want to share your model with specific parameters.
var mixed = false
var url_query = {}
location.search.substr(1).split("&").forEach(function (item) { url_query[item.split("=")[0]] = item.split("=")[1] })
if (url_query.mixed) mixed=true




CustomHTML

Finally, you can add some custom HTML stuff to one of the Cacatoo divs ('form_holder', 'graph_holder', 'canvas_holder'):
addHTML("div_name", "html")