Browse Source

Start working on radar

pull/8/head
Florian Mounier 13 years ago
parent
commit
0ee9d3425c
  1. 13
      out.py
  2. 1
      pygal/__init__.py
  3. 27
      pygal/graph/radar.py
  4. 32
      pygal/svg.py

13
out.py

@ -1,6 +1,6 @@
#!/usr/bin/env python
from pygal import (
Line, Bar, XY, Pie, StackedBar, Config,
Line, Bar, XY, Pie, Radar, StackedBar, Config,
HorizontalBar, HorizontalStackedBar)
from pygal.style import NeonStyle
from math import cos, sin
@ -80,3 +80,14 @@ pie.add('test2', 29)
pie.title = "Pie test"
with open('out-pie.svg', 'w') as f:
f.write(pie.render())
config = Config()
config.x_labels = (
'black', 'red', 'blue', 'yellow', 'orange', 'green', 'white')
radar = Radar(config)
radar.add('test', [9, 10, 3, 5, 7, 2, 5])
radar.add('test2', [10, 2, 0, 5, 1, 9, 4])
radar.title = "Radar test"
with open('out-radar.svg', 'w') as f:
f.write(radar.render())

1
pygal/__init__.py

@ -7,4 +7,5 @@ from pygal.graph.horizontal import HorizontalStackedBar
from pygal.graph.line import Line
from pygal.graph.xy import XY
from pygal.graph.pie import Pie
from pygal.graph.radar import Radar
from pygal.config import Config

27
pygal/graph/radar.py

@ -0,0 +1,27 @@
from pygal.graph.base import BaseGraph
from math import pi
class Radar(BaseGraph):
"""Kiviat graph"""
def _compute(self):
vals = [val for serie in self.series for val in serie.values]
self._box.ymax = 2 * max(vals)
self._box.ymin = - self._box.ymax
self._box.xmin = self._box.ymin
self._box.xmax = self._box.ymax
delta = 2 * pi / float(len(self.x_labels))
x_step = len(self.series[0].values)
self._x_pos = [.5 * pi - i * delta for i in range(x_step)]
self._y_pos = self._pos(self._box.ymin, self._box.ymax, self.y_scale
) if not self.y_labels else map(int, self.y_labels)
self._x_labels = self.x_labels and zip(self.x_labels, self._x_pos)
self._y_labels = zip(map(str, self._y_pos), self._y_pos)
def _plot(self):
for serie in self.series:
serie_node = self.svg.serie(serie.index)
# self.svg.web(serie_node, serie,
# [val / float(self._rmax) for val in serie.values])

32
pygal/svg.py

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
import os
from lxml import etree
from pygal.view import View
@ -20,7 +21,8 @@ class Svg(object):
None: self.ns,
'xlink': 'http://www.w3.org/1999/xlink',
})
self.root.append(etree.Comment(u'Generated with pygal ©Kozea 2012'))
self.root.append(etree.Comment(u'http://github.com/Kozea/pygal'))
self.defs = self.node(tag='defs')
self.add_style(self.graph.base_css or os.path.join(
os.path.dirname(__file__), 'css', 'graph.css'))
@ -133,6 +135,22 @@ class Svg(object):
self.graph.y_label_rotation, x, y)
text.text = label
def web_axis(self):
axis = self.node(self.plot, class_="axis polar")
delta = 2 * pi / float(len(self.graph.x_labels))
center = self.view((0, 0))
f = lambda x: '%f %f' % x
for i, title in enumerate(self.graph.x_labels):
angle = .5 * pi - i * delta
end = self.view((cos(angle), sin(angle)))
self.node(axis, 'path',
d='M%s L%s' % (f(center), f(end)),
class_='line')
self.node(axis, 'text',
x=end[0],
y=end[1]
).text = str(i)
def legend(self):
if not self.graph.show_legend:
return
@ -265,6 +283,18 @@ class Svg(object):
y=center[1] - text_r * sin(text_angle),
).text = '{:.2%}'.format(perc)
def web(self, serie_node, serie, radius):
webs = self.node(serie_node, class_="webs")
web = self.node(webs, class_="web")
# view_radius = map(self.view, radius)
origin = '%f %f' % self.view((0, 0))
dot1 = '%f %f' % self.view((1, 1))
dot2 = '%f %f' % self.view((-1, -1))
self.node(web, 'path',
d='M%s L%s %s' % (
origin, dot1, dot2),
class_='web')
def render(self):
return etree.tostring(
self.root, pretty_print=True,

Loading…
Cancel
Save