construction d'un graphique en html avec des tables
541837
public function getHtml($params = array())
	{
		$html="";
		$maxValue = $this->getMaxValue(); // cette valeur va permettre de calculer l'echelle la plus pratique a utiliser
		
		$nbChiffres = pia_strlen($maxValue);
		
		$unite='1';
		for($i=0 ; $i<$nbChiffres-2 ; $i++)
		{
			$unite.='0';
		}
		
		$roundedValue = round($maxValue,-$nbChiffres+2)+$unite;
		
		
		$hauteur = 200;
		if(isset($params['hauteur']) && $params['hauteur']!='')
		{
			$hauteur = $params['hauteur'];
		}
		
		
		$colWidth=20;
		if(isset($params['colWidth']) && $params['colWidth']!='')
		{
			$colWidth=$params['colWidth'];
		}
		
		// echelle
		$heightEchelle = $hauteur;
		
		$html.="<table cellspacing=0 cellpadding=0 border=0 height=".($heightEchelle+50+50)."><tr><td valign=bottom>";
		$html.="<table border=0 cellspacing=0 cellpadding=0 style='background-color:white;' height=".($heightEchelle+50).">";
		$html.="<tr>";
		$html.="<td valign=top>";
		$html.=" <table height=$heightEchelle width=60 border=0 cellspacing=0 cellpadding=0 style=''><tr><td width=60 valign=bottom>";
		$html.="<div style='position:relative;'>";
		$html.="<div style='position:absolute;bottom:".round($heightEchelle/4)."px;left:0;width:60px;text-align:right;'>".round($roundedValue/4)."_</div>";
		$html.="<div style='position:absolute;bottom:".round($heightEchelle/2)."px;left:0;width:60px;text-align:right;'>".round($roundedValue/2)."_</div>";
		$html.="<div style='position:absolute;bottom:".round($heightEchelle/(4/3))."px;left:0;width:60px;text-align:right;'>".round($roundedValue/(4/3))."_</div>";
		$html.="<div style='position:absolute;bottom:0px;left:0;width:60px;text-align:right;'>0_</div>";
		$html.="<div style='position:absolute;bottom:".$heightEchelle."px;left:0;width:60px;text-align:right;'>".$roundedValue."_</div>";
		$html.="</div>";
		$html.="</td><td style='background-color:black;' width=2></td></tr></table>";
		$html.="</td>";
		
		foreach($this->listeValues as $indice => $value)
		{
			if(is_array($value))
			{

				if(!isset($this->listeModesAffichage[$indice]) || $this->listeModesAffichage[$indice]!='cumul')
				{
					asort($value);
				}
		
				$html.="<td valign=bottom height=200>";
				
				$html.="<table cellspacing=0 cellpadding=0 border=0  width=$colWidth style=''>";
				$valPrecedente = 0;
				$arrayHtmlGraph = array();
				foreach($value as $index => $values)
				{
					if(isset($this->listeModesAffichage[$indice]) && $this->listeModesAffichage[$indice]=='cumul')
					{
						// dans ce cas on cumul les barres , on affiche la premiere puis la seconde au dessus
						$height1 = round($value[$index]*$hauteur/$roundedValue);
						$arrayHtmlGraph[] = "<tr><td style='".$this->listeStyles[$indice][$index]."' height=".$height1."></td></tr>";
					}
					else
					{
						// dans ce cas on affiche les barres les une derriere les autres , et ont chacune comme ordonnee 0 au depart
						$height1 = round((($value[$index] - $valPrecedente) * $hauteur) / $roundedValue);
						$arrayHtmlGraph[] = "<tr><td style='".$this->listeStyles[$indice][$index]."' height=".$height1."></td></tr>";
						$valPrecedente = $value[$index] - $valPrecedente;
					}
				}
				
				// et on affiche a l'envers
				for($i=count($arrayHtmlGraph)-1 ; $i>=0 ; $i--)
				{
					$html.=$arrayHtmlGraph[$i];
				}
				
				$html.="<tr height=50><td style='background-color:white;border-top:1px solid black;font-size:9px;' valign=top>".$this->listeLibelles[$indice]."</td></tr>";//
				$html.="</table>";
				$html.="</td>";
			}
			else
			{
				$html.="<td valign=bottom height=200>";
				$height = round($value * $hauteur / $roundedValue);
				$html.="<table cellspacing=0 cellpadding=0 border=0 height=".($height+50)." width=$colWidth style='".$this->listeStyles[$indice]."'>";
				$html.="<tr>";
				$html.="<td valign=top></td>";
				$html.="</tr>";
				$html.="<tr height=50><td style='background-color:white;border-top:1px solid black;font-size:9px;' valign=top>".$this->listeLibelles[$indice]."</td></tr>";//
				$html.="</table>";
				$html.="</td>";
			}
		}
		
		$html.="</tr>";
		$html.="</table>";
		$html.="</tr>";
		$html.="</table>";
		
		
		return $html;
	}
