How to use viewbox when height of svg is dynamically changing

A_user picture A_user · Jul 27, 2012 · Viewed 13.9k times · Source

I have a resizable div. It has two inner divs. One of the inner divs has an svg element in it.

In the svg element I am adding and removing the content dynamically such that each time I add something in my svg. I increase its height by adding 20px to it and when I remove I subtract the height by 20px. When my svg height become greater than its parent div a scroll bar appears in the parent div. Similarly scroll bar is removed when svg height is less than parent div.

The problem starts when I do the resizing. I have added a viewbox option in my svg for resizing. But when I increase the size some of my svg elements are not visible. And when I decrease the size my svg get placed at a lower position leaving empty space.

Its all messed up in my mind that how to deal svg position/height with viewbox property.

I have tried to make a fiddle to simulate the behavior somehow. But here elements in svg are not adding dynamically and the svg height is constant.

Link to my code

Any help will be appreciated

Answer

Dmitry Koroliov picture Dmitry Koroliov · Jul 27, 2012

LATEST UPDATE:

Most important if you're going to use SVG it is better to be acquainted with spec or read a definite guide like "SVG Essentials" by J. Eisenberg, cause it is not such a trivial thing you might think at first.

Then if I understood you right, there is another approach jsFiddle.

First, set correctly the value of the viewBox attribute. In your current example in should be viewBox="0 0 130 220" so that all you content be visible (you have to specify at least 220 as the last number cause your last group <g> is translated i.e. it's coordinate system moved down to 200 units, if you don't do that your content will be not visible cause it is far beyond the outmost y-point of your viewbox, which in your jsfiddle is set to 70).

Second, specify the correct value for preserveAspectRatio which should be preserveAspectRatio="xMinYMax meet", which means (courtesy of the "SVG Essentials" by J. Eisenberg):

Align minimum x of viewBox with left corner of viewport.

Align maximum y value of viewBox with bottom edge of viewport.

meet means meet the content, not slice it, if it doesn't fit.

Third, if you are going to add elements to the bottom of your svg you have to change the viewBox value accordingly, cause if you will insert into it smth like:

<g transform="translate(0, 300)">
     <text>text 55 </text>
</g>

it will occur beyound your viewBox, which has a max y-point at 220 (if you would set it as I said earlier)

For now hope that helps, let me know.

OLD STUFF

remove style="height:200px" from your svg

Then if you need height, you can dynamically change the height of your svg

var $wrapper = $('#resize'),
    $svg = $('#svg2');
$wrapper.resizable({
    handles: 'se',
    aspectRatio: 400/200,
    resize: function(ev, ui) {
        $svg.css('height', ui.size.height);
    }
});

'#resize' - is the id of the wrapper of the svg

I'm now very confused of what you want. You specified viewbox attr on the svg. That means that only a part of your svg will be visible. Try to remove viewbox and see whether result looks satisfactory for you.

It then be all visible and normally adjusted to parent div