Ticket #14953: trac_14953_review1.patch
File trac_14953_review1.patch, 8.7 KB (added by , 7 years ago) |
---|
-
sage/graphs/graph_plot_js.py
# HG changeset patch # User Frederic Chapoton <chapoton at math.univ-lyon1.fr> # Date 1377780626 -7200 # Node ID 6e0bcdc6c35fd1ccdb9e024295f15507c8cd031e # Parent 4abecb26bc4053b012e0afaa9e590d1536ab17d6 trac #14953 cleanup, pep8 and details diff --git a/sage/graphs/graph_plot_js.py b/sage/graphs/graph_plot_js.py
a b The ID of a vertex is its index in the v 33 33 - ``color`` -- color (hexadecimal code) 34 34 35 35 -``curve`` -- distance from the barycenter of the two endpoints and the 36 center of the edge. It defines the curve o rthe edge, which can be useful36 center of the edge. It defines the curve of the edge, which can be useful 37 37 for multigraphs. 38 38 39 39 - ``pos`` -- a list whose `i` th element is a dictionary defining the position of … … definition can be found in the documenta 46 46 47 47 .. TODO:: 48 48 49 - Add tooltip like in `<http://bl.ocks.org/bentwonk/2514276>`_.49 - Add tooltip like in `<http://bl.ocks.org/bentwonk/2514276>`_. 50 50 51 - Add a zoom through scrolling (`<http://bl.ocks.org/mbostock/3681006>`_).51 - Add a zoom through scrolling (`<http://bl.ocks.org/mbostock/3681006>`_). 52 52 53 53 Authors: 54 54 … … import os 73 73 # http://www.gnu.org/licenses/ 74 74 #***************************************************************************** 75 75 76 76 77 def show(G, 77 vertex_labels = False, 78 edge_labels = False, 79 vertex_partition = [], 80 edge_partition = [], 81 force_spring_layout = False, 82 charge=-120, 83 link_distance=30, 84 link_strength=2, 85 gravity=.04, 86 vertex_size=7, 87 edge_thickness=4 88 ): 78 vertex_labels=False, 79 edge_labels=False, 80 vertex_partition=[], 81 edge_partition=[], 82 force_spring_layout=False, 83 charge=-120, 84 link_distance=30, 85 link_strength=2, 86 gravity=.04, 87 vertex_size=7, 88 edge_thickness=4): 89 89 r""" 90 90 Displays the graph in a browser using `d3.js <http://d3js.org/>`_. 91 91 … … def show(G, 158 158 multiple_edges = G.has_multiple_edges() 159 159 160 160 # Associated an integer to each vertex 161 v_to_id = {v: i for i,v in enumerate(G.vertices())}161 v_to_id = {v: i for i, v in enumerate(G.vertices())} 162 162 163 163 # Vertex colors 164 color = {i: len(vertex_partition) for i in range(G.order())}165 for i, l in enumerate(vertex_partition):164 color = {i: len(vertex_partition) for i in range(G.order())} 165 for i, l in enumerate(vertex_partition): 166 166 for v in l: 167 167 color[v_to_id[v]] = i 168 168 169 169 # Vertex list 170 170 nodes = [] 171 171 for v in G.vertices(): 172 nodes.append({"name": str(v),"group":str(color[v_to_id[v]])})172 nodes.append({"name": str(v), "group": str(color[v_to_id[v]])}) 173 173 174 174 # Edge colors. 175 175 edge_color_default = "#aaa" 176 176 color_list = rainbow(len(edge_partition)) 177 177 edge_color = {} 178 for i, l in enumerate(edge_partition):178 for i, l in enumerate(edge_partition): 179 179 for e in l: 180 u, v,label = e if len(e) == 3 else e+(None,)181 edge_color[u, v,label] = color_list[i]180 u, v, label = e if len(e) == 3 else e+(None,) 181 edge_color[u, v, label] = color_list[i] 182 182 if not directed: 183 edge_color[v, u,label] = color_list[i]183 edge_color[v, u, label] = color_list[i] 184 184 185 185 # Edge list 186 186 edges = [] 187 seen = {} # How many times has this edge been seen ?187 seen = {} # How many times has this edge been seen ? 188 188 189 for u, v,l in G.edges():189 for u, v, l in G.edges(): 190 190 191 191 # Edge color 192 color = edge_color.get((u, v,l),edge_color_default)192 color = edge_color.get((u, v, l), edge_color_default) 193 193 194 194 # Computes the curve of the edge 195 195 curve = 0 196 196 197 197 # Loop ? 198 198 if u == v: 199 seen[u, v] = seen.get((u,v),0)+1200 curve = seen[u, v]*10+10199 seen[u, v] = seen.get((u, v), 0)+1 200 curve = seen[u, v]*10+10 201 201 202 202 # For directed graphs, one also has to take into accounts 203 203 # edges in the opposite direction 204 204 elif directed: 205 if G.has_edge(v, u):206 seen[u, v] = seen.get((u,v),0)+1207 curve = seen[u, v]*15205 if G.has_edge(v, u): 206 seen[u, v] = seen.get((u, v), 0)+1 207 curve = seen[u, v]*15 208 208 else: 209 if multiple_edges and len(G.edge_label(u, v)) != 1:209 if multiple_edges and len(G.edge_label(u, v)) != 1: 210 210 # Multiple edges. The first one has curve 15, then 211 211 # -15, then 30, then -30, ... 212 seen[u, v] = seen.get((u,v),0) + 1213 curve = (1 if seen[u, v]%2 else -1)*(seen[u,v]//2)*15212 seen[u, v] = seen.get((u, v), 0) + 1 213 curve = (1 if seen[u, v] % 2 else -1)*(seen[u, v]//2)*15 214 214 215 215 elif not directed and multiple_edges: 216 216 # Same formula as above for multiple edges 217 if len(G.edge_label(u, v)) != 1:218 seen[u, v] = seen.get((u,v),0) + 1219 curve = (1 if seen[u, v]%2 else -1)*(seen[u,v]//2)*15217 if len(G.edge_label(u, v)) != 1: 218 seen[u, v] = seen.get((u, v), 0) + 1 219 curve = (1 if seen[u, v] % 2 else -1)*(seen[u, v]//2)*15 220 220 221 221 # Adding the edge to the list 222 edges.append({"source": v_to_id[u],223 "target": v_to_id[v],224 "strength": 0,225 "color": color,226 "curve": curve,227 "name": str(l) if edge_labels else ""})222 edges.append({"source": v_to_id[u], 223 "target": v_to_id[v], 224 "strength": 0, 225 "color": color, 226 "curve": curve, 227 "name": str(l) if edge_labels else ""}) 228 228 229 loops = [e for e in edges if e["source"] ==e["target"]]230 edges = [e for e in edges if e["source"] !=e["target"]]229 loops = [e for e in edges if e["source"] == e["target"]] 230 edges = [e for e in edges if e["source"] != e["target"]] 231 231 232 232 # Defines the vertices' layout if possible 233 233 Gpos = G.get_pos() 234 234 pos = [] 235 235 if Gpos is not None and force_spring_layout is False: 236 charge =0;237 link_strength =0;238 gravity =0;236 charge = 0 237 link_strength = 0 238 gravity = 0 239 239 240 240 for v in G.vertices(): 241 x, y = Gpos[v]242 pos.append([x, -y])241 x, y = Gpos[v] 242 pos.append([x, -y]) 243 243 244 244 # Encodes the data as a JSON string 245 245 from json import JSONEncoder 246 string = JSONEncoder().encode({"nodes":nodes,"links":edges,"loops":loops,"pos":pos, 247 "directed":G.is_directed(), 248 "charge":int(charge),"link_distance":int(link_distance), 249 "link_strength":int(link_strength),"gravity":float(gravity), 250 "vertex_labels":bool(vertex_labels),"edge_labels":bool(edge_labels), 251 "vertex_size":int(vertex_size), 252 "edge_thickness":int(edge_thickness)}) 246 string = JSONEncoder().encode({"nodes": nodes, 247 "links": edges, "loops": loops, "pos": pos, 248 "directed": G.is_directed(), 249 "charge": int(charge), 250 "link_distance": int(link_distance), 251 "link_strength": int(link_strength), 252 "gravity": float(gravity), 253 "vertex_labels": bool(vertex_labels), 254 "edge_labels": bool(edge_labels), 255 "vertex_size": int(vertex_size), 256 "edge_thickness": int(edge_thickness)}) 253 257 254 258 from sage.misc.misc import SAGE_ROOT 255 js_code_file = open(SAGE_ROOT+"/devel/sage/sage/graphs/graph_plot_js.html", 'r')256 js_code = js_code_file.read().replace("// HEREEEEEEEEEEE", string)259 js_code_file = open(SAGE_ROOT+"/devel/sage/sage/graphs/graph_plot_js.html", 'r') 260 js_code = js_code_file.read().replace("// HEREEEEEEEEEEE", string) 257 261 js_code_file.close() 258 262 259 263 # Writes the temporary .html file 260 264 filename = tmp_filename(ext='.html') 261 f = open(filename, 'w')265 f = open(filename, 'w') 262 266 f.write(js_code) 263 267 f.close() 264 268 … … def show(G, 266 270 from sage.misc.viewer import browser 267 271 os.system('%s %s 2>/dev/null 1>/dev/null &' 268 272 % (browser(), filename)) 269