119559
function inlineMargins ($) {
  $('table[style*=margin]').toNodes().forEach(($el) => {
    const { left, right } = getSideMargins($el.attr('style'))

    if (left === 'auto' && right === 'auto') {
      $el.attr('align', 'center')
    } else if (left === 'auto' && right !== 'auto') {
      $el.attr('align', 'right')
    } else if (left !== 'auto') {
      $el.attr('align', 'left')
    }
  })
}
794834
def make_table(self, renderable):
        """"""
        self._make_prefix()
        diffs = renderable.diff._diff

        # set up iterator to wrap lines that exceed desired width
        if self._wrapcolumn:
            diffs = self._line_wrapper(diffs, renderable.diff.hide_expected)

        # collect up from/to lines and flags into lists (also format the lines)
        fromlist, tolist, flaglist = self._collect_lines(diffs)

        # process change flags, generating middle column of next anchors/links
        fromlist, tolist, flaglist, next_href, next_id = self._convert_flags(
            fromlist, tolist, flaglist, False, 5)

        s = []
        fmt = '            <tr><td class="diff_next"%s>%s</td>%s' + \
              '<td class="diff_next">%s</td>%s</tr>\n'
        for i in range(len(flaglist)):
            if flaglist[i] is None:
                # mdiff yields None on separator lines skip the bogus ones
                # generated for the first line
                if i > 0:
                    s.append('        </tbody>        \n        <tbody>\n')
            else:
                s.append(fmt % (next_id[i], next_href[i], fromlist[i],
                                next_href[i], tolist[i]))
        header_row = '<thead><tr>%s%s%s%s</tr></thead>' % (
            '<th class="diff_next"><br /></th>',
            '<th colspan="2" class="diff_header">%s</th>' % self.FROM_DESC,
            '<th class="diff_next"><br /></th>',
            '<th colspan="2" class="diff_header">%s</th>' % self.TO_DESC)

        table = self._table_template % dict(
            data_rows=''.join(s),
            header_row=header_row,
            prefix=self._prefix[1])

        return table.replace('\0+', '<span class="diff_add">'). \
            replace('\0-', '<span class="diff_sub">'). \
            replace('\0^', '<span class="diff_chg">'). \
            replace('\1', '</span>'). \
            replace('\t', '&nbsp;')
764570
function adjacencyListToCells(adjacencyList) {

        var elements = [];
        var links = [];

        _.each(adjacencyList, function(edges, parentElementLabel) {
            elements.push(makeElement(parentElementLabel));

            _.each(edges, function(childElementLabel) {
                links.push(makeLink(parentElementLabel, childElementLabel));
            });
        });

        // Links must be added after all the elements. This is because when the links
        // are added to the graph, link source/target
        // elements must be in the graph already.
        var cells = elements.concat(links);

        return cells;
    }
