mirror of
https://github.com/Quodatum/graphxq.git
synced 2025-04-11 11:42:24 +01:00
svg viewbox
This commit is contained in:
parent
74916f723f
commit
41d29c6036
6 changed files with 374 additions and 23 deletions
|
@ -100,13 +100,14 @@ else
|
|||
(:~ post process svg :)
|
||||
declare %private function get-svg($dot as xs:string) as node(){
|
||||
let $svgx:=gr:dot($dot,())
|
||||
return gr:autosize($svgx)
|
||||
return gr:autosize($svgx)
|
||||
};
|
||||
|
||||
declare function render($template,$locals){
|
||||
let $sidebar:=<div>
|
||||
<a href="/graphxq/viewbox/viewBox.svg">viewbox work</a>
|
||||
<ul>
|
||||
<div>Smples:</div>
|
||||
<div>Samples:</div>
|
||||
<li> <a href="dot?src=graphxq/samples/process.gv">process</a></li>
|
||||
<li><a href="/restxq/graphxq/dot?src=graphxq/samples/unix.gv">unix</a></li>
|
||||
<li> <a href="/restxq/graphxq/dot?src=graphxq/samples/root.gv">root (slow)</a></li>
|
||||
|
|
|
@ -51,9 +51,9 @@ declare %private function dot1( $dot as xs:string) as node(){
|
|||
let $ver:=$s/comment()[1]/fn:normalize-space()
|
||||
let $title:=$s/comment()[2]/fn:normalize-space()
|
||||
let $svg:=$s/*
|
||||
return <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
|
||||
{$svg/@* except ($svg/@width,$svg/@height,$svg/@preserveAspectRatio),
|
||||
return <svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" >
|
||||
{$svg/@* ,
|
||||
<metadata>
|
||||
<rdf:RDF
|
||||
xmlns:rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
|
|
171
src/graphxq/viewbox/ViewBox.js
Normal file
171
src/graphxq/viewbox/ViewBox.js
Normal file
|
@ -0,0 +1,171 @@
|
|||
/*****
|
||||
*
|
||||
* ViewBox.js
|
||||
*
|
||||
* copyright 2002, Kevin Lindsey
|
||||
*
|
||||
*****/
|
||||
|
||||
ViewBox.VERSION = "1.0";
|
||||
|
||||
|
||||
/*****
|
||||
*
|
||||
* constructor
|
||||
*
|
||||
*****/
|
||||
function ViewBox(svgNode) {
|
||||
if ( arguments.length > 0 ) {
|
||||
this.init(svgNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****
|
||||
*
|
||||
* init
|
||||
*
|
||||
*****/
|
||||
ViewBox.prototype.init = function(svgNode) {
|
||||
var viewBox = svgNode.getAttributeNS(null, "viewBox");
|
||||
var preserveAspectRatio = svgNode.getAttributeNS(null, "preserveAspectRatio");
|
||||
|
||||
if ( viewBox != null && viewBox != "" ) {
|
||||
var params = viewBox.split(/\s*,\s*|\s+/);
|
||||
|
||||
this.x = parseFloat( params[0] );
|
||||
this.y = parseFloat( params[1] );
|
||||
this.width = parseFloat( params[2] );
|
||||
this.height = parseFloat( params[3] );
|
||||
} else {
|
||||
// NOTE: Need to put an SVGResize event handler on the svgNode to keep
|
||||
// these values in sync with the window size or should add additional
|
||||
// logic (probably a flag) to getTM() so it will know to use the window
|
||||
// dimensions instead of this object's width and height properties
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.width = innerWidth;
|
||||
this.height = innerHeight;
|
||||
}
|
||||
|
||||
this.setPAR(preserveAspectRatio);
|
||||
};
|
||||
|
||||
|
||||
/*****
|
||||
*
|
||||
* getTM
|
||||
*
|
||||
*****/
|
||||
ViewBox.prototype.getTM = function() {
|
||||
var svgRoot = svgDocument.documentElement;
|
||||
var matrix = svgDocument.documentElement.createSVGMatrix();
|
||||
var windowWidth = svgRoot.getAttributeNS(null, "width");
|
||||
var windowHeight = svgRoot.getAttributeNS(null, "height");
|
||||
|
||||
if (windowWidth != null && windowWidth != "") {
|
||||
windowWidth = parseFloat(windowWidth);
|
||||
} else {
|
||||
if (window.innerWidth) {
|
||||
windowWidth = innerWidth;
|
||||
} else {
|
||||
windowWidth = document.documentElement.viewport.width;
|
||||
}
|
||||
}
|
||||
|
||||
if (windowHeight != null && windowHeight != "") {
|
||||
windowHeight = parseFloat(windowHeight);
|
||||
} else {
|
||||
if (window.innerHeight) {
|
||||
windowHeight = innerHeight;
|
||||
} else {
|
||||
windowHeight = document.documentElement.viewport.height;
|
||||
}
|
||||
}
|
||||
|
||||
var x_ratio = this.width / windowWidth;
|
||||
var y_ratio = this.height / windowHeight;
|
||||
|
||||
matrix = matrix.translate(this.x, this.y);
|
||||
if ( this.alignX == "none" ) {
|
||||
matrix = matrix.scaleNonUniform( x_ratio, y_ratio );
|
||||
} else {
|
||||
if ( x_ratio < y_ratio && this.meetOrSlice == "meet" ||
|
||||
x_ratio > y_ratio && this.meetOrSlice == "slice" )
|
||||
{
|
||||
var x_trans = 0;
|
||||
var x_diff = windowWidth*y_ratio - this.width;
|
||||
|
||||
if ( this.alignX == "Mid" )
|
||||
x_trans = -x_diff/2;
|
||||
else if ( this.alignX == "Max" )
|
||||
x_trans = -x_diff;
|
||||
|
||||
matrix = matrix.translate(x_trans, 0);
|
||||
matrix = matrix.scale( y_ratio );
|
||||
}
|
||||
else if ( x_ratio > y_ratio && this.meetOrSlice == "meet" ||
|
||||
x_ratio < y_ratio && this.meetOrSlice == "slice" )
|
||||
{
|
||||
var y_trans = 0;
|
||||
var y_diff = windowHeight*x_ratio - this.height;
|
||||
|
||||
if ( this.alignY == "Mid" )
|
||||
y_trans = -y_diff/2;
|
||||
else if ( this.alignY == "Max" )
|
||||
y_trans = -y_diff;
|
||||
|
||||
matrix = matrix.translate(0, y_trans);
|
||||
matrix = matrix.scale( x_ratio );
|
||||
}
|
||||
else
|
||||
{
|
||||
// x_ratio == y_ratio so, there is no need to translate
|
||||
// We can scale by either value
|
||||
matrix = matrix.scale( x_ratio );
|
||||
}
|
||||
}
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
|
||||
/*****
|
||||
*
|
||||
* get/set methods
|
||||
*
|
||||
*****/
|
||||
|
||||
/*****
|
||||
*
|
||||
* setPAR
|
||||
*
|
||||
*****/
|
||||
ViewBox.prototype.setPAR = function(PAR) {
|
||||
// NOTE: This function needs to use default values when encountering
|
||||
// unrecognized values
|
||||
if ( PAR ) {
|
||||
var params = PAR.split(/\s+/);
|
||||
var align = params[0];
|
||||
|
||||
if ( align == "none" ) {
|
||||
this.alignX = "none";
|
||||
this.alignY = "none";
|
||||
} else {
|
||||
this.alignX = align.substring(1,4);
|
||||
this.alignY = align.substring(5,9);
|
||||
}
|
||||
|
||||
if ( params.length == 2 ) {
|
||||
this.meetOrSlice = params[1];
|
||||
} else {
|
||||
this.meetOrSlice = "meet";
|
||||
}
|
||||
} else {
|
||||
this.align = "xMidYMid";
|
||||
this.alignX = "Mid";
|
||||
this.alignY = "Mid";
|
||||
this.meetOrSlice = "meet";
|
||||
}
|
||||
};
|
||||
|
168
src/graphxq/viewbox/viewBox.svg
Normal file
168
src/graphxq/viewbox/viewBox.svg
Normal file
|
@ -0,0 +1,168 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<svg onload="init(evt)"
|
||||
viewBox="10 10 500 400" preserveAspectRatio="xMidYMid meet"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
font-size="10pt">
|
||||
<script type="text/ecmascript" xlink:href="ViewBox.js"/>
|
||||
<script type="text/ecmascript"><![CDATA[
|
||||
var svgns = "http://www.w3.org/2000/svg";
|
||||
var svgRoot;
|
||||
|
||||
var viewBox;
|
||||
var cursor;
|
||||
var lastAlign;
|
||||
var lastMeetOrSlice;
|
||||
|
||||
function init(e) {
|
||||
if ( window.svgDocument == null )
|
||||
svgDocument = e.target.ownerDocument;
|
||||
|
||||
svgRoot = svgDocument.documentElement;
|
||||
|
||||
viewBox = new ViewBox(svgDocument.documentElement);
|
||||
cursor = svgDocument.getElementById("cursor");
|
||||
lastAlign = svgDocument.getElementById("xMidYMid");
|
||||
lastMeetOrSlice = svgDocument.getElementById("meet");
|
||||
}
|
||||
|
||||
function setAlign(e) {
|
||||
var align = e.target.id;
|
||||
var meetOrSlice = lastMeetOrSlice.id;
|
||||
var PAR = align + " " + meetOrSlice;
|
||||
|
||||
svgRoot.setAttributeNS(null, "preserveAspectRatio", PAR);
|
||||
viewBox.setPAR(PAR);
|
||||
|
||||
lastAlign.setAttributeNS(null, "fill", "grey");
|
||||
e.target.setAttributeNS(null, "fill", "darkblue");
|
||||
lastAlign = e.target;
|
||||
}
|
||||
|
||||
function setMeetOrSlice(e) {
|
||||
var align = lastAlign.id;
|
||||
var meetOrSlice = e.target.id;
|
||||
var PAR = align + " " + meetOrSlice;
|
||||
|
||||
svgRoot.setAttributeNS(null, "preserveAspectRatio", PAR);
|
||||
viewBox.setPAR(PAR);
|
||||
|
||||
lastMeetOrSlice.setAttributeNS(null, "fill", "grey");
|
||||
e.target.setAttributeNS(null, "fill", "darkblue");
|
||||
lastMeetOrSlice = e.target;
|
||||
}
|
||||
|
||||
function show_coords(e) {
|
||||
var parent = e.currentTarget;
|
||||
var rect = parent.childNodes.item(1);
|
||||
var CTM = getTransformToElement(rect);
|
||||
var iCTM = CTM.inverse();
|
||||
var trans = svgRoot.currentTranslate;
|
||||
var scale = svgRoot.currentScale;
|
||||
var m = viewBox.getTM();
|
||||
var p1 = svgRoot.createSVGPoint();
|
||||
var p2, p3;
|
||||
|
||||
m = m.scale( 1/scale );
|
||||
m = m.translate(-trans.x, -trans.y);
|
||||
|
||||
p1.x = e.clientX;
|
||||
p1.y = e.clientY;
|
||||
|
||||
p2 = p1.matrixTransform(m);
|
||||
p3 = p2.matrixTransform(iCTM);
|
||||
|
||||
//alert("p1 = " + p1.x + "," + p1.y);
|
||||
//alert("p2 = " + p2.x + "," + p2.y);
|
||||
//alert("p3 = " + p3.x + "," + p3.y);
|
||||
|
||||
// Update cursor
|
||||
cursor.setAttributeNS(null, "cx", p2.x);
|
||||
cursor.setAttributeNS(null, "cy", p2.y);
|
||||
|
||||
// Show the results
|
||||
var tspans = parent.getElementsByTagNameNS(svgns, "tspan");
|
||||
tspans.item(1).firstChild.data = e.clientX;
|
||||
tspans.item(3).firstChild.data = e.clientY;
|
||||
tspans.item(5).firstChild.data = Math.round(p3.x*100) / 100;
|
||||
tspans.item(7).firstChild.data = Math.round(p3.y*100) / 100;
|
||||
}
|
||||
|
||||
/*****
|
||||
*
|
||||
* getTransformToElement
|
||||
*
|
||||
*****/
|
||||
function getTransformToElement(node) {
|
||||
// Initialize our node's Current Transformation Matrix
|
||||
var CTM = node.getCTM();
|
||||
|
||||
// Work our way bacwards through the ancestor nodes stopping at the
|
||||
// SVG Document
|
||||
while ( ( node = node.parentNode ) != svgDocument ) {
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=543965
|
||||
// Multiply the new CTM with what we've accumulated so far
|
||||
var m=node.getCTM();
|
||||
m=m?m:node.getScreenCTM();
|
||||
CTM = m.multiply(CTM);
|
||||
}
|
||||
|
||||
return CTM;
|
||||
}
|
||||
]]></script>
|
||||
<circle id="cursor" r="10" fill="black"/>
|
||||
<g onmousemove="show_coords(evt)">
|
||||
<rect x="10" y="10" width="500" height="400" fill="blue" opacity="0.5"/>
|
||||
<text fill="white" transform="translate(19,10)"
|
||||
pointer-events="none">
|
||||
<tspan x="0" dy="10pt">Client X = </tspan><tspan> </tspan>
|
||||
<tspan x="0" dy="10pt">Client Y = </tspan><tspan> </tspan>
|
||||
<tspan x="0" dy="10pt">User X = </tspan><tspan> </tspan>
|
||||
<tspan x="0" dy="10pt">User Y = </tspan><tspan> </tspan>
|
||||
</text>
|
||||
<g transform="translate(230,180)">
|
||||
<rect width="36" height="36" fill="white" stroke="red" stroke-width="2"/>
|
||||
<g onmousedown="setAlign(evt)">
|
||||
<rect id="xMinYMin" x="2" y="2" width="10" height="10" fill="grey"/>
|
||||
<rect id="xMidYMin" x="13" y="2" width="10" height="10" fill="grey"/>
|
||||
<rect id="xMaxYMin" x="24" y="2" width="10" height="10" fill="grey"/>
|
||||
<rect id="xMinYMid" x="2" y="13" width="10" height="10" fill="grey"/>
|
||||
<rect id="xMidYMid" x="13" y="13" width="10" height="10" fill="darkblue"/>
|
||||
<rect id="xMaxYMid" x="24" y="13" width="10" height="10" fill="grey"/>
|
||||
<rect id="xMinYMax" x="2" y="24" width="10" height="10" fill="grey"/>
|
||||
<rect id="xMidYMax" x="13" y="24" width="10" height="10" fill="grey"/>
|
||||
<rect id="xMaxYMax" x="24" y="24" width="10" height="10" fill="grey"/>
|
||||
|
||||
<g fill="grey" stroke="white" transform="translate(2,40)">
|
||||
<rect id="none" width="32" height="12"/>
|
||||
<text x="16" y="10" fill="white" stroke="none"
|
||||
text-anchor="middle" pointer-events="none">none</text>
|
||||
</g>
|
||||
</g>
|
||||
<g onmousedown="setMeetOrSlice(evt)">
|
||||
<g fill="darkblue" stroke="white" transform="translate(42,5)">
|
||||
<rect id="meet" width="32" height="12"/>
|
||||
<text x="16" y="10" fill="white" stroke="none"
|
||||
text-anchor="middle" pointer-events="none">meet</text>
|
||||
</g>
|
||||
<g fill="grey" stroke="white" transform="translate(42,21)">
|
||||
<rect id="slice" width="32" height="12"/>
|
||||
<text x="16" y="10" fill="white" stroke="none"
|
||||
text-anchor="middle" pointer-events="none">slice</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="scale(4)" onmousemove="show_coords(evt)">
|
||||
<g transform="translate(20,35) rotate(30) scale(2)">
|
||||
<rect x="-2" y="0" width="10" height="10" fill="darkblue" opacity="0.5"/>
|
||||
<text font-size="1pt" fill="white" transform="translate(9,0)"
|
||||
pointer-events="none">
|
||||
<tspan x="0" dy="1pt">Client X = </tspan><tspan> </tspan>
|
||||
<tspan x="0" dy="1pt">Client Y = </tspan><tspan> </tspan>
|
||||
<tspan x="0" dy="1pt">User X = </tspan><tspan> </tspan>
|
||||
<tspan x="0" dy="1pt">User Y = </tspan><tspan> </tspan>
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 7.1 KiB |
|
@ -61,7 +61,10 @@
|
|||
<button id="bndn" class="btn btn-mini"><i class="icon-download-alt"></i>download</button>
|
||||
</div>
|
||||
<div id="svgdiv" style="width:100%;height:30em;border:1px solid red;min-height:20em;">svg here</div>
|
||||
<div id="svgdiv2" style="width:100%;height:30em;border:1px solid red;min-height:20em;">svg here</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
</script>
|
||||
|
|
|
@ -47,29 +47,37 @@
|
|||
<img src="/graphxq/graphxq2.png" />
|
||||
graphXQ
|
||||
</a>
|
||||
<form class="pull-right navbar-search" action="search">
|
||||
<input type="text" class="search-query span3" placeholder="Search"
|
||||
name="q" />
|
||||
<div class="icon-search"></div>
|
||||
</form>
|
||||
<div class="btn-group pull-right" style="margin-top:0px">
|
||||
{$usermenu}
|
||||
|
||||
</div>
|
||||
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
|
||||
<li class="">
|
||||
<a href="./dot" rel="tooltip" data-title="first tooltip">Dot</a>
|
||||
</li>
|
||||
<li class="">
|
||||
<a href="./dotml">DotML</a>
|
||||
</li>
|
||||
|
||||
<li class="">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
Create
|
||||
<b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a href="dot"><i class="icon-edit"></i> Dot</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="dotml"><i class="icon-align-center"></i> DotML</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="nav">
|
||||
<a href="about">About</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="pull-right navbar-search" action="search">
|
||||
<input type="text" class="search-query span3" placeholder="Search"
|
||||
name="q" />
|
||||
<div class="icon-search"></div>
|
||||
</form>
|
||||
<div class="btn-group pull-right" style="margin-top:0px">
|
||||
{$usermenu}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue