An introduction to SVG and an example - pie chart

    SVG ( scalable vector graphics) is a vector graphics format similar to EPS, animation and user interaction, developed in W3C. Inside, the file is not binary, but regular XML that describes objects, their effects and behavior. Vector graphics are generally needed when resizing an image without losing quality, such as printing. On the web, I see this in rubber sites, where the block sizes are set in%, the font size in em, and the logo in SVG. Moved to a better monitor - everything changed proportionally. Practical examples are icons, graphs, maps, logos, interfaces . Below I give an example of such a Pie-chart.


    Integration

    HTML - Inline
    Since SVG is essentially XML, it can immediately be described inline-style in an XHTML structure. However, as I have already seen, XHTML1.1 doctype implies that the MIME of the document is no longer text-plain. And the “donkey” IE6 does not understand XHTML in principle, on the other hand, Firefox uses two parsers, and if MIME is not application / xhtml + xml, then inline SVG will not be recognized. This is a double-edged sword - IE and FF. The second method and the most practical one is to refer to an existing file through an object tag. To reduce traffic, you can compress the file and get the SVGZ archive.
    />

    CSS and Javascipt
    As you will see below - since SVG is very closely connected with HTML / XML, it is natural that you can not only describe CSS objects with CSS, but also write Javascript functions for all kinds of onclick and so on. events (hence the interactivity). />
    Converting and Editors
    You can also convert SVG to png / jpeg, but for this you actually need to do the work of the handler. In PHP, the PEAR XML_svg2image library does this . There is also a service for converting a raster image into a vector one (although there is EPS). From the editors - there are Inkscape and Adobe Illustrator, Corel Draw.

    Graphics

    Primitives

    Any drawing begins with the definition of space (two-dimensional), separation into coordinates (in units of floating point or percent) and the introduction of primitive constructions:
    • line - a straight line. x1, y1, x2, y2 - coordinates
    • polyline - a broken line. points - enumeration of coordinates of points
    • rect is the rectangle. x, y, width, height, rx, ry - upper left corner, dimensions, corner radii
    • polygone is a polygon. Looks like a polyline. points - coordinates of points
    • circle - circle. cx, cy, r - center coordinates and radius
    • ellipse. cx, cy, rx, ry - center coordinates and radii
    • text - text inscription. Very inconvenient, because without line breaks and with absolute positioning. x, y, font-family, font-size
    • tspan - can describe words inside a text element. For example, shift or colorize
    • tref - reuse of the text element with the specified id
      Простой текст
      <tref xlink:href="#myText" x="50" y="50">
    textPath - text on the path curve associated by id image - bitmap/>
    <textPath xlink:href="#myPath" startOffset="50%">Водка Vinogradoff

    <image image-rendering="optimizeSpeed" xlink:href"background.jpg" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" filter="url(#blurpane)"/>
    Options and Styles
    Like in html, few people need some lines - they need to be painted over, colors must be specified, and all this is done by parameters
    • fill, fill-rule - fill. For example, "none", blue, indigo.
    • stroke, stroke-linecap, stroke-linejoin, stroke-dasharray, stroke-dashoffset, stroke-width - border, analog of border. Together stroke-width.
    • font-family, font-size, font-style, font-weight - fonts for text elements
    • text-anchor
    Tags are used for filling:
    • pattern
    • linearGradient
    • radialGradient
    These parameters can all be combined into one CSS analog and written in inline-style:
    style="stroke-width:1; stroke:blue; fill:none"
    Besier groups and curves
    Elements can and should be grouped into each other. In addition to the fact that tspan is set inside the text element, grouping occurs due to the element. Bezier curves are smooth transition lines defined by points. In SVG there is a path element for this, for which, like a broken line, coordinates are indicated. Near the coordinates can be letters indicating the properties of the line. Large letters indicate absolute positioning, small letters indicate relative
    • M is the beginning of the curve (x, y)
    • Z - end of the curve (without coordinates)
    • L-straight line (x, y)
    • H - horizontal line
    • V - vertical line
    • Q is a quadratic curve at one point
    • T - continuation of the curve with the reflection of the previous point - simplifies the drawing of repeating rhythms
    • C - the actual Bezier curve of the third order at two points
    • S is a simplified version of C
    • A - elliptic curve (radii, rotation)

    Transformations and Opportunities

    Objects in SVG can be distorted, twisted and moved using filters, which are specified as parameters:
    • translate - object transfer
    • rotate rotation
    • scale - scaling
    • scewX, scewY - distortion
    • matrix - mixed transformation
    SVG supports filters with lighting effects. And besides static images, there is the possibility of animation and interactivity with the user. For example, Tetris or the acclaimed Microsoft Table and Silverlight are implemented programmatically in SVG , and if you so desire, the video ( Ogg Theora = SVGT format) also works. Of course, the latest features are not yet implemented in all browsers, but pioneers such as Opera are available.


    Cake graph on SVG and PHP / DB

    Sure, the Google API is a very handy thing. But do not forget that it is still an external service, albeit a reliable one. Commercial developments do not like to take risks, so the generation of graphs should still be local (if they are not static). I will generate the image using php, based on the
    data obtained from the database to display the poll results. Since the GD library, although it understands the size of SWF,
    only binary files are generated. Therefore, XML will header("Content-Type: image/svg+xml"); have to be generated: Let's see what we should strive for (so far without cool animation ) ...Let's start with the rubber arrangement of two ellipses? Sectors apparently go clockwise in decreasing order to reduce the amount of gradient in small areas. The color of the sector is apparently calculated in proportion to the number of pieces - this is where the problem arises. As it turns out, you cannot just fill in a sector with two lines and an existing ellipse - the figure must be precisely outlined, so we need to draw everything individually using path , but we don’t need ellipse .
    Color trigonometry
    To calculate the path element in a loop, you need to remember a little math. Since a circle is a special case of an ellipse, the formulas have a lot in common, which is very useful to us: For an ellipse, the radius is simply replaced by the major and minor axis, respectively. Next, create a cycle where we calculate the percentage distribution of data, degrees for the sector with path . We compute the coordinates for the arch, for this we use a “degree shift” so that the drawing of all sectors goes closely. An RGB cube, you can cut it in different ways, make projections and enter your own coordinate systems like CMYK and HSL. Different shades of the selected orange fill are obtained when dividing the segment between the selected dot-color and the white vertex (255,255,255).x=cos(angle)*radius; y=sin(angle)*radius; //circle
    x=cos(angle)*rx; y=sin(angle)*ry; //ellipse


    if ($intTotalValue) // если сумма значений голосования больше нуля то можно делить и рисовать
    foreach((array) $Data as $key=>$recEntry){
    $Data[$key]->percent=$recEntry->value/$intTotalValue;
    $Data[$key]->color[0]=round($graph->fill[0]+($key/count($Data)*(255-$graph->fill[0])));
    $Data[$key]->color[1]=round($graph->fill[1]+($key/count($Data)*(255-$graph->fill[1])));
    $Data[$key]->color[2]=round($graph->fill[2]+($key/count($Data)*(255-$graph->fill[2])));

    $Data[$key]->degree=360*$Data[$key]->percent;
    $Data[$key]->start['x']=$graph->cx+round(cos(deg2rad($intDegreeShift)) * $graph->rx,3);
    $Data[$key]->start['y']=$graph->cy+round(sin(deg2rad($intDegreeShift)) * $graph->ry,3);
    $Data[$key]->end['x']=$graph->cx+round(cos(deg2rad($intDegreeShift+$Data[$key]->degree)) * $graph->rx,3);
    $Data[$key]->end['y']=$graph->cy+round(sin(deg2rad($intDegreeShift+$Data[$key]->degree)) * $graph->ry,3);
    $intDegreeShift+=$Data[$key]->degree; //increase degree shift

    $boolIsLargeArc=$Data[$key]->degrees>180? 1 : 0;
    echo "\n".'/>';
    }
    If you look at the graph carefully, you can see that the volume is done
    using a gradient, which we first fill in as a background in SVG,
    and we will already overlay specific sector colors with transparency:

    />
    />
    />

    Main problems

    But the problem remains with painting the border sectors - only the areas that go to half the cake should be painted over the front area over the gradient. To this stage, the picture looks like this:graph_limit_problem_416
    Absolute text
    In addition, the question arises how to arrange textual descriptions of sectors? Google simply draws lines from the middle of the sectors, even if the text does not fit on one line. In SVG, you need to position the text from the upper left corner - which is already a problem, since we do not know the width. There are two ways out: to abandon the relative positioning of the text and make callouts color, or use text with a fixed width (monospace, Courier) and on this basis calculate the length in pixels and position on the fly. Fortunately, I came across the text-anchor: end parameter , which in a strange way expanded the text as it should.

    Interactivity and the future

    Thanks to integration with javascript, you can update the image accordingly in real time using AJAX . In my case, this is necessary when the user votes and it is necessary to update the distribution of votes on the chart.

    Read also:

    Original article with illustrations and usage example

    Also popular now: