quapka
quapka

Reputation: 2929

Shift SVG objects towards origin

I am creating bunch of different SVG files in Python using svgwrite module. I need to present those pictures later on a website.

Since those pictures consists of different mathematical object I am working in whole plane, both with positive and negative numbers. That means that I need to shift all the objects so they will be visible and maintain the structure. Sometimes shifting those objects is not hard, but since I have to do it in almost all my work I am looking for something more general.

So I am looking for something that will shift all of the objects and maintain their structure, so that everything will be visible and the size of the picture would be minimal(meaning the width/height).

I search the official documentation but haven't been successful so far, maybe just blind.

Update To make it clearer I have added an example

Python example:

import svgwrite

im = svgwrite.drawing.Drawing()
im.add(im.line( start = (-10,-10),\
                end   = (20,20),\
                stroke= 'black'))
im.saveas('example.svg')

Then, when I view example.svg in e.g. Firefox there would be only part the "positive" part that is line from [0,0] to [20,20].

Or slightly different example:

import svgwrite

im = svgwrite.drawing.Drawing()
im.add(im.line( start = (10,10),\
                end   = (20,20),\
                stroke= 'black'))
im.saveas('example2.svg')

Now there is unnecessary gap between [0,0] and the line, which starts at [10,10].

So, to sum it up. Imagine bunch of SVG objects, they can be drawn anywhere. I want to find minimal x_min, y_min coordinates throughout all the objects and then:

After that the all the objects will be visible, and they will touch one or both axis at zero. As discussed below, same result might be achieved by shifting the origin (in corresponding way).

Note While I am at it, the similar problem comes with module Image.

Upvotes: 2

Views: 1826

Answers (2)

Paul LeBeau
Paul LeBeau

Reputation: 101966

If I understand your clarifications right, what you want is for the diagram not to go off the page when rendered (?). If that's the case, what you need to do is add a viewBox to your SVG.

First, keep track of the minimum and maximum, x and y values over the whole diagram. You may have to do that yourself, or it is possible the svgwrite library will do that for you.

Once the diagram is finished, add a viewBox attribute to your root SVG element that contains these values.

The viewBox takes this form:

minX minY width height

where minX minY is the top left of the diagram. So, for your first example above, the viewBox would be:

<svg viewBox="-10 -10 30 30" ... >

and for your second example it would be:

<svg viewBox="10 10 10 10" ... >

Then when the picture is rendered in, say, a browser, it will use the picture dimensions given by the viewBox attribute to position and scale the contents to fill the container (the browser window, <div> etc).

If, rather than having it fill the container, you want to specify a default width and height for the diagram (eg. 200px x 200px), add width and height attributes to the SVG. Like this:

<svg width="200px" height="200px" viewBox="-10 -10 30 30">

    <line x1="-10" y1="-10" x2="20" y2="20" stroke="black" />

</svg>

Demo here

Upvotes: 2

Paul LeBeau
Paul LeBeau

Reputation: 101966

Assuming you want to shift the origin, what you need to do is surround your graph lines with a group element and apply a transform to that.

I don't know the proper syntax for that library, but going by the documentation, it will be something like the following:

im = svgwrite.drawing.Drawing()
g = svgwrite.container.Group(transform='translate(50,50)')
im.add(g)
g.add(im.line( start = (-10,-10),\
                end   = (20,20),\
                stroke= 'black'))
im.saveas('example.svg')

Upvotes: 4

Related Questions