239967
function ($nodeChart, data) {
      var newSiblingCount = $.isArray(data) ? data.length : data.children.length;
      var existingSibligCount = $nodeChart.parent().is('td') ? $nodeChart.closest('tr').children().length : 1;
      var siblingCount = existingSibligCount + newSiblingCount;
      var insertPostion = (siblingCount > 1) ? Math.floor(siblingCount/2 - 1) : 0;
      // just build the sibling nodes for the specific node
      if ($nodeChart.parent().is('td')) {
        var $parent = $nodeChart.closest('tr').prevAll('tr:last');
        $nodeChart.closest('tr').prevAll('tr:lt(2)').remove();
        this.buildChildNode($nodeChart.parent().closest('table'), data);
        var $siblingTds = $nodeChart.parent().closest('table').children('tr:last').children('td');
        if (existingSibligCount > 1) {
          this.complementLine($siblingTds.eq(0).before($nodeChart.closest('td').siblings().addBack().unwrap()), siblingCount, existingSibligCount);
        } else {
          this.complementLine($siblingTds.eq(insertPostion).after($nodeChart.closest('td').unwrap()), siblingCount, 1);
        }
      } else { // build the sibling nodes and parent node for the specific ndoe
        this.buildHierarchy($nodeChart.closest('.orgchart'), data);
        this.complementLine($nodeChart.next().children('tr:last').children().eq(insertPostion).after($('<td colspan="2">').append($nodeChart)),
          siblingCount, 1);
      }
    }
1238212
def dom_lt(graph):
    """"""

    def _dfs(v, n):
        semi[v] = n = n + 1
        vertex[n] = label[v] = v
        ancestor[v] = 0
        for w in graph.all_sucs(v):
            if not semi[w]:
                parent[w] = v
                n = _dfs(w, n)
            pred[w].add(v)
        return n

    def _compress(v):
        u = ancestor[v]
        if ancestor[u]:
            _compress(u)
            if semi[label[u]] < semi[label[v]]:
                label[v] = label[u]
            ancestor[v] = ancestor[u]

    def _eval(v):
        if ancestor[v]:
            _compress(v)
            return label[v]
        return v

    def _link(v, w):
        ancestor[w] = v

    parent, ancestor, vertex = {}, {}, {}
    label, dom = {}, {}
    pred, bucket = defaultdict(set), defaultdict(set)

    # Step 1:
    semi = {v: 0 for v in graph.nodes}
    n = _dfs(graph.entry, 0)
    for i in range(n, 1, -1):
        w = vertex[i]
        # Step 2:
        for v in pred[w]:
            u = _eval(v)
            y = semi[w] = min(semi[w], semi[u])
        bucket[vertex[y]].add(w)
        pw = parent[w]
        _link(pw, w)
        # Step 3:
        bpw = bucket[pw]
        while bpw:
            v = bpw.pop()
            u = _eval(v)
            dom[v] = u if semi[u] < semi[v] else pw
    # Step 4:
    for i in range(2, n + 1):
        w = vertex[i]
        dw = dom[w]
        if dw != vertex[semi[w]]:
            dom[w] = dom[dw]
    dom[graph.entry] = None
    return dom
1364226
def rdf2dot( g, stream, opts={} ):
    

    accept_lang = set( opts.get('lang',[]) )
    do_literal = opts.get('literal')
    nodes = {}
    links = []

    def node_id(x):
        if x not in nodes:
            nodes[x] = "node%d" % len(nodes)
        return nodes[x]

    def qname(x, g):
        try:
            q = g.compute_qname(x)
            return q[0] + ":" + q[2]
        except:
            return x

    def accept( node ):
        if isinstance( node, (rdflib.URIRef,rdflib.BNode) ):
            return True
        if not do_literal:
            return False
        return (not accept_lang) or (node.language in accept_lang)


    stream.write( u'digraph { \n node [ fontname="DejaVu Sans,Tahoma,Geneva,sans-serif" ] ; \n' )

    # Write all edges. In the process make a list of all nodes
    for s, p, o in g:
        # skip triples for labels
        if p == rdflib.RDFS.label:
            continue

        # Create a link if both objects are graph nodes
        # (or, if literals are also included, if their languages match)
        if not (accept(s) and accept(o)):
            continue

        # add the nodes to the list
        sn = node_id(s)
        on = node_id(o)

        # add the link
        q = qname(p,g)
        if isinstance(p, rdflib.URIRef):
            opstr = u'\t%s -> %s [ arrowhead="open", color="#9FC9E560", fontsize=9, fontcolor="#204080", label="%s", href="%s", target="_other" ] ;\n' % (sn,on,q,p)
        else:
            opstr = u'\t%s -> %s [ arrowhead="open", color="#9FC9E560", fontsize=9, fontcolor="#204080", label="%s" ] ;\n'%(sn,on,q)
        stream.write( opstr )

    # Write all nodes
    for u, n in nodes.items():
        lbl = escape( label(u,g,accept_lang), True )
        if isinstance(u, rdflib.URIRef):
            opstr = u'%s [ shape=none, fontsize=10, fontcolor=%s, label="%s", href="%s", target=_other ] \n' % (n, 'blue', lbl, u )
        else:
            opstr = u'%s [ shape=none, fontsize=10, fontcolor=%s, label="%s" ] \n' % (n, 'black', lbl )
        stream.write( u"# %s %s\n" % (u, n) )
        stream.write( opstr )

    stream.write(u'}\n')
