- From: Fred P. <fprog26@hotmail.com>
- Date: Mon, 12 May 2003 03:13:22 -0400
- To: www-svg@w3.org
- Cc: Kim.Marriott@infotech.monash.edu.au, arazdow@mathsoft.com
I think the arguments of Professor Kim Marriott
describes exactly what some of the things that we tried to achieve.
Especially his formal PDF article on one-way constrained SVG.
This is especially true for rendering UML diagrams using SVG,
similar to Visio or Rational Rose, using an SVG web client.
Let's take a simple case of springs:
0 1 2 3
(0,0) 012345678901234567890123456789012345
0+----------------------------------+
1| z z |
2| (9,3) z (22,3) z |
3| +---+ +---+ |
4|zzzzzzzz| A |zzzzzzzz| B |zzzzzzzz|
5| +---+ +---+ |
6| z z |
7| z z |
8+----------------------------------+ (W,H)
Spring conversion into one-way constraint functions can be derived with some
low level logic:
Notice that any thing calculation are integer based mostly using floor(x)
A.x = (document.width - A.width - B.width) * 1/3 + 1
= (35 - 5 - 5) * 1/3 + 1
= (25 ) * 1/3 + 1
= 8.33 + 1
= 8 + 1
= 9
A.y = (document.height - A.height - B.height) * 1/2 + 1
= (8 - 3) / 2 + 1
= 5 /2 + 1
= 2.5 + 1
= 2 + 1
= 3
B.x = (document.width - A.width - B.width) * 2/3 + A.width + 1
= (35 - 5 - 5) * 2/3 + 5 + 1
= (25 ) * 2/3 + 5 + 1
= 16.67 + 6
= 16 + 6
= 22
B.y = (document.height - A.height - B.height) * 1/2 + 1
= (8 - 3) / 2 + 1
= 5 /2 + 1
= 2.5 + 1
= 2 + 1
= 3
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg SYSTEM
"http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-stylable.dtd">
<svg height="300" width="300"
xmlns:xlink="http://www.w3.org/2000/xlink/namespace/"
>
<defs>
<!-- Assuming you want 10px spacing between the box border and the text
-->
<constant id="offset" value="10px"/>
</defs>
<rect id="A"
x="eval( (document.width - A.width - B.width ) * 1/3 + 1 );"
y="eval( (document.height - A.height - B.height) * 1/2 + 1 );"
width="eval( offset + textA.width + offset );"
height="eval( offset + textA.height + offset );"
style="fill:#00FFFF; stroke:#000000; stroke-width:1; shape-rendering:
optimizeSpeed;"
/>
<rect id="B"
x="eval( (document.width - A.width - B.width ) * 2/3 + A.width + 1
);"
y="eval( (document.height - A.height - B.height) * 1/2 + 1 );"
width="eval( offset + textB.width + offset );"
height="eval( offset + textB.height + offset );"
style="fill:#00FFFF; stroke:#000000; stroke-width:1; shape-rendering:
optimizeSpeed;"
/>
<text id="textA"
x="eval( A.x + offset );"
y="eval( A.y + offset );"
style="font:arial; font-size:8pt; text-rendering:optimizeSpeed;"
>A</text>
<text id="textB"
x="eval( B.x + offset );"
y="eval( B.y + offset );"
style="font:arial; font-size:8pt; text-rendering:optimizeSpeed;"
>B</text>
</svg>
Acyclic Dependancy:
===================
A.width --> textA.width
A.height --> textA.height
B.width --> textB.width
B.height --> textB.height
textA.x --> A.x --> document.width | A.width | B.width --> textA.width
| textB.width
textA.y --> A.y --> document.height | A.height | B.height --> textA.height
| textB.height
textB.x --> B.x --> document.width | A.width | B.width --> textA.width
| textB.width
textB.y --> B.y --> document.height | A.height | B.height --> textA.height
| textB.height
As you can see, it's quite straight-forword to derive expression for GUI
widget spring equations,
at least for square box spacing approximation of complex shapes like a cloud
or triangle and similar.
For your <path/> example, I think something like this should make everyone
happy:
<path d="M {if {viewport.right-viewport.left > 10px} then
{viewport.left+10px}
else
{0.5*viewport.right+0.5*viewport.left}}...."/>
becomes:
<path d="M
eval( if ( viewport.right-viewport.left > 10px )
{ return new Point( viewport.left+10px, 10px ); }
else
{ return new Point( 0.5*viewport.right+0.5*viewport.left, 10px );
}
);
l 1 0 l 0 1 l -1 0z"/>
The following notation might be needed:
<defs>
<expression id='len' value='eval( viewport.width/2 + 10px );' />
</defs>
<path d="M
eval( if ( viewport.right-viewport.left > 10px )
{ return new Point( viewport.left+10px, 10px ); }
else
{ return new Point( 0.5*viewport.right+0.5*viewport.left, 10px );
}
);
l eval( len ) 0 l 0 eval( len ) l eval( -1 * len ) 0z"/>
Here we see clearly why eval( x ) is needed to not confound the l 'el'
relative line command
and the variable name len.
or use { } as mentionned:
<path d="M
{eval( if ( viewport.right-viewport.left > 10px )
{ return new Point( viewport.left+10px, 10px ); }
else
{ return new Point( 0.5*viewport.right+0.5*viewport.left, 10px );
}
); }
l 1 0 l 0 1 l -1 0z"/>
The following might be needed:
<defs>
<expression id='len' value='eval( viewport.width/2 + 10px );' />
</defs>
<path d="M
{eval( if ( viewport.right-viewport.left > 10px )
{ return new Point( viewport.left+10px, 10px ); }
else
{ return new Point( 0.5*viewport.right+0.5*viewport.left, 10px );
}
); }
l {eval( len )} 0 l 0 {eval( len )} l {eval( -1 * len )} 0z"/>
or simply
<path d="M
{eval( if ( viewport.right-viewport.left > 10px )
{ return new Point( viewport.left+10px, 10px ); }
else
{ return new Point( 0.5*viewport.right+0.5*viewport.left, 10px );
}
); }
l {len} 0 l 0 {len} l {-len} 0z"/>
Anybody else, would be enthusiast to have such functionality?
BTW, all those inlined calculation could be ECMAScript based
and therefore hooked-up directly to existing embedded SVG ECMAscript
engines,
allowing for 'safe' recursive functions.
Sincerely yours,
Fred.
_________________________________________________________________
Add photos to your messages with MSN 8. Get 2 months FREE*.
http://join.msn.com/?page=features/featuredemail
Received on Monday, 12 May 2003 03:13:30 UTC