Stefán Freyr Stefánsson wrote:
-----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!

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>

<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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]

-----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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]






---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to