xmlgraphics-batik-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stefán Freyr Stefánsson <stef...@althingi.is>
Subject Re: Voting system UI - manipulating DOM vs. Extending Batik
Date Thu, 07 Aug 2003 17:24:06 GMT
-----BEGIN PGP SIGNED MESSAGE-----
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 new 
coordinate system.

I've done some experiments with this and it looks like it could work!

To explain I have to ellaborate a bit on what I've already done:
As I said in my previous post I've managed to create a small application that 
displays a floor plan with "chairs" that are given a special ID by using a 
custom made attribute.
In order to manipulate these "chairs" I recursively scan the SVG DOM tree once 
it's been parsed and look for any Element that has that attribute and store 
that element in a HashMap that maps the value of the chair-id attribute to 
the Element that contains the chair definition.  So in reality, I'm able to 
get a reference to the <use...> element that defines the chair in the SVG 
floor plan document.
When I receive the vote event for a particular chair, I look up that chairs 
element using the HashMap and manipulate the Element object.

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:
<svg ...>
    <defs>
        <g id="chair" style="stroke:black;stroke-width:1.5;">
            <rect width="400" height="400" x="0" y="0"/>
        </g>
    </defs>

    <use xlink:href="#chair" x="50" y="50" embla:chair-id="1"/>
    <use xlink:href="#chair" x="500" y="100" embla:chair-id="2"/>
</svg>

But after the pre-processing, the DOM tree will actually look like this:
<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>

(I've tried to view this file in Squiggle and it seems to work)

And instead of keeping a reference to the <use> element I'll keep a reference 
to the generated <svg> element.  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.

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. 

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>
>
> <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>
> </g>
>
> 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
> asked.
>
> <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>
>
> </svg>
>
> 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.)
>
> Later,
> G. Wade
>
> Stefán Freyr Stefánsson wrote:
> > -----BEGIN PGP SIGNED MESSAGE-----
> > 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 I
> > 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" .../>
> > </use>
> > 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
> > similar?
> >
> > 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"/>
> > >    ...
> > > </svg>
> > >
> > > 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:
> > >
> > > chair1,yes
> > > chair2,no
> > >   ...
> > >
> > > (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.)
> >
> > -----BEGIN PGP SIGNATURE-----
> > Version: GnuPG v1.2.2 (GNU/Linux)
> >
> > iQEVAwUBPzJw970ge6mq4AL2AQLdsAf9E/s5xz4Yy4qvFrbzAjVLHVrByji689L2
> > PBN7Sgmryd1J3CFJTxJGWsj3ZPOUcH9O0KGhJOuw7pzdjN0tH/2BirxewS7H6F/I
> > CR0eE75khX7+k5GD6gA7xZ9cuut7Yf8oimtFoz+i913Mxposqn3hjvuzx7Ut9AZn
> > cgdnviG6Kx9N5XQlH/xCgC2lKp+2jCQkyUCaD9J0mvKo2w8exgAOE+V3m3Isx38G
> > UP/fYHMkZUFrdxdZKuaZxPy2SKziKgRT+cbh903yOwEYLq794zLBcedEYRfu9Q2n
> > E/JvWo+BonaP5QPYss5wFxwRMkGoL+tgayYXpEZvZ2CHgtXyFyGqkw==
> > =fpst
> > -----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
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)

iQEVAwUBPzKLNr0ge6mq4AL2AQJK0gf9EyEidNNNN0vq1MX/2vDDF8p7bnu7hTCu
dk7Cu7zHBQ34bTw/FzibeikjnEtYS6VEP1fM08Zd8zO2KzTdkKXd6AtIoeXJ1HLG
jfp391HeNDUz890EHyW73UmfWlh3nBJgsBTNW6IaswhnaQ96+1exyITPFa25RMQ0
SKKA5+x+3CB/I1fdwdZmfpfcv0t13RCBIK2k48JFcSx4KCDLRS3WwGJto6iwz0Dz
H9i31k/yBi23LOzuP1CkIQnPc/1PwVpcaOprbt6byptgOChmgEQxc1nazzZ+8INx
ZwrJifUILe+eqthlaUiwa0FUFTSZIcryVNcRv139kEXJWGdg1AUNvA==
=z0PX
-----END PGP SIGNATURE-----


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


Mime
View raw message