Agent-based modeling in JavaScript in the browser or on the server. [v0.5.19]



In addition to rendering agents in an environment themselves, you might want to visualize aggregate data, such as average values across agents or maximum or minimum values. The flocc.LineChartRenderer class (from here on, just LineChartRenderer) allows you to display data about the agents in an environment over time, instead of representing the agents themselves.


LineChartRenderer requires an Environment to render, as well as a DOM element in which to mount, and at least one metric (key of agent data to visualize):

const environment = new Environment();
const chart = new LineChartRenderer(environment);
chart.metric('x', { color: 'green' });
chart.metric('y', { color: 'blue' });


LineChartRenderer can also be instantiated with configuration options, which affect the output.

const opts = {
    autoScale: boolean = false,
    autoScroll: boolean = false,
    background: string = 'transparent',
    height: number = 500,
    width: number = 500,
    range: {
      max: number = 1,
      min: number = 0
const chart = new LineChartRenderer(environment, opts);

width / height

The width and height (in pixels) of the chart. Defaults to 500 each.


If set to true, the chart will attempt to fit any data that goes out-of-bounds (vertically above or below the given range, or horizontally beyond the width of the chart) and will dynamically resize the existing visualization to fit all lines in the bounds of the chart.
Although setting autoScale to true will initially respect the range values, it will resize the chart and update this range if necessary.


If set to true, any data that would go out-of-bound horizontally (as time passes) will push the earliest data off to the left, resulting in a horizontally scrolling view of the data.
If both autoScale and autoScroll are set to true, then the chart will only scale vertically (for data above or below the given range) and will respect the horizontally scrolling view of the data.


The background color of the chart. Defaults to a transparent background. Can be a color name ("gray""pink"), a hex value ("#eee""#ffe2e2"), or an rgb string ("rgb(255, 200, 220)").


An object with min and max keys whose values are numbers corresponding to the what range values should be drawn on the chart. Defaults to { min: 0, max: 1 }.


.mount(selector or element, opts)

Calling .mount specifies where on the page the chart should be drawn. If passed a CSS selector (like #id or .class), it will look for the first matching element on the page, and use that as a container. If passed an element directly, it will use that element as a container.

<div id="some-element"></div>
// or...
const element = document.getElementById('some-element');

.metric(key, opts)

Calling .metric adds a metric to the line chart to be visualized over time. The required key parameter should match the key on the agent data you would like to visualize. For example, if you are trying to visualize the average age of agents, and each agent has a age key-value pair, you would call this:


Then, with every tick of the environment, the chart will update to show the average age of all agents.
You can also pass in options to customize the visual display of the metric. The default options look like this:

const opts = {
  color: 'black',
  fn: flocc.utils.mean

color: Determines the color of the line drawn. Defaults to a black line. Can be a color name ("gray""pink"), a hex value ("#eee""#ffe2e2"), or an rgb string ("rgb(255, 200, 220)").
fn: A function that determines the value to be displayed for the metric. Any function that takes an array of numbers (corresponding to the values for all the agents with the metric’s key-value pair) and returns a single number will work. Defaults to utils.mean. Other utility functions that can be used are utils.medianutils.sumutils.stdDevutils.min, and utils.max.
In addition to the above utility functions, you could also write a custom function to visualize aggregate agent data. For example, to visualize the number of agents with a size value over 50, you could use the following:

chart.metric('size', {
  fn: arr => {
    return arr.filter(size => size > 50).length;