Scale uniform on X axis - svg

I dynamically generate an svg, which can result in a very high height value. (It's a table.)
My aim is to have:
ratio on x axis
scrollbar to scroll the image down
I know I have to play with svg's height and width, viewBox and preserveAspectRatio, but to achieve my goal I'm using a dirty trick which leaves a lot of white space at the bottom: I set the height of the image to a very high value.
The problem is that I have no certainty that the table (image) will never exceed this value (and I don't want to end up setting it to something like 100000).
Can anybody help me?
Here's the example I'm working on to find a solution:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="100%"
height="2000"
viewBox="0 0 1366 768"
preserveAspectRatio="xMinYMin meet">
<rect
width="1359.5181"
height="42.065403"
x="3"
y="3"
id="rect2985"
style="fill:#ffff78;stroke:#000000;stroke-width:10" />
<rect
width="719.58691"
height="805.50775"
x="316.83304"
y="177.29433"
id="rect2987"
style="fill:#ffff78;stroke:#000000;stroke-width:10" />
<text
x="15"
y="30"
id="text2989"
style="font-size:23px">LOL</text>
</svg>

Yeah, I guess I should.
I'll use this for now (still gotta be fully tested):
function fixHeight()
{
node = document.getElementById("table");
node.setAttribute("height", node.getBBox().width);
}

Related

How to automatically create the minimal size of the viewbox which fits for the complete content?

I have a simple or complex SVG graphic. For example a rotated rectangle.
Without calculating you cannot know the minimal size of the viewbox, where the graphic fits into completely.
<svg viewBox="0 0 30 30">
<rect x="20" y="0" width="100" height="20" transform="rotate(45)" fill="black" />
</svg>
The result is, that the graphic does not fit into the viewbox.
Is there any method, how to get an the minimal size of the viewbox, where the graphic is shown completely?
Ideally I do not want to declare a size/ratio of a viewbox. I just want that the minimal size is a result of the content of the SVG graphics.
Is there any disadvantage, when I do not declare the viewBox attribute at all?
Thanks for your help.
One way to do it is wrapping the transformed rectangle in a <g> element and then get the value of the bounding box for theG. Next you use the values of the bounding box (BB) to reset the viewBox of theSVG. I hope it helps.
// the bounding box for the wrapping g
let BB = theG.getBBox();
theSVG.setAttributeNS(null, "viewBox", `${BB.x} ${BB.y} ${BB.width} ${BB.height}`)
svg{border:1px solid}
<svg id="theSVG" viewBox="0 0 30 30" width="300">
<g id="theG">
<rect x="20" y="0" width="100" height="20" transform="rotate(45)" fill="black" />
</g>
</svg>

Force SVG tooltip appear when mouse over unfilled area

Here is a simple SVG code with a tooltip embedded:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" enable-background="new 0 0 100 100"
xml:space="preserve">
<g>
<title>Blue Frame</title>
<path
fill="#2E3192"
d="M75,25v50H25V25H75 M100,0H0v100h100V0L100,0z"
/>
</g>
</svg>
It draws blue frame and does nothing more.
The problem is tooltip appears only when the mouse pointer is over the frame. When it moves to unfilled center of the SVG image, then tooltip disappears.
Moving <title> tag over the <g> tag leads to no tooltip at all.
What have I missed to make tooltip appear always when the mouse pointer is over any point of this SVG, not just over filled parts?
It is just a quick and short preview to show the problem. For example it is very difficult to catch the tooltip on any large image with only a few thin lines.
I know I can place a rectangle that will cover all available SVG space and put anything over it. But this rectangle also needs some color while I need transparent parts of my SVGs to remain strictly transparent.
You could always put a hidden rect in the background to catch those mouse events you'd otherwise miss like so:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 100 100" xml:space="preserve">
<g>
<title>Blue Frame</title>
<rect width="100%" height="100%" visibility="hidden" pointer-events="all"/>
<path
fill="#2E3192"
d="M75,25v50H25V25H75 M100,0H0v100h100V0L100,0z"
/>
</g>
</svg>
I would also suggest to define X and Y positions to the rectangle offered by Mr.Longson. Otherwise the rectangle may appear outside of your drawing partially or completely and you would have to catch the tooltip again.
You may get X and Y values at the <svg> tag's viewBox parameter, they are the first two groups of digits, the very first one is for the X and the second one is Y. Other two describes the initial size of the SVG and not needed for this case.
According to your example you don't need to define either X or Y as they are both equal to 0:
<rect x="0" y="0" width="100%" height="100%" visibility="hidden" pointer-events="all"/>
But as soon as they are for example viewBox="-123 456 100 100" you'll immediately notice that some parts of your SVG still don't show any tooltip. In such case the <rect> tag should look like this:
<rect x="-123" y="456" width="100%" height="100%" visibility="hidden" pointer-events="all"/>

SVG rotate text with % as Unit

I try to rotate a svg text. i get the position of the text as % i.e. 15% by calling a php function from xslt. the problem is that i can not rotate a svg object using %. it works if i use a digit number instead.
Below i present the problem as simplified:
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://ww.w3.org/2001/xml-events" xmlns:php="http://php.net/xsl" version="1.1" baseProfile="full">
<text x="50%" y="50%" transform="rotate(-90 50% 50%)">rotateMe</text>
<line x1="50%" y1="47%" x2="60%" y2="47%" stroke="black" stroke-width="2px"/>
</svg>
this pic is in the middle of my browser screen
And i want that it looks like this:
but it dont work because of %
transform="rotate(-90 **50% 50%**)"
it is a requirement for me to use % for the coordinates. Any ideas or solution to my problem?
Thank you in advanced.
You can translate the co-ordinates using an inner <svg> element. The example below displays as per your "i want that it looks like this" bitmap on Firefox.
If you can't see the text on whatever browser you are using, try adding overflow="visible" to the inner <svg> element so you can see where it ends up. Not all browsers support the dominant-baseline attribute so you may need to fiddle about with the text's y attribute instead.
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg x="50%" y="50%" width="100" height="100">
<text text-anchor="end" dominant-baseline="text-before-edge" transform="rotate(-90 0 0)">rotateMe</text>
</svg>
<line x1="50%" y1="47%" x2="60%" y2="47%" stroke="black" stroke-width="2px"/>
</svg>

Rotate an object in SVG

I am just getting started with SVG and am now trying out rotating objects.
I have the initial canvas and have created my own drag and drop function so on mousedown the drag is initialized and mouseup it stops. The problem i'm having is when I rotate an object, it seems to change the x and y. This is visible when i'm trying to drag an object. Does anyone know how to get around this so the x and y get "normalized" in relation to the rotate angle?
Here's my code.
<svg version="1.1" width="900" height="400"><text x="10" y="10" id="text_0" width="200" height="40" transform="rotate(45, 0, 0)">SVG test</text></svg>
Thanks
rotate parameters give you the angle and the center of the rotation (see MDN for example). And what about the width and height attributes in your text anyways? This is not part of the standard as of here. If you want to change the size of your text, do so using font-size in the style.
If you want to rotate the text around its (the text element's) center you may use for example the following:
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" width="900" height="400" xmlns="http://www.w3.org/2000/svg">
<text x="10" y="10" id="text_0" transform="rotate(45, 10, 10)" style="dominant-baseline: middle; text-anchor: middle;">
SVG test
</text>
</svg>

Why is this svg cropped and not scaled?

I'm new to SVG and a bit surprised that this example is cropped and not scaled? Whats missing to make it scaleable/sizeable using width/height in the svg element?
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="200px"
height="200px"
viewBox="0 0 400px 400px">
<g fill-opacity="0.7" stroke="black" stroke-width="0.1cm">
<circle cx="200px" cy="60px" r="100" fill="red"
transform="translate(0,50)" />
<circle cx="200px" cy="60px" r="100" fill="blue"
transform="translate(70,150)" />
<circle cx="200px" cy="60px" r="100" fill="green"
transform="translate(-70,150)" />
</g>
</svg>
Because if your viewBox is invalid the viewport is determined by the width and height of the outermost element (in your case the SVG element at 200x200px). Since your content overflows this it is cropped.
By defining a valid viewBox of 400x400 you gave your content enough room inside the viewBox but it was all scaled to fit inside the SVG element. The viewBox is a sort of virtual space mapped onto the real space.
The issue is fairly involved. The viewport and the viewbox are different things. The spec covers both in detail: http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute

Resources