xmlgraphics-batik-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Thomas DeWeese <Thomas.DeWe...@Kodak.com>
Subject Re: Voting system UI - manipulating DOM vs. Extending Batik
Date Thu, 07 Aug 2003 17:44:16 GMT
Stefán Freyr Stefánsson wrote:
> Hash: SHA1
> Thank you for your reply.
> I just had an idea! :o)
> I was reading about SVG when I suddenly noticed that it's possible to "embed" 
> a new <svg> element inside the root <svg> element to obtain a completely
> coordinate system.
> I've done some experiments with this and it looks like it could work!

    Yes this will work just fine.

> So... since I'm able to do that, I could just as well "pre-process" the SVG 
> DOM tree in memory in such a way that I yank the <use...> element out of the 
> tree and put in a new <svg> element using the x and y values of the <use>

> element that was there in the first place...  So what I'll have is a floor 
> plan file that looks very simple:

   Ugg, this will work but it isn't very efficent.  You might
consider writting a small XSL script to do this once whenever
you get a new floor plan.

> But after the pre-processing, the DOM tree will actually look like this:

    This is basically the structure I would suggest using.

> <svg ...>
>     <defs>
>         <g id="chair" style="stroke:black;stroke-width:1.5;">
>             <rect width="400" height="400" x="0" y="0"/>
>         </g>
>     </defs>
>     <svg x="50" y="50">
>         <use xlink:href="#chair" x="0" y="0" embla:chair-id="1"/>
>     </svg>
>     <svg x="500" y="100">
>         <use xlink:href="#chair" x="0" y="0" embla:chair-id="2"/>
>     </svg>
> </svg>
> This will allow me to add layers much easier 
> since I could for example create a Java interface that defines a method that 
> returns an Element object containing any SVG code that should be layered on 
> top of a chair.

   Usually when people talk about layers they think of a seperate group
This way you can toggle visibility on all elements of the group at
once.  Also You have the advantage that all members of the layer
can actually be 'above' all members of another layer.  So for example
one persons name could flow over an ajacent chair if it were very long
(I could see polititians getting touchy about this however ;).

    The other advantage of putting layers in true layers is that
you need to touch fewer elements - the end result is the same but
you only need to set one attribute as opposed to hundreds.  Once you
know the bounds of the chair (see below) putting the text in
another layer isn't hard (you can even use the transform attribute
on the text so that the 'x' & 'y' attributes are in the same
coordinate system as the original chair).

> The only caveat that I don't see an immediate solution to is the width and 
> height attributes of the generated svg element.  It would be nice to be able 
> to establish a firm boundary to the layers so that they can't "flow" over 
> areas that the "chair" doesn't cover.  With the above solution it seems like 
> that would be the case but if I could somehow figure out the width and height 
> of the original chair element that was being referenced, I could add the 
> width and height attributes to the generated <svg> element.

> If you have any idea about how I could possibly figure out that width and 
> height, that would be absolutely great to know. 

    Take a look at org.w3c.dom.svg.SVGLocatable.getBBox()  this will
return the bounding box for the element.  The element must be part
of the rendering tree for this to work (so call it on the use element
before you remove it from the rendering tree).

> It would be nice to hear your views on this.  What I really like is that it 
> keeps the logic out of the floor plan itself.  There shouldn't have to be any 
> notion of these information layers in the original SVG image... that should 
> be added by the application... not the graphics designer.

