提交 406ed6f1 authored 作者: Christof Angermueller's avatar Christof Angermueller

Relate js, css, html path

上级 27ee6095
......@@ -26,7 +26,6 @@ doc/indexes/oplist.txt
doc/indexes/typelist.txt
html
pdf
pull.sh
setuptools-*.egg
theano/generated_version.py
theano/generated_version.py.out
......@@ -39,4 +38,3 @@ Theano.suo
doc/d3printing/GSoC/150724_opfrom/bundle/
doc/d3printing/GSoC/150724_opfrom/bundle2/
......@@ -3,14 +3,13 @@
# Authors: Christof Angermueller <cangermueller@gmail.com>
import os
import os.path as pt
from glob import glob
import shutil
from theano.printing import pydotprint
from formatting import GraphFormatter
__path__ = os.path.dirname(os.path.realpath(__file__))
__path__ = pt.dirname(pt.realpath(__file__))
def replace_patterns(x, replace):
......@@ -20,20 +19,6 @@ def replace_patterns(x, replace):
return x
def d3dot(fct, node_colors=None, *args, **kwargs):
if node_colors is None:
node_colors = {'input': 'limegreen',
'output': 'dodgerblue',
'unused': 'lightgrey'
}
dot_graph = pydotprint(fct, format='dot', return_image=True,
node_colors=node_colors, *args, **kwargs)
dot_graph = dot_graph.replace('\n', ' ')
dot_graph = dot_graph.replace('node [label="\N"];', '')
return dot_graph
def d3write(fct, path, *args, **kwargs):
# Convert theano graph to pydot graph and write to file
gf = GraphFormatter(*args, **kwargs)
......@@ -49,22 +34,25 @@ def d3print(fct, outfile, *args, **kwargs):
:param outfile: The output file
"""
outdir = os.path.dirname(outfile)
if not os.path.exists(outdir):
outdir = pt.dirname(outfile)
if not pt.exists(outdir):
os.makedirs(outdir)
# Create dot file
dot_file = os.path.splitext(outfile)[0] + '.dot'
dot_file = pt.splitext(outfile)[0] + '.dot'
d3write(fct, dot_file, *args, **kwargs)
# Read template HTML file and replace variables
template_file = os.path.join(__path__, 'template.html')
# Read template HTML file
template_file = pt.join(__path__, 'html', 'template.html')
f = open(template_file)
template = f.read()
f.close()
# Replace patterns in template
replace = {
'%% DOT_FILE %%': os.path.basename(dot_file),
'%% JS_DIR %%': pt.join(__path__, 'js'),
'%% CSS_DIR %%': pt.join(__path__, 'css'),
'%% DOT_FILE %%': pt.basename(dot_file),
}
html = replace_patterns(template, replace)
......@@ -73,9 +61,3 @@ def d3print(fct, outfile, *args, **kwargs):
f = open(outfile, 'w')
f.write(html)
f.close()
# Copy dependencies
deps = glob(os.path.join(__path__, 'javascript', '*'))
for dep in deps:
o = os.path.join(outdir, os.path.basename(dep))
shutil.copyfile(dep, o)
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<script type='text/javascript' src="http://cpettitt.github.io/project/dagre-d3/v0.1.5/dagre-d3.min.js"></script>
<script type='text/javascript' src="http://cpettitt.github.io/project/graphlib-dot/v0.4.10/graphlib-dot.min.js"></script>
</head>
<body>
<style>
.svg {
margin-left:auto;
margin-right:auto;
display:block;
position: fixed;
border: 2px solid black;
top:1%; left:1%; right:1% bottom=1%
}
.nodeRect {
stroke: black;
border: 3px solid black;
}
.nodeEllipse {
stroke: black;
border: 3px solid black;
}
.nodeText {
color: black;
}
.edge {
stroke: black;
stroke-width: 3px;
cursor: pointer;
}
.edgeLabelRect {
stroke: black;
border: 1px solid black;
fill: skyblue;
opacity: 0.9;
}
.edgeLabelText {
fill: black;
text-anchor: start;
}
.arrowHead {
stroke: black;
stroke-width: 3px;
fill: black;
}
</style>
<input type="file" id="files" name="fileSelector"/>
<script type="text/javascript">
function dotViz(path) {
console.log(path);
// Global attributes
var pad = 10;
d3.select('body').select('svg').remove();
var svg = d3.select('body').append('svg')
.attr('class', 'svg')
.attr('width', '90%')
.attr('height', '90%');
var pane = svg.append('g');
// Definition head of edges
svg.append("defs").append("marker")
.attr("id", 'edgeArrow')
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("refX", 3)
.attr("refY", 3)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,0 L6,3 L0,6 Z")
.attr('style', 'arrowHead');
function textSize(text, attr) {
var t = svg.append('text').text(text);
if (typeof(attr) != 'undefined') {
for (a in attr) {
t.attr(a, attr[a]);
}
}
var bbox = t.node().getBBox();
t.remove();
return bbox;
}
var dotGraph;
var graph = {};
var nodes = [];
var edges = [];
d3.text(path, function(data) {
dotGraph = graphlibDot.parse(data);
// Calculate width and height
var posMax = [0, 0];
for (var nodeId in dotGraph._nodes) {
var node = dotGraph._nodes[nodeId];
node.value.pos = node.value.pos.split(',').map(function(d) {return parseInt(d);});
node.value.width = parseInt(node.value.width);
node.value.height = parseInt(node.value.height);
posMax[0] = Math.max(posMax[0], node.value.pos[0] + node.value.width);
posMax[1] = Math.max(posMax[1], node.value.pos[1] + node.value.height);
}
dotWidth = posMax[0];
dotHeight = posMax[1];
svg.attr('viewBox', '0,0,' + dotWidth + ',' + dotHeight);
var scaleDotX = d3.scale.linear().domain([0, dotWidth + 100]).range([0, dotWidth]);
var scaleDotY = d3.scale.linear().domain([-25, dotHeight + 100]).range([0, dotHeight]);
// Parse nodes
var i = 0;
for (nodeId in dotGraph._nodes) {
var node = dotGraph._nodes[nodeId];
node.index = i++;
// x, y is center of node (not corner)
node.x = scaleDotX(node.value.pos[0]);
node.y = scaleDotY(dotHeight - (node.value.pos[1] + node.value.height));
var size = textSize(node.value.label, {'class': 'nodeText'});
node.value.width = size.width + 2 * pad;
node.value.height = size.height + 2 * pad;
node.value.cx = node.value.width / 2;
node.value.cy = node.value.height / 2;
node.fixed = true;
nodes.push(node);
dotGraph._nodes[nodeId] = node;
}
// Parse edges
for (edgeId in dotGraph._edges) {
var edge = dotGraph._edges[edgeId];
edge.source = dotGraph._nodes[edge.u].index;
edge.target = dotGraph._nodes[edge.v].index;
var size = textSize(edge.value.label, {'class': 'edgeLabelText'});
edge.value.width = size.width + 2 * pad;
edge.value.height = size.height + 2 * pad;
edges.push(edge);
dotGraph._edges[edgeId] = edge;
}
// Setup graph
graph['nodes'] = nodes;
graph['edges'] = edges;
var isEdgeOver = false;
var isEdgeLabelOver = false;
// Add edges
edges = pane.append('g').attr('id', 'edges').selectAll('path').data(graph['edges']).enter().append('path')
.attr('class', 'edge')
.attr('marker-mid', 'url(#edgeArrow)')
.on('mouseover', function(d) {
var edgeLabel = pane.select('#edgeLabels .' + d.id);
edgeLabel.attr('style', 'display: inline');
})
.on('mouseout', function(d) {
if (!isEdgeLabelOver) {
var edgeLabel = pane.select('#edgeLabels .' + d.id);
edgeLabel.attr('style', 'display: none');
}
});
// Add edge labels
edgeLabels = pane.append('g').attr('id', 'edgeLabels').selectAll('g').data(graph['edges']).enter().append('g')
.attr('style', 'display: none')
.attr('class', function(d) {return d.id;})
.on('mouseover', function(d) {
isEdgeLabelOver = true;
var edgeLabel = d3.select(this);
edgeLabel.attr('style', 'display: inline');
})
.on('mouseout', function(d) {
var edgeLabel = d3.select(this);
edgeLabel.attr('style', 'display: none');
isEdgeLabelOver = false;
});
var edgeLabelsRect = edgeLabels.append('rect')
.attr('class', 'edgeLabelRect')
.attr('fill', 'white')
.attr('width', function(d) {return d.value.width;})
.attr('height', function(d) {return d.value.height;})
.attr('rx', 5)
.attr('ry', 5);
var edgeLabelsText = edgeLabels.append('text')
.attr('class', 'edgeLabelText')
.attr('x', function(d) {return pad;})
.attr('dy', function(d) {return d.value.height - pad - 5;})
.text(function(d) {return d.value.label;});
// Add nodes
nodes = pane.append('g').attr('id', 'nodes').selectAll('g').data(graph['nodes']).enter().append('g');
function fillColor(f) {
return typeof(f) == 'undefined' ? 'white' : f;
}
nodes.each(function(d) {
sel = d3.select(this);
var shape;
if (d.value.shape == 'ellipse') {
shape = sel.append('ellipse')
.attr('class', 'nodeEllipse')
.attr('cx', d.value.cx)
.attr('cy', d.value.cy)
.attr('rx', d.value.width * 0.6)
.attr('ry', d.value.height * 0.6);
} else {
shape = sel.append('rect')
.attr('class', 'nodeRect')
.attr('width', d.value.width)
.attr('height', d.value.height);
}
shape.attr('fill', fillColor(d.value.fillcolor));
});
var nodesText = nodes.append('text')
.attr('class', 'nodeText')
.attr('x', pad)
.attr('dy', function(d) {return d.value.height - pad - 5;})
.text(function(d) {return d.value.label;});
// Update graph
function updateGraph() {
// Update nodes
nodes.attr('transform', function(d) { return 'translate(' + (d.x - d.value.cx) + ' ' + (d.y - d.value.cy) + ')'; });
// Update edges
edges.attr('d', function(d) {
return 'M' + d.source.x + ',' + d.source.y + ' L' + 0.5 * (d.source.x + d.target.x) + ',' + 0.5 * (d.source.y + d.target.y) + ' L' + d.target.x + ',' + d.target.y;
});
// Update edge labels
edgeLabels.attr('transform', function(d) {
return 'translate(' + (0.5 * (d.source.x + d.target.x - d.value.width)) + ',' + (0.5 * (d.source.y + d.target.y - d.value.height)) + ')';
});
}
// Drag-start event handler
function dragStart(d) {
d3.event.sourceEvent.stopPropagation();
d.fixed = true;
}
// Zoom and translate event handler
function zoom(d) {
pane.attr('transform', 'translate(' + d3.event.translate + ') scale(' + d3.event.scale + ')');
}
// Force layout
var layout = d3.layout.force()
.nodes(graph['nodes'])
.links(graph['edges'])
.size([dotWidth, dotHeight])
.gravity(0.2)
.charge(-6000)
.linkDistance(75)
.linkStrength(0.1)
.on('tick', updateGraph);
// Drag behavour
var drag = layout.drag()
.on('dragstart', dragStart);
nodes.call(drag);
// Zoom behaviour
var bZoom = d3.behavior.zoom()
.scaleExtent([0.2, 8])
.on('zoom', zoom);
svg.call(bZoom);
// Start force layout
//updateGraph();
layout.start();
});
}
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
dotViz(files[0].name);
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
</body>
</html>
......@@ -173,7 +173,7 @@ class GraphFormatter(object):
list.__add__, node.op.destroy_map.values(), []):
edge_params['color'] = 'red'
edge_label = str(var.type)
edge_label = vparams['dtype']
if len(node.inputs) > 1:
edge_label = str(id) + ' ' + edge_label
pdedge = pd.Edge(var_id, node_id, label=edge_label,
......@@ -199,9 +199,9 @@ class GraphFormatter(object):
pd_var = self.dict_to_pdnode(vparams)
graph.add_node(pd_var)
graph.add_edge(pd.Edge(node_id, var_id, label=str(var.type)))
graph.add_edge(pd.Edge(node_id, var_id, label=vparams['dtype']))
elif var.name or not self.compact:
graph.add_edge(pd.Edge(node_id, var_id, label=str(var.type)))
graph.add_edge(pd.Edge(node_id, var_id, label=vparams['dtype']))
if isinstance(node.op, builders.OpFromGraph):
subgraph = pd.Cluster(node_id)
......
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="d3-context-menu.css"/>
<link rel="stylesheet" href="d3theano.css"/>
<script type="text/javascript" src="d3.v3.min.js"></script>
<script type='text/javascript' src="dagre-d3.js"></script>
<script type='text/javascript' src="graphlib-dot.js"></script>
<script src="d3-context-menu.js"></script>
<script src="d3theano.js"></script>
<link rel="stylesheet" href="%% CSS_DIR %%/d3-context-menu.css"/>
<link rel="stylesheet" href="%% CSS_DIR %%/d3theano.css"/>
<script type="text/javascript" src="%% JS_DIR %%/d3.v3.min.js"></script>
<script type='text/javascript' src="%% JS_DIR %%/dagre-d3.js"></script>
<script type='text/javascript' src="%% JS_DIR %%/graphlib-dot.js"></script>
<script src="%% JS_DIR %%/d3-context-menu.js"></script>
<script src="%% JS_DIR %%/d3theano.js"></script>
</head>
<body>
<div id='menu'>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论