125503
def render_graph(result, cfg, **kwargs):
    
    # Mapping from MIME types to formats accepted by RDFlib
    rdflib_formats = {'text/rdf+n3': 'n3',
                      'text/turtle': 'turtle',
                      'application/x-turtle': 'turtle',
                      'text/turtle': 'turtle',
                      'application/rdf+xml': 'xml',
                      'text/rdf': 'xml',
                      'application/rdf+xml': 'xml'}


    try:
        got = kwargs.get('format', 'text/rdf+n3')
        fmt = rdflib_formats[got]
    except KeyError:
        raise KrnlException('Unsupported format for graph processing: {!s}', got)

    g = ConjunctiveGraph()
    g.load(StringInputSource(result), format=fmt)

    display = cfg.dis[0] if is_collection(cfg.dis) else cfg.dis
    if display in ('png', 'svg'):
        try:
            literal = len(cfg.dis) > 1 and cfg.dis[1].startswith('withlit')
            opt = {'lang': cfg.lan, 'literal': literal, 'graphviz': []}
            data, metadata = draw_graph(g, fmt=display, options=opt)
            return {'data': data,
                    'metadata': metadata}
        except Exception as e:
            raise KrnlException('Exception while drawing graph: {!r}', e)
    elif display == 'table':
        it = rdf_iterator(g, set(cfg.lan), add_vtype=cfg.typ)
        n, data = html_table(it, limit=cfg.lmt, withtype=cfg.typ)
        data += div('Shown: {}, Total rows: {}', n if cfg.lmt else 'all',
                    len(g), css="tinfo")
        data = {'text/html': div(data)}
    elif len(g) == 0:
        data = {'text/html': div(div('empty graph', css='krn-warn'))}
    else:
        data = {'text/plain': g.serialize(format='nt').decode('utf-8')}

    return {'data': data,
            'metadata': {}}
537842
function updateInputGraph(inputGraph, layoutGraph) {
  _.forEach(inputGraph.nodes(), function(v) {
    var inputLabel = inputGraph.node(v);
    var layoutLabel = layoutGraph.node(v);

    if (inputLabel) {
      inputLabel.x = layoutLabel.x;
      inputLabel.y = layoutLabel.y;

      if (layoutGraph.children(v).length) {
        inputLabel.width = layoutLabel.width;
        inputLabel.height = layoutLabel.height;
      }
    }
  });

  _.forEach(inputGraph.edges(), function(e) {
    var inputLabel = inputGraph.edge(e);
    var layoutLabel = layoutGraph.edge(e);

    inputLabel.points = layoutLabel.points;
    if (_.has(layoutLabel, "x")) {
      inputLabel.x = layoutLabel.x;
      inputLabel.y = layoutLabel.y;
    }
  });

  inputGraph.graph().width = layoutGraph.graph().width;
  inputGraph.graph().height = layoutGraph.graph().height;
}
1153292
def draw(molecule, TraversalType=SmilesTraversal):
    """"""
    result = []
    atoms = allAtoms = molecule.atoms

    visitedAtoms = {}
    #
    # Traverse all components of the graph to form
    # the output string
    while atoms:
        atom = _get_lowest_symorder(atoms)
        visitedAtoms[atom] = 1

        visitedBonds = {}
        nextTraverse = TraversalType()
        atomsUsed, bondsUsed = [], []
        _traverse(atom, nextTraverse, None,
                  visitedAtoms, visitedBonds,
                  atomsUsed, bondsUsed, TraversalType)
        atoms = []
        for atom in allAtoms:
            if not visitedAtoms.has_key(atom):
                atoms.append(atom)
        assert nextTraverse.atoms == atomsUsed
        assert nextTraverse.bonds == bondsUsed, "%s %s"%(
            nextTraverse.bonds, bondsUsed)
        

        result.append((str(nextTraverse),
                       atomsUsed, bondsUsed))

    result.sort()
    fragments = []
    for r in result:
        fragments.append(r[0])

    return ".".join(fragments), result
