📜 ⬆️ ⬇️

SVG introduction and example pie chart

SVG ( scalable vector graphics) is a vector graphics format similar to EPS, animation, and user interaction developed in the W3C. Inside the file is not binary but plain XML, describing objects, their effects and behavior. Vector graphics are generally needed when resizing an image without losing quality, for example in printing. In the web, I see it in rubber sites, where the block sizes are set in%, the font size in em, and the logo in SVG. We moved to a better monitor - everything changed in proportion. Practical examples are icons, graphics, maps, logos, interfaces . Below I give an example of such a pie-chart.


Integration

HTML - Inline
Since SVG is essentially XML, it can be immediately described in inline-style in the 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 IE6 donkey doesn't 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 stick - IE and FF.
/>
The second method and the most practical one is to refer to an existing file via an object tag. For
to reduce traffic, the file can be compressed and get the SVGZ archive.
CSS and Javascipt
As you will see below - since SVG is very closely related to HTML / XML, it’s natural that graphic objects can not only be described using CSS, but also write Javascript functions on all sorts of onclick and so on. event'y (hence the interactivity). />
Conversion and Editors
You can convert SVG to png / jpeg, but for this you actually need to do the work of the handler. In PHP, this is the PEAR XML_svg2image library. There is also a service for converting a raster image into a vector (although there is EPS). From the editors - there is Inkscape and Adobe Illustrator, Corel Draw.

Graphics

Primitives

Any drawing begins with the definition of space (two-dimensional), the division into coordinates (in floating-point or percentage units) and the introduction of primitive structures:
  • line - straight line. x1, y1, x2, y2 - coordinates
  • polyline - broken line. points - enumeration of coordinates of points
  • rect is a rectangle. x, y, width, height, rx, ry - upper left corner, dimensions, radii of corners
  • polygone is a polygon. Looks like a polyline. points - coordinates of points
  • circle is a circle. cx, cy, r - coordinates of the center and radius
  • ellipse. cx, cy, rx, ry - coordinates of the center 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 move or color
  • tref - reuse of the text element with the specified id

    <tref xlink:href="#myText" x="50" y="50">
textPath - text on the path-curve, linked by id />
<textPath xlink:href="#myPath" startOffset="50%"> Vinogradoff
/>
<textPath xlink:href="#myPath" startOffset="50%"> Vinogradoff
/>
<textPath xlink:href="#myPath" startOffset="50%"> Vinogradoff
image - raster image
<image image-rendering="optimizeSpeed" xlink:href"background.jpg" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" filter="url(#blurpane)"/>
Parameters and styles
As in html, some lines are not needed very much - they need to be painted over, colors are indicated, 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, analogue of the border. Together stroke-width.
  • font-family, font-size, font-style, font-weight - fonts for text-elements
  • text-anchor
For filling tags are used:
  • pattern
  • linearGradient
  • radialGradient
These parameters can all be combined into one analog CSS and write in inline-style:
style="stroke-width:1; stroke:blue; fill:none"
Groups and Bezier curves
Elements can and should be grouped into each other. In addition to the fact that tspan is set inside the text element, the grouping takes place thanks to the element. Bezier curves are smooth transition lines, defined by points. In SVG, there is a path element for this, where coordinates are specified like a broken line. Near the coordinates there may be letters indicating the properties of the line. Large letters indicate absolute positioning, small letters indicate relative
  • M - the beginning of the curve (x, y)
  • Z - the end of the curve (without coordinates)
  • L-line (x, y)
  • H - horizontal line
  • V - vertical line
  • Q - quadratic curve on one point
  • T - continuation of the curve with the reflection of the previous point - simplifies drawing repetitive rhythms
  • C is the third-order Bezier curve itself at two points
  • S - simplified version of C
  • A - elliptic curve (radii, rotation)

Transformations and opportunities

Objects in SVG can be distorted, twisted and moved using filters that 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 with a strong desire, the video ( Ogg Theora = SVGT format) also worked. Of course, the latest features are not yet implemented in all browsers, but there are Opera discoverers .


Cake schedule on SVG and PHP / DB

Undoubtedly, the Google API is a very handy thing. But do not forget that after all this is an external service, even if it is reliable. Commercial development do not like to take risks, so the generation of graphs still has to be local (if they are not static). I will generate the image using php, based on
Database data to display poll results (poll). Since the GD library, although it understands the size of the SWF,
generates only binary files. Therefore, XML will have to be generated: header("Content-Type: image/svg+xml"); Let's see what we should strive for (for now without cool animation ) ... Let's start with the rubber arrangement of the two ellipses? Sectors apparently go in descending order in a clockwise direction, in order to reduce the number of gradients 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, the sector cannot simply be filled in with two lines and an existing ellipse - the figure must be precisely delineated, so you need to draw everything separately with the help of path , and we will not need ellipse .
Color trigonometry
To calculate the coordinates of a path-element in a cycle, it is necessary to recall a bit of mathematics. Since the circle is a special case of an ellipse, there is much in common in the formulas, which is very useful to us: x=cos(angle)*radius; y=sin(angle)*radius; //circle
x=cos(angle)*rx; y=sin(angle)*ry; //ellipse
x=cos(angle)*radius; y=sin(angle)*radius; //circle
x=cos(angle)*rx; y=sin(angle)*ry; //ellipse

For an ellipse, the radius is simply replaced by the major and minor semi-axis, respectively. Next, create a loop, where we calculate the percentage distribution of data, the degree for the sector with path . We include the coordinates for the arch, for this we use a “degree shift” to draw all sectors closely. RGB cube, you can cut, make projections and enter your systems in different ways
coordinates like CMYK and HSL. Different shades of the selected orange fill are obtained by dividing the segment between the selected point-color and the top of white (255,255,255). 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 chart closely, you can see that the volume is done
using a gradient, which in SVG we first fill in as a background,
and on top we will impose specific colors of the sector with transparency:

/>
/>
/>

Main problems

But the problem remains with painting over the border sectors - it is necessary to paint over the front area over the gradient only in those areas that go up to half of the cake. To this stage, the picture looks like this: graph_limit_problem_416
Absolute text
In addition, the question arises how to locate text descriptions of sectors? Google simply leads lines from the middle of the sectors, even if the text does not fit in one line. In SVG, text should be positioned from the upper left corner - which is already a problem, since we don’t know the widths. Two ways out - to abandon the relative positioning of the text and make the callouts in 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 stumbled upon the parameter text-anchor: end , which strangely unfolded the text as it should.

Interactivity and Future

Thanks to the integration with javascript, you can update the image in real time using AJAX, respectively. In my case, this is necessary when the user votes and you need to update the distribution of votes on the chart.
')
See also:

Original article with illustrations and example of use

Source: https://habr.com/ru/post/23724/


All Articles