Skip to content

Commit

Permalink
Select size and tooltip text of nodes in D3 module
Browse files Browse the repository at this point in the history
Select size and tooltip text of nodes in D3 module and refactoring of network examples
  • Loading branch information
cauemello committed Feb 10, 2018
1 parent 6383846 commit 404ebfd
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 79 deletions.
20 changes: 9 additions & 11 deletions examples/boltzmann_wealth_model_network/wealth_model/server.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
from mesa.visualization.ModularVisualization import ModularServer
from mesa.visualization.modules import ChartModule
from mesa.visualization.UserParam import UserSettableParameter
from mesa.visualization.modules import ChartModule
from mesa.visualization.modules import NetworkModule

from .model import MoneyModel


def network_portrayal(G):
# The model ensures there is 0 or 1 agent per node

portrayal = dict()
portrayal['nodes'] = [{'id': n_id,
'agent_id': None if not n['agent'] else n['agent'][0].unique_id,
'size': 3 if n['agent'] else 1,
'color': '#CC0000' if not n['agent'] or n['agent'][0].wealth == 0 else '#007959',
'label': None if not n['agent'] else 'Agent:{} Wealth:{}'.format(n['agent'][0].unique_id,
n['agent'][0].wealth),
portrayal['nodes'] = [{'id': node_id,
'size': 3 if agents else 1,
'color': '#CC0000' if not agents or agents[0].wealth == 0 else '#007959',
'label': None if not agents else 'Agent:{} Wealth:{}'.format(agents[0].unique_id,
agents[0].wealth),
}
for n_id, n in G.nodes(data=True)]
for (node_id, agents) in G.nodes.data('agent')]

portrayal['edges'] = [{'id': i,
portrayal['edges'] = [{'id': edge_id,
'source': source,
'target': target,
'color': '#000000',
}
for i, (source, target, _) in enumerate(G.edges(data=True))]
for edge_id, (source, target) in enumerate(G.edges)]

return portrayal

Expand Down
54 changes: 23 additions & 31 deletions examples/virus_on_network/virus_on_network/server.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,48 @@
import math

from mesa.visualization.ModularVisualization import ModularServer
from mesa.visualization.modules import ChartModule
from mesa.visualization.modules import TextElement
from mesa.visualization.UserParam import UserSettableParameter
from mesa.visualization.modules import ChartModule
from mesa.visualization.modules import NetworkModule

from mesa.visualization.modules import TextElement
from .model import VirusModel, State, number_infected


def network_portrayal(G):
# The model ensures there is always 1 agent per node

def node_color(agent):
if agent.state is State.INFECTED:
return '#FF0000'
elif agent.state is State.SUSCEPTIBLE:
return '#008000'
else:
return '#808080'
return {
State.INFECTED: '#FF0000',
State.SUSCEPTIBLE: '#008000'
}.get(agent.state, '#808080')

def edge_color(agent1, agent2):
if agent1.state is State.RESISTANT or agent2.state is State.RESISTANT:
if State.RESISTANT in (agent1.state, agent2.state):
return '#000000'
return '#e8e8e8'

def edge_width(agent1, agent2):
if agent1.state is State.RESISTANT or agent2.state is State.RESISTANT:
if State.RESISTANT in (agent1.state, agent2.state):
return 3
return 2

def get_agents(source, target):
return G.node[source]['agent'][0], G.node[target]['agent'][0]

portrayal = dict()
portrayal['nodes'] = [{'id': n_id,
'agent_id': n['agent'][0].unique_id,
'size': 2,
'color': node_color(n['agent'][0]),
portrayal['nodes'] = [{'size': 6,
'color': node_color(agents[0]),
'tooltip': "id: {}<br>state: {}".format(agents[0].unique_id, agents[0].state.name),
}
for n_id, n in G.nodes(data=True)]
for (_, agents) in G.nodes.data('agent')]

portrayal['edges'] = [{'id': i,
'source': source,
portrayal['edges'] = [{'source': source,
'target': target,
'color': edge_color(G.node[source]['agent'][0], G.node[target]['agent'][0]),
'width': edge_width(G.node[source]['agent'][0], G.node[target]['agent'][0]),
'color': edge_color(*get_agents(source, target)),
'width': edge_width(*get_agents(source, target)),
}
for i, (source, target, _) in enumerate(G.edges(data=True))]
for (source, target) in G.edges]

return portrayal

Expand All @@ -55,20 +53,14 @@ def edge_width(agent1, agent2):
{'Label': 'Resistant', 'Color': '#808080'}])


class RatioElement(TextElement):
class MyTextElement(TextElement):
def render(self, model):
ratio = model.resistant_susceptible_ratio()
ratio_text = '&infin;' if ratio is math.inf else '{0:.2f}'.format(ratio)
return 'Resistant/Susceptible Ratio: ' + ratio_text


class InfectedRemainingElement(TextElement):
def render(self, model):
infected = number_infected(model)
return 'Infected Remaining: ' + str(infected)
infected_text = str(number_infected(model))

return "Resistant/Susceptible Ratio: {}<br>Infected Remaining: {}".format(ratio_text, infected_text)

text = RatioElement(), InfectedRemainingElement()

model_params = {
'num_nodes': UserSettableParameter('slider', 'Number of agents', 10, 10, 100, 1,
Expand All @@ -89,5 +81,5 @@ def render(self, model):
'resistant to this virus in the future'),
}

server = ModularServer(VirusModel, [network, chart, *text], 'Virus Model', model_params)
server = ModularServer(VirusModel, [network, MyTextElement(), chart], 'Virus Model', model_params)
server.port = 8521
4 changes: 1 addition & 3 deletions mesa/visualization/templates/css/visualization.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
div.tooltip {
position: absolute;
text-align: center;
width: 60px;
height: 28px;
padding: 1px;
font: 20px sans-serif;
background: lightsteelblue;
border: 0px;
border: 3px;
border-radius: 8px;
pointer-events: none;
}
44 changes: 12 additions & 32 deletions mesa/visualization/templates/js/NetworkModule_d3.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ var NetworkModule = function(svg_width, svg_height) {
.attr("font-size", 10)
.text("Simulating. One moment please…");



// Use a timeout to allow the rest of the page to load first.
d3.timeout(function() {
loading.remove();
Expand All @@ -56,24 +54,12 @@ var NetworkModule = function(svg_width, svg_height) {
.data(graph.edges);
links.enter()
.append("line")
.attr("x1", function(d) {
return d.source.x;
})
.attr("y1", function(d) {
return d.source.y;
})
.attr("x2", function(d) {
return d.target.x;
})
.attr("y2", function(d) {
return d.target.y;
})
.attr("stroke-width", function(d) {
return d.width;
})
.attr("stroke", function(d) {
return d.color;
});
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; })
.attr("stroke-width", function(d) { return d.width; })
.attr("stroke", function(d) { return d.color; });

links.exit()
.remove();
Expand All @@ -83,25 +69,19 @@ var NetworkModule = function(svg_width, svg_height) {
.data(graph.nodes);
nodes.enter()
.append("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", 6)
.attr("fill", function(d) {
return d.color;
})
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", function(d) { return d.size; })
.attr("fill", function(d) { return d.color; })
.on("mouseover", function(d) {
tooltip.transition()
.duration(200)
.style("opacity", .9);
tooltip.html("id: " + d.id)
tooltip.html(d.tooltip)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY) + "px");
})
.on("mouseout", function(d) {
.on("mouseout", function() {
tooltip.transition()
.duration(500)
.style("opacity", 0);
Expand Down
4 changes: 2 additions & 2 deletions mesa/visualization/templates/js/d3.min.js

Large diffs are not rendered by default.

0 comments on commit 404ebfd

Please sign in to comment.