1182778
function tinf_build_fixed_trees(lt, dt) {
  var i;

  /* build fixed length tree */
  for (i = 0; i < 7; ++i) lt.table[i] = 0;

  lt.table[7] = 24;
  lt.table[8] = 152;
  lt.table[9] = 112;

  for (i = 0; i < 24; ++i) lt.trans[i] = 256 + i;
  for (i = 0; i < 144; ++i) lt.trans[24 + i] = i;
  for (i = 0; i < 8; ++i) lt.trans[24 + 144 + i] = 280 + i;
  for (i = 0; i < 112; ++i) lt.trans[24 + 144 + 8 + i] = 144 + i;

  /* build fixed distance tree */
  for (i = 0; i < 5; ++i) dt.table[i] = 0;

  dt.table[5] = 32;

  for (i = 0; i < 32; ++i) dt.trans[i] = i;
}
498885
def tableMaker(inputLabel, outputLabels, port, _E=elementMaker):
    
    colspan = {}
    if outputLabels:
        colspan['colspan'] = str(len(outputLabels))

    inputLabelCell = _E("td",
                        _E("font",
                           inputLabel,
                           face="menlo-italic"),
                        color="purple",
                        port=port,
                        **colspan)

    pointSize = {"point-size": "9"}
    outputLabelCells = [_E("td",
                           _E("font",
                              outputLabel,
                              **pointSize),
                           color="pink")
                        for outputLabel in outputLabels]

    rows = [_E("tr", inputLabelCell)]

    if outputLabels:
        rows.append(_E("tr", *outputLabelCells))

    return _E("table", *rows)
1356704
function createVisualization(data) {
  var json = buildHierarchy(data);

  // Basic setup of page elements.
  initializeBreadcrumbTrail();

  // Bounding circle underneath the sunburst, to make it easier to detect
  // when the mouse leaves the parent g.
  vis.append("svg:circle")
      .attr("r", radius)
      .style("opacity", 0);

  // For efficiency, filter nodes to keep only those large enough to see.
  var nodes = partition.nodes(json)
      .filter(function(d) {
      return (d.dx > 0.005); // 0.005 radians = 0.29 degrees
      });

  var path = vis.data([json]).selectAll("path")
      .data(nodes)
      .enter().append("svg:path")
      .attr("display", function(d) { return d.depth ? null : "none"; })
      .attr("d", arc)
      .attr("fill-rule", "evenodd")
      .style("fill", function(d) { return colors[d.depth]; })
      .style("opacity", 1)
      .on("mouseover", mouseover);

  // Add the mouseleave handler to the bounding circle.
  d3.select("#container").on("mouseleave", mouseleave);

  // Get total size of the tree = value of root node from partition.
  totalSize = path.node().__data__.value;
 }
