-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBorderCanvasGrid.py
More file actions
executable file
·127 lines (107 loc) · 5.48 KB
/
BorderCanvasGrid.py
File metadata and controls
executable file
·127 lines (107 loc) · 5.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"""
Modular Canvas Rendering
========================
Module for visualizing model objects in grid cells.
"""
from collections import defaultdict
from mesa.visualization.ModularVisualization import VisualizationElement
class CanvasGrid(VisualizationElement):
"""A CanvasGrid object uses a user-provided portrayal method to generate a
portrayal for each object. A portrayal is a JSON-ready dictionary which
tells the relevant JavaScript code (GridDraw.js) where to draw what shape.
The render method returns a dictionary, keyed on layers, with values as
lists of portrayals to draw. Portrayals themselves are generated by the
user-provided portrayal_method, which accepts an object as an input and
produces a portrayal of it.
A portrayal as a dictionary with the following structure:
"x", "y": Coordinates for the cell in which the object is placed.
"Shape": Can be either "circle", "rect", "arrowHead" or a custom image.
For Circles:
"r": The radius, defined as a fraction of cell size. r=1 will
fill the entire cell.
For Rectangles:
"w", "h": The width and height of the rectangle, which are in
fractions of cell width and height.
For arrowHead:
"scale": Proportion scaling as a fraction of cell size.
"heading_x": represents x direction unit vector.
"heading_y": represents y direction unit vector.
For an image:
The image must be placed in the same directory from which the
server is launched. An image has the attributes "x", "y",
"scale", "text" and "text_color".
"Color": The color to draw the shape in; needs to be a valid HTML
color, e.g."Red" or "#AA08F8"
"Filled": either "true" or "false", and determines whether the shape is
filled or not.
"Layer": Layer number of 0 or above; higher-numbered layers are drawn
above lower-numbered layers.
"text": The text to be inscribed inside the Shape. Normally useful for
showing the unique_id of the agent.
"text_color": The color to draw the inscribed text. Should be given in
conjunction of "text" property.
Attributes:
portrayal_method: Function which generates portrayals from objects, as
described above.
grid_height, grid_width: Size of the grid to visualize, in cells.
canvas_height, canvas_width: Size, in pixels, of the grid visualization
to draw on the client.
template: "canvas_module.html" stores the module's HTML template.
"""
package_includes = ["InteractionHandler.js"]
local_includes = ["BorderGridDraw.js", "BorderCanvasModule.js"]
def __init__(
self,
portrayal_method,
influence_sphere_portrayal_method,
influence_sphere_circle_portrayal_method,
grid_width,
grid_height,
canvas_width=500,
canvas_height=500,
draw_sphere_literal=False
):
"""Instantiate a new CanvasGrid.
Args:
portrayal_method: function to convert each object on the grid to
a portrayal, as described above.
grid_width, grid_height: Size of the grid, in cells.
canvas_height, canvas_width: Size of the canvas to draw in the
client, in pixels. (default: 500x500)
"""
self.portrayal_method = portrayal_method
self.influence_sphere_portrayal_method = influence_sphere_portrayal_method
self.influence_sphere_circle_portrayal_method = influence_sphere_circle_portrayal_method
self.grid_width = grid_width
self.grid_height = grid_height
self.canvas_width = canvas_width
self.canvas_height = canvas_height
self.draw_sphere_literal = draw_sphere_literal
new_element = "new CanvasModule({}, {}, {}, {})".format(
self.canvas_width, self.canvas_height, self.grid_width, self.grid_height
)
self.js_code = "elements.push(" + new_element + ");"
def render(self, model):
grid_state = { "cells": defaultdict(list),
"spheres": [],
"border": model.border_coords }
for x in range(model.grid.width):
for y in range(model.grid.height):
cell_objects = model.grid.get_cell_list_contents([(x, y)])
for obj in cell_objects:
portrayal = self.portrayal_method(obj)
if portrayal:
portrayal["x"] = x
portrayal["y"] = y
grid_state["cells"][portrayal["Layer"]].append(portrayal)
if self.draw_sphere_literal:
for influence_sphere in model.influence_spheres:
for coords_pairs in influence_sphere.coordinates:
portrayal = self.influence_sphere_portrayal_method(influence_sphere)
portrayal["x"] = coords_pairs[0]
portrayal["y"] = coords_pairs[1]
grid_state["cells"][portrayal["Layer"]].append(portrayal)
for influence_sphere in model.influence_spheres:
portrayal = self.influence_sphere_circle_portrayal_method(influence_sphere)
grid_state["spheres"].append(portrayal)
return grid_state