Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Graph plotting in Javascript with d3.js
This module implements everything that can be used to draw graphs with `d3.js <http://d3js.org/>`_ in Sage.
On Python's side, this is mainly done by wrapping a graph's edges and vertices in a structure that can then be used in the javascript code. This javascript code is then inserted into a .html file to be opened by a browser.
What Sage feeds javascript with is a "graph" object with the following content:
- ``vertices`` -- each vertex is a dictionary defining :
- ``name`` -- The vertex's label
- ``group`` -- the vertex' color (integer)
The ID of a vertex is its index in the vertex list.
- ``edges`` -- each edge is a dictionary defining :
- ``source`` -- the ID (int) of the edge's source
- ``target`` -- the ID (int) of the edge's destination
- ``color`` -- the edge's color (integer)
- ``value`` -- thickness of the edge
- ``strength`` -- the edge's strength in the automatic layout
- ``color`` -- color (hexadecimal code)
- ``curve`` -- distance from the barycenter of the two endpoints and the center of the edge. It defines the curve of the edge, which can be useful for multigraphs.
- ``pos`` -- a list whose `i` th element is a dictionary defining the position of the `i` th vertex.
It also contains the definition of some numerical/boolean variables whose definition can be found in the documentation of :meth:`~sage.graphs.generic_graph.GenericGraph.show` : ``directed``, ``charge``, ``link_distance``, ``link_strength``, ``gravity``, ``vertex_size``, ``edge_thickness``.
.. WARNING::
Since the d3js package is not standard yet, the javascript is fetched from d3js.org website by the browser. If you want to avoid that (e.g. to protect your privacy or by lack of internet connection), you can install the d3js package for offline use by running ``sage -i d3js`` from the command line.
.. TODO::
- Add tooltip like in `<http://bl.ocks.org/bentwonk/2514276>`_.
- Add a zoom through scrolling (`<http://bl.ocks.org/mbostock/3681006>`_).
Authors:
- Nathann Cohen, Brice Onfroy -- July 2013 -- Initial version of the Sage code, Javascript code, using examples from `d3.js <http://d3js.org/>`_.
- Thierry Monteil (June 2014): allow offline use of d3.js provided by d3js spkg.
Functions --------- """
#***************************************************************************** # Copyright (C) 2013 Nathann Cohen <nathann.cohen@gmail.com> # Brice Onfroy <onfroy.brice@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # http://www.gnu.org/licenses/ #*****************************************************************************
vertex_labels=True, edge_labels=False, vertex_partition=[], vertex_colors=None, edge_partition=[], force_spring_layout=False, charge=-120, link_distance=30, link_strength=2, gravity=.04, vertex_size=7, edge_thickness=4): r""" Creates a .html file showing the graph using `d3.js <http://d3js.org/>`_.
This function returns the name of the .html file. If you want to visualize the actual graph use :meth:`~sage.graphs.generic_graph.GenericGraph.show`.
INPUT:
- ``G`` -- the graph
- ``vertex_labels`` (boolean) -- Whether to display vertex labels (set to ``False`` by default).
- ``edge_labels`` (boolean) -- Whether to display edge labels (set to ``False`` by default).
- ``vertex_partition`` -- a list of lists representing a partition of the vertex set. Vertices are then colored in the graph according to the partition. Set to ``[]`` by default.
- ``vertex_colors`` -- a dictionary representing a partition of the vertex set. Keys are colors (ignored) and values are lists of vertices. Vertices are then colored in the graph according to the partition. Set to ``None`` by default.
- ``edge_partition`` -- same as ``vertex_partition``, with edges instead. Set to ``[]`` by default.
- ``force_spring_layout`` -- whether to take previously computed position of nodes into account if there is one, or to compute a spring layout. Set to ``False`` by default.
- ``vertex_size`` -- The size of a vertex' circle. Set to `7` by default.
- ``edge_thickness`` -- Thickness of an edge. Set to ``4`` by default.
- ``charge`` -- the vertices' charge. Defines how they repulse each other. See `<https://github.com/mbostock/d3/wiki/Force-Layout>`_ for more information. Set to ``-120`` by default.
- ``link_distance`` -- See `<https://github.com/mbostock/d3/wiki/Force-Layout>`_ for more information. Set to ``30`` by default.
- ``link_strength`` -- See `<https://github.com/mbostock/d3/wiki/Force-Layout>`_ for more information. Set to ``2`` by default.
- ``gravity`` -- See `<https://github.com/mbostock/d3/wiki/Force-Layout>`_ for more information. Set to ``0.04`` by default.
.. WARNING::
Since the d3js package is not standard yet, the javascript is fetched from d3js.org website by the browser. If you want to avoid that (e.g. to protect your privacy or by lack of internet connection), you can install the d3js package for offline use by running ``sage -i d3js`` from the command line.
EXAMPLES::
sage: graphs.RandomTree(50).show(method="js") # optional -- internet
sage: g = graphs.PetersenGraph() sage: g.show(method = "js", vertex_partition=g.coloring()) # optional -- internet
sage: graphs.DodecahedralGraph().show(method="js", force_spring_layout=True) # optional -- internet
sage: graphs.DodecahedralGraph().show(method="js") # optional -- internet
sage: g = digraphs.DeBruijn(2,2) sage: g.allow_multiple_edges(True) sage: g.add_edge("10","10","a") sage: g.add_edge("10","10","b") sage: g.add_edge("10","10","c") sage: g.add_edge("10","10","d") sage: g.add_edge("01","11","1") sage: g.show(method="js", vertex_labels=True,edge_labels=True, ....: link_distance=200,gravity=.05,charge=-500, ....: edge_partition=[[("11","12","2"),("21","21","a")]], ....: edge_thickness=4) # optional -- internet
TESTS::
sage: from sage.graphs.graph_plot_js import gen_html_code sage: filename = gen_html_code(graphs.PetersenGraph())
:trac:`17370`::
sage: filename = gen_html_code(graphs.CompleteBipartiteGraph(4,5)) """
# Associated an integer to each vertex
# Vertex colors vertex_partition = list(vertex_colors.values()) for v in l: color[v_to_id[v]] = i
# Vertex list
# Edge colors. edge_color[v, u, label] = color_list[i]
# Edge list
# Edge color
# Computes the curve of the edge
# Loop ?
# For directed graphs, one also has to take into accounts # edges in the opposite direction else: # Multiple edges. The first one has curve 15, then # -15, then 30, then -30, ...
# Same formula as above for multiple edges if len(G.edge_label(u, v)) != 1: seen[u, v] = seen.get((u, v), 0) + 1 curve = (1 if seen[u, v] % 2 else -1)*(seen[u, v]//2)*15
# Adding the edge to the list "target": v_to_id[v], "strength": 0, "color": color, "curve": curve, "name": str(l) if edge_labels else ""})
# Defines the vertices' layout if possible
# Encodes the data as a JSON string "links": edges, "loops": loops, "pos": pos, "directed": G.is_directed(), "charge": int(charge), "link_distance": int(link_distance), "link_strength": int(link_strength), "gravity": float(gravity), "vertex_labels": bool(vertex_labels), "edge_labels": bool(edge_labels), "vertex_size": int(vertex_size), "edge_thickness": int(edge_thickness)})
# Add d3.js script depending on whether d3js package is installed. with open(d3js_filepath, 'r') as d3js_code_file: d3js_script = '<script>' + d3js_code_file.read() + '</script>' else:
# Writes the temporary .html file
|