144279
function render() {
		var labels = options.labels,
			credits = options.credits,
			creditsHref;

		// Title
		setTitle();


		// Legend
		legend = chart.legend = new Legend();

		// Get margins by pre-rendering axes
		getMargins();
		each(axes, function (axis) {
			axis.setTickPositions(true); // update to reflect the new margins
		});
		adjustTickAmounts();
		getMargins(); // second pass to check for new labels


		// Draw the borders and backgrounds
		drawChartBox();

		// Axes
		if (hasCartesianSeries) {
			each(axes, function (axis) {
				axis.render();
			});
		}


		// The series
		if (!chart.seriesGroup) {
			chart.seriesGroup = renderer.g('series-group')
				.attr({ zIndex: 3 })
				.add();
		}
		each(series, function (serie) {
			serie.translate();
			serie.setTooltipPoints();
			serie.render();
		});


		// Labels
		if (labels.items) {
			each(labels.items, function () {
				var style = extend(labels.style, this.style),
					x = pInt(style.left) + plotLeft,
					y = pInt(style.top) + plotTop + 12;

				// delete to prevent rewriting in IE
				delete style.left;
				delete style.top;

				renderer.text(
					this.html,
					x,
					y
				)
				.attr({ zIndex: 2 })
				.css(style)
				.add();

			});
		}

		// Toolbar (don't redraw)
		if (!chart.toolbar) {
			chart.toolbar = Toolbar();
		}

		// Credits
		if (credits.enabled && !chart.credits) {
			creditsHref = credits.href;
			chart.credits = renderer.text(
				credits.text,
				0,
				0
			)
			.on('click', function () {
				if (creditsHref) {
					location.href = creditsHref;
				}
			})
			.attr({
				align: credits.position.align,
				zIndex: 8
			})
			.css(credits.style)
			.add()
			.align(credits.position);
		}

		placeTrackerGroup();

		// Set flag
		chart.hasRendered = true;

		// If the chart was rendered outside the top container, put it back in
		if (renderToClone) {
			renderTo.appendChild(container);
			discardElement(renderToClone);
			//updatePosition(container);
		}
	}
1363401
function drawSlices() {
            // Not ideal, we need to figure out how to call exit for nested elements
            if (slices) {
                svg.selectAll('g.arc').remove();
            }

            slices = svg.select('.chart-group')
                .selectAll('g.arc')
                .data(layout(data));

            let newSlices = slices.enter()
                .append('g')
                  .each(storeAngle)
                  .each(reduceOuterRadius)
                  .classed('arc', true)
                  .append('path');

            if (isAnimated) {
                newSlices.merge(slices)
                    .attr('fill', getSliceFill)
                    .on('mouseover', function(d) {
                        handleMouseOver(this, d, chartWidth, chartHeight);
                    })
                    .on('mousemove', function(d) {
                        handleMouseMove(this, d, chartWidth, chartHeight);
                    })
                    .on('mouseout', function(d) {
                        handleMouseOut(this, d, chartWidth, chartHeight);
                    })
                    .on('click', function(d) {
                        handleClick(this, d, chartWidth, chartHeight);
                    })
                    .transition()
                    .ease(ease)
                    .duration(pieDrawingTransitionDuration)
                    .attrTween('d', tweenLoading);
            } else {
                newSlices.merge(slices)
                    .attr('fill', getSliceFill)
                    .attr('d', shape)
                    .on('mouseover', function(d) {
                        handleMouseOver(this, d, chartWidth, chartHeight);
                    })
                    .on('mousemove', function(d) {
                        handleMouseMove(this, d, chartWidth, chartHeight);
                    })
                    .on('mouseout', function(d) {
                        handleMouseOut(this, d, chartWidth, chartHeight);
                    })
                    .on('click', function(d) {
                        handleClick(this, d, chartWidth, chartHeight);
                    });
            }

            slices.exit().remove();
        }
