Source code for mesa.visualization.modules.ChartVisualization

"""
Chart Module
============

Module for drawing live-updating line charts using Charts.js
"""
import json

from mesa.visualization.ModularVisualization import CHART_JS_FILE, VisualizationElement


[docs]class ChartModule(VisualizationElement): """Each chart can visualize one or more model-level series as lines with the data value on the Y axis and the step number as the X axis. At the moment, each call to the render method returns a list of the most recent values of each series. Attributes: series: A list of dictionaries containing information on series to plot. Each dictionary must contain (at least) the "Label" and "Color" keys. The "Label" value must correspond to a model-level series collected by the model's DataCollector, and "Color" must have a valid HTML color. canvas_height, canvas_width: The width and height to draw the chart on the page, in pixels. Default to 200 x 500 data_collector_name: Name of the DataCollector object in the model to retrieve data from. template: "chart_module.html" stores the HTML template for the module. Example: schelling_chart = ChartModule([{"Label": "happy", "Color": "Black"}], data_collector_name="datacollector") TODO: Have it be able to handle agent-level variables as well. More Pythonic customization; in particular, have both series-level and chart-level options settable in Python, and passed to the front-end the same way that "Color" is currently. """ package_includes = [CHART_JS_FILE, "ChartModule.js"] def __init__( self, series, canvas_height=200, canvas_width=500, data_collector_name="datacollector", ): """ Create a new line chart visualization. Args: series: A list of dictionaries containing series names and HTML colors to chart them in, e.g. [{"Label": "happy", "Color": "Black"},] canvas_height, canvas_width: Size in pixels of the chart to draw. data_collector_name: Name of the DataCollector to use. """ self.series = series self.canvas_height = canvas_height self.canvas_width = canvas_width self.data_collector_name = data_collector_name series_json = json.dumps(self.series) new_element = "new ChartModule({}, {}, {})" new_element = new_element.format(series_json, canvas_width, canvas_height) self.js_code = "elements.push(" + new_element + ");"
[docs] def render(self, model): current_values = [] data_collector = getattr(model, self.data_collector_name) for s in self.series: name = s["Label"] try: val = data_collector.model_vars[name][-1] # Latest value except (IndexError, KeyError): val = 0 current_values.append(val) return current_values