SVGo is a Go library that generates SVG as defined by the Scalable
Vector Graphics 1.1 Specification (http://www.w3.org/TR/SVG11/) to
standard output.
The code is hosted at http://github.com/ajstarks/svgo and example
outputs can be seen at http://www.flickr.com/photos/ajstarks/sets/72157623441699483/detail/
== Supported SVG elements ==
circle, ellipse, polygon, polyline, rect (including roundrects),
paths (arc,
cubic and quadratic bezier paths), line, image, text,
== Metadata elements ==
desc, defs, g (style, transform, id), title, (a)ddress, use
== Building and Usage ==
See svgdef.[svg|png|pdf] for a graphical view of the function calls
Usage: (where $GC and $GL are the Go compiler and linker for your
targer architecture, $A)
$ $GC svg.go = compile the library
$ $GC svgdef.go && $GL -o svgdef svgdef.$A = compile a client
program
$ ./svgdef = run the client program
a minimal program:
package main
import "svg"
func main() {
svg.Start(500, 500)
svg.Circle(250, 250, 100)
svg.End()
}
You may view the SVG output with a browser that supports SVG (tested
on Chrome, Opera, Firefox and Safari), or any other SVG user-agent
such as Batik Squiggle. The test-svgo script tries to use reasonable
defaults based on the GOOS and GOARCH environment variables
The command:
$ ./newsvg foo.go
creates a template Go source file ready for your code.
== Package contents ==
svg.go Library
test-svgo Compiles the library, builds the clients and
displays the results||
newsvg Coding template command||
svgdef.go Creates a SVG representation of the API||
vismem.go Visualize data from files||
randcomp.go Compare random number generators||
planets.go Show the scale of the Solar system||
rl.go Random lines (port of a Processing demo)||
imfade.go Show image fading||
images/* Images used by the client programs||
== Functions ==
Many functions use x, y to specify an object's location, and w, h to
specify the object's width and height.
Where applicable, a final optional argument specifies the style to be
applied to the object.
The style strings follow the SVG standard; name:value pairs delimited
by semicolons.
For example:"fill:none; opacity:0.3" (see: http://www.w3.org/TR/SVG11/styling.html)
=== Structure, Metadata and Links ===
Start(w int, h int)
begin the SVG document with the width w and height h
http://www.w3.org/TR/SVG11/struct.html=SVGElement
End()
end the SVG document
Gstyle(s string)
begin a group, with the specified style
http://www.w3.org/TR/SVG11/struct.html=GElement
Gtransform(s string)
begin a group, with the specified transform
Gid(s string)
begin a group, with the specified id
Gend()
end the group (must be paired with Gstyle, Gtransform, Gid)
Def()
begin a definition block
http://www.w3.org/TR/SVG11/struct.html=DefsElement
DefEnd()
end a definition block
Desc(s string)
specify the text of the description
http://www.w3.org/TR/SVG11/struct.html=DescElement
Title(s string)
specify the text of the title
http://www.w3.org/TR/SVG11/struct.html=TitleElement
Link(name string, title string)
begin a link named "name", with the specified title
http://www.w3.org/TR/SVG11/linking.html=Links
LinkEnd()
end the link
Use(x int, y int, link string, s ...string)
place the object referenced at link at the location x, y
http://www.w3.org/TR/SVG11/struct.html=UseElement
=== Shapes ===
Circle(x int, y int, r int, s ...string)
draw a circle, centered at x,y with radius r
http://www.w3.org/TR/SVG11/shapes.html=CircleElement
Ellipse(x int, y int, w int, h int, s ...string)
draw an ellipse, centered at x,y with radii w, and h
http://www.w3.org/TR/SVG11/shapes.html=EllipseElement
Polygon(x []int, y []int, s ...string)
draw a series of line segments using an array of x, y coordinates
http://www.w3.org/TR/SVG11/shapes.html=PolygonElement
Rect(x int, y int, w int, h int, s ...string)
draw a rectangle with upper left-hand corner at x,y, with width w,
and height h
http://www.w3.org/TR/SVG11/shapes.html=RectElement
Roundrect(x int, y int, w int, h int, rx int, ry int, s ...string)
draw a rounded rectangle with upper the left-hand corner at x,y,
with width w, and height h. The radii for the rounded portion
is specified by rx (width), and ry (height)
Square(x int, y int, s int, style ...string)
draw a square with upper left corner at x,y with sides of length s
=== Paths ===
Arc(sx int, sy int, ax int, ay int, r int, large bool, sweep bool, ex
int, ey int, s ...string)
draw an elliptical arc beginning coordinate at sx,sy, ending
coordinate at ex, ey
width and height of the arc are specified by ax, ay, the x axis
rotation is r
if sweep is true, then the arc will be drawn in a "positive-angle"
direction (clockwise), if false,
the arc is drawn counterclockwise.
if large is true, the arc sweep angle is greater than or equal to
180 degrees,
otherwise the arc sweep is less than 180 degrees
http://www.w3.org/TR/SVG11/paths.html=PathDataEllipticalArcCommands
Bezier(sx int, sy int, cx int, cy int, px int, py int, ex int, ey int,
s ...string)
draw a cubic bezier curve, beginning at sx,sy, ending at ex,ey
with control points at cx,cy and px,py
http://www.w3.org/TR/SVG11/paths.html=PathDataCubicBezierCommands
Qbezier(sx int, sy int, cx int, cy int, ex int, ey int, tx int, ty
int, s ...string)
draw a quadratic bezier curve, beginning at sx, sy, ending at tx,ty
with control points are at cx,cy, ex,ey
http://www.w3.org/TR/SVG11/paths.html=PathDataQuadraticBezierCommands
=== Lines ===
Line(x1 int, y1 int, x2 int, y2 int, s ...string)
draw a line segment between x1,y1 and x2,y2
http://www.w3.org/TR/SVG11/shapes.html=LineElement
Polyline(x []int, y []int, s ...string)
draw a polygon using coordinates specified in x,y arrays
http://www.w3.org/TR/SVG11/shapes.html=PolylineElement
=== Image and Text ===
Image(x int, y int, w int, h int, link string, s ...string)
place at x,y (upper left hand corner), the image with width w, and
height h, referenced at link
http://www.w3.org/TR/SVG11/struct.html=ImageElement
Text(x int, y int, t string, s ...string)
Place the specified text, t at x,y according to the style specified
in s
http://www.w3.org/TR/SVG11/text.html=TextElement
=== Color ===
RGB(r int, g int, b int) string
creates a style string for the fill color designated
by the (r)ed, g(reen), (b)lue components
http://www.w3.org/TR/css3-color/
RGBA(r int, g int, b int, a float) string
as above, but includes the color's opacity as a value
between 0.0 (fully transparent) and 1.0 (opaque)
=== Utility ===
Grid(x int, y int, w int, h int, n int, s ...string)
draws a grid of straight lines starting at x,y, with a width w, and
height h, and a size of n
The current code writes to standard output, so it wouldn't work
inside, say, a web server generating pictures on demand.
It might be more general to have something like
func New(w io.Writer) *SVG
and then make all the top-level functions you have
methods on SVG.
Also, I wonder if maybe instead of the many functions
it might make sense to have many types instead, and then
a program can manipulate a picture as a data structure,
calling into the SVG package to marshal the data structure
out in wire format. The data structures would probably be a
better fit for the grouping concept (just a recursive SVG),
and package xml might make this very easy.
(And if it doesn't, maybe it would be a good test case for
making package xml more useful. See the xmpp code I
posted last week for an example of what I mean.)
It would be even cooler if the package could read SVG
back into memory, creating an equivalent data structure,
so that one could do SVG transformations or embed SVG
pictures inside other pictures.
Russ
I'd like to reiterate this point:
On 21 March 2010 06:54, Russ Cox <r...@golang.org> wrote:
> The current code writes to standard output, so it wouldn't work
> inside, say, a web server generating pictures on demand.
>
> It might be more general to have something like
>
> func New(w io.Writer) *SVG
>
> and then make all the top-level functions you have
> methods on SVG.
I would actually like to use this library inside a web server to make
a simple web-based strategy game. Without this change it wouldn't be
possible.
Andrew
Take a look at the svg.go. Ajstarks has done a good job of making it
extremely simple.
I almost had it converted over to use a writer last night, but wife
demanded attention. Would you be interested in a copy of the patch
when it is ready?
Jonathan.
On Mar 20, 1:53 pm, ajstarks <ajsta...@gmail.com> wrote:
> (This message is a request for comments from the Go community on the
> SVG library and 2D graphics APIs for Go.)
>
> SVGo is a Go library that generates SVG as defined by the Scalable
> Vector Graphics 1.1 Specification (http://www.w3.org/TR/SVG11/) to
> standard output.
>
> The code is hosted athttp://github.com/ajstarks/svgoand example
> outputs can be seen athttp://www.flickr.com/photos/ajstarks/sets/72157623441699483/detail/
The branch also contains two other patches, one for gofmting the
examples, and another for preventing rm failed error messages the
first time test-svgo is run.
[1] http://github.com/quag/svgo/commit/b787f6d95291af55bad12d03c361996f964134ee
Thanks,
Jonathan Wright.
> To unsubscribe from this group, send email to golang-nuts+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
>
I would find the examples easier to read and understand, by the way,
if you didn't define "var svg" at the top level. It originally didn't
occur to me to look outside the main function, and I thought I was
looking at the wrong examples or the wrong version of the code.
David
That would be cool.
> I would find the examples easier to read and understand, by the way,
> if you didn't define "var svg" at the top level. It originally didn't
> occur to me to look outside the main function, and I thought I was
> looking at the wrong examples or the wrong version of the code.
Quite right. The "var svg" hack is there as I didn't want to disturb
Antony's examples when putting in the writer change.
Antony, how do you feel about passing around svg pointers every where?
Thanks,
Jonathan.
Along with the comments and code posted by others, I'd like to toss in
another use-case:
Last year I was working on a mobile radiation detection instrument for
Homeland Security that needed to report its results not only on a local
GUI and local wireless PDAs, but also to "higher authority".
Unfortunately, no implementable standards for upstream reporting existed
(the closest in trial use was CAP - the Common Alerting Protocol).
The project ended last year, with no upstream protocol ever being
designed or implemented. But the problem has been nagging me ever
since. Since I'm primarily a sensor and processing/analysis wonk
(deeply embedded software), I had little clue what an upstream
high-level protocol should look like (from DHS's perspective). I knew
the data stream needed to be easy to archive, and fully tolerant of
latency, interruptions, and loss. It had to be effective over
intermittent one-way networks (no acks), yet permit some level of
interaction (when available or possible).
First, I knew I had to send live instrument data, along with at least
some meta-data (units, timestamps, etc.). For simplicity and
convenience, I chose a very simple XML document with an equally simple
DTD, so the data would be both human and machine readable. However, a
textual list of data would completely fail to communicate to the distant
listener the level of "situational awareness" the data contained. So I
decided to send a snapshot of the GUI, which would give a useful "big
picture view" to non-experts. I also wanted to eliminate any need to
install instrument-specific software outside of the instrument itself,
and to minimize demands on what will often be an unreliable upstream
network.
With the live data in XML, creating a GUI snapshot in SVG seemed to be a
no-brainer. Unfortunately, I have little experience with XML or SVG,
and my initial efforts (in Inkscape) were very crude (and were probably
Just Plain Wrong). But I did learn a few things, and most of all I
found myself wishing for an XML/SVG layer that would support and
simplify the following:
1. Send "live" XML data packets at full instrument rate (1 Hz), in plain
text.
2. Send XML instrument configuration and status information less often.
2. Send the DTD less often, in plain text.
3. Send an SVG snapshot of the GUI (occasionally), in plain text
(viewable in any SVG viewer).
4. Send an SVG template of the primary display screen that can be
parameterized by the XML data (to permit a remote GUI to update a GUI
image at full data rate without saturating the network with snapshots).
Since this assumes a higher level of end-processing, it can be sent gzipped.
5. Send additional gzipped SVG screen templates for other live data
views, and to view configuration and status information.
6. Send an "interaction overlay" (in ecmascript?) to permit a listener
with a basic browser to locally select between "live" SVG screens
(pseudo-interaction).
7. Send an "operator overlay" to permit a listener/talker to remotely
control some aspects of instrument operation (with access control), and
to communicate with local users/operators. This is the only layer that
requires a secure two-way connection.
Again, I'm pretty much an XML/SVG newbie, so a brain-dead simple
implementation strategy is highly desirable! Which leads to my main
question:
Is (or will) the SVGo package be suitable/helpful for generating some or
all of the above?
While my original project is dead and gone, it seems the above stack
would have general applicability ranging from my specific instrument
reporting example all the way up to remote interfaces for networks of
systems (for things like IT network maintenance). I suppose it could be
viewed as a kind of archivable RDP (remote desktop protocol) that works
at various levels of interaction.
And with Go, supporting multiple remote interactive users should be
effortless.
-BobC
svg.Start(width, height) // by default use stdout
and if you wanted to use it in a web server as Russ and Andrew have suggested:
svg.Start(width, height, w)
where w is your web server's io.Writer
The problem with that is that you can't then easily create two or more
svg outputs from one program. Often I'd like to create several plots
from the same data, and it'd be nice to be able to do that in
parallel. e.g. imagine reading some very large file (won't fit in
memory, maybe?) to plot every nth datum or to plot a moving average.
It's not a show stopper, but having an SVG object seems to me much the
cleaner approach. It also keeps the API flexible for if you want to
generate a figure that is used several times within a larger figure.
David
On Mar 22, 5:13 pm, Bob Cunningham <FlyM...@gmail.com> wrote:
> On 03/20/2010 10:53 AM, ajstarks wrote:
>
> > (This message is a request for comments from the Go community on the
> > SVG library and 2D graphics APIs for Go.)
>
> > SVGo is a Go library that generates SVG as defined by the Scalable
> > Vector Graphics 1.1 Specification (http://www.w3.org/TR/SVG11/) to
> > standard output.
>
> > The code is hosted athttp://github.com/ajstarks/svgoand example
> > outputs can be seen athttp://www.flickr.com/photos/ajstarks/sets/72157623441699483/detail/
If you want to reuse objects, here is an edited example from svgdef.go
const objstyle = "fill:none; stroke-width:2; stroke:rgb(127,0,0); opacity:0.75"
const textsize = 15
func defrect(id string, w int, h int, legend string) {
svg.Gid(id)
svg.Rect(0, 0, w, h, objstyle)
svg.Text(-textsize, (h / 2), "h", legendstyle)
svg.Text((w / 2), -textsize, "w", legendstyle)
svg.Gend()
}
func main() {
...
defrect("rectangle", 160, 100, "svg.Rect(x, y, w, h,...)") // define initial object
svg.Use(40, 80, "#rectangle") // initial use
svg.Use(400, 200, '#rectangle") // use it again
svg.Gtransform("rotate(30)") // use it again, with a transformation
svg.Use(100, 200, "#rectangle")
svg.Gend()
Russ
few comments (in-lined) on the xml package.
On Mon, 2010-04-19 at 07:16 -0700, andbelo wrote:
...
> 2. While reading a XML document with package xml, the fields in the Go
> structure are required to be of type string.
the xml.Unmarshal will handle scalar types. see the scalar tests in
xml_test.go.
> It would be nice if
> functions or methods could be written to allow the transformation of
> the strings coming from XML to the appropriate types, so that when the
> type is manipulated later on, it already has the proper types in it.
that is in the pipe-line. see this thread for how it will be addressed,
hopefully in the near future:
cheers;
rsn