1220593
def _plot_graph(self, graph, title=None, width=None, height=None):
        
        if not self._elements_row and not self._elements_graph:
            raise ValueError('Unable to display the graph or the table')
        title = title or self.q
        width = width or json.dumps(None)
        height = height or 300
        d3_uuid = text_type(uuid.uuid1())
        d3_graph = self._transform_graph_to_d3(graph)
        d3_id = "d3_id_" + d3_uuid
        d3_title = title
        d3_container_id = d3_id + "_d3c"
        style = """
        #{d3_id} path.link {{
            fill: none;
            stroke-width: 1.5px;
        }}
        #{d3_id} .node {{
            /*fill: #ccc;*/
            stroke: #333;
            stroke-width: 1.5px;
        }}
        #{d3_id} text {{
            font: 10px sans-serif;
            pointer-events: none;
        }}
        #{d3_id} text.shadow {{
            stroke: #fff;
            stroke-width: 3px;
            stroke-opacity: .8;
        }}
        #{d3_id} .node.sticky {{
            /* stroke-width: 2px; */
        }}
        """.format(d3_id=d3_id)
        js = """
        var links = graph.links;
        var nodes = graph.nodes;

        // Compute the distinct nodes from the links.
        links.forEach(function(link) {
            link.source = (nodes[link.source] ||
                           (nodes[link.source] = {name: link.source}));
            link.target = (nodes[link.target] ||
                           (nodes[link.target] = {name: link.target}));
        });

        var w = width || $(container).width(), h = height;

        var force = d3.layout.force()
            .nodes(d3.values(nodes))
            .links(links)
            .size([w, h])
            .linkDistance(60)
            .charge(-300)
            .on("tick", tick)
            .start();

        var svg = d3.select(container).append("svg:svg")
            .attr("width", w)
            .attr("height", h);

        // Per-type markers, as they don't inherit styles.
        svg.append("svg:defs").selectAll("marker")
            .data(["arrow"])
            .enter().append("svg:marker")
            .attr("id", String)
            .attr("viewBox", "0 -5 10 10")
            .attr("refX", 15)
            .attr("refY", -1.5)
            .attr("markerWidth", 6)
            .attr("markerHeight", 6)
            .attr("orient", "auto")
            .append("svg:path")
            .attr("d", "M0,-5L10,0L0,5");

        var path = svg.append("svg:g").selectAll("path")
            .data(force.links())
            .enter().append("svg:path")
            .attr("class", function(d) { return "link " + d.stroke; })
            .attr("stroke", function(d) { return d.stroke; })
            .attr("marker-end", function(d) { return "url(#arrow)"; });

        var circle = svg.append("svg:g").selectAll("circle")
            .data(force.nodes())
            .enter().append("svg:circle")
            .attr("fill", function(d) { return d.fill; })
            .attr("r", 6)
            .attr("class", "node")
            .call(force.drag)
            .on("mousedown", function(d) {
                d.fixed = true;
                d3.select(this).classed("sticky", true);
            });

        var text = svg.append("svg:g").selectAll("g")
            .data(force.nodes())
            .enter().append("svg:g");

        // A copy of the text with a thick white stroke for legibility.
        text.append("svg:text")
            .attr("x", 8)
            .attr("y", ".31em")
            .attr("class", "shadow")
            .text(function(d) { return d.label; });

        text.append("svg:text")
            .attr("x", 8)
            .attr("y", ".31em")
            .attr("class", "front")
            .text(function(d) { return d.label; });

        // Use elliptical arc path segments to doubly-encode directionality.
        function tick() {
            path.attr("d", function(d) {
                var dx = d.target.x - d.source.x,
                dy = d.target.y - d.source.y,
                dr = Math.sqrt(dx * dx + dy * dy);
                return ("M" + d.source.x + "," + d.source.y + "A"
                        + dr + "," + dr + " 0 0,1 " + d.target.x + ","
                        + d.target.y);
            });

            circle.attr("transform", function(d) {
                return "translate(" + d.x + "," + d.y + ")";
            });

            text.attr("transform", function(d) {
                return "translate(" + d.x + "," + d.y + ")";
            });
        }

        // Display options
        var display = $(container + "_display");
        graph.properties.forEach(function (property) {
            var option = $("<OPTION/>");
            option.text(property);
            option.attr("value", property);
            display.append(option);
        });
        display.on("change", function () {
            var selected = $(this).find(":selected").val(),
                displayFunc;
            if (selected.length !== 0) {
                displayFunc = function(d) {
                    return d.properties[selected];
                }
            } else {
                displayFunc = function(d) {
                    return d.label;
                }
            }
            text.select("text.front").text(displayFunc);
            text.select("text.shadow").text(displayFunc);
        });
        """
        return ("""
        <style type="text/css">
        {style}
        </style>

        <div class="accordion">
            <div class="accordion-group">
                <div class="accordion-heading">
                    <a class="accordion-toggle collapsed"
                       data-toggle="collapse" data-parent=""
                       href="#{d3_id}">
                        {d3_title}
                    </a>
                </div>
                <div id="{d3_id}" class="accordion-body in collapse">
                    <div class="accordion-inner">
                        <div id="{d3_container_id}">
                            <select id="{d3_container_id}_display">
                                <option value="">ID</option>
                            </select>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <script>
            var neo4jrestclient = window.neo4jrestclient || {{}};
            neo4jrestclient['{d3_uuid}'] = {{}};
            neo4jrestclient['{d3_uuid}'].graph = {d3_graph};
            neo4jrestclient['{d3_uuid}'].container_id = "{d3_container_id}";
            neo4jrestclient['{d3_uuid}'].container = "#{d3_container_id}";
            neo4jrestclient['{d3_uuid}'].render = function () {{
                (function (graph, container, width, height) {{
                    {js}
                }})(
                    neo4jrestclient['{d3_uuid}'].graph,
                    neo4jrestclient['{d3_uuid}'].container,
                    {width},
                    {height}
                );
            }}
            if (!window.d3) {{
                $.getScript(
                    "//d3js.org/d3.v2.js?2.9.1",
                    neo4jrestclient['{d3_uuid}'].render
                );
            }} else {{
                neo4jrestclient['{d3_uuid}'].render();
            }}
        </script>
        """.format(
            style=style,
            js=js,
            d3_graph=json.dumps(d3_graph),
            d3_id=d3_id,
            d3_uuid=d3_uuid,
            d3_title=d3_title,
            d3_container_id=d3_container_id,
            width=width,
            height=height,
        ))