> Kind regards, Stefan Freyr.
> On Thursday 07 August 2003 16:43, G. Wade Johnson wrote:
>>Once again, apologies to all for the long post.
>>According to the SVG spec, a <use/> can only contain <desc/>, <title/>,
>><metadata/> and the "animate" elements.
>>Modifying an approach I've used to your problem would go something like:
>><use id="chair1" xlink:href="#chair" x="10" y="10"/>
>><use id="chair2" xlink:href="#chair" x="30" y="10"/>
>><use id="chair3" xlink:href="#chair" x="50" y="10"/>
>><g id="votelayer" visibility="hidden">
>>  <use id="chair1vote" xlink:href="#chair" x="10" y="10"/>
>>  <use id="chair2vote" xlink:href="#chair" x="50" y="10"/>
>>  <use id="chair2vote" xlink:href="#chair" x="50" y="10"/>
>><g id="namelayer" visibility="hidden">
>>  <text id="chair1name" x="12" y="20">Wade</text>
>>  <text id="chair2name" x="22" y="20">Thomas</text>
>>  <text id="chair2name" x="22" y="20">Stef&#xE1;n</text>
>>Althought there is lots of repetition, this is easy to manipulate.
>>While writing this up, I had another idea which is closer to what you
>><svg xmlns:xlink="http://www.w3.org/1999/xlink"
>>     xmlns="http://www.w3.org/2000/svg"
>>     width="300" height="300" viewBox="0,0 100,100">
>>   <defs>
>>     <g id="chair">
>>       <rect x="0" y="0" width="5" height="5"
>>             style="stroke:black; stroke-width:0.5;"/>
>>     </g>
>>     <style type="text/css"><![CDATA[
>>        .yes   { fill:green; }
>>        .no    { fill:red; }
>>        .none  { fill:none; }
>>	.baselayer  { visibility: inherit; fill: none; }
>>	.votelayer  { visibility: hidden; }
>>	.namelayer  { visibility: hidden; }
>>	text        { font-size: 4; text-anchor:middle; }
>>     ]]></style>
>>   </defs>
>>   <g transform="translate(10,10)">
>>     <use id="chair1" xlink:href="#chair" class="baselayer"/>
>>     <use id="chair1vote" xlink:href="#chair" class="no votelayer"/>
>>     <text x="2" y="10" class="namelayer">Wade</text>
>>   </g>
>>   <g transform="translate(30,10)">
>>     <use id="chair2" xlink:href="#chair" class="baselayer"/>
>>     <use id="chair2vote" xlink:href="#chair" class="votelayer yes"/>
>>     <text x="2" y="10" class="namelayer">Thomas</text>
>>   </g>
>>   <g transform="translate(50,10)">
>>     <use id="chair2" xlink:href="#chair" class="baselayer"/>
>>     <use id="chair2vote" xlink:href="#chair" class="votelayer none"/>
>>     <text x="2" y="10" class="namelayer">Stef&#xE1;n</text>
>>   </g>
>>Manipulating the layers and states seems a bit more difficultto me.
>>Now, to add/change a vote, you will need to combine a few classes as
>>shown above. Turning the layers on and off will require modifying the
>>styles for the various classes. (I haven't done this, so I don't know
>>how hard that might be.)
>>G. Wade
>>Stefán Freyr Stefánsson wrote:
>>>Hash: SHA1
>>>Thanks so much for your reply.
>>>I have been looking into things today and in short I'm moving back
>>>towards what you're saying... that is, to use standard SVG instead of
>>>extending the SVG syntax for our purposes.
>>>I can see that I'm obviously suffering from lack of experience and things
>>>such as this are something that I don't even think of :o(.  Good thing
>>>that I can turn to this list for ideas (thanks again).
>>>I have implemented a little application that reads a very basic floor
>>>plan and I was able to dynamically update the image using a
>>>VotingSimulator thread (yay).
>>>(Oh, btw... it would be a good idea to make it more clear in the
>>>documentation for Batik that JSVGCanvas's setDocumentState(
>>>JSVGCanvas.ALWAYS_DYNAMIC ) _must_ be called _before_ setting the
>>>document with the setDocument( Document ) if you want to be able to
>>>retrieve an UpdateManager from that JSVGCanvas instance!  It took me
>>>forever to figure out that getUpdateManager() always returned null
>>>because I called the setDocumentState method after I had called the
>>>setDocument method).
>>>I've pretty much decided on using standard SVG and I think your
>>>suggestion about using internal stylesheets looks really good so I think
>>>I'll use that too.
>>>There is, however, one little thing that I'm not quite shure on how to
>>>solve. That thing is my "layer" concept.  In my application, I'd want to
>>>be able to turn on and off various information layers.  For example, I'd
>>>like to be able to turn off the voting "layer" so that all chairs are
>>>displayed normally.  I am able to imagine how that would be done (simply
>>>defining a class called "off" in the stylesheet and setting all chairs to
>>>that) but I'm having a more difficult time imagining how I could solve
>>>other types of layers such as the name of the person sitting in that
>>>chair.  I'd like to be able to somehow "overlay" this information in the
>>>same location as the chair is put on the basic floor plan (my goal is to
>>>keep the basic floor plan as simple as possible so it is easy to update
>>>it, rearrange chairs and so on).  This information is pulled from a
>>>database so your suggestion of using the persons name as the ID instead
>>>of an integer would not work for us, people can switch chairs and so on
>>>and information about which person is sitting in which chair is
>>>registered into a database.  I'd like to be able to easily add such
>>>information layers (where information is pulled from a database and
>>>rendered on top of the chair location).  Unfortunately I'm not quite
>>>getting how it would be best to do that.  Here are some questions that
>>>are related to this problem:
>>>1) Is it possible in SVG to define anything within the <use> tag?  What
>>>mean is that the chairs are rendered on the floor plan by referencing the
>>>"chair definition".  Is it possible to do something like:
>>><use xlink:href="#chair" x="20" y="20">
>>>  <circle x="5" y="5" .../>
>>>The way I see it is that the circle would then be rendered within its own
>>>coordinate system and the area of the referenced element would be used as
>>>its viewport (I hope I'm making myself clear).
>>>If this would be possible, adding information "layers" would be a piece
>>>of cake by utilizing regular DOM manipulation like I've already done with
>>>the fill element in my little test application.
>>>2) If #1 is impossible, how would you suggest to achieve something
>>>Kind regards and thanks for your answers,
>>>        Stefan Freyr
>>>On Thursday 07 August 2003 13:29, G. Wade Johnson wrote:
>>>>Apologies in advance for a fairly long post.
>>>>If I'm not misunderstanding, the basic design of what you want is
>>>>relatively easy with just SVG and Batik. (Even without adding new
>>>>attributes or elements.<grin/>) I'll have to defer to Thomas on the
>>>>extending approach, I've not used that as yet.
>>>>Modifying your example slightly,
>>>><svg xmlns:xlink="http://www.w3.org/1999/xlink"
>>>>     xmlns="http://www.w3.org/2000/svg">
>>>>   <defs>
>>>>     <g id="chair"/>
>>>>     <style type="text/css"><![CDATA[
>>>>        .yes { fill:green; }
>>>>        .no  { fill:red; }
>>>>     ]]></style>
>>>>   </defs>
>>>>   <use id="chair1" xlink:href="#chair" x="10" y="10"/>
>>>>   <use id="chair2" xlink:href="#chair" x="20" y="20"/>
>>>>   ...
>>>>For a simple change in state like the vote, you could have the data
>>>>stream that you read for updates contain the id and vote. For example,
>>>>a CSV data stream with one change per line:
>>>>  ...
>>>>(For more complex changes, a more complex data stream might be
>>>>necessary. But, to start, simpler might be better.)
>>>>As each vote comes in you do the following,
>>>>  doc.getElementById( idstr ).setAttributeNS( null, "class", vote );
>>>>Of course, you will need the document in the 'doc' variable, and the
>>>>'idstr' and 'vote' need to be set up correctly. (Not to mention error
>>>>checking.) But this is the basic idea.
>>>>I could also see using a person's name for the chair id instead of
>>>>a number, which could lead to other interesting features.
>>>>If you want to keep up with more than a single state, associating
>>>>a Java object with each "chair" would allow you to manipulate the
>>>>the object in arbitrary ways.
>>>>Also the "class" attribute can contain a space-separated list of
>>>>classes. As long as the properties don't conflict, this allows
>>>>you to make fairly complex visual effects.
>>>>This approach would require you to develop less code and the SVG
>>>>files could be created using standard tools. (That may not be an
>>>>issue yet, but you can bet that someone is going to ask to make
>>>>the picture more complex over time. Good tools would make that
>>>>less of a hardship.)
>>>Version: GnuPG v1.2.2 (GNU/Linux)
>>>-----END PGP SIGNATURE-----
>>>To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
>>>For additional commands, e-mail: batik-users-help@xml.apache.org
>>To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
>>For additional commands, e-mail: batik-users-help@xml.apache.org
> Version: GnuPG v1.2.2 (GNU/Linux)
> iQEVAwUBPzKLNr0ge6mq4AL2AQJK0gf9EyEidNNNN0vq1MX/2vDDF8p7bnu7hTCu
> dk7Cu7zHBQ34bTw/FzibeikjnEtYS6VEP1fM08Zd8zO2KzTdkKXd6AtIoeXJ1HLG
> jfp391HeNDUz890EHyW73UmfWlh3nBJgsBTNW6IaswhnaQ96+1exyITPFa25RMQ0
> SKKA5+x+3CB/I1fdwdZmfpfcv0t13RCBIK2k48JFcSx4KCDLRS3WwGJto6iwz0Dz
> H9i31k/yBi23LOzuP1CkIQnPc/1PwVpcaOprbt6byptgOChmgEQxc1nazzZ+8INx
> ZwrJifUILe+eqthlaUiwa0FUFTSZIcryVNcRv139kEXJWGdg1AUNvA==
> =z0PX
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
> For additional commands, e-mail: batik-users-help@xml.apache.org

To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org

View raw message