mirror of
https://github.com/Quodatum/graphxq.git
synced 2025-04-11 11:42:24 +01:00
update libraries, use d3 for svg
This commit is contained in:
parent
922e1066ef
commit
632af43220
20 changed files with 1082 additions and 58 deletions
7
.settings/de.loskutov.FileSync.prefs
Normal file
7
.settings/de.loskutov.FileSync.prefs
Normal file
|
@ -0,0 +1,7 @@
|
|||
WARNING=DO NOT MODIFY THIS FILE IF YOU DON'T UNDERSTAND
|
||||
defaultDestination=C\:/Program Files (x86)/basex/webapp
|
||||
defaultVariables=
|
||||
eclipse.preferences.version=1
|
||||
includeTeamPrivateFiles=false
|
||||
map|0=src|,|,|,|,
|
||||
useCurrentDateForDestinationFiles=false
|
11
src/graphxq/cxan.xml
Normal file
11
src/graphxq/cxan.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<package xmlns="http://cxan.org/ns/package" id="graphxq">
|
||||
<abstract>Network graphs using Graphviz and DotML</abstract>
|
||||
<author id="abunce">Andy Bunce</author>
|
||||
<maintainer id="abunce">Andy Bunce</maintainer>
|
||||
<home>https://github.com/apb2006/graphxq</home>
|
||||
<category id="apps">Applications</category>
|
||||
<tag>basex</tag>
|
||||
<tag>restxq</tag>
|
||||
<tag>graph</tag>
|
||||
<tag>svg</tag>
|
||||
</package>
|
|
@ -1,7 +1,9 @@
|
|||
<package abbrev="graphxq" name="https://github.com/apb2006/graphxq"
|
||||
version="0.6" spec="1.0" xmlns="http://expath.org/ns/pkg">
|
||||
version="0.7" spec="1.0" xmlns="http://expath.org/ns/pkg">
|
||||
<title>Graphxq</title>
|
||||
<dependency name="twitter-bootstrap" version="3.3.1" />
|
||||
<dependency name="svg-pan-zoom" version="3.2.8" />
|
||||
<dependency name="jquery" version="2.0.2" />
|
||||
<dependency name="ace" version="1.1.8" />
|
||||
<dependency name="ace" version="1.2.3" />
|
||||
<dependency name="d3" version="3" />
|
||||
</package>
|
10
src/graphxq/graphml/default.css
Normal file
10
src/graphxq/graphml/default.css
Normal file
|
@ -0,0 +1,10 @@
|
|||
.node > rect {
|
||||
fill:silver;
|
||||
}
|
||||
.node > text {
|
||||
font-size:24;
|
||||
font-weight:bold;
|
||||
}
|
||||
.edge {
|
||||
fill:black;
|
||||
}
|
120
src/graphxq/graphml/full.xsl
Normal file
120
src/graphxq/graphml/full.xsl
Normal file
|
@ -0,0 +1,120 @@
|
|||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg">
|
||||
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
|
||||
|
||||
<!-- for a 'graph' element, creates an 'svg' element -->
|
||||
<xsl:template match="graph">
|
||||
<!-- first give a CSS reference for the generated SVG -->
|
||||
<xsl:processing-instruction name="xml-stylesheet">type="text/css" href="default.css"</xsl:processing-instruction>
|
||||
<svg>
|
||||
<!-- defs section for the arrow -->
|
||||
<defs>
|
||||
<marker id="arrow" refX="5" refY="5" markerUnits="userSpaceOnUse" markerWidth="10" markerHeight="10" orient="auto">
|
||||
<path class="edge" d="M0 0 10 5 0 10z"/>
|
||||
</marker>
|
||||
</defs>
|
||||
<!-- ... -->
|
||||
<!-- recurse 'node' elements of the graph to find graph root -->
|
||||
<xsl:apply-templates select="node"/>
|
||||
</svg>
|
||||
</xsl:template>
|
||||
|
||||
<!-- recurse 'node' element to find graph root -->
|
||||
<xsl:template match="node">
|
||||
<!-- check if the first 'edge' has current 'node' as target -->
|
||||
<xsl:apply-templates select="../edge[1]">
|
||||
<xsl:with-param name="n" select="."/>
|
||||
</xsl:apply-templates>
|
||||
</xsl:template>
|
||||
|
||||
<!-- check if a 'node' ($n) is a target of the current 'edge' -->
|
||||
<xsl:template match="edge">
|
||||
<xsl:param name="n">null</xsl:param>
|
||||
<!-- if the 'node' is not a target of the current 'edge' -->
|
||||
<xsl:if test="not(@target=$n/@id)">
|
||||
<!-- advance to the next edge -->
|
||||
<xsl:apply-templates select="following-sibling::edge[position()=1]">
|
||||
<xsl:with-param name="n" select="$n"/>
|
||||
</xsl:apply-templates>
|
||||
<!-- if all edges have been queried -->
|
||||
<xsl:if test="not(following-sibling::edge[position()=1])">
|
||||
<!-- the 'node' ($n) is the root, create it -->
|
||||
<xsl:call-template name="create-node">
|
||||
<xsl:with-param name="n" select="$n"/>
|
||||
</xsl:call-template>
|
||||
</xsl:if>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<!-- transform a 'node' to SVG and recurse trough its children -->
|
||||
<xsl:template name="create-node">
|
||||
<xsl:param name="n">null</xsl:param>
|
||||
<xsl:param name="level">0</xsl:param>
|
||||
<xsl:param name="count">0</xsl:param>
|
||||
<xsl:param name="edge">null</xsl:param>
|
||||
<xsl:param name="x1">0</xsl:param>
|
||||
<xsl:param name="y1">0</xsl:param>
|
||||
<!-- some helpers -->
|
||||
<xsl:variable name="side" select="1-2*($count mod 2)"/>
|
||||
<xsl:variable name="x" select="$level*150"/>
|
||||
<xsl:variable name="y" select="$y1 - 50+$side*ceiling($count div 2)*150"/>
|
||||
<!-- create the 'node' itself and position it -->
|
||||
<g class="node">
|
||||
<rect x="{$x}" y="{$y}" width="100" height="100"/>
|
||||
<text text-anchor="middle" x="{$x+50}" y="{$y+55}">
|
||||
<xsl:value-of select="$n/@id"/>
|
||||
</text>
|
||||
</g>
|
||||
<!-- if there is an 'edge' ($edge) draw it -->
|
||||
<xsl:if test="$edge!='null'">
|
||||
<!-- the 'edge' position goes from previous 'node' position to $n one -->
|
||||
<line class="edge" x1="{$x1}" y1="{$y1}" x2="{$x}" y2="{$y+50}">
|
||||
<xsl:attribute name="style">marker-end:url(#arrow)</xsl:attribute>
|
||||
</line>
|
||||
</xsl:if>
|
||||
<!-- now that the 'node' is created, recurse to children through edges -->
|
||||
<xsl:call-template name="query-edge">
|
||||
<xsl:with-param name="edge" select="$n/../edge[@source=$n/@id][1]"/>
|
||||
<xsl:with-param name="x1" select="$x+100"/>
|
||||
<xsl:with-param name="y1" select="$y+50"/>
|
||||
<xsl:with-param name="n" select="$n"/>
|
||||
<!-- going to the upper level, increment level -->
|
||||
<xsl:with-param name="level" select="$level+1"/>
|
||||
<!-- going to the first child, set counter to 0 -->
|
||||
<xsl:with-param name="count" select="0"/>
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
<!-- recurse a 'node' ($n) edges to find 'node' children -->
|
||||
<xsl:template name="query-edge">
|
||||
<xsl:param name="edge">null</xsl:param>
|
||||
<xsl:param name="x1">0</xsl:param>
|
||||
<xsl:param name="y1">0</xsl:param>
|
||||
<xsl:param name="n">null</xsl:param>
|
||||
<xsl:param name="level">0</xsl:param>
|
||||
<xsl:param name="count">0</xsl:param>
|
||||
<xsl:variable name="target" select="$edge/@target"/>
|
||||
<!-- if there is an 'edge' -->
|
||||
<xsl:if test="$edge!='null'">
|
||||
<!-- go down the tree, create the 'node' of the 'edge' target -->
|
||||
<xsl:call-template name="create-node">
|
||||
<xsl:with-param name="n" select="$edge/../node[@id=$target]"/>
|
||||
<xsl:with-param name="level" select="$level"/>
|
||||
<xsl:with-param name="count" select="$count"/>
|
||||
<xsl:with-param name="edge" select="$edge"/>
|
||||
<xsl:with-param name="x1" select="$x1"/>
|
||||
<xsl:with-param name="y1" select="$y1"/>
|
||||
</xsl:call-template>
|
||||
<!-- go to the next 'edge' that has also the 'node' ($n) has source -->
|
||||
<xsl:variable name="next-edge" select="$edge/following-sibling::edge[position()=1][@source=$n/@id]"/>
|
||||
<xsl:call-template name="query-edge">
|
||||
<xsl:with-param name="edge" select="$next-edge"/>
|
||||
<xsl:with-param name="x1" select="$x1"/>
|
||||
<xsl:with-param name="y1" select="$y1"/>
|
||||
<xsl:with-param name="n" select="$n"/>
|
||||
<xsl:with-param name="level" select="$level"/>
|
||||
<!-- next 'edge', increment counter -->
|
||||
<xsl:with-param name="count" select="$count+1"/>
|
||||
</xsl:call-template>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
60
src/graphxq/graphml/graphml.xsl
Normal file
60
src/graphxq/graphml/graphml.xsl
Normal file
|
@ -0,0 +1,60 @@
|
|||
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:graphml2svg="http://www.sample.org/graphml2svg"
|
||||
>
|
||||
<!--
|
||||
http://www.svgopen.org/2003/papers/ComparisonXML2SVGTransformationMechanisms
|
||||
-->
|
||||
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
|
||||
<!-- for a 'graph' element, creates an 'svg' element -->
|
||||
<xsl:template match="graph">
|
||||
<!-- first give a CSS reference for the generated SVG -->
|
||||
<xsl:processing-instruction name="xml-stylesheet">type="text/css" href="default.css"</xsl:processing-instruction>
|
||||
<svg>
|
||||
<!-- defs section for the arrow -->
|
||||
<!-- ... -->
|
||||
<xsl:apply-templates select="graphml2svg:getroot()"/>
|
||||
</svg>
|
||||
</xsl:template>
|
||||
<!-- transform a 'node' to SVG -->
|
||||
<xsl:template match="node">
|
||||
<xsl:variable name="x1">0</xsl:variable>
|
||||
<xsl:variable name="y1">0</xsl:variable>
|
||||
<!-- some helpers -->
|
||||
<xsl:variable name="level" select="graphml2svg:getlevel()"/>
|
||||
<xsl:variable name="count" select="graphml2svg:getindex()"/>
|
||||
<xsl:variable name="edge" select="graphml2svg:getedge()"/>
|
||||
<xsl:variable name="side" select="1-2*($count mod 2)"/>
|
||||
<xsl:variable name="x" select="$level*150"/>
|
||||
<xsl:variable name="y" select="$y1 - 50+$side*ceiling($count div 2)*150"/>
|
||||
<!-- create the 'node' itself and position it -->
|
||||
<g class="node">
|
||||
<rect x="{$x}" y="{$y}" width="100" height="100"/>
|
||||
<text text-anchor="middle" x="{$x+50}" y="{$y+55}">
|
||||
<xsl:value-of select="./@id"/>
|
||||
</text>
|
||||
</g>
|
||||
<!-- if there is an 'edge' ($edge) to draw it -->
|
||||
<xsl:if test="$edge!='null'">
|
||||
<!-- the 'edge' position goes from previous 'node' position to $n one -->
|
||||
<line class="edge" x1="{$x1}" y1="{$y1}" x2="{$x}" y2="{$y+50}">
|
||||
<xsl:attribute name="style">marker-end:url(#arrow)</xsl:attribute>
|
||||
</line>
|
||||
</xsl:if>
|
||||
<!-- now that the 'node' is created, go to children -->
|
||||
<xsl:apply-templates select="graphml2svg:getchildren()">
|
||||
<xsl:with-param name="x1" select="$x+100"/>
|
||||
<xsl:with-param name="y1" select="$y+50"/>
|
||||
</xsl:apply-templates>
|
||||
</xsl:template>
|
||||
<xsl:function name="graphml2svg:getroot">
|
||||
</xsl:function>
|
||||
<xsl:function name="graphml2svg:getchildren">
|
||||
</xsl:function>
|
||||
<xsl:function name="graphml2svg:getlevel">
|
||||
</xsl:function>
|
||||
<xsl:function name="graphml2svg:getindex">
|
||||
</xsl:function>
|
||||
<xsl:function name="graphml2svg:getedge">
|
||||
</xsl:function>
|
||||
</xsl:stylesheet>
|
31
src/graphxq/graphml/out.svg
Normal file
31
src/graphxq/graphml/out.svg
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?xml-stylesheet type="text/css" href="default.css"?><svg xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<marker id="arrow" refX="5" refY="5" markerUnits="userSpaceOnUse" markerWidth="10" markerHeight="10" orient="auto">
|
||||
<path class="edge" d="M0 0 10 5 0 10z"/>
|
||||
</marker>
|
||||
</defs>
|
||||
<g class="node">
|
||||
<rect x="0" y="-50" width="100" height="100"/>
|
||||
<text text-anchor="middle" x="50" y="5">n1</text>
|
||||
</g>
|
||||
<g class="node">
|
||||
<rect x="150" y="-50" width="100" height="100"/>
|
||||
<text text-anchor="middle" x="200" y="5">n2</text>
|
||||
</g>
|
||||
<line class="edge" x1="100" y1="0" x2="150" y2="0" style="marker-end:url(#arrow)"/>
|
||||
<g class="node">
|
||||
<rect x="300" y="-50" width="100" height="100"/>
|
||||
<text text-anchor="middle" x="350" y="5">n4</text>
|
||||
</g>
|
||||
<line class="edge" x1="250" y1="0" x2="300" y2="0" style="marker-end:url(#arrow)"/>
|
||||
<g class="node">
|
||||
<rect x="300" y="-200" width="100" height="100"/>
|
||||
<text text-anchor="middle" x="350" y="-145">n4</text>
|
||||
</g>
|
||||
<line class="edge" x1="250" y1="0" x2="300" y2="-150" style="marker-end:url(#arrow)"/>
|
||||
<g class="node">
|
||||
<rect x="150" y="-200" width="100" height="100"/>
|
||||
<text text-anchor="middle" x="200" y="-145">n3</text>
|
||||
</g>
|
||||
<line class="edge" x1="100" y1="0" x2="150" y2="-150" style="marker-end:url(#arrow)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
11
src/graphxq/graphml/sample.graphml
Normal file
11
src/graphxq/graphml/sample.graphml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<graph edgedefault="directed">
|
||||
<desc>GraphML sample</desc>
|
||||
<node id="n1"/>
|
||||
<node id="n2"/>
|
||||
<node id="n3"/>
|
||||
<node id="n4"/>
|
||||
<edge source="n1" target="n2"/>
|
||||
<edge source="n1" target="n3"/>
|
||||
<edge source="n2" target="n4"/>
|
||||
<edge source="n2" target="n4" directed="false"/>
|
||||
</graph>
|
|
@ -107,6 +107,13 @@ declare
|
|||
function api(){
|
||||
render("views/api.xml",map{"title": "API information"})
|
||||
};
|
||||
(:~ static d3test page :)
|
||||
declare
|
||||
%restxq:GET %restxq:path("graphxq/testd3")
|
||||
%output:method("html") %output:version("5.0")
|
||||
function testd3(){
|
||||
render("views/testd3.xml",map{"title": "d3 test"})
|
||||
};
|
||||
|
||||
(:~ static ace page :)
|
||||
declare
|
||||
|
|
|
@ -23,9 +23,24 @@ node[shape=circle,style=filled,fillcolor=lightblue]
|
|||
|
||||
}}</textarea>
|
||||
</div>
|
||||
<div class="col-md-6" id="rightPane">
|
||||
<div id="svgdiv" class="extend"
|
||||
style="width:100%;height:30em;border: 1px solid #E3E3E3;min-height:10em;">{$svgwidget}</div>
|
||||
<div class="col-md-6" id="rightPane" style="background-color:red;">
|
||||
<div id="svgdiv" class="extend">
|
||||
<div id="canvasQwpYZa" class="canvas" style="width:100%;height:100%;"></div>
|
||||
<script>
|
||||
var canvas = d3.demo.canvas();
|
||||
d3.select("#canvasQwpYZa").call(canvas);
|
||||
|
||||
d3.select("#resetButtonQwpYZa").on("click", function() {{
|
||||
canvas.reset();
|
||||
}});
|
||||
|
||||
function replaceItem(item) {{
|
||||
canvas.clear();
|
||||
canvas.addItem(d3.select(item));
|
||||
canvas.reset();
|
||||
}};
|
||||
</script>
|
||||
</div>
|
||||
<div id="svgsrc" class="extend ace-container" style="display: none">
|
||||
<div id="svgsrc2" class="ace " data-mode="svg" data-readonly="1">(no svg loaded)</div>
|
||||
</div>
|
||||
|
|
|
@ -20,8 +20,26 @@ declare variable $svgwidget external :="{svg}";
|
|||
</graph></textarea>
|
||||
</div>
|
||||
<div class="col-md-6" id="rightPane">
|
||||
<div id="svgdiv" class="extend"
|
||||
style="width:100%;height:30em;border: 1px solid #E3E3E3;min-height:10em;">{$svgwidget}</div>
|
||||
<div id="svgdiv" class="extend">
|
||||
<div id="canvasQwpYZa" class="canvas" style="width:100%;height:100%;"></div>
|
||||
<script>
|
||||
var canvas = d3.demo.canvas();
|
||||
d3.select("#canvasQwpYZa").call(canvas);
|
||||
|
||||
d3.select("#resetButtonQwpYZa").on("click", function() {{
|
||||
canvas.reset();
|
||||
}});
|
||||
|
||||
function addItem(item) {{
|
||||
canvas.addItem(d3.select(item));
|
||||
}};
|
||||
function replaceItem(item) {{
|
||||
canvas.clear();
|
||||
canvas.addItem(d3.select(item));
|
||||
canvas.reset();
|
||||
}};
|
||||
</script>
|
||||
</div>
|
||||
<div id="svgsrc" class="extend ace-container" style="display: none">
|
||||
<div id="svgsrc2" class="ace "
|
||||
data-mode="svg" data-readonly="1">(no svg loaded)</div>
|
||||
|
|
|
@ -20,11 +20,14 @@ declare variable $active-link external :=function($_){$_};
|
|||
<!-- Le fav and touch icons -->
|
||||
<link rel="shortcut icon" href="/static/graphxq/graphxq2.png" />
|
||||
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js" type="text/javascript"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js" type="text/javascript"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.8/ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<link href="/static/graphxq/app.css" rel="stylesheet" type="text/css" />
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.3/ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<link href="/static/graphxq/app.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/graphxq/svg-pan-zoom.css" rel="stylesheet" type="text/css" />
|
||||
<script src="/static/graphxq/app.js" type="text/javascript"></script>
|
||||
<script src="http://d3js.org/d3.v3.js" charset="utf-8"></script>
|
||||
<script src="/static/graphxq/svg-pan-zoom.js"></script>
|
||||
<script type="text/javascript"><![CDATA[
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-34544921-1']);
|
||||
|
@ -95,7 +98,9 @@ declare variable $active-link external :=function($_){$_};
|
|||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">About <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
<li>
|
||||
<a href="testd3">D3 test</a>
|
||||
</li>
|
||||
<li class="{$active-link('api')}">
|
||||
<a href="api" title="About the API"
|
||||
><i class="glyphicon glyphicon-wrench"></i> API</a>
|
||||
|
@ -123,9 +128,10 @@ declare variable $active-link external :=function($_){$_};
|
|||
<button class="btn btn-primary">Save changes</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="container">
|
||||
{$body}
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,44 +1,44 @@
|
|||
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog"
|
||||
aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<form id="frm-defaults" class="form-table">
|
||||
<label>
|
||||
Title:
|
||||
<input type="text" value="" name="dotTitle" size="15" />
|
||||
</label>
|
||||
|
||||
<label>
|
||||
RankDir:
|
||||
<select name="rankdir">
|
||||
<option value="rankdir=TB;" selected="selected">TB (top
|
||||
-> bottom)
|
||||
</option>
|
||||
<option value="rankdir=LR;">LR (left -> right)</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Default Shape:
|
||||
<select name="shape">{$list-shapes}</select>
|
||||
</label>
|
||||
<label>
|
||||
Color:
|
||||
<select id="lstColors" width="10">{$list-colors}</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Background:
|
||||
<select name="bgcolor">{$list-colors}</select>
|
||||
</label>
|
||||
<label>
|
||||
Filter:
|
||||
<select name="filter">
|
||||
<option value="Bumpy">Bumpy</option>
|
||||
<option value="" selected="selected">(None)</option>
|
||||
<option value="grey_bevel_shadow">grey_bevel_shadow</option>
|
||||
<option value="Bevel">Bevel</option>
|
||||
<option value="MyFilter">MyFilter</option>
|
||||
<option value="MyShadow">MyShadow</option>
|
||||
</select>
|
||||
</label>
|
||||
</form>
|
||||
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog"
|
||||
aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<form id="frm-defaults" class="form-table">
|
||||
<label>
|
||||
Title:
|
||||
<input type="text" value="" name="dotTitle" size="15" />
|
||||
</label>
|
||||
|
||||
<label>
|
||||
RankDir:
|
||||
<select name="rankdir">
|
||||
<option value="rankdir=TB;" selected="selected">TB (top
|
||||
-> bottom)
|
||||
</option>
|
||||
<option value="rankdir=LR;">LR (left -> right)</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Default Shape:
|
||||
<select name="shape">{$list-shapes}</select>
|
||||
</label>
|
||||
<label>
|
||||
Color:
|
||||
<select id="lstColors" width="10">{$list-colors}</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Background:
|
||||
<select name="bgcolor">{$list-colors}</select>
|
||||
</label>
|
||||
<label>
|
||||
Filter:
|
||||
<select name="filter">
|
||||
<option value="Bumpy">Bumpy</option>
|
||||
<option value="" selected="selected">(None)</option>
|
||||
<option value="grey_bevel_shadow">grey_bevel_shadow</option>
|
||||
<option value="Bevel">Bevel</option>
|
||||
<option value="MyFilter">MyFilter</option>
|
||||
<option value="MyShadow">MyShadow</option>
|
||||
</select>
|
||||
</label>
|
||||
</form>
|
||||
</div>
|
36
src/graphxq/views/testd3.xml
Normal file
36
src/graphxq/views/testd3.xml
Normal file
|
@ -0,0 +1,36 @@
|
|||
<div class="row">
|
||||
<div id="leftPane" class="col-md-6 extend">
|
||||
<h1>d3 test</h1>
|
||||
<button id="resetButtonQwpYZa">Reset</button>
|
||||
<button id="loadButton">Load</button>
|
||||
</div>
|
||||
<div id="rightPane" class="col-md-6 extend" style="background-color:red;">
|
||||
<div id="canvasQwpYZa" class="canvas" style="width:100%;height:100%;"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var canvas = d3.demo.canvas();
|
||||
d3.select("#canvasQwpYZa").call(canvas);
|
||||
|
||||
d3.select("#resetButtonQwpYZa").on("click", function() {{
|
||||
canvas.reset();
|
||||
}});
|
||||
d3.select("#loadButton").on("click", function() {{
|
||||
d3.xml("/static/graphxq/sample.svg","image/svg+xml", function(xml) {{
|
||||
replaceItem(xml.documentElement);
|
||||
}});
|
||||
}});
|
||||
d3.xml("http://www.billdwhite.com/wordpress/wp-content/images/butterfly.svg", "image/svg+xml", function(xml) {{
|
||||
addItem(xml.documentElement);
|
||||
}});
|
||||
|
||||
function addItem(item) {{
|
||||
canvas.addItem(d3.select(item));
|
||||
}};
|
||||
function replaceItem(item) {{
|
||||
canvas.clear();
|
||||
canvas.addItem(d3.select(item));
|
||||
canvas.reset();
|
||||
}};
|
||||
</script>
|
||||
</div>
|
|
@ -46,6 +46,10 @@
|
|||
<i class="glyphicon glyphicon-info-sign" title="Request status, click for more."></i>
|
||||
</a>
|
||||
<div class="btn-group pull-right">
|
||||
<button id="resetButtonQwpYZa" class="btn btn-mini btn-default" data-toggle="button" title="Zoom to fit">
|
||||
<i class="glyphicon glyphicon-screenshot"></i>
|
||||
Fit
|
||||
</button>
|
||||
<button id="bnsvg" class="btn btn-mini btn-default" title="Show SVG standalone.">
|
||||
<i class="glyphicon glyphicon-fullscreen"></i>
|
||||
SVG
|
||||
|
@ -54,11 +58,11 @@
|
|||
<i class="glyphicon glyphicon-download-alt"></i>
|
||||
download
|
||||
</button>
|
||||
</div>
|
||||
<div class="btn-group pull-right">
|
||||
|
||||
<button id="bnxml" class="btn btn-mini btn-default" data-toggle="button" title="Toggle SVG graphic and text">
|
||||
<i class="glyphicon glyphicon-eye-close"></i>
|
||||
SVG text
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -87,7 +87,7 @@ function getsvg(){
|
|||
var data = oParser.parseFromString(str, "text/xml");
|
||||
// http://stackoverflow.com/questions/3346106/accessing-a-dom-object-defined-in-an-external-svg-file
|
||||
var n = document.importNode(data.documentElement,true);
|
||||
$("#gInsertSVG").empty().append(n);
|
||||
replaceItem(n);
|
||||
ace.edit("svgsrc2").setValue(str,1);
|
||||
//ace.edit("svgsrc2").selection.clear();
|
||||
$("#infotip").attr("data-content","SVG returned in: "+d +" ms.");
|
||||
|
|
40
src/static/graphxq/index.html
Normal file
40
src/static/graphxq/index.html
Normal file
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>SVG v0.6</title>
|
||||
<link href="svg-pan-zoom.css" rel="stylesheet" type="text/css" />
|
||||
<script src="http://d3js.org/d3.v3.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<button id="resetButtonQwpYZa">Reset</button>
|
||||
<button id="loadButton">Load</button>
|
||||
<div id="canvasQwpYZa" class="canvas"></div>
|
||||
|
||||
<script src="svg-pan-zoom.js"></script>
|
||||
<script>
|
||||
var canvas = d3.demo.canvas().width(435).height(400);
|
||||
d3.select("#canvasQwpYZa").call(canvas);
|
||||
|
||||
d3.select("#resetButtonQwpYZa").on("click", function() {
|
||||
canvas.reset();
|
||||
});
|
||||
d3.select("#loadButton").on("click", function() {
|
||||
d3.xml("/static/graphxq/sample.svg","image/svg+xml", function(xml) {
|
||||
replaceItem(xml.documentElement);
|
||||
});
|
||||
});
|
||||
d3.xml("http://www.billdwhite.com/wordpress/wp-content/images/butterfly.svg", "image/svg+xml", function(xml) {
|
||||
addItem(xml.documentElement);
|
||||
});
|
||||
|
||||
function addItem(item) {
|
||||
canvas.addItem(d3.select(item));
|
||||
}
|
||||
function replaceItem(item) {
|
||||
canvas.clear();
|
||||
canvas.addItem(d3.select(item));
|
||||
canvas.reset();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
174
src/static/graphxq/sample.svg
Normal file
174
src/static/graphxq/sample.svg
Normal file
|
@ -0,0 +1,174 @@
|
|||
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="xMidYMid meet" viewBox="0.00 0.00 224.00 408.00">
|
||||
<metadata>
|
||||
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<rdf:Description about="https://github.com/apb2006/graphxq" dc:title="Title: process Pages: 1" dc:description="A graph visualization" dc:date="2016-05-31T21:51:47.767+01:00" dc:format="image/svg+xml">
|
||||
<dc:creator>
|
||||
<rdf:Bag>
|
||||
<rdf:li>Generated by graphviz version 2.38.0 (20140413.2041)</rdf:li>
|
||||
<rdf:li resource="https://github.com/apb2006/graphxq"/>
|
||||
</rdf:Bag>
|
||||
</dc:creator>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 404)">
|
||||
<title>process</title>
|
||||
<polygon fill="white" stroke="none" points="-4,4 -4,-404 220,-404 220,4 -4,4"/>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_0</title>
|
||||
<polygon fill="lightgrey" stroke="lightgrey" points="8,-65 8,-356 98,-356 98,-65 8,-65"/>
|
||||
<text text-anchor="middle" x="53" y="-340.8" font-family="Times New Roman,serif" font-size="14.00">process #1</text>
|
||||
</g>
|
||||
<g id="clust2" class="cluster">
|
||||
<title>cluster_1</title>
|
||||
<polygon fill="none" stroke="blue" points="129,-65 129,-356 208,-356 208,-65 129,-65"/>
|
||||
<text text-anchor="middle" x="168.5" y="-340.8" font-family="Times New Roman,serif" font-size="14.00">process #2</text>
|
||||
</g>
|
||||
<!-- a0 -->
|
||||
<g id="node1" class="node">
|
||||
<title>a0</title>
|
||||
<ellipse fill="white" stroke="white" cx="63" cy="-307" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="63" y="-303.3" font-family="Times New Roman,serif" font-size="14.00">a0</text>
|
||||
</g>
|
||||
<!-- a1 -->
|
||||
<g id="node2" class="node">
|
||||
<title>a1</title>
|
||||
<ellipse fill="white" stroke="white" cx="63" cy="-235" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="63" y="-231.3" font-family="Times New Roman,serif" font-size="14.00">a1</text>
|
||||
</g>
|
||||
<!-- a0->a1 -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>a0->a1</title>
|
||||
<path fill="none" stroke="black" d="M63,-288.697C63,-280.983 63,-271.712 63,-263.112"/>
|
||||
<polygon fill="black" stroke="black" points="66.5001,-263.104 63,-253.104 59.5001,-263.104 66.5001,-263.104"/>
|
||||
</g>
|
||||
<!-- a2 -->
|
||||
<g id="node3" class="node">
|
||||
<title>a2</title>
|
||||
<ellipse fill="white" stroke="white" cx="63" cy="-163" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="63" y="-159.3" font-family="Times New Roman,serif" font-size="14.00">a2</text>
|
||||
</g>
|
||||
<!-- a1->a2 -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>a1->a2</title>
|
||||
<path fill="none" stroke="black" d="M63,-216.697C63,-208.983 63,-199.712 63,-191.112"/>
|
||||
<polygon fill="black" stroke="black" points="66.5001,-191.104 63,-181.104 59.5001,-191.104 66.5001,-191.104"/>
|
||||
</g>
|
||||
<!-- b3 -->
|
||||
<g id="node8" class="node">
|
||||
<title>b3</title>
|
||||
<ellipse fill="lightgrey" stroke="black" cx="164" cy="-91" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="164" y="-87.3" font-family="Times New Roman,serif" font-size="14.00">b3</text>
|
||||
</g>
|
||||
<!-- a1->b3 -->
|
||||
<g id="edge9" class="edge">
|
||||
<title>a1->b3</title>
|
||||
<path fill="none" stroke="black" d="M74.001,-218.533C91.6079,-193.779 126.245,-145.081 147.038,-115.847"/>
|
||||
<polygon fill="black" stroke="black" points="150.069,-117.625 153.013,-107.448 144.364,-113.568 150.069,-117.625"/>
|
||||
</g>
|
||||
<!-- a3 -->
|
||||
<g id="node4" class="node">
|
||||
<title>a3</title>
|
||||
<ellipse fill="white" stroke="white" cx="63" cy="-91" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="63" y="-87.3" font-family="Times New Roman,serif" font-size="14.00">a3</text>
|
||||
</g>
|
||||
<!-- a2->a3 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>a2->a3</title>
|
||||
<path fill="none" stroke="black" d="M63,-144.697C63,-136.983 63,-127.712 63,-119.112"/>
|
||||
<polygon fill="black" stroke="black" points="66.5001,-119.104 63,-109.104 59.5001,-119.104 66.5001,-119.104"/>
|
||||
</g>
|
||||
<!-- a3->a0 -->
|
||||
<g id="edge11" class="edge">
|
||||
<title>a3->a0</title>
|
||||
<path fill="none" stroke="black" d="M49.2496,-106.931C41.0392,-116.9 31.381,-130.753 27,-145 12.8916,-190.88 12.8916,-207.12 27,-253 30.2858,-263.685 36.5399,-274.149 42.9254,-282.919"/>
|
||||
<polygon fill="black" stroke="black" points="40.354,-285.314 49.2496,-291.069 45.8844,-281.023 40.354,-285.314"/>
|
||||
</g>
|
||||
<!-- end -->
|
||||
<g id="node10" class="node">
|
||||
<title>end</title>
|
||||
<polygon fill="none" stroke="black" points="131.5,-37 94.5,-37 94.5,-0 131.5,-0 131.5,-37"/>
|
||||
<polyline fill="none" stroke="black" points="106.5,-37 94.5,-25 "/>
|
||||
<polyline fill="none" stroke="black" points="94.5,-12 106.5,-0 "/>
|
||||
<polyline fill="none" stroke="black" points="119.5,-0 131.5,-12 "/>
|
||||
<polyline fill="none" stroke="black" points="131.5,-25 119.5,-37 "/>
|
||||
<text text-anchor="middle" x="113" y="-14.8" font-family="Times New Roman,serif" font-size="14.00">end</text>
|
||||
</g>
|
||||
<!-- a3->end -->
|
||||
<g id="edge12" class="edge">
|
||||
<title>a3->end</title>
|
||||
<path fill="none" stroke="black" d="M74.0966,-74.3538C80.1492,-65.8197 87.7959,-55.0378 94.7049,-45.2961"/>
|
||||
<polygon fill="black" stroke="black" points="97.5978,-47.2672 100.528,-37.0856 91.888,-43.2177 97.5978,-47.2672"/>
|
||||
</g>
|
||||
<!-- b0 -->
|
||||
<g id="node5" class="node">
|
||||
<title>b0</title>
|
||||
<ellipse fill="lightgrey" stroke="black" cx="168" cy="-307" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="168" y="-303.3" font-family="Times New Roman,serif" font-size="14.00">b0</text>
|
||||
</g>
|
||||
<!-- b1 -->
|
||||
<g id="node6" class="node">
|
||||
<title>b1</title>
|
||||
<ellipse fill="lightgrey" stroke="black" cx="170" cy="-235" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="170" y="-231.3" font-family="Times New Roman,serif" font-size="14.00">b1</text>
|
||||
</g>
|
||||
<!-- b0->b1 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>b0->b1</title>
|
||||
<path fill="none" stroke="black" d="M168.494,-288.697C168.715,-280.983 168.98,-271.712 169.225,-263.112"/>
|
||||
<polygon fill="black" stroke="black" points="172.724,-263.2 169.511,-253.104 165.727,-263 172.724,-263.2"/>
|
||||
</g>
|
||||
<!-- b2 -->
|
||||
<g id="node7" class="node">
|
||||
<title>b2</title>
|
||||
<ellipse fill="lightgrey" stroke="black" cx="173" cy="-163" rx="27" ry="18"/>
|
||||
<text text-anchor="middle" x="173" y="-159.3" font-family="Times New Roman,serif" font-size="14.00">b2</text>
|
||||
</g>
|
||||
<!-- b1->b2 -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>b1->b2</title>
|
||||
<path fill="none" stroke="black" d="M170.742,-216.697C171.072,-208.983 171.469,-199.712 171.838,-191.112"/>
|
||||
<polygon fill="black" stroke="black" points="175.335,-191.245 172.267,-181.104 168.342,-190.945 175.335,-191.245"/>
|
||||
</g>
|
||||
<!-- b2->a3 -->
|
||||
<g id="edge10" class="edge">
|
||||
<title>b2->a3</title>
|
||||
<path fill="none" stroke="black" d="M153.839,-149.807C136.331,-138.665 110.241,-122.062 90.5068,-109.504"/>
|
||||
<polygon fill="black" stroke="black" points="92.2567,-106.469 81.941,-104.053 88.4985,-112.375 92.2567,-106.469"/>
|
||||
</g>
|
||||
<!-- b2->b3 -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>b2->b3</title>
|
||||
<path fill="none" stroke="black" d="M170.821,-145.055C169.83,-137.346 168.632,-128.027 167.518,-119.364"/>
|
||||
<polygon fill="black" stroke="black" points="170.968,-118.747 166.221,-109.275 164.025,-119.64 170.968,-118.747"/>
|
||||
</g>
|
||||
<!-- b3->end -->
|
||||
<g id="edge13" class="edge">
|
||||
<title>b3->end</title>
|
||||
<path fill="none" stroke="black" d="M152.681,-74.3538C146.508,-65.8197 138.708,-55.0378 131.661,-45.2961"/>
|
||||
<polygon fill="black" stroke="black" points="134.419,-43.1364 125.721,-37.0856 128.747,-47.2393 134.419,-43.1364"/>
|
||||
</g>
|
||||
<!-- start -->
|
||||
<g id="node9" class="node">
|
||||
<title>start</title>
|
||||
<polygon fill="none" stroke="black" points="115,-400 77.1282,-382 115,-364 152.872,-382 115,-400"/>
|
||||
<polyline fill="none" stroke="black" points="87.9663,-387.151 87.9663,-376.849 "/>
|
||||
<polyline fill="none" stroke="black" points="104.162,-369.151 125.838,-369.151 "/>
|
||||
<polyline fill="none" stroke="black" points="142.034,-376.849 142.034,-387.151 "/>
|
||||
<polyline fill="none" stroke="black" points="125.838,-394.849 104.162,-394.849 "/>
|
||||
<text text-anchor="middle" x="115" y="-378.3" font-family="Times New Roman,serif" font-size="14.00">start</text>
|
||||
</g>
|
||||
<!-- start->a0 -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>start->a0</title>
|
||||
<path fill="none" stroke="black" d="M105.942,-368.284C98.8241,-358.292 88.7051,-344.086 80.0777,-331.974"/>
|
||||
<polygon fill="black" stroke="black" points="82.776,-329.73 74.1234,-323.616 77.0746,-333.791 82.776,-329.73"/>
|
||||
</g>
|
||||
<!-- start->b0 -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>start->b0</title>
|
||||
<path fill="none" stroke="black" d="M124.232,-368.284C131.487,-358.292 141.801,-344.086 150.594,-331.974"/>
|
||||
<polygon fill="black" stroke="black" points="153.62,-333.764 156.663,-323.616 147.955,-329.651 153.62,-333.764"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.6 KiB |
36
src/static/graphxq/svg-pan-zoom.css
Normal file
36
src/static/graphxq/svg-pan-zoom.css
Normal file
|
@ -0,0 +1,36 @@
|
|||
html, body {
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 12px;
|
||||
}
|
||||
.canvas {
|
||||
overflow: hidden;
|
||||
fill: #808040;
|
||||
}
|
||||
.canvas .wrapper.outer > .background {
|
||||
fill: #000000;
|
||||
}
|
||||
.canvas .wrapper.inner > .background {
|
||||
fill: #CCCCCC;
|
||||
cursor: move;
|
||||
}
|
||||
.canvas .background {
|
||||
fill: #F6F6F6;
|
||||
stroke: #333333;
|
||||
cursor: move;
|
||||
}
|
||||
.canvas .panCanvas {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.canvas .minimap .frame .background {
|
||||
stroke: #111111;
|
||||
stroke-width: 4px;
|
||||
fill-opacity: 0.4;
|
||||
fill: #000000;
|
||||
fill: url(#minimapGradient_qwpyza);
|
||||
xfilter: url(#minimapDropShadow_qwpyza);
|
||||
cursor: move;
|
||||
}
|
436
src/static/graphxq/svg-pan-zoom.js
Normal file
436
src/static/graphxq/svg-pan-zoom.js
Normal file
|
@ -0,0 +1,436 @@
|
|||
// http://www.billdwhite.com/wordpress/2013/11/26/d3-minimap-pan-and-zoom-demo/
|
||||
d3.demo = {};
|
||||
|
||||
/** CANVAS **/
|
||||
d3.demo.canvas = function() {
|
||||
|
||||
"use strict";
|
||||
|
||||
var width = 500,
|
||||
height = 500,
|
||||
zoomEnabled = true,
|
||||
dragEnabled = true,
|
||||
scale = 1,
|
||||
translation = [0,0],
|
||||
base = null,
|
||||
wrapperBorder = 2,
|
||||
minimap = null,
|
||||
minimapPadding = 20,
|
||||
minimapScale = 0.25;
|
||||
|
||||
function canvas(selection) {
|
||||
|
||||
base = selection;
|
||||
|
||||
var xScale = d3.scale.linear()
|
||||
.domain([-width / 2, width / 2])
|
||||
.range([0, width]);
|
||||
|
||||
var yScale = d3.scale.linear()
|
||||
.domain([-height / 2, height / 2])
|
||||
.range([height, 0]);
|
||||
|
||||
var zoomHandler = function(newScale) {
|
||||
if (!zoomEnabled) { return; }
|
||||
if (d3.event) {
|
||||
scale = d3.event.scale;
|
||||
} else {
|
||||
scale = newScale;
|
||||
}
|
||||
if (dragEnabled) {
|
||||
var tbound = -height * scale,
|
||||
bbound = height * scale,
|
||||
lbound = -width * scale,
|
||||
rbound = width * scale;
|
||||
// limit translation to thresholds
|
||||
translation = d3.event ? d3.event.translate : [0, 0];
|
||||
translation = [
|
||||
Math.max(Math.min(translation[0], rbound), lbound),
|
||||
Math.max(Math.min(translation[1], bbound), tbound)
|
||||
];
|
||||
}
|
||||
|
||||
d3.select(".panCanvas, .panCanvas .bg")
|
||||
.attr("transform", "translate(" + translation + ")" + " scale(" + scale + ")");
|
||||
|
||||
minimap.scale(scale).render();
|
||||
}; // startoff zoomed in a bit to show pan/zoom rectangle
|
||||
|
||||
var zoom = d3.behavior.zoom()
|
||||
.x(xScale)
|
||||
.y(yScale)
|
||||
.scaleExtent([0.1, 10])
|
||||
.on("zoom.canvas", zoomHandler);
|
||||
var w=width + (wrapperBorder*2) + minimapPadding*2 + (width*minimapScale);
|
||||
var h=height + (wrapperBorder*2);
|
||||
var svg = selection.append("svg")
|
||||
.attr("class", "svg canvas")
|
||||
.attr("width", "100%")
|
||||
.attr("height", "100%")
|
||||
.attr("viewBox", "0 0 "+w + " "+h)
|
||||
.attr("shape-rendering", "auto");
|
||||
|
||||
var svgDefs = svg.append("defs");
|
||||
|
||||
svgDefs.append("clipPath")
|
||||
.attr("id", "wrapperClipPath_qwpyza")
|
||||
.attr("class", "wrapper clipPath")
|
||||
.append("rect")
|
||||
.attr("class", "background")
|
||||
.attr("width", width)
|
||||
.attr("height", height);
|
||||
|
||||
svgDefs.append("clipPath")
|
||||
.attr("id", "minimapClipPath_qwpyza")
|
||||
.attr("class", "minimap clipPath")
|
||||
.attr("width", width)
|
||||
.attr("height", height)
|
||||
//.attr("transform", "translate(" + (width + minimapPadding) + "," + (minimapPadding/2) + ")")
|
||||
.append("rect")
|
||||
.attr("class", "background")
|
||||
.attr("width", width)
|
||||
.attr("height", height);
|
||||
|
||||
var filter = svgDefs.append("svg:filter")
|
||||
.attr("id", "minimapDropShadow_qwpyza")
|
||||
.attr("x", "-20%")
|
||||
.attr("y", "-20%")
|
||||
.attr("width", "150%")
|
||||
.attr("height", "150%");
|
||||
|
||||
filter.append("svg:feOffset")
|
||||
.attr("result", "offOut")
|
||||
.attr("in", "SourceGraphic")
|
||||
.attr("dx", "1")
|
||||
.attr("dy", "1");
|
||||
|
||||
filter.append("svg:feColorMatrix")
|
||||
.attr("result", "matrixOut")
|
||||
.attr("in", "offOut")
|
||||
.attr("type", "matrix")
|
||||
.attr("values", "0.1 0 0 0 0 0 0.1 0 0 0 0 0 0.1 0 0 0 0 0 0.5 0");
|
||||
|
||||
filter.append("svg:feGaussianBlur")
|
||||
.attr("result", "blurOut")
|
||||
.attr("in", "matrixOut")
|
||||
.attr("stdDeviation", "10");
|
||||
|
||||
filter.append("svg:feBlend")
|
||||
.attr("in", "SourceGraphic")
|
||||
.attr("in2", "blurOut")
|
||||
.attr("mode", "normal");
|
||||
|
||||
var minimapRadialFill = svgDefs.append("radialGradient")
|
||||
.attr({
|
||||
id:"minimapGradient_qwpyza",
|
||||
gradientUnits:"userSpaceOnUse",
|
||||
cx:"500",
|
||||
cy:"500",
|
||||
r:"400",
|
||||
fx:"500",
|
||||
fy:"500"
|
||||
});
|
||||
minimapRadialFill.append("stop")
|
||||
.attr("offset", "0%")
|
||||
.attr("stop-color", "#FFFFFF");
|
||||
minimapRadialFill.append("stop")
|
||||
.attr("offset", "40%")
|
||||
.attr("stop-color", "#EEEEEE");
|
||||
minimapRadialFill.append("stop")
|
||||
.attr("offset", "100%")
|
||||
.attr("stop-color", "#E0E0E0");
|
||||
|
||||
var outerWrapper = svg.append("g")
|
||||
.attr("class", "wrapper outer")
|
||||
.attr("transform", "translate(0, " + minimapPadding + ")");
|
||||
|
||||
outerWrapper.append("rect")
|
||||
.attr("class", "background")
|
||||
.attr("width", width + wrapperBorder*2)
|
||||
.attr("height", height + wrapperBorder*2);
|
||||
|
||||
var innerWrapper = outerWrapper.append("g")
|
||||
.attr("class", "wrapper inner")
|
||||
.attr("clip-path", "url(#wrapperClipPath_qwpyza)")
|
||||
.attr("transform", "translate(" + (wrapperBorder) + "," + (wrapperBorder) + ")")
|
||||
.call(zoom);
|
||||
|
||||
innerWrapper.append("rect")
|
||||
.attr("class", "background")
|
||||
.attr("width", width)
|
||||
.attr("height", height);
|
||||
|
||||
var panCanvas = innerWrapper.append("g")
|
||||
.attr("class", "panCanvas")
|
||||
.attr("width", width)
|
||||
.attr("height", height)
|
||||
.attr("transform", "translate(0,0)");
|
||||
|
||||
panCanvas.append("rect")
|
||||
.attr("class", "background")
|
||||
.attr("width", width)
|
||||
.attr("height", height);
|
||||
|
||||
minimap = d3.demo.minimap()
|
||||
.zoom(zoom)
|
||||
.target(panCanvas)
|
||||
.minimapScale(minimapScale)
|
||||
.x(width + minimapPadding)
|
||||
.y(minimapPadding);
|
||||
|
||||
svg.call(minimap);
|
||||
|
||||
// startoff zoomed in a bit to show pan/zoom rectangle
|
||||
zoom.scale(1.75);
|
||||
zoomHandler(1.75);
|
||||
|
||||
/** ADD SHAPE **/
|
||||
canvas.addItem = function(item) {
|
||||
panCanvas.node().appendChild(item.node());
|
||||
minimap.render();
|
||||
};
|
||||
canvas.clear = function() {
|
||||
var node=panCanvas.node();
|
||||
while (node.hasChildNodes()) {
|
||||
node.removeChild(node.lastChild);
|
||||
};
|
||||
};
|
||||
/** RENDER **/
|
||||
canvas.render = function() {
|
||||
svgDefs
|
||||
.select(".clipPath .background")
|
||||
.attr("width", width)
|
||||
.attr("height", height);
|
||||
var w=width + (wrapperBorder*2) + minimapPadding*2 + (width*minimapScale);
|
||||
var h=height + (wrapperBorder*2);
|
||||
svg
|
||||
.attr("width", "100%")
|
||||
.attr("height", "100%")
|
||||
.attr("viewBox", "0 0 "+w + " "+h);
|
||||
outerWrapper
|
||||
.select(".background")
|
||||
.attr("width", width + wrapperBorder*2)
|
||||
.attr("height", height + wrapperBorder*2);
|
||||
|
||||
innerWrapper
|
||||
.attr("transform", "translate(" + (wrapperBorder) + "," + (wrapperBorder) + ")")
|
||||
.select(".background")
|
||||
.attr("width", width)
|
||||
.attr("height", height);
|
||||
|
||||
panCanvas
|
||||
.attr("width", width)
|
||||
.attr("height", height)
|
||||
.select(".background")
|
||||
.attr("width", width)
|
||||
.attr("height", height);
|
||||
|
||||
minimap
|
||||
.x(width + minimapPadding)
|
||||
.y(minimapPadding)
|
||||
.render();
|
||||
};
|
||||
|
||||
canvas.zoomEnabled = function(isEnabled) {
|
||||
if (!arguments.length) { return zoomEnabled }
|
||||
zoomEnabled = isEnabled;
|
||||
};
|
||||
|
||||
canvas.dragEnabled = function(isEnabled) {
|
||||
if (!arguments.length) { return dragEnabled }
|
||||
dragEnabled = isEnabled;
|
||||
};
|
||||
|
||||
canvas.reset = function() {
|
||||
svg.call(zoom.event);
|
||||
zoom.scale(1);
|
||||
zoom.translate([0,0]);
|
||||
svg.transition().duration(750).call(zoom.event);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//============================================================
|
||||
// Accessors
|
||||
//============================================================
|
||||
|
||||
canvas.width = function(value) {
|
||||
if (!arguments.length) return width;
|
||||
width = parseInt(value, 10);
|
||||
return this;
|
||||
};
|
||||
|
||||
canvas.height = function(value) {
|
||||
if (!arguments.length) return height;
|
||||
height = parseInt(value, 10);
|
||||
return this;
|
||||
};
|
||||
|
||||
canvas.scale = function(value) {
|
||||
if (!arguments.length) { return scale; }
|
||||
scale = value;
|
||||
return this;
|
||||
};
|
||||
|
||||
return canvas;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** MINIMAP **/
|
||||
d3.demo.minimap = function() {
|
||||
|
||||
"use strict";
|
||||
|
||||
var minimapScale = 0.15,
|
||||
scale = 1,
|
||||
zoom = null,
|
||||
base = null,
|
||||
target = null,
|
||||
width = 0,
|
||||
height = 0,
|
||||
x = 0,
|
||||
y = 0,
|
||||
frameX = 0,
|
||||
frameY = 0;
|
||||
|
||||
function minimap(selection) {
|
||||
|
||||
base = selection;
|
||||
|
||||
var container = selection.append("g")
|
||||
.attr("class", "minimap")
|
||||
.call(zoom);
|
||||
|
||||
zoom.on("zoom.minimap", function() {
|
||||
scale = d3.event.scale;
|
||||
});
|
||||
|
||||
|
||||
minimap.node = container.node();
|
||||
|
||||
var frame = container.append("g")
|
||||
.attr("class", "frame")
|
||||
|
||||
frame.append("rect")
|
||||
.attr("class", "background")
|
||||
.attr("width", width)
|
||||
.attr("height", height)
|
||||
.attr("filter", "url(#minimapDropShadow_qwpyza)");
|
||||
|
||||
var drag = d3.behavior.drag()
|
||||
.on("dragstart.minimap", function() {
|
||||
var frameTranslate = d3.demo.util.getXYFromTranslate(frame.attr("transform"));
|
||||
frameX = frameTranslate[0];
|
||||
frameY = frameTranslate[1];
|
||||
})
|
||||
.on("drag.minimap", function() {
|
||||
d3.event.sourceEvent.stopImmediatePropagation();
|
||||
frameX += d3.event.dx;
|
||||
frameY += d3.event.dy;
|
||||
frame.attr("transform", "translate(" + frameX + "," + frameY + ")");
|
||||
var translate = [(-frameX*scale),(-frameY*scale)];
|
||||
target.attr("transform", "translate(" + translate + ")scale(" + scale + ")");
|
||||
zoom.translate(translate);
|
||||
});
|
||||
|
||||
frame.call(drag);
|
||||
|
||||
/** RENDER **/
|
||||
minimap.render = function() {
|
||||
scale = zoom.scale();
|
||||
container.attr("transform", "translate(" + x + "," + y + ")scale(" + minimapScale + ")");
|
||||
var node = target.node().cloneNode(true);
|
||||
node.removeAttribute("id");
|
||||
base.selectAll(".minimap .panCanvas").remove();
|
||||
minimap.node.appendChild(node);
|
||||
var targetTransform = d3.demo.util.getXYFromTranslate(target.attr("transform"));
|
||||
frame.attr("transform", "translate(" + (-targetTransform[0]/scale) + "," + (-targetTransform[1]/scale) + ")")
|
||||
.select(".background")
|
||||
.attr("width", width/scale)
|
||||
.attr("height", height/scale);
|
||||
frame.node().parentNode.appendChild(frame.node());
|
||||
d3.select(node).attr("transform", "translate(1,1)");
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//============================================================
|
||||
// Accessors
|
||||
//============================================================
|
||||
|
||||
|
||||
minimap.width = function(value) {
|
||||
if (!arguments.length) return width;
|
||||
width = parseInt(value, 10);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
minimap.height = function(value) {
|
||||
if (!arguments.length) return height;
|
||||
height = parseInt(value, 10);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
minimap.x = function(value) {
|
||||
if (!arguments.length) return x;
|
||||
x = parseInt(value, 10);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
minimap.y = function(value) {
|
||||
if (!arguments.length) return y;
|
||||
y = parseInt(value, 10);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
minimap.scale = function(value) {
|
||||
if (!arguments.length) { return scale; }
|
||||
scale = value;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
minimap.minimapScale = function(value) {
|
||||
if (!arguments.length) { return minimapScale; }
|
||||
minimapScale = value;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
minimap.zoom = function(value) {
|
||||
if (!arguments.length) return zoom;
|
||||
zoom = value;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
minimap.target = function(value) {
|
||||
if (!arguments.length) { return target; }
|
||||
target = value;
|
||||
width = parseInt(target.attr("width"), 10);
|
||||
height = parseInt(target.attr("height"), 10);
|
||||
return this;
|
||||
};
|
||||
|
||||
return minimap;
|
||||
};
|
||||
|
||||
|
||||
/** UTILS **/
|
||||
d3.demo.util = {};
|
||||
d3.demo.util.getXYFromTranslate = function(translateString) {
|
||||
var currentTransform = d3.transform(translateString);
|
||||
currentX = currentTransform.translate[0];
|
||||
currentY = currentTransform.translate[1];
|
||||
return [currentX, currentY];
|
||||
};
|
||||
|
||||
|
||||
/** RUN SCRIPT **/
|
||||
|
||||
|
Loading…
Add table
Reference in a new issue