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

Relate js, css, html path

上级 27ee6095
...@@ -26,7 +26,6 @@ doc/indexes/oplist.txt ...@@ -26,7 +26,6 @@ doc/indexes/oplist.txt
doc/indexes/typelist.txt doc/indexes/typelist.txt
html html
pdf pdf
pull.sh
setuptools-*.egg setuptools-*.egg
theano/generated_version.py theano/generated_version.py
theano/generated_version.py.out theano/generated_version.py.out
...@@ -39,4 +38,3 @@ Theano.suo ...@@ -39,4 +38,3 @@ Theano.suo
doc/d3printing/GSoC/150724_opfrom/bundle/ doc/d3printing/GSoC/150724_opfrom/bundle/
doc/d3printing/GSoC/150724_opfrom/bundle2/ doc/d3printing/GSoC/150724_opfrom/bundle2/
...@@ -3,14 +3,13 @@ ...@@ -3,14 +3,13 @@
# Authors: Christof Angermueller <cangermueller@gmail.com> # Authors: Christof Angermueller <cangermueller@gmail.com>
import os import os
import os.path as pt
from glob import glob from glob import glob
import shutil import shutil
from theano.printing import pydotprint
from formatting import GraphFormatter from formatting import GraphFormatter
__path__ = pt.dirname(pt.realpath(__file__))
__path__ = os.path.dirname(os.path.realpath(__file__))
def replace_patterns(x, replace): def replace_patterns(x, replace):
...@@ -20,20 +19,6 @@ def replace_patterns(x, replace): ...@@ -20,20 +19,6 @@ def replace_patterns(x, replace):
return x 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): def d3write(fct, path, *args, **kwargs):
# Convert theano graph to pydot graph and write to file # Convert theano graph to pydot graph and write to file
gf = GraphFormatter(*args, **kwargs) gf = GraphFormatter(*args, **kwargs)
...@@ -49,22 +34,25 @@ def d3print(fct, outfile, *args, **kwargs): ...@@ -49,22 +34,25 @@ def d3print(fct, outfile, *args, **kwargs):
:param outfile: The output file :param outfile: The output file
""" """
outdir = os.path.dirname(outfile) outdir = pt.dirname(outfile)
if not os.path.exists(outdir): if not pt.exists(outdir):
os.makedirs(outdir) os.makedirs(outdir)
# Create dot file # Create dot file
dot_file = os.path.splitext(outfile)[0] + '.dot' dot_file = pt.splitext(outfile)[0] + '.dot'
d3write(fct, dot_file, *args, **kwargs) d3write(fct, dot_file, *args, **kwargs)
# Read template HTML file
# Read template HTML file and replace variables template_file = pt.join(__path__, 'html', 'template.html')
template_file = os.path.join(__path__, 'template.html')
f = open(template_file) f = open(template_file)
template = f.read() template = f.read()
f.close() f.close()
# Replace patterns in template
replace = { 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) html = replace_patterns(template, replace)
...@@ -73,9 +61,3 @@ def d3print(fct, outfile, *args, **kwargs): ...@@ -73,9 +61,3 @@ def d3print(fct, outfile, *args, **kwargs):
f = open(outfile, 'w') f = open(outfile, 'w')
f.write(html) f.write(html)
f.close() 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): ...@@ -173,7 +173,7 @@ class GraphFormatter(object):
list.__add__, node.op.destroy_map.values(), []): list.__add__, node.op.destroy_map.values(), []):
edge_params['color'] = 'red' edge_params['color'] = 'red'
edge_label = str(var.type) edge_label = vparams['dtype']
if len(node.inputs) > 1: if len(node.inputs) > 1:
edge_label = str(id) + ' ' + edge_label edge_label = str(id) + ' ' + edge_label
pdedge = pd.Edge(var_id, node_id, label=edge_label, pdedge = pd.Edge(var_id, node_id, label=edge_label,
...@@ -199,9 +199,9 @@ class GraphFormatter(object): ...@@ -199,9 +199,9 @@ class GraphFormatter(object):
pd_var = self.dict_to_pdnode(vparams) pd_var = self.dict_to_pdnode(vparams)
graph.add_node(pd_var) 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: 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): if isinstance(node.op, builders.OpFromGraph):
subgraph = pd.Cluster(node_id) subgraph = pd.Cluster(node_id)
......
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<link rel="stylesheet" href="d3-context-menu.css"/> <link rel="stylesheet" href="%% CSS_DIR %%/d3-context-menu.css"/>
<link rel="stylesheet" href="d3theano.css"/> <link rel="stylesheet" href="%% CSS_DIR %%/d3theano.css"/>
<script type="text/javascript" src="d3.v3.min.js"></script> <script type="text/javascript" src="%% JS_DIR %%/d3.v3.min.js"></script>
<script type='text/javascript' src="dagre-d3.js"></script> <script type='text/javascript' src="%% JS_DIR %%/dagre-d3.js"></script>
<script type='text/javascript' src="graphlib-dot.js"></script> <script type='text/javascript' src="%% JS_DIR %%/graphlib-dot.js"></script>
<script src="d3-context-menu.js"></script> <script src="%% JS_DIR %%/d3-context-menu.js"></script>
<script src="d3theano.js"></script> <script src="%% JS_DIR %%/d3theano.js"></script>
</head> </head>
<body> <body>
<div id='menu'> <div id='menu'>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论