19959
function Graphics()
{
    Container.call(this);

    /**
     * The alpha value used when filling the Graphics object.
     *
     * @member {number}
     * @default 1
     */
    this.fillAlpha = 1;

    /**
     * The width (thickness) of any lines drawn.
     *
     * @member {number}
     * @default 0
     */
    this.lineWidth = 0;

    /**
     * The color of any lines drawn.
     *
     * @member {string}
     * @default 0
     */
    this.lineColor = 0;

    /**
     * Graphics data
     *
     * @member {GraphicsData[]}
     * @private
     */
    this.graphicsData = [];

    /**
     * The tint applied to the graphic shape. This is a hex value. Apply a value of 0xFFFFFF to reset the tint.
     *
     * @member {number}
     * @default 0xFFFFFF
     */
    this.tint = 0xFFFFFF;

    /**
     * The previous tint applied to the graphic shape. Used to compare to the current tint and check if theres change.
     *
     * @member {number}
     * @private
     * @default 0xFFFFFF
     */
    this._prevTint = 0xFFFFFF;

    /**
     * The blend mode to be applied to the graphic shape. Apply a value of blendModes.NORMAL to reset the blend mode.
     *
     * @member {number}
     * @default CONST.BLEND_MODES.NORMAL;
     */
    this.blendMode = CONST.BLEND_MODES.NORMAL;

    /**
     * Current path
     *
     * @member {GraphicsData}
     * @private
     */
    this.currentPath = null;

    /**
     * Array containing some WebGL-related properties used by the WebGL renderer.
     *
     * @member {object<number, object>}
     * @private
     */
    // TODO - _webgl should use a prototype object, not a random undocumented object...
    this._webGL = {};

    /**
     * Whether this shape is being used as a mask.
     *
     * @member {boolean}
     */
    this.isMask = false;

    /**
     * The bounds' padding used for bounds calculation.
     *
     * @member {number}
     */
    this.boundsPadding = 0;

    /**
     * A cache of the local bounds to prevent recalculation.
     *
     * @member {Rectangle}
     * @private
     */
    this._localBounds = new math.Rectangle(0,0,1,1);

    /**
     * Used to detect if the graphics object has changed. If this is set to true then the graphics
     * object will be recalculated.
     *
     * @member {boolean}
     * @private
     */
    this.dirty = true;

    /**
     * Used to detect if the WebGL graphics object has changed. If this is set to true then the
     * graphics object will be recalculated.
     *
     * @member {boolean}
     * @private
     */
    this.glDirty = false;

    this.boundsDirty = true;

    /**
     * Used to detect if the cached sprite object needs to be updated.
     *
     * @member {boolean}
     * @private
     */
    this.cachedSpriteDirty = false;
}